Merge branch '10.0' into 10.1

This commit is contained in:
Sergei Golubchik 2018-12-06 15:08:42 +01:00
commit 6491c591b2
8 changed files with 159 additions and 64 deletions

View File

@ -591,6 +591,25 @@ id select_type table type possible_keys key key_len ref rows Extra
set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
set use_stat_tables=@save_use_stat_tables; set use_stat_tables=@save_use_stat_tables;
# #
# MDEV-17734: AddressSanitizer: use-after-poison in create_key_parts_for_pseudo_indexes
#
set @@use_stat_tables= PREFERABLY;
set @save_optimizer_use_condition_selectivity= @@optimizer_use_condition_selectivity;
set @@optimizer_use_condition_selectivity=4;
set @save_use_stat_tables= @@use_stat_tables;
create table t1 (a int, b int);
insert into t1(a,b) values (1,2),(1,3),(1,4),(1,5),(2,6),(2,7),(3,8),(3,9),(3,9),(4,10);
analyze table t1 persistent for columns (a) indexes ();
Table Op Msg_type Msg_text
test.t1 analyze status Engine-independent statistics collected
test.t1 analyze status OK
select * from t1 where a=1 and b=3;
a b
1 3
set @@optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity;
set use_stat_tables=@save_use_stat_tables;
drop table t1;
#
# MDEV-16711:CREATE OR REPLACE TABLE introducing BLOB column # MDEV-16711:CREATE OR REPLACE TABLE introducing BLOB column
# #
SET use_stat_tables= PREFERABLY; SET use_stat_tables= PREFERABLY;

View File

@ -618,6 +618,25 @@ id select_type table type possible_keys key key_len ref rows Extra
set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
set use_stat_tables=@save_use_stat_tables; set use_stat_tables=@save_use_stat_tables;
# #
# MDEV-17734: AddressSanitizer: use-after-poison in create_key_parts_for_pseudo_indexes
#
set @@use_stat_tables= PREFERABLY;
set @save_optimizer_use_condition_selectivity= @@optimizer_use_condition_selectivity;
set @@optimizer_use_condition_selectivity=4;
set @save_use_stat_tables= @@use_stat_tables;
create table t1 (a int, b int);
insert into t1(a,b) values (1,2),(1,3),(1,4),(1,5),(2,6),(2,7),(3,8),(3,9),(3,9),(4,10);
analyze table t1 persistent for columns (a) indexes ();
Table Op Msg_type Msg_text
test.t1 analyze status Engine-independent statistics collected
test.t1 analyze status OK
select * from t1 where a=1 and b=3;
a b
1 3
set @@optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity;
set use_stat_tables=@save_use_stat_tables;
drop table t1;
#
# MDEV-16711:CREATE OR REPLACE TABLE introducing BLOB column # MDEV-16711:CREATE OR REPLACE TABLE introducing BLOB column
# #
SET use_stat_tables= PREFERABLY; SET use_stat_tables= PREFERABLY;

View File

@ -0,0 +1,13 @@
use mysql;
insert db (db,user,select_priv) values ('foo','dwr_foo','Y'), ('bar','dwr_bar','Y');
insert roles_mapping (user,role) values ('dwr_qux_dev','dwr_foo'),('dwr_qux_dev','dwr_bar');
insert user (user,show_db_priv,is_role) values ('dwr_foo','N','Y'), ('dwr_bar','N','Y'), ('dwr_qux_dev','Y','Y');
Warnings:
Warning 1364 Field 'ssl_cipher' doesn't have a default value
Warning 1364 Field 'x509_issuer' doesn't have a default value
Warning 1364 Field 'x509_subject' doesn't have a default value
Warning 1364 Field 'authentication_string' doesn't have a default value
flush privileges;
drop role dwr_foo;
drop role dwr_bar;
drop role dwr_qux_dev;

View File

@ -0,0 +1,11 @@
#
# MDEV-17898 FLUSH PRIVILEGES crashes server with segfault
#
use mysql;
insert db (db,user,select_priv) values ('foo','dwr_foo','Y'), ('bar','dwr_bar','Y');
insert roles_mapping (user,role) values ('dwr_qux_dev','dwr_foo'),('dwr_qux_dev','dwr_bar');
insert user (user,show_db_priv,is_role) values ('dwr_foo','N','Y'), ('dwr_bar','N','Y'), ('dwr_qux_dev','Y','Y');
flush privileges;
drop role dwr_foo;
drop role dwr_bar;
drop role dwr_qux_dev;

