summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--BitKeeper/etc/logging_ok2
-rw-r--r--VC++Files/mysys/mysys.dsp4
-rw-r--r--include/mysql_com.h5
-rw-r--r--myisam/mi_extra.c2
-rw-r--r--myisam/mi_packrec.c9
-rw-r--r--mysql-test/r/binlog.result135
-rw-r--r--mysql-test/r/innodb.result6
-rw-r--r--mysql-test/r/kill.result12
-rw-r--r--mysql-test/r/mix_innodb_myisam_binlog.result27
-rw-r--r--mysql-test/r/rpl_insert_id.result5
-rw-r--r--mysql-test/r/rpl_rotate_logs.result117
-rw-r--r--mysql-test/r/rpl_view.result44
-rw-r--r--mysql-test/r/sp.result15
-rw-r--r--mysql-test/r/view.result52
-rw-r--r--mysql-test/r/view_query_cache.result25
-rw-r--r--mysql-test/t/binlog-master.opt1
-rw-r--r--mysql-test/t/binlog.test45
-rw-r--r--mysql-test/t/innodb.test4
-rw-r--r--mysql-test/t/kill.test19
-rw-r--r--mysql-test/t/rpl_insert_id.test16
-rw-r--r--mysql-test/t/rpl_rotate_logs.test27
-rw-r--r--mysql-test/t/rpl_view.test44
-rw-r--r--mysql-test/t/sp.test21
-rw-r--r--mysql-test/t/view.test53
-rw-r--r--mysql-test/t/view_query_cache.test31
-rw-r--r--mysys/my_mmap.c6
-rw-r--r--ndb/src/mgmsrv/MgmtSrvr.cpp3
-rw-r--r--sql/handler.h2
-rw-r--r--sql/item.cc70
-rw-r--r--sql/log.cc44
-rw-r--r--sql/log_event.cc3
-rw-r--r--sql/log_event.h2
-rw-r--r--sql/my_decimal.h4
-rw-r--r--sql/net_serv.cc3
-rw-r--r--sql/protocol.cc18
-rw-r--r--sql/set_var.cc6
-rw-r--r--sql/share/errmsg.txt2
-rw-r--r--sql/sql_acl.cc3
-rw-r--r--sql/sql_cache.cc259
-rw-r--r--sql/sql_cache.h4
-rw-r--r--sql/sql_class.h2
-rw-r--r--sql/sql_db.cc2
-rw-r--r--sql/sql_map.cc11
-rw-r--r--sql/sql_parse.cc225
-rw-r--r--sql/sql_select.cc26
-rw-r--r--sql/sql_view.cc3
-rw-r--r--sql/table.cc96
-rw-r--r--tests/mysql_client_test.c37
48 files changed, 1121 insertions, 431 deletions
diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok
index f5cb190ec8d..89e1ff4bd48 100644
--- a/BitKeeper/etc/logging_ok
+++ b/BitKeeper/etc/logging_ok
@@ -28,6 +28,7 @@ bar@gw.udmsearch.izhnet.ru
bar@mysql.com
bar@noter.intranet.mysql.r18.ru
bell@51.0.168.192.in-addr.arpa
+bell@52.0.168.192.in-addr.arpa
bell@laptop.sanja.is.com.ua
bell@sanja.is.com.ua
bk@admin.bk
@@ -207,6 +208,7 @@ ramil@mysql.com
ranger@regul.home.lan
rburnett@build.mysql.com
reggie@bob.(none)
+reggie@mdk10.(none)
root@home.(none)
root@mc04.(none)
root@x3.internalnet
diff --git a/VC++Files/mysys/mysys.dsp b/VC++Files/mysys/mysys.dsp
index f42357c2249..0a48b93b9ef 100644
--- a/VC++Files/mysys/mysys.dsp
+++ b/VC++Files/mysys/mysys.dsp
@@ -448,6 +448,10 @@ SOURCE=.\my_mkdir.c
# End Source File
# Begin Source File
+SOURCE=.\my_mmap.c
+# End Source File
+# Begin Source File
+
SOURCE=.\my_net.c
# End Source File
# Begin Source File
diff --git a/include/mysql_com.h b/include/mysql_com.h
index 22250e4b03e..094283f8330 100644
--- a/include/mysql_com.h
+++ b/include/mysql_com.h
@@ -188,6 +188,11 @@ typedef struct st_net {
my_bool no_send_ok; /* For SPs and other things that do multiple stmts */
my_bool no_send_eof; /* For SPs' first version read-only cursors */
/*
+ Set if OK packet is already sent, and we do not need to send error
+ messages
+ */
+ my_bool no_send_error;
+ /*
Pointer to query object in query cache, do not equal NULL (0) for
queries in cache that have not stored its results yet
*/
diff --git a/myisam/mi_extra.c b/myisam/mi_extra.c
index 9023fe26f9e..ba32bb9115a 100644
--- a/myisam/mi_extra.c
+++ b/myisam/mi_extra.c
@@ -15,7 +15,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "myisamdef.h"
-#ifdef HAVE_MMAP
+#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
diff --git a/myisam/mi_packrec.c b/myisam/mi_packrec.c
index a8a27858d79..cc62614cb07 100644
--- a/myisam/mi_packrec.c
+++ b/myisam/mi_packrec.c
@@ -1181,11 +1181,12 @@ static uint max_bit(register uint value)
/*****************************************************************************
Some redefined functions to handle files when we are using memmap
*****************************************************************************/
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
#ifdef HAVE_MMAP
-#include <sys/mman.h>
-
static int _mi_read_mempack_record(MI_INFO *info,my_off_t filepos,byte *buf);
static int _mi_read_rnd_mempack_record(MI_INFO*, byte *,my_off_t, my_bool);
@@ -1211,7 +1212,7 @@ my_bool _mi_memmap_file(MI_INFO *info)
DBUG_RETURN(0);
}
file_map=(byte*)
- mmap(0,share->state.state.data_file_length+MEMMAP_EXTRA_MARGIN,PROT_READ,
+ my_mmap(0,share->state.state.data_file_length+MEMMAP_EXTRA_MARGIN,PROT_READ,
MAP_SHARED | MAP_NORESERVE,info->dfile,0L);
if (file_map == (byte*) MAP_FAILED)
{
@@ -1230,7 +1231,7 @@ my_bool _mi_memmap_file(MI_INFO *info)
void _mi_unmap_file(MI_INFO *info)
{
- VOID(munmap((caddr_t) info->s->file_map,
+ VOID(my_munmap(info->s->file_map,
(size_t) info->s->state.state.data_file_length+
MEMMAP_EXTRA_MARGIN));
}
diff --git a/mysql-test/r/binlog.result b/mysql-test/r/binlog.result
new file mode 100644
index 00000000000..d59ea7e1340
--- /dev/null
+++ b/mysql-test/r/binlog.result
@@ -0,0 +1,135 @@
+drop table if exists t1, t2;
+reset master;
+create table t1 (a int) engine=bdb;
+create table t2 (a int) engine=innodb;
+begin;
+insert t1 values (5);
+commit;
+begin;
+insert t2 values (5);
+commit;
+show binlog events from 96;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 96 Query 1 194 use `test`; create table t1 (a int) engine=bdb
+master-bin.000001 194 Query 1 295 use `test`; create table t2 (a int) engine=innodb
+master-bin.000001 295 Query 1 364 use `test`; BEGIN
+master-bin.000001 364 Query 1 84 use `test`; insert t1 values (5)
+master-bin.000001 448 Query 1 518 use `test`; COMMIT
+master-bin.000001 518 Query 1 587 use `test`; BEGIN
+master-bin.000001 587 Query 1 84 use `test`; insert t2 values (5)
+master-bin.000001 671 Xid 1 698 COMMIT /* xid=11 */
+drop table t1,t2;
+reset master;
+create table t1 (n int) engine=innodb;
+begin;
+commit;
+drop table t1;
+show binlog events in 'master-bin.000001' from 96;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 96 Query 1 197 use `test`; create table t1 (n int) engine=innodb
+master-bin.000001 197 Query 1 266 use `test`; BEGIN
+master-bin.000001 266 Query 1 94 use `test`; insert into t1 values(100 + 4)
+master-bin.000001 360 Query 1 187 use `test`; insert into t1 values(99 + 4)
+master-bin.000001 453 Query 1 280 use `test`; insert into t1 values(98 + 4)
+master-bin.000001 546 Query 1 373 use `test`; insert into t1 values(97 + 4)
+master-bin.000001 639 Query 1 466 use `test`; insert into t1 values(96 + 4)
+master-bin.000001 732 Query 1 559 use `test`; insert into t1 values(95 + 4)
+master-bin.000001 825 Query 1 652 use `test`; insert into t1 values(94 + 4)
+master-bin.000001 918 Query 1 745 use `test`; insert into t1 values(93 + 4)
+master-bin.000001 1011 Query 1 838 use `test`; insert into t1 values(92 + 4)
+master-bin.000001 1104 Query 1 931 use `test`; insert into t1 values(91 + 4)
+master-bin.000001 1197 Query 1 1024 use `test`; insert into t1 values(90 + 4)
+master-bin.000001 1290 Query 1 1117 use `test`; insert into t1 values(89 + 4)
+master-bin.000001 1383 Query 1 1210 use `test`; insert into t1 values(88 + 4)
+master-bin.000001 1476 Query 1 1303 use `test`; insert into t1 values(87 + 4)
+master-bin.000001 1569 Query 1 1396 use `test`; insert into t1 values(86 + 4)
+master-bin.000001 1662 Query 1 1489 use `test`; insert into t1 values(85 + 4)
+master-bin.000001 1755 Query 1 1582 use `test`; insert into t1 values(84 + 4)
+master-bin.000001 1848 Query 1 1675 use `test`; insert into t1 values(83 + 4)
+master-bin.000001 1941 Query 1 1768 use `test`; insert into t1 values(82 + 4)
+master-bin.000001 2034 Query 1 1861 use `test`; insert into t1 values(81 + 4)
+master-bin.000001 2127 Query 1 1954 use `test`; insert into t1 values(80 + 4)
+master-bin.000001 2220 Query 1 2047 use `test`; insert into t1 values(79 + 4)
+master-bin.000001 2313 Query 1 2140 use `test`; insert into t1 values(78 + 4)
+master-bin.000001 2406 Query 1 2233 use `test`; insert into t1 values(77 + 4)
+master-bin.000001 2499 Query 1 2326 use `test`; insert into t1 values(76 + 4)
+master-bin.000001 2592 Query 1 2419 use `test`; insert into t1 values(75 + 4)
+master-bin.000001 2685 Query 1 2512 use `test`; insert into t1 values(74 + 4)
+master-bin.000001 2778 Query 1 2605 use `test`; insert into t1 values(73 + 4)
+master-bin.000001 2871 Query 1 2698 use `test`; insert into t1 values(72 + 4)
+master-bin.000001 2964 Query 1 2791 use `test`; insert into t1 values(71 + 4)
+master-bin.000001 3057 Query 1 2884 use `test`; insert into t1 values(70 + 4)
+master-bin.000001 3150 Query 1 2977 use `test`; insert into t1 values(69 + 4)
+master-bin.000001 3243 Query 1 3070 use `test`; insert into t1 values(68 + 4)
+master-bin.000001 3336 Query 1 3163 use `test`; insert into t1 values(67 + 4)
+master-bin.000001 3429 Query 1 3256 use `test`; insert into t1 values(66 + 4)
+master-bin.000001 3522 Query 1 3349 use `test`; insert into t1 values(65 + 4)
+master-bin.000001 3615 Query 1 3442 use `test`; insert into t1 values(64 + 4)
+master-bin.000001 3708 Query 1 3535 use `test`; insert into t1 values(63 + 4)
+master-bin.000001 3801 Query 1 3628 use `test`; insert into t1 values(62 + 4)
+master-bin.000001 3894 Query 1 3721 use `test`; insert into t1 values(61 + 4)
+master-bin.000001 3987 Query 1 3814 use `test`; insert into t1 values(60 + 4)
+master-bin.000001 4080 Query 1 3907 use `test`; insert into t1 values(59 + 4)
+master-bin.000001 4173 Query 1 4000 use `test`; insert into t1 values(58 + 4)
+master-bin.000001 4266 Query 1 4093 use `test`; insert into t1 values(57 + 4)
+master-bin.000001 4359 Query 1 4186 use `test`; insert into t1 values(56 + 4)
+master-bin.000001 4452 Query 1 4279 use `test`; insert into t1 values(55 + 4)
+master-bin.000001 4545 Query 1 4372 use `test`; insert into t1 values(54 + 4)
+master-bin.000001 4638 Query 1 4465 use `test`; insert into t1 values(53 + 4)
+master-bin.000001 4731 Query 1 4558 use `test`; insert into t1 values(52 + 4)
+master-bin.000001 4824 Query 1 4651 use `test`; insert into t1 values(51 + 4)
+master-bin.000001 4917 Query 1 4744 use `test`; insert into t1 values(50 + 4)
+master-bin.000001 5010 Query 1 4837 use `test`; insert into t1 values(49 + 4)
+master-bin.000001 5103 Query 1 4930 use `test`; insert into t1 values(48 + 4)
+master-bin.000001 5196 Query 1 5023 use `test`; insert into t1 values(47 + 4)
+master-bin.000001 5289 Query 1 5116 use `test`; insert into t1 values(46 + 4)
+master-bin.000001 5382 Query 1 5209 use `test`; insert into t1 values(45 + 4)
+master-bin.000001 5475 Query 1 5302 use `test`; insert into t1 values(44 + 4)
+master-bin.000001 5568 Query 1 5395 use `test`; insert into t1 values(43 + 4)
+master-bin.000001 5661 Query 1 5488 use `test`; insert into t1 values(42 + 4)
+master-bin.000001 5754 Query 1 5581 use `test`; insert into t1 values(41 + 4)
+master-bin.000001 5847 Query 1 5674 use `test`; insert into t1 values(40 + 4)
+master-bin.000001 5940 Query 1 5767 use `test`; insert into t1 values(39 + 4)
+master-bin.000001 6033 Query 1 5860 use `test`; insert into t1 values(38 + 4)
+master-bin.000001 6126 Query 1 5953 use `test`; insert into t1 values(37 + 4)
+master-bin.000001 6219 Query 1 6046 use `test`; insert into t1 values(36 + 4)
+master-bin.000001 6312 Query 1 6139 use `test`; insert into t1 values(35 + 4)
+master-bin.000001 6405 Query 1 6232 use `test`; insert into t1 values(34 + 4)
+master-bin.000001 6498 Query 1 6325 use `test`; insert into t1 values(33 + 4)
+master-bin.000001 6591 Query 1 6418 use `test`; insert into t1 values(32 + 4)
+master-bin.000001 6684 Query 1 6511 use `test`; insert into t1 values(31 + 4)
+master-bin.000001 6777 Query 1 6604 use `test`; insert into t1 values(30 + 4)
+master-bin.000001 6870 Query 1 6697 use `test`; insert into t1 values(29 + 4)
+master-bin.000001 6963 Query 1 6790 use `test`; insert into t1 values(28 + 4)
+master-bin.000001 7056 Query 1 6883 use `test`; insert into t1 values(27 + 4)
+master-bin.000001 7149 Query 1 6976 use `test`; insert into t1 values(26 + 4)
+master-bin.000001 7242 Query 1 7069 use `test`; insert into t1 values(25 + 4)
+master-bin.000001 7335 Query 1 7162 use `test`; insert into t1 values(24 + 4)
+master-bin.000001 7428 Query 1 7255 use `test`; insert into t1 values(23 + 4)
+master-bin.000001 7521 Query 1 7348 use `test`; insert into t1 values(22 + 4)
+master-bin.000001 7614 Query 1 7441 use `test`; insert into t1 values(21 + 4)
+master-bin.000001 7707 Query 1 7534 use `test`; insert into t1 values(20 + 4)
+master-bin.000001 7800 Query 1 7627 use `test`; insert into t1 values(19 + 4)
+master-bin.000001 7893 Query 1 7720 use `test`; insert into t1 values(18 + 4)
+master-bin.000001 7986 Query 1 7813 use `test`; insert into t1 values(17 + 4)
+master-bin.000001 8079 Query 1 7906 use `test`; insert into t1 values(16 + 4)
+master-bin.000001 8172 Query 1 7999 use `test`; insert into t1 values(15 + 4)
+master-bin.000001 8265 Query 1 8092 use `test`; insert into t1 values(14 + 4)
+master-bin.000001 8358 Query 1 8185 use `test`; insert into t1 values(13 + 4)
+master-bin.000001 8451 Query 1 8278 use `test`; insert into t1 values(12 + 4)
+master-bin.000001 8544 Query 1 8371 use `test`; insert into t1 values(11 + 4)
+master-bin.000001 8637 Query 1 8464 use `test`; insert into t1 values(10 + 4)
+master-bin.000001 8730 Query 1 8556 use `test`; insert into t1 values(9 + 4)
+master-bin.000001 8822 Query 1 8648 use `test`; insert into t1 values(8 + 4)
+master-bin.000001 8914 Query 1 8740 use `test`; insert into t1 values(7 + 4)
+master-bin.000001 9006 Query 1 8832 use `test`; insert into t1 values(6 + 4)
+master-bin.000001 9098 Query 1 8924 use `test`; insert into t1 values(5 + 4)
+master-bin.000001 9190 Query 1 9016 use `test`; insert into t1 values(4 + 4)
+master-bin.000001 9282 Query 1 9108 use `test`; insert into t1 values(3 + 4)
+master-bin.000001 9374 Query 1 9200 use `test`; insert into t1 values(2 + 4)
+master-bin.000001 9466 Query 1 9292 use `test`; insert into t1 values(1 + 4)
+master-bin.000001 9558 Xid 1 9585 COMMIT /* xid=18 */
+master-bin.000001 9585 Rotate 1 9629 master-bin.000002;pos=4
+show binlog events in 'master-bin.000002' from 96;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000002 96 Query 1 173 use `test`; drop table t1
diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result
index d65ce794a75..91f74be9453 100644
--- a/mysql-test/r/innodb.result
+++ b/mysql-test/r/innodb.result
@@ -272,6 +272,10 @@ n
7
rollback to savepoint `my_savepoint`;
ERROR 42000: SAVEPOINT my_savepoint does not exist
+insert into t1 values (8);
+savepoint sv;
+commit;
+savepoint sv;
set autocommit=1;
rollback;
drop table t1;
@@ -1717,7 +1721,7 @@ Variable_name Value
Innodb_rows_deleted 2070
show status like "Innodb_rows_inserted";
Variable_name Value
-Innodb_rows_inserted 31708
+Innodb_rows_inserted 31709
show status like "Innodb_rows_updated";
Variable_name Value
Innodb_rows_updated 29530
diff --git a/mysql-test/r/kill.result b/mysql-test/r/kill.result
index 788fab8d31a..f57c134b6d0 100644
--- a/mysql-test/r/kill.result
+++ b/mysql-test/r/kill.result
@@ -9,3 +9,15 @@ select 4;
4
4
drop table t1;
+select get_lock("a", 10);
+get_lock("a", 10)
+1
+ select get_lock("a", 10);
+get_lock("a", 10)
+NULL
+select 1;
+1
+1
+select RELEASE_LOCK("a");
+RELEASE_LOCK("a")
+1
diff --git a/mysql-test/r/mix_innodb_myisam_binlog.result b/mysql-test/r/mix_innodb_myisam_binlog.result
index 06ca3245535..d4ff95e4e29 100644
--- a/mysql-test/r/mix_innodb_myisam_binlog.result
+++ b/mysql-test/r/mix_innodb_myisam_binlog.result
@@ -101,10 +101,9 @@ insert into t1 values(9);
insert into t2 select * from t1;
show binlog events from 96;
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 96 Query 1 # use `test`; BEGIN
-master-bin.000001 165 Query 1 # use `test`; insert into t1 values(9)
-master-bin.000001 253 Xid 1 # COMMIT /* xid=59 */
-master-bin.000001 280 Query 1 # use `test`; insert into t2 select * from t1
+master-bin.000001 96 Query 1 # use `test`; insert into t1 values(9)
+master-bin.000001 184 Xid 1 # COMMIT /* xid=59 */
+master-bin.000001 211 Query 1 # use `test`; insert into t2 select * from t1
delete from t1;
delete from t2;
reset master;
@@ -113,21 +112,19 @@ begin;
insert into t2 select * from t1;
show binlog events from 96;
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 96 Query 1 # use `test`; BEGIN
-master-bin.000001 165 Query 1 # use `test`; insert into t1 values(10)
-master-bin.000001 254 Xid 1 # COMMIT /* xid=65 */
-master-bin.000001 281 Query 1 # use `test`; insert into t2 select * from t1
+master-bin.000001 96 Query 1 # use `test`; insert into t1 values(10)
+master-bin.000001 185 Xid 1 # COMMIT /* xid=65 */
+master-bin.000001 212 Query 1 # use `test`; insert into t2 select * from t1
insert into t1 values(11);
commit;
show binlog events from 96;
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 96 Query 1 # use `test`; BEGIN
-master-bin.000001 165 Query 1 # use `test`; insert into t1 values(10)
-master-bin.000001 254 Xid 1 # COMMIT /* xid=65 */
-master-bin.000001 281 Query 1 # use `test`; insert into t2 select * from t1
-master-bin.000001 376 Query 1 # use `test`; BEGIN
-master-bin.000001 445 Query 1 # use `test`; insert into t1 values(11)
-master-bin.000001 534 Xid 1 # COMMIT /* xid=67 */
+master-bin.000001 96 Query 1 # use `test`; insert into t1 values(10)
+master-bin.000001 185 Xid 1 # COMMIT /* xid=65 */
+master-bin.000001 212 Query 1 # use `test`; insert into t2 select * from t1
+master-bin.000001 307 Query 1 # use `test`; BEGIN
+master-bin.000001 376 Query 1 # use `test`; insert into t1 values(11)
+master-bin.000001 465 Xid 1 # COMMIT /* xid=67 */
alter table t2 engine=INNODB;
delete from t1;
delete from t2;
diff --git a/mysql-test/r/rpl_insert_id.result b/mysql-test/r/rpl_insert_id.result
index 8001cb59a35..8482f631553 100644
--- a/mysql-test/r/rpl_insert_id.result
+++ b/mysql-test/r/rpl_insert_id.result
@@ -68,3 +68,8 @@ b c
9 13
drop table t1;
drop table t2;
+SET TIMESTAMP=1000000000;
+CREATE TABLE t1 ( a INT UNIQUE );
+SET FOREIGN_KEY_CHECKS=0;
+INSERT INTO t1 VALUES (1),(1);
+ERROR 23000: Duplicate entry '1' for key 1
diff --git a/mysql-test/r/rpl_rotate_logs.result b/mysql-test/r/rpl_rotate_logs.result
index 745d4d8138e..ec29a01db10 100644
--- a/mysql-test/r/rpl_rotate_logs.result
+++ b/mysql-test/r/rpl_rotate_logs.result
@@ -92,120 +92,3 @@ count(*)
100
unlock tables;
drop table if exists t1,t2,t3,t4;
-slave stop;
-reset master;
-create table t1 (n int) engine=innodb;
-begin;
-commit;
-drop table t1;
-show binlog events in 'master-bin.000001';
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 4 Format_desc 1 96 Server ver: VERSION, Binlog ver: 4
-master-bin.000001 96 Query 1 197 use `test`; create table t1 (n int) engine=innodb
-master-bin.000001 197 Query 1 266 use `test`; BEGIN
-master-bin.000001 266 Query 1 94 use `test`; insert into t1 values(100 + 4)
-master-bin.000001 360 Query 1 187 use `test`; insert into t1 values(99 + 4)
-master-bin.000001 453 Query 1 280 use `test`; insert into t1 values(98 + 4)
-master-bin.000001 546 Query 1 373 use `test`; insert into t1 values(97 + 4)
-master-bin.000001 639 Query 1 466 use `test`; insert into t1 values(96 + 4)
-master-bin.000001 732 Query 1 559 use `test`; insert into t1 values(95 + 4)
-master-bin.000001 825 Query 1 652 use `test`; insert into t1 values(94 + 4)
-master-bin.000001 918 Query 1 745 use `test`; insert into t1 values(93 + 4)
-master-bin.000001 1011 Query 1 838 use `test`; insert into t1 values(92 + 4)
-master-bin.000001 1104 Query 1 931 use `test`; insert into t1 values(91 + 4)
-master-bin.000001 1197 Query 1 1024 use `test`; insert into t1 values(90 + 4)
-master-bin.000001 1290 Query 1 1117 use `test`; insert into t1 values(89 + 4)
-master-bin.000001 1383 Query 1 1210 use `test`; insert into t1 values(88 + 4)
-master-bin.000001 1476 Query 1 1303 use `test`; insert into t1 values(87 + 4)
-master-bin.000001 1569 Query 1 1396 use `test`; insert into t1 values(86 + 4)
-master-bin.000001 1662 Query 1 1489 use `test`; insert into t1 values(85 + 4)
-master-bin.000001 1755 Query 1 1582 use `test`; insert into t1 values(84 + 4)
-master-bin.000001 1848 Query 1 1675 use `test`; insert into t1 values(83 + 4)
-master-bin.000001 1941 Query 1 1768 use `test`; insert into t1 values(82 + 4)
-master-bin.000001 2034 Query 1 1861 use `test`; insert into t1 values(81 + 4)
-master-bin.000001 2127 Query 1 1954 use `test`; insert into t1 values(80 + 4)
-master-bin.000001 2220 Query 1 2047 use `test`; insert into t1 values(79 + 4)
-master-bin.000001 2313 Query 1 2140 use `test`; insert into t1 values(78 + 4)
-master-bin.000001 2406 Query 1 2233 use `test`; insert into t1 values(77 + 4)
-master-bin.000001 2499 Query 1 2326 use `test`; insert into t1 values(76 + 4)
-master-bin.000001 2592 Query 1 2419 use `test`; insert into t1 values(75 + 4)
-master-bin.000001 2685 Query 1 2512 use `test`; insert into t1 values(74 + 4)
-master-bin.000001 2778 Query 1 2605 use `test`; insert into t1 values(73 + 4)
-master-bin.000001 2871 Query 1 2698 use `test`; insert into t1 values(72 + 4)
-master-bin.000001 2964 Query 1 2791 use `test`; insert into t1 values(71 + 4)
-master-bin.000001 3057 Query 1 2884 use `test`; insert into t1 values(70 + 4)
-master-bin.000001 3150 Query 1 2977 use `test`; insert into t1 values(69 + 4)
-master-bin.000001 3243 Query 1 3070 use `test`; insert into t1 values(68 + 4)
-master-bin.000001 3336 Query 1 3163 use `test`; insert into t1 values(67 + 4)
-master-bin.000001 3429 Query 1 3256 use `test`; insert into t1 values(66 + 4)
-master-bin.000001 3522 Query 1 3349 use `test`; insert into t1 values(65 + 4)
-master-bin.000001 3615 Query 1 3442 use `test`; insert into t1 values(64 + 4)
-master-bin.000001 3708 Query 1 3535 use `test`; insert into t1 values(63 + 4)
-master-bin.000001 3801 Query 1 3628 use `test`; insert into t1 values(62 + 4)
-master-bin.000001 3894 Query 1 3721 use `test`; insert into t1 values(61 + 4)
-master-bin.000001 3987 Query 1 3814 use `test`; insert into t1 values(60 + 4)
-master-bin.000001 4080 Query 1 3907 use `test`; insert into t1 values(59 + 4)
-master-bin.000001 4173 Query 1 4000 use `test`; insert into t1 values(58 + 4)
-master-bin.000001 4266 Query 1 4093 use `test`; insert into t1 values(57 + 4)
-master-bin.000001 4359 Query 1 4186 use `test`; insert into t1 values(56 + 4)
-master-bin.000001 4452 Query 1 4279 use `test`; insert into t1 values(55 + 4)
-master-bin.000001 4545 Query 1 4372 use `test`; insert into t1 values(54 + 4)
-master-bin.000001 4638 Query 1 4465 use `test`; insert into t1 values(53 + 4)
-master-bin.000001 4731 Query 1 4558 use `test`; insert into t1 values(52 + 4)
-master-bin.000001 4824 Query 1 4651 use `test`; insert into t1 values(51 + 4)
-master-bin.000001 4917 Query 1 4744 use `test`; insert into t1 values(50 + 4)
-master-bin.000001 5010 Query 1 4837 use `test`; insert into t1 values(49 + 4)
-master-bin.000001 5103 Query 1 4930 use `test`; insert into t1 values(48 + 4)
-master-bin.000001 5196 Query 1 5023 use `test`; insert into t1 values(47 + 4)
-master-bin.000001 5289 Query 1 5116 use `test`; insert into t1 values(46 + 4)
-master-bin.000001 5382 Query 1 5209 use `test`; insert into t1 values(45 + 4)
-master-bin.000001 5475 Query 1 5302 use `test`; insert into t1 values(44 + 4)
-master-bin.000001 5568 Query 1 5395 use `test`; insert into t1 values(43 + 4)
-master-bin.000001 5661 Query 1 5488 use `test`; insert into t1 values(42 + 4)
-master-bin.000001 5754 Query 1 5581 use `test`; insert into t1 values(41 + 4)
-master-bin.000001 5847 Query 1 5674 use `test`; insert into t1 values(40 + 4)
-master-bin.000001 5940 Query 1 5767 use `test`; insert into t1 values(39 + 4)
-master-bin.000001 6033 Query 1 5860 use `test`; insert into t1 values(38 + 4)
-master-bin.000001 6126 Query 1 5953 use `test`; insert into t1 values(37 + 4)
-master-bin.000001 6219 Query 1 6046 use `test`; insert into t1 values(36 + 4)
-master-bin.000001 6312 Query 1 6139 use `test`; insert into t1 values(35 + 4)
-master-bin.000001 6405 Query 1 6232 use `test`; insert into t1 values(34 + 4)
-master-bin.000001 6498 Query 1 6325 use `test`; insert into t1 values(33 + 4)
-master-bin.000001 6591 Query 1 6418 use `test`; insert into t1 values(32 + 4)
-master-bin.000001 6684 Query 1 6511 use `test`; insert into t1 values(31 + 4)
-master-bin.000001 6777 Query 1 6604 use `test`; insert into t1 values(30 + 4)
-master-bin.000001 6870 Query 1 6697 use `test`; insert into t1 values(29 + 4)
-master-bin.000001 6963 Query 1 6790 use `test`; insert into t1 values(28 + 4)
-master-bin.000001 7056 Query 1 6883 use `test`; insert into t1 values(27 + 4)
-master-bin.000001 7149 Query 1 6976 use `test`; insert into t1 values(26 + 4)
-master-bin.000001 7242 Query 1 7069 use `test`; insert into t1 values(25 + 4)
-master-bin.000001 7335 Query 1 7162 use `test`; insert into t1 values(24 + 4)
-master-bin.000001 7428 Query 1 7255 use `test`; insert into t1 values(23 + 4)
-master-bin.000001 7521 Query 1 7348 use `test`; insert into t1 values(22 + 4)
-master-bin.000001 7614 Query 1 7441 use `test`; insert into t1 values(21 + 4)
-master-bin.000001 7707 Query 1 7534 use `test`; insert into t1 values(20 + 4)
-master-bin.000001 7800 Query 1 7627 use `test`; insert into t1 values(19 + 4)
-master-bin.000001 7893 Query 1 7720 use `test`; insert into t1 values(18 + 4)
-master-bin.000001 7986 Query 1 7813 use `test`; insert into t1 values(17 + 4)
-master-bin.000001 8079 Query 1 7906 use `test`; insert into t1 values(16 + 4)
-master-bin.000001 8172 Query 1 7999 use `test`; insert into t1 values(15 + 4)
-master-bin.000001 8265 Query 1 8092 use `test`; insert into t1 values(14 + 4)
-master-bin.000001 8358 Query 1 8185 use `test`; insert into t1 values(13 + 4)
-master-bin.000001 8451 Query 1 8278 use `test`; insert into t1 values(12 + 4)
-master-bin.000001 8544 Query 1 8371 use `test`; insert into t1 values(11 + 4)
-master-bin.000001 8637 Query 1 8464 use `test`; insert into t1 values(10 + 4)
-master-bin.000001 8730 Query 1 8556 use `test`; insert into t1 values(9 + 4)
-master-bin.000001 8822 Query 1 8648 use `test`; insert into t1 values(8 + 4)
-master-bin.000001 8914 Query 1 8740 use `test`; insert into t1 values(7 + 4)
-master-bin.000001 9006 Query 1 8832 use `test`; insert into t1 values(6 + 4)
-master-bin.000001 9098 Query 1 8924 use `test`; insert into t1 values(5 + 4)
-master-bin.000001 9190 Query 1 9016 use `test`; insert into t1 values(4 + 4)
-master-bin.000001 9282 Query 1 9108 use `test`; insert into t1 values(3 + 4)
-master-bin.000001 9374 Query 1 9200 use `test`; insert into t1 values(2 + 4)
-master-bin.000001 9466 Query 1 9292 use `test`; insert into t1 values(1 + 4)
-master-bin.000001 9558 Xid 1 9319 COMMIT /* xid=146 */
-master-bin.000001 9585 Rotate 1 9629 master-bin.000002;pos=4
-show binlog events in 'master-bin.000002';
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000002 4 Format_desc 1 96 Server ver: VERSION, Binlog ver: 4
-master-bin.000002 96 Query 1 173 use `test`; drop table t1
diff --git a/mysql-test/r/rpl_view.result b/mysql-test/r/rpl_view.result
new file mode 100644
index 00000000000..ce807a361ba
--- /dev/null
+++ b/mysql-test/r/rpl_view.result
@@ -0,0 +1,44 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+drop table if exists t1,v1;
+drop view if exists t1,v1;
+create table t1 (a int);
+insert into t1 values (1);
+create view v1 as select a from t1;
+insert into v1 values (2);
+select * from v1 order by a;
+a
+1
+2
+select * from v1 order by a;
+a
+1
+2
+update v1 set a=3 where a=1;
+select * from v1 order by a;
+a
+2
+3
+select * from v1 order by a;
+a
+2
+3
+delete from v1 where a=2;
+select * from v1 order by a;
+a
+3
+select * from v1 order by a;
+a
+3
+alter view v1 as select a as b from t1;
+select * from v1 order by 1;
+b
+3
+drop view v1;
+select * from v1 order by a;
+ERROR 42S02: Table 'test.v1' doesn't exist
+drop table t1;
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index 3edfbdc726e..f3a42d75258 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -2096,8 +2096,7 @@ s1 count(s1)
1 1
NULL 2
drop procedure bug7013|
-drop table if exists t4;
---enable_warnings|
+drop table if exists t4|
create table t4 (
a mediumint(8) unsigned not null auto_increment,
b smallint(5) unsigned not null,
@@ -2480,5 +2479,17 @@ ERROR 42000: Can't find any matching row in the user table
select bug5278()|
ERROR 42000: Can't find any matching row in the user table
drop function bug5278|
+drop procedure if exists p1|
+create table t3(id int)|
+insert into t3 values(1)|
+create procedure bug7992()
+begin
+declare i int;
+select max(id)+1 into i from t3;
+end|
+call bug7992()|
+call bug7992()|
+drop procedure bug7992|
+drop table t3|
drop table t1;
drop table t2;
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index 21f07317159..ece710a7a1b 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -1726,3 +1726,55 @@ select * from v1 where F1 = 1;
f1
drop view v1;
drop table t1;
+create table t1(c1 int);
+create table t2(c2 int);
+insert into t1 values (1),(2),(3);
+insert into t2 values (1);
+SELECT c1 FROM t1 WHERE c1 IN (SELECT c2 FROM t2);
+c1
+1
+SELECT c1 FROM t1 WHERE EXISTS (SELECT c2 FROM t2 WHERE c2 = c1);
+c1
+1
+create view v1 as SELECT c1 FROM t1 WHERE c1 IN (SELECT c2 FROM t2);
+create view v2 as SELECT c1 FROM t1 WHERE EXISTS (SELECT c2 FROM t2 WHERE c2 = c1);
+select * from v1;
+c1
+1
+select * from v2;
+c1
+1
+select * from (select c1 from v2) X;
+c1
+1
+drop view v2, v1;
+drop table t1, t2;
+CREATE TABLE t1 (C1 INT, C2 INT);
+CREATE TABLE t2 (C2 INT);
+CREATE VIEW v1 AS SELECT C2 FROM t2;
+CREATE VIEW v2 AS SELECT C1 FROM t1 LEFT OUTER JOIN v1 USING (C2);
+SELECT * FROM v2;
+C1
+drop view v2, v1;
+drop table t1, t2;
+create table t1 (col1 char(5),col2 int,col3 int);
+insert into t1 values ('one',10,25), ('two',10,50), ('two',10,50), ('one',20,25), ('one',30,25);
+create view v1 as select * from t1;
+select col1,group_concat(col2,col3) from t1 group by col1;
+col1 group_concat(col2,col3)
+one 1025,2025,3025
+two 1050,1050
+select col1,group_concat(col2,col3) from v1 group by col1;
+col1 group_concat(col2,col3)
+two 1025,2025,3025
+two 1050,1050
+drop view v1;
+drop table t1;
+create table t1 (s1 int, s2 char);
+create view v1 as select s1, s2 from t1;
+select s2 from v1 vq1 where 2 = (select count(*) from v1 vq2 having vq1.s2 = vq2.s2);
+ERROR 42S22: Unknown column 'vq2.s2' in 'having clause'
+select s2 from v1 vq1 where 2 = (select count(*) aa from v1 vq2 having vq1.s2 = aa);
+s2
+drop view v1;
+drop table t1;
diff --git a/mysql-test/r/view_query_cache.result b/mysql-test/r/view_query_cache.result
index f46f0f609cd..e6c2c0152f3 100644
--- a/mysql-test/r/view_query_cache.result
+++ b/mysql-test/r/view_query_cache.result
@@ -1,3 +1,5 @@
+drop table if exists t1,t2,v1,v2,v3;
+drop view if exists t1,t2,v1,v2,v3;
set GLOBAL query_cache_size=1355776;
flush status;
create table t1 (a int, b int);
@@ -98,4 +100,27 @@ Qcache_hits 1
drop view v1;
set query_cache_type=default;
drop table t1;
+create table t1 (a int);
+insert into t1 values (1), (2), (3);
+create view v1 as select a from t1 where a > 1;
+select * from v1;
+a
+2
+3
+alter view v1 as select a from t1 where a > 2;
+select * from v1;
+a
+3
+drop view v1;
+select * from v1;
+ERROR 42S02: Table 'test.v1' doesn't exist
+drop table t1;
+create table t1 (a int, primary key (a), b int);
+create table t2 (a int, primary key (a), b int);
+insert into t2 values (1000, 2000);
+create view v3 (a,b) as select t1.a as a, t2.a as b from t1, t2;
+select * from v3;
+a b
+drop view v3;
+drop table t1, t2;
set GLOBAL query_cache_size=default;
diff --git a/mysql-test/t/binlog-master.opt b/mysql-test/t/binlog-master.opt
new file mode 100644
index 00000000000..ad2c6a647b5
--- /dev/null
+++ b/mysql-test/t/binlog-master.opt
@@ -0,0 +1 @@
+-O max_binlog_size=4096
diff --git a/mysql-test/t/binlog.test b/mysql-test/t/binlog.test
new file mode 100644
index 00000000000..5862861eaeb
--- /dev/null
+++ b/mysql-test/t/binlog.test
@@ -0,0 +1,45 @@
+#
+# misc binlogging tests that do not require a slave running
+#
+-- source include/have_bdb.inc
+-- source include/have_innodb.inc
+
+--disable_warnings
+drop table if exists t1, t2;
+--enable_warnings
+reset master;
+
+create table t1 (a int) engine=bdb;
+create table t2 (a int) engine=innodb;
+begin;
+insert t1 values (5);
+commit;
+begin;
+insert t2 values (5);
+commit;
+# first COMMIT must be Query_log_event, second - Xid_log_event
+--replace_result "xid=18" "xid=11"
+show binlog events from 96;
+drop table t1,t2;
+
+#
+# binlog rotation after one big transaction
+#
+reset master;
+let $1=100;
+
+create table t1 (n int) engine=innodb;
+begin;
+--disable_query_log
+while ($1)
+{
+ eval insert into t1 values($1 + 4);
+ dec $1;
+}
+--enable_query_log
+commit;
+drop table t1;
+--replace_result "xid=29" "xid=18"
+show binlog events in 'master-bin.000001' from 96;
+show binlog events in 'master-bin.000002' from 96;
+
diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test
index 6514f3d5c94..82f91081d03 100644
--- a/mysql-test/t/innodb.test
+++ b/mysql-test/t/innodb.test
@@ -141,6 +141,10 @@ release savepoint `my_savepoint`;
select n from t1;
-- error 1305
rollback to savepoint `my_savepoint`;
+insert into t1 values (8);
+savepoint sv;
+commit;
+savepoint sv;
set autocommit=1;
# nop
rollback;
diff --git a/mysql-test/t/kill.test b/mysql-test/t/kill.test
index 65d4f27059f..c8adff32eb7 100644
--- a/mysql-test/t/kill.test
+++ b/mysql-test/t/kill.test
@@ -35,3 +35,22 @@ select @id != connection_id();
connection con2;
select 4;
drop table t1;
+
+#
+# test of blocking of sending ERROR after OK or EOF
+#
+connection con1;
+select get_lock("a", 10);
+connection con2;
+let $ID= `select connection_id()`;
+send select get_lock("a", 10);
+-- sleep 2
+connection con1;
+disable_query_log;
+eval kill query $ID;
+enable_query_log;
+connection con2;
+reap;
+select 1;
+connection con1;
+select RELEASE_LOCK("a");
diff --git a/mysql-test/t/rpl_insert_id.test b/mysql-test/t/rpl_insert_id.test
index 4c27c03af60..a4506e32963 100644
--- a/mysql-test/t/rpl_insert_id.test
+++ b/mysql-test/t/rpl_insert_id.test
@@ -61,3 +61,19 @@ drop table t2;
save_master_pos;
connection slave;
sync_with_master;
+
+#
+# Bug#8412: Error codes reported in binary log for CHARACTER SET,
+# FOREIGN_KEY_CHECKS
+#
+connection master;
+SET TIMESTAMP=1000000000;
+CREATE TABLE t1 ( a INT UNIQUE );
+SET FOREIGN_KEY_CHECKS=0;
+--error 1062
+INSERT INTO t1 VALUES (1),(1);
+sync_slave_with_master;
+
+
+
+
diff --git a/mysql-test/t/rpl_rotate_logs.test b/mysql-test/t/rpl_rotate_logs.test
index 47b5754232c..7622a93e2a3 100644
--- a/mysql-test/t/rpl_rotate_logs.test
+++ b/mysql-test/t/rpl_rotate_logs.test
@@ -153,30 +153,3 @@ connection master;
drop table if exists t1,t2,t3,t4;
sync_slave_with_master;
-#
-# now the same in a transaction
-#
-slave stop; # we don't need it anymore
-connection master;
-reset master;
-let $1=100;
-
---disable_warnings
-create table t1 (n int) engine=innodb;
---enable_warnings
-begin;
---disable_query_log
-while ($1)
-{
- eval insert into t1 values($1 + 4);
- dec $1;
-}
---enable_query_log
-commit;
-drop table t1;
-let $VERSION=`select version()`;
---replace_result $VERSION VERSION "xid=373" "xid=146"
-show binlog events in 'master-bin.000001';
---replace_result $VERSION VERSION
-show binlog events in 'master-bin.000002';
-
diff --git a/mysql-test/t/rpl_view.test b/mysql-test/t/rpl_view.test
new file mode 100644
index 00000000000..c50e9fc6dc9
--- /dev/null
+++ b/mysql-test/t/rpl_view.test
@@ -0,0 +1,44 @@
+source include/master-slave.inc;
+--disable_warnings
+drop table if exists t1,v1;
+drop view if exists t1,v1;
+sync_slave_with_master;
+--enable_warnings
+
+#
+# Check that createion drop of view is replicated, also check replication of
+# updating of view
+#
+connection master;
+create table t1 (a int);
+insert into t1 values (1);
+create view v1 as select a from t1;
+insert into v1 values (2);
+select * from v1 order by a;
+sync_slave_with_master;
+# view already have to be on slave
+select * from v1 order by a;
+connection master;
+update v1 set a=3 where a=1;
+select * from v1 order by a;
+sync_slave_with_master;
+select * from v1 order by a;
+connection master;
+delete from v1 where a=2;
+select * from v1 order by a;
+sync_slave_with_master;
+select * from v1 order by a;
+connection master;
+# 'alter view' internally maped to creation, but still check that it works
+alter view v1 as select a as b from t1;
+sync_slave_with_master;
+select * from v1 order by 1;
+connection master;
+drop view v1;
+sync_slave_with_master;
+#error, because view have to be removed from slave
+-- error 1146
+select * from v1 order by a;
+connection master;
+drop table t1;
+sync_slave_with_master;
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index 6fe8edc5244..2cfd27134ad 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -2572,7 +2572,7 @@ drop procedure bug7013|
# BUG#7743: 'Lost connection to MySQL server during query' on Stored Procedure
#
--disable_warnings
-drop table if exists t4;
+drop table if exists t4|
--enable_warnings
create table t4 (
a mediumint(8) unsigned not null auto_increment,
@@ -2982,7 +2982,26 @@ select bug5278()|
select bug5278()|
drop function bug5278|
+#
+# BUG#7992: rolling back temporary Item tree changes in SP
+#
+--disable_warnings
+drop procedure if exists p1|
+--enable_warnings
+create table t3(id int)|
+insert into t3 values(1)|
+create procedure bug7992()
+begin
+ declare i int;
+ select max(id)+1 into i from t3;
+end|
+
+call bug7992()|
+call bug7992()|
+drop procedure bug7992|
+drop table t3|
delimiter ;|
drop table t1;
drop table t2;
+
diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test
index fa0e2fbb8d0..ff300235ea8 100644
--- a/mysql-test/t/view.test
+++ b/mysql-test/t/view.test
@@ -1658,9 +1658,62 @@ select * from v3;
drop view v3;
drop tables t1,t2;
+#
# View field names should be case insensitive
+#
create table t1(f1 int);
create view v1 as select f1 from t1;
select * from v1 where F1 = 1;
drop view v1;
drop table t1;
+
+#
+# Resolving view fields in subqueries in VIEW (Bug #6394)
+#
+create table t1(c1 int);
+create table t2(c2 int);
+insert into t1 values (1),(2),(3);
+insert into t2 values (1);
+SELECT c1 FROM t1 WHERE c1 IN (SELECT c2 FROM t2);
+SELECT c1 FROM t1 WHERE EXISTS (SELECT c2 FROM t2 WHERE c2 = c1);
+create view v1 as SELECT c1 FROM t1 WHERE c1 IN (SELECT c2 FROM t2);
+create view v2 as SELECT c1 FROM t1 WHERE EXISTS (SELECT c2 FROM t2 WHERE c2 = c1);
+select * from v1;
+select * from v2;
+select * from (select c1 from v2) X;
+drop view v2, v1;
+drop table t1, t2;
+
+#
+# view over other view setup (BUG#7433)
+#
+CREATE TABLE t1 (C1 INT, C2 INT);
+CREATE TABLE t2 (C2 INT);
+CREATE VIEW v1 AS SELECT C2 FROM t2;
+CREATE VIEW v2 AS SELECT C1 FROM t1 LEFT OUTER JOIN v1 USING (C2);
+SELECT * FROM v2;
+drop view v2, v1;
+drop table t1, t2;
+
+#
+# view and group_concat() (BUG#7116)
+#
+create table t1 (col1 char(5),col2 int,col3 int);
+insert into t1 values ('one',10,25), ('two',10,50), ('two',10,50), ('one',20,25), ('one',30,25);
+create view v1 as select * from t1;
+select col1,group_concat(col2,col3) from t1 group by col1;
+select col1,group_concat(col2,col3) from v1 group by col1;
+drop view v1;
+drop table t1;
+
+#
+# Item_ref resolved as view field (BUG#6894)
+#
+create table t1 (s1 int, s2 char);
+create view v1 as select s1, s2 from t1;
+-- error 1054
+select s2 from v1 vq1 where 2 = (select count(*) from v1 vq2 having vq1.s2 = vq2.s2);
+select s2 from v1 vq1 where 2 = (select count(*) aa from v1 vq2 having vq1.s2 = aa);
+drop view v1;
+drop table t1;
+
diff --git a/mysql-test/t/view_query_cache.test b/mysql-test/t/view_query_cache.test
index dd9c8006915..bca111a5ed1 100644
--- a/mysql-test/t/view_query_cache.test
+++ b/mysql-test/t/view_query_cache.test
@@ -2,6 +2,11 @@
#
# QUERY CACHE options for VIEWs
#
+--disable_warnings
+drop table if exists t1,t2,v1,v2,v3;
+drop view if exists t1,t2,v1,v2,v3;
+--enable_warnings
+
set GLOBAL query_cache_size=1355776;
flush status;
create table t1 (a int, b int);
@@ -53,6 +58,30 @@ drop view v1;
set query_cache_type=default;
drop table t1;
-set GLOBAL query_cache_size=default;
+#
+# invalidation of view
+#
+create table t1 (a int);
+insert into t1 values (1), (2), (3);
+create view v1 as select a from t1 where a > 1;
+select * from v1;
+alter view v1 as select a from t1 where a > 2;
+select * from v1;
+drop view v1;
+-- error 1146
+select * from v1;
+drop table t1;
+
+#
+# join view with QC
+#
+create table t1 (a int, primary key (a), b int);
+create table t2 (a int, primary key (a), b int);
+insert into t2 values (1000, 2000);
+create view v3 (a,b) as select t1.a as a, t2.a as b from t1, t2;
+select * from v3;
+drop view v3;
+drop table t1, t2;
+set GLOBAL query_cache_size=default;
diff --git a/mysys/my_mmap.c b/mysys/my_mmap.c
index 0225e7fac24..ed662a38712 100644
--- a/mysys/my_mmap.c
+++ b/mysys/my_mmap.c
@@ -84,6 +84,12 @@ int my_msync(int fd, void *addr, size_t len, int flags)
}
#endif
+
+#ifdef _WINDOWS
+#pragma message "no mmap!"
+#else
#warning "no mmap!"
#endif
+#endif
+
diff --git a/ndb/src/mgmsrv/MgmtSrvr.cpp b/ndb/src/mgmsrv/MgmtSrvr.cpp
index cf98f3a09ae..e915216c793 100644
--- a/ndb/src/mgmsrv/MgmtSrvr.cpp
+++ b/ndb/src/mgmsrv/MgmtSrvr.cpp
@@ -2251,9 +2251,6 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId,
id_found= tmp;
break;
}
- assert(no_mgm > 1);
- assert(*nodeId != 0);
- assert(type != NDB_MGM_NODE_TYPE_MGM);
if (id_found) { // mgmt server may only have one match
error_string.appfmt("Ambiguous node id's %d and %d.\n"
"Suggest specifying node id in connectstring,\n"
diff --git a/sql/handler.h b/sql/handler.h
index a9e26e7fe4c..d4e24bbb411 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -197,7 +197,7 @@ enum row_type { ROW_TYPE_NOT_USED=-1, ROW_TYPE_DEFAULT, ROW_TYPE_FIXED,
#define HA_CREATE_USED_COMMENT (1L << 16)
#define HA_CREATE_USED_PASSWORD (1L << 17)
-typedef ulonglong my_xid;
+typedef ulonglong my_xid; // this line is the same as in log_event.h
#define MYSQL_XID_PREFIX "MySQLXid"
#define MYSQL_XID_PREFIX_LEN 8 // must be a multiple of 8
#define MYSQL_XID_OFFSET (MYSQL_XID_PREFIX_LEN+sizeof(server_id))
diff --git a/sql/item.cc b/sql/item.cc
index da9c98862b7..3b920bd218d 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -2101,23 +2101,29 @@ bool Item_ref_null_helper::get_date(TIME *ltime, uint fuzzydate)
/*
- Mark item and SELECT_LEXs as dependent if it is not outer resolving
+ Mark item and SELECT_LEXs as dependent if item was resolved in outer SELECT
SYNOPSIS
mark_as_dependent()
thd - thread handler
last - select from which current item depend
current - current select
- item - item which should be marked
+ resolved_item - item which was resolved in outer SELECT(for warning)
+ mark_item - item which should be marked (can be differ in case of
+ substitution)
*/
static void mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current,
- Item_ident *item)
+ Item_ident *resolved_item,
+ Item_ident *mark_item)
{
- const char *db_name= item->db_name ? item->db_name : "";
- const char *table_name= item->table_name ? item->table_name : "";
+ const char *db_name= (resolved_item->db_name ?
+ resolved_item->db_name : "");
+ const char *table_name= (resolved_item->table_name ?
+ resolved_item->table_name : "");
/* store pointer on SELECT_LEX from which item is dependent */
- item->depended_from= last;
+ if (mark_item)
+ mark_item->depended_from= last;
current->mark_as_dependent(last);
if (thd->lex->describe & DESCRIBE_EXTENDED)
{
@@ -2125,7 +2131,7 @@ static void mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current,
sprintf(warn_buff, ER(ER_WARN_FIELD_RESOLVED),
db_name, (db_name[0] ? "." : ""),
table_name, (table_name [0] ? "." : ""),
- item->field_name,
+ resolved_item->field_name,
current->select_number, last->select_number);
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_WARN_FIELD_RESOLVED, warn_buff);
@@ -2391,6 +2397,11 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference)
{
bool upward_lookup= FALSE;
Field *from_field= (Field *)not_found_field;
+ /*
+ In case of view, find_field_in_tables() write pointer to view field
+ expression to 'reference', i.e. it substitute that expression instead
+ of this Item_field
+ */
if ((from_field= find_field_in_tables(thd, this, tables, reference,
IGNORE_EXCEPT_NON_UNIQUE,
!any_privileges)) ==
@@ -2436,6 +2447,10 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference)
Check table fields only if the subquery is used somewhere out of
HAVING, or the outer SELECT does not use grouping (i.e. tables are
accessible).
+
+ In case of view, find_field_in_tables() write pointer to view
+ field expression to 'reference', i.e. it substitute that
+ expression instead of this Item_field
*/
if ((place != IN_HAVING ||
(outer_sel->with_sum_func == 0 &&
@@ -2455,10 +2470,21 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference)
}
else
{
+ Item::Type type= (*reference)->type();
prev_subselect_item->used_tables_cache|=
(*reference)->used_tables();
prev_subselect_item->const_item_cache&=
(*reference)->const_item();
+ mark_as_dependent(thd, last, current_sel, this,
+ ((type == REF_ITEM || type == FIELD_ITEM) ?
+ (Item_ident*) (*reference) :
+ 0));
+ /*
+ view reference found, we substituted it instead of this
+ Item (find_field_in_tables do it by assigning new value to
+ *reference), so can quit
+ */
+ return FALSE;
}
}
break;
@@ -2536,12 +2562,12 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference)
if (rf->fix_fields(thd, tables, reference) || rf->check_cols(1))
return TRUE;
- mark_as_dependent(thd, last, current_sel, rf);
+ mark_as_dependent(thd, last, current_sel, this, rf);
return FALSE;
}
else
{
- mark_as_dependent(thd, last, current_sel, this);
+ mark_as_dependent(thd, last, current_sel, this, this);
if (last->having_fix_field)
{
Item_ref *rf;
@@ -2574,8 +2600,10 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference)
Also we suppose that view can't be changed during PS/SP life.
*/
- if (from_field != view_ref_found)
- set_field(from_field);
+ if (from_field == view_ref_found)
+ return FALSE;
+
+ set_field(from_field);
}
else if (thd->set_query_id && field->query_id != thd->query_id)
{
@@ -3569,6 +3597,11 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference)
(!outer_sel->with_sum_func &&
outer_sel->group_list.elements == 0)))
{
+ /*
+ In case of view, find_field_in_tables() write pointer to view
+ field expression to 'reference', i.e. it substitute that
+ expression instead of this Item_ref
+ */
if ((from_field= find_field_in_tables(thd, this, table_list,
reference,
IGNORE_EXCEPT_NON_UNIQUE,
@@ -3582,10 +3615,21 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference)
}
else
{
+ Item::Type type= (*reference)->type();
prev_subselect_item->used_tables_cache|=
(*reference)->used_tables();
prev_subselect_item->const_item_cache&=
(*reference)->const_item();
+ DBUG_ASSERT((*reference)->type() == REF_ITEM);
+ mark_as_dependent(thd, last, current_sel, this,
+ ((type == REF_ITEM || type == FIELD_ITEM) ?
+ (Item_ident*) (*reference) :
+ 0));
+ /*
+ view reference found, we substituted it instead of this
+ Item, so can quit
+ */
+ return FALSE;
}
break;
}
@@ -3624,7 +3668,7 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference)
if (!(fld= new Item_field(from_field)))
return TRUE;
thd->change_item_tree(reference, fld);
- mark_as_dependent(thd, last, thd->lex->current_select, fld);
+ mark_as_dependent(thd, last, thd->lex->current_select, this, fld);
return FALSE;
}
/*
@@ -3642,7 +3686,7 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference)
{
/* Should be checked in resolve_ref_in_select_and_group(). */
DBUG_ASSERT(*ref && (*ref)->fixed);
- mark_as_dependent(thd, last, current_sel, this);
+ mark_as_dependent(thd, last, current_sel, this, this);
}
}
else
diff --git a/sql/log.cc b/sql/log.cc
index a873d75def9..b37d053dfd7 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -80,8 +80,13 @@ static int binlog_close_connection(THD *thd)
return 0;
}
-static inline void binlog_cleanup_trans(IO_CACHE *trans_log)
+static int binlog_end_trans(THD *thd, IO_CACHE *trans_log, Log_event *end_ev)
{
+ int error=0;
+ DBUG_ENTER("binlog_end_trans");
+ if (end_ev)
+ error= mysql_bin_log.write(thd, trans_log, end_ev);
+
statistic_increment(binlog_cache_use, &LOCK_status);
if (trans_log->disk_writes != 0)
{
@@ -90,6 +95,7 @@ static inline void binlog_cleanup_trans(IO_CACHE *trans_log)
}
reinit_io_cache(trans_log, WRITE_CACHE, (my_off_t) 0, 0, 1); // cannot fail
trans_log->end_of_file= max_binlog_cache_size;
+ DBUG_RETURN(error);
}
static int binlog_prepare(THD *thd, bool all)
@@ -105,7 +111,6 @@ static int binlog_prepare(THD *thd, bool all)
static int binlog_commit(THD *thd, bool all)
{
- int error;
IO_CACHE *trans_log= (IO_CACHE*)thd->ha_data[binlog_hton.slot];
DBUG_ENTER("binlog_commit");
DBUG_ASSERT(mysql_bin_log.is_open() &&
@@ -116,11 +121,8 @@ static int binlog_commit(THD *thd, bool all)
// we're here because trans_log was flushed in MYSQL_LOG::log()
DBUG_RETURN(0);
}
-
- /* Update the binary log as we have cached some queries */
- error= mysql_bin_log.write(thd, trans_log);
- binlog_cleanup_trans(trans_log);
- DBUG_RETURN(error);
+ Query_log_event qev(thd, "COMMIT", 6, TRUE, FALSE);
+ DBUG_RETURN(binlog_end_trans(thd, trans_log, &qev));
}
static int binlog_rollback(THD *thd, bool all)
@@ -144,10 +146,10 @@ static int binlog_rollback(THD *thd, bool all)
if (unlikely(thd->options & OPTION_STATUS_NO_TRANS_UPDATE))
{
Query_log_event qev(thd, "ROLLBACK", 8, TRUE, FALSE);
- qev.write(trans_log);
- error= mysql_bin_log.write(thd, trans_log);
+ error= binlog_end_trans(thd, trans_log, &qev);
}
- binlog_cleanup_trans(trans_log);
+ else
+ error= binlog_end_trans(thd, trans_log, 0);
DBUG_RETURN(error);
}
@@ -1735,7 +1737,9 @@ COLLATION_CONNECTION=%u,COLLATION_DATABASE=%u,COLLATION_SERVER=%u",
}
}
- /* Write the SQL command */
+ /*
+ Write the SQL command
+ */
if (event_info->write(file))
goto err;
@@ -1822,11 +1826,11 @@ uint MYSQL_LOG::next_file_id()
that the same updates are run on the slave.
*/
-bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache)
+bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event)
{
bool error= 0;
VOID(pthread_mutex_lock(&LOCK_log));
- DBUG_ENTER("MYSQL_LOG::write(THD *, IO_CACHE *)");
+ DBUG_ENTER("MYSQL_LOG::write(THD *, IO_CACHE *, Log_event *)");
if (likely(is_open())) // Should always be true
{
@@ -1835,9 +1839,8 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache)
/*
Log "BEGIN" at the beginning of the transaction.
which may contain more than 1 SQL statement.
- There is no need to append "COMMIT", as it's already in the 'cache'
- (in fact, Xid_log_event is there which does the commit on slaves)
*/
+ if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
{
Query_log_event qinfo(thd, "BEGIN", 5, TRUE, FALSE);
/*
@@ -1869,10 +1872,14 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache)
if (my_b_write(&log_file, cache->read_pos, length))
goto err;
cache->read_pos=cache->read_end; // Mark buffer used up
+ DBUG_EXECUTE_IF("half_binlogged_transaction", goto DBUG_skip_commit;);
} while ((length=my_b_fill(cache)));
+ if (commit_event->write(&log_file))
+ goto err;
+DBUG_skip_commit:
if (flush_io_cache(&log_file) || sync_binlog(&log_file))
- goto err;
+ goto err;
DBUG_EXECUTE_IF("half_binlogged_transaction", abort(););
if (cache->error) // Error on read
{
@@ -2985,10 +2992,9 @@ void TC_LOG_BINLOG::close()
int TC_LOG_BINLOG::log(THD *thd, my_xid xid)
{
Xid_log_event xle(thd, xid);
- if (xle.write((IO_CACHE*)thd->ha_data[binlog_hton.slot]))
- return 0;
+ IO_CACHE *trans_log= (IO_CACHE*)thd->ha_data[binlog_hton.slot];
thread_safe_increment(prepared_xids, &LOCK_prep_xids);
- return !binlog_commit(thd,1); // invert return value
+ return !binlog_end_trans(thd, trans_log, &xle); // invert return value
}
void TC_LOG_BINLOG::unlog(ulong cookie, my_xid xid)
diff --git a/sql/log_event.cc b/sql/log_event.cc
index bbf894c2385..fa193df40a2 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -3140,10 +3140,9 @@ void Xid_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_eve
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
int Xid_log_event::exec_event(struct st_relay_log_info* rli)
{
- rli->inc_event_relay_log_pos();
/* For a slave Xid_log_event is COMMIT */
mysql_log.write(thd,COM_QUERY,"COMMIT /* implicit, from Xid_log_event */");
- return end_trans(thd, COMMIT);
+ return end_trans(thd, COMMIT) || Log_event::exec_event(rli);
}
#endif /* !MYSQL_CLIENT */
diff --git a/sql/log_event.h b/sql/log_event.h
index f422a91f358..7a041959f92 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -1077,7 +1077,7 @@ class Rand_log_event: public Log_event
****************************************************************************/
#ifdef MYSQL_CLIENT
-typedef ulong my_xid;
+typedef ulonglong my_xid; // this line is the same as in handler.h
#endif
class Xid_log_event: public Log_event
diff --git a/sql/my_decimal.h b/sql/my_decimal.h
index b3d6b6ccde6..c02b0cb4c8b 100644
--- a/sql/my_decimal.h
+++ b/sql/my_decimal.h
@@ -244,8 +244,7 @@ int str2my_decimal(uint mask, const char *str, my_decimal *d, char **end)
int str2my_decimal(uint mask, const char *from, uint length,
CHARSET_INFO *charset, my_decimal *decimal_value);
-
-#ifdef MYSQL_SERVER
+#if defined(MYSQL_SERVER) || defined(EMBEDDED_LIBRARY)
inline
int string2my_decimal(uint mask, const String *str, my_decimal *d)
{
@@ -253,7 +252,6 @@ int string2my_decimal(uint mask, const String *str, my_decimal *d)
}
#endif
-
inline
int double2my_decimal(uint mask, double val, my_decimal *d)
{
diff --git a/sql/net_serv.cc b/sql/net_serv.cc
index bd3bbe3e1a9..2de5853599f 100644
--- a/sql/net_serv.cc
+++ b/sql/net_serv.cc
@@ -121,8 +121,7 @@ my_bool my_net_init(NET *net, Vio* vio)
DBUG_RETURN(1);
net->buff_end=net->buff+net->max_packet;
net->vio = vio;
- net->no_send_ok = 0;
- net->no_send_eof = 0;
+ net->no_send_ok= net->no_send_eof= net->no_send_error= 0;
net->error=0; net->return_errno=0; net->return_status=0;
net->pkt_nr=net->compress_pkt_nr=0;
net->write_pos=net->read_pos = net->buff;
diff --git a/sql/protocol.cc b/sql/protocol.cc
index b84d170873d..f31462ddad1 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -66,6 +66,12 @@ void net_send_error(THD *thd, uint sql_errno, const char *err)
err ? err : net->last_error[0] ?
net->last_error : "NULL"));
+ if (net && net->no_send_error)
+ {
+ thd->clear_error();
+ DBUG_PRINT("info", ("sending error messages prohibited"));
+ DBUG_VOID_RETURN;
+ }
if (thd->spcont && thd->spcont->find_handler(sql_errno,
MYSQL_ERROR::WARN_LEVEL_ERROR))
{
@@ -158,6 +164,13 @@ net_printf_error(THD *thd, uint errcode, ...)
DBUG_ENTER("net_printf_error");
DBUG_PRINT("enter",("message: %u",errcode));
+ if (net && net->no_send_error)
+ {
+ thd->clear_error();
+ DBUG_PRINT("info", ("sending error messages prohibited"));
+ DBUG_VOID_RETURN;
+ }
+
if (thd->spcont && thd->spcont->find_handler(errcode,
MYSQL_ERROR::WARN_LEVEL_ERROR))
{
@@ -306,6 +319,9 @@ send_ok(THD *thd, ha_rows affected_rows, ulonglong id, const char *message)
VOID(net_flush(net));
/* We can't anymore send an error to the client */
thd->net.report_error= 0;
+ thd->net.no_send_error= 1;
+ DBUG_PRINT("info", ("OK sent, so no more error sendong allowed"));
+
DBUG_VOID_RETURN;
}
@@ -363,6 +379,8 @@ send_eof(THD *thd, bool no_flush)
if (!no_flush)
VOID(net_flush(net));
}
+ thd->net.no_send_error= 1;
+ DBUG_PRINT("info", ("EOF sent, so no more error sendong allowed"));
}
DBUG_VOID_RETURN;
}
diff --git a/sql/set_var.cc b/sql/set_var.cc
index fc144a908a4..fc0802bf185 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -2097,7 +2097,7 @@ bool sys_var_character_set_server::check(THD *thd, set_var *var)
(mysql_bin_log.is_open() ||
active_mi->slave_running || active_mi->rli.slave_running))
{
- my_error(ER_LOGING_PROHIBIT_CHANGING_OF, MYF(0),
+ my_error(ER_LOGGING_PROHIBIT_CHANGING_OF, MYF(0),
"character set, collation");
return 1;
}
@@ -2204,7 +2204,7 @@ bool sys_var_collation_server::check(THD *thd, set_var *var)
(mysql_bin_log.is_open() ||
active_mi->slave_running || active_mi->rli.slave_running))
{
- my_error(ER_LOGING_PROHIBIT_CHANGING_OF, MYF(0),
+ my_error(ER_LOGGING_PROHIBIT_CHANGING_OF, MYF(0),
"character set, collation");
return 1;
}
@@ -2554,7 +2554,7 @@ bool sys_var_thd_time_zone::check(THD *thd, set_var *var)
(mysql_bin_log.is_open() ||
active_mi->slave_running || active_mi->rli.slave_running))
{
- my_error(ER_LOGING_PROHIBIT_CHANGING_OF, MYF(0), "time zone");
+ my_error(ER_LOGGING_PROHIBIT_CHANGING_OF, MYF(0), "time zone");
return 1;
}
#endif
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index fa20e52f7e7..5757510bfb4 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -5276,7 +5276,7 @@ ER_NO_GROUP_FOR_PROC
eng "Select must have a group with this procedure"
ER_ORDER_WITH_PROC
eng "Can't use ORDER clause with this procedure"
-ER_LOGING_PROHIBIT_CHANGING_OF
+ER_LOGGING_PROHIBIT_CHANGING_OF
eng "Binary logging and replication forbid changing the global server %s"
ER_NO_FILE_MAPPING
eng "Can't map file: %-.64s, errno: %d"
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 651fa947694..f3a61b43c34 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -5554,6 +5554,9 @@ void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant,
/* global privileges */
grant->privilege= thd->master_access;
+ if (!thd->priv_user)
+ return; // it is slave
+
/* db privileges */
grant->privilege|= acl_get(thd->host, thd->ip, thd->priv_user, db, 0);
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index 1f85d081d55..5fa161257c7 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -311,7 +311,7 @@ TODO list:
#include "emb_qcache.h"
#endif
-#if defined(EXTRA_DEBUG) && !defined(DBUG_OFF)
+#if !defined(EXTRA_DBUG) && !defined(DBUG_OFF)
#define MUTEX_LOCK(M) { DBUG_PRINT("lock", ("mutex lock 0x%lx", (ulong)(M))); \
pthread_mutex_lock(M);}
#define MUTEX_UNLOCK(M) {DBUG_PRINT("lock", ("mutex unlock 0x%lx",\
@@ -2103,6 +2103,105 @@ void Query_cache::invalidate_table(Query_cache_block *table_block)
}
}
+
+/*
+ Register given table list begining with given position in tables table of
+ block
+
+ SYNOPSIS
+ Query_cache::register_tables_from_list
+ tables_used given table list
+ counter number current position in table of tables of block
+ block_table pointer to current position in tables table of block
+
+ RETURN
+ 0 error
+ number of next position of table entry in table of tables of block
+*/
+
+TABLE_COUNTER_TYPE
+Query_cache::register_tables_from_list(TABLE_LIST *tables_used,
+ TABLE_COUNTER_TYPE counter,
+ Query_cache_block_table *block_table)
+{
+ TABLE_COUNTER_TYPE n;
+ DBUG_ENTER("Query_cache::register_tables_from_list");
+ for (n= counter;
+ tables_used;
+ tables_used= tables_used->next_global, n++, block_table++)
+ {
+ block_table->n= n;
+ if (tables_used->view)
+ {
+ char key[MAX_DBKEY_LENGTH];
+ uint key_length;
+ DBUG_PRINT("qcache", ("view %s, db %s",
+ tables_used->view_name.str,
+ tables_used->view_db.str));
+ key_length= (uint) (strmov(strmov(key, tables_used->view_db.str) + 1,
+ tables_used->view_name.str) - key) + 1;
+ /*
+ There are not callback function for for VIEWs
+ */
+ if (!insert_table(key_length, key, block_table,
+ tables_used->view_db.length + 1,
+ HA_CACHE_TBL_NONTRANSACT, 0, 0))
+ DBUG_RETURN(0);
+ {
+ TABLE_COUNTER_TYPE inc= register_tables_from_list(tables_used->ancestor,
+ n + 1,
+ block_table + 1);
+ if (!inc)
+ DBUG_RETURN(0);
+ n+= inc;
+ block_table+= inc;
+ }
+ }
+ else
+ {
+ DBUG_PRINT("qcache",
+ ("table %s, db %s, openinfo at 0x%lx, keylen %u, key at 0x%lx",
+ tables_used->table->s->table_name,
+ tables_used->table->s->table_cache_key,
+ (ulong) tables_used->table,
+ tables_used->table->s->key_length,
+ (ulong) tables_used->table->s->table_cache_key));
+ if (!insert_table(tables_used->table->s->key_length,
+ tables_used->table->s->table_cache_key, block_table,
+ tables_used->db_length,
+ tables_used->table->file->table_cache_type(),
+ tables_used->callback_func,
+ tables_used->engine_data))
+ DBUG_RETURN(0);
+
+ if (tables_used->table->s->db_type == DB_TYPE_MRG_MYISAM)
+ {
+ ha_myisammrg *handler = (ha_myisammrg *) tables_used->table->file;
+ MYRG_INFO *file = handler->myrg_info();
+ for (MYRG_TABLE *table = file->open_tables;
+ table != file->end_table ;
+ table++)
+ {
+ char key[MAX_DBKEY_LENGTH];
+ uint32 db_length;
+ uint key_length= filename_2_table_key(key, table->table->filename,
+ &db_length);
+ (++block_table)->n= ++n;
+ /*
+ There are not callback function for for MyISAM, and engine data
+ */
+ if (!insert_table(key_length, key, block_table,
+ db_length,
+ tables_used->table->file->table_cache_type(),
+ 0, 0))
+ DBUG_RETURN(0);
+ }
+ }
+ }
+ }
+ DBUG_RETURN(n - counter);
+}
+
/*
Store all used tables
@@ -2124,52 +2223,10 @@ my_bool Query_cache::register_all_tables(Query_cache_block *block,
Query_cache_block_table *block_table = block->table(0);
- for (n= 0;
- tables_used;
- tables_used= tables_used->next_global, n++, block_table++)
- {
- DBUG_PRINT("qcache",
- ("table %s, db %s, openinfo at 0x%lx, keylen %u, key at 0x%lx",
- tables_used->table_name, tables_used->db,
- (ulong) tables_used->table,
- tables_used->table->s->key_length,
- (ulong) tables_used->table->s->table_cache_key));
- block_table->n= n;
- if (!insert_table(tables_used->table->s->key_length,
- tables_used->table->s->table_cache_key, block_table,
- tables_used->db_length,
- tables_used->table->file->table_cache_type(),
- tables_used->callback_func,
- tables_used->engine_data))
- break;
-
- if (tables_used->table->s->db_type == DB_TYPE_MRG_MYISAM)
- {
- ha_myisammrg *handler = (ha_myisammrg *) tables_used->table->file;
- MYRG_INFO *file = handler->myrg_info();
- for (MYRG_TABLE *table = file->open_tables;
- table != file->end_table ;
- table++)
- {
- char key[MAX_DBKEY_LENGTH];
- uint32 db_length;
- uint key_length= filename_2_table_key(key, table->table->filename,
- &db_length);
- (++block_table)->n= ++n;
- /*
- There are not callback function for for MyISAM, and engine data
- */
- if (!insert_table(key_length, key, block_table,
- db_length,
- tables_used->table->file->table_cache_type(),
- 0, 0))
- goto err;
- }
- }
- }
+ n= register_tables_from_list(tables_used, 0, block_table);
err:
- if (tables_used)
+ if (n)
{
DBUG_PRINT("qcache", ("failed at table %d", (int) n));
/* Unlink the tables we allocated above */
@@ -2178,7 +2235,7 @@ err:
tmp++)
unlink_table(tmp);
}
- return (tables_used == 0);
+ return (n);
}
/*
@@ -2676,6 +2733,78 @@ void Query_cache::double_linked_list_join(Query_cache_block *head_tail,
*****************************************************************************/
/*
+ Collect information about table types, check that tables are cachable and
+ count them
+
+ SYNOPSIS
+ process_and_count_tables()
+ tables_used table list for processing
+ tables_type pointer to variable for table types collection
+
+ RETURN
+ 0 error
+ >0 number of tables
+*/
+
+static TABLE_COUNTER_TYPE process_and_count_tables(TABLE_LIST *tables_used,
+ uint8 *tables_type)
+{
+ DBUG_ENTER("process_and_count_tables");
+ TABLE_COUNTER_TYPE table_count = 0;
+ for (; tables_used; tables_used= tables_used->next_global)
+ {
+ table_count++;
+ if (tables_used->view)
+ {
+ DBUG_PRINT("qcache", ("view %s, db %s",
+ tables_used->view_name.str,
+ tables_used->view_db.str));
+ *tables_type|= HA_CACHE_TBL_NONTRANSACT;
+ {
+ TABLE_COUNTER_TYPE subcount;
+ if (!(subcount= process_and_count_tables(tables_used->ancestor,
+ tables_type)))
+ DBUG_RETURN(0);
+ table_count+= subcount;
+ }
+ }
+ else
+ {
+ DBUG_PRINT("qcache", ("table %s, db %s, type %u",
+ tables_used->table->s->table_name,
+ tables_used->table->s->table_cache_key,
+ tables_used->table->s->db_type));
+ *tables_type|= tables_used->table->file->table_cache_type();
+
+ /*
+ table_alias_charset used here because it depends of
+ lower_case_table_names variable
+ */
+ if (tables_used->table->s->tmp_table != NO_TMP_TABLE ||
+ (*tables_type & HA_CACHE_TBL_NOCACHE) ||
+ (tables_used->db_length == 5 &&
+ my_strnncoll(table_alias_charset,
+ (uchar*)tables_used->table->s->table_cache_key, 6,
+ (uchar*)"mysql",6) == 0))
+ {
+ DBUG_PRINT("qcache",
+ ("select not cacheable: temporary, system or \
+ other non-cacheable table(s)"));
+ DBUG_RETURN(0);
+ }
+ if (tables_used->table->s->db_type == DB_TYPE_MRG_MYISAM)
+ {
+ ha_myisammrg *handler = (ha_myisammrg *)tables_used->table->file;
+ MYRG_INFO *file = handler->myrg_info();
+ table_count+= (file->end_table - file->open_tables);
+ }
+ }
+ }
+ DBUG_RETURN(table_count);
+}
+
+
+/*
If query is cacheable return number tables in query
(query without tables are not cached)
*/
@@ -2686,7 +2815,7 @@ TABLE_COUNTER_TYPE Query_cache::is_cacheable(THD *thd, uint32 query_len,
TABLE_LIST *tables_used,
uint8 *tables_type)
{
- TABLE_COUNTER_TYPE table_count = 0;
+ TABLE_COUNTER_TYPE table_count;
DBUG_ENTER("Query_cache::is_cacheable");
if (lex->sql_command == SQLCOM_SELECT &&
@@ -2700,36 +2829,8 @@ TABLE_COUNTER_TYPE Query_cache::is_cacheable(THD *thd, uint32 query_len,
lex->select_lex.options,
(int) thd->variables.query_cache_type));
- for (; tables_used; tables_used= tables_used->next_global)
- {
- table_count++;
- DBUG_PRINT("qcache", ("table %s, db %s, type %u",
- tables_used->table_name,
- tables_used->db, tables_used->table->s->db_type));
- *tables_type|= tables_used->table->file->table_cache_type();
-
- /*
- table_alias_charset used here because it depends of
- lower_case_table_names variable
- */
- if (tables_used->table->s->tmp_table != NO_TMP_TABLE ||
- (*tables_type & HA_CACHE_TBL_NOCACHE) ||
- (tables_used->db_length == 5 &&
- my_strnncoll(table_alias_charset, (uchar*)tables_used->db, 6,
- (uchar*)"mysql",6) == 0))
- {
- DBUG_PRINT("qcache",
- ("select not cacheable: temporary, system or \
-other non-cacheable table(s)"));
- DBUG_RETURN(0);
- }
- if (tables_used->table->s->db_type == DB_TYPE_MRG_MYISAM)
- {
- ha_myisammrg *handler = (ha_myisammrg *)tables_used->table->file;
- MYRG_INFO *file = handler->myrg_info();
- table_count+= (file->end_table - file->open_tables);
- }
- }
+ if (!(table_count= process_and_count_tables(tables_used, tables_type)))
+ DBUG_RETURN(0);
if ((thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
((*tables_type)&HA_CACHE_TBL_TRANSACT))
@@ -2769,7 +2870,9 @@ my_bool Query_cache::ask_handler_allowance(THD *thd,
for (; tables_used; tables_used= tables_used->next_global)
{
- TABLE *table= tables_used->table;
+ TABLE *table;
+ if (!(table= tables_used->table))
+ continue;
handler *handler= table->file;
if (!handler->register_query_cache_table(thd, table->s->table_cache_key,
table->s->key_length,
diff --git a/sql/sql_cache.h b/sql/sql_cache.h
index e7116c7718a..c1b08904f51 100644
--- a/sql/sql_cache.h
+++ b/sql/sql_cache.h
@@ -285,6 +285,10 @@ protected:
void invalidate_table(TABLE *table);
void invalidate_table(byte *key, uint32 key_length);
void invalidate_table(Query_cache_block *table_block);
+ TABLE_COUNTER_TYPE
+ register_tables_from_list(TABLE_LIST *tables_used,
+ TABLE_COUNTER_TYPE counter,
+ Query_cache_block_table *block_table);
my_bool register_all_tables(Query_cache_block *block,
TABLE_LIST *tables_used,
TABLE_COUNTER_TYPE tables);
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 1a6a024b225..662ee171367 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -309,7 +309,7 @@ public:
bool write(THD *thd, const char *query, uint query_length,
time_t query_start=0);
bool write(Log_event* event_info); // binary log write
- bool write(THD *thd, IO_CACHE *cache);
+ bool write(THD *thd, IO_CACHE *cache, Log_event *commit_event);
/*
v stands for vector
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index 1705a25c124..c0b74d24d83 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -906,7 +906,7 @@ static my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error)
if (rmdir(path) < 0 && send_error)
{
my_error(ER_DB_DROP_RMDIR, MYF(0), path, errno);
- DBUG_RETURN(-1);
+ DBUG_RETURN(1);
}
DBUG_RETURN(0);
}
diff --git a/sql/sql_map.cc b/sql/sql_map.cc
index 687e60b7c72..e557840957e 100644
--- a/sql/sql_map.cc
+++ b/sql/sql_map.cc
@@ -19,10 +19,11 @@
#pragma implementation // gcc: Class implementation
#endif
+#include <sys/stat.h>
+
#include "mysql_priv.h"
-#ifdef HAVE_MMAP
+#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
-#include <sys/stat.h>
#endif
#ifndef MAP_NORESERVE
@@ -42,7 +43,7 @@ mapped_files::mapped_files(const my_string filename,byte *magic,uint magic_lengt
struct stat stat_buf;
if (!fstat(file,&stat_buf))
{
- if (!(map=(byte*) mmap(0,(size=(ulong) stat_buf.st_size),PROT_READ,
+ if (!(map=(byte*) my_mmap(0,(size=(ulong) stat_buf.st_size),PROT_READ,
MAP_SHARED | MAP_NORESERVE,file,
0L)))
{
@@ -53,7 +54,7 @@ mapped_files::mapped_files(const my_string filename,byte *magic,uint magic_lengt
if (map && memcmp(map,magic,magic_length))
{
my_error(ER_WRONG_MAGIC, MYF(0), name);
- VOID(munmap(map,size));
+ VOID(my_munmap(map,size));
map=0;
}
if (!map)
@@ -71,7 +72,7 @@ mapped_files::~mapped_files()
#ifdef HAVE_MMAP
if (file >= 0)
{
- VOID(munmap((caddr_t) map,size));
+ VOID(my_munmap(map,size));
VOID(my_close(file,MYF(0)));
file= -1; map=0;
}
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 3e2915e6e07..9a1b2eb0430 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -129,13 +129,13 @@ static bool end_active_trans(THD *thd)
OPTION_TABLE_LOCK))
{
DBUG_PRINT("info",("options: 0x%lx", (ulong) thd->options));
- thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
/* Safety if one did "drop table" on locked tables */
if (!thd->locked_tables)
thd->options&= ~OPTION_TABLE_LOCK;
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
if (ha_commit(thd))
error=1;
+ thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
}
DBUG_RETURN(error);
}
@@ -1007,6 +1007,7 @@ void execute_init_command(THD *thd, sys_var_str *init_command_var,
*/
save_vio= thd->net.vio;
thd->net.vio= 0;
+ thd->net.no_send_error= 0;
dispatch_command(COM_QUERY, thd, thd->query, thd->query_length+1);
rw_unlock(var_mutex);
thd->client_capabilities= save_client_capabilities;
@@ -1066,6 +1067,7 @@ pthread_handler_decl(handle_one_connection,arg)
int error;
NET *net= &thd->net;
thd->thread_stack= (char*) &thd;
+ net->no_send_error= 0;
if ((error=check_connection(thd)))
{ // Wrong permissions
@@ -1104,6 +1106,7 @@ pthread_handler_decl(handle_one_connection,arg)
thd->init_for_queries();
while (!net->error && net->vio != 0 && !(thd->killed == THD::KILL_CONNECTION))
{
+ net->no_send_error= 0;
if (do_command(thd))
break;
}
@@ -1337,9 +1340,9 @@ int end_trans(THD *thd, enum enum_mysql_completiontype completion)
even if there is a problem with the OPTION_AUTO_COMMIT flag
(Which of course should never happen...)
*/
- thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
res= ha_commit(thd);
+ thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
break;
case COMMIT_RELEASE:
do_release= 1; /* fall through */
@@ -1452,6 +1455,106 @@ bool do_command(THD *thd)
}
#endif /* EMBEDDED_LIBRARY */
+static void release_local_lock(THD *thd, TABLE_LIST *locked_tables,
+ bool old_innodb_table_locks)
+{
+ if (locked_tables)
+ {
+#ifdef HAVE_INNOBASE_DB
+ thd->variables.innodb_table_locks= old_innodb_table_locks;
+#endif
+ if (thd->locked_tables)
+ sp_unlock_tables(thd);
+ }
+
+}
+
+static bool process_nested_sp(THD *thd, LEX *lex, TABLE_LIST** locked_tables)
+{
+ DBUG_ENTER("process_nested_sp");
+ while (1)
+ {
+ if (sp_cache_routines(thd, lex, TYPE_ENUM_FUNCTION))
+ DBUG_RETURN(TRUE);
+ if (sp_cache_routines(thd, lex, TYPE_ENUM_PROCEDURE))
+ DBUG_RETURN(TRUE);
+ if (!thd->locked_tables &&
+ lex->sql_command != SQLCOM_CREATE_TABLE &&
+ lex->sql_command != SQLCOM_CREATE_VIEW)
+ {
+ MEM_ROOT *thdmemroot= NULL;
+
+ sp_merge_routine_tables(thd, lex);
+ // QQ Preopen tables to find views and triggers.
+ // This means we open, close and open again, which sucks, but
+ // right now it's the easiest way to get it to work. A better
+ // solution will hopefully be found soon...
+ if (lex->sptabs.records || lex->query_tables)
+ {
+ uint procs, funs, tabs;
+
+ if (thd->mem_root != thd->current_arena->mem_root)
+ {
+ thdmemroot= thd->mem_root;
+ thd->mem_root= thd->current_arena->mem_root;
+ }
+ if (!sp_merge_table_list(thd, &lex->sptabs, lex->query_tables))
+ DBUG_RETURN(TRUE);
+ procs= lex->spprocs.records;
+ funs= lex->spfuns.records;
+ tabs= lex->sptabs.records;
+
+ if (((*locked_tables)= sp_hash_to_table_list(thd, &lex->sptabs)))
+ {
+ // We don't want these updated now
+ uint ctmpdtabs= thd->status_var.created_tmp_disk_tables;
+ uint ctmptabs= thd->status_var.created_tmp_tables;
+ uint count;
+
+ thd->shortcut_make_view= TRUE;
+ open_tables(thd, *locked_tables, &count);
+ thd->shortcut_make_view= FALSE;
+ close_thread_tables(thd);
+ thd->status_var.created_tmp_disk_tables= ctmpdtabs;
+ thd->status_var.created_tmp_tables= ctmptabs;
+ thd->clear_error();
+ mysql_reset_errors(thd);
+ (*locked_tables)= NULL;
+ }
+ // A kludge: Decrease all temp. table's query ids to allow a
+ // second opening.
+ for (TABLE *table= thd->temporary_tables; table ; table=table->next)
+ table->query_id-= 1;
+ if (procs < lex->spprocs.records ||
+ funs < lex->spfuns.records ||
+ tabs < lex->sptabs.records)
+ {
+ if (thdmemroot)
+ thd->mem_root= thdmemroot;
+ continue; // Found more SPs or tabs, try again
+ }
+ }
+ if (lex->sptabs.records &&
+ (lex->spfuns.records || lex->spprocs.records) &&
+ sp_merge_table_list(thd, &lex->sptabs, lex->query_tables))
+ {
+ if (((*locked_tables)= sp_hash_to_table_list(thd, &lex->sptabs)))
+ {
+#ifdef HAVE_INNOBASE_DB
+ thd->variables.innodb_table_locks= FALSE;
+#endif
+ sp_open_and_lock_tables(thd, *locked_tables);
+ }
+ }
+ if (thdmemroot)
+ thd->mem_root= thdmemroot;
+ }
+ break;
+ } // while (1)
+ DBUG_RETURN(FALSE);
+}
+
+
/*
Perform one connection-level (COM_XXXX) command.
SYNOPSIS
@@ -1702,8 +1805,15 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
#else
{
char *fields, *pend;
+ /* Locked closure of all tables */
+ TABLE_LIST *locked_tables= NULL;
TABLE_LIST table_list;
LEX_STRING conv_name;
+ /* Saved variable value */
+#ifdef HAVE_INNOBASE_DB
+ my_bool old_innodb_table_locks= thd->variables.innodb_table_locks;
+#endif
+
statistic_increment(thd->status_var.com_stat[SQLCOM_SHOW_FIELDS],
&LOCK_status);
@@ -1747,12 +1857,16 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd->lex->
select_lex.table_list.link_in_list((byte*) &table_list,
(byte**) &table_list.next_local);
+ thd->lex->query_tables= &table_list;
+ thd->shortcut_make_view= 0;
+ process_nested_sp(thd, thd->lex, &locked_tables);
/* switch on VIEW optimisation: do not fill temporary tables */
thd->lex->sql_command= SQLCOM_SHOW_FIELDS;
mysqld_list_fields(thd,&table_list,fields);
thd->lex->unit.cleanup();
thd->cleanup_after_query();
+ release_local_lock(thd, locked_tables, old_innodb_table_locks);
break;
}
#endif
@@ -2226,6 +2340,7 @@ mysql_execute_command(THD *thd)
my_bool old_innodb_table_locks= thd->variables.innodb_table_locks;
#endif
DBUG_ENTER("mysql_execute_command");
+ thd->net.no_send_error= 0;
/*
In many cases first table of main SELECT_LEX have special meaning =>
@@ -2252,85 +2367,8 @@ mysql_execute_command(THD *thd)
lex->sql_command != SQLCOM_LOCK_TABLES &&
lex->sql_command != SQLCOM_UNLOCK_TABLES)
{
- while (1)
- {
- if (sp_cache_routines(thd, lex, TYPE_ENUM_FUNCTION))
- DBUG_RETURN(-1);
- if (sp_cache_routines(thd, lex, TYPE_ENUM_PROCEDURE))
- DBUG_RETURN(-1);
- if (!thd->locked_tables &&
- lex->sql_command != SQLCOM_CREATE_TABLE &&
- lex->sql_command != SQLCOM_CREATE_VIEW)
- {
- MEM_ROOT *thdmemroot= NULL;
-
- sp_merge_routine_tables(thd, lex);
- // QQ Preopen tables to find views and triggers.
- // This means we open, close and open again, which sucks, but
- // right now it's the easiest way to get it to work. A better
- // solution will hopefully be found soon...
- if (lex->sptabs.records || lex->query_tables)
- {
- uint procs, funs, tabs;
-
- if (thd->mem_root != thd->current_arena->mem_root)
- {
- thdmemroot= thd->mem_root;
- thd->mem_root= thd->current_arena->mem_root;
- }
- if (!sp_merge_table_list(thd, &lex->sptabs, lex->query_tables))
- DBUG_RETURN(-1);
- procs= lex->spprocs.records;
- funs= lex->spfuns.records;
- tabs= lex->sptabs.records;
-
- if ((locked_tables= sp_hash_to_table_list(thd, &lex->sptabs)))
- {
- // We don't want these updated now
- uint ctmpdtabs= thd->status_var.created_tmp_disk_tables;
- uint ctmptabs= thd->status_var.created_tmp_tables;
- uint count;
-
- thd->shortcut_make_view= TRUE;
- open_tables(thd, locked_tables, &count);
- thd->shortcut_make_view= FALSE;
- close_thread_tables(thd);
- thd->status_var.created_tmp_disk_tables= ctmpdtabs;
- thd->status_var.created_tmp_tables= ctmptabs;
- thd->clear_error();
- mysql_reset_errors(thd);
- locked_tables= NULL;
- }
- // A kludge: Decrease all temp. table's query ids to allow a
- // second opening.
- for (TABLE *table= thd->temporary_tables; table ; table=table->next)
- table->query_id-= 1;
- if (procs < lex->spprocs.records ||
- funs < lex->spfuns.records ||
- tabs < lex->sptabs.records)
- {
- if (thdmemroot)
- thd->mem_root= thdmemroot;
- continue; // Found more SPs or tabs, try again
- }
- }
- if (lex->sptabs.records &&
- (lex->spfuns.records || lex->spprocs.records) &&
- sp_merge_table_list(thd, &lex->sptabs, lex->query_tables))
- {
- if ((locked_tables= sp_hash_to_table_list(thd, &lex->sptabs)))
- {
-#ifdef HAVE_INNOBASE_DB
- thd->variables.innodb_table_locks= FALSE;
-#endif
- sp_open_and_lock_tables(thd, locked_tables);
- }
- }
- if (thdmemroot)
- thd->mem_root= thdmemroot;
- }
- break;
- } // while (1)
+ if (process_nested_sp(thd, lex, &locked_tables))
+ DBUG_RETURN(TRUE);
}
/*
@@ -4330,7 +4368,13 @@ unsent_create_error:
}
case SQLCOM_CREATE_VIEW:
{
- res= mysql_create_view(thd, thd->lex->create_view_mode);
+ if (!(res= mysql_create_view(thd, thd->lex->create_view_mode)) &&
+ mysql_bin_log.is_open())
+ {
+ thd->clear_error();
+ Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
+ mysql_bin_log.write(&qinfo);
+ }
break;
}
case SQLCOM_DROP_VIEW:
@@ -4338,7 +4382,13 @@ unsent_create_error:
if (check_table_access(thd, DROP_ACL, all_tables, 0) ||
end_active_trans(thd))
goto error;
- res= mysql_drop_view(thd, first_table, thd->lex->drop_mode);
+ if (!(res= mysql_drop_view(thd, first_table, thd->lex->drop_mode)) &&
+ mysql_bin_log.is_open())
+ {
+ thd->clear_error();
+ Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
+ mysql_bin_log.write(&qinfo);
+ }
break;
}
case SQLCOM_CREATE_TRIGGER:
@@ -4548,14 +4598,7 @@ cleanup:
thd->lock= 0;
}
- if (locked_tables)
- {
-#ifdef HAVE_INNOBASE_DB
- thd->variables.innodb_table_locks= old_innodb_table_locks;
-#endif
- if (thd->locked_tables)
- sp_unlock_tables(thd);
- }
+ release_local_lock(thd, locked_tables, old_innodb_table_locks);
DBUG_RETURN(res || thd->net.report_error);
}
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index ebbfc073848..4c494e85300 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -11384,22 +11384,24 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
/* Check whether the resolved field is not ambiguos. */
if (select_item != not_found_item)
{
+ Item *view_ref= NULL;
/*
If we have found field not by its alias in select list but by its
original field name, we should additionaly check if we have conflict
for this name (in case if we would perform lookup in all tables).
*/
- if (unaliased && !order_item->fixed && order_item->fix_fields(thd, tables, order->item))
+ if (unaliased && !order_item->fixed && order_item->fix_fields(thd, tables,
+ order->item))
return 1;
/* Lookup the current GROUP field in the FROM clause. */
order_item_type= order_item->type();
if (is_group_field &&
- order_item_type == Item::FIELD_ITEM || order_item_type == Item::REF_ITEM)
+ order_item_type == Item::FIELD_ITEM ||
+ order_item_type == Item::REF_ITEM)
{
- Item **view_ref= NULL;
from_field= find_field_in_tables(thd, (Item_ident*) order_item, tables,
- view_ref, IGNORE_ERRORS, TRUE);
+ &view_ref, IGNORE_ERRORS, TRUE);
if(!from_field)
from_field= (Field*) not_found_field;
}
@@ -11407,9 +11409,19 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
from_field= (Field*) not_found_field;
if (from_field == not_found_field ||
- from_field && from_field != view_ref_found &&
- (*select_item)->type() == Item::FIELD_ITEM &&
- ((Item_field*) (*select_item))->field->eq(from_field))
+ from_field &&
+ (from_field != view_ref_found ?
+ /* it is field of base table => check that fields are same */
+ ((*select_item)->type() == Item::FIELD_ITEM &&
+ ((Item_field*) (*select_item))->field->eq(from_field)) :
+ /*
+ in is field of view table => check that references on translation
+ table are same
+ */
+ ((*select_item)->type() == Item::Item::REF_ITEM &&
+ view_ref->type() == Item::Item::REF_ITEM &&
+ ((Item_ref *) (*select_item))->ref ==
+ ((Item_ref *) view_ref)->ref)))
/*
If there is no such field in the FROM clause, or it is the same field as
the one found in the SELECT clause, then use the Item created for the
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 456f513dab0..96a0dc2f636 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -305,6 +305,8 @@ bool mysql_create_view(THD *thd,
VOID(pthread_mutex_lock(&LOCK_open));
res= mysql_register_view(thd, view, mode);
VOID(pthread_mutex_unlock(&LOCK_open));
+ if (view->revision != 1)
+ query_cache_invalidate3(thd, view, 0);
start_waiting_global_read_lock(thd);
if (res)
goto err;
@@ -917,6 +919,7 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
}
if (my_delete(path, MYF(MY_WME)))
goto err;
+ query_cache_invalidate3(thd, view, 0);
VOID(pthread_mutex_unlock(&LOCK_open));
}
send_ok(thd);
diff --git a/sql/table.cc b/sql/table.cc
index 69a132329c0..dc791b384be 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1599,24 +1599,42 @@ void st_table_list::calc_md5(char *buffer)
/*
set ancestor TABLE for table place holder of VIEW
+ DESCRIPTION
+ Replace all views that only uses one table with the table itself.
+ This allows us to treat the view as a simple table and even update
+ it
+
SYNOPSIS
st_table_list::set_ancestor()
*/
void st_table_list::set_ancestor()
{
- /* process all tables of view */
- for (TABLE_LIST *tbl= ancestor; tbl; tbl= tbl->next_local)
- {
- if (tbl->ancestor)
- ancestor->set_ancestor();
- tbl->table->grant= grant;
- }
- /* if view contain only one table, substitute TABLE of it */
- if (!ancestor->next_local)
+ TABLE_LIST *tbl;
+
+ if ((tbl= ancestor))
{
- table= ancestor->table;
- schema_table= ancestor->schema_table;
+ /* This is a view. Process all tables of view */
+ DBUG_ASSERT(view);
+ do
+ {
+ if (tbl->ancestor) // This is a view
+ {
+ /*
+ This is the only case where set_ancestor is called on an object
+ that may not be a view (in which case ancestor is 0)
+ */
+ tbl->ancestor->set_ancestor();
+ }
+ tbl->table->grant= grant;
+ } while ((tbl= tbl->next_local));
+
+ /* if view contain only one table, substitute TABLE of it */
+ if (!ancestor->next_local)
+ {
+ table= ancestor->table;
+ schema_table= ancestor->schema_table;
+ }
}
}
@@ -1679,6 +1697,8 @@ void st_table_list::restore_want_privilege()
conds - condition of this JOIN
check_opt_type - WHITH CHECK OPTION type (VIEW_CHECK_NONE,
VIEW_CHECK_LOCAL, VIEW_CHECK_CASCADED)
+ NOTES
+ ancestor is list of tables and views used by view
DESCRIPTION
It is:
@@ -1689,8 +1709,8 @@ void st_table_list::restore_want_privilege()
If there are underlying view(s) procedure first will be called for them.
RETURN
- 0 - OK
- 1 - error
+ FALSE - OK
+ TRUE - error
*/
bool st_table_list::setup_ancestor(THD *thd, Item **conds,
@@ -1699,13 +1719,17 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds,
Field_translator *transl;
SELECT_LEX *select= &view->select_lex;
SELECT_LEX *current_select_save= thd->lex->current_select;
+ byte *main_table_list_save= select_lex->table_list.first;
Item *item;
TABLE_LIST *tbl;
List_iterator_fast<Item> it(select->item_list);
uint i= 0;
+ enum sub_select_type linkage_save=
+ select_lex->master_unit()->first_select()->linkage;
bool save_set_query_id= thd->set_query_id;
- bool save_wrapper= thd->lex->select_lex.no_wrap_view_item;
+ bool save_wrapper= select_lex->no_wrap_view_item;
bool save_allow_sum_func= thd->allow_sum_func;
+ bool res= FALSE;
DBUG_ENTER("st_table_list::setup_ancestor");
for (tbl= ancestor; tbl; tbl= tbl->next_local)
@@ -1715,15 +1739,26 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds,
(check_opt_type == VIEW_CHECK_CASCADED ?
VIEW_CHECK_CASCADED :
VIEW_CHECK_NONE)))
- DBUG_RETURN(1);
+ DBUG_RETURN(TRUE);
}
+ /*
+ We have to ensure that inside the view we are not referring to any
+ table outside of the view. We do it by changing the pointers used
+ by fix_fields to look up tables so that only tables and views in
+ view are seen. We also set linkage to DERIVED_TABLE_TYPE as a barrier
+ so that we stop resolving fields as this level.
+ */
+ thd->lex->current_select= select_lex;
+ select_lex->table_list.first= (byte *)ancestor;
+ select_lex->master_unit()->first_select()->linkage= DERIVED_TABLE_TYPE;
+
if (field_translation)
{
DBUG_PRINT("info", ("there are already translation table"));
- /* prevent look up in SELECTs tree */
- thd->lex->current_select= &thd->lex->select_lex;
- thd->lex->select_lex.no_wrap_view_item= 1;
+
+ select_lex->no_wrap_view_item= 1;
+
thd->set_query_id= 1;
/* this view was prepared already on previous PS/SP execution */
Field_translator *end= field_translation + select->item_list.elements;
@@ -1758,18 +1793,17 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds,
goto ok;
}
- /* view fields translation table */
+ /* Create view fields translation table */
+
if (!(transl=
(Field_translator*)(thd->current_arena->
alloc(select->item_list.elements *
sizeof(Field_translator)))))
{
- DBUG_RETURN(1);
+ DBUG_RETURN(TRUE);
}
- /* prevent look up in SELECTs tree */
- thd->lex->current_select= &thd->lex->select_lex;
- thd->lex->select_lex.no_wrap_view_item= 1;
+ select_lex->no_wrap_view_item= 1;
/*
Resolve all view items against ancestor table.
@@ -1910,14 +1944,10 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds,
thd->restore_backup_item_arena(arena, &backup);
}
-ok:
- thd->lex->select_lex.no_wrap_view_item= save_wrapper;
- thd->lex->current_select= current_select_save;
- thd->set_query_id= save_set_query_id;
- thd->allow_sum_func= save_allow_sum_func;
- DBUG_RETURN(0);
+ goto ok;
err:
+ res= TRUE;
/* Hide "Unknown column" or "Unknown function" error */
if (thd->net.last_errno == ER_BAD_FIELD_ERROR ||
thd->net.last_errno == ER_SP_DOES_NOT_EXIST)
@@ -1925,11 +1955,15 @@ err:
thd->clear_error();
my_error(ER_VIEW_INVALID, MYF(0), view_db.str, view_name.str);
}
- thd->lex->select_lex.no_wrap_view_item= save_wrapper;
+
+ok:
+ select_lex->no_wrap_view_item= save_wrapper;
thd->lex->current_select= current_select_save;
+ select_lex->table_list.first= main_table_list_save;
+ select_lex->master_unit()->first_select()->linkage= linkage_save;
thd->set_query_id= save_set_query_id;
thd->allow_sum_func= save_allow_sum_func;
- DBUG_RETURN(1);
+ DBUG_RETURN(res);
}
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index 1eb0151767d..8f49b45de0c 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -12584,6 +12584,42 @@ static void test_bug7990()
}
+static void test_view_sp_list_fields()
+{
+ MYSQL_STMT *stmt;
+ int rc;
+ MYSQL_RES *res;
+
+ myheader("test_view_insert_fields");
+
+ rc= mysql_query(mysql, "DROP FUNCTION IF EXISTS f1");
+ myquery(rc);
+ rc= mysql_query(mysql, "DROP TABLE IF EXISTS v1, t1, t2");
+ myquery(rc);
+ rc= mysql_query(mysql, "DROP VIEW IF EXISTS v1, t1, t2");
+ myquery(rc);
+ rc= mysql_query(mysql, "create function f1 () returns int return 5");
+ myquery(rc);
+ rc= mysql_query(mysql, "create table t1 (s1 char,s2 char)");
+ myquery(rc);
+ rc= mysql_query(mysql, "create table t2 (s1 int);");
+ myquery(rc);
+ rc= mysql_query(mysql, "create view v1 as select s2,sum(s1) - \
+count(s2) as vx from t1 group by s2 having sum(s1) - count(s2) < (select f1() \
+from t2);");
+ myquery(rc);
+ res= mysql_list_fields(mysql, "v1", NullS);
+ DIE_UNLESS(res != 0 && mysql_num_fields(res) != 0);
+ rc= mysql_query(mysql, "DROP FUNCTION f1");
+ myquery(rc);
+ rc= mysql_query(mysql, "DROP VIEW v1");
+ myquery(rc);
+ rc= mysql_query(mysql, "DROP TABLE t1, t2");
+ myquery(rc);
+
+}
+
+
/*
Test mysql_real_escape_string() with gbk charset
@@ -12693,6 +12729,7 @@ and you are welcome to modify and redistribute it under the GPL license\n");
static struct my_tests_st my_tests[]= {
+ { "test_view_sp_list_fields", test_view_sp_list_fields},
{ "client_query", client_query },
{ "test_prepare_insert_update", test_prepare_insert_update},
#if NOT_YET_WORKING