From 32a7fafe093d9d3a84eca63a6e4aad02c508539f Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 31 May 2006 00:07:58 -0700 Subject: [PATCH 01/26] Bug#12096 "Add line for non-executable stack in .s files" Fix so that configure will use "--noexecstack" for assembler if gcc supports option and compiled C doesn't need executable stack. config/ac-macros/compiler_flag.m4: Bug#12096 Add macro to check if "--noexecstack" should be used when compiling assembler configure.in: Bug#12096 Add macro to check if "--noexecstack" should be used when compiling assembler strings/Makefile.am: Bug#12096 Automake knows how to handle assembler --- config/ac-macros/compiler_flag.m4 | 22 ++++++++++++++++++++++ configure.in | 4 ++++ strings/Makefile.am | 6 ------ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/config/ac-macros/compiler_flag.m4 b/config/ac-macros/compiler_flag.m4 index a236f61a198..9dda6da72fa 100644 --- a/config/ac-macros/compiler_flag.m4 +++ b/config/ac-macros/compiler_flag.m4 @@ -38,3 +38,25 @@ AC_DEFUN([AC_SYS_OS_COMPILER_FLAG], fi ]) +AC_DEFUN([AC_CHECK_NOEXECSTACK], +[ + AC_CACHE_CHECK(whether --noexecstack is desirable for .S files, + mysql_cv_as_noexecstack, [dnl + cat > conftest.c <&AS_MESSAGE_LOG_FD]) \ + && grep -q .note.GNU-stack conftest.s \ + && AC_TRY_COMMAND([${CC-cc} $CCASFLAGS $CPPFLAGS -Wa,--noexecstack + -c -o conftest.o conftest.s 1>&AS_MESSAGE_LOG_FD]) + then + mysql_cv_as_noexecstack=yes + else + mysql_cv_as_noexecstack=no + fi + rm -f conftest*]) + if test $mysql_cv_as_noexecstack = yes; then + CCASFLAGS="$CCASFLAGS -Wa,--noexecstack" + fi +]) diff --git a/configure.in b/configure.in index ac1c122c2ea..1b44081a4a0 100644 --- a/configure.in +++ b/configure.in @@ -515,6 +515,10 @@ AM_PROG_CC_STDC # We need an assembler, too AM_PROG_AS +CCASFLAGS="$CCASFLAGS $ASFLAGS" + +# Check if we need noexec stack for assembler +AC_CHECK_NOEXECSTACK if test "$am_cv_prog_cc_stdc" = "no" then diff --git a/strings/Makefile.am b/strings/Makefile.am index c43cf0f290a..7ee115c09e5 100644 --- a/strings/Makefile.am +++ b/strings/Makefile.am @@ -66,12 +66,6 @@ conf_to_src_LDFLAGS= @NOINST_LDFLAGS@ #strtoull.o: @CHARSET_OBJS@ -if ASSEMBLER -# On Linux gcc can compile the assembly files -%.o : %.s - $(AS) $(ASFLAGS) -o $@ $< -endif - FLAGS=$(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) @NOINST_LDFLAGS@ str_test: str_test.c $(pkglib_LIBRARIES) From b7e27e80d9dc065d2ecc49aad371a71ad3a824a4 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 19 Jun 2006 17:34:12 +0300 Subject: [PATCH 02/26] Bug #18080: INSERT ... SELECT ... JOIN results in ambiguous field list error There was an incomplete reset of the name resolution context, that caused INSERT ... SELECT ... JOIN statements to resolve not by joint row type calculated for the join. Removed the redundant re-initialization of the context, because mysql_insert_select_prepare() now correctly saves/restores the context. mysql-test/r/insert_select.result: Bug #18080: INSERT ... SELECT ... JOIN results in ambiguous field list error - testsuite for the bug mysql-test/t/insert_select.test: Bug #18080: INSERT ... SELECT ... JOIN results in ambiguous field list error - testsuite for the bug sql/sql_parse.cc: Bug #18080: INSERT ... SELECT ... JOIN results in ambiguous field list error - remove an incomplete reset of the context because the mentioned function correctly saves/restores the context. --- mysql-test/r/insert_select.result | 5 +++++ mysql-test/t/insert_select.test | 9 +++++++++ sql/sql_parse.cc | 9 --------- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/mysql-test/r/insert_select.result b/mysql-test/r/insert_select.result index 434dddb3049..62450997260 100644 --- a/mysql-test/r/insert_select.result +++ b/mysql-test/r/insert_select.result @@ -686,3 +686,8 @@ ERROR 42S22: Unknown column 'z' in 'field list' insert into t1(x,y) select x,z from t2 on duplicate key update x=values(t2.x); ERROR 42S22: Unknown column 't2.x' in 'field list' drop table t1,t2; +CREATE TABLE t1 (x int, y int); +CREATE TABLE t2 (z int, y int); +CREATE TABLE t3 (a int, b int); +INSERT INTO t3 (SELECT x, y FROM t1 JOIN t2 USING (y) WHERE z = 1); +DROP TABLE IF EXISTS t1,t2,t3; diff --git a/mysql-test/t/insert_select.test b/mysql-test/t/insert_select.test index 5dd6f338865..0e1d48fe9f5 100644 --- a/mysql-test/t/insert_select.test +++ b/mysql-test/t/insert_select.test @@ -225,3 +225,12 @@ insert into t1(x,y) select x,z from t2 on duplicate key update x=values(t2.x); drop table t1,t2; # End of 4.1 tests + +# +# Bug #18080: INSERT ... SELECT ... JOIN results in ambiguous field list error +# +CREATE TABLE t1 (x int, y int); +CREATE TABLE t2 (z int, y int); +CREATE TABLE t3 (a int, b int); +INSERT INTO t3 (SELECT x, y FROM t1 JOIN t2 USING (y) WHERE z = 1); +DROP TABLE IF EXISTS t1,t2,t3; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index ba5c2ebf484..28b2abfc883 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3333,15 +3333,6 @@ end_with_restore_list: &lex->value_list, lex->duplicates, lex->ignore))) { - /* - Skip first table, which is the table we are inserting in. - Below we set context.table_list again because the call above to - mysql_insert_select_prepare() calls resolve_in_table_list_only(), - which in turn resets context.table_list and - context.first_name_resolution_table. - */ - select_lex->context.table_list= - select_lex->context.first_name_resolution_table= second_table; res= handle_select(thd, lex, result, OPTION_SETUP_TABLES_DONE); /* Invalidate the table in the query cache if something changed From 7751eeaf3c928cc799f5ce3f4766e44367a70910 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 20 Jun 2006 11:28:59 +0300 Subject: [PATCH 03/26] wrong merge of bug9676 from 4.1 to 5.0 corrected --- sql/sql_select.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index a243f22e7ee..fe4993fddbf 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -8817,7 +8817,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, } else { - set_if_smaller(table->max_rows, rows_limit); + set_if_smaller(table->s->max_rows, rows_limit); param->end_write_records= rows_limit; } From 0baf2087a2bdc87aca5c64be8097f978e5228c10 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 21 Jun 2006 02:21:10 +0400 Subject: [PATCH 04/26] Remove deadcode in select_dumpvar::send_data() --- sql/sql_class.cc | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 678048226af..06082a57964 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1853,15 +1853,10 @@ bool select_dumpvar::send_data(List &items) Item_func_set_user_var *xx; Item_splocal *yy; my_var *zz; - DBUG_ENTER("send_data"); - if (unit->offset_limit_cnt) - { // using limit offset,count - unit->offset_limit_cnt--; - DBUG_RETURN(0); - } + DBUG_ENTER("select_dumpvar::send_data"); if (unit->offset_limit_cnt) - { // Using limit offset,count + { // using limit offset,count unit->offset_limit_cnt--; DBUG_RETURN(0); } From 6c787151613ad1d443b43389d534861b8bf757e4 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 21 Jun 2006 12:12:46 +0300 Subject: [PATCH 05/26] Bug #20482: failure on Create join view with sources views/tables in different schemas The function check_one_table_access() called to check access to tables in SELECT/INSERT/UPDATE was doing additional checks/modifications that don't hold in the context of setup_tables_and_check_access(). That's why the check_one_table() was split into two : the functionality needed by setup_tables_and_check_access() into check_single_table_access() and the rest of the functionality stays in check_one_table_access() that is made to call the new check_single_table_access() function. mysql-test/r/view_grant.result: Bug #20482: failure on Create join view with sources views/tables in different schemas - test suite for the bug mysql-test/t/view_grant.test: Bug #20482: failure on Create join view with sources views/tables in different schemas - test suite for the bug sql/mysql_priv.h: Bug #20482: failure on Create join view with sources views/tables in different schemas - check_one_table_access split into 2 sql/sql_base.cc: Bug #20482: failure on Create join view with sources views/tables in different schemas - the new sub-function called sql/sql_parse.cc: Bug #20482: failure on Create join view with sources views/tables in different schemas - check_one_table_access() split into two : check_single_table_access() to actually check access to the table(ro) and check_one_table_access() that calls check_single_table_access() and checks also the tables belonging to sub selects or implicitly opened tables. --- mysql-test/r/view_grant.result | 12 ++++++++++ mysql-test/t/view_grant.test | 21 ++++++++++++++++++ sql/mysql_priv.h | 2 ++ sql/sql_base.cc | 2 +- sql/sql_parse.cc | 40 ++++++++++++++++++++++++++-------- 5 files changed, 67 insertions(+), 10 deletions(-) diff --git a/mysql-test/r/view_grant.result b/mysql-test/r/view_grant.result index f6559e6f838..11161d0c844 100644 --- a/mysql-test/r/view_grant.result +++ b/mysql-test/r/view_grant.result @@ -618,3 +618,15 @@ ERROR HY000: There is no 'no-such-user'@'localhost' registered DROP VIEW v; DROP TABLE t1; USE test; +CREATE DATABASE test1; +CREATE DATABASE test2; +CREATE TABLE test1.t0 (a VARCHAR(20)); +CREATE TABLE test2.t1 (a VARCHAR(20)); +CREATE VIEW test2.t3 AS SELECT * FROM test1.t0; +CREATE OR REPLACE VIEW test.v1 AS +SELECT ta.a AS col1, tb.a AS col2 FROM test2.t3 ta, test2.t1 tb; +DROP VIEW test.v1; +DROP VIEW test2.t3; +DROP TABLE test2.t1, test1.t0; +DROP DATABASE test2; +DROP DATABASE test1; diff --git a/mysql-test/t/view_grant.test b/mysql-test/t/view_grant.test index 4663a667d25..9d23bfa6197 100644 --- a/mysql-test/t/view_grant.test +++ b/mysql-test/t/view_grant.test @@ -807,3 +807,24 @@ SELECT * FROM v; DROP VIEW v; DROP TABLE t1; USE test; + +# +# BUG#20482: failure on Create join view with sources views/tables +# in different schemas +# +--disable_warnings +CREATE DATABASE test1; +CREATE DATABASE test2; +--enable_warnings + +CREATE TABLE test1.t0 (a VARCHAR(20)); +CREATE TABLE test2.t1 (a VARCHAR(20)); +CREATE VIEW test2.t3 AS SELECT * FROM test1.t0; +CREATE OR REPLACE VIEW test.v1 AS + SELECT ta.a AS col1, tb.a AS col2 FROM test2.t3 ta, test2.t1 tb; + +DROP VIEW test.v1; +DROP VIEW test2.t3; +DROP TABLE test2.t1, test1.t0; +DROP DATABASE test2; +DROP DATABASE test1; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 6d39f2f7440..3bb371b6004 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -513,6 +513,8 @@ class THD; void close_thread_tables(THD *thd, bool locked=0, bool skip_derived=0); bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *tables); +bool check_single_table_access(THD *thd, ulong privilege, + TABLE_LIST *tables); bool check_routine_access(THD *thd,ulong want_access,char *db,char *name, bool is_proc, bool no_errors); bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 7fe626c8f2d..f01ab4cf74f 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -4545,7 +4545,7 @@ bool setup_tables_and_check_access(THD *thd, for (; leaves_tmp; leaves_tmp= leaves_tmp->next_leaf) if (leaves_tmp->belong_to_view && - check_one_table_access(thd, want_access, leaves_tmp)) + check_single_table_access(thd, want_access, leaves_tmp)) { tables->hide_view_error(thd); return TRUE; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 37e45e999b3..6ec8bd65a90 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4978,11 +4978,10 @@ error: /* - Check grants for commands which work only with one table and all other - tables belonging to subselects or implicitly opened tables. + Check grants for commands which work only with one table. SYNOPSIS - check_one_table_access() + check_single_table_access() thd Thread handler privilege requested privilege all_tables global table list of query @@ -4992,7 +4991,8 @@ error: 1 - access denied, error is sent to client */ -bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *all_tables) +bool check_single_table_access(THD *thd, ulong privilege, + TABLE_LIST *all_tables) { Security_context * backup_ctx= thd->security_ctx; @@ -5010,19 +5010,41 @@ bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *all_tables) goto deny; thd->security_ctx= backup_ctx; + return 0; + +deny: + thd->security_ctx= backup_ctx; + return 1; +} + +/* + Check grants for commands which work only with one table and all other + tables belonging to subselects or implicitly opened tables. + + SYNOPSIS + check_one_table_access() + thd Thread handler + privilege requested privilege + all_tables global table list of query + + RETURN + 0 - OK + 1 - access denied, error is sent to client +*/ + +bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *all_tables) +{ + if (check_single_table_access (thd,privilege,all_tables)) + return 1; /* Check rights on tables of subselects and implictly opened tables */ TABLE_LIST *subselects_tables; if ((subselects_tables= all_tables->next_global)) { if ((check_table_access(thd, SELECT_ACL, subselects_tables, 0))) - goto deny; + return 1; } return 0; - -deny: - thd->security_ctx= backup_ctx; - return 1; } From ea3392fb976298d4e4451daaeab6d064c77df741 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 21 Jun 2006 13:01:00 +0300 Subject: [PATCH 06/26] manual merge mysql-test/r/view_grant.result: merged mysql-test/t/view_grant.test: merged --- mysql-test/r/view_grant.result | 29 ++++++++++++++++++++++++++ mysql-test/t/view_grant.test | 38 ++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/mysql-test/r/view_grant.result b/mysql-test/r/view_grant.result index 11161d0c844..0431957f602 100644 --- a/mysql-test/r/view_grant.result +++ b/mysql-test/r/view_grant.result @@ -618,6 +618,35 @@ ERROR HY000: There is no 'no-such-user'@'localhost' registered DROP VIEW v; DROP TABLE t1; USE test; +CREATE USER mysqltest_db1@localhost identified by 'PWD'; +GRANT ALL ON mysqltest_db1.* TO mysqltest_db1@localhost WITH GRANT OPTION; +CREATE SCHEMA mysqltest_db1 ; +USE mysqltest_db1 ; +CREATE TABLE t1 (f1 INTEGER); +CREATE VIEW view1 AS +SELECT * FROM t1; +SHOW CREATE VIEW view1; +View Create View +view1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqltest_db1`@`localhost` SQL SECURITY DEFINER VIEW `view1` AS select `t1`.`f1` AS `f1` from `t1` +CREATE VIEW view2 AS +SELECT * FROM view1; +# Here comes a suspicious warning +SHOW CREATE VIEW view2; +View Create View +view2 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqltest_db1`@`localhost` SQL SECURITY DEFINER VIEW `view2` AS select `view1`.`f1` AS `f1` from `view1` +# But the view view2 is usable +SELECT * FROM view2; +f1 +CREATE VIEW view3 AS +SELECT * FROM view2; +SELECT * from view3; +f1 +DROP VIEW mysqltest_db1.view3; +DROP VIEW mysqltest_db1.view2; +DROP VIEW mysqltest_db1.view1; +DROP TABLE mysqltest_db1.t1; +DROP SCHEMA mysqltest_db1; +DROP USER mysqltest_db1@localhost; CREATE DATABASE test1; CREATE DATABASE test2; CREATE TABLE test1.t0 (a VARCHAR(20)); diff --git a/mysql-test/t/view_grant.test b/mysql-test/t/view_grant.test index 9d23bfa6197..429a2af6bac 100644 --- a/mysql-test/t/view_grant.test +++ b/mysql-test/t/view_grant.test @@ -808,6 +808,44 @@ DROP VIEW v; DROP TABLE t1; USE test; +# +# Bug#20363: Create view on just created view is now denied +# +eval CREATE USER mysqltest_db1@localhost identified by 'PWD'; +eval GRANT ALL ON mysqltest_db1.* TO mysqltest_db1@localhost WITH GRANT OPTION; + +# The session with the non root user is needed. +--replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK +connect (session1,localhost,mysqltest_db1,PWD,test); + +CREATE SCHEMA mysqltest_db1 ; +USE mysqltest_db1 ; + +CREATE TABLE t1 (f1 INTEGER); + +CREATE VIEW view1 AS +SELECT * FROM t1; +SHOW CREATE VIEW view1; + +CREATE VIEW view2 AS +SELECT * FROM view1; +--echo # Here comes a suspicious warning +SHOW CREATE VIEW view2; +--echo # But the view view2 is usable +SELECT * FROM view2; + +CREATE VIEW view3 AS +SELECT * FROM view2; + +SELECT * from view3; + +connection default; +DROP VIEW mysqltest_db1.view3; +DROP VIEW mysqltest_db1.view2; +DROP VIEW mysqltest_db1.view1; +DROP TABLE mysqltest_db1.t1; +DROP SCHEMA mysqltest_db1; +DROP USER mysqltest_db1@localhost; # # BUG#20482: failure on Create join view with sources views/tables # in different schemas From 822e8866c7009d8d7bd25300f1cc4c09c110c640 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 22 Jun 2006 00:29:04 +0400 Subject: [PATCH 07/26] Fixed bug #14896. This bug in Field_string::cmp resulted in a wrong comparison with keys in partial indexes over multi-byte character fields. Given field a is declared as a varchar(16) collate utf8_unicode_ci INDEX(a(4)) gives us an example of such an index. Wrong key comparisons could lead to wrong result sets if the selected query execution plan used a range scan by a partial index over a utf8 character field. This also caused wrong results in many other cases. mysql-test/t/ctype_utf8.test: Added test cases for bug #14896. mysql-test/r/ctype_utf8.result: Added test cases for bug #14896. sql/field.cc: Fixed bug #14896. This bug in Field_string::cmp resulted in a wrong comparison with keys in partial indexes over multi-byte character fields. Given field a is declared as a varchar(16) collate utf8_unicode_ci INDEX(a(4)) gives us an example of such an index. Wrong key comparisons could lead to wrong result sets if the selected query execution plan used a range scan by a partial index over a utf8 character field. This also caused wrong results in many other cases. --- mysql-test/r/ctype_utf8.result | 40 ++++++++++++++++++++++++++++++++++ mysql-test/t/ctype_utf8.test | 26 ++++++++++++++++++++++ sql/field.cc | 20 ++++++----------- 3 files changed, 73 insertions(+), 13 deletions(-) diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index 69d7577ee77..cc271176dfc 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -1124,3 +1124,43 @@ check table t1; Table Op Msg_type Msg_text test.t1 check status OK drop table t1; +SET NAMES utf8; +CREATE TABLE t1 (id int PRIMARY KEY, +a varchar(16) collate utf8_unicode_ci NOT NULL default '', +b int, +f varchar(128) default 'XXX', +INDEX (a(4)) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; +INSERT INTO t1(id, a, b) VALUES +(1, 'cccc', 50), (2, 'cccc', 70), (3, 'cccc', 30), +(4, 'cccc', 30), (5, 'cccc', 20), (6, 'bbbbbb', 40), +(7, 'dddd', 30), (8, 'aaaa', 10), (9, 'aaaa', 50), +(10, 'eeeee', 40), (11, 'bbbbbb', 60); +SELECT id, a, b FROM t1; +id a b +1 cccc 50 +2 cccc 70 +3 cccc 30 +4 cccc 30 +5 cccc 20 +6 bbbbbb 40 +7 dddd 30 +8 aaaa 10 +9 aaaa 50 +10 eeeee 40 +11 bbbbbb 60 +SELECT id, a, b FROM t1 WHERE a BETWEEN 'aaaa' AND 'bbbbbb'; +id a b +8 aaaa 10 +9 aaaa 50 +6 bbbbbb 40 +11 bbbbbb 60 +SELECT id, a FROM t1 WHERE a='bbbbbb'; +id a +6 bbbbbb +11 bbbbbb +SELECT id, a FROM t1 WHERE a='bbbbbb' ORDER BY b; +id a +6 bbbbbb +11 bbbbbb +DROP TABLE t1; diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index 5044f7979f1..9b8e6590999 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -926,4 +926,30 @@ INSERT INTO t1 VALUES('uUABCDEFGHIGKLMNOPRSTUVWXYZ̈bbbbbbbbbbbbbbbbbbbbbbbbbbbb check table t1; drop table t1; +# +# Bug#14896: Comparison with a key in a partial index over mb chararacter field +# + +SET NAMES utf8; +CREATE TABLE t1 (id int PRIMARY KEY, + a varchar(16) collate utf8_unicode_ci NOT NULL default '', + b int, + f varchar(128) default 'XXX', + INDEX (a(4)) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; +INSERT INTO t1(id, a, b) VALUES + (1, 'cccc', 50), (2, 'cccc', 70), (3, 'cccc', 30), + (4, 'cccc', 30), (5, 'cccc', 20), (6, 'bbbbbb', 40), + (7, 'dddd', 30), (8, 'aaaa', 10), (9, 'aaaa', 50), + (10, 'eeeee', 40), (11, 'bbbbbb', 60); + +SELECT id, a, b FROM t1; + +SELECT id, a, b FROM t1 WHERE a BETWEEN 'aaaa' AND 'bbbbbb'; + +SELECT id, a FROM t1 WHERE a='bbbbbb'; +SELECT id, a FROM t1 WHERE a='bbbbbb' ORDER BY b; + +DROP TABLE t1; + # End of 4.1 tests diff --git a/sql/field.cc b/sql/field.cc index ec4d4b4e4f5..3cb0c0d3a7c 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -5072,17 +5072,6 @@ int Field_string::cmp(const char *a_ptr, const char *b_ptr) { uint a_len, b_len; - if (field_charset->strxfrm_multiply > 1) - { - /* - We have to remove end space to be able to compare multi-byte-characters - like in latin_de 'ae' and 0xe4 - */ - return field_charset->coll->strnncollsp(field_charset, - (const uchar*) a_ptr, field_length, - (const uchar*) b_ptr, - field_length); - } if (field_charset->mbmaxlen != 1) { uint char_len= field_length/field_charset->mbmaxlen; @@ -5091,8 +5080,13 @@ int Field_string::cmp(const char *a_ptr, const char *b_ptr) } else a_len= b_len= field_length; - return my_strnncoll(field_charset,(const uchar*) a_ptr, a_len, - (const uchar*) b_ptr, b_len); + /* + We have to remove end space to be able to compare multi-byte-characters + like in latin_de 'ae' and 0xe4 + */ + return field_charset->coll->strnncollsp(field_charset, + (const uchar*) a_ptr, a_len, + (const uchar*) b_ptr, b_len); } From edcba74415fc7a2ead3d65628d22efab598a61b8 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 21 Jun 2006 20:27:52 -0700 Subject: [PATCH 08/26] traditional grep does not have -q option --- config/ac-macros/compiler_flag.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/ac-macros/compiler_flag.m4 b/config/ac-macros/compiler_flag.m4 index 9dda6da72fa..88097c7a62e 100644 --- a/config/ac-macros/compiler_flag.m4 +++ b/config/ac-macros/compiler_flag.m4 @@ -47,7 +47,7 @@ void foo (void) { } EOF if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -S -o conftest.s conftest.c 1>&AS_MESSAGE_LOG_FD]) \ - && grep -q .note.GNU-stack conftest.s \ + && grep .note.GNU-stack conftest.s >/dev/null \ && AC_TRY_COMMAND([${CC-cc} $CCASFLAGS $CPPFLAGS -Wa,--noexecstack -c -o conftest.o conftest.s 1>&AS_MESSAGE_LOG_FD]) then From 505c2b3d5f0178aa9bdb9f97da707104489250a5 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 22 Jun 2006 12:03:28 +0200 Subject: [PATCH 09/26] ndb - bug#19164 set max value on ports ndb/src/mgmsrv/ConfigInfo.cpp: set max vlue on ports --- ndb/src/mgmsrv/ConfigInfo.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/ndb/src/mgmsrv/ConfigInfo.cpp b/ndb/src/mgmsrv/ConfigInfo.cpp index 66a400a3e22..54c4863b969 100644 --- a/ndb/src/mgmsrv/ConfigInfo.cpp +++ b/ndb/src/mgmsrv/ConfigInfo.cpp @@ -30,6 +30,7 @@ extern my_bool opt_core; #define MAX_LINE_LENGTH 255 #define KEY_INTERNAL 0 #define MAX_INT_RNIL 0xfffffeff +#define MAX_PORT_NO 65535 #define _STR_VALUE(x) #x #define STR_VALUE(x) _STR_VALUE(x) @@ -426,7 +427,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { ConfigInfo::CI_INT, UNDEFINED, "1", - STR_VALUE(MAX_INT_RNIL) }, + STR_VALUE(MAX_PORT_NO) }, { CFG_DB_NO_REPLICAS, @@ -1430,7 +1431,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { ConfigInfo::CI_INT, NDB_PORT, "0", - STR_VALUE(MAX_INT_RNIL) }, + STR_VALUE(MAX_PORT_NO) }, { KEY_INTERNAL, @@ -1442,7 +1443,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { ConfigInfo::CI_INT, UNDEFINED, "0", - STR_VALUE(MAX_INT_RNIL) }, + STR_VALUE(MAX_PORT_NO) }, { CFG_NODE_ARBIT_RANK, @@ -1573,7 +1574,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { ConfigInfo::CI_INT, MANDATORY, "0", - STR_VALUE(MAX_INT_RNIL) }, + STR_VALUE(MAX_PORT_NO) }, { CFG_TCP_SEND_BUFFER_SIZE, @@ -1679,7 +1680,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { ConfigInfo::CI_INT, MANDATORY, "0", - STR_VALUE(MAX_INT_RNIL) }, + STR_VALUE(MAX_PORT_NO) }, { CFG_SHM_SIGNUM, @@ -1879,7 +1880,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { ConfigInfo::CI_INT, MANDATORY, "0", - STR_VALUE(MAX_INT_RNIL) }, + STR_VALUE(MAX_PORT_NO) }, { CFG_SCI_HOST1_ID_0, From 8dc9ca833366e4844ac0a46de568c95bdc3572ee Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 22 Jun 2006 14:57:43 +0200 Subject: [PATCH 10/26] ndb - bug#20008 no DD when diskless storage/ndb/include/kernel/signaldata/CreateFilegroup.hpp: New error code for create file when diskless storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp: New error code for create file when diskless storage/ndb/src/ndbapi/ndberror.c: New error code for create file when diskless --- .../ndb/include/kernel/signaldata/CreateFilegroup.hpp | 3 ++- storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp | 11 +++++++++++ storage/ndb/src/ndbapi/ndberror.c | 1 + 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/storage/ndb/include/kernel/signaldata/CreateFilegroup.hpp b/storage/ndb/include/kernel/signaldata/CreateFilegroup.hpp index 78216249a72..59e4a33b89d 100644 --- a/storage/ndb/include/kernel/signaldata/CreateFilegroup.hpp +++ b/storage/ndb/include/kernel/signaldata/CreateFilegroup.hpp @@ -159,7 +159,8 @@ struct CreateFileRef { InvalidFilegroupVersion = 754, FilenameAlreadyExists = 760, OutOfFileRecords = 751, - InvalidFileType = 750 + InvalidFileType = 750, + NotSupportedWhenDiskless = 775 }; Uint32 senderData; diff --git a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp index 908c116988d..20132be1261 100644 --- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp +++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp @@ -15153,6 +15153,17 @@ Dbdict::create_file_prepare_start(Signal* signal, SchemaOp* op){ break; } + { + Uint32 dl; + const ndb_mgm_configuration_iterator * p = + m_ctx.m_config.getOwnConfigIterator(); + if(!ndb_mgm_get_int_parameter(p, CFG_DB_DISCLESS, &dl) && dl) + { + op->m_errorCode = CreateFileRef::NotSupportedWhenDiskless; + break; + } + } + // Loop through all filenames... if(!c_obj_pool.seize(obj_ptr)){ op->m_errorCode = CreateTableRef::NoMoreTableRecords; diff --git a/storage/ndb/src/ndbapi/ndberror.c b/storage/ndb/src/ndbapi/ndberror.c index 22252960e21..71291aa39cc 100644 --- a/storage/ndb/src/ndbapi/ndberror.c +++ b/storage/ndb/src/ndbapi/ndberror.c @@ -417,6 +417,7 @@ ErrorBundle ErrorCodes[] = { { 1514, DMEC, SE, "Currently there is a limit of one logfile group" }, { 773, DMEC, SE, "Out of string memory, please modify StringMemory config parameter" }, + { 775, DMEC, SE, "Create file is not supported when Diskless=1" }, /** * FunctionNotImplemented From a5ea8cb0d8d6fe1ae8c8de3fde280a57413788f4 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 22 Jun 2006 15:16:33 +0200 Subject: [PATCH 11/26] ndb - bug#18782 crash correct node in case of START_FRAGREF storage/ndb/include/kernel/signaldata/SystemError.hpp: Add error code storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp: Add error code storage/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp: Add error code storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp: Add error code storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp: Add error code --- .../include/kernel/signaldata/SystemError.hpp | 3 ++- storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp | 1 + .../ndb/src/kernel/blocks/dbdih/DbdihInit.cpp | 3 +++ .../ndb/src/kernel/blocks/dbdih/DbdihMain.cpp | 20 +++++++++++++++++++ .../src/kernel/blocks/ndbcntr/NdbcntrMain.cpp | 7 +++++++ 5 files changed, 33 insertions(+), 1 deletion(-) diff --git a/storage/ndb/include/kernel/signaldata/SystemError.hpp b/storage/ndb/include/kernel/signaldata/SystemError.hpp index b3646a858f6..afc25fb004f 100644 --- a/storage/ndb/include/kernel/signaldata/SystemError.hpp +++ b/storage/ndb/include/kernel/signaldata/SystemError.hpp @@ -45,7 +45,8 @@ public: CopyFragRefError = 5, TestStopOnError = 6, CopySubscriptionRef = 7, - CopySubscriberRef = 8 + CopySubscriberRef = 8, + StartFragRefError = 9 }; Uint32 errorRef; diff --git a/storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp b/storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp index f98df82ea7d..77dedc46f0a 100644 --- a/storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp +++ b/storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp @@ -683,6 +683,7 @@ private: void execGETGCIREQ(Signal *); void execDIH_RESTARTREQ(Signal *); void execSTART_RECCONF(Signal *); + void execSTART_FRAGREF(Signal *); void execSTART_FRAGCONF(Signal *); void execADD_FRAGCONF(Signal *); void execADD_FRAGREF(Signal *); diff --git a/storage/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp b/storage/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp index a6ec3749606..0e2fd3869be 100644 --- a/storage/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp +++ b/storage/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp @@ -251,6 +251,9 @@ Dbdih::Dbdih(Block_context& ctx): addRecSignal(GSN_CREATE_FRAGMENTATION_REQ, &Dbdih::execCREATE_FRAGMENTATION_REQ); + addRecSignal(GSN_START_FRAGREF, + &Dbdih::execSTART_FRAGREF); + apiConnectRecord = 0; connectRecord = 0; fileRecord = 0; diff --git a/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp b/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp index bb4c2ed197e..97006de1c5d 100644 --- a/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp +++ b/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp @@ -1106,6 +1106,26 @@ void Dbdih::execSTART_FRAGCONF(Signal* signal) return; }//Dbdih::execSTART_FRAGCONF() +void Dbdih::execSTART_FRAGREF(Signal* signal) +{ + jamEntry(); + + /** + * Kill starting node + */ + Uint32 errCode = signal->theData[1]; + Uint32 nodeId = signal->theData[2]; + + SystemError * const sysErr = (SystemError*)&signal->theData[0]; + sysErr->errorCode = SystemError::StartFragRefError; + sysErr->errorRef = reference(); + sysErr->data1 = errCode; + sysErr->data2 = 0; + sendSignal(calcNdbCntrBlockRef(nodeId), GSN_SYSTEM_ERROR, signal, + SystemError::SignalLength, JBB); + return; +}//Dbdih::execSTART_FRAGCONF() + void Dbdih::execSTART_MEREF(Signal* signal) { jamEntry(); diff --git a/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp b/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp index 7c48ebb5e8b..c3140bea25b 100644 --- a/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp +++ b/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp @@ -205,6 +205,13 @@ void Ndbcntr::execSYSTEM_ERROR(Signal* signal) killingNode, data1); break; + case SystemError::StartFragRefError: + BaseString::snprintf(buf, sizeof(buf), + "Node %d killed this node because " + "it replied StartFragRef error code: %u.", + killingNode, data1); + break; + case SystemError::CopySubscriptionRef: BaseString::snprintf(buf, sizeof(buf), "Node %d killed this node because " From 92ad3d5bd7fbfc64b083824f28470eebca5cd199 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 23 Jun 2006 00:37:31 +0200 Subject: [PATCH 12/26] mysql.spec.sh: Disable the simplistic auto dependency scan for test/bench (bug#20078) support-files/mysql.spec.sh: Disable the simplistic auto dependency scan for test/bench (bug#20078) --- support-files/mysql.spec.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 9656851dc9c..854ad2e7ce7 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -148,6 +148,7 @@ Summary: MySQL - Benchmarks and test system Group: Applications/Databases Provides: mysql-bench Obsoletes: mysql-bench +AutoReqProv: no %description bench This package contains MySQL benchmark scripts and data. From 89e415950cf3b40b15e493cb72784f6ad3dc2b64 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 23 Jun 2006 13:19:30 +0500 Subject: [PATCH 13/26] Bug#11228: DESC shows arbitrary column as "PRI" An UNIQUE KEY consisting of NOT NULL columns was displayed as PRIMARY KEY in "DESC t1". According to the code, that was intentional behaviour for some reasons unknown to me. This code was written before bitkeeper time, so I cannot check who and why made this. After discussing on dev-public, a decision was made to remove this code mysql-test/r/key.result: Adding test case. mysql-test/t/key.test: Adding test case. sql/table.cc: Removing old wrong code --- mysql-test/r/key.result | 10 ++++++++++ mysql-test/t/key.test | 11 +++++++++++ sql/table.cc | 21 --------------------- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/mysql-test/r/key.result b/mysql-test/r/key.result index f0a7afa239f..0bc241c0d19 100644 --- a/mysql-test/r/key.result +++ b/mysql-test/r/key.result @@ -326,6 +326,16 @@ alter table t1 add key (c1,c1,c2); ERROR 42S21: Duplicate column name 'c1' drop table t1; create table t1 ( +i1 INT NOT NULL, +i2 INT NOT NULL, +UNIQUE i1idx (i1), +UNIQUE i2idx (i2)); +desc t1; +Field Type Null Key Default Extra +i1 int(11) UNI 0 +i2 int(11) UNI 0 +drop table t1; +create table t1 ( c1 int, c2 varchar(20) not null, primary key (c1), diff --git a/mysql-test/t/key.test b/mysql-test/t/key.test index 85728582c75..796e36cb608 100644 --- a/mysql-test/t/key.test +++ b/mysql-test/t/key.test @@ -321,6 +321,17 @@ alter table t1 add key (c1,c2,c1); alter table t1 add key (c1,c1,c2); drop table t1; +# +# Bug#11228: DESC shows arbitrary column as "PRI" +# +create table t1 ( + i1 INT NOT NULL, + i2 INT NOT NULL, + UNIQUE i1idx (i1), + UNIQUE i2idx (i2)); +desc t1; +drop table t1; + # # Bug#12565 - ERROR 1034 when running simple UPDATE or DELETE # on large MyISAM table diff --git a/sql/table.cc b/sql/table.cc index 8ac64ac198d..513f42665a6 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -567,27 +567,6 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, if (outparam->key_info[key].flags & HA_FULLTEXT) outparam->key_info[key].algorithm= HA_KEY_ALG_FULLTEXT; - if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME)) - { - /* - If the UNIQUE key doesn't have NULL columns and is not a part key - declare this as a primary key. - */ - primary_key=key; - for (i=0 ; i < keyinfo->key_parts ;i++) - { - uint fieldnr= key_part[i].fieldnr; - if (!fieldnr || - outparam->field[fieldnr-1]->null_ptr || - outparam->field[fieldnr-1]->key_length() != - key_part[i].length) - { - primary_key=MAX_KEY; // Can't be used - break; - } - } - } - for (i=0 ; i < keyinfo->key_parts ; key_part++,i++) { if (new_field_pack_flag <= 1) From 907acc785da95878f0ff7eb6a5b88b5b18e713a8 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 23 Jun 2006 19:36:54 +0400 Subject: [PATCH 14/26] key.result: After merge fix mysql-test/r/key.result: After merge fix --- mysql-test/r/key.result | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/key.result b/mysql-test/r/key.result index 6c05a3dde8b..a6f05143b3e 100644 --- a/mysql-test/r/key.result +++ b/mysql-test/r/key.result @@ -336,8 +336,8 @@ UNIQUE i1idx (i1), UNIQUE i2idx (i2)); desc t1; Field Type Null Key Default Extra -i1 int(11) UNI 0 -i2 int(11) UNI 0 +i1 int(11) NO UNI +i2 int(11) NO UNI drop table t1; create table t1 ( c1 int, From 7072a63acd51b0b2870b9c14937ff03bd47f8e4a Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 26 Jun 2006 12:16:39 +0200 Subject: [PATCH 15/26] ndb - bug#20683 part 1 - make sure return code is propagated from request tracker ndb/src/kernel/vm/RequestTracker.hpp: propagate return value ndb/src/kernel/vm/SafeCounter.hpp: make sure object is not initialized in case of seize() failure, to make sure destructor doesnt assert --- ndb/src/kernel/vm/RequestTracker.hpp | 4 ++-- ndb/src/kernel/vm/SafeCounter.hpp | 22 ++++++++++++++-------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/ndb/src/kernel/vm/RequestTracker.hpp b/ndb/src/kernel/vm/RequestTracker.hpp index 5fd1ae7255a..ac9ed85ae4b 100644 --- a/ndb/src/kernel/vm/RequestTracker.hpp +++ b/ndb/src/kernel/vm/RequestTracker.hpp @@ -26,12 +26,12 @@ public: void init() { m_confs.clear(); m_nRefs = 0; } template - void init(SafeCounterManager& mgr, + bool init(SafeCounterManager& mgr, NodeReceiverGroup rg, Uint16 GSN, Uint32 senderData) { init(); SafeCounter tmp(mgr, m_sc); - tmp.init(rg, GSN, senderData); + return tmp.init(rg, GSN, senderData); } bool ignoreRef(SafeCounterManager& mgr, Uint32 nodeId) diff --git a/ndb/src/kernel/vm/SafeCounter.hpp b/ndb/src/kernel/vm/SafeCounter.hpp index 1f3cc15c2d6..869a7ef671f 100644 --- a/ndb/src/kernel/vm/SafeCounter.hpp +++ b/ndb/src/kernel/vm/SafeCounter.hpp @@ -230,10 +230,13 @@ inline bool SafeCounter::init(NodeReceiverGroup rg, Uint16 GSN, Uint32 senderData){ - bool b = init(rg.m_block, GSN, senderData); - m_nodes = rg.m_nodes; - m_count = m_nodes.count(); - return b; + if (init(rg.m_block, GSN, senderData)) + { + m_nodes = rg.m_nodes; + m_count = m_nodes.count(); + return true; + } + return false; } template @@ -241,10 +244,13 @@ inline bool SafeCounter::init(NodeReceiverGroup rg, Uint32 senderData){ - bool b = init(rg.m_block, Ref::GSN, senderData); - m_nodes = rg.m_nodes; - m_count = m_nodes.count(); - return b; + if (init(rg.m_block, Ref::GSN, senderData)) + { + m_nodes = rg.m_nodes; + m_count = m_nodes.count(); + return true; + } + return false; } inline From 9aa82e53d432ab7c84a8d4bd429dc095560146e5 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 26 Jun 2006 12:31:09 +0200 Subject: [PATCH 16/26] ndb - bug#20683 part 2 - handle safecounter.init() failing in all parts of event code storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp: Handle out safecounter.init() failing storage/ndb/src/kernel/blocks/suma/Suma.cpp: Dont try to get table RNIL storage/ndb/test/ndbapi/test_event.cpp: Add testcase for subscribe/unscubscribe --- .../ndb/src/kernel/blocks/dbdict/Dbdict.cpp | 50 ++++++++++++---- storage/ndb/src/kernel/blocks/suma/Suma.cpp | 3 +- storage/ndb/test/ndbapi/test_event.cpp | 57 +++++++++++++++++++ 3 files changed, 99 insertions(+), 11 deletions(-) diff --git a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp index 20132be1261..b3af476454a 100644 --- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp +++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp @@ -9476,7 +9476,14 @@ Dbdict::createEventComplete_RT_USER_GET(Signal* signal, NodeReceiverGroup rg(DBDICT, c_aliveNodes); RequestTracker & p = evntRecPtr.p->m_reqTracker; - p.init(c_counterMgr, rg, GSN_CREATE_EVNT_REF, evntRecPtr.i); + if (!p.init(c_counterMgr, rg, GSN_CREATE_EVNT_REF, + evntRecPtr.i)) + { + jam(); + evntRecPtr.p->m_errorCode = 701; + createEvent_sendReply(signal, evntRecPtr); + return; + } sendSignal(rg, GSN_CREATE_EVNT_REQ, signal, CreateEvntReq::SignalLength, JBB); } @@ -9764,8 +9771,12 @@ void Dbdict::execSUB_START_REQ(Signal* signal) return; } OpSubEventPtr subbPtr; + Uint32 errCode = 0; if (!c_opSubEvent.seize(subbPtr)) { + errCode = SubStartRef::Busy; +busy: SubStartRef * ref = (SubStartRef *)signal->getDataPtrSend(); + { // fix Uint32 subcriberRef = ((SubStartReq*)signal->getDataPtr())->subscriberRef; ref->subscriberRef = subcriberRef; @@ -9775,7 +9786,7 @@ void Dbdict::execSUB_START_REQ(Signal* signal) // ret->setErrorLine(__LINE__); // ret->setErrorNode(reference()); ref->senderRef = reference(); - ref->errorCode = SubStartRef::Busy; + ref->errorCode = errCode; sendSignal(origSenderRef, GSN_SUB_START_REF, signal, SubStartRef::SignalLength2, JBB); @@ -9798,7 +9809,12 @@ void Dbdict::execSUB_START_REQ(Signal* signal) subbPtr.p->m_senderRef = origSenderRef; // not sure if API sets correctly NodeReceiverGroup rg(DBDICT, c_aliveNodes); RequestTracker & p = subbPtr.p->m_reqTracker; - p.init(c_counterMgr, rg, GSN_SUB_START_REF, subbPtr.i); + if (!p.init(c_counterMgr, rg, GSN_SUB_START_REF, subbPtr.i)) + { + c_opSubEvent.release(subbPtr); + errCode = SubStartRef::Busy; + goto busy; + } SubStartReq* req = (SubStartReq*) signal->getDataPtrSend(); @@ -9988,14 +10004,17 @@ void Dbdict::execSUB_STOP_REQ(Signal* signal) return; } OpSubEventPtr subbPtr; + Uint32 errCode = 0; if (!c_opSubEvent.seize(subbPtr)) { + errCode = SubStopRef::Busy; +busy: SubStopRef * ref = (SubStopRef *)signal->getDataPtrSend(); jam(); // ret->setErrorCode(SubStartRef::SeizeError); // ret->setErrorLine(__LINE__); // ret->setErrorNode(reference()); ref->senderRef = reference(); - ref->errorCode = SubStopRef::Busy; + ref->errorCode = errCode; sendSignal(origSenderRef, GSN_SUB_STOP_REF, signal, SubStopRef::SignalLength, JBB); @@ -10020,10 +10039,16 @@ void Dbdict::execSUB_STOP_REQ(Signal* signal) subbPtr.p->m_senderRef = origSenderRef; // not sure if API sets correctly NodeReceiverGroup rg(DBDICT, c_aliveNodes); RequestTracker & p = subbPtr.p->m_reqTracker; - p.init(c_counterMgr, rg, GSN_SUB_STOP_REF, subbPtr.i); - + if (!p.init(c_counterMgr, rg, GSN_SUB_STOP_REF, subbPtr.i)) + { + jam(); + c_opSubEvent.release(subbPtr); + errCode = SubStopRef::Busy; + goto busy; + } + SubStopReq* req = (SubStopReq*) signal->getDataPtrSend(); - + req->senderRef = reference(); req->senderData = subbPtr.i; @@ -10313,9 +10338,14 @@ Dbdict::dropEventUTIL_EXECUTE_READ(Signal* signal, NodeReceiverGroup rg(DBDICT, c_aliveNodes); RequestTracker & p = evntRecPtr.p->m_reqTracker; - p.init(c_counterMgr, rg, GSN_SUB_REMOVE_REF, - evntRecPtr.i); - + if (!p.init(c_counterMgr, rg, GSN_SUB_REMOVE_REF, + evntRecPtr.i)) + { + evntRecPtr.p->m_errorCode = 701; + dropEvent_sendReply(signal, evntRecPtr); + return; + } + SubRemoveReq* req = (SubRemoveReq*) signal->getDataPtrSend(); req->senderRef = reference(); diff --git a/storage/ndb/src/kernel/blocks/suma/Suma.cpp b/storage/ndb/src/kernel/blocks/suma/Suma.cpp index 91f0fab06f8..5f4b8717e6c 100644 --- a/storage/ndb/src/kernel/blocks/suma/Suma.cpp +++ b/storage/ndb/src/kernel/blocks/suma/Suma.cpp @@ -2465,7 +2465,8 @@ Suma::execSUB_STOP_REQ(Signal* signal){ TablePtr tabPtr; tabPtr.i = subPtr.p->m_table_ptrI; - if (!(tabPtr.p = c_tables.getPtr(tabPtr.i)) || + if (tabPtr.i == RNIL || + !(tabPtr.p = c_tables.getPtr(tabPtr.i)) || tabPtr.p->m_tableId != subPtr.p->m_tableId) { jam(); diff --git a/storage/ndb/test/ndbapi/test_event.cpp b/storage/ndb/test/ndbapi/test_event.cpp index d8939f06b14..d132ec103ee 100644 --- a/storage/ndb/test/ndbapi/test_event.cpp +++ b/storage/ndb/test/ndbapi/test_event.cpp @@ -1559,6 +1559,56 @@ static int runCreateDropNR(NDBT_Context* ctx, NDBT_Step* step) DBUG_RETURN(result); } +static +int +runSubscribeUnsubscribe(NDBT_Context* ctx, NDBT_Step* step) +{ + char buf[1024]; + const NdbDictionary::Table & tab = * ctx->getTab(); + sprintf(buf, "%s_EVENT", tab.getName()); + Ndb* ndb = GETNDB(step); + int loops = 5 * ctx->getNumLoops(); + + while (--loops) + { + NdbEventOperation *pOp= ndb->createEventOperation(buf); + if (pOp == 0) + { + g_err << "createEventOperation: " + << ndb->getNdbError().code << " " + << ndb->getNdbError().message << endl; + return NDBT_FAILED; + } + + int n_columns= tab.getNoOfColumns(); + for (int j = 0; j < n_columns; j++) + { + pOp->getValue(tab.getColumn(j)->getName()); + pOp->getPreValue(tab.getColumn(j)->getName()); + } + if ( pOp->execute() ) + { + g_err << "pOp->execute(): " + << pOp->getNdbError().code << " " + << pOp->getNdbError().message << endl; + + ndb->dropEventOperation(pOp); + + return NDBT_FAILED; + } + + if (ndb->dropEventOperation(pOp)) + { + g_err << "pOp->execute(): " + << ndb->getNdbError().code << " " + << ndb->getNdbError().message << endl; + return NDBT_FAILED; + } + } + + return NDBT_OK; +} + NDBT_TESTSUITE(test_event); TESTCASE("BasicEventOperation", "Verify that we can listen to Events" @@ -1673,6 +1723,13 @@ TESTCASE("CreateDropNR", "NOTE! No errors are allowed!" ){ FINALIZER(runCreateDropNR); } +TESTCASE("SubscribeUnsubscribe", + "A bunch of threads doing subscribe/unsubscribe in loop" + "NOTE! No errors are allowed!" ){ + INITIALIZER(runCreateEvent); + STEPS(runSubscribeUnsubscribe, 16); + FINALIZER(runDropEvent); +} NDBT_TESTSUITE_END(test_event); int main(int argc, const char** argv){ From 90913a036450a784f36ffccc0921f1946ea44222 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 26 Jun 2006 15:08:09 +0200 Subject: [PATCH 17/26] ndb - bug#20053 make sure we can only drop files from correct file group mysql-test/r/ndb_dd_ddl.result: add testcase mysql-test/t/ndb_dd_ddl.test: add testcase sql/ha_ndbcluster.cc: Make sure correct tablespace for dropping datafile storage/ndb/include/ndbapi/NdbDictionary.hpp: Cleanup {data/undo}file get{tablespace/logfilegroup} storage/ndb/src/ndbapi/NdbDictionary.cpp: Cleanup {data/undo}file get{tablespace/logfilegroup} storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp: Cleanup {data/undo}file get{tablespace/logfilegroup} storage/ndb/tools/restore/consumer_restore.cpp: Cleanup {data/undo}file get{tablespace/logfilegroup} --- mysql-test/r/ndb_dd_ddl.result | 18 +++++++++++ mysql-test/t/ndb_dd_ddl.test | 26 +++++++++++++++ sql/ha_ndbcluster.cc | 15 ++++++--- storage/ndb/include/ndbapi/NdbDictionary.hpp | 8 ++--- storage/ndb/src/ndbapi/NdbDictionary.cpp | 32 +++++++++++++------ storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp | 12 +++++-- .../ndb/tools/restore/consumer_restore.cpp | 13 +++++--- 7 files changed, 98 insertions(+), 26 deletions(-) diff --git a/mysql-test/r/ndb_dd_ddl.result b/mysql-test/r/ndb_dd_ddl.result index 9fff9f06f2a..eea80090768 100644 --- a/mysql-test/r/ndb_dd_ddl.result +++ b/mysql-test/r/ndb_dd_ddl.result @@ -188,6 +188,19 @@ ENGINE NDB; CREATE INDEX b_i on t1(b); CREATE INDEX bc_i on t1(b, c); DROP TABLE t1; +CREATE TABLESPACE ts2 +ADD DATAFILE 'datafile3.dat' +USE LOGFILE GROUP lg1 +INITIAL_SIZE 1M +ENGINE NDB; +ALTER TABLESPACE ts1 +DROP DATAFILE 'datafile3.dat' +ENGINE NDB; +ERROR HY000: Failed to alter: NO SUCH FILE +ALTER TABLESPACE ts2 +DROP DATAFILE 'datafile2.dat' +ENGINE NDB; +ERROR HY000: Failed to alter: NO SUCH FILE ALTER TABLESPACE ts1 DROP DATAFILE 'datafile2.dat' ENGINE NDB; @@ -196,6 +209,11 @@ DROP DATAFILE 'datafile.dat' ENGINE NDB; DROP TABLESPACE ts1 ENGINE NDB; +ALTER TABLESPACE ts2 +DROP DATAFILE 'datafile3.dat' +ENGINE NDB; +DROP TABLESPACE ts2 +ENGINE NDB; DROP LOGFILE GROUP lg1 ENGINE NDB; **** End = And No = **** diff --git a/mysql-test/t/ndb_dd_ddl.test b/mysql-test/t/ndb_dd_ddl.test index 95ad7f0d152..1a470d52c6c 100644 --- a/mysql-test/t/ndb_dd_ddl.test +++ b/mysql-test/t/ndb_dd_ddl.test @@ -280,6 +280,25 @@ CREATE INDEX bc_i on t1(b, c); DROP TABLE t1; +# bug#20053 + +CREATE TABLESPACE ts2 +ADD DATAFILE 'datafile3.dat' +USE LOGFILE GROUP lg1 +INITIAL_SIZE 1M +ENGINE NDB; + +--error ER_ALTER_FILEGROUP_FAILED +ALTER TABLESPACE ts1 +DROP DATAFILE 'datafile3.dat' +ENGINE NDB; + +--error ER_ALTER_FILEGROUP_FAILED +ALTER TABLESPACE ts2 +DROP DATAFILE 'datafile2.dat' +ENGINE NDB; +# bug#20053 + ALTER TABLESPACE ts1 DROP DATAFILE 'datafile2.dat' ENGINE NDB; @@ -291,6 +310,13 @@ ENGINE NDB; DROP TABLESPACE ts1 ENGINE NDB; +ALTER TABLESPACE ts2 +DROP DATAFILE 'datafile3.dat' +ENGINE NDB; + +DROP TABLESPACE ts2 +ENGINE NDB; + DROP LOGFILE GROUP lg1 ENGINE NDB; diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 986014a36d1..69e615daea2 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -9949,7 +9949,7 @@ int ndbcluster_alter_tablespace(THD* thd, st_alter_tablespace *info) } NdbError err; - NDBDICT *dict = ndb->getDictionary(); + NDBDICT *dict= ndb->getDictionary(); int error; const char * errmsg; LINT_INIT(errmsg); @@ -10013,9 +10013,12 @@ int ndbcluster_alter_tablespace(THD* thd, st_alter_tablespace *info) } else if(info->ts_alter_tablespace_type == ALTER_TABLESPACE_DROP_FILE) { - NdbDictionary::Datafile df = dict->getDatafile(0, - info->data_file_name); - if (strcmp(df.getPath(), info->data_file_name) == 0) + NdbDictionary::Tablespace ts= dict->getTablespace(info->tablespace_name); + NdbDictionary::Datafile df= dict->getDatafile(0, info->data_file_name); + NdbDictionary::ObjectId objid; + df.getTablespaceId(&objid); + if (ts.getObjectId() == objid.getObjectId() && + strcmp(df.getPath(), info->data_file_name) == 0) { errmsg= " DROP DATAFILE"; if (dict->dropDatafile(df)) @@ -10344,10 +10347,12 @@ static int ndbcluster_fill_files_table(THD *thd, TABLE_LIST *tables, table->field[c++]->set_null(); // TABLE_NAME // LOGFILE_GROUP_NAME + NdbDictionary::ObjectId objid; + uf.getLogfileGroupId(&objid); table->field[c++]->store(uf.getLogfileGroup(), strlen(uf.getLogfileGroup()), system_charset_info); - table->field[c++]->store(uf.getLogfileGroupId()); // LOGFILE_GROUP_NUMBER + table->field[c++]->store(objid.getObjectId()); // LOGFILE_GROUP_NUMBER table->field[c++]->store(ndbcluster_hton_name, ndbcluster_hton_name_length, system_charset_info); // ENGINE diff --git a/storage/ndb/include/ndbapi/NdbDictionary.hpp b/storage/ndb/include/ndbapi/NdbDictionary.hpp index a9fd107c06e..2133c9658aa 100644 --- a/storage/ndb/include/ndbapi/NdbDictionary.hpp +++ b/storage/ndb/include/ndbapi/NdbDictionary.hpp @@ -184,7 +184,7 @@ public: virtual int getObjectId() const; private: - friend class Dictionary; + friend class NdbDictObjectImpl; class NdbDictObjectImpl & m_impl; }; @@ -1462,11 +1462,11 @@ public: void setSize(Uint64); Uint64 getSize() const; Uint64 getFree() const; - + void setTablespace(const char * name); void setTablespace(const class Tablespace &); const char * getTablespace() const; - Uint32 getTablespaceId() const; + void getTablespaceId(ObjectId * dst) const; void setNode(Uint32 nodeId); Uint32 getNode() const; @@ -1509,7 +1509,7 @@ public: void setLogfileGroup(const char * name); void setLogfileGroup(const class LogfileGroup &); const char * getLogfileGroup() const; - Uint32 getLogfileGroupId() const; + void getLogfileGroupId(ObjectId * dst) const; void setNode(Uint32 nodeId); Uint32 getNode() const; diff --git a/storage/ndb/src/ndbapi/NdbDictionary.cpp b/storage/ndb/src/ndbapi/NdbDictionary.cpp index 7d888456888..132e651c687 100644 --- a/storage/ndb/src/ndbapi/NdbDictionary.cpp +++ b/storage/ndb/src/ndbapi/NdbDictionary.cpp @@ -1224,9 +1224,14 @@ NdbDictionary::Datafile::getTablespace() const { return m_impl.m_filegroup_name.c_str(); } -Uint32 -NdbDictionary::Datafile::getTablespaceId() const { - return m_impl.m_filegroup_id; +void +NdbDictionary::Datafile::getTablespaceId(NdbDictionary::ObjectId* dst) const +{ + if (dst) + { + NdbDictObjectImpl::getImpl(* dst).m_id = m_impl.m_filegroup_id; + NdbDictObjectImpl::getImpl(* dst).m_version = m_impl.m_filegroup_version; + } } NdbDictionary::Object::Status @@ -1310,9 +1315,14 @@ NdbDictionary::Undofile::getLogfileGroup() const { return m_impl.m_filegroup_name.c_str(); } -Uint32 -NdbDictionary::Undofile::getLogfileGroupId() const { - return m_impl.m_filegroup_id; +void +NdbDictionary::Undofile::getLogfileGroupId(NdbDictionary::ObjectId * dst)const +{ + if (dst) + { + NdbDictObjectImpl::getImpl(* dst).m_id = m_impl.m_filegroup_id; + NdbDictObjectImpl::getImpl(* dst).m_version = m_impl.m_filegroup_version; + } } NdbDictionary::Object::Status @@ -1829,7 +1839,8 @@ NdbDictionary::Dictionary::createLogfileGroup(const LogfileGroup & lg, ObjectId * obj) { return m_impl.createLogfileGroup(NdbLogfileGroupImpl::getImpl(lg), - obj ? &obj->m_impl : 0); + obj ? + & NdbDictObjectImpl::getImpl(* obj) : 0); } int @@ -1852,7 +1863,8 @@ NdbDictionary::Dictionary::createTablespace(const Tablespace & lg, ObjectId * obj) { return m_impl.createTablespace(NdbTablespaceImpl::getImpl(lg), - obj ? &obj->m_impl : 0); + obj ? + & NdbDictObjectImpl::getImpl(* obj) : 0); } int @@ -1887,7 +1899,7 @@ NdbDictionary::Dictionary::createDatafile(const Datafile & df, { return m_impl.createDatafile(NdbDatafileImpl::getImpl(df), force, - obj ? &obj->m_impl : 0); + obj ? & NdbDictObjectImpl::getImpl(* obj) : 0); } int @@ -1913,7 +1925,7 @@ NdbDictionary::Dictionary::createUndofile(const Undofile & df, { return m_impl.createUndofile(NdbUndofileImpl::getImpl(df), force, - obj ? &obj->m_impl : 0); + obj ? & NdbDictObjectImpl::getImpl(* obj) : 0); } int diff --git a/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp b/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp index 35e8027cdec..a95af988f1e 100644 --- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp +++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp @@ -46,14 +46,22 @@ public: NdbDictionary::Object::Status m_status; bool change(); + + static NdbDictObjectImpl & getImpl(NdbDictionary::ObjectId & t) { + return t.m_impl; + } + static const NdbDictObjectImpl & getImpl(const NdbDictionary::ObjectId & t){ + return t.m_impl; + } + protected: + friend class NdbDictionary::ObjectId; + NdbDictObjectImpl(NdbDictionary::Object::Type type) : m_type(type), m_status(NdbDictionary::Object::New) { m_id = -1; } - - friend class NdbDictionary::ObjectId; }; /** diff --git a/storage/ndb/tools/restore/consumer_restore.cpp b/storage/ndb/tools/restore/consumer_restore.cpp index 6b0d42ee0d2..97bb3ad9587 100644 --- a/storage/ndb/tools/restore/consumer_restore.cpp +++ b/storage/ndb/tools/restore/consumer_restore.cpp @@ -533,9 +533,11 @@ BackupRestore::object(Uint32 type, const void * ptr) if (!m_no_restore_disk) { NdbDictionary::Datafile old(*(NdbDictionary::Datafile*)ptr); - NdbDictionary::Tablespace * ts = m_tablespaces[old.getTablespaceId()]; + NdbDictionary::ObjectId objid; + old.getTablespaceId(&objid); + NdbDictionary::Tablespace * ts = m_tablespaces[objid.getObjectId()]; debug << "Connecting datafile " << old.getPath() - << " to tablespace: oldid: " << old.getTablespaceId() + << " to tablespace: oldid: " << objid.getObjectId() << " newid: " << ts->getObjectId() << endl; old.setTablespace(* ts); info << "Creating datafile \"" << old.getPath() << "\"..." << flush; @@ -554,10 +556,11 @@ BackupRestore::object(Uint32 type, const void * ptr) if (!m_no_restore_disk) { NdbDictionary::Undofile old(*(NdbDictionary::Undofile*)ptr); - NdbDictionary::LogfileGroup * lg = - m_logfilegroups[old.getLogfileGroupId()]; + NdbDictionary::ObjectId objid; + old.getLogfileGroupId(&objid); + NdbDictionary::LogfileGroup * lg = m_logfilegroups[objid.getObjectId()]; debug << "Connecting undofile " << old.getPath() - << " to logfile group: oldid: " << old.getLogfileGroupId() + << " to logfile group: oldid: " << objid.getObjectId() << " newid: " << lg->getObjectId() << " " << (void*)lg << endl; old.setLogfileGroup(* lg); From 2ad33373d62c22d4fe22a104e5ac0ebaff0d0615 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 26 Jun 2006 23:31:10 +1000 Subject: [PATCH 18/26] BUG#11459 ndb status variables not updated change names of some undocumented ndb status variables to better reflect what their values mean sql/ha_ndbcluster.cc: rename some status variables to better reflect what they show. --- sql/ha_ndbcluster.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 98dd9d5a122..9814e2c84b6 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -160,8 +160,8 @@ static int update_status_variables(Ndb_cluster_connection *c) struct show_var_st ndb_status_variables[]= { {"cluster_node_id", (char*) &ndb_cluster_node_id, SHOW_LONG}, - {"connected_host", (char*) &ndb_connected_host, SHOW_CHAR_PTR}, - {"connected_port", (char*) &ndb_connected_port, SHOW_LONG}, + {"config_from_host", (char*) &ndb_connected_host, SHOW_CHAR_PTR}, + {"config_from_port", (char*) &ndb_connected_port, SHOW_LONG}, // {"number_of_replicas", (char*) &ndb_number_of_replicas, SHOW_LONG}, {"number_of_storage_nodes",(char*) &ndb_number_of_storage_nodes, SHOW_LONG}, {NullS, NullS, SHOW_LONG} From f105602806c030f7a2252843986e048d35cb13f3 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 27 Jun 2006 11:41:00 +0200 Subject: [PATCH 19/26] ndb - bug#20252 allow user to specify scan batch size in readTuples ndb/include/ndbapi/NdbIndexScanOperation.hpp: Allow user to specify batch size ndb/include/ndbapi/NdbScanOperation.hpp: Allow user to specify batch size ndb/src/kernel/blocks/dblqh/DblqhMain.cpp: Fix so that last row works even if batch is complete ndb/src/ndbapi/NdbReceiver.cpp: Allow user yo specify batch size ndb/src/ndbapi/NdbScanOperation.cpp: Allow user to specify batchsize --- ndb/include/ndbapi/NdbIndexScanOperation.hpp | 6 +++-- ndb/include/ndbapi/NdbScanOperation.hpp | 4 +++- ndb/src/kernel/blocks/dblqh/DblqhMain.cpp | 8 +++---- ndb/src/ndbapi/NdbReceiver.cpp | 10 ++++++++- ndb/src/ndbapi/NdbScanOperation.cpp | 23 +++++++++++++------- 5 files changed, 35 insertions(+), 16 deletions(-) diff --git a/ndb/include/ndbapi/NdbIndexScanOperation.hpp b/ndb/include/ndbapi/NdbIndexScanOperation.hpp index e9f92d84d1c..e7393bdfd17 100644 --- a/ndb/include/ndbapi/NdbIndexScanOperation.hpp +++ b/ndb/include/ndbapi/NdbIndexScanOperation.hpp @@ -41,7 +41,9 @@ public: * @param parallel No of fragments to scan in parallel (0=max) */ virtual int readTuples(LockMode lock_mode = LM_Read, - Uint32 scan_flags = 0, Uint32 parallel = 0); + Uint32 scan_flags = 0, + Uint32 parallel = 0, + Uint32 batch = 0); #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL /** @@ -66,7 +68,7 @@ public: (SF_OrderBy & -(Int32)order_by) | (SF_Descending & -(Int32)order_desc) | (SF_ReadRangeNo & -(Int32)read_range_no); - return readTuples(lock_mode, scan_flags, parallel); + return readTuples(lock_mode, scan_flags, parallel, batch); } #endif diff --git a/ndb/include/ndbapi/NdbScanOperation.hpp b/ndb/include/ndbapi/NdbScanOperation.hpp index 77b255dc2f4..2cab02c58a9 100644 --- a/ndb/include/ndbapi/NdbScanOperation.hpp +++ b/ndb/include/ndbapi/NdbScanOperation.hpp @@ -56,7 +56,9 @@ public: */ virtual int readTuples(LockMode lock_mode = LM_Read, - Uint32 scan_flags = 0, Uint32 parallel = 0); + Uint32 scan_flags = 0, + Uint32 parallel = 0, + Uint32 batch = 0); #ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED /** diff --git a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp index 19a003f00fc..c8fd440a150 100644 --- a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp +++ b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp @@ -7349,15 +7349,15 @@ void Dblqh::scanLockReleasedLab(Signal* signal) scanptr.p->m_curr_batch_size_rows = 0; scanptr.p->m_curr_batch_size_bytes = 0; closeScanLab(signal); + } else if (scanptr.p->m_last_row && !scanptr.p->scanLockHold) { + jam(); + closeScanLab(signal); + return; } else if (scanptr.p->check_scan_batch_completed() && scanptr.p->scanLockHold != ZTRUE) { jam(); scanptr.p->scanState = ScanRecord::WAIT_SCAN_NEXTREQ; sendScanFragConf(signal, ZFALSE); - } else if (scanptr.p->m_last_row && !scanptr.p->scanLockHold) { - jam(); - closeScanLab(signal); - return; } else { jam(); /* diff --git a/ndb/src/ndbapi/NdbReceiver.cpp b/ndb/src/ndbapi/NdbReceiver.cpp index df16ae66915..62119880076 100644 --- a/ndb/src/ndbapi/NdbReceiver.cpp +++ b/ndb/src/ndbapi/NdbReceiver.cpp @@ -121,7 +121,15 @@ NdbReceiver::calculate_batch_size(Uint32 key_size, * no more than MAX_SCAN_BATCH_SIZE is sent from all nodes in total per * batch. */ - batch_byte_size= max_batch_byte_size; + if (batch_size == 0) + { + batch_byte_size= max_batch_byte_size; + } + else + { + batch_byte_size= batch_size * tot_size; + } + if (batch_byte_size * parallelism > max_scan_batch_size) { batch_byte_size= max_scan_batch_size / parallelism; } diff --git a/ndb/src/ndbapi/NdbScanOperation.cpp b/ndb/src/ndbapi/NdbScanOperation.cpp index 869704c7bb3..f14b5409ce8 100644 --- a/ndb/src/ndbapi/NdbScanOperation.cpp +++ b/ndb/src/ndbapi/NdbScanOperation.cpp @@ -117,7 +117,8 @@ NdbScanOperation::init(const NdbTableImpl* tab, NdbTransaction* myConnection) int NdbScanOperation::readTuples(NdbScanOperation::LockMode lm, Uint32 scan_flags, - Uint32 parallel) + Uint32 parallel, + Uint32 batch) { m_ordered = m_descending = false; Uint32 fragCount = m_currentTable->m_fragmentCount; @@ -181,9 +182,12 @@ NdbScanOperation::readTuples(NdbScanOperation::LockMode lm, bool tupScan = (scan_flags & SF_TupScan); if (tupScan && rangeScan) tupScan = false; - - theParallelism = parallel; + if (rangeScan && (scan_flags & SF_OrderBy)) + parallel = fragCount; + + theParallelism = parallel; + if(fix_receivers(parallel) == -1){ setErrorCodeAbort(4000); return -1; @@ -202,6 +206,7 @@ NdbScanOperation::readTuples(NdbScanOperation::LockMode lm, req->tableSchemaVersion = m_accessTable->m_version; req->storedProcId = 0xFFFF; req->buddyConPtr = theNdbCon->theBuddyConPtr; + req->first_batch_size = batch; // Save user specified batch size Uint32 reqInfo = 0; ScanTabReq::setParallelism(reqInfo, parallel); @@ -750,13 +755,14 @@ int NdbScanOperation::prepareSendScan(Uint32 aTC_ConnectPtr, * The number of records sent by each LQH is calculated and the kernel * is informed of this number by updating the SCAN_TABREQ signal */ - Uint32 batch_size, batch_byte_size, first_batch_size; + ScanTabReq * req = CAST_PTR(ScanTabReq, theSCAN_TABREQ->getDataPtrSend()); + Uint32 batch_size = req->first_batch_size; // User specified + Uint32 batch_byte_size, first_batch_size; theReceiver.calculate_batch_size(key_size, theParallelism, batch_size, batch_byte_size, first_batch_size); - ScanTabReq * req = CAST_PTR(ScanTabReq, theSCAN_TABREQ->getDataPtrSend()); ScanTabReq::setScanBatch(req->requestInfo, batch_size); req->batch_byte_size= batch_byte_size; req->first_batch_size= first_batch_size; @@ -1206,13 +1212,14 @@ error: int NdbIndexScanOperation::readTuples(LockMode lm, Uint32 scan_flags, - Uint32 parallel) + Uint32 parallel, + Uint32 batch) { const bool order_by = scan_flags & SF_OrderBy; const bool order_desc = scan_flags & SF_Descending; const bool read_range_no = scan_flags & SF_ReadRangeNo; - - int res = NdbScanOperation::readTuples(lm, scan_flags, 0); + + int res = NdbScanOperation::readTuples(lm, scan_flags, parallel, batch); if(!res && read_range_no) { m_read_range_no = 1; From 9512629598687882a2c7abd3ec5af9c732163607 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 28 Jun 2006 01:07:44 +1000 Subject: [PATCH 20/26] BUG#20725 MySQLD cluster use "fast count" is broken Post recent handler changes, fast count(*) for cluster was broken. Seeing as we maintain an exact count for ndb, we can easily use this for an optimisation. With this patch, and use_exact_count DISABLED, we will use the fast way of getting count(*) but not use the exact count for the optimiser. With this patch and use_exact_count ENABLED, we will use the fast way of getting count(*) and use the exact count for the optimiser. sql/ha_ndbcluster.cc: Implement handler::records() and set appropriate handler flag. sql/ha_ndbcluster.h: we implment handler::records() for fast count(*) --- sql/ha_ndbcluster.cc | 27 ++++++++++++++++++++++++++- sql/ha_ndbcluster.h | 1 + 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 997072bd2a5..f31b8c7e397 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -414,6 +414,30 @@ void ha_ndbcluster::set_rec_per_key() DBUG_VOID_RETURN; } +ha_rows ha_ndbcluster::records() +{ + ha_rows retval; + DBUG_ENTER("ha_ndbcluster::records"); + struct Ndb_local_table_statistics *info= m_table_info; + DBUG_PRINT("info", ("id=%d, no_uncommitted_rows_count=%d", + ((const NDBTAB *)m_table)->getTableId(), + info->no_uncommitted_rows_count)); + + Ndb *ndb= get_ndb(); + ndb->setDatabaseName(m_dbname); + struct Ndb_statistics stat; + if (ndb_get_table_statistics(ndb, m_table, &stat) == 0) + { + retval= stat.row_count; + } + + THD *thd= current_thd; + if (get_thd_ndb(thd)->error) + info->no_uncommitted_rows_count= 0; + + DBUG_RETURN(retval + info->no_uncommitted_rows_count); +} + void ha_ndbcluster::records_update() { if (m_ha_not_exact_count) @@ -5455,7 +5479,8 @@ void ha_ndbcluster::get_auto_increment(ulonglong offset, ulonglong increment, HA_PRIMARY_KEY_REQUIRED_FOR_POSITION | \ HA_PRIMARY_KEY_REQUIRED_FOR_DELETE | \ HA_PARTIAL_COLUMN_READ | \ - HA_HAS_OWN_BINLOGGING + HA_HAS_OWN_BINLOGGING | \ + HA_HAS_RECORDS ha_ndbcluster::ha_ndbcluster(TABLE_SHARE *table_arg): handler(&ndbcluster_hton, table_arg), diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h index 2e78a00ef94..d03a6cc4c5d 100644 --- a/sql/ha_ndbcluster.h +++ b/sql/ha_ndbcluster.h @@ -622,6 +622,7 @@ class ha_ndbcluster: public handler int read_multi_range_next(KEY_MULTI_RANGE **found_range_p); bool get_error_message(int error, String *buf); + ha_rows records(); void info(uint); void get_dynamic_partition_info(PARTITION_INFO *stat_info, uint part_id); int extra(enum ha_extra_function operation); From da81451d518fc1db35e16ff62d701f87c2461242 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 28 Jun 2006 01:28:07 +1000 Subject: [PATCH 21/26] BUG#20725 MySQLD cluster use "fast count" is broken fix based on review by tomas. conform to bug we haven't fixed yet. sql/ha_ndbcluster.cc: return -1 on error in ::records(). produces a compiler warning, a bug and is evil. however, until we go and really fix the bug properly, it's best to conform --- sql/ha_ndbcluster.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index f31b8c7e397..f499f01986a 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -430,6 +430,13 @@ ha_rows ha_ndbcluster::records() { retval= stat.row_count; } + else + { + /** + * Be consistent with BUG#19914 until we fix it properly + */ + DBUG_RETURN(-1); + } THD *thd= current_thd; if (get_thd_ndb(thd)->error) From d7534c3af39aa775dc9478b74b873634e697ccfd Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 28 Jun 2006 11:27:37 +0200 Subject: [PATCH 22/26] ndb - bug#20442 force close of scan (of outstanding scan_frag) ndb/src/ndbapi/NdbScanOperation.cpp: Force close of scan in when not doing committed read scan --- ndb/src/ndbapi/NdbScanOperation.cpp | 60 +++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/ndb/src/ndbapi/NdbScanOperation.cpp b/ndb/src/ndbapi/NdbScanOperation.cpp index f14b5409ce8..6b587be688f 100644 --- a/ndb/src/ndbapi/NdbScanOperation.cpp +++ b/ndb/src/ndbapi/NdbScanOperation.cpp @@ -1503,6 +1503,66 @@ NdbScanOperation::close_impl(TransporterFacade* tp, bool forceSend){ return -1; } + bool holdLock = false; + if (theSCAN_TABREQ) + { + ScanTabReq * req = CAST_PTR(ScanTabReq, theSCAN_TABREQ->getDataPtrSend()); + holdLock = ScanTabReq::getHoldLockFlag(req->requestInfo); + } + + /** + * When using locks, force close of scan directly + */ + if (holdLock && theError.code == 0 && + (m_sent_receivers_count + m_conf_receivers_count + m_api_receivers_count)) + { + TransporterFacade * tp = TransporterFacade::instance(); + NdbApiSignal tSignal(theNdb->theMyRef); + tSignal.setSignal(GSN_SCAN_NEXTREQ); + + Uint32* theData = tSignal.getDataPtrSend(); + Uint64 transId = theNdbCon->theTransactionId; + theData[0] = theNdbCon->theTCConPtr; + theData[1] = 1; + theData[2] = transId; + theData[3] = (Uint32) (transId >> 32); + + tSignal.setLength(4); + int ret = tp->sendSignal(&tSignal, nodeId); + if (ret) + { + setErrorCode(4008); + return -1; + } + checkForceSend(forceSend); + + /** + * If no receiver is outstanding... + * set it to 1 as execCLOSE_SCAN_REP resets it + */ + m_sent_receivers_count = m_sent_receivers_count ? m_sent_receivers_count : 1; + + while(theError.code == 0 && (m_sent_receivers_count + m_conf_receivers_count)) + { + theNdb->theImpl->theWaiter.m_node = nodeId; + theNdb->theImpl->theWaiter.m_state = WAIT_SCAN; + int return_code = theNdb->receiveResponse(WAITFOR_SCAN_TIMEOUT); + switch(return_code){ + case 0: + break; + case -1: + setErrorCode(4008); + case -2: + m_api_receivers_count = 0; + m_conf_receivers_count = 0; + m_sent_receivers_count = 0; + theNdbCon->theReleaseOnClose = true; + return -1; + } + } + return 0; + } + /** * Wait for outstanding */ From 52c32382ce7c83d2c9d7590fc517d4e4aa4c1c2f Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 28 Jun 2006 11:38:22 +0200 Subject: [PATCH 23/26] ndb - ndbapi test of bug#20252 storage/ndb/test/ndbapi/testScan.cpp: ndbapi test of bug#20252 --- storage/ndb/test/ndbapi/testScan.cpp | 104 ++++++++++++++------------- 1 file changed, 55 insertions(+), 49 deletions(-) diff --git a/storage/ndb/test/ndbapi/testScan.cpp b/storage/ndb/test/ndbapi/testScan.cpp index d8c45985630..097454f69b2 100644 --- a/storage/ndb/test/ndbapi/testScan.cpp +++ b/storage/ndb/test/ndbapi/testScan.cpp @@ -1151,70 +1151,76 @@ runScanVariants(NDBT_Context* ctx, NDBT_Step* step) { for(int flags = 0; flags < 4; flags++) { - for (int par = 0; par < 16; par += 1 + (rand() % 3)) + for (int batch = 0; batch < 100; batch += (1 + batch + (batch >> 3))) { - bool disk = flags & 1; - bool tups = flags & 2; - g_info << "lm: " << lm - << " disk: " << disk - << " tup scan: " << tups - << " par: " << par - << endl; - - NdbConnection* pCon = pNdb->startTransaction(); - NdbScanOperation* pOp = pCon->getNdbScanOperation(pTab->getName()); - if (pOp == NULL) { - ERR(pCon->getNdbError()); - return NDBT_FAILED; - } - - if( pOp->readTuples((NdbOperation::LockMode)lm, - tups ? NdbScanOperation::SF_TupScan : 0, - par) != 0) + for (int par = 0; par < 16; par += 1 + (rand() % 3)) { - ERR(pCon->getNdbError()); - return NDBT_FAILED; - } - - int check = pOp->interpret_exit_ok(); - if( check == -1 ) { - ERR(pCon->getNdbError()); - return NDBT_FAILED; - } - - // Define attributes to read - bool found_disk = false; - for(int a = 0; agetNoOfColumns(); a++){ - if (pTab->getColumn(a)->getStorageType() == NdbDictionary::Column::StorageTypeDisk) - { - found_disk = true; - if (!disk) - continue; - } + bool disk = flags & 1; + bool tups = flags & 2; + g_info << "lm: " << lm + << " disk: " << disk + << " tup scan: " << tups + << " par: " << par + << " batch: " << batch + << endl; - if((pOp->getValue(pTab->getColumn(a)->getName())) == 0) { + NdbConnection* pCon = pNdb->startTransaction(); + NdbScanOperation* pOp = pCon->getNdbScanOperation(pTab->getName()); + if (pOp == NULL) { ERR(pCon->getNdbError()); return NDBT_FAILED; } - } - - if (! (disk && !found_disk)) - { - check = pCon->execute(NoCommit); + + if( pOp->readTuples((NdbOperation::LockMode)lm, + tups ? NdbScanOperation::SF_TupScan : 0, + par, + batch) != 0) + { + ERR(pCon->getNdbError()); + return NDBT_FAILED; + } + + int check = pOp->interpret_exit_ok(); if( check == -1 ) { ERR(pCon->getNdbError()); return NDBT_FAILED; } - int res; - int row = 0; - while((res = pOp->nextResult()) == 0); + // Define attributes to read + bool found_disk = false; + for(int a = 0; agetNoOfColumns(); a++){ + if (pTab->getColumn(a)->getStorageType() == + NdbDictionary::Column::StorageTypeDisk) + { + found_disk = true; + if (!disk) + continue; + } + + if((pOp->getValue(pTab->getColumn(a)->getName())) == 0) { + ERR(pCon->getNdbError()); + return NDBT_FAILED; + } + } + + if (! (disk && !found_disk)) + { + check = pCon->execute(NoCommit); + if( check == -1 ) { + ERR(pCon->getNdbError()); + return NDBT_FAILED; + } + + int res; + int row = 0; + while((res = pOp->nextResult()) == 0); + } + pCon->close(); } - pCon->close(); } } } - + return NDBT_OK; } From 42f612626f7825a3eac4d3dadd841c1fa344fb81 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 28 Jun 2006 12:16:10 +0200 Subject: [PATCH 24/26] ndb - 50->51 merge of bug#20442, force close scan (with locks) storage/ndb/src/ndbapi/NdbScanOperation.cpp: merge --- storage/ndb/src/ndbapi/NdbScanOperation.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/storage/ndb/src/ndbapi/NdbScanOperation.cpp b/storage/ndb/src/ndbapi/NdbScanOperation.cpp index bc4baacbcf0..5852570a686 100644 --- a/storage/ndb/src/ndbapi/NdbScanOperation.cpp +++ b/storage/ndb/src/ndbapi/NdbScanOperation.cpp @@ -1587,7 +1587,6 @@ NdbScanOperation::close_impl(TransporterFacade* tp, bool forceSend, if (holdLock && theError.code == 0 && (m_sent_receivers_count + m_conf_receivers_count + m_api_receivers_count)) { - TransporterFacade * tp = TransporterFacade::instance(); NdbApiSignal tSignal(theNdb->theMyRef); tSignal.setSignal(GSN_SCAN_NEXTREQ); @@ -1605,8 +1604,7 @@ NdbScanOperation::close_impl(TransporterFacade* tp, bool forceSend, setErrorCode(4008); return -1; } - checkForceSend(forceSend); - + /** * If no receiver is outstanding... * set it to 1 as execCLOSE_SCAN_REP resets it @@ -1615,9 +1613,7 @@ NdbScanOperation::close_impl(TransporterFacade* tp, bool forceSend, while(theError.code == 0 && (m_sent_receivers_count + m_conf_receivers_count)) { - theNdb->theImpl->theWaiter.m_node = nodeId; - theNdb->theImpl->theWaiter.m_state = WAIT_SCAN; - int return_code = theNdb->receiveResponse(WAITFOR_SCAN_TIMEOUT); + int return_code = poll_guard->wait_scan(WAITFOR_SCAN_TIMEOUT, nodeId, forceSend); switch(return_code){ case 0: break; @@ -1639,8 +1635,7 @@ NdbScanOperation::close_impl(TransporterFacade* tp, bool forceSend, */ while(theError.code == 0 && m_sent_receivers_count) { - int return_code= poll_guard->wait_scan(WAITFOR_SCAN_TIMEOUT, nodeId, - false); + int return_code= poll_guard->wait_scan(WAITFOR_SCAN_TIMEOUT, nodeId, forceSend); switch(return_code){ case 0: break; From a0837ecec49cbd258cb9f0a3cd83ecef90355179 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 28 Jun 2006 21:52:24 +1000 Subject: [PATCH 25/26] BUG#19894 Data nodes fail during loading data if NoOfFragmentLogFiles=1 change default minimum to 3 bug is *very* timing dependent, unable to reproduce here, but theoretically possible. ndb/src/mgmsrv/ConfigInfo.cpp: change minimum NoOfFragmentLogFiles to 3 --- ndb/src/mgmsrv/ConfigInfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ndb/src/mgmsrv/ConfigInfo.cpp b/ndb/src/mgmsrv/ConfigInfo.cpp index 66a400a3e22..3b257e2da48 100644 --- a/ndb/src/mgmsrv/ConfigInfo.cpp +++ b/ndb/src/mgmsrv/ConfigInfo.cpp @@ -857,7 +857,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { false, ConfigInfo::CI_INT, "8", - "1", + "3", STR_VALUE(MAX_INT_RNIL) }, { From 78c814154a621c5d0992261afd0a84f68867a708 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 29 Jun 2006 13:01:54 +0200 Subject: [PATCH 26/26] fixed too small requestInfo in signal + adopted signal to be as close as possible to 5.1... --- ndb/include/kernel/signaldata/LqhFrag.hpp | 46 +++++++++++------------ 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/ndb/include/kernel/signaldata/LqhFrag.hpp b/ndb/include/kernel/signaldata/LqhFrag.hpp index 50b0caaba07..72c1537854c 100644 --- a/ndb/include/kernel/signaldata/LqhFrag.hpp +++ b/ndb/include/kernel/signaldata/LqhFrag.hpp @@ -104,7 +104,7 @@ class LqhFragReq { friend bool printLQH_FRAG_REQ(FILE *, const Uint32 *, Uint32, Uint16); public: - STATIC_CONST( SignalLength = 24 ); + STATIC_CONST( SignalLength = 23 ); enum RequestInfo { CreateInRunning = 0x8000000, @@ -115,33 +115,33 @@ private: Uint32 senderData; Uint32 senderRef; Uint32 fragmentId; - Uint8 requestInfo; - Uint8 unused1; + Uint32 requestInfo; + Uint32 maxLoadFactor; + Uint32 minLoadFactor; + Uint32 kValue; + Uint32 schemaVersion; + Uint32 nextLCP; + Uint16 noOfNewAttr; + Uint16 noOfCharsets; + Uint32 startGci; + Uint32 tableType; // DictTabInfo::TableType + Uint32 primaryTableId; // table of index or RNIL + Uint16 tableId; + Uint16 localKeyLength; + Uint16 lh3DistrBits; + Uint16 lh3PageBits; Uint16 noOfAttributes; - Uint32 tableId; - Uint32 localKeyLength; - Uint16 maxLoadFactor; - Uint16 minLoadFactor; - Uint16 kValue; - Uint8 tableType; // DictTabInfo::TableType - Uint8 GCPIndicator; - Uint32 lh3DistrBits; - Uint32 lh3PageBits; - Uint32 noOfNullAttributes; + Uint16 noOfNullAttributes; + Uint16 noOfPagesToPreAllocate; + Uint16 keyLength; + Uint16 noOfKeyAttr; + Uint8 checksumIndicator; + Uint8 GCPIndicator; + Uint32 noOfAttributeGroups; Uint32 maxRowsLow; Uint32 maxRowsHigh; Uint32 minRowsLow; Uint32 minRowsHigh; - Uint32 schemaVersion; - Uint32 keyLength; - Uint32 nextLCP; - Uint32 noOfKeyAttr; - Uint16 noOfNewAttr; - Uint16 noOfCharsets; - Uint32 checksumIndicator; - Uint32 noOfAttributeGroups; - Uint32 startGci; - Uint32 primaryTableId; // table of index or RNIL }; class LqhFragConf {