View File

@ -369,6 +369,23 @@ SELECT * FROM INFORMATION_SCHEMA.PROFILING, mysql.user;
set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
set use_stat_tables=@save_use_stat_tables; set use_stat_tables=@save_use_stat_tables;
--echo #
--echo # MDEV-17734: AddressSanitizer: use-after-poison in create_key_parts_for_pseudo_indexes
--echo #
set @@use_stat_tables= PREFERABLY;
set @save_optimizer_use_condition_selectivity= @@optimizer_use_condition_selectivity;
set @@optimizer_use_condition_selectivity=4;
set @save_use_stat_tables= @@use_stat_tables;
create table t1 (a int, b int);
insert into t1(a,b) values (1,2),(1,3),(1,4),(1,5),(2,6),(2,7),(3,8),(3,9),(3,9),(4,10);
analyze table t1 persistent for columns (a) indexes ();
select * from t1 where a=1 and b=3;
set @@optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity;
set use_stat_tables=@save_use_stat_tables;
drop table t1;
--echo # --echo #
--echo # MDEV-16711:CREATE OR REPLACE TABLE introducing BLOB column --echo # MDEV-16711:CREATE OR REPLACE TABLE introducing BLOB column
--echo # --echo #

View File

@ -2762,7 +2762,9 @@ bool create_key_parts_for_pseudo_indexes(RANGE_OPT_PARAM *param,
if (bitmap_is_set(used_fields, (*field_ptr)->field_index)) if (bitmap_is_set(used_fields, (*field_ptr)->field_index))
{ {
Field *field= *field_ptr; Field *field= *field_ptr;
if (field->type() == MYSQL_TYPE_GEOMETRY) Column_statistics* col_stats= field->read_stats;
if (field->type() == MYSQL_TYPE_GEOMETRY ||
!col_stats || col_stats->no_stat_values_provided())
continue; continue;
uint16 store_length; uint16 store_length;

View File

@ -714,7 +714,9 @@ bool ROLE_GRANT_PAIR::init(MEM_ROOT *mem, char *username,
/* Flag to mark that on_node was already called for this role */ /* Flag to mark that on_node was already called for this role */
#define ROLE_OPENED (1L << 3) #define ROLE_OPENED (1L << 3)
static DYNAMIC_ARRAY acl_hosts, acl_users, acl_dbs, acl_proxy_users; static DYNAMIC_ARRAY acl_hosts, acl_users, acl_proxy_users;
static Dynamic_array<ACL_DB> acl_dbs(0U,50U);
typedef Dynamic_array<ACL_DB>::CMP_FUNC acl_dbs_cmp;
static HASH acl_roles; static HASH acl_roles;
/* /*
An hash containing mappings user <--> role An hash containing mappings user <--> role
@ -1582,12 +1584,11 @@ static bool acl_load(THD *thd, TABLE_LIST *tables)
db.access|=REFERENCES_ACL | INDEX_ACL | ALTER_ACL; db.access|=REFERENCES_ACL | INDEX_ACL | ALTER_ACL;
} }
#endif #endif
(void) push_dynamic(&acl_dbs,(uchar*) &db); acl_dbs.push(db);
} }
my_qsort((uchar*) dynamic_element(&acl_dbs,0,ACL_DB*),acl_dbs.elements,
sizeof(ACL_DB),(qsort_cmp) acl_compare);
end_read_record(&read_record_info); end_read_record(&read_record_info);
freeze_size(&acl_dbs); acl_dbs.sort((acl_dbs_cmp)acl_compare);
acl_dbs.freeze();
if ((table= tables[PROXIES_PRIV_TABLE].table)) if ((table= tables[PROXIES_PRIV_TABLE].table))
{ {
@ -1675,7 +1676,7 @@ void acl_free(bool end)
free_root(&acl_memroot,MYF(0)); free_root(&acl_memroot,MYF(0));
delete_dynamic(&acl_hosts); delete_dynamic(&acl_hosts);
delete_dynamic_with_callback(&acl_users, (FREE_FUNC) free_acl_user); delete_dynamic_with_callback(&acl_users, (FREE_FUNC) free_acl_user);
delete_dynamic(&acl_dbs); acl_dbs.free_memory();
delete_dynamic(&acl_wild_hosts); delete_dynamic(&acl_wild_hosts);
delete_dynamic(&acl_proxy_users); delete_dynamic(&acl_proxy_users);
my_hash_free(&acl_check_hosts); my_hash_free(&acl_check_hosts);
@ -1714,7 +1715,8 @@ void acl_free(bool end)
bool acl_reload(THD *thd) bool acl_reload(THD *thd)
{ {
TABLE_LIST tables[TABLES_MAX]; TABLE_LIST tables[TABLES_MAX];
DYNAMIC_ARRAY old_acl_hosts, old_acl_users, old_acl_dbs, old_acl_proxy_users; DYNAMIC_ARRAY old_acl_hosts, old_acl_users, old_acl_proxy_users;
Dynamic_array<ACL_DB> old_acl_dbs(0U,0U);
HASH old_acl_roles, old_acl_roles_mappings; HASH old_acl_roles, old_acl_roles_mappings;
MEM_ROOT old_mem; MEM_ROOT old_mem;
int result; int result;
@ -1749,7 +1751,7 @@ bool acl_reload(THD *thd)
old_acl_dbs= acl_dbs; old_acl_dbs= acl_dbs;
my_init_dynamic_array(&acl_hosts, sizeof(ACL_HOST), 20, 50, MYF(0)); my_init_dynamic_array(&acl_hosts, sizeof(ACL_HOST), 20, 50, MYF(0));
my_init_dynamic_array(&acl_users, sizeof(ACL_USER), 50, 100, MYF(0)); my_init_dynamic_array(&acl_users, sizeof(ACL_USER), 50, 100, MYF(0));
my_init_dynamic_array(&acl_dbs, sizeof(ACL_DB), 50, 100, MYF(0)); acl_dbs.init(50, 100);
my_init_dynamic_array(&acl_proxy_users, sizeof(ACL_PROXY_USER), 50, 100, MYF(0)); my_init_dynamic_array(&acl_proxy_users, sizeof(ACL_PROXY_USER), 50, 100, MYF(0));
my_hash_init2(&acl_roles,50, &my_charset_utf8_bin, my_hash_init2(&acl_roles,50, &my_charset_utf8_bin,
0, 0, 0, (my_hash_get_key) acl_role_get_key, 0, 0, 0, 0, (my_hash_get_key) acl_role_get_key, 0,
@ -1770,6 +1772,7 @@ bool acl_reload(THD *thd)
acl_roles_mappings= old_acl_roles_mappings; acl_roles_mappings= old_acl_roles_mappings;
acl_proxy_users= old_acl_proxy_users; acl_proxy_users= old_acl_proxy_users;
acl_dbs= old_acl_dbs; acl_dbs= old_acl_dbs;
old_acl_dbs.init(0,0);
acl_memroot= old_mem; acl_memroot= old_mem;
init_check_host(); init_check_host();
} }
@ -1780,7 +1783,6 @@ bool acl_reload(THD *thd)
delete_dynamic(&old_acl_hosts); delete_dynamic(&old_acl_hosts);
delete_dynamic_with_callback(&old_acl_users, (FREE_FUNC) free_acl_user); delete_dynamic_with_callback(&old_acl_users, (FREE_FUNC) free_acl_user);
delete_dynamic(&old_acl_proxy_users); delete_dynamic(&old_acl_proxy_users);
delete_dynamic(&old_acl_dbs);
my_hash_free(&old_acl_roles_mappings); my_hash_free(&old_acl_roles_mappings);
} }
mysql_mutex_unlock(&acl_cache->lock); mysql_mutex_unlock(&acl_cache->lock);
@ -1963,9 +1965,9 @@ bool acl_getroot(Security_context *sctx, char *user, char *host,
if (acl_user) if (acl_user)
{ {
res= 0; res= 0;
for (i=0 ; i < acl_dbs.elements ; i++) for (i=0 ; i < acl_dbs.elements() ; i++)
{ {
ACL_DB *acl_db= dynamic_element(&acl_dbs, i, ACL_DB*); ACL_DB *acl_db= &acl_dbs.at(i);
if (!acl_db->user || if (!acl_db->user ||
(user && user[0] && !strcmp(user, acl_db->user))) (user && user[0] && !strcmp(user, acl_db->user)))
{ {
@ -1994,9 +1996,9 @@ bool acl_getroot(Security_context *sctx, char *user, char *host,
if (acl_role) if (acl_role)
{ {
res= 0; res= 0;
for (i=0 ; i < acl_dbs.elements ; i++) for (i=0 ; i < acl_dbs.elements() ; i++)
{ {
ACL_DB *acl_db= dynamic_element(&acl_dbs, i, ACL_DB*); ACL_DB *acl_db= &acl_dbs.at(i);
if (!acl_db->user || if (!acl_db->user ||
(user && user[0] && !strcmp(user, acl_db->user))) (user && user[0] && !strcmp(user, acl_db->user)))
{ {
@ -2289,9 +2291,9 @@ static bool acl_update_db(const char *user, const char *host, const char *db,
bool updated= false; bool updated= false;
for (uint i=0 ; i < acl_dbs.elements ; i++) for (uint i=0 ; i < acl_dbs.elements() ; i++)
{ {
ACL_DB *acl_db=dynamic_element(&acl_dbs,i,ACL_DB*); ACL_DB *acl_db= &acl_dbs.at(i);
if ((!acl_db->user && !user[0]) || if ((!acl_db->user && !user[0]) ||
(acl_db->user && (acl_db->user &&
!strcmp(user,acl_db->user))) !strcmp(user,acl_db->user)))
@ -2310,7 +2312,7 @@ static bool acl_update_db(const char *user, const char *host, const char *db,
acl_db->initial_access= acl_db->access; acl_db->initial_access= acl_db->access;
} }
else else
delete_dynamic_element(&acl_dbs,i); acl_dbs.del(i);
updated= true; updated= true;
} }
} }
@ -2345,9 +2347,8 @@ static void acl_insert_db(const char *user, const char *host, const char *db,
acl_db.db=strdup_root(&acl_memroot,db); acl_db.db=strdup_root(&acl_memroot,db);
acl_db.initial_access= acl_db.access= privileges; acl_db.initial_access= acl_db.access= privileges;
acl_db.sort=get_sort(3,acl_db.host.hostname,acl_db.db,acl_db.user); acl_db.sort=get_sort(3,acl_db.host.hostname,acl_db.db,acl_db.user);
(void) push_dynamic(&acl_dbs,(uchar*) &acl_db); acl_dbs.push(acl_db);
my_qsort((uchar*) dynamic_element(&acl_dbs,0,ACL_DB*),acl_dbs.elements, acl_dbs.sort((acl_dbs_cmp)acl_compare);
sizeof(ACL_DB),(qsort_cmp) acl_compare);
} }
@ -2393,9 +2394,9 @@ ulong acl_get(const char *host, const char *ip,
/* /*
Check if there are some access rights for database and user Check if there are some access rights for database and user
*/ */
for (i=0 ; i < acl_dbs.elements ; i++) for (i=0 ; i < acl_dbs.elements() ; i++)
{ {
ACL_DB *acl_db=dynamic_element(&acl_dbs,i,ACL_DB*); ACL_DB *acl_db= &acl_dbs.at(i);
if (!acl_db->user || !strcmp(user,acl_db->user)) if (!acl_db->user || !strcmp(user,acl_db->user))
{ {
if (compare_hostname(&acl_db->host,host,ip)) if (compare_hostname(&acl_db->host,host,ip))
@ -5195,9 +5196,9 @@ static bool merge_role_global_privileges(ACL_ROLE *grantee)
return old != grantee->access; return old != grantee->access;
} }
static int db_name_sort(ACL_DB * const *db1, ACL_DB * const *db2) static int db_name_sort(const int *db1, const int *db2)
{ {
return strcmp((*db1)->db, (*db2)->db); return strcmp(acl_dbs.at(*db1).db, acl_dbs.at(*db2).db);
} }
/** /**
@ -5213,14 +5214,14 @@ static int db_name_sort(ACL_DB * const *db1, ACL_DB * const *db2)
2 - ACL_DB was added 2 - ACL_DB was added
4 - ACL_DB was deleted 4 - ACL_DB was deleted
*/ */
static int update_role_db(ACL_DB *merged, ACL_DB **first, ulong access, char *role) static int update_role_db(int merged, int first, ulong access, char *role)
{ {
if (!first) if (first < 0)
return 0; return 0;
DBUG_EXECUTE_IF("role_merge_stats", role_db_merges++;); DBUG_EXECUTE_IF("role_merge_stats", role_db_merges++;);
if (merged == NULL) if (merged < 0)
{ {
/* /*
there's no ACL_DB for this role (all db grants come from granted roles) there's no ACL_DB for this role (all db grants come from granted roles)
@ -5235,11 +5236,11 @@ static int update_role_db(ACL_DB *merged, ACL_DB **first, ulong access, char *ro
acl_db.user= role; acl_db.user= role;
acl_db.host.hostname= const_cast<char*>(""); acl_db.host.hostname= const_cast<char*>("");
acl_db.host.ip= acl_db.host.ip_mask= 0; acl_db.host.ip= acl_db.host.ip_mask= 0;
acl_db.db= first[0]->db; acl_db.db= acl_dbs.at(first).db;
acl_db.access= access; acl_db.access= access;
acl_db.initial_access= 0; acl_db.initial_access= 0;
acl_db.sort=get_sort(3, "", acl_db.db, role); acl_db.sort=get_sort(3, "", acl_db.db, role);
push_dynamic(&acl_dbs,(uchar*) &acl_db); acl_dbs.push(acl_db);
return 2; return 2;
} }
else if (access == 0) else if (access == 0)
@ -5255,13 +5256,13 @@ static int update_role_db(ACL_DB *merged, ACL_DB **first, ulong access, char *ro
2. it's O(N) operation, and we may need many of them 2. it's O(N) operation, and we may need many of them
so we only mark elements deleted and will delete later. so we only mark elements deleted and will delete later.
*/ */
merged->sort= 0; // lower than any valid ACL_DB sort value, will be sorted last acl_dbs.at(merged).sort= 0; // lower than any valid ACL_DB sort value, will be sorted last
return 4; return 4;
} }
else if (merged->access != access) else if (acl_dbs.at(merged).access != access)
{ {
/* this is easy */ /* this is easy */
merged->access= access; acl_dbs.at(merged).access= access;
return 1; return 1;
} }
return 0; return 0;
@ -5276,7 +5277,7 @@ static int update_role_db(ACL_DB *merged, ACL_DB **first, ulong access, char *ro
static bool merge_role_db_privileges(ACL_ROLE *grantee, const char *dbname, static bool merge_role_db_privileges(ACL_ROLE *grantee, const char *dbname,
role_hash_t *rhash) role_hash_t *rhash)
{ {
Dynamic_array<ACL_DB *> dbs; Dynamic_array<int> dbs;
/* /*
Supposedly acl_dbs can be huge, but only a handful of db grants Supposedly acl_dbs can be huge, but only a handful of db grants
@ -5284,9 +5285,9 @@ static bool merge_role_db_privileges(ACL_ROLE *grantee, const char *dbname,
Collect these applicable db grants. Collect these applicable db grants.
*/ */
for (uint i=0 ; i < acl_dbs.elements ; i++) for (uint i=0 ; i < acl_dbs.elements() ; i++)
{ {
ACL_DB *db= dynamic_element(&acl_dbs,i,ACL_DB*); ACL_DB *db= &acl_dbs.at(i);
if (db->host.hostname[0]) if (db->host.hostname[0])
continue; continue;
if (dbname && strcmp(db->db, dbname)) if (dbname && strcmp(db->db, dbname))
@ -5294,7 +5295,7 @@ static bool merge_role_db_privileges(ACL_ROLE *grantee, const char *dbname,
ACL_ROLE *r= rhash->find(db->user, strlen(db->user)); ACL_ROLE *r= rhash->find(db->user, strlen(db->user));
if (!r) if (!r)
continue; continue;
dbs.append(db); dbs.append(i);
} }
dbs.sort(db_name_sort); dbs.sort(db_name_sort);
@ -5303,21 +5304,21 @@ static bool merge_role_db_privileges(ACL_ROLE *grantee, const char *dbname,
(that should be merged) are sorted together. The grantee's ACL_DB element (that should be merged) are sorted together. The grantee's ACL_DB element
is not necessarily the first and may be not present at all. is not necessarily the first and may be not present at all.
*/ */
ACL_DB **first= NULL, *UNINIT_VAR(merged); int first= -1, merged= -1;
ulong UNINIT_VAR(access), update_flags= 0; ulong UNINIT_VAR(access), update_flags= 0;
for (ACL_DB **cur= dbs.front(); cur <= dbs.back(); cur++) for (int *p= dbs.front(); p <= dbs.back(); p++)
{ {
if (!first || (!dbname && strcmp(cur[0]->db, cur[-1]->db))) if (first<0 || (!dbname && strcmp(acl_dbs.at(*p).db, acl_dbs.at(*p-1).db)))
{ // new db name series { // new db name series
update_flags|= update_role_db(merged, first, access, grantee->user.str); update_flags|= update_role_db(merged, first, access, grantee->user.str);
merged= NULL; merged= -1;
access= 0; access= 0;
first= cur; first= *p;
} }
if (strcmp(cur[0]->user, grantee->user.str) == 0) if (strcmp(acl_dbs.at(*p).user, grantee->user.str) == 0)
access|= (merged= cur[0])->initial_access; access|= acl_dbs.at(merged= *p).initial_access;
else else
access|= cur[0]->access; access|= acl_dbs.at(*p).access;
} }
update_flags|= update_role_db(merged, first, access, grantee->user.str); update_flags|= update_role_db(merged, first, access, grantee->user.str);
@ -5330,14 +5331,12 @@ static bool merge_role_db_privileges(ACL_ROLE *grantee, const char *dbname,
*/ */
if (update_flags & (2|4)) if (update_flags & (2|4))
{ // inserted or deleted, need to sort { // inserted or deleted, need to sort
my_qsort((uchar*) dynamic_element(&acl_dbs,0,ACL_DB*),acl_dbs.elements, acl_dbs.sort((acl_dbs_cmp)acl_compare);
sizeof(ACL_DB),(qsort_cmp) acl_compare);
} }
if (update_flags & 4) if (update_flags & 4)
{ // deleted, trim the end { // deleted, trim the end
while (acl_dbs.elements && while (acl_dbs.elements() && acl_dbs.back()->sort == 0)
dynamic_element(&acl_dbs, acl_dbs.elements-1, ACL_DB*)->sort == 0) acl_dbs.pop();
acl_dbs.elements--;
} }
return update_flags; return update_flags;
} }
@ -8130,16 +8129,14 @@ static bool show_database_privileges(THD *thd, const char *username,
const char *hostname, const char *hostname,
char *buff, size_t buffsize) char *buff, size_t buffsize)
{ {
ACL_DB *acl_db;
ulong want_access; ulong want_access;
uint counter;
Protocol *protocol= thd->protocol; Protocol *protocol= thd->protocol;
for (counter=0 ; counter < acl_dbs.elements ; counter++) for (uint i=0 ; i < acl_dbs.elements() ; i++)
{ {
const char *user, *host; const char *user, *host;
acl_db=dynamic_element(&acl_dbs,counter,ACL_DB*); ACL_DB *acl_db= &acl_dbs.at(i);
user= safe_str(acl_db->user); user= safe_str(acl_db->user);
host=acl_db->host.hostname; host=acl_db->host.hostname;
@ -8958,7 +8955,7 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop,
elements= acl_users.elements; elements= acl_users.elements;
break; break;
case DB_ACL: case DB_ACL:
elements= acl_dbs.elements; elements= acl_dbs.elements();
break; break;
case COLUMN_PRIVILEGES_HASH: case COLUMN_PRIVILEGES_HASH:
grant_name_hash= &column_priv_hash; grant_name_hash= &column_priv_hash;
@ -9002,7 +8999,7 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop,
break; break;
case DB_ACL: case DB_ACL:
acl_db= dynamic_element(&acl_dbs, idx, ACL_DB*); acl_db= &acl_dbs.at(idx);
user= acl_db->user; user= acl_db->user;
host= acl_db->host.hostname; host= acl_db->host.hostname;
break; break;
@ -9086,7 +9083,7 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop,
break; break;
case DB_ACL: case DB_ACL:
delete_dynamic_element(&acl_dbs, idx); acl_dbs.del(idx);
break; break;
case COLUMN_PRIVILEGES_HASH: case COLUMN_PRIVILEGES_HASH:
@ -9850,11 +9847,11 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
*/ */
do do
{ {
for (counter= 0, revoked= 0 ; counter < acl_dbs.elements ; ) for (counter= 0, revoked= 0 ; counter < acl_dbs.elements() ; )
{ {
const char *user,*host; const char *user,*host;
acl_db=dynamic_element(&acl_dbs,counter,ACL_DB*); acl_db=&acl_dbs.at(counter);
user= safe_str(acl_db->user); user= safe_str(acl_db->user);
host= safe_str(acl_db->host.hostname); host= safe_str(acl_db->host.hostname);
@ -10467,6 +10464,14 @@ static int show_column_grants(THD *thd, SHOW_VAR *var, char *buff,
return 0; return 0;
} }
static int show_database_grants(THD *thd, SHOW_VAR *var, char *buff,
enum enum_var_type scope)
{
var->type= SHOW_UINT;
var->value= buff;
*(uint *)buff= acl_dbs.elements();
return 0;
}
#else #else
bool check_grant(THD *, ulong, TABLE_LIST *, bool, uint, bool) bool check_grant(THD *, ulong, TABLE_LIST *, bool, uint, bool)
@ -10478,7 +10483,7 @@ bool check_grant(THD *, ulong, TABLE_LIST *, bool, uint, bool)
SHOW_VAR acl_statistics[] = { SHOW_VAR acl_statistics[] = {
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
{"column_grants", (char*)show_column_grants, SHOW_SIMPLE_FUNC}, {"column_grants", (char*)show_column_grants, SHOW_SIMPLE_FUNC},
{"database_grants", (char*)&acl_dbs.elements, SHOW_UINT}, {"database_grants", (char*)show_database_grants, SHOW_SIMPLE_FUNC},
{"function_grants", (char*)&func_priv_hash.records, SHOW_ULONG}, {"function_grants", (char*)&func_priv_hash.records, SHOW_ULONG},
{"procedure_grants", (char*)&proc_priv_hash.records, SHOW_ULONG}, {"procedure_grants", (char*)&proc_priv_hash.records, SHOW_ULONG},
{"proxy_users", (char*)&acl_proxy_users.elements, SHOW_UINT}, {"proxy_users", (char*)&acl_proxy_users.elements, SHOW_UINT},
@ -10749,11 +10754,11 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
DBUG_RETURN(0); DBUG_RETURN(0);
mysql_mutex_lock(&acl_cache->lock); mysql_mutex_lock(&acl_cache->lock);
for (counter=0 ; counter < acl_dbs.elements ; counter++) for (counter=0 ; counter < acl_dbs.elements() ; counter++)
{ {
const char *user, *host, *is_grantable="YES"; const char *user, *host, *is_grantable="YES";
acl_db=dynamic_element(&acl_dbs,counter,ACL_DB*); acl_db=&acl_dbs.at(counter);
user= safe_str(acl_db->user); user= safe_str(acl_db->user);
host= safe_str(acl_db->host.hostname); host= safe_str(acl_db->host.hostname);

View File

@ -114,8 +114,7 @@ public:
void init(uint prealloc=16, uint increment=16) void init(uint prealloc=16, uint increment=16)
{ {
my_init_dynamic_array(&array, sizeof(Elem), prealloc, increment, init_dynamic_array2(&array, sizeof(Elem), 0, prealloc, increment, MYF(0));
MYF(0));
} }
/** /**
@ -208,6 +207,11 @@ public:
set_dynamic(&array, &el, idx); set_dynamic(&array, &el, idx);
} }
void freeze()
{
freeze_size(&array);
}
bool resize(size_t new_size, Elem default_val) bool resize(size_t new_size, Elem default_val)
{ {
size_t old_size= elements(); size_t old_size= elements();
@ -230,6 +234,11 @@ public:
delete_dynamic(&array); delete_dynamic(&array);
} }
void free_memory()
{
delete_dynamic(&array);
}
typedef int (*CMP_FUNC)(const Elem *el1, const Elem *el2); typedef int (*CMP_FUNC)(const Elem *el1, const Elem *el2);
void sort(CMP_FUNC cmp_func) void sort(CMP_FUNC cmp_func)
@ -237,7 +246,7 @@ public:
my_qsort(array.buffer, array.elements, sizeof(Elem), (qsort_cmp)cmp_func); my_qsort(array.buffer, array.elements, sizeof(Elem), (qsort_cmp)cmp_func);
} }
typedef int (*CMP_FUNC2)(const Elem *el1, const Elem *el2, void *); typedef int (*CMP_FUNC2)(void *, const Elem *el1, const Elem *el2);
void sort(CMP_FUNC2 cmp_func, void *data) void sort(CMP_FUNC2 cmp_func, void *data)
{ {
my_qsort2(array.buffer, array.elements, sizeof(Elem), (qsort2_cmp)cmp_func, data); my_qsort2(array.buffer, array.elements, sizeof(Elem), (qsort2_cmp)cmp_func, data);