1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

Merge 10.3 into 10.4

This commit is contained in:
Marko Mäkelä
2018-12-07 16:12:17 +02:00
16 changed files with 217 additions and 111 deletions

View File

@ -251,11 +251,8 @@ let $wait_condition =
--echo --echo
--echo # -- Waiting for connections to close... --echo # -- Waiting for connections to close...
let $wait_condition = let $count_sessions=1;
SELECT COUNT(*) = 1 --source include/wait_until_count_sessions.inc
FROM information_schema.processlist
WHERE db = 'test';
--source include/wait_condition.inc
--echo --echo
DROP USER mysqltest_u1@localhost; DROP USER mysqltest_u1@localhost;

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

@ -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

@ -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

@ -12,3 +12,4 @@
innodb_scrub : MDEV-8139 scrubbing does not work reliably innodb_scrub : MDEV-8139 scrubbing does not work reliably
innodb_scrub_background : MDEV-8139 scrubbing does not work reliably innodb_scrub_background : MDEV-8139 scrubbing does not work reliably
innodb-redo-badkey : MDEV-13893/MDEV-12699 fix recovery of corrupted pages

View File

@ -162,3 +162,19 @@ SELECT len,COUNT(*) FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS where name='word'
len COUNT(*) len COUNT(*)
84 6 84 6
DROP TABLE t; DROP TABLE t;
#
# MDEV-17923 Assertion memcmp(field, field_ref_zero, 7) failed in
# trx_undo_page_report_modify upon optimizing table
# under innodb_optimize_fulltext_only
#
CREATE TABLE t1 (f1 TEXT, f2 TEXT, FULLTEXT KEY (f2)) ENGINE=InnoDB;
INSERT INTO t1 (f1) VALUES ('foo'),('bar');
DELETE FROM t1 LIMIT 1;
ALTER TABLE t1 ADD FULLTEXT KEY (f1);
SET @optimize_fulltext.save= @@innodb_optimize_fulltext_only;
SET GLOBAL innodb_optimize_fulltext_only= 1;
OPTIMIZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
DROP TABLE t1;
SET GLOBAL innodb_optimize_fulltext_only= @optimize_fulltext.save;

View File

@ -90,3 +90,19 @@ ENGINE=InnoDB;
# The column length should be 84 bytes (84 characters * 1 byte/character). # The column length should be 84 bytes (84 characters * 1 byte/character).
SELECT len,COUNT(*) FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS where name='word' GROUP BY len; SELECT len,COUNT(*) FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS where name='word' GROUP BY len;
DROP TABLE t; DROP TABLE t;
--echo #
--echo # MDEV-17923 Assertion memcmp(field, field_ref_zero, 7) failed in
--echo # trx_undo_page_report_modify upon optimizing table
--echo # under innodb_optimize_fulltext_only
--echo #
CREATE TABLE t1 (f1 TEXT, f2 TEXT, FULLTEXT KEY (f2)) ENGINE=InnoDB;
INSERT INTO t1 (f1) VALUES ('foo'),('bar');
DELETE FROM t1 LIMIT 1;
ALTER TABLE t1 ADD FULLTEXT KEY (f1);
SET @optimize_fulltext.save= @@innodb_optimize_fulltext_only;
SET GLOBAL innodb_optimize_fulltext_only= 1;
OPTIMIZE TABLE t1;
DROP TABLE t1;
SET GLOBAL innodb_optimize_fulltext_only= @optimize_fulltext.save;

View File

@ -167,19 +167,6 @@ connection default;
# 6.1 Verify that there are no TCP/IP connections in the socket instance table # 6.1 Verify that there are no TCP/IP connections in the socket instance table
SELECT COUNT(*) = 0 AS 'Expect 1'
FROM performance_schema.socket_instances
WHERE EVENT_NAME LIKE '%client_connection%'
AND OBJECT_INSTANCE_BEGIN <> @default_object_instance_begin
AND (IP LIKE '%127.0.0.1' OR IP LIKE '%::1');
Expect 1
1
# 6.2 Verify that there are no TCP/IP connections in the summary instance table # 6.2 Verify that there are no TCP/IP connections in the summary instance table
SELECT COUNT(*) = 0 AS 'Expect 1'
FROM performance_schema.socket_summary_by_instance
WHERE EVENT_NAME LIKE '%client_connection%'
AND OBJECT_INSTANCE_BEGIN <> @default_object_instance_begin;
Expect 1
1

View File

