summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <jani@a88-113-38-195.elisa-laajakaista.fi>2007-08-24 15:25:02 +0300
committerunknown <jani@a88-113-38-195.elisa-laajakaista.fi>2007-08-24 15:25:02 +0300
commitc2d5b26a3c8f85be0421f3746efe2076962dc31b (patch)
tree2bc061d38daf95dca21edfb85cf19f6fb4778c54
parent7a60e167195674197de58af78bd19acef90bb6f7 (diff)
parent0aefd73b3dda1705270fb756329c32e10e1cc476 (diff)
downloadmariadb-git-c2d5b26a3c8f85be0421f3746efe2076962dc31b.tar.gz
Merge a88-113-38-195.elisa-laajakaista.fi:/home/my/bk/mysql-5.1-main
into a88-113-38-195.elisa-laajakaista.fi:/home/my/bk/mysql-5.1-marvel libmysql/libmysql.c: Auto merged mysql-test/r/query_cache.result: Auto merged mysql-test/t/query_cache.test: Auto merged sql/ha_partition.cc: Auto merged sql/ha_partition.h: Auto merged sql/handler.cc: Auto merged sql/item.cc: Auto merged sql/item_cmpfunc.h: Auto merged sql/opt_range.cc: Auto merged sql/sql_lex.cc: Auto merged sql/sql_select.cc: Auto merged sql/sql_show.cc: Auto merged tests/mysql_client_test.c: Auto merged
-rw-r--r--libmysql/libmysql.c10
-rw-r--r--mysql-test/include/mix1.inc30
-rw-r--r--mysql-test/r/information_schema.result26
-rw-r--r--mysql-test/r/information_schema_db.result2
-rw-r--r--mysql-test/r/innodb_mysql.result18
-rw-r--r--mysql-test/r/partition_pruning.result4
-rw-r--r--mysql-test/r/select.result57
-rw-r--r--mysql-test/t/information_schema.test25
-rw-r--r--mysql-test/t/select.test60
-rw-r--r--sql/ha_partition.cc37
-rw-r--r--sql/ha_partition.h1
-rw-r--r--sql/handler.cc3
-rw-r--r--sql/item.cc2
-rw-r--r--sql/item_cmpfunc.h1
-rw-r--r--sql/opt_range.cc3
-rw-r--r--sql/sql_base.cc1
-rw-r--r--sql/sql_cache.cc37
-rw-r--r--sql/sql_lex.cc1
-rw-r--r--sql/sql_lex.h3
-rw-r--r--sql/sql_select.cc56
-rw-r--r--sql/sql_show.cc12
-rw-r--r--sql/sql_view.cc6
-rw-r--r--tests/mysql_client_test.c73
23 files changed, 402 insertions, 66 deletions
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index bf082ea8f31..c8e2d48873f 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -4676,9 +4676,17 @@ int cli_read_binary_rows(MYSQL_STMT *stmt)
MYSQL *mysql= stmt->mysql;
MYSQL_DATA *result= &stmt->result;
MYSQL_ROWS *cur, **prev_ptr= &result->data;
- NET *net = &mysql->net;
+ NET *net;
+
+ if (!mysql)
+ {
+ set_stmt_error(stmt, CR_SERVER_LOST, unknown_sqlstate);
+ return 1;
+ }
+
DBUG_ENTER("cli_read_binary_rows");
+ net = &mysql->net;
mysql= mysql->last_used_con;
while ((pkt_len= cli_safe_read(mysql)) != packet_error)
diff --git a/mysql-test/include/mix1.inc b/mysql-test/include/mix1.inc
index 32a3e6b3ebd..5e6a535fce5 100644
--- a/mysql-test/include/mix1.inc
+++ b/mysql-test/include/mix1.inc
@@ -939,6 +939,36 @@ alter table t1 add index(a(1024));
show create table t1;
drop table t1;
+#
+# Bug #28570: handler::index_read() is called with different find_flag when
+# ORDER BY is used
+#
+
+CREATE TABLE t1 (
+ a INT,
+ b INT,
+ KEY (b)
+) ENGINE=InnoDB;
+
+INSERT INTO t1 VALUES (1,10), (2,10), (2,20), (3,30);
+
+START TRANSACTION;
+SELECT * FROM t1 WHERE b=20 FOR UPDATE;
+
+--connect (conn2, localhost, root,,test)
+
+# This statement gives a "failed: 1205: Lock wait timeout exceeded; try
+# restarting transaction" message when the bug is present.
+START TRANSACTION;
+SELECT * FROM t1 WHERE b=10 ORDER BY A FOR UPDATE;
+ROLLBACK;
+
+--disconnect conn2
+--connection default
+
+ROLLBACK;
+DROP TABLE t1;
+
--echo End of 5.0 tests
# Fix for BUG#19243 "wrong LAST_INSERT_ID() after ON DUPLICATE KEY
diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result
index f81277b1ff9..e87b46ac90f 100644
--- a/mysql-test/r/information_schema.result
+++ b/mysql-test/r/information_schema.result
@@ -196,7 +196,6 @@ t1 a select
show columns from mysqltest.t1;
Field Type Null Key Default Extra
a int(11) YES NULL
-b varchar(30) YES MUL NULL
select table_name, column_name, privileges from information_schema.columns
where table_schema = 'mysqltest' and table_name = 'v1';
table_name column_name privileges
@@ -1410,6 +1409,31 @@ alter database;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
alter database test;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
+create database mysqltest;
+create table mysqltest.t1(a int, b int, c int);
+create trigger mysqltest.t1_ai after insert on mysqltest.t1
+for each row set @a = new.a + new.b + new.c;
+grant select(b) on mysqltest.t1 to mysqltest_1@localhost;
+select trigger_name from information_schema.triggers
+where event_object_table='t1';
+trigger_name
+t1_ai
+show triggers from mysqltest;
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+t1_ai INSERT t1 set @a = new.a + new.b + new.c AFTER NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci
+show columns from t1;
+Field Type Null Key Default Extra
+b int(11) YES NULL
+select column_name from information_schema.columns where table_name='t1';
+column_name
+b
+show triggers;
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+select trigger_name from information_schema.triggers
+where event_object_table='t1';
+trigger_name
+drop user mysqltest_1@localhost;
+drop database mysqltest;
End of 5.0 tests.
select * from information_schema.engines WHERE ENGINE="MyISAM";
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
diff --git a/mysql-test/r/information_schema_db.result b/mysql-test/r/information_schema_db.result
index e5a5a583de3..51f7694ab68 100644
--- a/mysql-test/r/information_schema_db.result
+++ b/mysql-test/r/information_schema_db.result
@@ -151,13 +151,11 @@ create view v2 as select f1 from testdb_1.v1;
create view v4 as select f1,f2 from testdb_1.v3;
show fields from testdb_1.v5;
Field Type Null Key Default Extra
-f1 char(4) YES NULL
show create view testdb_1.v5;
View Create View character_set_client collation_connection
v5 CREATE ALGORITHM=UNDEFINED DEFINER=`testdb_1`@`localhost` SQL SECURITY DEFINER VIEW `testdb_1`.`v5` AS select `testdb_1`.`t1`.`f1` AS `f1` from `testdb_1`.`t1` latin1 latin1_swedish_ci
show fields from testdb_1.v6;
Field Type Null Key Default Extra
-f1 char(4) YES NULL
show create view testdb_1.v6;
View Create View character_set_client collation_connection
v6 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `testdb_1`.`v6` AS select `testdb_1`.`t1`.`f1` AS `f1` from `testdb_1`.`t1` latin1 latin1_swedish_ci
diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result
index ae442acd1b9..32c692501ad 100644
--- a/mysql-test/r/innodb_mysql.result
+++ b/mysql-test/r/innodb_mysql.result
@@ -1123,6 +1123,24 @@ t1 CREATE TABLE `t1` (
KEY `a` (`a`(255))
) ENGINE=InnoDB DEFAULT CHARSET=utf8
drop table t1;
+CREATE TABLE t1 (
+a INT,
+b INT,
+KEY (b)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1,10), (2,10), (2,20), (3,30);
+START TRANSACTION;
+SELECT * FROM t1 WHERE b=20 FOR UPDATE;
+a b
+2 20
+START TRANSACTION;
+SELECT * FROM t1 WHERE b=10 ORDER BY A FOR UPDATE;
+a b
+1 10
+2 10
+ROLLBACK;
+ROLLBACK;
+DROP TABLE t1;
End of 5.0 tests
CREATE TABLE `t2` (
`k` int(11) NOT NULL auto_increment,
diff --git a/mysql-test/r/partition_pruning.result b/mysql-test/r/partition_pruning.result
index 9595676016c..776e6f3a15a 100644
--- a/mysql-test/r/partition_pruning.result
+++ b/mysql-test/r/partition_pruning.result
@@ -631,7 +631,7 @@ flush status;
delete from t2 where b > 5;
show status like 'Handler_read_rnd_next';
Variable_name Value
-Handler_read_rnd_next 1215
+Handler_read_rnd_next 1115
show status like 'Handler_read_key';
Variable_name Value
Handler_read_key 0
@@ -645,7 +645,7 @@ flush status;
delete from t2 where b < 5 or b > 3;
show status like 'Handler_read_rnd_next';
Variable_name Value
-Handler_read_rnd_next 1215
+Handler_read_rnd_next 1115
show status like 'Handler_read_key';
Variable_name Value
Handler_read_key 0
diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result
index 1ebed6d17d5..48e8bf933e1 100644
--- a/mysql-test/r/select.result
+++ b/mysql-test/r/select.result
@@ -3990,4 +3990,61 @@ id select_type table type possible_keys key key_len ref rows Extra
EXPLAIN SELECT c1 FROM t1 WHERE (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT COUNT(c2))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) > 0;
ERROR HY000: Too high level of nesting for select
DROP TABLE t1;
+CREATE TABLE t1 (
+c1 int(11) NOT NULL AUTO_INCREMENT,
+c2 varchar(1000) DEFAULT NULL,
+c3 bigint(20) DEFAULT NULL,
+c4 bigint(20) DEFAULT NULL,
+PRIMARY KEY (c1)
+);
+EXPLAIN EXTENDED
+SELECT join_2.c1
+FROM
+t1 AS join_0,
+t1 AS join_1,
+t1 AS join_2,
+t1 AS join_3,
+t1 AS join_4,
+t1 AS join_5,
+t1 AS join_6,
+t1 AS join_7
+WHERE
+join_0.c1=join_1.c1 AND
+join_1.c1=join_2.c1 AND
+join_2.c1=join_3.c1 AND
+join_3.c1=join_4.c1 AND
+join_4.c1=join_5.c1 AND
+join_5.c1=join_6.c1 AND
+join_6.c1=join_7.c1
+OR
+join_0.c2 < '?' AND
+join_1.c2 < '?' AND
+join_2.c2 > '?' AND
+join_2.c2 < '!' AND
+join_3.c2 > '?' AND
+join_4.c2 = '?' AND
+join_5.c2 <> '?' AND
+join_6.c2 <> '?' AND
+join_7.c2 >= '?' AND
+join_0.c1=join_1.c1 AND
+join_1.c1=join_2.c1 AND
+join_2.c1=join_3.c1 AND
+join_3.c1=join_4.c1 AND
+join_4.c1=join_5.c1 AND
+join_5.c1=join_6.c1 AND
+join_6.c1=join_7.c1
+GROUP BY
+join_3.c1,
+join_2.c1,
+join_7.c1,
+join_1.c1,
+join_0.c1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+Warnings:
+Note 1003 select '0' AS `c1` from `test`.`t1` `join_0` join `test`.`t1` `join_1` join `test`.`t1` `join_2` join `test`.`t1` `join_3` join `test`.`t1` `join_4` join `test`.`t1` `join_5` join `test`.`t1` `join_6` join `test`.`t1` `join_7` where 0 group by '0','0','0','0','0'
+SHOW WARNINGS;
+Level Code Message
+Note 1003 select '0' AS `c1` from `test`.`t1` `join_0` join `test`.`t1` `join_1` join `test`.`t1` `join_2` join `test`.`t1` `join_3` join `test`.`t1` `join_4` join `test`.`t1` `join_5` join `test`.`t1` `join_6` join `test`.`t1` `join_7` where 0 group by '0','0','0','0','0'
+DROP TABLE t1;
End of 5.0 tests
diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test
index 774e75a79fa..40c87c40c12 100644
--- a/mysql-test/t/information_schema.test
+++ b/mysql-test/t/information_schema.test
@@ -1047,6 +1047,31 @@ alter database;
--error ER_PARSE_ERROR
alter database test;
+#
+# Bug#27629 Possible security flaw in INFORMATION_SCHEMA and SHOW statements
+#
+
+create database mysqltest;
+create table mysqltest.t1(a int, b int, c int);
+create trigger mysqltest.t1_ai after insert on mysqltest.t1
+ for each row set @a = new.a + new.b + new.c;
+grant select(b) on mysqltest.t1 to mysqltest_1@localhost;
+
+select trigger_name from information_schema.triggers
+where event_object_table='t1';
+show triggers from mysqltest;
+
+connect (con27629,localhost,mysqltest_1,,mysqltest);
+show columns from t1;
+select column_name from information_schema.columns where table_name='t1';
+
+show triggers;
+select trigger_name from information_schema.triggers
+where event_object_table='t1';
+connection default;
+drop user mysqltest_1@localhost;
+drop database mysqltest;
+
--echo End of 5.0 tests.
#
# Show engines
diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test
index b513d17bfa0..3f17eb92d40 100644
--- a/mysql-test/t/select.test
+++ b/mysql-test/t/select.test
@@ -3389,4 +3389,64 @@ eval EXPLAIN SELECT c1 FROM t1 WHERE $q > 0;
DROP TABLE t1;
+#
+# Bug #30396: crash for a join with equalities and sargable predicates
+# in disjunctive parts of the WHERE condition
+#
+
+CREATE TABLE t1 (
+ c1 int(11) NOT NULL AUTO_INCREMENT,
+ c2 varchar(1000) DEFAULT NULL,
+ c3 bigint(20) DEFAULT NULL,
+ c4 bigint(20) DEFAULT NULL,
+ PRIMARY KEY (c1)
+);
+
+EXPLAIN EXTENDED
+SELECT join_2.c1
+FROM
+ t1 AS join_0,
+ t1 AS join_1,
+ t1 AS join_2,
+ t1 AS join_3,
+ t1 AS join_4,
+ t1 AS join_5,
+ t1 AS join_6,
+ t1 AS join_7
+WHERE
+ join_0.c1=join_1.c1 AND
+ join_1.c1=join_2.c1 AND
+ join_2.c1=join_3.c1 AND
+ join_3.c1=join_4.c1 AND
+ join_4.c1=join_5.c1 AND
+ join_5.c1=join_6.c1 AND
+ join_6.c1=join_7.c1
+ OR
+ join_0.c2 < '?' AND
+ join_1.c2 < '?' AND
+ join_2.c2 > '?' AND
+ join_2.c2 < '!' AND
+ join_3.c2 > '?' AND
+ join_4.c2 = '?' AND
+ join_5.c2 <> '?' AND
+ join_6.c2 <> '?' AND
+ join_7.c2 >= '?' AND
+ join_0.c1=join_1.c1 AND
+ join_1.c1=join_2.c1 AND
+ join_2.c1=join_3.c1 AND
+ join_3.c1=join_4.c1 AND
+ join_4.c1=join_5.c1 AND
+ join_5.c1=join_6.c1 AND
+ join_6.c1=join_7.c1
+GROUP BY
+ join_3.c1,
+ join_2.c1,
+ join_7.c1,
+ join_1.c1,
+ join_0.c1;
+
+SHOW WARNINGS;
+
+DROP TABLE t1;
+
--echo End of 5.0 tests
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 6521be1cb9a..bff94da63bb 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -2676,6 +2676,7 @@ int ha_partition::write_row(uchar * buf)
uint32 part_id;
int error;
longlong func_value;
+ bool autoincrement_lock= false;
#ifdef NOT_NEEDED
uchar *rec0= m_rec0;
#endif
@@ -2691,7 +2692,21 @@ int ha_partition::write_row(uchar * buf)
or a new row, then update the auto_increment value in the record.
*/
if (table->next_number_field && buf == table->record[0])
+ {
+ /*
+ Some engines (InnoDB for example) can change autoincrement
+ counter only after 'table->write_row' operation.
+ So if another thread gets inside the ha_partition::write_row
+ before it is complete, it gets same auto_increment value,
+ which means DUP_KEY error (bug #27405)
+ Here we separate the access using table_share->mutex, and
+ use autoincrement_lock variable to avoid unnecessary locks.
+ Probably not an ideal solution.
+ */
+ autoincrement_lock= true;
+ pthread_mutex_lock(&table_share->mutex);
update_auto_increment();
+ }
my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
#ifdef NOT_NEEDED
@@ -2712,11 +2727,15 @@ int ha_partition::write_row(uchar * buf)
if (unlikely(error))
{
m_part_info->err_value= func_value;
- DBUG_RETURN(error);
+ goto exit;
}
m_last_part= part_id;
DBUG_PRINT("info", ("Insert in partition %d", part_id));
- DBUG_RETURN(m_file[part_id]->write_row(buf));
+ error= m_file[part_id]->write_row(buf);
+exit:
+ if (autoincrement_lock)
+ pthread_mutex_unlock(&table_share->mutex);
+ DBUG_RETURN(error);
}
@@ -3216,9 +3235,14 @@ end_dont_reset_start_part:
void ha_partition::position(const uchar *record)
{
- handler *file= m_file[m_last_part];
+ handler *file;
DBUG_ENTER("ha_partition::position");
+ if (unlikely(get_part_for_delete(record, m_rec0, m_part_info, &m_last_part)))
+ m_last_part= 0;
+
+ file= m_file[m_last_part];
+
file->position(record);
int2store(ref, m_last_part);
memcpy((ref + PARTITION_BYTES_IN_POS), file->ref,
@@ -5568,6 +5592,13 @@ int ha_partition::indexes_are_disabled(void)
}
+void ha_partition::column_bitmaps_signal()
+{
+ handler::column_bitmaps_signal();
+ bitmap_union(table->read_set, &m_part_info->full_part_field_set);
+}
+
+
/****************************************************************************
MODULE Partition Share
****************************************************************************/
diff --git a/sql/ha_partition.h b/sql/ha_partition.h
index 555f7a72740..434d90a4487 100644
--- a/sql/ha_partition.h
+++ b/sql/ha_partition.h
@@ -449,6 +449,7 @@ private:
int handle_ordered_next(uchar * buf, bool next_same);
int handle_ordered_prev(uchar * buf);
void return_top_record(uchar * buf);
+ void column_bitmaps_signal();
public:
/*
-------------------------------------------------------------------------
diff --git a/sql/handler.cc b/sql/handler.cc
index dbe7f6727f7..2cb3c5aa348 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -3184,7 +3184,8 @@ int handler::read_multi_range_next(KEY_MULTI_RANGE **found_range_p)
read_range_first()
start_key Start key. Is 0 if no min range
end_key End key. Is 0 if no max range
- eq_range_arg Set to 1 if start_key == end_key
+ eq_range_arg Set to 1 if start_key == end_key and the range endpoints
+ will not change during query execution.
sorted Set to 1 if result should be sorted per key
NOTES
diff --git a/sql/item.cc b/sql/item.cc
index 8afb502c983..d98a37e3c32 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1801,6 +1801,8 @@ void Item_field::set_field(Field *field_par)
unsigned_flag=test(field_par->flags & UNSIGNED_FLAG);
collation.set(field_par->charset(), field_par->derivation());
fixed= 1;
+ if (field->table->s->tmp_table == SYSTEM_TMP_TABLE)
+ any_privileges= 0;
}
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 35ecfdb0f2c..4015e5618e8 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -1569,7 +1569,6 @@ public:
the current and level */
COND_EQUAL()
{
- max_members= 0;
upper_levels= 0;
}
};
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 516da13d857..c027ce20e89 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -7815,8 +7815,7 @@ QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
range->min_keypart_map= range->max_keypart_map=
make_prev_keypart_map(ref->key_parts);
range->flag= ((ref->key_length == key_info->key_length &&
- (key_info->flags & (HA_NOSAME | HA_END_SPACE_KEY)) ==
- HA_NOSAME) ? EQ_RANGE : 0);
+ (key_info->flags & HA_END_SPACE_KEY) == 0) ? EQ_RANGE : 0);
if (!(quick->key_parts=key_part=(KEY_PART *)
alloc_root(&quick->alloc,sizeof(KEY_PART)*ref->key_parts)))
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 83bab51f870..309d3061a2f 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -6730,6 +6730,7 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns));
select_lex->cond_count= 0;
select_lex->between_count= 0;
+ select_lex->max_equal_elems= 0;
for (table= tables; table; table= table->next_local)
{
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index 98d99f4c6e2..ada927fa467 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -749,6 +749,12 @@ void query_cache_end_of_result(THD *thd)
if (thd->net.query_cache_query == 0)
DBUG_VOID_RETURN;
+ if (thd->killed)
+ {
+ query_cache_abort(&thd->net);
+ DBUG_VOID_RETURN;
+ }
+
#ifdef EMBEDDED_LIBRARY
query_cache_insert(&thd->net, (char*)thd,
emb_count_querycache_size(thd));
@@ -775,28 +781,31 @@ void query_cache_end_of_result(THD *thd)
DUMP(&query_cache);
BLOCK_LOCK_WR(query_block);
Query_cache_query *header= query_block->query();
- Query_cache_block *last_result_block= header->result()->prev;
- ulong allign_size= ALIGN_SIZE(last_result_block->used);
- ulong len= max(query_cache.min_allocation_unit, allign_size);
- if (last_result_block->length >= query_cache.min_allocation_unit + len)
- query_cache.split_block(last_result_block,len);
+ Query_cache_block *last_result_block;
+ ulong allign_size;
+ ulong len;
-#ifndef DBUG_OFF
if (header->result() == 0)
{
- DBUG_PRINT("error", ("end of data whith no result. query '%s'",
- header->query()));
- query_cache.wreck(__LINE__, "");
-
+ DBUG_PRINT("error", ("End of data with no result blocks; "
+ "Query '%s' removed from cache.", header->query()));
/*
- We do not need call of BLOCK_UNLOCK_WR(query_block); here because
- query_cache.wreck() switched query cache off but left content
- untouched for investigation (it is debugging method).
+ Extra safety: empty result should not happen in the normal call
+ to this function. In the release version that query should be ignored
+ and removed from QC.
*/
+ DBUG_ASSERT(0);
+ query_cache.free_query(query_block);
STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
DBUG_VOID_RETURN;
}
-#endif
+
+ last_result_block= header->result()->prev;
+ allign_size= ALIGN_SIZE(last_result_block->used);
+ len= max(query_cache.min_allocation_unit, allign_size);
+ if (last_result_block->length >= query_cache.min_allocation_unit + len)
+ query_cache.split_block(last_result_block,len);
+
header->found_rows(current_thd->limit_found_rows);
header->result()->type= Query_cache_block::RESULT;
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index b8ca8a7bd31..66f5540d286 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -1530,6 +1530,7 @@ void st_select_lex::init_query()
*/
parent_lex->push_context(&context);
cond_count= between_count= with_wild= 0;
+ max_equal_elems= 0;
conds_processed_with_permanent_arena= 0;
ref_pointer_array= 0;
select_n_where_fields= 0;
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 2e72a87c35d..057d59d3ccf 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -609,7 +609,8 @@ public:
*/
uint select_n_having_items;
uint cond_count; /* number of arguments of and/or/xor in where/having/on */
- uint between_count; /* number of between predicates in where/having/on */
+ uint between_count; /* number of between predicates in where/having/on */
+ uint max_equal_elems; /* maximal number of elements in multiple equalities */
/*
Number of fields used in select list or where clause of current select
and all inner subselects.
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 3aa490ab7f8..fd3be1aef08 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -3566,10 +3566,7 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
uint and_level,i,found_eq_constant;
KEY_FIELD *key_fields, *end, *field;
uint sz;
- uint m= 1;
-
- if (cond_equal && cond_equal->max_members)
- m= cond_equal->max_members;
+ uint m= max(select_lex->max_equal_elems,1);
/*
We use the same piece of memory to store both KEY_FIELD
@@ -3589,7 +3586,8 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
it is considered as sargable only for its first argument.
Multiple equality can add elements that are filled after
substitution of field arguments by equal fields. There
- can be not more than cond_equal->max_members such substitutions.
+ can be not more than select_lex->max_equal_elems such
+ substitutions.
*/
sz= max(sizeof(KEY_FIELD),sizeof(SARGABLE_PARAM))*
(((thd->lex->current_select->cond_count+1)*2 +
@@ -7392,8 +7390,7 @@ static bool check_equality(THD *thd, Item *item, COND_EQUAL *cond_equal,
just an argument of a comparison predicate.
The function also determines the maximum number of members in
equality lists of each Item_cond_and object assigning it to
- cond_equal->max_members of this object and updating accordingly
- the upper levels COND_EQUAL structures.
+ thd->lex->current_select->max_equal_elems.
NOTES
Multiple equality predicate =(f1,..fn) is equivalent to the conjuction of
@@ -7438,7 +7435,6 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
COND_EQUAL *inherited)
{
Item_equal *item_equal;
- uint members;
COND_EQUAL cond_equal;
cond_equal.upper_levels= inherited;
@@ -7476,19 +7472,8 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
{
item_equal->fix_length_and_dec();
item_equal->update_used_tables();
- members= item_equal->members();
- if (cond_equal.max_members < members)
- cond_equal.max_members= members;
- }
- members= cond_equal.max_members;
- if (inherited && inherited->max_members < members)
- {
- do
- {
- inherited->max_members= members;
- inherited= inherited->upper_levels;
- }
- while (inherited);
+ set_if_bigger(thd->lex->current_select->max_equal_elems,
+ item_equal->members());
}
((Item_cond_and*)cond)->cond_equal= cond_equal;
@@ -7543,10 +7528,12 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
{
item_equal->fix_length_and_dec();
item_equal->update_used_tables();
- return item_equal;
}
else
- return eq_list.pop();
+ item_equal= (Item_equal *) eq_list.pop();
+ set_if_bigger(thd->lex->current_select->max_equal_elems,
+ item_equal->members());
+ return item_equal;
}
else
{
@@ -7562,9 +7549,8 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
{
item_equal->fix_length_and_dec();
item_equal->update_used_tables();
- members= item_equal->members();
- if (cond_equal.max_members < members)
- cond_equal.max_members= members;
+ set_if_bigger(thd->lex->current_select->max_equal_elems,
+ item_equal->members());
}
and_cond->cond_equal= cond_equal;
args->concat((List<Item> *)&cond_equal.current_level);
@@ -9422,7 +9408,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
bool using_unique_constraint= 0;
bool use_packed_rows= 0;
bool not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
- char *tmpname, *tmppath, path[FN_REFLEN], table_name[NAME_LEN+1];
+ char *tmpname,path[FN_REFLEN];
uchar *pos, *group_buff, *bitmaps;
uchar *null_flags;
Field **reg_field, **from_field, **default_field;
@@ -9446,12 +9432,12 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
temp_pool_slot = bitmap_lock_set_next(&temp_pool);
if (temp_pool_slot != MY_BIT_NONE) // we got a slot
- sprintf(table_name, "%s_%lx_%i", tmp_file_prefix,
+ sprintf(path, "%s_%lx_%i", tmp_file_prefix,
current_pid, temp_pool_slot);
else
{
/* if we run out of slots or we are not using tempool */
- sprintf(table_name, "%s%lx_%lx_%x", tmp_file_prefix,current_pid,
+ sprintf(path,"%s%lx_%lx_%x", tmp_file_prefix,current_pid,
thd->thread_id, thd->tmp_table++);
}
@@ -9459,8 +9445,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
No need to change table name to lower case as we are only creating
MyISAM or HEAP tables here
*/
- fn_format(path, table_name, mysql_tmpdir, "",
- MY_REPLACE_EXT|MY_UNPACK_FILENAME);
+ fn_format(path, path, mysql_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
+
if (group)
{
@@ -9506,8 +9492,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
sizeof(*key_part_info)*(param->group_parts+1),
&param->start_recinfo,
sizeof(*param->recinfo)*(field_count*2+4),
- &tmppath, (uint) strlen(path)+1,
- &tmpname, (uint) strlen(table_name)+1,
+ &tmpname, (uint) strlen(path)+1,
&group_buff, (group && ! using_unique_constraint ?
param->group_length : 0),
&bitmaps, bitmap_buffer_size(field_count)*2,
@@ -9526,8 +9511,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
DBUG_RETURN(NULL); /* purecov: inspected */
}
param->items_to_copy= copy_func;
- strmov(tmppath, path);
- strmov(tmpname, table_name);
+ strmov(tmpname,path);
/* make table according to fields */
bzero((char*) table,sizeof(*table));
@@ -9552,7 +9536,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
table->keys_in_use_for_query.init();
table->s= share;
- init_tmp_table_share(share, "", 0, tmpname, tmppath);
+ init_tmp_table_share(share, "", 0, tmpname, tmpname);
share->blob_field= blob_field;
share->blob_ptr_size= mi_portable_sizeof_char_ptr;
share->db_low_byte_first=1; // True for HEAP and MyISAM
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index e1bcf0eef96..19e0bf826c5 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -3567,8 +3567,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
col_access= get_column_grant(thd, &tables->grant,
db_name->str, table_name->str,
field->field_name) & COL_ACLS;
- if (lex->sql_command != SQLCOM_SHOW_FIELDS &&
- !tables->schema_table && !col_access)
+ if (!tables->schema_table && !col_access)
continue;
end= tmp;
for (uint bitnr=0; col_access ; col_access>>=1,bitnr++)
@@ -4361,6 +4360,12 @@ static int get_schema_triggers_record(THD *thd, TABLE_LIST *tables,
{
Table_triggers_list *triggers= tables->table->triggers;
int event, timing;
+
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ if (check_table_access(thd, TRIGGER_ACL, tables, 1))
+ goto ret;
+#endif
+
for (event= 0; event < (int)TRG_EVENT_MAX; event++)
{
for (timing= 0; timing < (int)TRG_ACTION_MAX; timing++)
@@ -4397,6 +4402,9 @@ static int get_schema_triggers_record(THD *thd, TABLE_LIST *tables,
}
}
}
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ret:
+#endif
DBUG_RETURN(0);
}
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 9a46bbc39e4..38d7174b7ca 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -397,7 +397,13 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
{
Item_field *field;
if ((field= item->filed_for_view_update()))
+ {
+ /*
+ any_privileges may be reset later by the Item_field::set_field
+ method in case of a system temporary table.
+ */
field->any_privileges= 1;
+ }
}
}
#endif
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index 0b23f1ab9d4..7f0289d93db 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -16267,6 +16267,78 @@ static void test_bug27592()
DBUG_VOID_RETURN;
}
+static void test_bug29948()
+{
+ MYSQL *dbc=NULL;
+ MYSQL_STMT *stmt=NULL;
+ MYSQL_BIND bind;
+
+ int res=0;
+ my_bool auto_reconnect=1, error=0, is_null=0;
+ char kill_buf[20];
+ const char *query;
+ int buf;
+ unsigned long length, cursor_type;
+
+ dbc = mysql_init(NULL);
+ DIE_UNLESS(dbc);
+
+ mysql_options(dbc, MYSQL_OPT_RECONNECT, (char*)&auto_reconnect);
+ if (!mysql_real_connect(dbc, opt_host, opt_user,
+ opt_password, current_db, opt_port,
+ opt_unix_socket,
+ (CLIENT_FOUND_ROWS | CLIENT_MULTI_STATEMENTS |
+ CLIENT_MULTI_RESULTS)))
+ {
+ printf("connection failed: %s (%d)", mysql_error(dbc),
+ mysql_errno(dbc));
+ exit(1);
+ }
+
+ bind.buffer_type= MYSQL_TYPE_LONG;
+ bind.buffer= (char *)&buf;
+ bind.is_null= &is_null;
+ bind.error= &error;
+ bind.length= &length;
+
+ res= mysql_query(dbc, "DROP TABLE IF EXISTS t1");
+ myquery(res);
+ res= mysql_query(dbc, "CREATE TABLE t1 (a INT)");
+ myquery(res);
+ res= mysql_query(dbc, "INSERT INTO t1 VALUES(1)");
+ myquery(res);
+
+ stmt= mysql_stmt_init(dbc);
+ check_stmt(stmt);
+
+ cursor_type= CURSOR_TYPE_READ_ONLY;
+ res= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void *)&cursor_type);
+ myquery(res);
+
+ query= "SELECT * from t1 where a=?";
+ res= mysql_stmt_prepare(stmt, query, strlen(query));
+ myquery(res);
+
+ res= mysql_stmt_bind_param(stmt, &bind);
+ myquery(res);
+
+ res= mysql_stmt_execute(stmt);
+ check_execute(stmt, res);
+
+ res= mysql_stmt_bind_result(stmt,&bind);
+ check_execute(stmt, res);
+
+ sprintf(kill_buf, "kill %ld", dbc->thread_id);
+ mysql_query(dbc, kill_buf);
+
+ res= mysql_stmt_store_result(stmt);
+ DIE_UNLESS(res);
+
+ mysql_stmt_free_result(stmt);
+ mysql_stmt_close(stmt);
+ mysql_query(dbc, "DROP TABLE t1");
+ mysql_close(dbc);
+}
/*
@@ -16668,6 +16740,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug28505", test_bug28505 },
{ "test_bug28934", test_bug28934 },
{ "test_bug27592", test_bug27592 },
+ { "test_bug29948", test_bug29948 },
{ "test_bug29687", test_bug29687 },
{ "test_bug29692", test_bug29692 },
{ "test_bug29306", test_bug29306 },