@ -273,18 +273,21 @@ WHERE EVENT_NAME LIKE '%client_connection%'
--echo --echo
--echo # 6.1 Verify that there are no TCP/IP connections in the socket instance table --echo # 6.1 Verify that there are no TCP/IP connections in the socket instance table
--echo --echo
eval SELECT COUNT(*) = 0 AS 'Expect 1' let $wait_condition=
SELECT COUNT(*) = 0 AS 'Expect 1'
FROM performance_schema.socket_instances FROM performance_schema.socket_instances
WHERE EVENT_NAME LIKE '%client_connection%' WHERE EVENT_NAME LIKE '%client_connection%'
AND OBJECT_INSTANCE_BEGIN <> @default_object_instance_begin AND OBJECT_INSTANCE_BEGIN <> @default_object_instance_begin
AND $ip_localhost; AND $ip_localhost;
--source include/wait_condition.inc
--echo --echo
--echo # 6.2 Verify that there are no TCP/IP connections in the summary instance table --echo # 6.2 Verify that there are no TCP/IP connections in the summary instance table
--echo --echo
eval SELECT COUNT(*) = 0 AS 'Expect 1' let $wait_condition=
SELECT COUNT(*) = 0 AS 'Expect 1'
FROM performance_schema.socket_summary_by_instance FROM performance_schema.socket_summary_by_instance
WHERE EVENT_NAME LIKE '%client_connection%' WHERE EVENT_NAME LIKE '%client_connection%'
AND OBJECT_INSTANCE_BEGIN <> @default_object_instance_begin; AND OBJECT_INSTANCE_BEGIN <> @default_object_instance_begin;
--source include/wait_condition.inc
exit; exit;

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 ignore 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 ignore 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

@ -2869,7 +2869,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

@ -596,7 +596,9 @@ bool ROLE_GRANT_PAIR::init(MEM_ROOT *mem, const 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
@ -2043,11 +2045,11 @@ static bool acl_load(THD *thd, const Grant_tables& 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);
} }
rebuild_acl_dbs();
end_read_record(&read_record_info); end_read_record(&read_record_info);
freeze_size(&acl_dbs); rebuild_acl_dbs();
acl_dbs.freeze();
const Proxies_priv_table& proxies_priv_table= tables.proxies_priv_table(); const Proxies_priv_table& proxies_priv_table= tables.proxies_priv_table();
if (proxies_priv_table.table_exists()) if (proxies_priv_table.table_exists())
@ -2126,7 +2128,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);
@ -2164,7 +2166,8 @@ void acl_free(bool end)
bool acl_reload(THD *thd) bool acl_reload(THD *thd)
{ {
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;
@ -2200,7 +2203,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,
@ -2221,6 +2224,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();
} }
@ -2231,7 +2235,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);
@ -2369,8 +2372,7 @@ static void rebuild_acl_users()
static void rebuild_acl_dbs() static void rebuild_acl_dbs()
{ {
my_qsort((uchar*)dynamic_element(&acl_dbs, 0, ACL_DB*), acl_dbs.elements, acl_dbs.sort(acl_db_compare);
sizeof(ACL_DB), (qsort_cmp)acl_db_compare);
} }
@ -2416,7 +2418,7 @@ static uint acl_find_user_by_name(const char *user)
static uint acl_find_db_by_username(const char *user) static uint acl_find_db_by_username(const char *user)
{ {
return find_first_user<ACL_DB>((ACL_DB *)acl_dbs.buffer, acl_dbs.elements, user); return find_first_user<ACL_DB>(acl_dbs.front(), acl_dbs.elements(), user);
} }
static bool match_db(ACL_DB *acl_db, const char *db, my_bool db_is_pattern) static bool match_db(ACL_DB *acl_db, const char *db, my_bool db_is_pattern)
@ -2437,17 +2439,15 @@ static bool match_db(ACL_DB *acl_db, const char *db, my_bool db_is_pattern)
This function uses optimizations (binary search by username), yet preserves the This function uses optimizations (binary search by username), yet preserves the
historical behavior, i.e the returns a match with highest ACL_ENTRY::sort. historical behavior, i.e the returns a match with highest ACL_ENTRY::sort.
*/ */
template <typename T> T* find_by_username_or_anon(DYNAMIC_ARRAY *dynarray, const char *user, template <typename T> T* find_by_username_or_anon(T* arr, size_t len, const char *user,
const char *host, const char *ip, const char *host, const char *ip,
const char *db, my_bool db_is_pattern, bool (*match_db_func)(T*,const char *,my_bool)) const char *db, my_bool db_is_pattern, bool (*match_db_func)(T*,const char *,my_bool))
{ {
uint i; size_t i;
T *ret = NULL; T *ret = NULL;
T* arr= (T*)dynarray->buffer;
uint len= dynarray->elements;
// Check entries matching user name. // Check entries matching user name.
uint start = find_first_user(arr, len, user); size_t start = find_first_user(arr, len, user);
for (i= start; i < len; i++) for (i= start; i < len; i++)
{ {
T *entry= &arr[i]; T *entry= &arr[i];
@ -2479,7 +2479,8 @@ template <typename T> T* find_by_username_or_anon(DYNAMIC_ARRAY *dynarray, const
static ACL_DB *acl_db_find(const char *db, const char *user, const char *host, const char *ip, my_bool db_is_pattern) static ACL_DB *acl_db_find(const char *db, const char *user, const char *host, const char *ip, my_bool db_is_pattern)
{ {
return find_by_username_or_anon<ACL_DB>(&acl_dbs, user, host, ip, db, db_is_pattern, match_db); return find_by_username_or_anon(acl_dbs.front(), acl_dbs.elements(),
user, host, ip, db, db_is_pattern, match_db);
} }
@ -2535,8 +2536,7 @@ bool acl_getroot(Security_context *sctx, const char *user, const char *host,
if (acl_user) if (acl_user)
{ {
res= 0; res= 0;
ACL_DB *acl_db= acl_db_find(db, user, host, ip, FALSE); if (ACL_DB *acl_db= acl_db_find(db, user, host, ip, FALSE))
if(acl_db)
sctx->db_access= acl_db->access; sctx->db_access= acl_db->access;
sctx->master_access= acl_user->access; sctx->master_access= acl_user->access;
@ -2553,8 +2553,7 @@ bool acl_getroot(Security_context *sctx, const char *user, const char *host,
if (acl_role) if (acl_role)
{ {
res= 0; res= 0;
ACL_DB *acl_db = acl_db_find(db, user, "", "", FALSE); if (ACL_DB *acl_db= acl_db_find(db, user, "", "", FALSE))
if (acl_db)
sctx->db_access = acl_db->access; sctx->db_access = acl_db->access;
sctx->master_access= acl_role->access; sctx->master_access= acl_role->access;
@ -2755,9 +2754,9 @@ static bool acl_update_db(const char *user, const char *host, const char *db,
bool updated= false; bool updated= false;
for (uint i=acl_find_db_by_username(user) ; i < acl_dbs.elements ; i++) for (uint i= acl_find_db_by_username(user); 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 (!strcmp(user,acl_db->user)) if (!strcmp(user,acl_db->user))
{ {
if ((!acl_db->host.hostname && !host[0]) || if ((!acl_db->host.hostname && !host[0]) ||
@ -2773,7 +2772,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;
} }
} }
@ -2810,7 +2809,7 @@ 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);
rebuild_acl_dbs(); rebuild_acl_dbs();
} }
@ -2857,9 +2856,7 @@ 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
*/ */
ACL_DB *acl_db = acl_db_find(db,user, host, ip, db_is_pattern); if (ACL_DB *acl_db= acl_db_find(db,user, host, ip, db_is_pattern))
if (acl_db)
{ {
db_access= acl_db->access; db_access= acl_db->access;
if (acl_db->host.hostname) if (acl_db->host.hostname)
@ -3523,7 +3520,9 @@ bool is_acl_user(const char *host, const char *user)
*/ */
static ACL_USER *find_user_or_anon(const char *host, const char *user, const char *ip) static ACL_USER *find_user_or_anon(const char *host, const char *user, const char *ip)
{ {
return find_by_username_or_anon<ACL_USER>(&acl_users,user,host, ip, 0, false, 0); return find_by_username_or_anon<ACL_USER>
(reinterpret_cast<ACL_USER*>(acl_users.buffer), acl_users.elements,
user, host, ip, NULL, FALSE, NULL);
} }
@ -5674,15 +5673,15 @@ 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);
} }
/** /**
update ACL_DB for given database and a given role with merged privileges update ACL_DB for given database and a given role with merged privileges
@param merged ACL_DB of the role in question (or NULL if it wasn't found) @param merged ACL_DB of the role in question (or -1 if it wasn't found)
@param first first ACL_DB in an array for the database in question @param first first ACL_DB in an array for the database in question
@param access new privileges for the given role on the gived database @param access new privileges for the given role on the gived database
@param role the name of the given role @param role the name of the given role
@ -5692,15 +5691,15 @@ 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, static int update_role_db(int merged, int first, ulong access,
const char *role) const 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)
@ -5715,11 +5714,11 @@ static int update_role_db(ACL_DB *merged, ACL_DB **first, ulong access,
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)
@ -5735,13 +5734,13 @@ static int update_role_db(ACL_DB *merged, ACL_DB **first, ulong access,
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; // mark for deletion 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;
@ -5756,7 +5755,7 @@ static int update_role_db(ACL_DB *merged, ACL_DB **first, ulong access,
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
@ -5764,9 +5763,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))
@ -5774,7 +5773,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);
@ -5783,21 +5782,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, *merged= NULL; int first= -1, merged= -1;
ulong access= 0, update_flags= 0; ulong access= 0, 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);
@ -5805,17 +5804,17 @@ static bool merge_role_db_privileges(ACL_ROLE *grantee, const char *dbname,
{ {
// Remove elements marked for deletion. // Remove elements marked for deletion.
uint count= 0; uint count= 0;
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->sort) if (acl_db->sort)
{ {
if (i > count) if (i > count)
set_dynamic(&acl_dbs, acl_db, count); acl_dbs.set(count, *acl_db);
count++; count++;
} }
} }
acl_dbs.elements= count; acl_dbs.elements(count);
} }
@ -8770,16 +8769,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= acl_db->user; user= acl_db->user;
host=acl_db->host.hostname; host=acl_db->host.hostname;
@ -9534,7 +9531,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;
@ -9586,7 +9583,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;
@ -9670,7 +9667,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:
@ -10565,11 +10562,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= acl_db->user; user= acl_db->user;
host= safe_str(acl_db->host.hostname); host= safe_str(acl_db->host.hostname);
@ -11172,6 +11169,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)
@ -11183,7 +11188,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},
{"package_spec_grants", (char*)&package_spec_priv_hash.records, SHOW_ULONG}, {"package_spec_grants", (char*)&package_spec_priv_hash.records, SHOW_ULONG},
@ -11456,11 +11461,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= acl_db->user; user= acl_db->user;
host= safe_str(acl_db->host.hostname); host= safe_str(acl_db->host.hostname);

View File

@ -123,8 +123,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));
} }
/** /**
@ -218,6 +217,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();
@ -252,7 +256,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);

View File

@ -11076,9 +11076,6 @@ err_col:
case DB_SUCCESS: case DB_SUCCESS:
ut_ad(table); ut_ad(table);
m_table = table; m_table = table;
if (m_flags2 & DICT_TF2_FTS) {
fts_optimize_add_table(table);
}
DBUG_RETURN(0); DBUG_RETURN(0);
default: default:
break; break;
@ -11097,7 +11094,8 @@ err_col:
: ER_TABLESPACE_EXISTS, MYF(0), display_name); : ER_TABLESPACE_EXISTS, MYF(0), display_name);
} }
DBUG_RETURN(convert_error_code_to_mysql(err, m_flags, m_thd));} DBUG_RETURN(convert_error_code_to_mysql(err, m_flags, m_thd));
}
/*****************************************************************//** /*****************************************************************//**
Creates an index in an InnoDB database. */ Creates an index in an InnoDB database. */
@ -12485,6 +12483,10 @@ create_table_info_t::create_table_update_dict()
trx_free(m_trx); trx_free(m_trx);
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
mutex_enter(&dict_sys->mutex);
fts_optimize_add_table(innobase_table);
mutex_exit(&dict_sys->mutex);
} }
if (const Field* ai = m_form->found_next_number_field) { if (const Field* ai = m_form->found_next_number_field) {

View File

@ -1579,9 +1579,6 @@ row_fts_merge_insert(
dict_table_t* aux_table; dict_table_t* aux_table;
dict_index_t* aux_index; dict_index_t* aux_index;
trx_t* trx; trx_t* trx;
byte trx_id_buf[6];
roll_ptr_t roll_ptr = 0;
dfield_t* field;
ut_ad(index); ut_ad(index);
ut_ad(table); ut_ad(table);
@ -1692,16 +1689,13 @@ row_fts_merge_insert(
dict_index_get_n_fields(aux_index)); dict_index_get_n_fields(aux_index));
/* Set TRX_ID and ROLL_PTR */ /* Set TRX_ID and ROLL_PTR */
trx_write_trx_id(trx_id_buf, trx->id); dfield_set_data(dtuple_get_nth_field(ins_ctx.tuple, 2),
field = dtuple_get_nth_field(ins_ctx.tuple, 2); &reset_trx_id, DATA_TRX_ID_LEN);
dfield_set_data(field, &trx_id_buf, 6); dfield_set_data(dtuple_get_nth_field(ins_ctx.tuple, 3),
&reset_trx_id[DATA_TRX_ID_LEN], DATA_ROLL_PTR_LEN);
field = dtuple_get_nth_field(ins_ctx.tuple, 3); ut_d(ins_ctx.aux_index_id = id);
dfield_set_data(field, &roll_ptr, 7);
#ifdef UNIV_DEBUG
ins_ctx.aux_index_id = id;
#endif
const ulint space = table->space_id; const ulint space = table->space_id;
for (i = 0; i < fts_sort_pll_degree; i++) { for (i = 0; i < fts_sort_pll_degree; i++) {