diff options
157 files changed, 7089 insertions, 960 deletions
diff --git a/BUILD/SETUP.sh.rej b/BUILD/SETUP.sh.rej deleted file mode 100644 index ccbcaa4404f..00000000000 --- a/BUILD/SETUP.sh.rej +++ /dev/null @@ -1,19 +0,0 @@ -*************** -*** 39,46 **** - c_warnings="$global_warnings -Wunused" - cxx_warnings="$global_warnings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor" - -! alpha_cflags="-mcpu=ev6 -Wa,-mev6" # Not used yet -! pentium_cflags="-mcpu=pentiumpro" - sparc_cflags="" - - # be as fast as we can be without losing our ability to backtrace ---- 39,46 ---- - c_warnings="$global_warnings -Wunused" - cxx_warnings="$global_warnings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor" - -! #alpha_cflags="-mcpu=ev6 -Wa,-mev6" # Not used yet -! #pentium_cflags="-mcpu=pentiumpro" - sparc_cflags="" - - # be as fast as we can be without losing our ability to backtrace diff --git a/config/ac-macros/misc.m4 b/config/ac-macros/misc.m4 index d8199f5970e..09081fb3eac 100644 --- a/config/ac-macros/misc.m4 +++ b/config/ac-macros/misc.m4 @@ -790,3 +790,27 @@ esac AC_SUBST(AR) AC_SUBST(ARFLAGS) ]) + +dnl +dnl Macro to check time_t range: according to C standard +dnl array index must be greater than 0 => if time_t is signed, +dnl the code in the macros below won't compile. +dnl + +AC_DEFUN([MYSQL_CHECK_TIME_T],[ + AC_MSG_CHECKING(if time_t is unsigned) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [[ +#include <time.h> + ]], + [[ + int array[(((time_t)-1) > 0) ? 1 : -1]; + ]] ) + ], [ + AC_DEFINE([TIME_T_UNSIGNED], 1, [Define to 1 if time_t is unsigned]) + AC_MSG_RESULT(yes) + ], + [AC_MSG_RESULT(no)] + ) +]) + diff --git a/config/ac-macros/zlib.m4 b/config/ac-macros/zlib.m4 index a01d13937ff..5defdfd6749 100644 --- a/config/ac-macros/zlib.m4 +++ b/config/ac-macros/zlib.m4 @@ -2,7 +2,7 @@ dnl Define zlib paths to point at bundled zlib AC_DEFUN([MYSQL_USE_BUNDLED_ZLIB], [ ZLIB_INCLUDES="-I\$(top_srcdir)/zlib" -ZLIB_LIBS="\$(top_builddir)/zlib/libz.la" +ZLIB_LIBS="\$(top_builddir)/zlib/libzlt.la" dnl Omit -L$pkglibdir as it's always in the list of mysql_config deps. ZLIB_DEPS="-lz" zlib_dir="zlib" @@ -10,16 +10,25 @@ AC_SUBST([zlib_dir]) mysql_cv_compress="yes" ]) -dnl Auxiliary macro to check for zlib at given path +dnl Auxiliary macro to check for zlib at given path. +dnl We are strict with the server, as "archive" engine +dnl needs zlibCompileFlags(), but for client only we +dnl are less strict, and take the zlib we find. AC_DEFUN([MYSQL_CHECK_ZLIB_DIR], [ save_CPPFLAGS="$CPPFLAGS" save_LIBS="$LIBS" CPPFLAGS="$ZLIB_INCLUDES $CPPFLAGS" LIBS="$LIBS $ZLIB_LIBS" +if test X"$with_server" = Xno +then + zlibsym=zlibVersion +else + zlibsym=zlibCompileFlags +fi AC_CACHE_VAL([mysql_cv_compress], [AC_TRY_LINK([#include <zlib.h>], - [return zlibCompileFlags();], + [return $zlibsym();], [mysql_cv_compress="yes" AC_MSG_RESULT([ok])], [mysql_cv_compress="no"]) diff --git a/configure.in b/configure.in index c508fdfc580..d42da033f3d 100644 --- a/configure.in +++ b/configure.in @@ -30,7 +30,7 @@ NDB_VERSION_STATUS="" # Remember that regexps needs to quote [ and ] since this is run through m4 MYSQL_NO_DASH_VERSION=`echo $VERSION | sed -e "s|[[a-z]]*-.*$||"` MYSQL_BASE_VERSION=`echo $MYSQL_NO_DASH_VERSION | sed -e "s|\.[[^.]]*$||"` -MYSQL_VERSION_ID=`echo $MYSQL_NO_DASH_VERSION. | sed -e 's/[[^0-9.]]//g; s/\./ /g; s/ \([[0-9]]\) / 0\\1 /g; s/ //g'` +MYSQL_VERSION_ID=`echo $MYSQL_NO_DASH_VERSION | sed -e 's|[[^0-9.]].*$||;s|$|.|' | sed -e 's/[[^0-9.]]//g; s/\./ /g; s/ \([[0-9]]\) / 0\\1 /g; s/ //g'` # The port should be constant for a LONG time MYSQL_TCP_PORT_DEFAULT=3306 @@ -1601,9 +1601,9 @@ fi # dlopen, dlerror case "$with_mysqld_ldflags " in - *"-static "*) + *"-all-static "*) # No need to check for dlopen when mysqld is linked with - # -all-static or -static as it won't be able to load any functions. + # -all-static as it won't be able to load any functions. # NOTE! It would be better if it was possible to test if dlopen # can be used, but a good way to test it couldn't be found diff --git a/include/my_global.h.rej b/include/my_global.h.rej deleted file mode 100644 index f2953d169e7..00000000000 --- a/include/my_global.h.rej +++ /dev/null @@ -1,17 +0,0 @@ -*************** -*** 97,103 **** - - - /* Fix problem with S_ISLNK() on Linux */ -! #if defined(HAVE_LINUXTHREADS) - #undef _GNU_SOURCE - #define _GNU_SOURCE 1 - #endif ---- 97,103 ---- - - - /* Fix problem with S_ISLNK() on Linux */ -! #if defined(TARGET_OS_LINUX) || defined(__GLIBC__) - #undef _GNU_SOURCE - #define _GNU_SOURCE 1 - #endif diff --git a/include/my_pthread.h.rej b/include/my_pthread.h.rej deleted file mode 100644 index 1f73655b0bd..00000000000 --- a/include/my_pthread.h.rej +++ /dev/null @@ -1,80 +0,0 @@ -*************** -*** 286,293 **** - #undef HAVE_PTHREAD_RWLOCK_RDLOCK - #undef HAVE_SNPRINTF - -! #define sigset(A,B) pthread_signal((A),(void (*)(int)) (B)) -! #define signal(A,B) pthread_signal((A),(void (*)(int)) (B)) - #define my_pthread_attr_setprio(A,B) - #endif /* defined(PTHREAD_SCOPE_GLOBAL) && !defined(PTHREAD_SCOPE_SYSTEM) */ - ---- 294,301 ---- - #undef HAVE_PTHREAD_RWLOCK_RDLOCK - #undef HAVE_SNPRINTF - -! #define my_sigset(A,B) pthread_signal((A),(void (*)(int)) (B)) -! #define my_signal(A,B) pthread_signal((A),(void (*)(int)) (B)) - #define my_pthread_attr_setprio(A,B) - #endif /* defined(PTHREAD_SCOPE_GLOBAL) && !defined(PTHREAD_SCOPE_SYSTEM) */ - -*************** -*** 324,337 **** - #if !defined(HAVE_SIGWAIT) && !defined(HAVE_mit_thread) && !defined(HAVE_rts_threads) && !defined(sigwait) && !defined(alpha_linux_port) && !defined(HAVE_NONPOSIX_SIGWAIT) && !defined(HAVE_DEC_3_2_THREADS) && !defined(_AIX) - int sigwait(sigset_t *setp, int *sigp); /* Use our implemention */ - #endif -! #if !defined(HAVE_SIGSET) && !defined(HAVE_mit_thread) && !defined(sigset) -! #define sigset(A,B) do { struct sigaction s; sigset_t set; \ -! sigemptyset(&set); \ -! s.sa_handler = (B); \ -! s.sa_mask = set; \ -! s.sa_flags = 0; \ -! sigaction((A), &s, (struct sigaction *) NULL); \ - } while (0) - #endif - - #ifndef my_pthread_setprio ---- 332,358 ---- - #if !defined(HAVE_SIGWAIT) && !defined(HAVE_mit_thread) && !defined(HAVE_rts_threads) && !defined(sigwait) && !defined(alpha_linux_port) && !defined(HAVE_NONPOSIX_SIGWAIT) && !defined(HAVE_DEC_3_2_THREADS) && !defined(_AIX) - int sigwait(sigset_t *setp, int *sigp); /* Use our implemention */ - #endif -! -! /* -! We define my_sigset() and use that instead of the system sigset() so that -! we can favor an implementation based on sigaction(). On some systems, such -! as Mac OS X, sigset() results in flags such as SA_RESTART being set, and -! we want to make sure that no such flags are set. -! */ -! #if defined(HAVE_SIGACTION) && !defined(my_sigset) -! #define my_sigset(A,B) do { struct sigaction s; sigset_t set; int rc; \ -! DBUG_ASSERT((A) != 0); \ -! sigemptyset(&set); \ -! s.sa_handler = (B); \ -! s.sa_mask = set; \ -! s.sa_flags = 0; \ -! rc= sigaction((A), &s, (struct sigaction *) NULL); \ -! DBUG_ASSERT(rc == 0); \ - } while (0) -+ #elif defined(HAVE_SIGSET) && !defined(my_sigset) -+ #define my_sigset(A,B) sigset((A),(B)) -+ #elif !defined(my_sigset) -+ #define my_sigset(A,B) signal((A),(B)) - #endif - - #ifndef my_pthread_setprio -*************** -*** 416,422 **** - #undef pthread_detach_this_thread - #define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(tmp); } - #undef sigset -! #define sigset(A,B) pthread_signal((A),(void (*)(int)) (B)) - #endif - - #if ((defined(HAVE_PTHREAD_ATTR_CREATE) && !defined(HAVE_SIGWAIT)) || defined(HAVE_DEC_3_2_THREADS)) && !defined(HAVE_CTHREADS_WRAPPER) ---- 437,443 ---- - #undef pthread_detach_this_thread - #define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(tmp); } - #undef sigset -! #define my_sigset(A,B) pthread_signal((A),(void (*)(int)) (B)) - #endif - - #if ((defined(HAVE_PTHREAD_ATTR_CREATE) && !defined(HAVE_SIGWAIT)) || defined(HAVE_DEC_3_2_THREADS)) && !defined(HAVE_CTHREADS_WRAPPER) diff --git a/mysql-test/r/distinct.result b/mysql-test/r/distinct.result index 3508a83a810..190e8595126 100644 --- a/mysql-test/r/distinct.result +++ b/mysql-test/r/distinct.result @@ -668,3 +668,17 @@ NULL 3 4 DROP TABLE t1; +CREATE TABLE t1 (a INT, b INT); +INSERT INTO t1 VALUES(1,1),(1,2),(1,3); +SELECT DISTINCT a, b FROM t1; +a b +1 1 +1 2 +1 3 +SELECT DISTINCT a, a, b FROM t1; +a a b +1 1 1 +1 1 2 +1 1 3 +DROP TABLE t1; +End of 5.0 tests diff --git a/mysql-test/r/ndb_restore.result b/mysql-test/r/ndb_restore.result index e5bf4315e5c..bc31798cee7 100644 --- a/mysql-test/r/ndb_restore.result +++ b/mysql-test/r/ndb_restore.result @@ -1,14 +1,14 @@ use test; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9,t10; drop table if exists t1_c,t2_c,t3_c,t4_c,t5_c,t6_c,t7_c,t8_c,t9_c,t10_c; -CREATE TABLE `t1` ( -`capgoaledatta` smallint(5) unsigned NOT NULL auto_increment, +CREATE TABLE `t1_c` ( +`capgoaledatta` mediumint(5) unsigned NOT NULL auto_increment, `goaledatta` char(2) NOT NULL default '', `maturegarbagefa` varchar(32) NOT NULL default '', PRIMARY KEY (`capgoaledatta`,`goaledatta`,`maturegarbagefa`) -) ENGINE=myisam DEFAULT CHARSET=latin1; -INSERT INTO `t1` VALUES (2,'3','q3plus.qt'),(4,'4','q3plus.qt'),(1,'3','q3.net'),(3,'4','q3.net'),(3,'20','threetrees.qt'); -CREATE TABLE `t2` ( +) ENGINE=ndbcluster DEFAULT CHARSET=latin1; +INSERT INTO `t1_c` VALUES (2,'3','q3plus.qt'),(400,'4','q3plus.qt'),(1,'3','q3.net'),(3,'4','q3.net'),(3000,'20','threetrees.qt'); +CREATE TABLE `t2_c` ( `capgotod` smallint(5) unsigned NOT NULL auto_increment, `gotod` smallint(5) unsigned NOT NULL default '0', `goaledatta` char(2) default NULL, @@ -16,16 +16,16 @@ CREATE TABLE `t2` ( `descrpooppo` varchar(64) default NULL, `svcutonsa` varchar(64) NOT NULL default '', PRIMARY KEY (`capgotod`), -KEY `i_quadaddsvr` (`gotod`) -) ENGINE=myisam DEFAULT CHARSET=latin1; -INSERT INTO `t2` VALUES (5,4,'','q3.net','addavp:MK_CASELECTOR=1','postorod rattoaa'),(2,1,'4','','addavp:MK_BRANDTAD=345','REDS Brandtad'),(3,2,'4','q3.net','execorder','fixedRatediPO REDS'),(1,1,'3','','addavp:MK_BRANDTAD=123','TEST Brandtad'),(6,5,'','told.q3.net','addavp:MK_BRANDTAD=123','Brandtad Toldzone'),(4,3,'3','q3.net','addavp:MK_POOLHINT=2','ratedi PO TEST'); -CREATE TABLE `t3` ( +KEY `i quadaddsvr` (`gotod`) +) ENGINE=ndbcluster DEFAULT CHARSET=latin1; +INSERT INTO `t2_c` VALUES (500,4,'','q3.net','addavp:MK_CASELECTOR=1','postorod rattoaa'),(2,1,'4','','addavp:MK_BRANDTAD=345','REDS Brandtad'),(3,2,'4','q3.net','execorder','fixedRatediPO REDS'),(1,1,'3','','addavp:MK_BRANDTAD=123','TEST Brandtad'),(6,5,'','told.q3.net','addavp:MK_BRANDTAD=123','Brandtad Toldzone'),(4,3,'3','q3.net','addavp:MK_POOLHINT=2','ratedi PO TEST'); +CREATE TABLE `t3_c` ( `CapGoaledatta` smallint(5) unsigned NOT NULL default '0', `capgotod` smallint(5) unsigned NOT NULL default '0', PRIMARY KEY (`capgotod`,`CapGoaledatta`) -) ENGINE=myisam DEFAULT CHARSET=latin1; -INSERT INTO `t3` VALUES (5,3),(2,4),(5,4),(1,3); -CREATE TABLE `t4` ( +) ENGINE=ndbcluster DEFAULT CHARSET=latin1; +INSERT INTO `t3_c` VALUES (5,3),(2,4),(5,4),(1,3); +CREATE TABLE `t4_c` ( `capfa` bigint(20) unsigned NOT NULL auto_increment, `realm` varchar(32) NOT NULL default '', `authpwchap` varchar(32) default NULL, @@ -35,34 +35,34 @@ CREATE TABLE `t4` ( PRIMARY KEY (`fa`,`realm`), KEY `capfa` (`capfa`), KEY `i_quadentity` (`fa`,`realm`) -) ENGINE=myisam DEFAULT CHARSET=latin1; -INSERT INTO `t4` VALUES (18,'john.smith','q3.net','dessjohn.smith',0,NULL),(21,'quad_katt_with_brandtad','q3.net','acne',0,NULL),(22,'quad_katt_carattoaa','q3.net','acne',0,NULL),(26,'436462612809','sqasdt.q3.net','N/A',0,'6'),(19,'john','smith.qt','dessjohn',0,NULL),(33,'436643196120','sqasdt.q3.net','N/A',1,'6'),(28,'436642900019','sqasdt.q3.net','N/A',0,'6'),(30,'436462900209','sqasdt.q3.net','N/A',0,'6'),(16,'436640006666','sqasdt.q3.net','',0,NULL),(19,'dette','el-redun.com','dessdette',0,NULL),(12,'quad_kattPP','q3.net','acne',2,NULL),(14,'436640008888','sqasdt.q3.net','',0,NULL),(29,'463624900028','sqasdt.q3.net','N/A',0,'6'),(15,'436640099099','sqasdt.q3.net','',0,NULL),(13,'pap','q3plus.qt','acne',1,NULL),(19,'436642612091','sqasdt.q3.net','N/A',0,'6'),(12,'quad_katt','q3.net','acne',0,NULL),(11,'quad_kattVK','q3.net','acne',1,NULL),(32,'463641969502','sqasdt.q3.net','N/A',1,'6'),(20,'joe','q3.net','joedesswd',0,NULL),(29,'436642900034','sqasdt.q3.net','N/A',0,'6'),(25,'contind','armerde.qt','acne',1,NULL); -CREATE TABLE `t5` ( +) ENGINE=ndbcluster DEFAULT CHARSET=latin1; +INSERT INTO `t4_c` VALUES (18,'john.smith','q3.net','dessjohn.smith',0,NULL),(21,'quad_katt_with_brandtad','q3.net','acne',0,NULL),(2200,'quad_katt_carattoaa','q3.net','acne',0,NULL),(26,'436462612809','sqasdt.q3.net','N/A',0,'6'),(19,'john','smith.qt','dessjohn',0,NULL),(33,'436643196120','sqasdt.q3.net','N/A',1,'6'),(28,'436642900019','sqasdt.q3.net','N/A',0,'6'),(30,'436462900209','sqasdt.q3.net','N/A',0,'6'),(16,'436640006666','sqasdt.q3.net','',0,NULL),(19,'dette','el-redun.com','dessdette',0,NULL),(12,'quad_kattPP','q3.net','acne',2,NULL),(14,'436640008888','sqasdt.q3.net','',0,NULL),(29,'463624900028','sqasdt.q3.net','N/A',0,'6'),(15,'436640099099','sqasdt.q3.net','',0,NULL),(13,'pap','q3plus.qt','acne',1,NULL),(19,'436642612091','sqasdt.q3.net','N/A',0,'6'),(12,'quad_katt','q3.net','acne',0,NULL),(11,'quad_kattVK','q3.net','acne',1,NULL),(32000,'463641969502','sqasdt.q3.net','N/A',1,'6'),(20,'joe','q3.net','joedesswd',0,NULL),(290000000,'436642900034','sqasdt.q3.net','N/A',0,'6'),(25,'contind','armerde.qt','acne',1,NULL); +CREATE TABLE `t5_c` ( `capfa` bigint(20) unsigned NOT NULL default '0', `gotod` smallint(5) unsigned NOT NULL default '0', `orderutonsa` varchar(64) NOT NULL default '', PRIMARY KEY (`capfa`,`gotod`,`orderutonsa`) -) ENGINE=myisam DEFAULT CHARSET=latin1; -INSERT INTO `t5` VALUES (21,2,''),(21,1,''),(22,4,''); -CREATE TABLE `t6` ( +) ENGINE=ndbcluster DEFAULT CHARSET=latin1; +INSERT INTO `t5_c` VALUES (21,2,''),(21,1,''),(22,4,''); +CREATE TABLE `t6_c` ( `capfa_parent` bigint(20) unsigned NOT NULL default '0', `capfa_child` bigint(20) unsigned NOT NULL default '0', `relatta` smallint(5) unsigned NOT NULL default '0', PRIMARY KEY (`capfa_child`,`capfa_parent`,`relatta`) -) ENGINE=myisam DEFAULT CHARSET=latin1; -INSERT INTO `t6` VALUES (15,16,0),(19,20,0),(18326932092909551615,30,0),(26,29,0),(18326932092909551615,29,0),(19,18,0),(26,28,0),(12,14,0); -CREATE TABLE `t7` ( +) ENGINE=ndbcluster DEFAULT CHARSET=latin1; +INSERT INTO `t6_c` VALUES (15,16,0),(19,20,0),(18326932092909551615,30,0),(26,29,0),(18326932092909551615,29,0),(19,18,0),(26,28,0),(12,14,0); +CREATE TABLE `t7_c` ( `dardpo` char(15) NOT NULL default '', -`dardtestard` tinyint(3) unsigned NOT NULL default '0', +`dardtestard` tinyint(3) unsigned NOT NULL auto_increment, `FastFA` char(5) NOT NULL default '', `FastCode` char(6) NOT NULL default '', `Fastca` char(1) NOT NULL default '', `Fastmag` char(1) NOT NULL default '', `Beareratta` char(2) NOT NULL default '', PRIMARY KEY (`dardpo`,`dardtestard`) -) ENGINE=myisam DEFAULT CHARSET=latin1; -INSERT INTO `t7` VALUES ('2.6.2.4',24,'CECHP','54545','0','0','5'),('2.2.5.4',26,'CANFA','33223','1','1','4'),('4.3.2.4',28,'ITALD','54222','1','0','5'),('129..0.0.eins',28,'G','99999','1','1','5'),('1.1.1.1',24,'AUTPT','32323','0','1','3'); -CREATE TABLE `t8` ( +) ENGINE=ndbcluster DEFAULT CHARSET=latin1; +INSERT INTO `t7_c` VALUES ('2.6.2.4',24,'CECHP','54545','0','0','5'),('2.2.5.4',26,'CANFA','33223','1','1','4'),('4.3.2.4',28,'ITALD','54222','1','0','5'),('129..0.0.eins',28,'G','99999','1','1','5'),('1.1.1.1',24,'AUTPT','32323','0','1','3'); +CREATE TABLE `t8_c` ( `kattjame` varchar(32) NOT NULL default '', `realm` varchar(32) NOT NULL default '', `realm_entered` varchar(32) NOT NULL default '', @@ -88,9 +88,9 @@ CREATE TABLE `t8` ( `acctinputoctets` bigint(20) unsigned default NULL, PRIMARY KEY (`kattjame`,`hunderaaarbagefa`,`hassetistart`,`hassetino`), KEY `squardporoot` (`squardporoot`) -) ENGINE=myisam DEFAULT CHARSET=latin1; -INSERT INTO `t8` VALUES ('4tt45345235','pap','q3plus.qt','q3plus.qt','q3.net','436643196120','436643196929','8956234534568968','5524595699','uxasmt21.net.acne.qt/481889229462692422','','1.1.1.1','2.2.4.6','4','86989','34','x','x','2012-03-12 12:55:34','2012-12-05 11:20:04',3223433,3369,9565),('4545435545','john','q3.net','q3.net','acne.li','436643196120','436643196929','45345234568968','995696699','uxasmt21.net.acne.qt/481889229462692423','','1.1.1.1','2.2.9.8','2','86989','34','x','x','2012-03-12 11:35:03','2012-12-05 08:50:04',8821923,169,3565),('versteckter_q3net_katt','joe','q3.net','elredun.com','q3.net','436643196120','436643196939','91341234568968','695595699','uxasmt21.net.acne.qt/481889229462692421','','1.1.1.1','2.5.2.5','3','86989','34','x','x','2012-03-12 18:35:04','2012-12-05 12:35:04',1923123,9569,6565); -CREATE TABLE `t9` ( +) ENGINE=ndbcluster DEFAULT CHARSET=latin1; +INSERT INTO `t8_c` VALUES ('4tt45345235','pap','q3plus.qt','q3plus.qt','q3.net','436643196120','436643196929','8956234534568968','5524595699','uxasmt21.net.acne.qt/481889229462692422','','1.1.1.1','2.2.4.6','4','86989','34','x','x','2012-03-12 12:55:34','2012-12-05 11:20:04',3223433,3369,9565),('4545435545','john','q3.net','q3.net','acne.li','436643196120','436643196929','45345234568968','995696699','uxasmt21.net.acne.qt/481889229462692423','','1.1.1.1','2.2.9.8','2','86989','34','x','x','2012-03-12 11:35:03','2012-12-05 08:50:04',8821923,169,3565),('versteckter_q3net_katt','joe','q3.net','elredun.com','q3.net','436643196120','436643196939','91341234568968','695595699','uxasmt21.net.acne.qt/481889229462692421','','1.1.1.1','2.5.2.5','3','86989','34','x','x','2012-03-12 18:35:04','2012-12-05 12:35:04',1923123,9569,6565); +CREATE TABLE `t9_c` ( `kattjame` varchar(32) NOT NULL default '', `kattjame_entered` varchar(32) NOT NULL default '', `realm` varchar(32) NOT NULL default '', @@ -114,20 +114,21 @@ CREATE TABLE `t9` ( `actinputocctets` bigint(20) unsigned default NULL, `terminateraste` tinyint(3) unsigned default NULL, PRIMARY KEY (`kattjame`,`hunderaaarbagefa`,`hassetistart`,`hassetino`) -) ENGINE=myisam DEFAULT CHARSET=latin1; -INSERT INTO `t9` VALUES ('3g4jh8gar2t','joe','q3.net','elredun.com','q3.net','436643316120','436643316939','91341234568968','695595699','1.1.1.1','2.2.6.2','3','86989','34','x','x','2012-03-12 18:35:04','2012-12-05 12:35:04',3123123,9569,6565,1),('4tt45345235','pap','q3plus.qt','q3plus.qt','q3.net','436643316120','436643316939','8956234534568968','5254595969','1.1.1.1','8.6.2.2','4','86989','34','x','x','2012-03-12 12:55:34','2012-12-05 11:20:04',3223433,3369,9565,2),('4545435545','john','q3.net','q3.net','acne.li','436643316120','436643316939','45345234568968','995696699','1.1.1.1','2.9.9.2','2','86998','34','x','x','2012-03-12 11:35:03','2012-12-05 08:50:04',8823123,169,3565,3); -create table t10 (a int auto_increment key); -insert into t10 values (1),(2),(3); -create table t1_c engine=ndbcluster as select * from t1; -create table t2_c engine=ndbcluster as select * from t2; -create table t3_c engine=ndbcluster as select * from t3; -create table t4_c engine=ndbcluster as select * from t4; -create table t5_c engine=ndbcluster as select * from t5; -create table t6_c engine=ndbcluster as select * from t6; -create table t7_c engine=ndbcluster as select * from t7; -create table t8_c engine=ndbcluster as select * from t8; -create table t9_c engine=ndbcluster as select * from t9; -create table t10_c engine=ndbcluster as select * from t10; +) ENGINE=ndbcluster DEFAULT CHARSET=latin1; +INSERT INTO `t9_c` VALUES ('3g4jh8gar2t','joe','q3.net','elredun.com','q3.net','436643316120','436643316939','91341234568968','695595699','1.1.1.1','2.2.6.2','3','86989','34','x','x','2012-03-12 18:35:04','2012-12-05 12:35:04',3123123,9569,6565,1),('4tt45345235','pap','q3plus.qt','q3plus.qt','q3.net','436643316120','436643316939','8956234534568968','5254595969','1.1.1.1','8.6.2.2','4','86989','34','x','x','2012-03-12 12:55:34','2012-12-05 11:20:04',3223433,3369,9565,2),('4545435545','john','q3.net','q3.net','acne.li','436643316120','436643316939','45345234568968','995696699','1.1.1.1','2.9.9.2','2','86998','34','x','x','2012-03-12 11:35:03','2012-12-05 08:50:04',8823123,169,3565,3); +create table t10_c (a int auto_increment key) ENGINE=ndbcluster; +insert into t10_c values (1),(2),(3); +insert into t10_c values (10000),(2000),(3000); +create table t1 engine=myisam as select * from t1_c; +create table t2 engine=myisam as select * from t2_c; +create table t3 engine=myisam as select * from t3_c; +create table t4 engine=myisam as select * from t4_c; +create table t5 engine=myisam as select * from t5_c; +create table t6 engine=myisam as select * from t6_c; +create table t7 engine=myisam as select * from t7_c; +create table t8 engine=myisam as select * from t8_c; +create table t9 engine=myisam as select * from t9_c; +create table t10 engine=myisam as select * from t10_c; drop table t1_c,t2_c,t3_c,t4_c,t5_c,t6_c,t7_c,t8_c,t9_c, t10_c; show tables; Tables_in_test @@ -255,6 +256,24 @@ a 1 2 3 +2000 +3000 +10000 +show table status like 't1_c'; +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment +X X X X X X X X X X 3001 X X X X X X X +show table status like 't2_c'; +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment +X X X X X X X X X X 501 X X X X X X X +show table status like 't4_c'; +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment +X X X X X X X X X X 290000001 X X X X X X X +show table status like 't7_c'; +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment +X X X X X X X X X X 29 X X X X X X X +show table status like 't10_c'; +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment +X X X X X X X X X X 10001 X X X X X X X drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9, t10; drop table if exists t1_c,t2_c,t3_c,t4_c,t5_c,t6_c,t7_c,t8_c,t9_c, t10_c; 520093696,1 diff --git a/mysql-test/r/ndb_single_user.result b/mysql-test/r/ndb_single_user.result index 7959d8478e1..4606a47dde2 100644 --- a/mysql-test/r/ndb_single_user.result +++ b/mysql-test/r/ndb_single_user.result @@ -25,11 +25,12 @@ update t1 set b=b+100; update t1 set b=b+100 where a > 7; delete from t1; insert into t1 select * from t2; +create unique index new_index on t1 (b,c); drop table t1; ERROR 42S02: Unknown table 't1' -create index new_index on t1 (c); +create index new_index_fail on t1 (c); ERROR HY000: Got error 299 'Operation not allowed or aborted due to single user mode' from ndbcluster -insert into t1 values (1,1,0),(2,2,0),(3,3,0),(4,4,0),(5,5,0),(6,6,0),(7,7,0),(8,8,0),(9,9,0),(10,10,0); +insert into t1 values (21,21,0),(22,22,0),(23,23,0),(24,24,0),(25,25,0),(26,26,0),(27,27,0),(28,28,0),(29,29,0),(210,210,0); ERROR HY000: Got error 299 'Operation not allowed or aborted due to single user mode' from ndbcluster select * from t1 where a = 1; ERROR HY000: Got error 299 'Operation not allowed or aborted due to single user mode' from ndbcluster diff --git a/mysql-test/r/row.result b/mysql-test/r/row.result index faf9b11d7c9..bb9e2109f0f 100644 --- a/mysql-test/r/row.result +++ b/mysql-test/r/row.result @@ -175,6 +175,24 @@ ROW(2,10) <=> ROW(3,4) SELECT ROW(NULL,10) <=> ROW(3,NULL); ROW(NULL,10) <=> ROW(3,NULL) 0 +SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),ROW(1,1)); +ERROR 21000: Operand should contain 2 column(s) +SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),ROW(1,1),ROW(1,ROW(2,3))); +ERROR 21000: Operand should contain 2 column(s) +SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),ROW(1,ROW(2,2,2))); +ERROR 21000: Operand should contain 2 column(s) +SELECT ROW(1,ROW(2,3,4)) IN (ROW(1,ROW(2,3,4)),ROW(1,ROW(2,2))); +ERROR 21000: Operand should contain 3 column(s) +SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),(SELECT 1,1)); +ERROR 21000: Operand should contain 2 column(s) +SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),(SELECT 1,1),ROW(1,ROW(2,4))); +ERROR 21000: Operand should contain 2 column(s) +SELECT ROW(1,ROW(2,3)) IN ((SELECT 1,1),ROW(1,ROW(2,3))); +ERROR 21000: Operand should contain 2 column(s) +SELECT ROW(2,1) IN (ROW(21,2),ROW(ROW(1,1,3),0)); +ERROR 21000: Operand should contain 1 column(s) +SELECT ROW(2,1) IN (ROW(ROW(1,1,3),0),ROW(21,2)); +ERROR 21000: Operand should contain 1 column(s) SELECT ROW(1,1,1) = ROW(1,1,1) as `1`, ROW(1,1,1) = ROW(1,2,1) as `0`, ROW(1,NULL,1) = ROW(2,2,1) as `0`, ROW(1,NULL,1) = ROW(1,2,2) as `0`, ROW(1,NULL,1) = ROW(1,2,1) as `null` ; 1 0 0 0 null 1 0 0 0 NULL diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index b501d547e0a..bfe0b9d19df 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -3986,4 +3986,13 @@ t2.access_id IN (1,4) AND t.access_id IS NULL AND t2.faq_id in (265); faq_id 265 DROP TABLE t1,t2; +CREATE TABLE t1 (a INT, b INT, KEY inx (b,a)); +INSERT INTO t1 VALUES (1,1), (1,2), (1,3), (1,4), (1,5), (1, 6), (1,7); +EXPLAIN SELECT COUNT(*) FROM t1 f1 INNER JOIN t1 f2 +ON ( f1.b=f2.b AND f1.a<f2.a ) +WHERE 1 AND f1.b NOT IN (100,2232,3343,51111); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE f1 index inx inx 10 NULL 7 Using where; Using index +1 SIMPLE f2 ref inx inx 5 test.f1.b 1 Using where; Using index +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result index 636a00a4343..f9d84df5d9f 100644 --- a/mysql-test/r/strict.result +++ b/mysql-test/r/strict.result @@ -1386,4 +1386,9 @@ ERROR 01000: Data truncated for column 'a' at row 1 insert into t1 values ('2E3x'); ERROR 01000: Data truncated for column 'a' at row 1 drop table t1; +set sql_mode='traditional'; +create table t1 (f1 set('a','a')); +ERROR HY000: Column 'f1' has duplicated value 'a' in SET +create table t1 (f1 enum('a','a')); +ERROR HY000: Column 'f1' has duplicated value 'a' in ENUM End of 5.0 tests diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index d5a1c0b2451..94075df57b4 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -48,7 +48,7 @@ id select_type table type possible_keys key key_len ref rows Extra 3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used 2 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1276 Field or reference 'a' of SELECT #3 was resolved in SELECT #1 +Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1 Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1 Note 1003 select 1 AS `1` from (select 1 AS `a`) `b` having ((select '1' AS `a`) = 1) SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1; @@ -330,7 +330,7 @@ patient_uq clinic_uq explain extended select * from t6 where exists (select * from t7 where uq = clinic_uq); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t6 ALL NULL NULL NULL NULL 4 Using where -2 DEPENDENT SUBQUERY t7 eq_ref PRIMARY PRIMARY 4 t6.clinic_uq 1 Using where; Using index +2 DEPENDENT SUBQUERY t7 eq_ref PRIMARY PRIMARY 4 test.t6.clinic_uq 1 Using index Warnings: Note 1276 Field or reference 'test.t6.clinic_uq' of SELECT #2 was resolved in SELECT #1 Note 1003 select `test`.`t6`.`patient_uq` AS `patient_uq`,`test`.`t6`.`clinic_uq` AS `clinic_uq` from `test`.`t6` where exists(select 1 AS `Not_used` from `test`.`t7` where (`test`.`t7`.`uq` = `test`.`t6`.`clinic_uq`)) @@ -1741,7 +1741,7 @@ Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`text` AS `text` from `tes explain extended select * from t1 as tt where not exists (select id from t1 where id < 8 and (id = tt.id or id is null) having id is not null); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY tt ALL NULL NULL NULL NULL 12 Using where -2 DEPENDENT SUBQUERY t1 eq_ref PRIMARY PRIMARY 4 tt.id 1 Using where; Using index +2 DEPENDENT SUBQUERY t1 eq_ref PRIMARY PRIMARY 4 test.tt.id 1 Using where; Using index Warnings: Note 1276 Field or reference 'test.tt.id' of SELECT #2 was resolved in SELECT #1 Note 1003 select `test`.`tt`.`id` AS `id`,`test`.`tt`.`text` AS `text` from `test`.`t1` `tt` where (not(exists(select `test`.`t1`.`id` AS `id` from `test`.`t1` where ((`test`.`t1`.`id` < 8) and (`test`.`t1`.`id` = `test`.`tt`.`id`)) having (`test`.`t1`.`id` is not null)))) @@ -3924,6 +3924,71 @@ c a (SELECT GROUP_CONCAT(COUNT(a)+1) FROM t2 WHERE m = a) 3 3 4 1 4 2,2 DROP table t1,t2; +CREATE TABLE t1 (a int, b INT, d INT, c CHAR(10) NOT NULL, PRIMARY KEY (a, b)); +INSERT INTO t1 VALUES (1,1,0,'a'), (1,2,0,'b'), (1,3,0,'c'), (1,4,0,'d'), +(1,5,0,'e'), (2,1,0,'f'), (2,2,0,'g'), (2,3,0,'h'), (3,4,0,'i'), (3,3,0,'j'), +(3,2,0,'k'), (3,1,0,'l'), (1,9,0,'m'), (1,0,10,'n'), (2,0,5,'o'), (3,0,7,'p'); +SELECT a, MAX(b), +(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b + 0)) as test +FROM t1 GROUP BY a; +a MAX(b) test +1 9 m +2 3 h +3 4 i +SELECT a x, MAX(b), +(SELECT t.c FROM t1 AS t WHERE x=t.a AND t.b=MAX(t1.b + 0)) as test +FROM t1 GROUP BY a; +x MAX(b) test +1 9 m +2 3 h +3 4 i +SELECT a, AVG(b), +(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=AVG(t1.b)) AS test +FROM t1 WHERE t1.d=0 GROUP BY a; +a AVG(b) test +1 4.0000 d +2 2.0000 g +3 2.5000 NULL +SELECT tt.a, +(SELECT (SELECT c FROM t1 as t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a) +LIMIT 1) FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test +FROM t1 as tt; +a test +1 n +1 n +1 n +1 n +1 n +1 n +1 n +2 o +2 o +2 o +2 o +3 p +3 p +3 p +3 p +3 p +SELECT tt.a, +(SELECT (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a) +LIMIT 1) +FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test +FROM t1 as tt GROUP BY tt.a; +a test +1 n +2 o +3 p +SELECT tt.a, MAX( +(SELECT (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a) +LIMIT 1) +FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1)) as test +FROM t1 as tt GROUP BY tt.a; +a test +1 n +2 o +3 p +DROP TABLE t1; CREATE TABLE t1 (a int, b int); INSERT INTO t1 VALUES (2,22),(1,11),(2,22); SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 0 GROUP BY a; diff --git a/mysql-test/r/subselect3.result b/mysql-test/r/subselect3.result index 96a3ee00a59..33e7fc54ed2 100644 --- a/mysql-test/r/subselect3.result +++ b/mysql-test/r/subselect3.result @@ -432,7 +432,7 @@ alter table t1 add index idx(oref,ie); explain select oref, a, a in (select ie from t1 where oref=t2.oref) Z from t2; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 7 -2 DEPENDENT SUBQUERY t1 ref_or_null idx idx 10 t2.oref,func 4 Using where; Using index; Full scan on NULL key +2 DEPENDENT SUBQUERY t1 ref_or_null idx idx 10 test.t2.oref,func 4 Using where; Using index; Full scan on NULL key select oref, a, a in (select ie from t1 where oref=t2.oref) Z from t2; oref a Z ee NULL NULL @@ -457,7 +457,7 @@ group by grp having min(ie) > 1) Z from t2; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 7 -2 DEPENDENT SUBQUERY t1 ref idx idx 5 t2.oref 2 Using where; Using temporary; Using filesort +2 DEPENDENT SUBQUERY t1 ref idx idx 5 test.t2.oref 2 Using where; Using temporary; Using filesort select oref, a, a in (select min(ie) from t1 where oref=t2.oref group by grp having min(ie) > 1) Z diff --git a/mysql-test/r/truncate.result b/mysql-test/r/truncate.result index 74a6cb72cc6..6c21db0e2b8 100644 --- a/mysql-test/r/truncate.result +++ b/mysql-test/r/truncate.result @@ -53,3 +53,30 @@ a 3 4 drop table t1; +create table t1 (s1 int); +insert into t1 (s1) values (1), (2), (3), (4), (5); +create view v1 as select * from t1; +truncate table v1; +select count(*) from t1; +count(*) +0 +insert into t1 (s1) values (1), (2), (3), (4), (5); +create view v2 as select * from t1 where s1 > 3; +truncate table v2; +select * from t1; +s1 +1 +2 +3 +select * from v2; +s1 +delete from t1; +create table t2 (s1 int, s2 int); +create view v3 as select a.s1, b.s2 from t1 a join t2 b on a.s1 = b.s1 where a.s1 > 3; +truncate table v3; +ERROR HY000: Can not delete from join view 'test.v3' +create view v4 as select * from t1 limit 1,1; +truncate table v4; +ERROR HY000: The target table v4 of the TRUNCATE is not updatable +drop view v1, v2, v3, v4; +drop table t1, t2; diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index dc87f97b322..71d743f37b9 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -2395,6 +2395,16 @@ Table Op Msg_type Msg_text test.v1 optimize error 'test.v1' is not BASE TABLE Warnings: Error 1347 'test.v1' is not BASE TABLE +ANALYZE TABLE v1; +Table Op Msg_type Msg_text +test.v1 analyze error 'test.v1' is not BASE TABLE +Warnings: +Error 1347 'test.v1' is not BASE TABLE +REPAIR TABLE v1; +Table Op Msg_type Msg_text +test.v1 repair error 'test.v1' is not BASE TABLE +Warnings: +Error 1347 'test.v1' is not BASE TABLE DROP VIEW v1; create definer = current_user() sql security invoker view v1 as select 1; show create view v1; diff --git a/mysql-test/suite/row_lock/include/row_lock.inc b/mysql-test/suite/row_lock/include/row_lock.inc new file mode 100644 index 00000000000..8572bc0246e --- /dev/null +++ b/mysql-test/suite/row_lock/include/row_lock.inc @@ -0,0 +1,83 @@ +--disable_warnings +DROP TABLE IF EXISTS t1, t2; +--enable_warnings +SET autocommit=0; +# Create additional connections used through test +CONNECT (root1, localhost, root,,); +SET autocommit=0; +--echo connection default; +CONNECTION default; +eval CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=$engine; +INSERT INTO t1 VALUES (1,123,1,123); +INSERT INTO t1 VALUES (2,124,2,124); +INSERT INTO t1 VALUES (3,125,3,125); +INSERT INTO t1 VALUES (4,126,4,126); +eval $indext1; +eval CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=$engine; +INSERT INTO t2 VALUES (1,123,1,123); +INSERT INTO t2 VALUES (2,124,2,124); +INSERT INTO t2 VALUES (3,125,3,125); +INSERT INTO t2 VALUES (4,126,4,126); +eval $indext2; +COMMIT; +SELECT @@global.tx_isolation; + +# Both transaction are able to update the tables +eval EXPLAIN $select; +eval $select; + +--echo connection root1; +CONNECTION root1; +UPDATE t1,t2 SET t1.i=225,t2.i=225 WHERE t1.i=125 AND t2.i=t1.i; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; + +--echo connection default; +CONNECTION default; +UPDATE t1,t2 SET t1.i=223,t2.i=223 WHERE t1.i=123 AND t2.i=t1.i; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; + +--echo connection root1; +CONNECTION root1; +UPDATE t1,t2 SET t1.i=226,t2.i=226 WHERE t1.i=126 AND t2.i=t1.i; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; + +--echo connection default; +CONNECTION default; +UPDATE t1,t2 SET t1.i=224,t2.i=224 WHERE t1.i=124 AND t2.i=t1.i; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; + +--echo connection root1; +CONNECTION root1; +DELETE FROM t1 WHERE t1.i=226; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; + +--echo connection default; +CONNECTION default; +DELETE FROM t1 WHERE t1.i=224; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; +COMMIT; + +--echo connection root1; +CONNECTION root1; +ROLLBACK; + +--echo connection default; +CONNECTION default; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; + +--echo connection root1; +CONNECTION root1; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; +DISCONNECT root1; +--echo connection default; +CONNECTION default; +DROP TABLE t1, t2; + diff --git a/mysql-test/suite/row_lock/include/row_lock_big_tab.inc b/mysql-test/suite/row_lock/include/row_lock_big_tab.inc new file mode 100644 index 00000000000..f0823067eac --- /dev/null +++ b/mysql-test/suite/row_lock/include/row_lock_big_tab.inc @@ -0,0 +1,94 @@ +--disable_warnings +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1; +--enable_warnings +SET autocommit=0; +# Create additional connections used through test +CONNECT (root1, localhost, root,,); +SET autocommit=0; +--echo connection default; +CONNECTION default; +eval CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=$engine; +eval $indext1; +eval CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=$engine; +eval $indext2; +DELIMITER |; +CREATE PROCEDURE fill_t1 (IN upb int) +BEGIN +DECLARE cnt int DEFAULT 0; +WHILE cnt < upb DO + INSERT INTO t1 VALUES (cnt, cnt+100, cnt, cnt+100); + SET cnt= cnt+1; +END WHILE; +END; +| +CREATE FUNCTION half_t1() RETURNS int +BEGIN + DECLARE res int DEFAULT 0; + SELECT count(*)/2 INTO res FROM t1; + RETURN res; +END; +| +CREATE PROCEDURE fill_t2 (IN upb int) +BEGIN +DECLARE cnt int DEFAULT 0; +WHILE cnt < upb DO + INSERT INTO t2 VALUES (cnt, cnt+100, cnt, cnt+100); + SET cnt= cnt+1; +END WHILE; +END; +| +CREATE FUNCTION half_t2() RETURNS int +BEGIN + DECLARE res int DEFAULT 0; + SELECT count(*)/2 INTO res FROM t2; + RETURN res; +END; +| +DELIMITER ;| +CALL fill_t1 (10); +CALL fill_t2 (10); +COMMIT; +SELECT @@global.tx_isolation; +# With the two separate selects (without join) the differs from +# that select with join. + +# Both transaction are able to update the tables +eval EXPLAIN $select; +eval $select; + +--echo connection root1; +CONNECTION root1; +SELECT k from t1 WHERE k < half_t1(); +SELECT k from t1 WHERE k >= half_t1(); +UPDATE t1,t2 SET t1.i=1111,t2.i=2222 WHERE t1.k < half_t1() AND t2.i=t1.i; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; + +--echo connection default; +CONNECTION default; +UPDATE t1,t2 SET t1.i=3333,t2.i=4444 WHERE t1.k >= half_t1() AND t2.i=t1.i; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; +COMMIT; + +--echo connection root1; +CONNECTION root1; +ROLLBACK; + +--echo connection default; +CONNECTION default; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; + +--echo connection root1; +CONNECTION root1; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; +DISCONNECT root1; +--echo connection default; +CONNECTION default; +DROP VIEW IF EXISTS v1; +DROP TABLE t1, t2; +#DROP VIEW v1; + diff --git a/mysql-test/suite/row_lock/include/row_lock_big_tab_1.inc b/mysql-test/suite/row_lock/include/row_lock_big_tab_1.inc new file mode 100644 index 00000000000..8535c016819 --- /dev/null +++ b/mysql-test/suite/row_lock/include/row_lock_big_tab_1.inc @@ -0,0 +1,93 @@ +--disable_warnings +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1; +--enable_warnings +SET autocommit=0; +# Create additional connections used through test +CONNECT (root1, localhost, root,,); +SET autocommit=0; +--echo connection default; +CONNECTION default; +eval CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=$engine; +eval $indext1; +eval CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=$engine; +eval $indext2; +DELIMITER |; +CREATE PROCEDURE fill_t1 (IN upb int) +BEGIN +DECLARE cnt int DEFAULT 0; +WHILE cnt < upb DO + INSERT INTO t1 VALUES (cnt, cnt+100, cnt, cnt+100); + SET cnt= cnt+1; +END WHILE; +END; +| +CREATE FUNCTION half_t1() RETURNS int +BEGIN + DECLARE res int DEFAULT 0; + SELECT MOD(k,2) INTO res FROM t1; + RETURN res; +END; +| +CREATE PROCEDURE fill_t2 (IN upb int) +BEGIN +DECLARE cnt int DEFAULT 0; +WHILE cnt < upb DO + INSERT INTO t2 VALUES (cnt, cnt+100, cnt, cnt+100); + SET cnt= cnt+1; +END WHILE; +END; +| +CREATE FUNCTION half_t2() RETURNS int +BEGIN + DECLARE res int DEFAULT 0; + SELECT MOD(k,2) INTO res FROM t2; + RETURN res; +END; +| +DELIMITER ;| +eval CALL fill_t1 ($nbrows); +eval CALL fill_t2 ($nbrows); +COMMIT; +SELECT @@global.tx_isolation; +# With the two separate selects (without join) the differs from +# that select with join. + +# Both transaction are able to update the tables +eval EXPLAIN $select; +eval $select; + +--echo connection root1; +CONNECTION root1; +SELECT t1.i,t2.i FROM t1,t2 WHERE t1.k % 2= 1 AND t1.k = t2.k LOCK IN SHARE MODE; +UPDATE t1,t2 SET t1.i=1111,t2.i=2222 WHERE t1.k % 2 = 1 AND t1.k = t2.k; +SELECT * FROM t1 WHERE k < 20 ORDER BY t1.k; +SELECT * FROM t2 WHERE k < 20 ORDER BY t2.k; + +--echo connection default; +CONNECTION default; +UPDATE t1,t2 SET t1.i=3333,t2.i=4444 WHERE t1.k % 2 = 0 AND t1.k = t2.k; +SELECT * FROM t1 WHERE k < 20 ORDER BY t1.k; +SELECT * FROM t2 WHERE k < 20 ORDER BY t2.k; + +COMMIT; + +--echo connection root1; +CONNECTION root1; +ROLLBACK; + +--echo connection default; +CONNECTION default; +SELECT * FROM t1 WHERE k < 40 ORDER BY t1.k; +SELECT * FROM t2 WHERE k < 40 ORDER BY t2.k; + +--echo connection root1; +CONNECTION root1; +SELECT * FROM t1 WHERE k < 40 ORDER BY t1.k; +SELECT * FROM t2 WHERE k < 40 ORDER BY t2.k; +DISCONNECT root1; +--echo connection default; +CONNECTION default; +DROP TABLE t1, t2; + + diff --git a/mysql-test/suite/row_lock/include/row_lock_big_tab_2.inc b/mysql-test/suite/row_lock/include/row_lock_big_tab_2.inc new file mode 100644 index 00000000000..050f2a54016 --- /dev/null +++ b/mysql-test/suite/row_lock/include/row_lock_big_tab_2.inc @@ -0,0 +1,93 @@ +--disable_warnings +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1; +--enable_warnings +SET autocommit=0; +# Create additional connections used through test +CONNECT (root1, localhost, root,,); +SET autocommit=0; +--echo connection default; +CONNECTION default; +eval CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=$engine; +eval $indext1; +eval CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=$engine; +eval $indext2; +DELIMITER |; +CREATE PROCEDURE fill_t1 (IN upb int) +BEGIN +DECLARE cnt int DEFAULT 0; +WHILE cnt < upb DO + INSERT INTO t1 VALUES (cnt, cnt+100, cnt, cnt+100); + SET cnt= cnt+1; +END WHILE; +END; +| +CREATE FUNCTION half_t1() RETURNS int +BEGIN + DECLARE res int DEFAULT 0; + SELECT MOD(k,2) INTO res FROM t1; + RETURN res; +END; +| +CREATE PROCEDURE fill_t2 (IN upb int) +BEGIN +DECLARE cnt int DEFAULT 0; +WHILE cnt < upb DO + INSERT INTO t2 VALUES (cnt, cnt+100, cnt, cnt+100); + SET cnt= cnt+1; +END WHILE; +END; +| +CREATE FUNCTION half_t2() RETURNS int +BEGIN + DECLARE res int DEFAULT 0; + SELECT MOD(k,2) INTO res FROM t2; + RETURN res; +END; +| +DELIMITER ;| +eval CALL fill_t1 ($nbrows); +eval CALL fill_t2 ($nbrows); +COMMIT; +SELECT @@global.tx_isolation; +# With the two separate selects (without join) the differs from +# that select with join. + +# Both transaction are able to update the tables +eval EXPLAIN $select; +eval $select; + +--echo connection root1; +CONNECTION root1; +#SELECT t1.i,t2.i FROM t1,t2 WHERE t1.k % 2= 1 AND t1.k = t2.k FOR UPDATE; +DELETE FROM t1 WHERE t1.k % 2 = 1; +SELECT * FROM t1 WHERE k < 20 ORDER BY t1.k; +SELECT * FROM t2 WHERE k < 20 ORDER BY t2.k; + +--echo connection default; +CONNECTION default; +UPDATE t1,t2 SET t1.i=3333,t2.i=4444 WHERE t1.k % 2 = 0 AND t1.k = t2.k; +SELECT * FROM t1 WHERE k < 20 ORDER BY t1.k; +SELECT * FROM t2 WHERE k < 20 ORDER BY t2.k; + +COMMIT; + +--echo connection root1; +CONNECTION root1; +ROLLBACK; + +--echo connection default; +CONNECTION default; +SELECT * FROM t1 WHERE k < 40 ORDER BY t1.k; +SELECT * FROM t2 WHERE k < 40 ORDER BY t2.k; + +--echo connection root1; +CONNECTION root1; +SELECT * FROM t1 WHERE k < 40 ORDER BY t1.k; +SELECT * FROM t2 WHERE k < 40 ORDER BY t2.k; +DISCONNECT root1; +--echo connection default; +CONNECTION default; +DROP TABLE t1, t2; + + diff --git a/mysql-test/suite/row_lock/include/row_lock_trig.inc b/mysql-test/suite/row_lock/include/row_lock_trig.inc new file mode 100644 index 00000000000..384f00f243e --- /dev/null +++ b/mysql-test/suite/row_lock/include/row_lock_trig.inc @@ -0,0 +1,96 @@ +--disable_warnings +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1; +--enable_warnings +SET autocommit=0; +# Create additional connections used through test +CONNECT (root1, localhost, root,,); +SET autocommit=0; +--echo connection default; +CONNECTION default; +eval CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=$engine; +INSERT INTO t1 VALUES (1,123,1,123); +INSERT INTO t1 VALUES (2,124,2,124); +INSERT INTO t1 VALUES (3,125,3,125); +INSERT INTO t1 VALUES (4,126,4,126); +eval $indext1; +eval CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=$engine; +INSERT INTO t2 VALUES (1,123,1,123); +INSERT INTO t2 VALUES (2,124,2,124); +INSERT INTO t2 VALUES (3,125,3,125); +INSERT INTO t2 VALUES (4,126,4,126); +eval $indext2; +DELIMITER |; + +CREATE TRIGGER trig_t2 AFTER UPDATE ON t2 + FOR EACH ROW BEGIN + UPDATE t1 SET l = NEW.i WHERE i = OLD.i; + END; +| + +DELIMITER ;| + +COMMIT; +SELECT @@global.tx_isolation; +# With the two separate selects (without join) the differs from +# that select with join. + +# Both transaction are able to update the tables +eval EXPLAIN $select; +eval $select; +--echo connection root1; +CONNECTION root1; +UPDATE t2 SET t2.i=225 WHERE t2.i=125; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; + +--echo connection default; +CONNECTION default; +UPDATE t2 SET t2.i=223 WHERE t2.i=123; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; + +--echo connection root1; +CONNECTION root1; +UPDATE t2 SET t2.i=226 WHERE t2.i=126; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; + +--echo connection default; +CONNECTION default; +UPDATE t2 SET t2.i=224 WHERE t2.i=124; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; + +--echo connection root1; +CONNECTION root1; +DELETE FROM t1 WHERE t1.i=226; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; + +--echo connection default; +CONNECTION default; +DELETE FROM t1 WHERE t1.i=224; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; +COMMIT; + +--echo connection root1; +CONNECTION root1; +ROLLBACK; + +--echo connection default; +CONNECTION default; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; + +--echo connection root1; +CONNECTION root1; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; +DISCONNECT root1; +--echo connection default; +CONNECTION default; +DROP TABLE t1, t2; +#DROP VIEW v1; + diff --git a/mysql-test/suite/row_lock/include/row_lock_view.inc b/mysql-test/suite/row_lock/include/row_lock_view.inc new file mode 100644 index 00000000000..fbed8f64d3a --- /dev/null +++ b/mysql-test/suite/row_lock/include/row_lock_view.inc @@ -0,0 +1,89 @@ +--disable_warnings +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1; +--enable_warnings +SET autocommit=0; +# Create additional connections used through test +CONNECT (root1, localhost, root,,); +SET autocommit=0; +--echo connection default; +CONNECTION default; +eval CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=$engine; +INSERT INTO t1 VALUES (1,123,1,123); +INSERT INTO t1 VALUES (2,124,2,124); +INSERT INTO t1 VALUES (3,125,3,125); +INSERT INTO t1 VALUES (4,126,4,126); +eval $indext1; +eval CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=$engine; +INSERT INTO t2 VALUES (1,123,1,123); +INSERT INTO t2 VALUES (2,124,2,124); +INSERT INTO t2 VALUES (3,125,3,125); +INSERT INTO t2 VALUES (4,126,4,126); +eval $indext2; +CREATE VIEW v1 AS SELECT t1.i, t2.l from t1,t2; +COMMIT; +SELECT @@global.tx_isolation; +# With the two separate selects (without join) the differs from +# that select with join. + +# Both transaction are able to update the tables +eval EXPLAIN $select; +eval $select; + +--echo connection root1; +CONNECTION root1; +UPDATE v1 SET i=325 where i=125; +SELECT * FROM v1 ORDER BY i,l; +SELECT * FROM t1 ORDER BY t1.k; + +--echo connection default; +CONNECTION default; +UPDATE v1 SET i=323 where i=123; +SELECT * FROM v1 ORDER BY i,l; +SELECT * FROM t1 ORDER BY t1.k; + +--echo connection root1; +CONNECTION root1; +UPDATE v1 SET i=326 where i=126; +SELECT * FROM v1 ORDER BY i,l; +SELECT * FROM t1 ORDER BY t1.k; + +--echo connection default; +CONNECTION default; +UPDATE v1 SET i=324 where i=124; +SELECT * FROM v1 ORDER BY i,l; +SELECT * FROM t1 ORDER BY t1.k; + +--echo connection root1; +CONNECTION root1; +DELETE FROM t1 WHERE t1.i=226; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; + +--echo connection default; +CONNECTION default; +DELETE FROM t1 WHERE t1.i=224; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; +COMMIT; + +--echo connection root1; +CONNECTION root1; +ROLLBACK; + +--echo connection default; +CONNECTION default; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; + +--echo connection root1; +CONNECTION root1; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; +DISCONNECT root1; +--echo connection default; +CONNECTION default; +DROP VIEW IF EXISTS v1; +DROP TABLE t1, t2; +#DROP VIEW v1; + diff --git a/mysql-test/suite/row_lock/include/row_lock_view_mix.inc b/mysql-test/suite/row_lock/include/row_lock_view_mix.inc new file mode 100644 index 00000000000..9e8cf3d34fc --- /dev/null +++ b/mysql-test/suite/row_lock/include/row_lock_view_mix.inc @@ -0,0 +1,92 @@ +--disable_warnings +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1; +--enable_warnings +SET autocommit=0; +# Create additional connections used through test +CONNECT (root1, localhost, root,,); +SET autocommit=0; +--echo connection default; +CONNECTION default; +eval CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=$engine; +INSERT INTO t1 VALUES (1,123,1,123); +INSERT INTO t1 VALUES (2,124,2,124); +INSERT INTO t1 VALUES (3,125,3,125); +INSERT INTO t1 VALUES (4,126,4,126); +eval $indext1; +eval CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=$engine; +INSERT INTO t2 VALUES (1,123,1,123); +INSERT INTO t2 VALUES (2,124,2,124); +INSERT INTO t2 VALUES (3,125,3,125); +INSERT INTO t2 VALUES (4,126,4,126); +eval $indext2; +CREATE VIEW v1 AS SELECT t1.i, t2.l from t1,t2; +COMMIT; +SELECT @@global.tx_isolation; +# With the two separate selects (without join) the differs from +# that select with join. + +# Both transaction are able to update the tables +eval EXPLAIN $select; +eval $select; + +--echo connection root1; +CONNECTION root1; +UPDATE t1,t2 SET t1.i=225,t2.i=225 WHERE t1.i=125 AND t2.i=t1.i; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; +#UPDATE v1 SET i=325 where i=125; +#SELECT * FROM v1 ORDER BY i,l; +#SELECT * FROM t1 ORDER BY t1.k; + +--echo connection default; +CONNECTION default; +UPDATE v1 SET i=323 where i=123; +SELECT * FROM v1 ORDER BY i,l; +SELECT * FROM t1 ORDER BY t1.k; + +--echo connection root1; +CONNECTION root1; +UPDATE t1,t2 SET t1.i=226,t2.i=226 WHERE t1.i=126 AND t2.i=t1.i; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; + +--echo connection default; +CONNECTION default; +UPDATE v1 SET i=324 where i=124; +SELECT * FROM v1 ORDER BY i,l; +SELECT * FROM t1 ORDER BY t1.k; + +--echo connection root1; +CONNECTION root1; +DELETE FROM t1 WHERE t1.i=226; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; + +--echo connection default; +CONNECTION default; +DELETE FROM t1 WHERE t1.i=224; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; +COMMIT; + +--echo connection root1; +CONNECTION root1; +ROLLBACK; + +--echo connection default; +CONNECTION default; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; + +--echo connection root1; +CONNECTION root1; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; +DISCONNECT root1; +--echo connection default; +CONNECTION default; +DROP VIEW IF EXISTS v1; +DROP TABLE t1, t2; +#DROP VIEW v1; + diff --git a/mysql-test/suite/row_lock/include/row_lock_view_storedp.inc b/mysql-test/suite/row_lock/include/row_lock_view_storedp.inc new file mode 100644 index 00000000000..479392098be --- /dev/null +++ b/mysql-test/suite/row_lock/include/row_lock_view_storedp.inc @@ -0,0 +1,126 @@ +--disable_warnings +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1; +DROP PROCEDURE IF EXISTS stp_t; +--enable_warnings +SET autocommit=0; +# Create additional connections used through test +CONNECT (root1, localhost, root,,); +SET autocommit=0; +CONNECT (root2, localhost, root,,); +SET autocommit=0; +--echo connection default; +CONNECTION default; +eval CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=$engine; +INSERT INTO t1 VALUES (1,123,1,123); +INSERT INTO t1 VALUES (2,124,2,124); +INSERT INTO t1 VALUES (3,125,3,125); +INSERT INTO t1 VALUES (4,126,4,126); +INSERT INTO t1 VALUES (5,127,5,127); +INSERT INTO t1 VALUES (6,128,6,128); +eval $indext1; +eval CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=$engine; +INSERT INTO t2 VALUES (1,123,1,123); +INSERT INTO t2 VALUES (2,124,2,124); +INSERT INTO t2 VALUES (3,125,3,125); +INSERT INTO t2 VALUES (4,126,4,126); +INSERT INTO t2 VALUES (5,127,5,127); +INSERT INTO t2 VALUES (6,128,6,128); +eval $indext2; +CREATE VIEW v1 AS SELECT t1.i from t1; +DELIMITER |; + +CREATE PROCEDURE stp_t (IN p1 int, IN p2 int) MODIFIES SQL DATA + BEGIN + UPDATE t2 SET i = p2 WHERE i = p1; + UPDATE v1 SET i = p2 WHERE i = p1; + SELECT * FROM v1 ORDER BY i; + SELECT * FROM t1 ORDER BY t1.k; + SELECT * FROM t2 ORDER BY t2.k; + END; +| + +DELIMITER ;| + +COMMIT; +SELECT @@global.tx_isolation; +eval EXPLAIN $select; +eval $select; +--echo connection root1; +CONNECTION root1; +CALL stp_t (125, 225); + +--echo connection root2; +CONNECTION root2; +CALL stp_t (127, 227); + +--echo connection default; +CONNECTION default; +CALL stp_t (123, 223); + +--echo connection root1; +CONNECTION root1; +CALL stp_t (126, 226); + +--echo connection root2; +CONNECTION root2; +CALL stp_t (128, 228); + +--echo connection default; +CONNECTION default; +CALL stp_t (124, 224); + +--echo connection root1; +CONNECTION root1; +DELETE FROM t1 WHERE t1.i=226; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; + +--echo connection root2; +CONNECTION root2; +DELETE FROM t1 WHERE t1.i=228; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; + +--echo connection default; +CONNECTION default; +DELETE FROM t1 WHERE t1.i=224; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; +COMMIT; + +--echo connection root1; +CONNECTION root1; +ROLLBACK; + +--echo connection root1; +CONNECTION root1; +COMMIT; + +--echo connection default; +CONNECTION default; +SELECT * FROM v1 ORDER BY i; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; + +--echo connection root1; +CONNECTION root1; +SELECT * FROM v1 ORDER BY i; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; +DISCONNECT root1; + +--echo connection root2; +CONNECTION root2; +SELECT * FROM v1 ORDER BY i; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; +DISCONNECT root2; + +--echo connection default; +CONNECTION default; +--disable_warnings +DROP VIEW v1; +DROP PROCEDURE stp_t; +DROP TABLE t1, t2; +--enable_warnings diff --git a/mysql-test/suite/row_lock/include/row_lock_view_trig.inc b/mysql-test/suite/row_lock/include/row_lock_view_trig.inc new file mode 100644 index 00000000000..785eb1b66a9 --- /dev/null +++ b/mysql-test/suite/row_lock/include/row_lock_view_trig.inc @@ -0,0 +1,99 @@ +--disable_warnings +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1; +--enable_warnings +SET autocommit=0; +# Create additional connections used through test +CONNECT (root1, localhost, root,,); +SET autocommit=0; +--echo connection default; +CONNECTION default; +eval CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=$engine; +INSERT INTO t1 VALUES (1,123,1,123); +INSERT INTO t1 VALUES (2,124,2,124); +INSERT INTO t1 VALUES (3,125,3,125); +INSERT INTO t1 VALUES (4,126,4,126); +eval $indext1; +eval CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=$engine; +INSERT INTO t2 VALUES (1,123,1,123); +INSERT INTO t2 VALUES (2,124,2,124); +INSERT INTO t2 VALUES (3,125,3,125); +INSERT INTO t2 VALUES (4,126,4,126); +eval $indext2; +CREATE VIEW v1 AS SELECT t1.i from t1; +DELIMITER |; + +CREATE TRIGGER trig_t2 AFTER UPDATE ON t2 + FOR EACH ROW BEGIN + UPDATE v1 SET i = NEW.i WHERE i = OLD.i; + END; +| + +DELIMITER ;| + +COMMIT; +SELECT @@global.tx_isolation; +eval EXPLAIN $select; +eval $select; +--echo connection root1; +CONNECTION root1; +UPDATE t2 SET t2.i=225 WHERE t2.i=125; +SELECT * FROM v1 ORDER BY i; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; + +--echo connection default; +CONNECTION default; +UPDATE t2 SET t2.i=223 WHERE t2.i=123; +SELECT * FROM v1 ORDER BY i; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; + +--echo connection root1; +CONNECTION root1; +UPDATE t2 SET t2.i=226 WHERE t2.i=126; +SELECT * FROM v1 ORDER BY i; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; + +--echo connection default; +CONNECTION default; +UPDATE t2 SET t2.i=224 WHERE t2.i=124; +SELECT * FROM v1 ORDER BY i; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; + +--echo connection root1; +CONNECTION root1; +DELETE FROM t1 WHERE t1.i=226; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; + +--echo connection default; +CONNECTION default; +DELETE FROM t1 WHERE t1.i=224; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; +COMMIT; + +--echo connection root1; +CONNECTION root1; +ROLLBACK; + +--echo connection default; +CONNECTION default; +SELECT * FROM v1 ORDER BY i; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; + +--echo connection root1; +CONNECTION root1; +SELECT * FROM v1 ORDER BY i; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; +DISCONNECT root1; +--echo connection default; +CONNECTION default; +DROP TABLE t1, t2; +DROP VIEW v1; + diff --git a/mysql-test/suite/row_lock/r/innodb_row_lock_1.result b/mysql-test/suite/row_lock/r/innodb_row_lock_1.result new file mode 100644 index 00000000000..54ed4350ba9 --- /dev/null +++ b/mysql-test/suite/row_lock/r/innodb_row_lock_1.result @@ -0,0 +1,142 @@ +SELECT @@global.innodb_table_locks into @table_locks; +SET @@global.innodb_table_locks= OFF; +DROP TABLE IF EXISTS t1, t2; +SET autocommit=0; +SET autocommit=0; +connection default; +CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,123,1,123); +INSERT INTO t1 VALUES (2,124,2,124); +INSERT INTO t1 VALUES (3,125,3,125); +INSERT INTO t1 VALUES (4,126,4,126); +CREATE INDEX ixi ON t1 (i); +CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,123,1,123); +INSERT INTO t2 VALUES (2,124,2,124); +INSERT INTO t2 VALUES (3,125,3,125); +INSERT INTO t2 VALUES (4,126,4,126); +CREATE INDEX ixi ON t2 (i); +COMMIT; +SELECT @@global.tx_isolation; +@@global.tx_isolation +REPEATABLE-READ +EXPLAIN SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i FOR UPDATE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index ixi ixi 5 NULL 4 Using where; Using index +1 SIMPLE t2 ref ixi ixi 5 test.t1.i 2 Using where; Using index +SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i FOR UPDATE; +i i +123 123 +124 124 +connection root1; +UPDATE t1,t2 SET t1.i=225,t2.i=225 WHERE t1.i=125 AND t2.i=t1.i; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 126 4 126 +connection default; +UPDATE t1,t2 SET t1.i=223,t2.i=223 WHERE t1.i=123 AND t2.i=t1.i; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +connection root1; +UPDATE t1,t2 SET t1.i=226,t2.i=226 WHERE t1.i=126 AND t2.i=t1.i; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 226 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 226 4 126 +connection default; +UPDATE t1,t2 SET t1.i=224,t2.i=224 WHERE t1.i=124 AND t2.i=t1.i; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +connection root1; +DELETE FROM t1 WHERE t1.i=226; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 226 4 126 +connection default; +DELETE FROM t1 WHERE t1.i=224; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +COMMIT; +connection root1; +ROLLBACK; +connection default; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +connection root1; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +connection default; +DROP TABLE t1, t2; +SET @@global.innodb_table_locks= @table_locks; diff --git a/mysql-test/suite/row_lock/r/innodb_row_lock_2.result b/mysql-test/suite/row_lock/r/innodb_row_lock_2.result new file mode 100644 index 00000000000..56154e64489 --- /dev/null +++ b/mysql-test/suite/row_lock/r/innodb_row_lock_2.result @@ -0,0 +1,32 @@ +SELECT @@global.innodb_table_locks into @table_locks; +SET @@global.innodb_table_locks= OFF; +DROP TABLE IF EXISTS t1, t2; +SET autocommit=0; +SET autocommit=0; +connection default; +CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,123,1,123); +INSERT INTO t1 VALUES (2,124,2,124); +INSERT INTO t1 VALUES (3,125,3,125); +INSERT INTO t1 VALUES (4,126,4,126); +#CREATE INDEX ixi ON t1 (i); +CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,123,1,123); +INSERT INTO t2 VALUES (2,124,2,124); +INSERT INTO t2 VALUES (3,125,3,125); +INSERT INTO t2 VALUES (4,126,4,126); +#CREATE INDEX ixi ON t2 (i); +COMMIT; +SELECT @@global.tx_isolation; +@@global.tx_isolation +REPEATABLE-READ +EXPLAIN SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i FOR UPDATE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 4 Using where +SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i FOR UPDATE; +i i +123 123 +124 124 +connection root1; +UPDATE t1,t2 SET t1.i=225,t2.i=225 WHERE t1.i=125 AND t2.i=t1.i; diff --git a/mysql-test/suite/row_lock/r/innodb_row_lock_3.result b/mysql-test/suite/row_lock/r/innodb_row_lock_3.result new file mode 100644 index 00000000000..a89c55973d2 --- /dev/null +++ b/mysql-test/suite/row_lock/r/innodb_row_lock_3.result @@ -0,0 +1,32 @@ +SELECT @@global.innodb_table_locks into @table_locks; +SET @@global.innodb_table_locks= OFF; +DROP TABLE IF EXISTS t1, t2; +SET autocommit=0; +SET autocommit=0; +connection default; +CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,123,1,123); +INSERT INTO t1 VALUES (2,124,2,124); +INSERT INTO t1 VALUES (3,125,3,125); +INSERT INTO t1 VALUES (4,126,4,126); +#CREATE INDEX ixi ON t1 (i); +CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,123,1,123); +INSERT INTO t2 VALUES (2,124,2,124); +INSERT INTO t2 VALUES (3,125,3,125); +INSERT INTO t2 VALUES (4,126,4,126); +#CREATE INDEX ixi ON t2 (i); +COMMIT; +SELECT @@global.tx_isolation; +@@global.tx_isolation +REPEATABLE-READ +EXPLAIN SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i LOCK IN SHARE MODE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 4 Using where +SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i LOCK IN SHARE MODE; +i i +123 123 +124 124 +connection root1; +UPDATE t1,t2 SET t1.i=225,t2.i=225 WHERE t1.i=125 AND t2.i=t1.i; diff --git a/mysql-test/suite/row_lock/r/innodb_row_lock_4.result b/mysql-test/suite/row_lock/r/innodb_row_lock_4.result new file mode 100644 index 00000000000..310d24a456a --- /dev/null +++ b/mysql-test/suite/row_lock/r/innodb_row_lock_4.result @@ -0,0 +1,142 @@ +SELECT @@global.innodb_table_locks into @table_locks; +SET @@global.innodb_table_locks= OFF; +DROP TABLE IF EXISTS t1, t2; +SET autocommit=0; +SET autocommit=0; +connection default; +CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,123,1,123); +INSERT INTO t1 VALUES (2,124,2,124); +INSERT INTO t1 VALUES (3,125,3,125); +INSERT INTO t1 VALUES (4,126,4,126); +CREATE INDEX ixi ON t1 (i); +CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,123,1,123); +INSERT INTO t2 VALUES (2,124,2,124); +INSERT INTO t2 VALUES (3,125,3,125); +INSERT INTO t2 VALUES (4,126,4,126); +CREATE INDEX ixi ON t2 (i); +COMMIT; +SELECT @@global.tx_isolation; +@@global.tx_isolation +REPEATABLE-READ +EXPLAIN SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i LOCK IN SHARE MODE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index ixi ixi 5 NULL 4 Using where; Using index +1 SIMPLE t2 ref ixi ixi 5 test.t1.i 2 Using where; Using index +SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i LOCK IN SHARE MODE; +i i +123 123 +124 124 +connection root1; +UPDATE t1,t2 SET t1.i=225,t2.i=225 WHERE t1.i=125 AND t2.i=t1.i; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 126 4 126 +connection default; +UPDATE t1,t2 SET t1.i=223,t2.i=223 WHERE t1.i=123 AND t2.i=t1.i; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +connection root1; +UPDATE t1,t2 SET t1.i=226,t2.i=226 WHERE t1.i=126 AND t2.i=t1.i; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 226 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 226 4 126 +connection default; +UPDATE t1,t2 SET t1.i=224,t2.i=224 WHERE t1.i=124 AND t2.i=t1.i; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +connection root1; +DELETE FROM t1 WHERE t1.i=226; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 226 4 126 +connection default; +DELETE FROM t1 WHERE t1.i=224; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +COMMIT; +connection root1; +ROLLBACK; +connection default; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +connection root1; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +connection default; +DROP TABLE t1, t2; +SET @@global.innodb_table_locks= @table_locks; diff --git a/mysql-test/suite/row_lock/r/innodb_row_lock_5.result b/mysql-test/suite/row_lock/r/innodb_row_lock_5.result new file mode 100644 index 00000000000..ace5fddfad5 --- /dev/null +++ b/mysql-test/suite/row_lock/r/innodb_row_lock_5.result @@ -0,0 +1,32 @@ +SELECT @@global.innodb_table_locks into @table_locks; +SET @@global.innodb_table_locks= OFF; +DROP TABLE IF EXISTS t1, t2; +SET autocommit=0; +SET autocommit=0; +connection default; +CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,123,1,123); +INSERT INTO t1 VALUES (2,124,2,124); +INSERT INTO t1 VALUES (3,125,3,125); +INSERT INTO t1 VALUES (4,126,4,126); +CREATE INDEX ixi ON t1 (i); +CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,123,1,123); +INSERT INTO t2 VALUES (2,124,2,124); +INSERT INTO t2 VALUES (3,125,3,125); +INSERT INTO t2 VALUES (4,126,4,126); +CREATE INDEX ixi ON t2 (i); +COMMIT; +SELECT @@global.tx_isolation; +@@global.tx_isolation +REPEATABLE-READ +EXPLAIN SELECT t1.i,t2.i FROM t1 ignore index (ixi),t2 IGNORE INDEX (ixi) WHERE t1.i<125 AND t2.i=t1.i LOCK IN SHARE MODE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 4 Using where +SELECT t1.i,t2.i FROM t1 ignore index (ixi),t2 IGNORE INDEX (ixi) WHERE t1.i<125 AND t2.i=t1.i LOCK IN SHARE MODE; +i i +123 123 +124 124 +connection root1; +UPDATE t1,t2 SET t1.i=225,t2.i=225 WHERE t1.i=125 AND t2.i=t1.i; diff --git a/mysql-test/suite/row_lock/r/innodb_row_lock_big_tab.result b/mysql-test/suite/row_lock/r/innodb_row_lock_big_tab.result new file mode 100644 index 00000000000..8f00c3a0bb7 --- /dev/null +++ b/mysql-test/suite/row_lock/r/innodb_row_lock_big_tab.result @@ -0,0 +1,97 @@ +SELECT @@global.innodb_table_locks into @table_locks; +SET @@global.innodb_table_locks= OFF; +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1; +SET autocommit=0; +SET autocommit=0; +connection default; +CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=InnoDB; +CREATE INDEX ixi ON t1 (i); +CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=InnoDB; +CREATE INDEX ixi ON t2 (i); +CREATE PROCEDURE fill_t1 (IN upb int) +BEGIN +DECLARE cnt int DEFAULT 0; +WHILE cnt < upb DO +INSERT INTO t1 VALUES (cnt, cnt+100, cnt, cnt+100); +SET cnt= cnt+1; +END WHILE; +END; +| +CREATE FUNCTION half_t1() RETURNS int +BEGIN +DECLARE res int DEFAULT 0; +SELECT count(*)/2 INTO res FROM t1; +RETURN res; +END; +| +CREATE PROCEDURE fill_t2 (IN upb int) +BEGIN +DECLARE cnt int DEFAULT 0; +WHILE cnt < upb DO +INSERT INTO t2 VALUES (cnt, cnt+100, cnt, cnt+100); +SET cnt= cnt+1; +END WHILE; +END; +| +CREATE FUNCTION half_t2() RETURNS int +BEGIN +DECLARE res int DEFAULT 0; +SELECT count(*)/2 INTO res FROM t2; +RETURN res; +END; +| +CALL fill_t1 (10); +CALL fill_t2 (10); +COMMIT; +SELECT @@global.tx_isolation; +@@global.tx_isolation +REPEATABLE-READ +EXPLAIN SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i < half_t1() AND t2.i=t1.i LOCK IN SHARE MODE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index ixi ixi 5 NULL 10 Using where; Using index +1 SIMPLE t2 ref ixi ixi 5 test.t1.i 1 Using where; Using index +SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i < half_t1() AND t2.i=t1.i LOCK IN SHARE MODE; +i i +connection root1; +SELECT k from t1 WHERE k < half_t1(); +k +0 +1 +2 +3 +4 +SELECT k from t1 WHERE k >= half_t1(); +k +5 +6 +7 +8 +9 +UPDATE t1,t2 SET t1.i=1111,t2.i=2222 WHERE t1.k < half_t1() AND t2.i=t1.i; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +0 1111 0 100 +1 1111 1 101 +2 1111 2 102 +3 1111 3 103 +4 1111 4 104 +5 105 5 105 +6 106 6 106 +7 107 7 107 +8 108 8 108 +9 109 9 109 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +0 2222 0 100 +1 2222 1 101 +2 2222 2 102 +3 2222 3 103 +4 2222 4 104 +5 105 5 105 +6 106 6 106 +7 107 7 107 +8 108 8 108 +9 109 9 109 +connection default; +UPDATE t1,t2 SET t1.i=3333,t2.i=4444 WHERE t1.k >= half_t1() AND t2.i=t1.i; diff --git a/mysql-test/suite/row_lock/r/innodb_row_lock_big_tab_1.result b/mysql-test/suite/row_lock/r/innodb_row_lock_big_tab_1.result new file mode 100644 index 00000000000..0b12f149193 --- /dev/null +++ b/mysql-test/suite/row_lock/r/innodb_row_lock_big_tab_1.result @@ -0,0 +1,145 @@ +SELECT @@global.innodb_table_locks into @table_locks; +SET @@global.innodb_table_locks= OFF; +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1; +SET autocommit=0; +SET autocommit=0; +connection default; +CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=InnoDB; +CREATE INDEX ixi ON t1 (i); +CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=InnoDB; +CREATE INDEX ixi ON t2 (i); +CREATE PROCEDURE fill_t1 (IN upb int) +BEGIN +DECLARE cnt int DEFAULT 0; +WHILE cnt < upb DO +INSERT INTO t1 VALUES (cnt, cnt+100, cnt, cnt+100); +SET cnt= cnt+1; +END WHILE; +END; +| +CREATE FUNCTION half_t1() RETURNS int +BEGIN +DECLARE res int DEFAULT 0; +SELECT MOD(k,2) INTO res FROM t1; +RETURN res; +END; +| +CREATE PROCEDURE fill_t2 (IN upb int) +BEGIN +DECLARE cnt int DEFAULT 0; +WHILE cnt < upb DO +INSERT INTO t2 VALUES (cnt, cnt+100, cnt, cnt+100); +SET cnt= cnt+1; +END WHILE; +END; +| +CREATE FUNCTION half_t2() RETURNS int +BEGIN +DECLARE res int DEFAULT 0; +SELECT MOD(k,2) INTO res FROM t2; +RETURN res; +END; +| +CALL fill_t1 (40); +CALL fill_t2 (40); +COMMIT; +SELECT @@global.tx_isolation; +@@global.tx_isolation +REPEATABLE-READ +EXPLAIN SELECT t1.i,t2.i FROM t1,t2 WHERE t1.k % 2= 0 AND t1.k = t2.k LOCK IN SHARE MODE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index PRIMARY ixi 5 NULL 40 Using where; Using index +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.k 1 +SELECT t1.i,t2.i FROM t1,t2 WHERE t1.k % 2= 0 AND t1.k = t2.k LOCK IN SHARE MODE; +i i +100 100 +102 102 +104 104 +106 106 +108 108 +110 110 +112 112 +114 114 +116 116 +118 118 +120 120 +122 122 +124 124 +126 126 +128 128 +130 130 +132 132 +134 134 +136 136 +138 138 +connection root1; +SELECT t1.i,t2.i FROM t1,t2 WHERE t1.k % 2= 1 AND t1.k = t2.k LOCK IN SHARE MODE; +i i +101 101 +103 103 +105 105 +107 107 +109 109 +111 111 +113 113 +115 115 +117 117 +119 119 +121 121 +123 123 +125 125 +127 127 +129 129 +131 131 +133 133 +135 135 +137 137 +139 139 +UPDATE t1,t2 SET t1.i=1111,t2.i=2222 WHERE t1.k % 2 = 1 AND t1.k = t2.k; +SELECT * FROM t1 WHERE k < 20 ORDER BY t1.k; +k i j l +0 100 0 100 +1 1111 1 101 +2 102 2 102 +3 1111 3 103 +4 104 4 104 +5 1111 5 105 +6 106 6 106 +7 1111 7 107 +8 108 8 108 +9 1111 9 109 +10 110 10 110 +11 1111 11 111 +12 112 12 112 +13 1111 13 113 +14 114 14 114 +15 1111 15 115 +16 116 16 116 +17 1111 17 117 +18 118 18 118 +19 1111 19 119 +SELECT * FROM t2 WHERE k < 20 ORDER BY t2.k; +k i j l +0 100 0 100 +1 2222 1 101 +2 102 2 102 +3 2222 3 103 +4 104 4 104 +5 2222 5 105 +6 106 6 106 +7 2222 7 107 +8 108 8 108 +9 2222 9 109 +10 110 10 110 +11 2222 11 111 +12 112 12 112 +13 2222 13 113 +14 114 14 114 +15 2222 15 115 +16 116 16 116 +17 2222 17 117 +18 118 18 118 +19 2222 19 119 +connection default; +UPDATE t1,t2 SET t1.i=3333,t2.i=4444 WHERE t1.k % 2 = 0 AND t1.k = t2.k; diff --git a/mysql-test/suite/row_lock/r/innodb_row_lock_big_tab_2.result b/mysql-test/suite/row_lock/r/innodb_row_lock_big_tab_2.result new file mode 100644 index 00000000000..cc9f297f9fb --- /dev/null +++ b/mysql-test/suite/row_lock/r/innodb_row_lock_big_tab_2.result @@ -0,0 +1,113 @@ +SELECT @@global.innodb_table_locks into @table_locks; +SET @@global.innodb_table_locks= OFF; +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1; +SET autocommit=0; +SET autocommit=0; +connection default; +CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=InnoDB; +CREATE INDEX ixi ON t1 (i); +CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=InnoDB; +CREATE INDEX ixi ON t2 (i); +CREATE PROCEDURE fill_t1 (IN upb int) +BEGIN +DECLARE cnt int DEFAULT 0; +WHILE cnt < upb DO +INSERT INTO t1 VALUES (cnt, cnt+100, cnt, cnt+100); +SET cnt= cnt+1; +END WHILE; +END; +| +CREATE FUNCTION half_t1() RETURNS int +BEGIN +DECLARE res int DEFAULT 0; +SELECT MOD(k,2) INTO res FROM t1; +RETURN res; +END; +| +CREATE PROCEDURE fill_t2 (IN upb int) +BEGIN +DECLARE cnt int DEFAULT 0; +WHILE cnt < upb DO +INSERT INTO t2 VALUES (cnt, cnt+100, cnt, cnt+100); +SET cnt= cnt+1; +END WHILE; +END; +| +CREATE FUNCTION half_t2() RETURNS int +BEGIN +DECLARE res int DEFAULT 0; +SELECT MOD(k,2) INTO res FROM t2; +RETURN res; +END; +| +CALL fill_t1 (40); +CALL fill_t2 (40); +COMMIT; +SELECT @@global.tx_isolation; +@@global.tx_isolation +REPEATABLE-READ +EXPLAIN SELECT t1.i,t2.i FROM t1,t2 WHERE t1.k % 2= 0 AND t1.k = t2.k LOCK IN SHARE MODE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index PRIMARY ixi 5 NULL 40 Using where; Using index +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.k 1 +SELECT t1.i,t2.i FROM t1,t2 WHERE t1.k % 2= 0 AND t1.k = t2.k LOCK IN SHARE MODE; +i i +100 100 +102 102 +104 104 +106 106 +108 108 +110 110 +112 112 +114 114 +116 116 +118 118 +120 120 +122 122 +124 124 +126 126 +128 128 +130 130 +132 132 +134 134 +136 136 +138 138 +connection root1; +DELETE FROM t1 WHERE t1.k % 2 = 1; +SELECT * FROM t1 WHERE k < 20 ORDER BY t1.k; +k i j l +0 100 0 100 +2 102 2 102 +4 104 4 104 +6 106 6 106 +8 108 8 108 +10 110 10 110 +12 112 12 112 +14 114 14 114 +16 116 16 116 +18 118 18 118 +SELECT * FROM t2 WHERE k < 20 ORDER BY t2.k; +k i j l +0 100 0 100 +1 101 1 101 +2 102 2 102 +3 103 3 103 +4 104 4 104 +5 105 5 105 +6 106 6 106 +7 107 7 107 +8 108 8 108 +9 109 9 109 +10 110 10 110 +11 111 11 111 +12 112 12 112 +13 113 13 113 +14 114 14 114 +15 115 15 115 +16 116 16 116 +17 117 17 117 +18 118 18 118 +19 119 19 119 +connection default; +UPDATE t1,t2 SET t1.i=3333,t2.i=4444 WHERE t1.k % 2 = 0 AND t1.k = t2.k; diff --git a/mysql-test/suite/row_lock/r/innodb_row_lock_trig_1.result b/mysql-test/suite/row_lock/r/innodb_row_lock_trig_1.result new file mode 100644 index 00000000000..dd43e5752e5 --- /dev/null +++ b/mysql-test/suite/row_lock/r/innodb_row_lock_trig_1.result @@ -0,0 +1,151 @@ +SELECT @@global.innodb_table_locks into @table_locks; +SET @@global.innodb_table_locks= OFF; +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1; +SET autocommit=0; +SET autocommit=0; +connection default; +CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,123,1,123); +INSERT INTO t1 VALUES (2,124,2,124); +INSERT INTO t1 VALUES (3,125,3,125); +INSERT INTO t1 VALUES (4,126,4,126); +CREATE INDEX ixi ON t1 (i); +CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,123,1,123); +INSERT INTO t2 VALUES (2,124,2,124); +INSERT INTO t2 VALUES (3,125,3,125); +INSERT INTO t2 VALUES (4,126,4,126); +CREATE INDEX ixi ON t2 (i); +CREATE TRIGGER trig_t2 AFTER UPDATE ON t2 +FOR EACH ROW BEGIN +UPDATE t1 SET l = NEW.i WHERE i = OLD.i; +END; +| +COMMIT; +SELECT @@global.tx_isolation; +@@global.tx_isolation +REPEATABLE-READ +EXPLAIN SELECT t1.i FROM t1 WHERE t1.i< 125 FOR UPDATE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index ixi ixi 5 NULL 4 Using where; Using index +SELECT t1.i FROM t1 WHERE t1.i< 125 FOR UPDATE; +i +123 +124 +connection root1; +UPDATE t2 SET t2.i=225 WHERE t2.i=125; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 125 3 225 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 126 4 126 +connection default; +UPDATE t2 SET t2.i=223 WHERE t2.i=123; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 223 +2 124 2 124 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +connection root1; +UPDATE t2 SET t2.i=226 WHERE t2.i=126; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 125 3 225 +4 126 4 226 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 226 4 126 +connection default; +UPDATE t2 SET t2.i=224 WHERE t2.i=124; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 223 +2 124 2 224 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +connection root1; +DELETE FROM t1 WHERE t1.i=226; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 125 3 225 +4 126 4 226 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 226 4 126 +connection default; +DELETE FROM t1 WHERE t1.i=224; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 223 +2 124 2 224 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +COMMIT; +connection root1; +ROLLBACK; +connection default; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 223 +2 124 2 224 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +connection root1; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 223 +2 124 2 224 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +connection default; +DROP TABLE t1, t2; +SET @@global.innodb_table_locks= @table_locks; diff --git a/mysql-test/suite/row_lock/r/innodb_row_lock_trig_2.result b/mysql-test/suite/row_lock/r/innodb_row_lock_trig_2.result new file mode 100644 index 00000000000..cb3a5c692e9 --- /dev/null +++ b/mysql-test/suite/row_lock/r/innodb_row_lock_trig_2.result @@ -0,0 +1,37 @@ +SELECT @@global.innodb_table_locks into @table_locks; +SET @@global.innodb_table_locks= OFF; +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1; +SET autocommit=0; +SET autocommit=0; +connection default; +CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,123,1,123); +INSERT INTO t1 VALUES (2,124,2,124); +INSERT INTO t1 VALUES (3,125,3,125); +INSERT INTO t1 VALUES (4,126,4,126); +#CREATE INDEX ixi ON t1 (i); +CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,123,1,123); +INSERT INTO t2 VALUES (2,124,2,124); +INSERT INTO t2 VALUES (3,125,3,125); +INSERT INTO t2 VALUES (4,126,4,126); +#CREATE INDEX ixi ON t2 (i); +CREATE TRIGGER trig_t2 AFTER UPDATE ON t2 +FOR EACH ROW BEGIN +UPDATE t1 SET l = NEW.i WHERE i = OLD.i; +END; +| +COMMIT; +SELECT @@global.tx_isolation; +@@global.tx_isolation +REPEATABLE-READ +EXPLAIN SELECT t1.i FROM t1 WHERE t1.i< 125 FOR UPDATE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where +SELECT t1.i FROM t1 WHERE t1.i< 125 FOR UPDATE; +i +123 +124 +connection root1; +UPDATE t2 SET t2.i=225 WHERE t2.i=125; diff --git a/mysql-test/suite/row_lock/r/innodb_row_lock_view_1.result b/mysql-test/suite/row_lock/r/innodb_row_lock_view_1.result new file mode 100644 index 00000000000..834cb669833 --- /dev/null +++ b/mysql-test/suite/row_lock/r/innodb_row_lock_view_1.result @@ -0,0 +1,34 @@ +SELECT @@global.innodb_table_locks into @table_locks; +SET @@global.innodb_table_locks= OFF; +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1; +SET autocommit=0; +SET autocommit=0; +connection default; +CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,123,1,123); +INSERT INTO t1 VALUES (2,124,2,124); +INSERT INTO t1 VALUES (3,125,3,125); +INSERT INTO t1 VALUES (4,126,4,126); +CREATE INDEX ixi ON t1 (i); +CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,123,1,123); +INSERT INTO t2 VALUES (2,124,2,124); +INSERT INTO t2 VALUES (3,125,3,125); +INSERT INTO t2 VALUES (4,126,4,126); +CREATE INDEX ixi ON t2 (i); +CREATE VIEW v1 AS SELECT t1.i, t2.l from t1,t2; +COMMIT; +SELECT @@global.tx_isolation; +@@global.tx_isolation +REPEATABLE-READ +EXPLAIN SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i FOR UPDATE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index ixi ixi 5 NULL 4 Using where; Using index +1 SIMPLE t2 ref ixi ixi 5 test.t1.i 2 Using where; Using index +SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i FOR UPDATE; +i i +123 123 +124 124 +connection root1; +UPDATE v1 SET i=325 where i=125; diff --git a/mysql-test/suite/row_lock/r/innodb_row_lock_view_2.result b/mysql-test/suite/row_lock/r/innodb_row_lock_view_2.result new file mode 100644 index 00000000000..440138d4cd1 --- /dev/null +++ b/mysql-test/suite/row_lock/r/innodb_row_lock_view_2.result @@ -0,0 +1,40 @@ +SELECT @@global.innodb_table_locks into @table_locks; +SET @@global.innodb_table_locks= OFF; +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1; +SET autocommit=0; +SET autocommit=0; +connection default; +CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,123,1,123); +INSERT INTO t1 VALUES (2,124,2,124); +INSERT INTO t1 VALUES (3,125,3,125); +INSERT INTO t1 VALUES (4,126,4,126); +CREATE INDEX ixi ON t1 (i); +CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,123,1,123); +INSERT INTO t2 VALUES (2,124,2,124); +INSERT INTO t2 VALUES (3,125,3,125); +INSERT INTO t2 VALUES (4,126,4,126); +CREATE INDEX ixi ON t2 (i); +CREATE VIEW v1 AS SELECT t1.i, t2.l from t1,t2; +COMMIT; +SELECT @@global.tx_isolation; +@@global.tx_isolation +REPEATABLE-READ +EXPLAIN SELECT v1.i FROM v1 WHERE v1.i<125 FOR UPDATE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index ixi ixi 5 NULL 4 Using where; Using index +1 SIMPLE t2 index NULL PRIMARY 4 NULL 4 Using index +SELECT v1.i FROM v1 WHERE v1.i<125 FOR UPDATE; +i +123 +124 +123 +124 +123 +124 +123 +124 +connection root1; +UPDATE v1 SET i=325 where i=125; diff --git a/mysql-test/suite/row_lock/r/innodb_row_lock_view_mix_1.result b/mysql-test/suite/row_lock/r/innodb_row_lock_view_mix_1.result new file mode 100644 index 00000000000..230873b67a0 --- /dev/null +++ b/mysql-test/suite/row_lock/r/innodb_row_lock_view_mix_1.result @@ -0,0 +1,48 @@ +SELECT @@global.innodb_table_locks into @table_locks; +SET @@global.innodb_table_locks= OFF; +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1; +SET autocommit=0; +SET autocommit=0; +connection default; +CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,123,1,123); +INSERT INTO t1 VALUES (2,124,2,124); +INSERT INTO t1 VALUES (3,125,3,125); +INSERT INTO t1 VALUES (4,126,4,126); +CREATE INDEX ixi ON t1 (i); +CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,123,1,123); +INSERT INTO t2 VALUES (2,124,2,124); +INSERT INTO t2 VALUES (3,125,3,125); +INSERT INTO t2 VALUES (4,126,4,126); +CREATE INDEX ixi ON t2 (i); +CREATE VIEW v1 AS SELECT t1.i, t2.l from t1,t2; +COMMIT; +SELECT @@global.tx_isolation; +@@global.tx_isolation +REPEATABLE-READ +EXPLAIN SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i FOR UPDATE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index ixi ixi 5 NULL 4 Using where; Using index +1 SIMPLE t2 ref ixi ixi 5 test.t1.i 2 Using where; Using index +SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i FOR UPDATE; +i i +123 123 +124 124 +connection root1; +UPDATE t1,t2 SET t1.i=225,t2.i=225 WHERE t1.i=125 AND t2.i=t1.i; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 126 4 126 +connection default; +UPDATE v1 SET i=323 where i=123; diff --git a/mysql-test/suite/row_lock/r/innodb_row_lock_view_mix_2.result b/mysql-test/suite/row_lock/r/innodb_row_lock_view_mix_2.result new file mode 100644 index 00000000000..d792d573f8e --- /dev/null +++ b/mysql-test/suite/row_lock/r/innodb_row_lock_view_mix_2.result @@ -0,0 +1,40 @@ +SELECT @@global.innodb_table_locks into @table_locks; +SET @@global.innodb_table_locks= OFF; +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1; +SET autocommit=0; +SET autocommit=0; +connection default; +CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,123,1,123); +INSERT INTO t1 VALUES (2,124,2,124); +INSERT INTO t1 VALUES (3,125,3,125); +INSERT INTO t1 VALUES (4,126,4,126); +CREATE INDEX ixi ON t1 (i); +CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,123,1,123); +INSERT INTO t2 VALUES (2,124,2,124); +INSERT INTO t2 VALUES (3,125,3,125); +INSERT INTO t2 VALUES (4,126,4,126); +CREATE INDEX ixi ON t2 (i); +CREATE VIEW v1 AS SELECT t1.i, t2.l from t1,t2; +COMMIT; +SELECT @@global.tx_isolation; +@@global.tx_isolation +REPEATABLE-READ +EXPLAIN SELECT v1.i FROM v1 WHERE v1.i<125 FOR UPDATE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index ixi ixi 5 NULL 4 Using where; Using index +1 SIMPLE t2 index NULL PRIMARY 4 NULL 4 Using index +SELECT v1.i FROM v1 WHERE v1.i<125 FOR UPDATE; +i +123 +124 +123 +124 +123 +124 +123 +124 +connection root1; +UPDATE t1,t2 SET t1.i=225,t2.i=225 WHERE t1.i=125 AND t2.i=t1.i; diff --git a/mysql-test/suite/row_lock/r/innodb_row_lock_view_storedp_1.result b/mysql-test/suite/row_lock/r/innodb_row_lock_view_storedp_1.result new file mode 100644 index 00000000000..77b9a4dd964 --- /dev/null +++ b/mysql-test/suite/row_lock/r/innodb_row_lock_view_storedp_1.result @@ -0,0 +1,312 @@ +SELECT @@global.innodb_table_locks into @table_locks; +SET @@global.innodb_table_locks= OFF; +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1; +SET autocommit=0; +SET autocommit=0; +SET autocommit=0; +connection default; +CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,123,1,123); +INSERT INTO t1 VALUES (2,124,2,124); +INSERT INTO t1 VALUES (3,125,3,125); +INSERT INTO t1 VALUES (4,126,4,126); +INSERT INTO t1 VALUES (5,127,5,127); +INSERT INTO t1 VALUES (6,128,6,128); +CREATE INDEX ixi ON t1 (i); +CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,123,1,123); +INSERT INTO t2 VALUES (2,124,2,124); +INSERT INTO t2 VALUES (3,125,3,125); +INSERT INTO t2 VALUES (4,126,4,126); +INSERT INTO t2 VALUES (5,127,5,127); +INSERT INTO t2 VALUES (6,128,6,128); +CREATE INDEX ixi ON t2 (i); +CREATE VIEW v1 AS SELECT t1.i from t1; +CREATE PROCEDURE stp_t (IN p1 int, IN p2 int) MODIFIES SQL DATA +BEGIN +UPDATE t2 SET i = p2 WHERE i = p1; +UPDATE v1 SET i = p2 WHERE i = p1; +SELECT * FROM v1 ORDER BY i; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; +END; +| +COMMIT; +SELECT @@global.tx_isolation; +@@global.tx_isolation +REPEATABLE-READ +EXPLAIN SELECT t1.i FROM t1 WHERE t1.i< 125 FOR UPDATE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index ixi ixi 5 NULL 6 Using where; Using index +SELECT t1.i FROM t1 WHERE t1.i< 125 FOR UPDATE; +i +123 +124 +connection root1; +CALL stp_t (125, 225); +i +123 +124 +126 +127 +128 +225 +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 126 4 126 +5 127 5 127 +6 128 6 128 +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 126 4 126 +5 127 5 127 +6 128 6 128 +connection root2; +CALL stp_t (127, 227); +i +123 +124 +125 +126 +128 +227 +k i j l +1 123 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +5 227 5 127 +6 128 6 128 +k i j l +1 123 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +5 227 5 127 +6 128 6 128 +connection default; +CALL stp_t (123, 223); +i +124 +125 +126 +127 +128 +223 +k i j l +1 223 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +5 127 5 127 +6 128 6 128 +k i j l +1 223 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +5 127 5 127 +6 128 6 128 +connection root1; +CALL stp_t (126, 226); +i +123 +124 +127 +128 +225 +226 +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 226 4 126 +5 127 5 127 +6 128 6 128 +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 226 4 126 +5 127 5 127 +6 128 6 128 +connection root2; +CALL stp_t (128, 228); +i +123 +124 +125 +126 +227 +228 +k i j l +1 123 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +5 227 5 127 +6 228 6 128 +k i j l +1 123 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +5 227 5 127 +6 228 6 128 +connection default; +CALL stp_t (124, 224); +i +125 +126 +127 +128 +223 +224 +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +5 127 5 127 +6 128 6 128 +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +5 127 5 127 +6 128 6 128 +connection root1; +DELETE FROM t1 WHERE t1.i=226; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +5 127 5 127 +6 128 6 128 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 226 4 126 +5 127 5 127 +6 128 6 128 +connection root2; +DELETE FROM t1 WHERE t1.i=228; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +5 227 5 127 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +5 227 5 127 +6 228 6 128 +connection default; +DELETE FROM t1 WHERE t1.i=224; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +3 125 3 125 +4 126 4 126 +5 127 5 127 +6 128 6 128 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +5 127 5 127 +6 128 6 128 +COMMIT; +connection root1; +ROLLBACK; +connection root1; +COMMIT; +connection default; +SELECT * FROM v1 ORDER BY i; +i +125 +126 +127 +128 +223 +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +3 125 3 125 +4 126 4 126 +5 127 5 127 +6 128 6 128 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +5 127 5 127 +6 128 6 128 +connection root1; +SELECT * FROM v1 ORDER BY i; +i +125 +126 +127 +128 +223 +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +3 125 3 125 +4 126 4 126 +5 127 5 127 +6 128 6 128 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +5 127 5 127 +6 128 6 128 +connection root2; +SELECT * FROM v1 ORDER BY i; +i +123 +124 +125 +126 +227 +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +5 227 5 127 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +5 227 5 127 +6 228 6 128 +connection default; +DROP TABLE t1, t2; +DROP VIEW v1; +SET @@global.innodb_table_locks= @table_locks; diff --git a/mysql-test/suite/row_lock/r/innodb_row_lock_view_storedp_2.result b/mysql-test/suite/row_lock/r/innodb_row_lock_view_storedp_2.result new file mode 100644 index 00000000000..73d8a3f4bea --- /dev/null +++ b/mysql-test/suite/row_lock/r/innodb_row_lock_view_storedp_2.result @@ -0,0 +1,47 @@ +SELECT @@global.innodb_table_locks into @table_locks; +SET @@global.innodb_table_locks= OFF; +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1; +SET autocommit=0; +SET autocommit=0; +SET autocommit=0; +connection default; +CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,123,1,123); +INSERT INTO t1 VALUES (2,124,2,124); +INSERT INTO t1 VALUES (3,125,3,125); +INSERT INTO t1 VALUES (4,126,4,126); +INSERT INTO t1 VALUES (5,127,5,127); +INSERT INTO t1 VALUES (6,128,6,128); +#CREATE INDEX ixi ON t1 (i); +CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,123,1,123); +INSERT INTO t2 VALUES (2,124,2,124); +INSERT INTO t2 VALUES (3,125,3,125); +INSERT INTO t2 VALUES (4,126,4,126); +INSERT INTO t2 VALUES (5,127,5,127); +INSERT INTO t2 VALUES (6,128,6,128); +#CREATE INDEX ixi ON t2 (i); +CREATE VIEW v1 AS SELECT t1.i from t1; +CREATE PROCEDURE stp_t (IN p1 int, IN p2 int) MODIFIES SQL DATA +BEGIN +UPDATE t2 SET i = p2 WHERE i = p1; +UPDATE v1 SET i = p2 WHERE i = p1; +SELECT * FROM v1 ORDER BY i; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; +END; +| +COMMIT; +SELECT @@global.tx_isolation; +@@global.tx_isolation +REPEATABLE-READ +EXPLAIN SELECT t1.i FROM t1 WHERE t1.i< 125 FOR UPDATE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 6 Using where +SELECT t1.i FROM t1 WHERE t1.i< 125 FOR UPDATE; +i +123 +124 +connection root1; +CALL stp_t (125, 225); diff --git a/mysql-test/suite/row_lock/r/innodb_row_lock_view_trig_1.result b/mysql-test/suite/row_lock/r/innodb_row_lock_view_trig_1.result new file mode 100644 index 00000000000..90383a9489f --- /dev/null +++ b/mysql-test/suite/row_lock/r/innodb_row_lock_view_trig_1.result @@ -0,0 +1,183 @@ +SELECT @@global.innodb_table_locks into @table_locks; +SET @@global.innodb_table_locks= OFF; +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1; +SET autocommit=0; +SET autocommit=0; +connection default; +CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,123,1,123); +INSERT INTO t1 VALUES (2,124,2,124); +INSERT INTO t1 VALUES (3,125,3,125); +INSERT INTO t1 VALUES (4,126,4,126); +CREATE INDEX ixi ON t1 (i); +CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,123,1,123); +INSERT INTO t2 VALUES (2,124,2,124); +INSERT INTO t2 VALUES (3,125,3,125); +INSERT INTO t2 VALUES (4,126,4,126); +CREATE INDEX ixi ON t2 (i); +CREATE VIEW v1 AS SELECT t1.i from t1; +CREATE TRIGGER trig_t2 AFTER UPDATE ON t2 +FOR EACH ROW BEGIN +UPDATE v1 SET i = NEW.i WHERE i = OLD.i; +END; +| +COMMIT; +SELECT @@global.tx_isolation; +@@global.tx_isolation +REPEATABLE-READ +EXPLAIN SELECT t1.i FROM t1 WHERE t1.i< 125 FOR UPDATE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index ixi ixi 5 NULL 4 Using where; Using index +SELECT t1.i FROM t1 WHERE t1.i< 125 FOR UPDATE; +i +123 +124 +connection root1; +UPDATE t2 SET t2.i=225 WHERE t2.i=125; +SELECT * FROM v1 ORDER BY i; +i +123 +124 +126 +225 +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 126 4 126 +connection default; +UPDATE t2 SET t2.i=223 WHERE t2.i=123; +SELECT * FROM v1 ORDER BY i; +i +124 +125 +126 +223 +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +connection root1; +UPDATE t2 SET t2.i=226 WHERE t2.i=126; +SELECT * FROM v1 ORDER BY i; +i +123 +124 +225 +226 +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 226 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 226 4 126 +connection default; +UPDATE t2 SET t2.i=224 WHERE t2.i=124; +SELECT * FROM v1 ORDER BY i; +i +125 +126 +223 +224 +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +connection root1; +DELETE FROM t1 WHERE t1.i=226; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 226 4 126 +connection default; +DELETE FROM t1 WHERE t1.i=224; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +COMMIT; +connection root1; +ROLLBACK; +connection default; +SELECT * FROM v1 ORDER BY i; +i +125 +126 +223 +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +connection root1; +SELECT * FROM v1 ORDER BY i; +i +125 +126 +223 +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +connection default; +DROP TABLE t1, t2; +DROP VIEW v1; +SET @@global.innodb_table_locks= @table_locks; diff --git a/mysql-test/suite/row_lock/r/innodb_row_lock_view_trig_2.result b/mysql-test/suite/row_lock/r/innodb_row_lock_view_trig_2.result new file mode 100644 index 00000000000..55793558b21 --- /dev/null +++ b/mysql-test/suite/row_lock/r/innodb_row_lock_view_trig_2.result @@ -0,0 +1,38 @@ +SELECT @@global.innodb_table_locks into @table_locks; +SET @@global.innodb_table_locks= OFF; +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1; +SET autocommit=0; +SET autocommit=0; +connection default; +CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,123,1,123); +INSERT INTO t1 VALUES (2,124,2,124); +INSERT INTO t1 VALUES (3,125,3,125); +INSERT INTO t1 VALUES (4,126,4,126); +#CREATE INDEX ixi ON t1 (i); +CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,123,1,123); +INSERT INTO t2 VALUES (2,124,2,124); +INSERT INTO t2 VALUES (3,125,3,125); +INSERT INTO t2 VALUES (4,126,4,126); +#CREATE INDEX ixi ON t2 (i); +CREATE VIEW v1 AS SELECT t1.i from t1; +CREATE TRIGGER trig_t2 AFTER UPDATE ON t2 +FOR EACH ROW BEGIN +UPDATE v1 SET i = NEW.i WHERE i = OLD.i; +END; +| +COMMIT; +SELECT @@global.tx_isolation; +@@global.tx_isolation +REPEATABLE-READ +EXPLAIN SELECT t1.i FROM t1 WHERE t1.i< 125 FOR UPDATE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where +SELECT t1.i FROM t1 WHERE t1.i< 125 FOR UPDATE; +i +123 +124 +connection root1; +UPDATE t2 SET t2.i=225 WHERE t2.i=125; diff --git a/mysql-test/suite/row_lock/r/ndb_row_lock_1.result b/mysql-test/suite/row_lock/r/ndb_row_lock_1.result new file mode 100644 index 00000000000..248c7d5ea1f --- /dev/null +++ b/mysql-test/suite/row_lock/r/ndb_row_lock_1.result @@ -0,0 +1,139 @@ +DROP TABLE IF EXISTS t1, t2; +SET autocommit=0; +SET autocommit=0; +connection default; +CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=NDB; +INSERT INTO t1 VALUES (1,123,1,123); +INSERT INTO t1 VALUES (2,124,2,124); +INSERT INTO t1 VALUES (3,125,3,125); +INSERT INTO t1 VALUES (4,126,4,126); +CREATE INDEX ixi ON t1 (i); +CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=NDB; +INSERT INTO t2 VALUES (1,123,1,123); +INSERT INTO t2 VALUES (2,124,2,124); +INSERT INTO t2 VALUES (3,125,3,125); +INSERT INTO t2 VALUES (4,126,4,126); +CREATE INDEX ixi ON t2 (i); +COMMIT; +SELECT @@global.tx_isolation; +@@global.tx_isolation +REPEATABLE-READ +EXPLAIN SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i FOR UPDATE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range ixi ixi 5 NULL 10 Using where +1 SIMPLE t2 ref ixi ixi 5 test.t1.i 1 Using where +SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i FOR UPDATE; +i i +123 123 +124 124 +connection root1; +UPDATE t1,t2 SET t1.i=225,t2.i=225 WHERE t1.i=125 AND t2.i=t1.i; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 126 4 126 +connection default; +UPDATE t1,t2 SET t1.i=223,t2.i=223 WHERE t1.i=123 AND t2.i=t1.i; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +connection root1; +UPDATE t1,t2 SET t1.i=226,t2.i=226 WHERE t1.i=126 AND t2.i=t1.i; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 226 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 226 4 126 +connection default; +UPDATE t1,t2 SET t1.i=224,t2.i=224 WHERE t1.i=124 AND t2.i=t1.i; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +connection root1; +DELETE FROM t1 WHERE t1.i=226; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 226 4 126 +connection default; +DELETE FROM t1 WHERE t1.i=224; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +COMMIT; +connection root1; +ROLLBACK; +connection default; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +connection root1; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +connection default; +DROP TABLE t1, t2; diff --git a/mysql-test/suite/row_lock/r/ndb_row_lock_2.result b/mysql-test/suite/row_lock/r/ndb_row_lock_2.result new file mode 100644 index 00000000000..109d99dd036 --- /dev/null +++ b/mysql-test/suite/row_lock/r/ndb_row_lock_2.result @@ -0,0 +1,31 @@ +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1; +SET autocommit=0; +SET autocommit=0; +connection default; +CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=NDB; +INSERT INTO t1 VALUES (1,123,1,123); +INSERT INTO t1 VALUES (2,124,2,124); +INSERT INTO t1 VALUES (3,125,3,125); +INSERT INTO t1 VALUES (4,126,4,126); +#CREATE INDEX ixi ON t1 (i); +CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=NDB; +INSERT INTO t2 VALUES (1,123,1,123); +INSERT INTO t2 VALUES (2,124,2,124); +INSERT INTO t2 VALUES (3,125,3,125); +INSERT INTO t2 VALUES (4,126,4,126); +#CREATE INDEX ixi ON t2 (i); +COMMIT; +SELECT @@global.tx_isolation; +@@global.tx_isolation +REPEATABLE-READ +EXPLAIN SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i FOR UPDATE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 4 Using where +SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i FOR UPDATE; +i i +123 123 +124 124 +connection root1; +UPDATE t1,t2 SET t1.i=225,t2.i=225 WHERE t1.i=125 AND t2.i=t1.i; diff --git a/mysql-test/suite/row_lock/r/ndb_row_lock_3.result b/mysql-test/suite/row_lock/r/ndb_row_lock_3.result new file mode 100644 index 00000000000..c936ea209ff --- /dev/null +++ b/mysql-test/suite/row_lock/r/ndb_row_lock_3.result @@ -0,0 +1,30 @@ +DROP TABLE IF EXISTS t1, t2; +SET autocommit=0; +SET autocommit=0; +connection default; +CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=NDB; +INSERT INTO t1 VALUES (1,123,1,123); +INSERT INTO t1 VALUES (2,124,2,124); +INSERT INTO t1 VALUES (3,125,3,125); +INSERT INTO t1 VALUES (4,126,4,126); +#CREATE INDEX ixi ON t1 (i); +CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=NDB; +INSERT INTO t2 VALUES (1,123,1,123); +INSERT INTO t2 VALUES (2,124,2,124); +INSERT INTO t2 VALUES (3,125,3,125); +INSERT INTO t2 VALUES (4,126,4,126); +#CREATE INDEX ixi ON t2 (i); +COMMIT; +SELECT @@global.tx_isolation; +@@global.tx_isolation +REPEATABLE-READ +EXPLAIN SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i LOCK IN SHARE MODE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 4 Using where +SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i LOCK IN SHARE MODE; +i i +123 123 +124 124 +connection root1; +UPDATE t1,t2 SET t1.i=225,t2.i=225 WHERE t1.i=125 AND t2.i=t1.i; diff --git a/mysql-test/suite/row_lock/r/ndb_row_lock_4.result b/mysql-test/suite/row_lock/r/ndb_row_lock_4.result new file mode 100644 index 00000000000..875c783bd81 --- /dev/null +++ b/mysql-test/suite/row_lock/r/ndb_row_lock_4.result @@ -0,0 +1,139 @@ +DROP TABLE IF EXISTS t1, t2; +SET autocommit=0; +SET autocommit=0; +connection default; +CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=NDB; +INSERT INTO t1 VALUES (1,123,1,123); +INSERT INTO t1 VALUES (2,124,2,124); +INSERT INTO t1 VALUES (3,125,3,125); +INSERT INTO t1 VALUES (4,126,4,126); +CREATE INDEX ixi ON t1 (i); +CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=NDB; +INSERT INTO t2 VALUES (1,123,1,123); +INSERT INTO t2 VALUES (2,124,2,124); +INSERT INTO t2 VALUES (3,125,3,125); +INSERT INTO t2 VALUES (4,126,4,126); +CREATE INDEX ixi ON t2 (i); +COMMIT; +SELECT @@global.tx_isolation; +@@global.tx_isolation +REPEATABLE-READ +EXPLAIN SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i LOCK IN SHARE MODE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range ixi ixi 5 NULL 10 Using where +1 SIMPLE t2 ref ixi ixi 5 test.t1.i 1 Using where +SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i LOCK IN SHARE MODE; +i i +123 123 +124 124 +connection root1; +UPDATE t1,t2 SET t1.i=225,t2.i=225 WHERE t1.i=125 AND t2.i=t1.i; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 126 4 126 +connection default; +UPDATE t1,t2 SET t1.i=223,t2.i=223 WHERE t1.i=123 AND t2.i=t1.i; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +connection root1; +UPDATE t1,t2 SET t1.i=226,t2.i=226 WHERE t1.i=126 AND t2.i=t1.i; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 226 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 226 4 126 +connection default; +UPDATE t1,t2 SET t1.i=224,t2.i=224 WHERE t1.i=124 AND t2.i=t1.i; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +connection root1; +DELETE FROM t1 WHERE t1.i=226; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 226 4 126 +connection default; +DELETE FROM t1 WHERE t1.i=224; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +COMMIT; +connection root1; +ROLLBACK; +connection default; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +connection root1; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +connection default; +DROP TABLE t1, t2; diff --git a/mysql-test/suite/row_lock/r/ndb_row_lock_5.result b/mysql-test/suite/row_lock/r/ndb_row_lock_5.result new file mode 100644 index 00000000000..0d94f8abf72 --- /dev/null +++ b/mysql-test/suite/row_lock/r/ndb_row_lock_5.result @@ -0,0 +1,30 @@ +DROP TABLE IF EXISTS t1, t2; +SET autocommit=0; +SET autocommit=0; +connection default; +CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=NDB; +INSERT INTO t1 VALUES (1,123,1,123); +INSERT INTO t1 VALUES (2,124,2,124); +INSERT INTO t1 VALUES (3,125,3,125); +INSERT INTO t1 VALUES (4,126,4,126); +CREATE INDEX ixi ON t1 (i); +CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=NDB; +INSERT INTO t2 VALUES (1,123,1,123); +INSERT INTO t2 VALUES (2,124,2,124); +INSERT INTO t2 VALUES (3,125,3,125); +INSERT INTO t2 VALUES (4,126,4,126); +CREATE INDEX ixi ON t2 (i); +COMMIT; +SELECT @@global.tx_isolation; +@@global.tx_isolation +REPEATABLE-READ +EXPLAIN SELECT t1.i,t2.i FROM t1 ignore index (ixi),t2 IGNORE INDEX (ixi) WHERE t1.i<125 AND t2.i=t1.i LOCK IN SHARE MODE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 4 Using where +SELECT t1.i,t2.i FROM t1 ignore index (ixi),t2 IGNORE INDEX (ixi) WHERE t1.i<125 AND t2.i=t1.i LOCK IN SHARE MODE; +i i +123 123 +124 124 +connection root1; +UPDATE t1,t2 SET t1.i=225,t2.i=225 WHERE t1.i=125 AND t2.i=t1.i; diff --git a/mysql-test/suite/row_lock/r/ndb_row_lock_big_tab.result b/mysql-test/suite/row_lock/r/ndb_row_lock_big_tab.result new file mode 100644 index 00000000000..94b67c63d94 --- /dev/null +++ b/mysql-test/suite/row_lock/r/ndb_row_lock_big_tab.result @@ -0,0 +1,177 @@ +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1; +SET autocommit=0; +SET autocommit=0; +connection default; +CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=NDB; +CREATE INDEX ixi ON t1 (i); +CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=NDB; +CREATE INDEX ixi ON t2 (i); +CREATE PROCEDURE fill_t1 (IN upb int) +BEGIN +DECLARE cnt int DEFAULT 0; +WHILE cnt < upb DO +INSERT INTO t1 VALUES (cnt, cnt+100, cnt, cnt+100); +SET cnt= cnt+1; +END WHILE; +END; +| +CREATE FUNCTION half_t1() RETURNS int +BEGIN +DECLARE res int DEFAULT 0; +SELECT count(*)/2 INTO res FROM t1; +RETURN res; +END; +| +CREATE PROCEDURE fill_t2 (IN upb int) +BEGIN +DECLARE cnt int DEFAULT 0; +WHILE cnt < upb DO +INSERT INTO t2 VALUES (cnt, cnt+100, cnt, cnt+100); +SET cnt= cnt+1; +END WHILE; +END; +| +CREATE FUNCTION half_t2() RETURNS int +BEGIN +DECLARE res int DEFAULT 0; +SELECT count(*)/2 INTO res FROM t2; +RETURN res; +END; +| +CALL fill_t1 (10); +CALL fill_t2 (10); +COMMIT; +SELECT @@global.tx_isolation; +@@global.tx_isolation +REPEATABLE-READ +EXPLAIN SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i < half_t1() AND t2.i=t1.i LOCK IN SHARE MODE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range ixi ixi 5 NULL 10 Using where +1 SIMPLE t2 ref ixi ixi 5 test.t1.i 1 Using where +SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i < half_t1() AND t2.i=t1.i LOCK IN SHARE MODE; +i i +connection root1; +SELECT k from t1 WHERE k < half_t1(); +k +0 +3 +1 +2 +4 +SELECT k from t1 WHERE k >= half_t1(); +k +6 +7 +9 +5 +8 +UPDATE t1,t2 SET t1.i=1111,t2.i=2222 WHERE t1.k < half_t1() AND t2.i=t1.i; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +0 1111 0 100 +1 1111 1 101 +2 1111 2 102 +3 1111 3 103 +4 1111 4 104 +5 105 5 105 +6 106 6 106 +7 107 7 107 +8 108 8 108 +9 109 9 109 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +0 2222 0 100 +1 2222 1 101 +2 2222 2 102 +3 2222 3 103 +4 2222 4 104 +5 105 5 105 +6 106 6 106 +7 107 7 107 +8 108 8 108 +9 109 9 109 +connection default; +UPDATE t1,t2 SET t1.i=3333,t2.i=4444 WHERE t1.k >= half_t1() AND t2.i=t1.i; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +0 100 0 100 +1 101 1 101 +2 102 2 102 +3 103 3 103 +4 104 4 104 +5 3333 5 105 +6 3333 6 106 +7 3333 7 107 +8 3333 8 108 +9 3333 9 109 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +0 100 0 100 +1 101 1 101 +2 102 2 102 +3 103 3 103 +4 104 4 104 +5 4444 5 105 +6 4444 6 106 +7 4444 7 107 +8 4444 8 108 +9 4444 9 109 +COMMIT; +connection root1; +ROLLBACK; +connection default; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +0 100 0 100 +1 101 1 101 +2 102 2 102 +3 103 3 103 +4 104 4 104 +5 3333 5 105 +6 3333 6 106 +7 3333 7 107 +8 3333 8 108 +9 3333 9 109 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +0 100 0 100 +1 101 1 101 +2 102 2 102 +3 103 3 103 +4 104 4 104 +5 4444 5 105 +6 4444 6 106 +7 4444 7 107 +8 4444 8 108 +9 4444 9 109 +connection root1; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +0 100 0 100 +1 101 1 101 +2 102 2 102 +3 103 3 103 +4 104 4 104 +5 3333 5 105 +6 3333 6 106 +7 3333 7 107 +8 3333 8 108 +9 3333 9 109 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +0 100 0 100 +1 101 1 101 +2 102 2 102 +3 103 3 103 +4 104 4 104 +5 4444 5 105 +6 4444 6 106 +7 4444 7 107 +8 4444 8 108 +9 4444 9 109 +connection default; +DROP VIEW IF EXISTS v1; +Warnings: +Note 1051 Unknown table 'test.v1' +DROP TABLE t1, t2; diff --git a/mysql-test/suite/row_lock/r/ndb_row_lock_big_tab_1.result b/mysql-test/suite/row_lock/r/ndb_row_lock_big_tab_1.result new file mode 100644 index 00000000000..9803895e1a7 --- /dev/null +++ b/mysql-test/suite/row_lock/r/ndb_row_lock_big_tab_1.result @@ -0,0 +1,357 @@ +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1; +SET autocommit=0; +SET autocommit=0; +connection default; +CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=NDB; +CREATE INDEX ixi ON t1 (i); +CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=NDB; +CREATE INDEX ixi ON t2 (i); +CREATE PROCEDURE fill_t1 (IN upb int) +BEGIN +DECLARE cnt int DEFAULT 0; +WHILE cnt < upb DO +INSERT INTO t1 VALUES (cnt, cnt+100, cnt, cnt+100); +SET cnt= cnt+1; +END WHILE; +END; +| +CREATE FUNCTION half_t1() RETURNS int +BEGIN +DECLARE res int DEFAULT 0; +SELECT MOD(k,2) INTO res FROM t1; +RETURN res; +END; +| +CREATE PROCEDURE fill_t2 (IN upb int) +BEGIN +DECLARE cnt int DEFAULT 0; +WHILE cnt < upb DO +INSERT INTO t2 VALUES (cnt, cnt+100, cnt, cnt+100); +SET cnt= cnt+1; +END WHILE; +END; +| +CREATE FUNCTION half_t2() RETURNS int +BEGIN +DECLARE res int DEFAULT 0; +SELECT MOD(k,2) INTO res FROM t2; +RETURN res; +END; +| +CALL fill_t1 (200); +CALL fill_t2 (200); +COMMIT; +SELECT @@global.tx_isolation; +@@global.tx_isolation +REPEATABLE-READ +EXPLAIN SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i < t1.k % 2 = 0 AND t2.k=t1.k LOCK IN SHARE MODE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 200 Using where +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.k 1 +SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i < t1.k % 2 = 0 AND t2.k=t1.k LOCK IN SHARE MODE; +i i +135 135 +119 119 +211 211 +184 184 +232 232 +105 105 +188 188 +216 216 +255 255 +154 154 +197 197 +279 279 +218 218 +127 127 +203 203 +281 281 +194 194 +161 161 +276 276 +122 122 +139 139 +183 183 +114 114 +247 247 +144 144 +148 148 +174 174 +267 267 +142 142 +168 168 +226 226 +258 258 +231 231 +146 146 +253 253 +189 189 +230 230 +290 290 +178 178 +158 158 +130 130 +214 214 +133 133 +229 229 +294 294 +295 295 +108 108 +112 112 +297 297 +151 151 +251 251 +270 270 +291 291 +159 159 +132 132 +121 121 +244 244 +272 272 +293 293 +186 186 +111 111 +166 166 +201 201 +175 175 +180 180 +209 209 +192 192 +246 246 +195 195 +107 107 +233 233 +239 239 +103 103 +109 109 +128 128 +266 266 +143 143 +160 160 +187 187 +243 243 +273 273 +259 259 +110 110 +176 176 +141 141 +170 170 +215 215 +191 191 +200 200 +271 271 +162 162 +260 260 +106 106 +150 150 +126 126 +147 147 +155 155 +193 193 +207 207 +287 287 +235 235 +252 252 +129 129 +205 205 +268 268 +278 278 +116 116 +137 137 +199 199 +217 217 +234 234 +190 190 +236 236 +257 257 +100 100 +210 210 +212 212 +264 264 +221 221 +241 241 +256 256 +262 262 +265 265 +269 269 +277 277 +173 173 +177 177 +208 208 +219 219 +285 285 +101 101 +164 164 +113 113 +125 125 +202 202 +140 140 +156 156 +282 282 +181 181 +206 206 +299 299 +102 102 +145 145 +227 227 +196 196 +138 138 +198 198 +204 204 +237 237 +171 171 +284 284 +263 263 +292 292 +104 104 +149 149 +250 250 +296 296 +228 228 +280 280 +242 242 +248 248 +185 185 +220 220 +245 245 +275 275 +118 118 +120 120 +152 152 +153 153 +157 157 +182 182 +179 179 +254 254 +288 288 +172 172 +283 283 +286 286 +115 115 +238 238 +289 289 +131 131 +223 223 +134 134 +136 136 +222 222 +225 225 +261 261 +274 274 +123 123 +163 163 +224 224 +117 117 +298 298 +169 169 +124 124 +167 167 +240 240 +249 249 +165 165 +213 213 +connection root1; +SELECT t1.i,t2.i FROM t1,t2 WHERE t1.k % 2= 1 AND t1.k = t2.k LOCK IN SHARE MODE; +i i +209 209 +195 195 +107 107 +233 233 +239 239 +103 103 +109 109 +143 143 +187 187 +243 243 +273 273 +259 259 +141 141 +215 215 +191 191 +271 271 +147 147 +155 155 +193 193 +207 207 +287 287 +235 235 +129 129 +205 205 +137 137 +199 199 +217 217 +257 257 +221 221 +241 241 +265 265 +269 269 +277 277 +173 173 +177 177 +135 135 +119 119 +211 211 +105 105 +255 255 +197 197 +279 279 +127 127 +203 203 +281 281 +161 161 +139 139 +183 183 +247 247 +267 267 +231 231 +253 253 +189 189 +133 133 +229 229 +295 295 +297 297 +151 151 +251 251 +291 291 +159 159 +121 121 +293 293 +111 111 +201 201 +175 175 +185 185 +245 245 +275 275 +153 153 +157 157 +179 179 +283 283 +115 115 +289 289 +131 131 +223 223 +225 225 +261 261 +123 123 +163 163 +117 117 +169 169 +167 167 +249 249 +165 165 +213 213 +219 219 +285 285 +101 101 +113 113 +125 125 +181 181 +299 299 +145 145 +227 227 +237 237 +171 171 +263 263 +149 149 +UPDATE t1,t2 SET t1.i=1111,t2.i=2222 WHERE t1.k % 2 = 1 AND t1.k = t2.k; diff --git a/mysql-test/suite/row_lock/r/ndb_row_lock_big_tab_2.result b/mysql-test/suite/row_lock/r/ndb_row_lock_big_tab_2.result new file mode 100644 index 00000000000..adb89b03480 --- /dev/null +++ b/mysql-test/suite/row_lock/r/ndb_row_lock_big_tab_2.result @@ -0,0 +1,255 @@ +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1; +SET autocommit=0; +SET autocommit=0; +connection default; +CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=NDB; +CREATE INDEX ixi ON t1 (i); +CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=NDB; +CREATE INDEX ixi ON t2 (i); +CREATE PROCEDURE fill_t1 (IN upb int) +BEGIN +DECLARE cnt int DEFAULT 0; +WHILE cnt < upb DO +INSERT INTO t1 VALUES (cnt, cnt+100, cnt, cnt+100); +SET cnt= cnt+1; +END WHILE; +END; +| +CREATE FUNCTION half_t1() RETURNS int +BEGIN +DECLARE res int DEFAULT 0; +SELECT MOD(k,2) INTO res FROM t1; +RETURN res; +END; +| +CREATE PROCEDURE fill_t2 (IN upb int) +BEGIN +DECLARE cnt int DEFAULT 0; +WHILE cnt < upb DO +INSERT INTO t2 VALUES (cnt, cnt+100, cnt, cnt+100); +SET cnt= cnt+1; +END WHILE; +END; +| +CREATE FUNCTION half_t2() RETURNS int +BEGIN +DECLARE res int DEFAULT 0; +SELECT MOD(k,2) INTO res FROM t2; +RETURN res; +END; +| +CALL fill_t1 (200); +CALL fill_t2 (200); +COMMIT; +SELECT @@global.tx_isolation; +@@global.tx_isolation +REPEATABLE-READ +EXPLAIN SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i < t1.k % 2 = 0 AND t2.k=t1.k LOCK IN SHARE MODE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 200 Using where +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.k 1 +SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i < t1.k % 2 = 0 AND t2.k=t1.k LOCK IN SHARE MODE; +i i +135 135 +119 119 +211 211 +184 184 +232 232 +105 105 +188 188 +216 216 +255 255 +154 154 +197 197 +279 279 +218 218 +127 127 +203 203 +281 281 +194 194 +161 161 +276 276 +122 122 +139 139 +183 183 +114 114 +247 247 +144 144 +148 148 +174 174 +267 267 +142 142 +168 168 +226 226 +258 258 +231 231 +146 146 +253 253 +189 189 +230 230 +290 290 +178 178 +158 158 +130 130 +214 214 +133 133 +229 229 +294 294 +295 295 +108 108 +112 112 +297 297 +151 151 +251 251 +270 270 +291 291 +159 159 +132 132 +121 121 +244 244 +272 272 +293 293 +186 186 +111 111 +166 166 +201 201 +175 175 +180 180 +209 209 +192 192 +246 246 +195 195 +107 107 +233 233 +239 239 +103 103 +109 109 +128 128 +266 266 +143 143 +160 160 +187 187 +243 243 +273 273 +259 259 +110 110 +176 176 +141 141 +170 170 +215 215 +191 191 +200 200 +271 271 +162 162 +260 260 +106 106 +150 150 +126 126 +147 147 +155 155 +193 193 +207 207 +287 287 +235 235 +252 252 +129 129 +205 205 +268 268 +278 278 +116 116 +137 137 +199 199 +217 217 +234 234 +190 190 +236 236 +257 257 +100 100 +210 210 +212 212 +264 264 +221 221 +241 241 +256 256 +262 262 +265 265 +269 269 +277 277 +173 173 +177 177 +208 208 +219 219 +285 285 +101 101 +164 164 +113 113 +125 125 +202 202 +140 140 +156 156 +282 282 +181 181 +206 206 +299 299 +102 102 +145 145 +227 227 +196 196 +138 138 +198 198 +204 204 +237 237 +171 171 +284 284 +263 263 +292 292 +104 104 +149 149 +250 250 +296 296 +228 228 +280 280 +242 242 +248 248 +185 185 +220 220 +245 245 +275 275 +118 118 +120 120 +152 152 +153 153 +157 157 +182 182 +179 179 +254 254 +288 288 +172 172 +283 283 +286 286 +115 115 +238 238 +289 289 +131 131 +223 223 +134 134 +136 136 +222 222 +225 225 +261 261 +274 274 +123 123 +163 163 +224 224 +117 117 +298 298 +169 169 +124 124 +167 167 +240 240 +249 249 +165 165 +213 213 +connection root1; +DELETE FROM t1 WHERE t1.k % 2 = 1; diff --git a/mysql-test/suite/row_lock/r/ndb_row_lock_trig_1.result b/mysql-test/suite/row_lock/r/ndb_row_lock_trig_1.result new file mode 100644 index 00000000000..eb69fd2e306 --- /dev/null +++ b/mysql-test/suite/row_lock/r/ndb_row_lock_trig_1.result @@ -0,0 +1,148 @@ +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1; +SET autocommit=0; +SET autocommit=0; +connection default; +CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=NDB; +INSERT INTO t1 VALUES (1,123,1,123); +INSERT INTO t1 VALUES (2,124,2,124); +INSERT INTO t1 VALUES (3,125,3,125); +INSERT INTO t1 VALUES (4,126,4,126); +CREATE INDEX ixi ON t1 (i); +CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=NDB; +INSERT INTO t2 VALUES (1,123,1,123); +INSERT INTO t2 VALUES (2,124,2,124); +INSERT INTO t2 VALUES (3,125,3,125); +INSERT INTO t2 VALUES (4,126,4,126); +CREATE INDEX ixi ON t2 (i); +CREATE TRIGGER trig_t2 AFTER UPDATE ON t2 +FOR EACH ROW BEGIN +UPDATE t1 SET l = NEW.i WHERE i = OLD.i; +END; +| +COMMIT; +SELECT @@global.tx_isolation; +@@global.tx_isolation +REPEATABLE-READ +EXPLAIN SELECT t1.i FROM t1 WHERE t1.i< 125 FOR UPDATE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range ixi ixi 5 NULL 10 Using where +SELECT t1.i FROM t1 WHERE t1.i< 125 FOR UPDATE; +i +123 +124 +connection root1; +UPDATE t2 SET t2.i=225 WHERE t2.i=125; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 125 3 225 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 126 4 126 +connection default; +UPDATE t2 SET t2.i=223 WHERE t2.i=123; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 223 +2 124 2 124 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +connection root1; +UPDATE t2 SET t2.i=226 WHERE t2.i=126; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 125 3 225 +4 126 4 226 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 226 4 126 +connection default; +UPDATE t2 SET t2.i=224 WHERE t2.i=124; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 223 +2 124 2 224 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +connection root1; +DELETE FROM t1 WHERE t1.i=226; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 125 3 225 +4 126 4 226 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 226 4 126 +connection default; +DELETE FROM t1 WHERE t1.i=224; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 223 +2 124 2 224 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +COMMIT; +connection root1; +ROLLBACK; +connection default; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 223 +2 124 2 224 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +connection root1; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 223 +2 124 2 224 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +connection default; +DROP TABLE t1, t2; diff --git a/mysql-test/suite/row_lock/r/ndb_row_lock_trig_2.result b/mysql-test/suite/row_lock/r/ndb_row_lock_trig_2.result new file mode 100644 index 00000000000..bedb75da93a --- /dev/null +++ b/mysql-test/suite/row_lock/r/ndb_row_lock_trig_2.result @@ -0,0 +1,35 @@ +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1; +SET autocommit=0; +SET autocommit=0; +connection default; +CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=NDB; +INSERT INTO t1 VALUES (1,123,1,123); +INSERT INTO t1 VALUES (2,124,2,124); +INSERT INTO t1 VALUES (3,125,3,125); +INSERT INTO t1 VALUES (4,126,4,126); +#CREATE INDEX ixi ON t1 (i); +CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=NDB; +INSERT INTO t2 VALUES (1,123,1,123); +INSERT INTO t2 VALUES (2,124,2,124); +INSERT INTO t2 VALUES (3,125,3,125); +INSERT INTO t2 VALUES (4,126,4,126); +#CREATE INDEX ixi ON t2 (i); +CREATE TRIGGER trig_t2 AFTER UPDATE ON t2 +FOR EACH ROW BEGIN +UPDATE t1 SET l = NEW.i WHERE i = OLD.i; +END; +| +COMMIT; +SELECT @@global.tx_isolation; +@@global.tx_isolation +REPEATABLE-READ +EXPLAIN SELECT t1.i FROM t1 WHERE t1.i< 125 FOR UPDATE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where +SELECT t1.i FROM t1 WHERE t1.i< 125 FOR UPDATE; +i +123 +124 +connection root1; +UPDATE t2 SET t2.i=225 WHERE t2.i=125; diff --git a/mysql-test/suite/row_lock/r/ndb_row_lock_view_1.result b/mysql-test/suite/row_lock/r/ndb_row_lock_view_1.result new file mode 100644 index 00000000000..279f2626c73 --- /dev/null +++ b/mysql-test/suite/row_lock/r/ndb_row_lock_view_1.result @@ -0,0 +1,194 @@ +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1; +SET autocommit=0; +SET autocommit=0; +connection default; +CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=NDB; +INSERT INTO t1 VALUES (1,123,1,123); +INSERT INTO t1 VALUES (2,124,2,124); +INSERT INTO t1 VALUES (3,125,3,125); +INSERT INTO t1 VALUES (4,126,4,126); +CREATE INDEX ixi ON t1 (i); +CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=NDB; +INSERT INTO t2 VALUES (1,123,1,123); +INSERT INTO t2 VALUES (2,124,2,124); +INSERT INTO t2 VALUES (3,125,3,125); +INSERT INTO t2 VALUES (4,126,4,126); +CREATE INDEX ixi ON t2 (i); +CREATE VIEW v1 AS SELECT t1.i, t2.l from t1,t2; +COMMIT; +SELECT @@global.tx_isolation; +@@global.tx_isolation +REPEATABLE-READ +EXPLAIN SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i FOR UPDATE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range ixi ixi 5 NULL 10 Using where +1 SIMPLE t2 ref ixi ixi 5 test.t1.i 1 Using where +SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i FOR UPDATE; +i i +123 123 +124 124 +connection root1; +UPDATE v1 SET i=325 where i=125; +SELECT * FROM v1 ORDER BY i,l; +i l +123 123 +123 124 +123 125 +123 126 +124 123 +124 124 +124 125 +124 126 +126 123 +126 124 +126 125 +126 126 +325 123 +325 124 +325 125 +325 126 +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 325 3 125 +4 126 4 126 +connection default; +UPDATE v1 SET i=323 where i=123; +SELECT * FROM v1 ORDER BY i,l; +i l +124 123 +124 124 +124 125 +124 126 +125 123 +125 124 +125 125 +125 126 +126 123 +126 124 +126 125 +126 126 +323 123 +323 124 +323 125 +323 126 +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 323 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +connection root1; +UPDATE v1 SET i=326 where i=126; +SELECT * FROM v1 ORDER BY i,l; +i l +123 123 +123 124 +123 125 +123 126 +124 123 +124 124 +124 125 +124 126 +325 123 +325 124 +325 125 +325 126 +326 123 +326 124 +326 125 +326 126 +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 325 3 125 +4 326 4 126 +connection default; +UPDATE v1 SET i=324 where i=124; +SELECT * FROM v1 ORDER BY i,l; +i l +125 123 +125 124 +125 125 +125 126 +126 123 +126 124 +126 125 +126 126 +323 123 +323 124 +323 125 +323 126 +324 123 +324 124 +324 125 +324 126 +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 323 1 123 +2 324 2 124 +3 125 3 125 +4 126 4 126 +connection root1; +DELETE FROM t1 WHERE t1.i=226; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 325 3 125 +4 326 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +connection default; +DELETE FROM t1 WHERE t1.i=224; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 323 1 123 +2 324 2 124 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +COMMIT; +connection root1; +ROLLBACK; +connection default; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 323 1 123 +2 324 2 124 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +connection root1; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 323 1 123 +2 324 2 124 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +connection default; +DROP VIEW IF EXISTS v1; +DROP TABLE t1, t2; diff --git a/mysql-test/suite/row_lock/r/ndb_row_lock_view_2.result b/mysql-test/suite/row_lock/r/ndb_row_lock_view_2.result new file mode 100644 index 00000000000..9e74e93b0cc --- /dev/null +++ b/mysql-test/suite/row_lock/r/ndb_row_lock_view_2.result @@ -0,0 +1,200 @@ +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1; +SET autocommit=0; +SET autocommit=0; +connection default; +CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=NDB; +INSERT INTO t1 VALUES (1,123,1,123); +INSERT INTO t1 VALUES (2,124,2,124); +INSERT INTO t1 VALUES (3,125,3,125); +INSERT INTO t1 VALUES (4,126,4,126); +CREATE INDEX ixi ON t1 (i); +CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=NDB; +INSERT INTO t2 VALUES (1,123,1,123); +INSERT INTO t2 VALUES (2,124,2,124); +INSERT INTO t2 VALUES (3,125,3,125); +INSERT INTO t2 VALUES (4,126,4,126); +CREATE INDEX ixi ON t2 (i); +CREATE VIEW v1 AS SELECT t1.i, t2.l from t1,t2; +COMMIT; +SELECT @@global.tx_isolation; +@@global.tx_isolation +REPEATABLE-READ +EXPLAIN SELECT v1.i FROM v1 WHERE v1.i<125 FOR UPDATE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range ixi ixi 5 NULL 10 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 4 +SELECT v1.i FROM v1 WHERE v1.i<125 FOR UPDATE; +i +123 +124 +123 +124 +123 +124 +123 +124 +connection root1; +UPDATE v1 SET i=325 where i=125; +SELECT * FROM v1 ORDER BY i,l; +i l +123 123 +123 124 +123 125 +123 126 +124 123 +124 124 +124 125 +124 126 +126 123 +126 124 +126 125 +126 126 +325 123 +325 124 +325 125 +325 126 +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 325 3 125 +4 126 4 126 +connection default; +UPDATE v1 SET i=323 where i=123; +SELECT * FROM v1 ORDER BY i,l; +i l +124 123 +124 124 +124 125 +124 126 +125 123 +125 124 +125 125 +125 126 +126 123 +126 124 +126 125 +126 126 +323 123 +323 124 +323 125 +323 126 +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 323 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +connection root1; +UPDATE v1 SET i=326 where i=126; +SELECT * FROM v1 ORDER BY i,l; +i l +123 123 +123 124 +123 125 +123 126 +124 123 +124 124 +124 125 +124 126 +325 123 +325 124 +325 125 +325 126 +326 123 +326 124 +326 125 +326 126 +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 325 3 125 +4 326 4 126 +connection default; +UPDATE v1 SET i=324 where i=124; +SELECT * FROM v1 ORDER BY i,l; +i l +125 123 +125 124 +125 125 +125 126 +126 123 +126 124 +126 125 +126 126 +323 123 +323 124 +323 125 +323 126 +324 123 +324 124 +324 125 +324 126 +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 323 1 123 +2 324 2 124 +3 125 3 125 +4 126 4 126 +connection root1; +DELETE FROM t1 WHERE t1.i=226; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 325 3 125 +4 326 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +connection default; +DELETE FROM t1 WHERE t1.i=224; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 323 1 123 +2 324 2 124 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +COMMIT; +connection root1; +ROLLBACK; +connection default; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 323 1 123 +2 324 2 124 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +connection root1; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 323 1 123 +2 324 2 124 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +connection default; +DROP VIEW IF EXISTS v1; +DROP TABLE t1, t2; diff --git a/mysql-test/suite/row_lock/r/ndb_row_lock_view_mix_1.result b/mysql-test/suite/row_lock/r/ndb_row_lock_view_mix_1.result new file mode 100644 index 00000000000..b5b1c519702 --- /dev/null +++ b/mysql-test/suite/row_lock/r/ndb_row_lock_view_mix_1.result @@ -0,0 +1,169 @@ +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1; +SET autocommit=0; +SET autocommit=0; +connection default; +CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=NDB; +INSERT INTO t1 VALUES (1,123,1,123); +INSERT INTO t1 VALUES (2,124,2,124); +INSERT INTO t1 VALUES (3,125,3,125); +INSERT INTO t1 VALUES (4,126,4,126); +CREATE INDEX ixi ON t1 (i); +CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=NDB; +INSERT INTO t2 VALUES (1,123,1,123); +INSERT INTO t2 VALUES (2,124,2,124); +INSERT INTO t2 VALUES (3,125,3,125); +INSERT INTO t2 VALUES (4,126,4,126); +CREATE INDEX ixi ON t2 (i); +CREATE VIEW v1 AS SELECT t1.i, t2.l from t1,t2; +COMMIT; +SELECT @@global.tx_isolation; +@@global.tx_isolation +REPEATABLE-READ +EXPLAIN SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i FOR UPDATE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range ixi ixi 5 NULL 10 Using where +1 SIMPLE t2 ref ixi ixi 5 test.t1.i 1 Using where +SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i FOR UPDATE; +i i +123 123 +124 124 +connection root1; +UPDATE t1,t2 SET t1.i=225,t2.i=225 WHERE t1.i=125 AND t2.i=t1.i; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 126 4 126 +connection default; +UPDATE v1 SET i=323 where i=123; +SELECT * FROM v1 ORDER BY i,l; +i l +124 123 +124 124 +124 125 +124 126 +125 123 +125 124 +125 125 +125 126 +126 123 +126 124 +126 125 +126 126 +323 123 +323 124 +323 125 +323 126 +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 323 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +connection root1; +UPDATE t1,t2 SET t1.i=226,t2.i=226 WHERE t1.i=126 AND t2.i=t1.i; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 226 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 226 4 126 +connection default; +UPDATE v1 SET i=324 where i=124; +SELECT * FROM v1 ORDER BY i,l; +i l +125 123 +125 124 +125 125 +125 126 +126 123 +126 124 +126 125 +126 126 +323 123 +323 124 +323 125 +323 126 +324 123 +324 124 +324 125 +324 126 +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 323 1 123 +2 324 2 124 +3 125 3 125 +4 126 4 126 +connection root1; +DELETE FROM t1 WHERE t1.i=226; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 226 4 126 +connection default; +DELETE FROM t1 WHERE t1.i=224; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 323 1 123 +2 324 2 124 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +COMMIT; +connection root1; +ROLLBACK; +connection default; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 323 1 123 +2 324 2 124 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +connection root1; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 323 1 123 +2 324 2 124 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +connection default; +DROP VIEW IF EXISTS v1; +DROP TABLE t1, t2; diff --git a/mysql-test/suite/row_lock/r/ndb_row_lock_view_mix_2.result b/mysql-test/suite/row_lock/r/ndb_row_lock_view_mix_2.result new file mode 100644 index 00000000000..d92f9ad9664 --- /dev/null +++ b/mysql-test/suite/row_lock/r/ndb_row_lock_view_mix_2.result @@ -0,0 +1,38 @@ +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1; +SET autocommit=0; +SET autocommit=0; +connection default; +CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=NDB; +INSERT INTO t1 VALUES (1,123,1,123); +INSERT INTO t1 VALUES (2,124,2,124); +INSERT INTO t1 VALUES (3,125,3,125); +INSERT INTO t1 VALUES (4,126,4,126); +CREATE INDEX ixi ON t1 (i); +CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=NDB; +INSERT INTO t2 VALUES (1,123,1,123); +INSERT INTO t2 VALUES (2,124,2,124); +INSERT INTO t2 VALUES (3,125,3,125); +INSERT INTO t2 VALUES (4,126,4,126); +CREATE INDEX ixi ON t2 (i); +CREATE VIEW v1 AS SELECT t1.i, t2.l from t1,t2; +COMMIT; +SELECT @@global.tx_isolation; +@@global.tx_isolation +REPEATABLE-READ +EXPLAIN SELECT v1.i FROM v1 WHERE v1.i<125 FOR UPDATE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range ixi ixi 5 NULL 10 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 4 +SELECT v1.i FROM v1 WHERE v1.i<125 FOR UPDATE; +i +123 +124 +123 +124 +123 +124 +123 +124 +connection root1; +UPDATE t1,t2 SET t1.i=225,t2.i=225 WHERE t1.i=125 AND t2.i=t1.i; diff --git a/mysql-test/suite/row_lock/r/ndb_row_lock_view_storedp_1.result b/mysql-test/suite/row_lock/r/ndb_row_lock_view_storedp_1.result new file mode 100644 index 00000000000..e2a2a6e7deb --- /dev/null +++ b/mysql-test/suite/row_lock/r/ndb_row_lock_view_storedp_1.result @@ -0,0 +1,309 @@ +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1; +DROP PROCEDURE IF EXISTS stp_t; +SET autocommit=0; +SET autocommit=0; +SET autocommit=0; +connection default; +CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=NDB; +INSERT INTO t1 VALUES (1,123,1,123); +INSERT INTO t1 VALUES (2,124,2,124); +INSERT INTO t1 VALUES (3,125,3,125); +INSERT INTO t1 VALUES (4,126,4,126); +INSERT INTO t1 VALUES (5,127,5,127); +INSERT INTO t1 VALUES (6,128,6,128); +CREATE INDEX ixi ON t1 (i); +CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=NDB; +INSERT INTO t2 VALUES (1,123,1,123); +INSERT INTO t2 VALUES (2,124,2,124); +INSERT INTO t2 VALUES (3,125,3,125); +INSERT INTO t2 VALUES (4,126,4,126); +INSERT INTO t2 VALUES (5,127,5,127); +INSERT INTO t2 VALUES (6,128,6,128); +CREATE INDEX ixi ON t2 (i); +CREATE VIEW v1 AS SELECT t1.i from t1; +CREATE PROCEDURE stp_t (IN p1 int, IN p2 int) MODIFIES SQL DATA +BEGIN +UPDATE t2 SET i = p2 WHERE i = p1; +UPDATE v1 SET i = p2 WHERE i = p1; +SELECT * FROM v1 ORDER BY i; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; +END; +| +COMMIT; +SELECT @@global.tx_isolation; +@@global.tx_isolation +REPEATABLE-READ +EXPLAIN SELECT t1.i FROM t1 WHERE t1.i< 125 FOR UPDATE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range ixi ixi 5 NULL 10 Using where +SELECT t1.i FROM t1 WHERE t1.i< 125 FOR UPDATE; +i +123 +124 +connection root1; +CALL stp_t (125, 225); +i +123 +124 +126 +127 +128 +225 +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 126 4 126 +5 127 5 127 +6 128 6 128 +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 126 4 126 +5 127 5 127 +6 128 6 128 +connection root2; +CALL stp_t (127, 227); +i +123 +124 +125 +126 +128 +227 +k i j l +1 123 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +5 227 5 127 +6 128 6 128 +k i j l +1 123 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +5 227 5 127 +6 128 6 128 +connection default; +CALL stp_t (123, 223); +i +124 +125 +126 +127 +128 +223 +k i j l +1 223 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +5 127 5 127 +6 128 6 128 +k i j l +1 223 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +5 127 5 127 +6 128 6 128 +connection root1; +CALL stp_t (126, 226); +i +123 +124 +127 +128 +225 +226 +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 226 4 126 +5 127 5 127 +6 128 6 128 +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 226 4 126 +5 127 5 127 +6 128 6 128 +connection root2; +CALL stp_t (128, 228); +i +123 +124 +125 +126 +227 +228 +k i j l +1 123 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +5 227 5 127 +6 228 6 128 +k i j l +1 123 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +5 227 5 127 +6 228 6 128 +connection default; +CALL stp_t (124, 224); +i +125 +126 +127 +128 +223 +224 +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +5 127 5 127 +6 128 6 128 +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +5 127 5 127 +6 128 6 128 +connection root1; +DELETE FROM t1 WHERE t1.i=226; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +5 127 5 127 +6 128 6 128 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 226 4 126 +5 127 5 127 +6 128 6 128 +connection root2; +DELETE FROM t1 WHERE t1.i=228; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +5 227 5 127 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +5 227 5 127 +6 228 6 128 +connection default; +DELETE FROM t1 WHERE t1.i=224; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +3 125 3 125 +4 126 4 126 +5 127 5 127 +6 128 6 128 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +5 127 5 127 +6 128 6 128 +COMMIT; +connection root1; +ROLLBACK; +connection root1; +COMMIT; +connection default; +SELECT * FROM v1 ORDER BY i; +i +125 +126 +127 +128 +223 +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +3 125 3 125 +4 126 4 126 +5 127 5 127 +6 128 6 128 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +5 127 5 127 +6 128 6 128 +connection root1; +SELECT * FROM v1 ORDER BY i; +i +125 +126 +127 +128 +223 +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +3 125 3 125 +4 126 4 126 +5 127 5 127 +6 128 6 128 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +5 127 5 127 +6 128 6 128 +connection root2; +SELECT * FROM v1 ORDER BY i; +i +125 +126 +223 +227 +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +3 125 3 125 +4 126 4 126 +5 227 5 127 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +5 227 5 127 +6 228 6 128 +connection default; +DROP VIEW v1; +DROP PROCEDURE stp_t; +DROP TABLE t1, t2; diff --git a/mysql-test/suite/row_lock/r/ndb_row_lock_view_storedp_2.result b/mysql-test/suite/row_lock/r/ndb_row_lock_view_storedp_2.result new file mode 100644 index 00000000000..6dbd5f834ed --- /dev/null +++ b/mysql-test/suite/row_lock/r/ndb_row_lock_view_storedp_2.result @@ -0,0 +1,46 @@ +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1; +DROP PROCEDURE IF EXISTS stp_t; +SET autocommit=0; +SET autocommit=0; +SET autocommit=0; +connection default; +CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=NDB; +INSERT INTO t1 VALUES (1,123,1,123); +INSERT INTO t1 VALUES (2,124,2,124); +INSERT INTO t1 VALUES (3,125,3,125); +INSERT INTO t1 VALUES (4,126,4,126); +INSERT INTO t1 VALUES (5,127,5,127); +INSERT INTO t1 VALUES (6,128,6,128); +#CREATE INDEX ixi ON t1 (i); +CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=NDB; +INSERT INTO t2 VALUES (1,123,1,123); +INSERT INTO t2 VALUES (2,124,2,124); +INSERT INTO t2 VALUES (3,125,3,125); +INSERT INTO t2 VALUES (4,126,4,126); +INSERT INTO t2 VALUES (5,127,5,127); +INSERT INTO t2 VALUES (6,128,6,128); +#CREATE INDEX ixi ON t2 (i); +CREATE VIEW v1 AS SELECT t1.i from t1; +CREATE PROCEDURE stp_t (IN p1 int, IN p2 int) MODIFIES SQL DATA +BEGIN +UPDATE t2 SET i = p2 WHERE i = p1; +UPDATE v1 SET i = p2 WHERE i = p1; +SELECT * FROM v1 ORDER BY i; +SELECT * FROM t1 ORDER BY t1.k; +SELECT * FROM t2 ORDER BY t2.k; +END; +| +COMMIT; +SELECT @@global.tx_isolation; +@@global.tx_isolation +REPEATABLE-READ +EXPLAIN SELECT t1.i FROM t1 WHERE t1.i< 125 FOR UPDATE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 6 Using where +SELECT t1.i FROM t1 WHERE t1.i< 125 FOR UPDATE; +i +123 +124 +connection root1; +CALL stp_t (125, 225); diff --git a/mysql-test/suite/row_lock/r/ndb_row_lock_view_trig_1.result b/mysql-test/suite/row_lock/r/ndb_row_lock_view_trig_1.result new file mode 100644 index 00000000000..f5c745ca41c --- /dev/null +++ b/mysql-test/suite/row_lock/r/ndb_row_lock_view_trig_1.result @@ -0,0 +1,180 @@ +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1; +SET autocommit=0; +SET autocommit=0; +connection default; +CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=NDB; +INSERT INTO t1 VALUES (1,123,1,123); +INSERT INTO t1 VALUES (2,124,2,124); +INSERT INTO t1 VALUES (3,125,3,125); +INSERT INTO t1 VALUES (4,126,4,126); +CREATE INDEX ixi ON t1 (i); +CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=NDB; +INSERT INTO t2 VALUES (1,123,1,123); +INSERT INTO t2 VALUES (2,124,2,124); +INSERT INTO t2 VALUES (3,125,3,125); +INSERT INTO t2 VALUES (4,126,4,126); +CREATE INDEX ixi ON t2 (i); +CREATE VIEW v1 AS SELECT t1.i from t1; +CREATE TRIGGER trig_t2 AFTER UPDATE ON t2 +FOR EACH ROW BEGIN +UPDATE v1 SET i = NEW.i WHERE i = OLD.i; +END; +| +COMMIT; +SELECT @@global.tx_isolation; +@@global.tx_isolation +REPEATABLE-READ +EXPLAIN SELECT t1.i FROM t1 WHERE t1.i< 125 FOR UPDATE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range ixi ixi 5 NULL 10 Using where +SELECT t1.i FROM t1 WHERE t1.i< 125 FOR UPDATE; +i +123 +124 +connection root1; +UPDATE t2 SET t2.i=225 WHERE t2.i=125; +SELECT * FROM v1 ORDER BY i; +i +123 +124 +126 +225 +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 126 4 126 +connection default; +UPDATE t2 SET t2.i=223 WHERE t2.i=123; +SELECT * FROM v1 ORDER BY i; +i +124 +125 +126 +223 +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 124 2 124 +3 125 3 125 +4 126 4 126 +connection root1; +UPDATE t2 SET t2.i=226 WHERE t2.i=126; +SELECT * FROM v1 ORDER BY i; +i +123 +124 +225 +226 +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 226 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 226 4 126 +connection default; +UPDATE t2 SET t2.i=224 WHERE t2.i=124; +SELECT * FROM v1 ORDER BY i; +i +125 +126 +223 +224 +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +connection root1; +DELETE FROM t1 WHERE t1.i=226; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 123 1 123 +2 124 2 124 +3 225 3 125 +4 226 4 126 +connection default; +DELETE FROM t1 WHERE t1.i=224; +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +COMMIT; +connection root1; +ROLLBACK; +connection default; +SELECT * FROM v1 ORDER BY i; +i +125 +126 +223 +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +connection root1; +SELECT * FROM v1 ORDER BY i; +i +125 +126 +223 +SELECT * FROM t1 ORDER BY t1.k; +k i j l +1 223 1 123 +3 125 3 125 +4 126 4 126 +SELECT * FROM t2 ORDER BY t2.k; +k i j l +1 223 1 123 +2 224 2 124 +3 125 3 125 +4 126 4 126 +connection default; +DROP TABLE t1, t2; +DROP VIEW v1; diff --git a/mysql-test/suite/row_lock/r/ndb_row_lock_view_trig_2.result b/mysql-test/suite/row_lock/r/ndb_row_lock_view_trig_2.result new file mode 100644 index 00000000000..d6a38753c1d --- /dev/null +++ b/mysql-test/suite/row_lock/r/ndb_row_lock_view_trig_2.result @@ -0,0 +1,36 @@ +DROP TABLE IF EXISTS t1, t2; +DROP VIEW IF EXISTS v1; +SET autocommit=0; +SET autocommit=0; +connection default; +CREATE TABLE t1 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=NDB; +INSERT INTO t1 VALUES (1,123,1,123); +INSERT INTO t1 VALUES (2,124,2,124); +INSERT INTO t1 VALUES (3,125,3,125); +INSERT INTO t1 VALUES (4,126,4,126); +#CREATE INDEX ixi ON t1 (i); +CREATE TABLE t2 (k INT NOT NULL PRIMARY KEY, i INT, j INT, l INT) ENGINE=NDB; +INSERT INTO t2 VALUES (1,123,1,123); +INSERT INTO t2 VALUES (2,124,2,124); +INSERT INTO t2 VALUES (3,125,3,125); +INSERT INTO t2 VALUES (4,126,4,126); +#CREATE INDEX ixi ON t2 (i); +CREATE VIEW v1 AS SELECT t1.i from t1; +CREATE TRIGGER trig_t2 AFTER UPDATE ON t2 +FOR EACH ROW BEGIN +UPDATE v1 SET i = NEW.i WHERE i = OLD.i; +END; +| +COMMIT; +SELECT @@global.tx_isolation; +@@global.tx_isolation +REPEATABLE-READ +EXPLAIN SELECT t1.i FROM t1 WHERE t1.i< 125 FOR UPDATE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where +SELECT t1.i FROM t1 WHERE t1.i< 125 FOR UPDATE; +i +123 +124 +connection root1; +UPDATE t2 SET t2.i=225 WHERE t2.i=125; diff --git a/mysql-test/suite/row_lock/readme.txt b/mysql-test/suite/row_lock/readme.txt new file mode 100644 index 00000000000..b43f04ecda4 --- /dev/null +++ b/mysql-test/suite/row_lock/readme.txt @@ -0,0 +1,9 @@ +All row lock test with InnoDB have to be executed with the options + +--innodb_lock_wait_timeout=1 +--innodb_locks_unsafe_for_binlog + +for example + +perl mysql-test-run.pl --mysqld=--innodb_lock_wait_timeout=2 --mysqld=--innodb_locks_unsafe_for_binlog --suite=row_lock innodb_row_lock_2 + diff --git a/mysql-test/suite/row_lock/summary_of_sel_test.txt b/mysql-test/suite/row_lock/summary_of_sel_test.txt new file mode 100644 index 00000000000..0fa332e957a --- /dev/null +++ b/mysql-test/suite/row_lock/summary_of_sel_test.txt @@ -0,0 +1,36 @@ +Test plan: +Create 2 tables with a primary key and 3 integer columns. Both get the same rows (1,123,1,123),(2,124,2,124),(3,125,3,125),(4,126,4,126). The second and third column may get an index to have cases with, without and mutilple index. Create views on the tables. Create an update trigger. Create a stored procedure updating the table. Create a stored function updating the table and deliver the key as result. + +The test isself consists of 2 sessions (transactions) running in "parallel" (same user "root") accessing and locking the same tables on basis of a row lock. Expected is that both sessions(transactions) can update the table successfully. + +First session +execute an explain to every select and one of the following selects on the first half of table t1: +- select <non index columns> ... where ... for update; +- select <non index columns> ... where ... lock in share mode; +- select <indexed columns> ... where ... for update; +- select <indexed columns> ... where ... lock in share mode; +- select <indexed columns> ... ignore index ... where ... for update; +- select <indexed columns> ... ignore index ... where ... lock in share mode; +- select ... where (select...) ... for update; +- select ... where (select...) ... lock in share mode; +- (select ... where) union (select ... where) for update; +- (select ... where) union (select ... where) lock in...; +- select <view> ... where ... for update; +- select <view> ... where ... lock in ...; +- select <join> ... where ... for update; +- select <join> ... where ... lock in ...; +Then executes +- update +- delete +- trigger accessing table t1 +- stored procedure accessing table t1 +- stored function accessing table t1 + +Second session +executes the same on the last half of table t1 + +call of mysqld with option +--innodb_locks_unsafe_for_binlog + +As the tests above work with small tables (<10 rows) there must be at least one test with a big table (>1000 rows) doing a table scan. + diff --git a/mysql-test/suite/row_lock/t/innodb_row_lock_1.test b/mysql-test/suite/row_lock/t/innodb_row_lock_1.test new file mode 100644 index 00000000000..e0440fe2669 --- /dev/null +++ b/mysql-test/suite/row_lock/t/innodb_row_lock_1.test @@ -0,0 +1,9 @@ +--source include/have_innodb.inc +SELECT @@global.innodb_table_locks into @table_locks; +SET @@global.innodb_table_locks= OFF; +let $engine= InnoDB; +let $select= SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i FOR UPDATE; +let $indext1= CREATE INDEX ixi ON t1 (i); +let $indext2= CREATE INDEX ixi ON t2 (i); +--source suite/row_lock/include/row_lock.inc +SET @@global.innodb_table_locks= @table_locks; diff --git a/mysql-test/suite/row_lock/t/innodb_row_lock_2.test b/mysql-test/suite/row_lock/t/innodb_row_lock_2.test new file mode 100644 index 00000000000..5cb3ea9f2d9 --- /dev/null +++ b/mysql-test/suite/row_lock/t/innodb_row_lock_2.test @@ -0,0 +1,9 @@ +--source include/have_innodb.inc +SELECT @@global.innodb_table_locks into @table_locks; +SET @@global.innodb_table_locks= OFF; +let $engine= InnoDB; +let $select= SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i FOR UPDATE; +let $indext1= #CREATE INDEX ixi ON t1 (i); +let $indext2= #CREATE INDEX ixi ON t2 (i); +--source suite/row_lock/include/row_lock.inc +SET @@global.innodb_table_locks= @table_locks; diff --git a/mysql-test/suite/row_lock/t/innodb_row_lock_3.test b/mysql-test/suite/row_lock/t/innodb_row_lock_3.test new file mode 100644 index 00000000000..11f4dc423d6 --- /dev/null +++ b/mysql-test/suite/row_lock/t/innodb_row_lock_3.test @@ -0,0 +1,9 @@ +--source include/have_innodb.inc +SELECT @@global.innodb_table_locks into @table_locks; +SET @@global.innodb_table_locks= OFF; +let $engine= InnoDB; +let $select= SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i LOCK IN SHARE MODE; +let $indext1= #CREATE INDEX ixi ON t1 (i); +let $indext2= #CREATE INDEX ixi ON t2 (i); +--source suite/row_lock/include/row_lock.inc +SET @@global.innodb_table_locks= @table_locks; diff --git a/mysql-test/suite/row_lock/t/innodb_row_lock_4.test b/mysql-test/suite/row_lock/t/innodb_row_lock_4.test new file mode 100644 index 00000000000..0a8ca9c13a0 --- /dev/null +++ b/mysql-test/suite/row_lock/t/innodb_row_lock_4.test @@ -0,0 +1,9 @@ +--source include/have_innodb.inc +SELECT @@global.innodb_table_locks into @table_locks; +SET @@global.innodb_table_locks= OFF; +let $engine= InnoDB; +let $select= SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i LOCK IN SHARE MODE; +let $indext1= CREATE INDEX ixi ON t1 (i); +let $indext2= CREATE INDEX ixi ON t2 (i); +--source suite/row_lock/include/row_lock.inc +SET @@global.innodb_table_locks= @table_locks; diff --git a/mysql-test/suite/row_lock/t/innodb_row_lock_5.test b/mysql-test/suite/row_lock/t/innodb_row_lock_5.test new file mode 100644 index 00000000000..7e411d31649 --- /dev/null +++ b/mysql-test/suite/row_lock/t/innodb_row_lock_5.test @@ -0,0 +1,9 @@ +--source include/have_innodb.inc +SELECT @@global.innodb_table_locks into @table_locks; +SET @@global.innodb_table_locks= OFF; +let $engine= InnoDB; +let $select= SELECT t1.i,t2.i FROM t1 ignore index (ixi),t2 IGNORE INDEX (ixi) WHERE t1.i<125 AND t2.i=t1.i LOCK IN SHARE MODE; +let $indext1= CREATE INDEX ixi ON t1 (i); +let $indext2= CREATE INDEX ixi ON t2 (i); +--source suite/row_lock/include/row_lock.inc +SET @@global.innodb_table_locks= @table_locks; diff --git a/mysql-test/suite/row_lock/t/innodb_row_lock_big_tab.test b/mysql-test/suite/row_lock/t/innodb_row_lock_big_tab.test new file mode 100644 index 00000000000..0c5b8b41bd5 --- /dev/null +++ b/mysql-test/suite/row_lock/t/innodb_row_lock_big_tab.test @@ -0,0 +1,9 @@ +--source include/have_innodb.inc +SELECT @@global.innodb_table_locks into @table_locks; +SET @@global.innodb_table_locks= OFF; +let $engine= InnoDB; +let $select= SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i < half_t1() AND t2.i=t1.i LOCK IN SHARE MODE; +let $indext1= CREATE INDEX ixi ON t1 (i); +let $indext2= CREATE INDEX ixi ON t2 (i); +--source suite/row_lock/include/row_lock_big_tab.inc +SET @@global.innodb_table_locks= @table_locks; diff --git a/mysql-test/suite/row_lock/t/innodb_row_lock_big_tab_1.test b/mysql-test/suite/row_lock/t/innodb_row_lock_big_tab_1.test new file mode 100644 index 00000000000..a12a07d82a9 --- /dev/null +++ b/mysql-test/suite/row_lock/t/innodb_row_lock_big_tab_1.test @@ -0,0 +1,10 @@ +--source include/have_innodb.inc +SELECT @@global.innodb_table_locks into @table_locks; +SET @@global.innodb_table_locks= OFF; +let $engine= InnoDB; +let $nbrows= 40; +let $select= SELECT t1.i,t2.i FROM t1,t2 WHERE t1.k % 2= 0 AND t1.k = t2.k LOCK IN SHARE MODE; +let $indext1= CREATE INDEX ixi ON t1 (i); +let $indext2= CREATE INDEX ixi ON t2 (i); +--source suite/row_lock/include/row_lock_big_tab_1.inc +SET @@global.innodb_table_locks= @table_locks; diff --git a/mysql-test/suite/row_lock/t/innodb_row_lock_big_tab_2.test b/mysql-test/suite/row_lock/t/innodb_row_lock_big_tab_2.test new file mode 100644 index 00000000000..49e834eb2ce --- /dev/null +++ b/mysql-test/suite/row_lock/t/innodb_row_lock_big_tab_2.test @@ -0,0 +1,10 @@ +--source include/have_innodb.inc +SELECT @@global.innodb_table_locks into @table_locks; +SET @@global.innodb_table_locks= OFF; +let $engine= InnoDB; +let $nbrows= 40; +let $select= SELECT t1.i,t2.i FROM t1,t2 WHERE t1.k % 2= 0 AND t1.k = t2.k LOCK IN SHARE MODE; +let $indext1= CREATE INDEX ixi ON t1 (i); +let $indext2= CREATE INDEX ixi ON t2 (i); +--source suite/row_lock/include/row_lock_big_tab_2.inc +SET @@global.innodb_table_locks= @table_locks; diff --git a/mysql-test/suite/row_lock/t/innodb_row_lock_trig_1.test b/mysql-test/suite/row_lock/t/innodb_row_lock_trig_1.test new file mode 100644 index 00000000000..225513d3f87 --- /dev/null +++ b/mysql-test/suite/row_lock/t/innodb_row_lock_trig_1.test @@ -0,0 +1,9 @@ +--source include/have_innodb.inc +SELECT @@global.innodb_table_locks into @table_locks; +SET @@global.innodb_table_locks= OFF; +let $engine= InnoDB; +let $select= SELECT t1.i FROM t1 WHERE t1.i< 125 FOR UPDATE; +let $indext1= CREATE INDEX ixi ON t1 (i); +let $indext2= CREATE INDEX ixi ON t2 (i); +--source suite/row_lock/include/row_lock_trig.inc +SET @@global.innodb_table_locks= @table_locks; diff --git a/mysql-test/suite/row_lock/t/innodb_row_lock_trig_2.test b/mysql-test/suite/row_lock/t/innodb_row_lock_trig_2.test new file mode 100644 index 00000000000..88dee5f23f8 --- /dev/null +++ b/mysql-test/suite/row_lock/t/innodb_row_lock_trig_2.test @@ -0,0 +1,9 @@ +--source include/have_innodb.inc +SELECT @@global.innodb_table_locks into @table_locks; +SET @@global.innodb_table_locks= OFF; +let $engine= InnoDB; +let $select= SELECT t1.i FROM t1 WHERE t1.i< 125 FOR UPDATE; +let $indext1= #CREATE INDEX ixi ON t1 (i); +let $indext2= #CREATE INDEX ixi ON t2 (i); +--source suite/row_lock/include/row_lock_trig.inc +SET @@global.innodb_table_locks= @table_locks; diff --git a/mysql-test/suite/row_lock/t/innodb_row_lock_view_1.test b/mysql-test/suite/row_lock/t/innodb_row_lock_view_1.test new file mode 100644 index 00000000000..d6381e1da5b --- /dev/null +++ b/mysql-test/suite/row_lock/t/innodb_row_lock_view_1.test @@ -0,0 +1,9 @@ +--source include/have_innodb.inc +SELECT @@global.innodb_table_locks into @table_locks; +SET @@global.innodb_table_locks= OFF; +let $engine= InnoDB; +let $select= SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i FOR UPDATE; +let $indext1= CREATE INDEX ixi ON t1 (i); +let $indext2= CREATE INDEX ixi ON t2 (i); +--source suite/row_lock/include/row_lock_view.inc +SET @@global.innodb_table_locks= @table_locks; diff --git a/mysql-test/suite/row_lock/t/innodb_row_lock_view_2.test b/mysql-test/suite/row_lock/t/innodb_row_lock_view_2.test new file mode 100644 index 00000000000..ee45e683669 --- /dev/null +++ b/mysql-test/suite/row_lock/t/innodb_row_lock_view_2.test @@ -0,0 +1,9 @@ +--source include/have_innodb.inc +SELECT @@global.innodb_table_locks into @table_locks; +SET @@global.innodb_table_locks= OFF; +let $engine= InnoDB; +let $select= SELECT v1.i FROM v1 WHERE v1.i<125 FOR UPDATE; +let $indext1= CREATE INDEX ixi ON t1 (i); +let $indext2= CREATE INDEX ixi ON t2 (i); +--source suite/row_lock/include/row_lock_view.inc +SET @@global.innodb_table_locks= @table_locks; diff --git a/mysql-test/suite/row_lock/t/innodb_row_lock_view_mix_1.test b/mysql-test/suite/row_lock/t/innodb_row_lock_view_mix_1.test new file mode 100644 index 00000000000..49cba88dd23 --- /dev/null +++ b/mysql-test/suite/row_lock/t/innodb_row_lock_view_mix_1.test @@ -0,0 +1,9 @@ +--source include/have_innodb.inc +SELECT @@global.innodb_table_locks into @table_locks; +SET @@global.innodb_table_locks= OFF; +let $engine= InnoDB; +let $select= SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i FOR UPDATE; +let $indext1= CREATE INDEX ixi ON t1 (i); +let $indext2= CREATE INDEX ixi ON t2 (i); +--source suite/row_lock/include/row_lock_view_mix.inc +SET @@global.innodb_table_locks= @table_locks; diff --git a/mysql-test/suite/row_lock/t/innodb_row_lock_view_mix_2.test b/mysql-test/suite/row_lock/t/innodb_row_lock_view_mix_2.test new file mode 100644 index 00000000000..b07f3a3378a --- /dev/null +++ b/mysql-test/suite/row_lock/t/innodb_row_lock_view_mix_2.test @@ -0,0 +1,10 @@ +--source include/have_innodb.inc +SELECT @@global.innodb_table_locks into @table_locks; +SET @@global.innodb_table_locks= OFF; +let $engine= InnoDB; +#let $select= SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i FOR UPDATE; +let $select= SELECT v1.i FROM v1 WHERE v1.i<125 FOR UPDATE; +let $indext1= CREATE INDEX ixi ON t1 (i); +let $indext2= CREATE INDEX ixi ON t2 (i); +--source suite/row_lock/include/row_lock_view_mix.inc +SET @@global.innodb_table_locks= @table_locks; diff --git a/mysql-test/suite/row_lock/t/innodb_row_lock_view_storedp_1.test b/mysql-test/suite/row_lock/t/innodb_row_lock_view_storedp_1.test new file mode 100644 index 00000000000..d507ff3296f --- /dev/null +++ b/mysql-test/suite/row_lock/t/innodb_row_lock_view_storedp_1.test @@ -0,0 +1,9 @@ +--source include/have_innodb.inc +SELECT @@global.innodb_table_locks into @table_locks; +SET @@global.innodb_table_locks= OFF; +let $engine= InnoDB; +let $select= SELECT t1.i FROM t1 WHERE t1.i< 125 FOR UPDATE; +let $indext1= CREATE INDEX ixi ON t1 (i); +let $indext2= CREATE INDEX ixi ON t2 (i); +--source suite/row_lock/include/row_lock_view_storedp.inc +SET @@global.innodb_table_locks= @table_locks; diff --git a/mysql-test/suite/row_lock/t/innodb_row_lock_view_storedp_2.test b/mysql-test/suite/row_lock/t/innodb_row_lock_view_storedp_2.test new file mode 100644 index 00000000000..a1bfb16055e --- /dev/null +++ b/mysql-test/suite/row_lock/t/innodb_row_lock_view_storedp_2.test @@ -0,0 +1,9 @@ +--source include/have_innodb.inc +SELECT @@global.innodb_table_locks into @table_locks; +SET @@global.innodb_table_locks= OFF; +let $engine= InnoDB; +let $select= SELECT t1.i FROM t1 WHERE t1.i< 125 FOR UPDATE; +let $indext1= #CREATE INDEX ixi ON t1 (i); +let $indext2= #CREATE INDEX ixi ON t2 (i); +--source suite/row_lock/include/row_lock_view_storedp.inc +SET @@global.innodb_table_locks= @table_locks; diff --git a/mysql-test/suite/row_lock/t/innodb_row_lock_view_trig_1.test b/mysql-test/suite/row_lock/t/innodb_row_lock_view_trig_1.test new file mode 100644 index 00000000000..24c76532d17 --- /dev/null +++ b/mysql-test/suite/row_lock/t/innodb_row_lock_view_trig_1.test @@ -0,0 +1,9 @@ +--source include/have_innodb.inc +SELECT @@global.innodb_table_locks into @table_locks; +SET @@global.innodb_table_locks= OFF; +let $engine= InnoDB; +let $select= SELECT t1.i FROM t1 WHERE t1.i< 125 FOR UPDATE; +let $indext1= CREATE INDEX ixi ON t1 (i); +let $indext2= CREATE INDEX ixi ON t2 (i); +--source suite/row_lock/include/row_lock_view_trig.inc +SET @@global.innodb_table_locks= @table_locks; diff --git a/mysql-test/suite/row_lock/t/innodb_row_lock_view_trig_2.test b/mysql-test/suite/row_lock/t/innodb_row_lock_view_trig_2.test new file mode 100644 index 00000000000..a8a67d77979 --- /dev/null +++ b/mysql-test/suite/row_lock/t/innodb_row_lock_view_trig_2.test @@ -0,0 +1,9 @@ +--source include/have_innodb.inc +SELECT @@global.innodb_table_locks into @table_locks; +SET @@global.innodb_table_locks= OFF; +let $engine= InnoDB; +let $select= SELECT t1.i FROM t1 WHERE t1.i< 125 FOR UPDATE; +let $indext1= #CREATE INDEX ixi ON t1 (i); +let $indext2= #CREATE INDEX ixi ON t2 (i); +--source suite/row_lock/include/row_lock_view_trig.inc +SET @@global.innodb_table_locks= @table_locks; diff --git a/mysql-test/suite/row_lock/t/ndb_row_lock_1.test b/mysql-test/suite/row_lock/t/ndb_row_lock_1.test new file mode 100644 index 00000000000..6ac2e829008 --- /dev/null +++ b/mysql-test/suite/row_lock/t/ndb_row_lock_1.test @@ -0,0 +1,6 @@ +--source include/have_ndb.inc +let $engine= NDB; +let $select= SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i FOR UPDATE; +let $indext1= CREATE INDEX ixi ON t1 (i); +let $indext2= CREATE INDEX ixi ON t2 (i); +--source suite/row_lock/include/row_lock.inc diff --git a/mysql-test/suite/row_lock/t/ndb_row_lock_2.test b/mysql-test/suite/row_lock/t/ndb_row_lock_2.test new file mode 100644 index 00000000000..994ecba96b0 --- /dev/null +++ b/mysql-test/suite/row_lock/t/ndb_row_lock_2.test @@ -0,0 +1,6 @@ +--source include/have_ndb.inc +let $engine= NDB; +let $select= SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i FOR UPDATE; +let $indext1= #CREATE INDEX ixi ON t1 (i); +let $indext2= #CREATE INDEX ixi ON t2 (i); +--source suite/row_lock/include/row_lock.inc diff --git a/mysql-test/suite/row_lock/t/ndb_row_lock_3.test b/mysql-test/suite/row_lock/t/ndb_row_lock_3.test new file mode 100644 index 00000000000..2de43c61c2a --- /dev/null +++ b/mysql-test/suite/row_lock/t/ndb_row_lock_3.test @@ -0,0 +1,6 @@ +--source include/have_ndb.inc +let $engine= NDB; +let $select= SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i LOCK IN SHARE MODE; +let $indext1= #CREATE INDEX ixi ON t1 (i); +let $indext2= #CREATE INDEX ixi ON t2 (i); +--source suite/row_lock/include/row_lock.inc diff --git a/mysql-test/suite/row_lock/t/ndb_row_lock_4.test b/mysql-test/suite/row_lock/t/ndb_row_lock_4.test new file mode 100644 index 00000000000..72b20488c74 --- /dev/null +++ b/mysql-test/suite/row_lock/t/ndb_row_lock_4.test @@ -0,0 +1,6 @@ +--source include/have_ndb.inc +let $engine= NDB; +let $select= SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i LOCK IN SHARE MODE; +let $indext1= CREATE INDEX ixi ON t1 (i); +let $indext2= CREATE INDEX ixi ON t2 (i); +--source suite/row_lock/include/row_lock.inc diff --git a/mysql-test/suite/row_lock/t/ndb_row_lock_5.test b/mysql-test/suite/row_lock/t/ndb_row_lock_5.test new file mode 100644 index 00000000000..045f127a4ef --- /dev/null +++ b/mysql-test/suite/row_lock/t/ndb_row_lock_5.test @@ -0,0 +1,6 @@ +--source include/have_ndb.inc +let $engine= NDB; +let $select= SELECT t1.i,t2.i FROM t1 ignore index (ixi),t2 IGNORE INDEX (ixi) WHERE t1.i<125 AND t2.i=t1.i LOCK IN SHARE MODE; +let $indext1= CREATE INDEX ixi ON t1 (i); +let $indext2= CREATE INDEX ixi ON t2 (i); +--source suite/row_lock/include/row_lock.inc diff --git a/mysql-test/suite/row_lock/t/ndb_row_lock_big_tab.test b/mysql-test/suite/row_lock/t/ndb_row_lock_big_tab.test new file mode 100644 index 00000000000..bf2df104e03 --- /dev/null +++ b/mysql-test/suite/row_lock/t/ndb_row_lock_big_tab.test @@ -0,0 +1,6 @@ +--source include/have_ndb.inc +let $engine= NDB; +let $select= SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i < half_t1() AND t2.i=t1.i LOCK IN SHARE MODE; +let $indext1= CREATE INDEX ixi ON t1 (i); +let $indext2= CREATE INDEX ixi ON t2 (i); +--source suite/row_lock/include/row_lock_big_tab.inc diff --git a/mysql-test/suite/row_lock/t/ndb_row_lock_big_tab_1.test b/mysql-test/suite/row_lock/t/ndb_row_lock_big_tab_1.test new file mode 100644 index 00000000000..4d32991d379 --- /dev/null +++ b/mysql-test/suite/row_lock/t/ndb_row_lock_big_tab_1.test @@ -0,0 +1,7 @@ +--source include/have_ndb.inc +let $engine= NDB; +let $nbrows= 200; +let $select= SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i < t1.k % 2 = 0 AND t2.k=t1.k LOCK IN SHARE MODE; +let $indext1= CREATE INDEX ixi ON t1 (i); +let $indext2= CREATE INDEX ixi ON t2 (i); +--source suite/row_lock/include/row_lock_big_tab_1.inc diff --git a/mysql-test/suite/row_lock/t/ndb_row_lock_big_tab_2.test b/mysql-test/suite/row_lock/t/ndb_row_lock_big_tab_2.test new file mode 100644 index 00000000000..894a83fc1b0 --- /dev/null +++ b/mysql-test/suite/row_lock/t/ndb_row_lock_big_tab_2.test @@ -0,0 +1,7 @@ +--source include/have_ndb.inc +let $engine= NDB; +let $nbrows= 200; +let $select= SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i < t1.k % 2 = 0 AND t2.k=t1.k LOCK IN SHARE MODE; +let $indext1= CREATE INDEX ixi ON t1 (i); +let $indext2= CREATE INDEX ixi ON t2 (i); +--source suite/row_lock/include/row_lock_big_tab_2.inc diff --git a/mysql-test/suite/row_lock/t/ndb_row_lock_trig_1.test b/mysql-test/suite/row_lock/t/ndb_row_lock_trig_1.test new file mode 100644 index 00000000000..a5586a6101e --- /dev/null +++ b/mysql-test/suite/row_lock/t/ndb_row_lock_trig_1.test @@ -0,0 +1,6 @@ +--source include/have_ndb.inc +let $engine= NDB; +let $select= SELECT t1.i FROM t1 WHERE t1.i< 125 FOR UPDATE; +let $indext1= CREATE INDEX ixi ON t1 (i); +let $indext2= CREATE INDEX ixi ON t2 (i); +--source suite/row_lock/include/row_lock_trig.inc diff --git a/mysql-test/suite/row_lock/t/ndb_row_lock_trig_2.test b/mysql-test/suite/row_lock/t/ndb_row_lock_trig_2.test new file mode 100644 index 00000000000..7af13697ccc --- /dev/null +++ b/mysql-test/suite/row_lock/t/ndb_row_lock_trig_2.test @@ -0,0 +1,6 @@ +--source include/have_ndb.inc +let $engine= NDB; +let $select= SELECT t1.i FROM t1 WHERE t1.i< 125 FOR UPDATE; +let $indext1= #CREATE INDEX ixi ON t1 (i); +let $indext2= #CREATE INDEX ixi ON t2 (i); +--source suite/row_lock/include/row_lock_trig.inc diff --git a/mysql-test/suite/row_lock/t/ndb_row_lock_view_1.test b/mysql-test/suite/row_lock/t/ndb_row_lock_view_1.test new file mode 100644 index 00000000000..a1aaf5ab441 --- /dev/null +++ b/mysql-test/suite/row_lock/t/ndb_row_lock_view_1.test @@ -0,0 +1,7 @@ +--source include/have_ndb.inc +let $engine= NDB; +let $select= SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i FOR UPDATE; +let $indext1= CREATE INDEX ixi ON t1 (i); +let $indext2= CREATE INDEX ixi ON t2 (i); +--source suite/row_lock/include/row_lock_view.inc + diff --git a/mysql-test/suite/row_lock/t/ndb_row_lock_view_2.test b/mysql-test/suite/row_lock/t/ndb_row_lock_view_2.test new file mode 100644 index 00000000000..b8feef693e7 --- /dev/null +++ b/mysql-test/suite/row_lock/t/ndb_row_lock_view_2.test @@ -0,0 +1,6 @@ +--source include/have_ndb.inc +let $engine= NDB; +let $select= SELECT v1.i FROM v1 WHERE v1.i<125 FOR UPDATE; +let $indext1= CREATE INDEX ixi ON t1 (i); +let $indext2= CREATE INDEX ixi ON t2 (i); +--source suite/row_lock/include/row_lock_view.inc diff --git a/mysql-test/suite/row_lock/t/ndb_row_lock_view_mix_1.test b/mysql-test/suite/row_lock/t/ndb_row_lock_view_mix_1.test new file mode 100644 index 00000000000..a97626048d3 --- /dev/null +++ b/mysql-test/suite/row_lock/t/ndb_row_lock_view_mix_1.test @@ -0,0 +1,6 @@ +--source include/have_ndb.inc +let $engine= NDB; +let $select= SELECT t1.i,t2.i FROM t1,t2 WHERE t1.i<125 AND t2.i=t1.i FOR UPDATE; +let $indext1= CREATE INDEX ixi ON t1 (i); +let $indext2= CREATE INDEX ixi ON t2 (i); +--source suite/row_lock/include/row_lock_view_mix.inc diff --git a/mysql-test/suite/row_lock/t/ndb_row_lock_view_mix_2.test b/mysql-test/suite/row_lock/t/ndb_row_lock_view_mix_2.test new file mode 100644 index 00000000000..e7a9a715785 --- /dev/null +++ b/mysql-test/suite/row_lock/t/ndb_row_lock_view_mix_2.test @@ -0,0 +1,6 @@ +--source include/have_ndb.inc +let $engine= NDB; +let $select= SELECT v1.i FROM v1 WHERE v1.i<125 FOR UPDATE; +let $indext1= CREATE INDEX ixi ON t1 (i); +let $indext2= CREATE INDEX ixi ON t2 (i); +--source suite/row_lock/include/row_lock_view_mix.inc diff --git a/mysql-test/suite/row_lock/t/ndb_row_lock_view_storedp_1.test b/mysql-test/suite/row_lock/t/ndb_row_lock_view_storedp_1.test new file mode 100644 index 00000000000..f57bcb3dd1b --- /dev/null +++ b/mysql-test/suite/row_lock/t/ndb_row_lock_view_storedp_1.test @@ -0,0 +1,6 @@ +--source include/have_ndb.inc +let $engine= NDB; +let $select= SELECT t1.i FROM t1 WHERE t1.i< 125 FOR UPDATE; +let $indext1= CREATE INDEX ixi ON t1 (i); +let $indext2= CREATE INDEX ixi ON t2 (i); +--source suite/row_lock/include/row_lock_view_storedp.inc diff --git a/mysql-test/suite/row_lock/t/ndb_row_lock_view_storedp_2.test b/mysql-test/suite/row_lock/t/ndb_row_lock_view_storedp_2.test new file mode 100644 index 00000000000..b0aaa38fb93 --- /dev/null +++ b/mysql-test/suite/row_lock/t/ndb_row_lock_view_storedp_2.test @@ -0,0 +1,6 @@ +--source include/have_ndb.inc +let $engine= NDB; +let $select= SELECT t1.i FROM t1 WHERE t1.i< 125 FOR UPDATE; +let $indext1= #CREATE INDEX ixi ON t1 (i); +let $indext2= #CREATE INDEX ixi ON t2 (i); +--source suite/row_lock/include/row_lock_view_storedp.inc diff --git a/mysql-test/suite/row_lock/t/ndb_row_lock_view_trig_1.test b/mysql-test/suite/row_lock/t/ndb_row_lock_view_trig_1.test new file mode 100644 index 00000000000..9c4128d78bf --- /dev/null +++ b/mysql-test/suite/row_lock/t/ndb_row_lock_view_trig_1.test @@ -0,0 +1,6 @@ +--source include/have_ndb.inc +let $engine= NDB; +let $select= SELECT t1.i FROM t1 WHERE t1.i< 125 FOR UPDATE; +let $indext1= CREATE INDEX ixi ON t1 (i); +let $indext2= CREATE INDEX ixi ON t2 (i); +--source suite/row_lock/include/row_lock_view_trig.inc diff --git a/mysql-test/suite/row_lock/t/ndb_row_lock_view_trig_2.test b/mysql-test/suite/row_lock/t/ndb_row_lock_view_trig_2.test new file mode 100644 index 00000000000..38c9472fb3d --- /dev/null +++ b/mysql-test/suite/row_lock/t/ndb_row_lock_view_trig_2.test @@ -0,0 +1,6 @@ +--source include/have_ndb.inc +let $engine= NDB; +let $select= SELECT t1.i FROM t1 WHERE t1.i< 125 FOR UPDATE; +let $indext1= #CREATE INDEX ixi ON t1 (i); +let $indext2= #CREATE INDEX ixi ON t2 (i); +--source suite/row_lock/include/row_lock_view_trig.inc diff --git a/mysql-test/t/distinct.test b/mysql-test/t/distinct.test index 476e4ce7735..7310f98cd16 100644 --- a/mysql-test/t/distinct.test +++ b/mysql-test/t/distinct.test @@ -540,3 +540,16 @@ EXPLAIN SELECT a FROM t1 GROUP BY a; SELECT a FROM t1 GROUP BY a; DROP TABLE t1; + +# +#Bug #27659: SELECT DISTINCT returns incorrect result set when field is +#repeated +# +# +CREATE TABLE t1 (a INT, b INT); +INSERT INTO t1 VALUES(1,1),(1,2),(1,3); +SELECT DISTINCT a, b FROM t1; +SELECT DISTINCT a, a, b FROM t1; +DROP TABLE t1; + +--echo End of 5.0 tests diff --git a/mysql-test/t/ndb_restore.test b/mysql-test/t/ndb_restore.test index 39c7ab67efb..5b839a0d3aa 100644 --- a/mysql-test/t/ndb_restore.test +++ b/mysql-test/t/ndb_restore.test @@ -8,15 +8,22 @@ drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9,t10; drop table if exists t1_c,t2_c,t3_c,t4_c,t5_c,t6_c,t7_c,t8_c,t9_c,t10_c; --enable_warnings -CREATE TABLE `t1` ( - `capgoaledatta` smallint(5) unsigned NOT NULL auto_increment, +# Bug #27775 - mediumint auto inc not restored correctly +# - check mediumint +CREATE TABLE `t1_c` ( + `capgoaledatta` mediumint(5) unsigned NOT NULL auto_increment, `goaledatta` char(2) NOT NULL default '', `maturegarbagefa` varchar(32) NOT NULL default '', PRIMARY KEY (`capgoaledatta`,`goaledatta`,`maturegarbagefa`) -) ENGINE=myisam DEFAULT CHARSET=latin1; -INSERT INTO `t1` VALUES (2,'3','q3plus.qt'),(4,'4','q3plus.qt'),(1,'3','q3.net'),(3,'4','q3.net'),(3,'20','threetrees.qt'); - -CREATE TABLE `t2` ( +) ENGINE=ndbcluster DEFAULT CHARSET=latin1; +INSERT INTO `t1_c` VALUES (2,'3','q3plus.qt'),(400,'4','q3plus.qt'),(1,'3','q3.net'),(3,'4','q3.net'),(3000,'20','threetrees.qt'); +# +# Bug #27758 Restoring NDB backups makes table usable in SQL nodes +# - space in key made table unusable after restore +# +# Bug #27775 - mediumint auto inc not restored correctly +# - check smallint +CREATE TABLE `t2_c` ( `capgotod` smallint(5) unsigned NOT NULL auto_increment, `gotod` smallint(5) unsigned NOT NULL default '0', `goaledatta` char(2) default NULL, @@ -24,18 +31,20 @@ CREATE TABLE `t2` ( `descrpooppo` varchar(64) default NULL, `svcutonsa` varchar(64) NOT NULL default '', PRIMARY KEY (`capgotod`), - KEY `i_quadaddsvr` (`gotod`) -) ENGINE=myisam DEFAULT CHARSET=latin1; -INSERT INTO `t2` VALUES (5,4,'','q3.net','addavp:MK_CASELECTOR=1','postorod rattoaa'),(2,1,'4','','addavp:MK_BRANDTAD=345','REDS Brandtad'),(3,2,'4','q3.net','execorder','fixedRatediPO REDS'),(1,1,'3','','addavp:MK_BRANDTAD=123','TEST Brandtad'),(6,5,'','told.q3.net','addavp:MK_BRANDTAD=123','Brandtad Toldzone'),(4,3,'3','q3.net','addavp:MK_POOLHINT=2','ratedi PO TEST'); + KEY `i quadaddsvr` (`gotod`) +) ENGINE=ndbcluster DEFAULT CHARSET=latin1; +INSERT INTO `t2_c` VALUES (500,4,'','q3.net','addavp:MK_CASELECTOR=1','postorod rattoaa'),(2,1,'4','','addavp:MK_BRANDTAD=345','REDS Brandtad'),(3,2,'4','q3.net','execorder','fixedRatediPO REDS'),(1,1,'3','','addavp:MK_BRANDTAD=123','TEST Brandtad'),(6,5,'','told.q3.net','addavp:MK_BRANDTAD=123','Brandtad Toldzone'),(4,3,'3','q3.net','addavp:MK_POOLHINT=2','ratedi PO TEST'); -CREATE TABLE `t3` ( +CREATE TABLE `t3_c` ( `CapGoaledatta` smallint(5) unsigned NOT NULL default '0', `capgotod` smallint(5) unsigned NOT NULL default '0', PRIMARY KEY (`capgotod`,`CapGoaledatta`) -) ENGINE=myisam DEFAULT CHARSET=latin1; -INSERT INTO `t3` VALUES (5,3),(2,4),(5,4),(1,3); +) ENGINE=ndbcluster DEFAULT CHARSET=latin1; +INSERT INTO `t3_c` VALUES (5,3),(2,4),(5,4),(1,3); -CREATE TABLE `t4` ( +# Bug #27775 - mediumint auto inc not restored correctly +# - check bigint +CREATE TABLE `t4_c` ( `capfa` bigint(20) unsigned NOT NULL auto_increment, `realm` varchar(32) NOT NULL default '', `authpwchap` varchar(32) default NULL, @@ -45,38 +54,40 @@ CREATE TABLE `t4` ( PRIMARY KEY (`fa`,`realm`), KEY `capfa` (`capfa`), KEY `i_quadentity` (`fa`,`realm`) -) ENGINE=myisam DEFAULT CHARSET=latin1; -INSERT INTO `t4` VALUES (18,'john.smith','q3.net','dessjohn.smith',0,NULL),(21,'quad_katt_with_brandtad','q3.net','acne',0,NULL),(22,'quad_katt_carattoaa','q3.net','acne',0,NULL),(26,'436462612809','sqasdt.q3.net','N/A',0,'6'),(19,'john','smith.qt','dessjohn',0,NULL),(33,'436643196120','sqasdt.q3.net','N/A',1,'6'),(28,'436642900019','sqasdt.q3.net','N/A',0,'6'),(30,'436462900209','sqasdt.q3.net','N/A',0,'6'),(16,'436640006666','sqasdt.q3.net','',0,NULL),(19,'dette','el-redun.com','dessdette',0,NULL),(12,'quad_kattPP','q3.net','acne',2,NULL),(14,'436640008888','sqasdt.q3.net','',0,NULL),(29,'463624900028','sqasdt.q3.net','N/A',0,'6'),(15,'436640099099','sqasdt.q3.net','',0,NULL),(13,'pap','q3plus.qt','acne',1,NULL),(19,'436642612091','sqasdt.q3.net','N/A',0,'6'),(12,'quad_katt','q3.net','acne',0,NULL),(11,'quad_kattVK','q3.net','acne',1,NULL),(32,'463641969502','sqasdt.q3.net','N/A',1,'6'),(20,'joe','q3.net','joedesswd',0,NULL),(29,'436642900034','sqasdt.q3.net','N/A',0,'6'),(25,'contind','armerde.qt','acne',1,NULL); +) ENGINE=ndbcluster DEFAULT CHARSET=latin1; +INSERT INTO `t4_c` VALUES (18,'john.smith','q3.net','dessjohn.smith',0,NULL),(21,'quad_katt_with_brandtad','q3.net','acne',0,NULL),(2200,'quad_katt_carattoaa','q3.net','acne',0,NULL),(26,'436462612809','sqasdt.q3.net','N/A',0,'6'),(19,'john','smith.qt','dessjohn',0,NULL),(33,'436643196120','sqasdt.q3.net','N/A',1,'6'),(28,'436642900019','sqasdt.q3.net','N/A',0,'6'),(30,'436462900209','sqasdt.q3.net','N/A',0,'6'),(16,'436640006666','sqasdt.q3.net','',0,NULL),(19,'dette','el-redun.com','dessdette',0,NULL),(12,'quad_kattPP','q3.net','acne',2,NULL),(14,'436640008888','sqasdt.q3.net','',0,NULL),(29,'463624900028','sqasdt.q3.net','N/A',0,'6'),(15,'436640099099','sqasdt.q3.net','',0,NULL),(13,'pap','q3plus.qt','acne',1,NULL),(19,'436642612091','sqasdt.q3.net','N/A',0,'6'),(12,'quad_katt','q3.net','acne',0,NULL),(11,'quad_kattVK','q3.net','acne',1,NULL),(32000,'463641969502','sqasdt.q3.net','N/A',1,'6'),(20,'joe','q3.net','joedesswd',0,NULL),(290000000,'436642900034','sqasdt.q3.net','N/A',0,'6'),(25,'contind','armerde.qt','acne',1,NULL); -CREATE TABLE `t5` ( +CREATE TABLE `t5_c` ( `capfa` bigint(20) unsigned NOT NULL default '0', `gotod` smallint(5) unsigned NOT NULL default '0', `orderutonsa` varchar(64) NOT NULL default '', PRIMARY KEY (`capfa`,`gotod`,`orderutonsa`) -) ENGINE=myisam DEFAULT CHARSET=latin1; -INSERT INTO `t5` VALUES (21,2,''),(21,1,''),(22,4,''); +) ENGINE=ndbcluster DEFAULT CHARSET=latin1; +INSERT INTO `t5_c` VALUES (21,2,''),(21,1,''),(22,4,''); -CREATE TABLE `t6` ( +CREATE TABLE `t6_c` ( `capfa_parent` bigint(20) unsigned NOT NULL default '0', `capfa_child` bigint(20) unsigned NOT NULL default '0', `relatta` smallint(5) unsigned NOT NULL default '0', PRIMARY KEY (`capfa_child`,`capfa_parent`,`relatta`) -) ENGINE=myisam DEFAULT CHARSET=latin1; -INSERT INTO `t6` VALUES (15,16,0),(19,20,0),(18326932092909551615,30,0),(26,29,0),(18326932092909551615,29,0),(19,18,0),(26,28,0),(12,14,0); +) ENGINE=ndbcluster DEFAULT CHARSET=latin1; +INSERT INTO `t6_c` VALUES (15,16,0),(19,20,0),(18326932092909551615,30,0),(26,29,0),(18326932092909551615,29,0),(19,18,0),(26,28,0),(12,14,0); -CREATE TABLE `t7` ( +# Bug #27775 - mediumint auto inc not restored correctly +# - check tinyint +CREATE TABLE `t7_c` ( `dardpo` char(15) NOT NULL default '', - `dardtestard` tinyint(3) unsigned NOT NULL default '0', + `dardtestard` tinyint(3) unsigned NOT NULL auto_increment, `FastFA` char(5) NOT NULL default '', `FastCode` char(6) NOT NULL default '', `Fastca` char(1) NOT NULL default '', `Fastmag` char(1) NOT NULL default '', `Beareratta` char(2) NOT NULL default '', PRIMARY KEY (`dardpo`,`dardtestard`) -) ENGINE=myisam DEFAULT CHARSET=latin1; -INSERT INTO `t7` VALUES ('2.6.2.4',24,'CECHP','54545','0','0','5'),('2.2.5.4',26,'CANFA','33223','1','1','4'),('4.3.2.4',28,'ITALD','54222','1','0','5'),('129..0.0.eins',28,'G','99999','1','1','5'),('1.1.1.1',24,'AUTPT','32323','0','1','3'); +) ENGINE=ndbcluster DEFAULT CHARSET=latin1; +INSERT INTO `t7_c` VALUES ('2.6.2.4',24,'CECHP','54545','0','0','5'),('2.2.5.4',26,'CANFA','33223','1','1','4'),('4.3.2.4',28,'ITALD','54222','1','0','5'),('129..0.0.eins',28,'G','99999','1','1','5'),('1.1.1.1',24,'AUTPT','32323','0','1','3'); -CREATE TABLE `t8` ( +CREATE TABLE `t8_c` ( `kattjame` varchar(32) NOT NULL default '', `realm` varchar(32) NOT NULL default '', `realm_entered` varchar(32) NOT NULL default '', @@ -102,10 +113,10 @@ CREATE TABLE `t8` ( `acctinputoctets` bigint(20) unsigned default NULL, PRIMARY KEY (`kattjame`,`hunderaaarbagefa`,`hassetistart`,`hassetino`), KEY `squardporoot` (`squardporoot`) -) ENGINE=myisam DEFAULT CHARSET=latin1; -INSERT INTO `t8` VALUES ('4tt45345235','pap','q3plus.qt','q3plus.qt','q3.net','436643196120','436643196929','8956234534568968','5524595699','uxasmt21.net.acne.qt/481889229462692422','','1.1.1.1','2.2.4.6','4','86989','34','x','x','2012-03-12 12:55:34','2012-12-05 11:20:04',3223433,3369,9565),('4545435545','john','q3.net','q3.net','acne.li','436643196120','436643196929','45345234568968','995696699','uxasmt21.net.acne.qt/481889229462692423','','1.1.1.1','2.2.9.8','2','86989','34','x','x','2012-03-12 11:35:03','2012-12-05 08:50:04',8821923,169,3565),('versteckter_q3net_katt','joe','q3.net','elredun.com','q3.net','436643196120','436643196939','91341234568968','695595699','uxasmt21.net.acne.qt/481889229462692421','','1.1.1.1','2.5.2.5','3','86989','34','x','x','2012-03-12 18:35:04','2012-12-05 12:35:04',1923123,9569,6565); +) ENGINE=ndbcluster DEFAULT CHARSET=latin1; +INSERT INTO `t8_c` VALUES ('4tt45345235','pap','q3plus.qt','q3plus.qt','q3.net','436643196120','436643196929','8956234534568968','5524595699','uxasmt21.net.acne.qt/481889229462692422','','1.1.1.1','2.2.4.6','4','86989','34','x','x','2012-03-12 12:55:34','2012-12-05 11:20:04',3223433,3369,9565),('4545435545','john','q3.net','q3.net','acne.li','436643196120','436643196929','45345234568968','995696699','uxasmt21.net.acne.qt/481889229462692423','','1.1.1.1','2.2.9.8','2','86989','34','x','x','2012-03-12 11:35:03','2012-12-05 08:50:04',8821923,169,3565),('versteckter_q3net_katt','joe','q3.net','elredun.com','q3.net','436643196120','436643196939','91341234568968','695595699','uxasmt21.net.acne.qt/481889229462692421','','1.1.1.1','2.5.2.5','3','86989','34','x','x','2012-03-12 18:35:04','2012-12-05 12:35:04',1923123,9569,6565); -CREATE TABLE `t9` ( +CREATE TABLE `t9_c` ( `kattjame` varchar(32) NOT NULL default '', `kattjame_entered` varchar(32) NOT NULL default '', `realm` varchar(32) NOT NULL default '', @@ -129,26 +140,29 @@ CREATE TABLE `t9` ( `actinputocctets` bigint(20) unsigned default NULL, `terminateraste` tinyint(3) unsigned default NULL, PRIMARY KEY (`kattjame`,`hunderaaarbagefa`,`hassetistart`,`hassetino`) -) ENGINE=myisam DEFAULT CHARSET=latin1; -INSERT INTO `t9` VALUES ('3g4jh8gar2t','joe','q3.net','elredun.com','q3.net','436643316120','436643316939','91341234568968','695595699','1.1.1.1','2.2.6.2','3','86989','34','x','x','2012-03-12 18:35:04','2012-12-05 12:35:04',3123123,9569,6565,1),('4tt45345235','pap','q3plus.qt','q3plus.qt','q3.net','436643316120','436643316939','8956234534568968','5254595969','1.1.1.1','8.6.2.2','4','86989','34','x','x','2012-03-12 12:55:34','2012-12-05 11:20:04',3223433,3369,9565,2),('4545435545','john','q3.net','q3.net','acne.li','436643316120','436643316939','45345234568968','995696699','1.1.1.1','2.9.9.2','2','86998','34','x','x','2012-03-12 11:35:03','2012-12-05 08:50:04',8823123,169,3565,3); +) ENGINE=ndbcluster DEFAULT CHARSET=latin1; +INSERT INTO `t9_c` VALUES ('3g4jh8gar2t','joe','q3.net','elredun.com','q3.net','436643316120','436643316939','91341234568968','695595699','1.1.1.1','2.2.6.2','3','86989','34','x','x','2012-03-12 18:35:04','2012-12-05 12:35:04',3123123,9569,6565,1),('4tt45345235','pap','q3plus.qt','q3plus.qt','q3.net','436643316120','436643316939','8956234534568968','5254595969','1.1.1.1','8.6.2.2','4','86989','34','x','x','2012-03-12 12:55:34','2012-12-05 11:20:04',3223433,3369,9565,2),('4545435545','john','q3.net','q3.net','acne.li','436643316120','436643316939','45345234568968','995696699','1.1.1.1','2.9.9.2','2','86998','34','x','x','2012-03-12 11:35:03','2012-12-05 08:50:04',8823123,169,3565,3); # Bug #20820 # auto inc table not handled correctly when restored from cluster backup # - before fix ndb_restore would not set auto inc value correct, # seen by select below -create table t10 (a int auto_increment key); -insert into t10 values (1),(2),(3); +create table t10_c (a int auto_increment key) ENGINE=ndbcluster; +insert into t10_c values (1),(2),(3); +# Bug #27775 - mediumint auto inc not restored correctly +# - check int +insert into t10_c values (10000),(2000),(3000); -create table t1_c engine=ndbcluster as select * from t1; -create table t2_c engine=ndbcluster as select * from t2; -create table t3_c engine=ndbcluster as select * from t3; -create table t4_c engine=ndbcluster as select * from t4; -create table t5_c engine=ndbcluster as select * from t5; -create table t6_c engine=ndbcluster as select * from t6; -create table t7_c engine=ndbcluster as select * from t7; -create table t8_c engine=ndbcluster as select * from t8; -create table t9_c engine=ndbcluster as select * from t9; -create table t10_c engine=ndbcluster as select * from t10; +create table t1 engine=myisam as select * from t1_c; +create table t2 engine=myisam as select * from t2_c; +create table t3 engine=myisam as select * from t3_c; +create table t4 engine=myisam as select * from t4_c; +create table t5 engine=myisam as select * from t5_c; +create table t6 engine=myisam as select * from t6_c; +create table t7 engine=myisam as select * from t7_c; +create table t8 engine=myisam as select * from t8_c; +create table t9 engine=myisam as select * from t9_c; +create table t10 engine=myisam as select * from t10_c; --exec $NDB_MGM --no-defaults -e "start backup" >> $NDB_TOOLS_OUTPUT @@ -215,6 +229,18 @@ select count(*) # Bug #20820 cont'd select * from t10_c order by a; +# Bug #27775 cont'd +# - auto inc info should be correct +--replace_column 1 X 2 X 3 X 4 X 5 X 6 X 7 X 8 X 9 X 10 X 12 X 13 X 14 X 15 X 16 X 17 X 18 X +show table status like 't1_c'; +--replace_column 1 X 2 X 3 X 4 X 5 X 6 X 7 X 8 X 9 X 10 X 12 X 13 X 14 X 15 X 16 X 17 X 18 X +show table status like 't2_c'; +--replace_column 1 X 2 X 3 X 4 X 5 X 6 X 7 X 8 X 9 X 10 X 12 X 13 X 14 X 15 X 16 X 17 X 18 X +show table status like 't4_c'; +--replace_column 1 X 2 X 3 X 4 X 5 X 6 X 7 X 8 X 9 X 10 X 12 X 13 X 14 X 15 X 16 X 17 X 18 X +show table status like 't7_c'; +--replace_column 1 X 2 X 3 X 4 X 5 X 6 X 7 X 8 X 9 X 10 X 12 X 13 X 14 X 15 X 16 X 17 X 18 X +show table status like 't10_c'; --disable_warnings drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9, t10; diff --git a/mysql-test/t/ndb_single_user.test b/mysql-test/t/ndb_single_user.test index f2f47becb0c..631d3800499 100644 --- a/mysql-test/t/ndb_single_user.test +++ b/mysql-test/t/ndb_single_user.test @@ -46,15 +46,18 @@ update t1 set b=b+100 where a > 7; # delete with full table scan delete from t1; insert into t1 select * from t2; +# Bug #27710 Creating unique index fails during single user mode +# - prior to bugfix this would fail +create unique index new_index on t1 (b,c); # test some sql on other mysqld --connection server2 --error 1051 drop table t1; --error 1296 -create index new_index on t1 (c); +create index new_index_fail on t1 (c); --error 1296 -insert into t1 values (1,1,0),(2,2,0),(3,3,0),(4,4,0),(5,5,0),(6,6,0),(7,7,0),(8,8,0),(9,9,0),(10,10,0); +insert into t1 values (21,21,0),(22,22,0),(23,23,0),(24,24,0),(25,25,0),(26,26,0),(27,27,0),(28,28,0),(29,29,0),(210,210,0); --error 1296 select * from t1 where a = 1; --error 1296 diff --git a/mysql-test/t/row.test b/mysql-test/t/row.test index 1d5c7a543ea..bf25359b7be 100644 --- a/mysql-test/t/row.test +++ b/mysql-test/t/row.test @@ -85,6 +85,31 @@ drop table t1; SELECT ROW(2,10) <=> ROW(3,4); SELECT ROW(NULL,10) <=> ROW(3,NULL); +# +# Bug #27484: nested row expressions in IN predicate +# + +--error 1241 +SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),ROW(1,1)); +--error 1241 +SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),ROW(1,1),ROW(1,ROW(2,3))); +--error 1241 +SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),ROW(1,ROW(2,2,2))); +--error 1241 +SELECT ROW(1,ROW(2,3,4)) IN (ROW(1,ROW(2,3,4)),ROW(1,ROW(2,2))); + +--error 1241 +SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),(SELECT 1,1)); +--error 1241 +SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),(SELECT 1,1),ROW(1,ROW(2,4))); +--error 1241 +SELECT ROW(1,ROW(2,3)) IN ((SELECT 1,1),ROW(1,ROW(2,3))); + +--error 1241 +SELECT ROW(2,1) IN (ROW(21,2),ROW(ROW(1,1,3),0)); +--error 1241 +SELECT ROW(2,1) IN (ROW(ROW(1,1,3),0),ROW(21,2)); + # End of 4.1 tests # diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index c5c7d07ee25..56b2f1b02b8 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -3357,4 +3357,17 @@ SELECT t2.faq_id DROP TABLE t1,t2; + +# +# Bug #19372: Optimizer does not use index anymore when WHERE index NOT IN +# () is added +# +CREATE TABLE t1 (a INT, b INT, KEY inx (b,a)); + +INSERT INTO t1 VALUES (1,1), (1,2), (1,3), (1,4), (1,5), (1, 6), (1,7); +EXPLAIN SELECT COUNT(*) FROM t1 f1 INNER JOIN t1 f2 + ON ( f1.b=f2.b AND f1.a<f2.a ) + WHERE 1 AND f1.b NOT IN (100,2232,3343,51111); +DROP TABLE t1; + --echo End of 5.0 tests diff --git a/mysql-test/t/strict.test b/mysql-test/t/strict.test index 5e4d956527b..1792c0fccbc 100644 --- a/mysql-test/t/strict.test +++ b/mysql-test/t/strict.test @@ -1249,4 +1249,13 @@ insert into t1 values ('2000a'); insert into t1 values ('2E3x'); drop table t1; +# +# Bug#27069 set with identical elements are created +# +set sql_mode='traditional'; +--error 1291 +create table t1 (f1 set('a','a')); +--error 1291 +create table t1 (f1 enum('a','a')); + --echo End of 5.0 tests diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 182b9b27ef7..482b3e883e6 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -2784,6 +2784,42 @@ SELECT COUNT(*) c, a, DROP table t1,t2; # +# Bug#27321: Wrong subquery result in a grouping select +# +CREATE TABLE t1 (a int, b INT, d INT, c CHAR(10) NOT NULL, PRIMARY KEY (a, b)); +INSERT INTO t1 VALUES (1,1,0,'a'), (1,2,0,'b'), (1,3,0,'c'), (1,4,0,'d'), +(1,5,0,'e'), (2,1,0,'f'), (2,2,0,'g'), (2,3,0,'h'), (3,4,0,'i'), (3,3,0,'j'), +(3,2,0,'k'), (3,1,0,'l'), (1,9,0,'m'), (1,0,10,'n'), (2,0,5,'o'), (3,0,7,'p'); + +SELECT a, MAX(b), + (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b + 0)) as test + FROM t1 GROUP BY a; +SELECT a x, MAX(b), + (SELECT t.c FROM t1 AS t WHERE x=t.a AND t.b=MAX(t1.b + 0)) as test + FROM t1 GROUP BY a; +SELECT a, AVG(b), + (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=AVG(t1.b)) AS test + FROM t1 WHERE t1.d=0 GROUP BY a; + +SELECT tt.a, + (SELECT (SELECT c FROM t1 as t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a) + LIMIT 1) FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test + FROM t1 as tt; + +SELECT tt.a, + (SELECT (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a) + LIMIT 1) + FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test + FROM t1 as tt GROUP BY tt.a; + +SELECT tt.a, MAX( + (SELECT (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a) + LIMIT 1) + FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1)) as test + FROM t1 as tt GROUP BY tt.a; + +DROP TABLE t1; +# # Bug #27348: SET FUNCTION used in a subquery from WHERE condition # diff --git a/mysql-test/t/subselect3.test b/mysql-test/t/subselect3.test index e8eae3e2452..11468cd6759 100644 --- a/mysql-test/t/subselect3.test +++ b/mysql-test/t/subselect3.test @@ -507,9 +507,6 @@ SELECT a, MAX(b), (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b)) SELECT * FROM t1 GROUP by t1.a HAVING (MAX(t1.b) > (SELECT MAX(t2.b) FROM t2 WHERE t2.c < t1.c HAVING MAX(t2.b+t1.a) < 10)); -#FIXME: Enable this test after fixing bug #27321 -#SELECT a, AVG(b), (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=AVG(t1.b)) -# AS test FROM t1 GROUP BY a; SELECT a,b,c FROM t1 WHERE b in (9,3,4) ORDER BY b,c; diff --git a/mysql-test/t/truncate.test b/mysql-test/t/truncate.test index f806bd8ec17..c52260124cb 100644 --- a/mysql-test/t/truncate.test +++ b/mysql-test/t/truncate.test @@ -52,3 +52,35 @@ SELECT * from t1; drop table t1; # End of 4.1 tests + +# Test for Bug#5507 "TRUNCATE should work with views" + +create table t1 (s1 int); + +insert into t1 (s1) values (1), (2), (3), (4), (5); +create view v1 as select * from t1; +truncate table v1; +select count(*) from t1; + +insert into t1 (s1) values (1), (2), (3), (4), (5); +create view v2 as select * from t1 where s1 > 3; +truncate table v2; +select * from t1; +select * from v2; +delete from t1; + +# The following should fail +create table t2 (s1 int, s2 int); +create view v3 as select a.s1, b.s2 from t1 a join t2 b on a.s1 = b.s1 where a.s1 > 3; +--error 1395 +truncate table v3; + +# The following should fail +create view v4 as select * from t1 limit 1,1; +--error 1288 +truncate table v4; + +drop view v1, v2, v3, v4; +drop table t1, t2; + +# End of 5.0 tests diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 1b229298896..920fcee3b24 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -2228,6 +2228,8 @@ REPAIR TABLE v1; DROP TABLE t1; OPTIMIZE TABLE v1; +ANALYZE TABLE v1; +REPAIR TABLE v1; DROP VIEW v1; diff --git a/mysys/my_memmem.c b/mysys/my_memmem.c index 682a1314f09..9230337409d 100644 --- a/mysys/my_memmem.c +++ b/mysys/my_memmem.c @@ -1,4 +1,20 @@ -#include "my_base.h" +/* Copyright (C) 2000 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include <my_global.h> +#include <m_string.h> /* my_memmem, port of a GNU extension. diff --git a/mysys/thr_alarm.c.rej b/mysys/thr_alarm.c.rej deleted file mode 100644 index c991121052e..00000000000 --- a/mysys/thr_alarm.c.rej +++ /dev/null @@ -1,220 +0,0 @@ -*************** -*** 76,96 **** - alarm_aborted=0; - init_queue(&alarm_queue,max_alarms+1,offsetof(ALARM,expire_time),0, - compare_ulong,NullS); -! sigfillset(&full_signal_set); /* Neaded to block signals */ - pthread_mutex_init(&LOCK_alarm,MY_MUTEX_INIT_FAST); - pthread_cond_init(&COND_alarm,NULL); -! #if THR_CLIENT_ALARM != SIGALRM || defined(USE_ALARM_THREAD) -! #if defined(HAVE_mit_thread) -! sigset(THR_CLIENT_ALARM,thread_alarm); /* int. thread system calls */ -! #else - { -! struct sigaction sact; -! sact.sa_flags = 0; -! sact.sa_handler = thread_alarm; -! sigaction(THR_CLIENT_ALARM, &sact, (struct sigaction*) 0); - } -- #endif -- #endif - sigemptyset(&s); - sigaddset(&s, THR_SERVER_ALARM); - alarm_thread=pthread_self(); ---- 74,89 ---- - alarm_aborted=0; - init_queue(&alarm_queue,max_alarms+1,offsetof(ALARM,expire_time),0, - compare_ulong,NullS); -! sigfillset(&full_signal_set); /* Needed to block signals */ - pthread_mutex_init(&LOCK_alarm,MY_MUTEX_INIT_FAST); - pthread_cond_init(&COND_alarm,NULL); -! #ifndef USE_ALARM_THREAD -! if (thd_lib_detected != THD_LIB_LT) -! #endif - { -! my_sigset(thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1, -! thread_alarm); - } - sigemptyset(&s); - sigaddset(&s, THR_SERVER_ALARM); - alarm_thread=pthread_self(); -*************** -*** 108,120 **** - } - #elif defined(USE_ONE_SIGNAL_HAND) - pthread_sigmask(SIG_BLOCK, &s, NULL); /* used with sigwait() */ -! #if THR_SERVER_ALARM == THR_CLIENT_ALARM -! sigset(THR_CLIENT_ALARM,process_alarm); /* Linuxthreads */ -! pthread_sigmask(SIG_UNBLOCK, &s, NULL); -! #endif - #else - pthread_sigmask(SIG_UNBLOCK, &s, NULL); -- sigset(THR_SERVER_ALARM,process_alarm); - #endif - DBUG_VOID_RETURN; - } ---- 101,115 ---- - } - #elif defined(USE_ONE_SIGNAL_HAND) - pthread_sigmask(SIG_BLOCK, &s, NULL); /* used with sigwait() */ -! if (thd_lib_detected == THD_LIB_LT) -! { -! my_sigset(thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1, -! process_alarm); /* Linuxthreads */ -! pthread_sigmask(SIG_UNBLOCK, &s, NULL); -! } - #else -+ my_sigset(THR_SERVER_ALARM, process_alarm); - pthread_sigmask(SIG_UNBLOCK, &s, NULL); - #endif - DBUG_VOID_RETURN; - } -*************** -*** 240,246 **** - if (alarm_data->malloced) - my_free((gptr) alarm_data,MYF(0)); - found++; -! #ifndef DBUG_OFF - break; - #endif - } ---- 235,241 ---- - if (alarm_data->malloced) - my_free((gptr) alarm_data,MYF(0)); - found++; -! #ifdef DBUG_OFF - break; - #endif - } -*************** -*** 249,258 **** - if (!found) - { - if (*alarmed) -! fprintf(stderr,"Warning: Didn't find alarm %lx in queue of %d alarms\n", -! (long) *alarmed, alarm_queue.elements); -! DBUG_PRINT("warning",("Didn't find alarm %lx in queue\n", -! (long) *alarmed)); - } - pthread_mutex_unlock(&LOCK_alarm); - pthread_sigmask(SIG_SETMASK,&old_mask,NULL); ---- 244,254 ---- - if (!found) - { - if (*alarmed) -! fprintf(stderr, -! "Warning: Didn't find alarm 0x%lx in queue of %d alarms\n", -! (long) *alarmed, alarm_queue.elements); -! DBUG_PRINT("warning",("Didn't find alarm 0x%lx in queue\n", -! (long) *alarmed)); - } - pthread_mutex_unlock(&LOCK_alarm); - pthread_sigmask(SIG_SETMASK,&old_mask,NULL); -*************** -*** 274,291 **** - This must be first as we can't call DBUG inside an alarm for a normal thread - */ - -! #if THR_SERVER_ALARM == THR_CLIENT_ALARM -! if (!pthread_equal(pthread_self(),alarm_thread)) - { - #if defined(MAIN) && !defined(__bsdi__) -! printf("thread_alarm\n"); fflush(stdout); - #endif - #ifdef DONT_REMEMBER_SIGNAL -! sigset(THR_CLIENT_ALARM,process_alarm); /* int. thread system calls */ - #endif - return; - } -- #endif - - /* - We have to do do the handling of the alarm in a sub function, ---- 270,287 ---- - This must be first as we can't call DBUG inside an alarm for a normal thread - */ - -! if (thd_lib_detected == THD_LIB_LT && -! !pthread_equal(pthread_self(),alarm_thread)) - { - #if defined(MAIN) && !defined(__bsdi__) -! printf("thread_alarm in process_alarm\n"); fflush(stdout); - #endif - #ifdef DONT_REMEMBER_SIGNAL -! my_sigset(thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1, -! process_alarm); /* int. thread system calls */ - #endif - return; - } - - /* - We have to do do the handling of the alarm in a sub function, -*************** -*** 301,307 **** - process_alarm_part2(sig); - #ifndef USE_ALARM_THREAD - #if defined(DONT_REMEMBER_SIGNAL) && !defined(USE_ONE_SIGNAL_HAND) -! sigset(THR_SERVER_ALARM,process_alarm); - #endif - pthread_mutex_unlock(&LOCK_alarm); - pthread_sigmask(SIG_SETMASK,&old_mask,NULL); ---- 297,303 ---- - process_alarm_part2(sig); - #ifndef USE_ALARM_THREAD - #if defined(DONT_REMEMBER_SIGNAL) && !defined(USE_ONE_SIGNAL_HAND) -! my_sigset(THR_SERVER_ALARM, process_alarm); - #endif - pthread_mutex_unlock(&LOCK_alarm); - pthread_sigmask(SIG_SETMASK,&old_mask,NULL); -*************** -*** 504,520 **** - ARGSUSED - */ - -- #if THR_CLIENT_ALARM != SIGALRM || defined(USE_ALARM_THREAD) - static sig_handler thread_alarm(int sig) - { - #ifdef MAIN - printf("thread_alarm\n"); fflush(stdout); - #endif - #ifdef DONT_REMEMBER_SIGNAL -! sigset(sig,thread_alarm); /* int. thread system calls */ - #endif - } -- #endif - - - #ifdef HAVE_TIMESPEC_TS_SEC ---- 499,513 ---- - ARGSUSED - */ - - static sig_handler thread_alarm(int sig) - { - #ifdef MAIN - printf("thread_alarm\n"); fflush(stdout); - #endif - #ifdef DONT_REMEMBER_SIGNAL -! my_sigset(sig, thread_alarm); /* int. thread system calls */ - #endif - } - - - #ifdef HAVE_TIMESPEC_TS_SEC -*************** -*** 915,921 **** - printf("Warning: Got signal %d from thread %s\n",sig,my_thread_name()); - fflush(stdout); - #ifdef DONT_REMEMBER_SIGNAL -! sigset(sig,print_signal_warning); /* int. thread system calls */ - #endif - #ifndef OS2 - if (sig == SIGALRM) ---- 908,914 ---- - printf("Warning: Got signal %d from thread %s\n",sig,my_thread_name()); - fflush(stdout); - #ifdef DONT_REMEMBER_SIGNAL -! my_sigset(sig, print_signal_warning); /* int. thread system calls */ - #endif - #ifndef OS2 - if (sig == SIGALRM) diff --git a/ndb/include/ndbapi/Ndb.hpp b/ndb/include/ndbapi/Ndb.hpp index 516333d1834..5af86cd09a8 100644 --- a/ndb/include/ndbapi/Ndb.hpp +++ b/ndb/include/ndbapi/Ndb.hpp @@ -1051,6 +1051,18 @@ class Ndb friend class NdbDictionaryImpl; friend class NdbDictInterface; friend class NdbBlob; + friend class Ndb_free_list_t<NdbRecAttr>; + friend class Ndb_free_list_t<NdbApiSignal>; + friend class Ndb_free_list_t<NdbLabel>; + friend class Ndb_free_list_t<NdbBranch>; + friend class Ndb_free_list_t<NdbSubroutine>; + friend class Ndb_free_list_t<NdbCall>; + friend class Ndb_free_list_t<NdbBlob>; + friend class Ndb_free_list_t<NdbReceiver>; + friend class Ndb_free_list_t<NdbIndexScanOperation>; + friend class Ndb_free_list_t<NdbOperation>; + friend class Ndb_free_list_t<NdbIndexOperation>; + friend class Ndb_free_list_t<NdbTransaction>; #endif public: @@ -1091,7 +1103,7 @@ public: * * @param aCatalogName is the new name of the current catalog */ - void setCatalogName(const char * aCatalogName); + int setCatalogName(const char * aCatalogName); /** * The current schema name can be fetched by getSchemaName. @@ -1105,7 +1117,7 @@ public: * * @param aSchemaName is the new name of the current schema */ - void setSchemaName(const char * aSchemaName); + int setSchemaName(const char * aSchemaName); #endif /** @@ -1120,7 +1132,7 @@ public: * * @param aDatabaseName is the new name of the current database */ - void setDatabaseName(const char * aDatabaseName); + int setDatabaseName(const char * aDatabaseName); /** * The current database schema name can be fetched by getDatabaseSchemaName. @@ -1134,7 +1146,7 @@ public: * * @param aDatabaseSchemaName is the new name of the current database schema */ - void setDatabaseSchemaName(const char * aDatabaseSchemaName); + int setDatabaseSchemaName(const char * aDatabaseSchemaName); /** * Initializes the Ndb object diff --git a/ndb/include/ndbapi/NdbDictionary.hpp b/ndb/include/ndbapi/NdbDictionary.hpp index 34686dd4db1..445bb513ffc 100644 --- a/ndb/include/ndbapi/NdbDictionary.hpp +++ b/ndb/include/ndbapi/NdbDictionary.hpp @@ -358,7 +358,7 @@ public: * Set name of column * @param name Name of the column */ - void setName(const char * name); + int setName(const char * name); /** * Set whether column is nullable or not @@ -446,7 +446,7 @@ public: void setAutoIncrement(bool); bool getAutoIncrement() const; void setAutoIncrementInitialValue(Uint64 val); - void setDefaultValue(const char*); + int setDefaultValue(const char*); const char* getDefaultValue() const; static const Column * FRAGMENT; @@ -661,13 +661,13 @@ public: * Name of table * @param name Name of table */ - void setName(const char * name); + int setName(const char * name); /** * Add a column definition to a table * @note creates a copy */ - void addColumn(const Column &); + int addColumn(const Column &); /** * @see NdbDictionary::Table::getLogging. @@ -723,7 +723,7 @@ public: /** * Set frm file to store with this table */ - void setFrm(const void* data, Uint32 len); + int setFrm(const void* data, Uint32 len); /** * Set table object type @@ -875,26 +875,26 @@ public: /** * Set the name of an index */ - void setName(const char * name); + int setName(const char * name); /** * Define the name of the table to be indexed */ - void setTable(const char * name); + int setTable(const char * name); /** * Add a column to the index definition * Note that the order of columns will be in * the order they are added (only matters for ordered indexes). */ - void addColumn(const Column & c); + int addColumn(const Column & c); /** * Add a column name to the index definition * Note that the order of indexes will be in * the order they are added (only matters for ordered indexes). */ - void addColumnName(const char * name); + int addColumnName(const char * name); #ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED /** @@ -903,7 +903,7 @@ public: * the order they are added (only matters for ordered indexes). * Depricated, use addColumnName instead. */ - void addIndexColumn(const char * name); + int addIndexColumn(const char * name); #endif /** @@ -911,7 +911,7 @@ public: * Note that the order of indexes will be in * the order they are added (only matters for ordered indexes). */ - void addColumnNames(unsigned noOfNames, const char ** names); + int addColumnNames(unsigned noOfNames, const char ** names); #ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED /** @@ -920,7 +920,7 @@ public: * the order they are added (only matters for ordered indexes). * Depricated, use addColumnNames instead. */ - void addIndexColumns(int noOfNames, const char ** names); + int addIndexColumns(int noOfNames, const char ** names); #endif /** diff --git a/ndb/include/ndbapi/NdbRecAttr.hpp b/ndb/include/ndbapi/NdbRecAttr.hpp index 7f8add774dc..f5777cdddb3 100644 --- a/ndb/include/ndbapi/NdbRecAttr.hpp +++ b/ndb/include/ndbapi/NdbRecAttr.hpp @@ -333,13 +333,6 @@ NdbRecAttr::int32_value() const } inline -Int32 -NdbRecAttr::medium_value() const -{ - return sint3korr((unsigned char *)theRef); -} - -inline short NdbRecAttr::short_value() const { @@ -361,13 +354,6 @@ NdbRecAttr::u_32_value() const } inline -Uint32 -NdbRecAttr::u_medium_value() const -{ - return uint3korr((unsigned char*)theRef); -} - -inline Uint16 NdbRecAttr::u_short_value() const { diff --git a/ndb/include/ndbapi/NdbReceiver.hpp b/ndb/include/ndbapi/NdbReceiver.hpp index 0af55c88f68..b8abd281496 100644 --- a/ndb/include/ndbapi/NdbReceiver.hpp +++ b/ndb/include/ndbapi/NdbReceiver.hpp @@ -38,7 +38,7 @@ public: }; NdbReceiver(Ndb *aNdb); - void init(ReceiverType type, void* owner); + int init(ReceiverType type, void* owner); void release(); ~NdbReceiver(); @@ -75,7 +75,7 @@ private: * At setup */ class NdbRecAttr * getValue(const class NdbColumnImpl*, char * user_dst_ptr); - void do_get_value(NdbReceiver*, Uint32 rows, Uint32 key_size, Uint32 range); + int do_get_value(NdbReceiver*, Uint32 rows, Uint32 key_size, Uint32 range); void prepareSend(); void calculate_batch_size(Uint32, Uint32, Uint32&, Uint32&, Uint32&); diff --git a/ndb/include/ndbapi/NdbTransaction.hpp b/ndb/include/ndbapi/NdbTransaction.hpp index 1a9c7158adf..d3405633f80 100644 --- a/ndb/include/ndbapi/NdbTransaction.hpp +++ b/ndb/include/ndbapi/NdbTransaction.hpp @@ -585,7 +585,7 @@ private: NdbTransaction(Ndb* aNdb); ~NdbTransaction(); - void init(); // Initialize connection object for new transaction + int init(); // Initialize connection object for new transaction int executeNoBlobs(ExecType execType, AbortOption abortOption = AbortOnError, diff --git a/ndb/include/util/BaseString.hpp b/ndb/include/util/BaseString.hpp index 44e1e4614be..34ca2d2be3d 100644 --- a/ndb/include/util/BaseString.hpp +++ b/ndb/include/util/BaseString.hpp @@ -185,6 +185,7 @@ public: private: char* m_chr; unsigned m_len; + friend bool operator!(const BaseString& str); }; inline const char* @@ -249,6 +250,12 @@ BaseString::operator!=(const char *str) const return strcmp(m_chr, str) != 0; } +inline bool +operator!(const BaseString& str) +{ + return str.m_chr == NULL; +} + inline BaseString& BaseString::assign(const BaseString& str) { diff --git a/ndb/include/util/Vector.hpp b/ndb/include/util/Vector.hpp index aeddbbb22f0..8f403b435dd 100644 --- a/ndb/include/util/Vector.hpp +++ b/ndb/include/util/Vector.hpp @@ -29,14 +29,14 @@ public: const T& operator[](unsigned i) const; unsigned size() const { return m_size; }; - void push_back(const T &); + int push_back(const T &); T& back(); void erase(unsigned index); void clear(); - void fill(unsigned new_size, T & obj); + int fill(unsigned new_size, T & obj); Vector<T>& operator=(const Vector<T>&); @@ -52,6 +52,14 @@ private: template<class T> Vector<T>::Vector(int i){ m_items = new T[i]; + if (m_items == NULL) + { + errno = ENOMEM; + m_size = 0; + m_arraySize = 0; + m_incSize = 0; + return; + } m_size = 0; m_arraySize = i; m_incSize = 50; @@ -89,12 +97,15 @@ Vector<T>::back(){ } template<class T> -void +int Vector<T>::push_back(const T & t){ if(m_size == m_arraySize){ T * tmp = new T [m_arraySize + m_incSize]; - if(!tmp) - abort(); + if(tmp == NULL) + { + errno = ENOMEM; + return -1; + } for (unsigned k = 0; k < m_size; k++) tmp[k] = m_items[k]; delete[] m_items; @@ -103,6 +114,8 @@ Vector<T>::push_back(const T & t){ } m_items[m_size] = t; m_size++; + + return 0; } template<class T> @@ -123,10 +136,12 @@ Vector<T>::clear(){ } template<class T> -void +int Vector<T>::fill(unsigned new_size, T & obj){ while(m_size <= new_size) - push_back(obj); + if (push_back(obj)) + return -1; + return 0; } template<class T> @@ -150,8 +165,8 @@ struct MutexVector : public NdbLockable { const T& operator[](unsigned i) const; unsigned size() const { return m_size; }; - void push_back(const T &); - void push_back(const T &, bool lockMutex); + int push_back(const T &); + int push_back(const T &, bool lockMutex); T& back(); void erase(unsigned index); @@ -160,7 +175,7 @@ struct MutexVector : public NdbLockable { void clear(); void clear(bool lockMutex); - void fill(unsigned new_size, T & obj); + int fill(unsigned new_size, T & obj); private: T * m_items; unsigned m_size; @@ -171,6 +186,14 @@ private: template<class T> MutexVector<T>::MutexVector(int i){ m_items = new T[i]; + if (m_items == NULL) + { + errno = ENOMEM; + m_size = 0; + m_arraySize = 0; + m_incSize = 0; + return; + } m_size = 0; m_arraySize = i; m_incSize = 50; @@ -208,11 +231,17 @@ MutexVector<T>::back(){ } template<class T> -void +int MutexVector<T>::push_back(const T & t){ lock(); if(m_size == m_arraySize){ T * tmp = new T [m_arraySize + m_incSize]; + if (tmp == NULL) + { + errno = ENOMEM; + unlock(); + return -1; + } for (unsigned k = 0; k < m_size; k++) tmp[k] = m_items[k]; delete[] m_items; @@ -222,15 +251,23 @@ MutexVector<T>::push_back(const T & t){ m_items[m_size] = t; m_size++; unlock(); + return 0; } template<class T> -void +int MutexVector<T>::push_back(const T & t, bool lockMutex){ if(lockMutex) lock(); if(m_size == m_arraySize){ T * tmp = new T [m_arraySize + m_incSize]; + if (tmp == NULL) + { + errno = ENOMEM; + if(lockMutex) + unlock(); + return -1; + } for (unsigned k = 0; k < m_size; k++) tmp[k] = m_items[k]; delete[] m_items; @@ -241,6 +278,7 @@ MutexVector<T>::push_back(const T & t, bool lockMutex){ m_size++; if(lockMutex) unlock(); + return 0; } template<class T> @@ -288,10 +326,12 @@ MutexVector<T>::clear(bool l){ } template<class T> -void +int MutexVector<T>::fill(unsigned new_size, T & obj){ while(m_size <= new_size) - push_back(obj); + if (push_back(obj)) + return -1; + return 0; } #endif diff --git a/ndb/src/common/util/BaseString.cpp b/ndb/src/common/util/BaseString.cpp index 6f20ae6a002..7e5adf0e9ef 100644 --- a/ndb/src/common/util/BaseString.cpp +++ b/ndb/src/common/util/BaseString.cpp @@ -16,19 +16,36 @@ /* -*- c-basic-offset: 4; -*- */ #include <ndb_global.h> #include <BaseString.hpp> -#include <basestring_vsnprintf.h> +#include "basestring_vsnprintf.h" BaseString::BaseString() { m_chr = new char[1]; + if (m_chr == NULL) + { + errno = ENOMEM; + m_len = 0; + return; + } m_chr[0] = 0; m_len = 0; } BaseString::BaseString(const char* s) { + if (s == NULL) + { + m_chr = NULL; + m_len = 0; + } const size_t n = strlen(s); m_chr = new char[n + 1]; + if (m_chr == NULL) + { + errno = ENOMEM; + m_len = 0; + return; + } memcpy(m_chr, s, n + 1); m_len = n; } @@ -37,7 +54,20 @@ BaseString::BaseString(const BaseString& str) { const char* const s = str.m_chr; const size_t n = str.m_len; + if (s == NULL) + { + m_chr = NULL; + m_len = 0; + return; + } char* t = new char[n + 1]; + if (t == NULL) + { + errno = ENOMEM; + m_chr = NULL; + m_len = 0; + return; + } memcpy(t, s, n + 1); m_chr = t; m_len = n; @@ -51,9 +81,23 @@ BaseString::~BaseString() BaseString& BaseString::assign(const char* s) { - const size_t n = strlen(s); + if (s == NULL) + { + m_chr = NULL; + m_len = 0; + return *this; + } + size_t n = strlen(s); char* t = new char[n + 1]; - memcpy(t, s, n + 1); + if (t) + { + memcpy(t, s, n + 1); + } + else + { + errno = ENOMEM; + n = 0; + } delete[] m_chr; m_chr = t; m_len = n; @@ -64,8 +108,16 @@ BaseString& BaseString::assign(const char* s, size_t n) { char* t = new char[n + 1]; - memcpy(t, s, n); - t[n] = 0; + if (t) + { + memcpy(t, s, n); + t[n] = 0; + } + else + { + errno = ENOMEM; + n = 0; + } delete[] m_chr; m_chr = t; m_len = n; @@ -83,10 +135,19 @@ BaseString::assign(const BaseString& str, size_t n) BaseString& BaseString::append(const char* s) { - const size_t n = strlen(s); + size_t n = strlen(s); char* t = new char[m_len + n + 1]; - memcpy(t, m_chr, m_len); - memcpy(t + m_len, s, n + 1); + if (t) + { + memcpy(t, m_chr, m_len); + memcpy(t + m_len, s, n + 1); + } + else + { + errno = ENOMEM; + m_len = 0; + n = 0; + } delete[] m_chr; m_chr = t; m_len += n; @@ -130,8 +191,14 @@ BaseString::assfmt(const char *fmt, ...) l = basestring_vsnprintf(buf, sizeof(buf), fmt, ap) + 1; va_end(ap); if(l > (int)m_len) { + char *t = new char[l]; + if (t == NULL) + { + errno = ENOMEM; + return *this; + } delete[] m_chr; - m_chr = new char[l]; + m_chr = t; } va_start(ap, fmt); basestring_vsnprintf(m_chr, l, fmt, ap); @@ -155,6 +222,11 @@ BaseString::appfmt(const char *fmt, ...) l = basestring_vsnprintf(buf, sizeof(buf), fmt, ap) + 1; va_end(ap); char *tmp = new char[l]; + if (tmp == NULL) + { + errno = ENOMEM; + return *this; + } va_start(ap, fmt); basestring_vsnprintf(tmp, l, fmt, ap); va_end(ap); @@ -242,9 +314,28 @@ BaseString::argify(const char *argv0, const char *src) { Vector<char *> vargv; if(argv0 != NULL) - vargv.push_back(strdup(argv0)); + { + char *t = strdup(argv0); + if (t == NULL) + { + errno = ENOMEM; + return NULL; + } + if (vargv.push_back(t)) + { + free(t); + return NULL; + } + } char *tmp = new char[strlen(src)+1]; + if (tmp == NULL) + { + for(size_t i = 0; i < vargv.size(); i++) + free(vargv[i]); + errno = ENOMEM; + return NULL; + } char *dst = tmp; const char *end = src + strlen(src); /* Copy characters from src to destination, while compacting them @@ -287,20 +378,48 @@ BaseString::argify(const char *argv0, const char *src) { /* Make sure the string is properly terminated */ *dst++ = '\0'; src++; - - vargv.push_back(strdup(begin)); + + { + char *t = strdup(begin); + if (t == NULL) + { + delete[] tmp; + for(size_t i = 0; i < vargv.size(); i++) + free(vargv[i]); + errno = ENOMEM; + return NULL; + } + if (vargv.push_back(t)) + { + free(t); + delete[] tmp; + for(size_t i = 0; i < vargv.size(); i++) + free(vargv[i]); + return NULL; + } + } } end: delete[] tmp; - vargv.push_back(NULL); + if (vargv.push_back(NULL)) + { + for(size_t i = 0; i < vargv.size(); i++) + free(vargv[i]); + return NULL; + } /* Convert the C++ Vector into a C-vector of strings, suitable for * calling execv(). */ char **argv = (char **)malloc(sizeof(*argv) * (vargv.size())); if(argv == NULL) + { + for(size_t i = 0; i < vargv.size(); i++) + free(vargv[i]); + errno = ENOMEM; return NULL; + } for(size_t i = 0; i < vargv.size(); i++){ argv[i] = vargv[i]; diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp index b8e2cfca41e..8f8e8fdfae3 100644 --- a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp +++ b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp @@ -6883,6 +6883,7 @@ Dbdict::createIndex_toCreateTable(Signal* signal, OpCreateIndexPtr opPtr) w.add(DictTabInfo::NoOfKeyAttr, indexPtr.p->noOfPrimkey); w.add(DictTabInfo::NoOfNullable, indexPtr.p->noOfNullAttr); w.add(DictTabInfo::KeyLength, indexPtr.p->tupKeyLength); + w.add(DictTabInfo::SingleUserMode, (Uint32)1); // write index key attributes AttributeRecordPtr aRecPtr; c_attributeRecordPool.getPtr(aRecPtr, tablePtr.p->firstAttribute); diff --git a/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp b/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp index 017b0ec5b92..71cfa98b68b 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp @@ -389,6 +389,7 @@ Dbtup::commitRecord(Signal* signal, fragptr.p = regFragPtr; tabptr.p = regTabPtr; + Uint32 hashValue = firstOpPtr.p->hashValue; if (opType == ZINSERT_DELETE) { ljam(); @@ -411,6 +412,7 @@ Dbtup::commitRecord(Signal* signal, //-------------------------------------------------------------------- Uint32 saveOpType = regOperPtr->optype; regOperPtr->optype = ZINSERT; + regOperPtr->hashValue = hashValue; operPtr.p = regOperPtr; checkDetachedTriggers(signal, @@ -443,6 +445,8 @@ Dbtup::commitRecord(Signal* signal, befOpPtr.p->changeMask.clear(); befOpPtr.p->changeMask.bitOR(attributeMask); befOpPtr.p->gci = regOperPtr->gci; + befOpPtr.p->optype = ZUPDATE; + befOpPtr.p->hashValue = hashValue; befOpPtr.p->optype = opType; operPtr.p = befOpPtr.p; @@ -477,11 +481,13 @@ Dbtup::commitRecord(Signal* signal, Uint32 fragPageId = befOpPtr.p->fragPageId; Uint32 pageIndex = befOpPtr.p->pageIndex; + befOpPtr.p->optype = ZDELETE; befOpPtr.p->realPageId = befOpPtr.p->realPageIdC; befOpPtr.p->pageOffset = befOpPtr.p->pageOffsetC; befOpPtr.p->fragPageId = befOpPtr.p->fragPageIdC; befOpPtr.p->pageIndex = befOpPtr.p->pageIndexC; befOpPtr.p->gci = regOperPtr->gci; + befOpPtr.p->hashValue = hashValue; befOpPtr.p->optype = opType; operPtr.p = befOpPtr.p; diff --git a/ndb/src/ndbapi/DictCache.cpp b/ndb/src/ndbapi/DictCache.cpp index 82e8d82bc24..6a815067233 100644 --- a/ndb/src/ndbapi/DictCache.cpp +++ b/ndb/src/ndbapi/DictCache.cpp @@ -141,7 +141,7 @@ void GlobalDictCache::printCache() } NdbTableImpl * -GlobalDictCache::get(const char * name) +GlobalDictCache::get(const char * name, int *error) { DBUG_ENTER("GlobalDictCache::get"); DBUG_PRINT("enter", ("name: %s", name)); @@ -151,6 +151,11 @@ GlobalDictCache::get(const char * name) versions = m_tableHash.getData(name, len); if(versions == 0){ versions = new Vector<TableVersion>(2); + if (versions == NULL) + { + *error = -1; + DBUG_RETURN(0); + } m_tableHash.insertKey(name, len, 0, versions); } @@ -180,7 +185,11 @@ GlobalDictCache::get(const char * name) tmp.m_impl = 0; tmp.m_status = RETREIVING; tmp.m_refCount = 1; // The one retreiving it - versions->push_back(tmp); + if (versions->push_back(tmp)) + { + *error = -1; + DBUG_RETURN(0); + } DBUG_RETURN(0); } diff --git a/ndb/src/ndbapi/DictCache.hpp b/ndb/src/ndbapi/DictCache.hpp index 4b569c114c9..db90a07d487 100644 --- a/ndb/src/ndbapi/DictCache.hpp +++ b/ndb/src/ndbapi/DictCache.hpp @@ -67,7 +67,7 @@ public: GlobalDictCache(); ~GlobalDictCache(); - NdbTableImpl * get(const char * name); + NdbTableImpl * get(const char * name, int *error); NdbTableImpl* put(const char * name, NdbTableImpl *); void drop(NdbTableImpl *); diff --git a/ndb/src/ndbapi/Makefile.am b/ndb/src/ndbapi/Makefile.am index 85013b540dc..1a5d10eae5b 100644 --- a/ndb/src/ndbapi/Makefile.am +++ b/ndb/src/ndbapi/Makefile.am @@ -48,7 +48,8 @@ libndbapi_la_SOURCES = \ DictCache.cpp \ ndb_cluster_connection.cpp \ NdbBlob.cpp \ - SignalSender.cpp + SignalSender.cpp \ + ObjectMap.cpp INCLUDES_LOC = -I$(top_srcdir)/ndb/src/mgmapi diff --git a/ndb/src/ndbapi/Ndb.cpp b/ndb/src/ndbapi/Ndb.cpp index 57077559c49..449f287dc1d 100644 --- a/ndb/src/ndbapi/Ndb.cpp +++ b/ndb/src/ndbapi/Ndb.cpp @@ -182,6 +182,7 @@ Ndb::NDB_connect(Uint32 tNode) nodeSequence = tp->getNodeSequence(tNode); bool node_is_alive = tp->get_node_alive(tNode); if (node_is_alive) { + DBUG_PRINT("info",("Sending signal to node %u", tNode)); tReturnCode = tp->sendSignal(tSignal, tNode); releaseSignal(tSignal); if (tReturnCode != -1) { @@ -449,7 +450,11 @@ Ndb::startTransactionLocal(Uint32 aPriority, Uint32 nodeId) theRemainingStartTransactions--; NdbTransaction* tConNext = theTransactionList; - tConnection->init(); + if (tConnection->init()) + { + theError.code = tConnection->theError.code; + DBUG_RETURN(NULL); + } theTransactionList = tConnection; // into a transaction list. tConnection->next(tConNext); // Add the active connection object tConnection->setTransactionId(tFirstTransId); @@ -1129,28 +1134,37 @@ const char * Ndb::getCatalogName() const } -void Ndb::setCatalogName(const char * a_catalog_name) +int Ndb::setCatalogName(const char * a_catalog_name) { if (a_catalog_name) { - theImpl->m_dbname.assign(a_catalog_name); - theImpl->update_prefix(); + if (!theImpl->m_dbname.assign(a_catalog_name) || + theImpl->update_prefix()) + { + theError.code = 4000; + return -1; + } } + return 0; } - const char * Ndb::getSchemaName() const { return theImpl->m_schemaname.c_str(); } -void Ndb::setSchemaName(const char * a_schema_name) +int Ndb::setSchemaName(const char * a_schema_name) { if (a_schema_name) { - theImpl->m_schemaname.assign(a_schema_name); - theImpl->update_prefix(); + if (!theImpl->m_schemaname.assign(a_schema_name) || + theImpl->update_prefix()) + { + theError.code = 4000; + return -1; + } } + return 0; } /* @@ -1161,9 +1175,9 @@ const char * Ndb::getDatabaseName() const return getCatalogName(); } -void Ndb::setDatabaseName(const char * a_catalog_name) +int Ndb::setDatabaseName(const char * a_catalog_name) { - setCatalogName(a_catalog_name); + return setCatalogName(a_catalog_name); } const char * Ndb::getDatabaseSchemaName() const @@ -1171,9 +1185,9 @@ const char * Ndb::getDatabaseSchemaName() const return getSchemaName(); } -void Ndb::setDatabaseSchemaName(const char * a_schema_name) +int Ndb::setDatabaseSchemaName(const char * a_schema_name) { - setSchemaName(a_schema_name); + return setSchemaName(a_schema_name); } bool Ndb::usingFullyQualifiedNames() @@ -1287,6 +1301,11 @@ const BaseString Ndb::getDatabaseFromInternalName(const char * internalName) { char * databaseName = new char[strlen(internalName) + 1]; + if (databaseName == NULL) + { + errno = ENOMEM; + return BaseString(NULL); + } strcpy(databaseName, internalName); register char *ptr = databaseName; @@ -1303,6 +1322,11 @@ const BaseString Ndb::getSchemaFromInternalName(const char * internalName) { char * schemaName = new char[strlen(internalName)]; + if (schemaName == NULL) + { + errno = ENOMEM; + return BaseString(NULL); + } register const char *ptr1 = internalName; /* Scan name for the second table_name_separator */ diff --git a/ndb/src/ndbapi/NdbDictionary.cpp b/ndb/src/ndbapi/NdbDictionary.cpp index 0a52f62aa01..86a6624959e 100644 --- a/ndb/src/ndbapi/NdbDictionary.cpp +++ b/ndb/src/ndbapi/NdbDictionary.cpp @@ -52,9 +52,9 @@ NdbDictionary::Column::operator=(const NdbDictionary::Column& column) return *this; } -void +int NdbDictionary::Column::setName(const char * name){ - m_impl.m_name.assign(name); + return !m_impl.m_name.assign(name); } const char* @@ -208,10 +208,10 @@ NdbDictionary::Column::setAutoIncrementInitialValue(Uint64 val){ m_impl.m_autoIncrementInitialValue = val; } -void +int NdbDictionary::Column::setDefaultValue(const char* defaultValue) { - m_impl.m_defaultValue.assign(defaultValue); + return !m_impl.m_defaultValue.assign(defaultValue); } const char* @@ -273,9 +273,9 @@ NdbDictionary::Table::operator=(const NdbDictionary::Table& table) return *this; } -void +int NdbDictionary::Table::setName(const char * name){ - m_impl.setName(name); + return m_impl.setName(name); } const char * @@ -288,18 +288,30 @@ NdbDictionary::Table::getTableId() const { return m_impl.m_tableId; } -void +int NdbDictionary::Table::addColumn(const Column & c){ NdbColumnImpl* col = new NdbColumnImpl; + if (col == NULL) + { + errno = ENOMEM; + return -1; + } (* col) = NdbColumnImpl::getImpl(c); - m_impl.m_columns.push_back(col); + if (m_impl.m_columns.push_back(col)) + { + return -1; + } if(c.getPrimaryKey()){ m_impl.m_noOfKeys++; } if (col->getBlobType()) { m_impl.m_noOfBlobs++; } - m_impl.buildColumnHash(); + if (m_impl.buildColumnHash()) + { + return -1; + } + return 0; } const NdbDictionary::Column* @@ -442,9 +454,9 @@ NdbDictionary::Table::setSingleUserMode(enum NdbDictionary::Table::SingleUserMod m_impl.m_single_user_mode = (Uint8)mode; } -void +int NdbDictionary::Table::setFrm(const void* data, Uint32 len){ - m_impl.m_frm.assign(data, len); + return m_impl.m_frm.assign(data, len); } NdbDictionary::Object::Status @@ -491,6 +503,7 @@ NdbDictionary::Table::createTableInDb(Ndb* pNdb, bool equalOk) const { /***************************************************************** * Index facade */ + NdbDictionary::Index::Index(const char * name) : m_impl(* new NdbIndexImpl(* this)) { @@ -509,9 +522,9 @@ NdbDictionary::Index::~Index(){ } } -void +int NdbDictionary::Index::setName(const char * name){ - m_impl.setName(name); + return m_impl.setName(name); } const char * @@ -519,9 +532,9 @@ NdbDictionary::Index::getName() const { return m_impl.getName(); } -void +int NdbDictionary::Index::setTable(const char * table){ - m_impl.setTable(table); + return m_impl.setTable(table); } const char * @@ -556,39 +569,56 @@ NdbDictionary::Index::getIndexColumn(int no) const { return NULL; } -void +int NdbDictionary::Index::addColumn(const Column & c){ NdbColumnImpl* col = new NdbColumnImpl; + if (col == NULL) + { + errno = ENOMEM; + return -1; + } (* col) = NdbColumnImpl::getImpl(c); - m_impl.m_columns.push_back(col); + if (m_impl.m_columns.push_back(col)) + { + return -1; + } + return 0; } -void +int NdbDictionary::Index::addColumnName(const char * name){ const Column c(name); - addColumn(c); + return addColumn(c); } -void +int NdbDictionary::Index::addIndexColumn(const char * name){ const Column c(name); - addColumn(c); + return addColumn(c); } -void +int NdbDictionary::Index::addColumnNames(unsigned noOfNames, const char ** names){ for(unsigned i = 0; i < noOfNames; i++) { const Column c(names[i]); - addColumn(c); + if (addColumn(c)) + { + return -1; + } } + return 0; } -void +int NdbDictionary::Index::addIndexColumns(int noOfNames, const char ** names){ for(int i = 0; i < noOfNames; i++) { const Column c(names[i]); - addColumn(c); + if (addColumn(c)) + { + return -1; + } } + return 0; } void diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/ndb/src/ndbapi/NdbDictionaryImpl.cpp index 8604d50830d..3fed04de26d 100644 --- a/ndb/src/ndbapi/NdbDictionaryImpl.cpp +++ b/ndb/src/ndbapi/NdbDictionaryImpl.cpp @@ -390,22 +390,34 @@ NdbTableImpl::equal(const NdbTableImpl& obj) const DBUG_RETURN(true); } -void +int NdbTableImpl::assign(const NdbTableImpl& org) { m_tableId = org.m_tableId; - m_internalName.assign(org.m_internalName); - m_externalName.assign(org.m_externalName); - m_newExternalName.assign(org.m_newExternalName); - m_frm.assign(org.m_frm.get_data(), org.m_frm.length()); + if (!m_internalName.assign(org.m_internalName) || + !m_externalName.assign(org.m_externalName) || + !m_newExternalName.assign(org.m_newExternalName) || + m_frm.assign(org.m_frm.get_data(), org.m_frm.length())) + { + return -1; + } m_fragmentType = org.m_fragmentType; m_fragmentCount = org.m_fragmentCount; for(unsigned i = 0; i<org.m_columns.size(); i++){ NdbColumnImpl * col = new NdbColumnImpl(); + if (col == NULL) + { + errno = ENOMEM; + return -1; + } const NdbColumnImpl * iorg = org.m_columns[i]; (* col) = (* iorg); - m_columns.push_back(col); + if (m_columns.push_back(col)) + { + delete col; + return -1; + } } m_logging = org.m_logging; @@ -428,11 +440,13 @@ NdbTableImpl::assign(const NdbTableImpl& org) m_max_rows = org.m_max_rows; m_min_rows = org.m_min_rows; + + return 0; } -void NdbTableImpl::setName(const char * name) +int NdbTableImpl::setName(const char * name) { - m_newExternalName.assign(name); + return !m_newExternalName.assign(name); } const char * @@ -445,7 +459,7 @@ NdbTableImpl::getName() const } -void +int NdbTableImpl::buildColumnHash(){ const Uint32 size = m_columns.size(); @@ -458,19 +472,29 @@ NdbTableImpl::buildColumnHash(){ } Vector<Uint32> hashValues; - Vector<Vector<Uint32> > chains; chains.fill(size, hashValues); + Vector<Vector<Uint32> > chains; + if (chains.fill(size, hashValues)) + { + return -1; + } for(i = 0; i< (int) size; i++){ Uint32 hv = Hash(m_columns[i]->getName()) & 0xFFFE; Uint32 bucket = hv & m_columnHashMask; bucket = (bucket < size ? bucket : bucket - size); assert(bucket < size); - hashValues.push_back(hv); - chains[bucket].push_back(i); + if (hashValues.push_back(hv) || + chains[bucket].push_back(i)) + { + return -1; + } } m_columnHash.clear(); Uint32 tmp = 1; - m_columnHash.fill((unsigned)size-1, tmp); // Default no chaining + if (m_columnHash.fill((unsigned)size-1, tmp)) // Default no chaining + { + return -1; + } Uint32 pos = 0; // In overflow vector for(i = 0; i< (int) size; i++){ @@ -490,12 +514,18 @@ NdbTableImpl::buildColumnHash(){ for(size_t j = 0; j<sz; j++, pos++){ Uint32 col = chains[i][j]; Uint32 hv = hashValues[col]; - m_columnHash.push_back((col << 16) | hv); + if (m_columnHash.push_back((col << 16) | hv)) + { + return -1; + } } } } - m_columnHash.push_back(0); // Overflow when looping in end of array + if (m_columnHash.push_back(0)) // Overflow when looping in end of array + { + return -1; + } #if 0 for(size_t i = 0; i<m_columnHash.size(); i++){ @@ -510,6 +540,7 @@ NdbTableImpl::buildColumnHash(){ i, col > 0 ? m_columns[col]->getName() : "" , m_columnHash[i]); } #endif + return 0; } Uint32 @@ -563,9 +594,9 @@ NdbIndexImpl::~NdbIndexImpl(){ delete m_columns[i]; } -void NdbIndexImpl::setName(const char * name) +int NdbIndexImpl::setName(const char * name) { - m_externalName.assign(name); + return !m_externalName.assign(name); } const char * @@ -574,10 +605,10 @@ NdbIndexImpl::getName() const return m_externalName.c_str(); } -void +int NdbIndexImpl::setTable(const char * table) { - m_tableName.assign(table); + return !m_tableName.assign(table); } const char * @@ -657,14 +688,18 @@ Ndb_local_table_info * NdbDictionaryImpl::fetchGlobalTableImpl(const BaseString& internalTableName) { NdbTableImpl *impl; + int error= 0; m_globalHash->lock(); - impl = m_globalHash->get(internalTableName.c_str()); + impl = m_globalHash->get(internalTableName.c_str(), &error); m_globalHash->unlock(); if (impl == 0){ - impl = m_receiver.getTable(internalTableName, - m_ndb.usingFullyQualifiedNames()); + if (error == 0) + impl = m_receiver.getTable(internalTableName, + m_ndb.usingFullyQualifiedNames()); + else + m_error.code = 4000; m_globalHash->lock(); m_globalHash->put(internalTableName.c_str(), impl); m_globalHash->unlock(); @@ -998,12 +1033,20 @@ NdbDictInterface::getTable(const BaseString& name, bool fullyQualifiedNames) // Copy name to m_buffer to get a word sized buffer m_buffer.clear(); - m_buffer.grow(namelen_words*4+4); - m_buffer.append(name.c_str(), namelen); + if (m_buffer.grow(namelen_words*4+4) || + m_buffer.append(name.c_str(), namelen)) + { + m_error.code= 4000; + return NULL; + } #ifndef IGNORE_VALGRIND_WARNINGS Uint32 pad = 0; - m_buffer.append(&pad, 4); + if (m_buffer.append(&pad, 4)) + { + m_error.code= 4000; + return NULL; + } #endif LinearSectionPtr ptr[1]; @@ -1034,7 +1077,14 @@ NdbDictInterface::getTable(class NdbApiSignal * signal, (Uint32*)m_buffer.get_data(), m_buffer.length() / 4, fullyQualifiedNames); if (rt != 0) - rt->buildColumnHash(); + { + if (rt->buildColumnHash()) + { + m_error.code = 4000; + delete rt; + return NULL; + } + } return rt; } @@ -1043,18 +1093,25 @@ NdbDictInterface::execGET_TABINFO_CONF(NdbApiSignal * signal, LinearSectionPtr ptr[3]) { const GetTabInfoConf* conf = CAST_CONSTPTR(GetTabInfoConf, signal->getDataPtr()); + const Uint32 i = GetTabInfoConf::DICT_TAB_INFO; if(signal->isFirstFragment()){ m_fragmentId = signal->getFragmentId(); - m_buffer.grow(4 * conf->totalLen); + if (m_buffer.grow(4 * conf->totalLen)) + { + m_error.code= 4000; + goto end; + } } else { if(m_fragmentId != signal->getFragmentId()){ abort(); } } - const Uint32 i = GetTabInfoConf::DICT_TAB_INFO; - m_buffer.append(ptr[i].p, 4 * ptr[i].sz); - + if (m_buffer.append(ptr[i].p, 4 * ptr[i].sz)) + { + m_error.code= 4000; + } +end: if(!signal->isLastFragment()){ return; } @@ -1185,10 +1242,12 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret, impl->m_tableId = tableDesc.TableId; impl->m_version = tableDesc.TableVersion; impl->m_status = NdbDictionary::Object::Retrieved; - impl->m_internalName.assign(internalName); - impl->m_externalName.assign(externalName); - - impl->m_frm.assign(tableDesc.FrmData, tableDesc.FrmLen); + if (!impl->m_internalName.assign(internalName) || + !impl->m_externalName.assign(externalName) || + impl->m_frm.assign(tableDesc.FrmData, tableDesc.FrmLen)) + { + DBUG_RETURN(4000); + } impl->m_fragmentType = (NdbDictionary::Object::FragmentType) getApiConstant(tableDesc.FragmentType, @@ -1216,7 +1275,10 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret, } else { const char * externalPrimary = Ndb::externalizeTableName(tableDesc.PrimaryTable, fullyQualifiedNames); - impl->m_primaryTable.assign(externalPrimary); + if (!impl->m_primaryTable.assign(externalPrimary)) + { + DBUG_RETURN(4000); + } } Uint32 keyInfoPos = 0; @@ -1243,6 +1305,7 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret, // check type and compute attribute size and array size if (! attrDesc.translateExtType()) { + delete col; delete impl; DBUG_RETURN(703); } @@ -1254,12 +1317,14 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret, unsigned cs_number = (attrDesc.AttributeExtPrecision >> 16); // charset is defined exactly for char types if (col->getCharType() != (cs_number != 0)) { + delete col; delete impl; DBUG_RETURN(703); } if (col->getCharType()) { col->m_cs = get_charset(cs_number, MYF(0)); if (col->m_cs == NULL) { + delete col; delete impl; DBUG_RETURN(743); } @@ -1277,7 +1342,12 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret, col->m_nullable = attrDesc.AttributeNullableFlag; col->m_autoIncrement = (attrDesc.AttributeAutoIncrement ? true : false); col->m_autoIncrementInitialValue = ~0; - col->m_defaultValue.assign(attrDesc.AttributeDefaultValue); + if (!col->m_defaultValue.assign(attrDesc.AttributeDefaultValue)) + { + delete col; + delete impl; + DBUG_RETURN(4000); + } if(attrDesc.AttributeKeyFlag){ col->m_keyInfoPos = keyInfoPos + 1; @@ -1317,7 +1387,11 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret, for(i = 0; i<(fragCount*replicaCount); i++) { - impl->m_fragments.push_back(tableDesc.FragmentData[i+2]); + if (impl->m_fragments.push_back(tableDesc.FragmentData[i+2])) + { + delete impl; + DBUG_RETURN(4000); + } } Uint32 topBit = (1 << 31); @@ -1481,7 +1555,11 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb, } if (!impl.m_newExternalName.empty()) { - impl.m_externalName.assign(impl.m_newExternalName); + if (!impl.m_externalName.assign(impl.m_newExternalName)) + { + m_error.code= 4000; + DBUG_RETURN(-1); + } AlterTableReq::setNameFlag(impl.m_changeMask, true); } @@ -1490,7 +1568,11 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb, const BaseString internalName( ndb.internalize_table_name(impl.m_externalName.c_str())); - impl.m_internalName.assign(internalName); + if (!impl.m_internalName.assign(internalName)) + { + m_error.code= 4000; + DBUG_RETURN(-1); + } UtilBufferWriter w(m_buffer); DictTabInfo::Table tmpTab; tmpTab.init(); BaseString::snprintf(tmpTab.TableName, @@ -1967,13 +2049,19 @@ NdbDictionaryImpl::getIndexImpl(const char * externalName, NdbIndexImpl* idx; if(NdbDictInterface::create_index_obj_from_table(&idx, tab, prim) == 0){ idx->m_table = tab; - idx->m_externalName.assign(externalName); - idx->m_internalName.assign(internalName); + if (!idx->m_externalName.assign(externalName) || + !idx->m_internalName.assign(internalName)) + { + delete idx; + m_error.code = 4000; + return 0; + } // TODO Assign idx to tab->m_index // Don't do it right now since assign can't asign a table with index // tab->m_index = idx; return idx; } + m_error.code = 4000; return 0; } @@ -1982,11 +2070,21 @@ NdbDictInterface::create_index_obj_from_table(NdbIndexImpl** dst, NdbTableImpl* tab, const NdbTableImpl* prim){ NdbIndexImpl *idx = new NdbIndexImpl(); + if (idx == NULL) + { + errno = ENOMEM; + return -1; + } idx->m_version = tab->m_version; idx->m_status = tab->m_status; idx->m_indexId = tab->m_tableId; - idx->m_externalName.assign(tab->getName()); - idx->m_tableName.assign(prim->m_externalName); + if (!idx->m_externalName.assign(tab->getName()) || + !idx->m_tableName.assign(prim->m_externalName)) + { + delete idx; + errno = ENOMEM; + return -1; + } NdbDictionary::Index::Type type = idx->m_type = tab->m_indexType; idx->m_logging = tab->m_logging; // skip last attribute (NDB$PK or NDB$TNODE) @@ -1999,9 +2097,20 @@ NdbDictInterface::create_index_obj_from_table(NdbIndexImpl** dst, NdbColumnImpl* org = tab->m_columns[i]; NdbColumnImpl* col = new NdbColumnImpl; + if (col == NULL) + { + errno = ENOMEM; + delete idx; + return -1; + } // Copy column definition *col = * org; - idx->m_columns.push_back(col); + if (idx->m_columns.push_back(col)) + { + delete col; + delete idx; + return -1; + } /** * reverse map @@ -2067,7 +2176,11 @@ NdbDictInterface::createIndex(Ndb & ndb, } const BaseString internalName( ndb.internalize_index_name(&table, impl.getName())); - impl.m_internalName.assign(internalName); + if (!impl.m_internalName.assign(internalName)) + { + m_error.code = 4000; + return -1; + } w.add(DictTabInfo::TableName, internalName.c_str()); w.add(DictTabInfo::TableLoggedFlag, impl.m_logging); @@ -2353,34 +2466,72 @@ NdbDictInterface::listObjects(NdbDictionary::Dictionary::List& list, BaseString databaseName; BaseString schemaName; BaseString objectName; + if (!databaseName || !schemaName || !objectName) + { + m_error.code= 4000; + return -1; + } if ((element.type == NdbDictionary::Object::UniqueHashIndex) || (element.type == NdbDictionary::Object::OrderedIndex)) { char * indexName = new char[n << 2]; + if (indexName == NULL) + { + m_error.code= 4000; + return -1; + } memcpy(indexName, &data[pos], n << 2); - databaseName = Ndb::getDatabaseFromInternalName(indexName); - schemaName = Ndb::getSchemaFromInternalName(indexName); + if (!(databaseName = Ndb::getDatabaseFromInternalName(indexName)) || + !(schemaName = Ndb::getSchemaFromInternalName(indexName))) + { + delete [] indexName; + m_error.code= 4000; + return -1; + } objectName = BaseString(Ndb::externalizeIndexName(indexName, fullyQualifiedNames)); delete [] indexName; } else if ((element.type == NdbDictionary::Object::SystemTable) || (element.type == NdbDictionary::Object::UserTable)) { char * tableName = new char[n << 2]; + if (tableName == NULL) + { + m_error.code= 4000; + return -1; + } memcpy(tableName, &data[pos], n << 2); - databaseName = Ndb::getDatabaseFromInternalName(tableName); - schemaName = Ndb::getSchemaFromInternalName(tableName); + if (!(databaseName = Ndb::getDatabaseFromInternalName(tableName)) || + !(schemaName = Ndb::getSchemaFromInternalName(tableName))) + { + delete [] tableName; + m_error.code= 4000; + return -1; + } objectName = BaseString(Ndb::externalizeTableName(tableName, fullyQualifiedNames)); delete [] tableName; } else { char * otherName = new char[n << 2]; + if (otherName == NULL) + { + m_error.code= 4000; + return -1; + } memcpy(otherName, &data[pos], n << 2); - objectName = BaseString(otherName); + if (!(objectName = BaseString(otherName))) + { + m_error.code= 4000; + return -1; + } delete [] otherName; } - element.database = new char[databaseName.length() + 1]; + if (!(element.database = new char[databaseName.length() + 1]) || + !(element.schema = new char[schemaName.length() + 1]) || + !(element.name = new char[objectName.length() + 1])) + { + m_error.code= 4000; + return -1; + } strcpy(element.database, databaseName.c_str()); - element.schema = new char[schemaName.length() + 1]; strcpy(element.schema, schemaName.c_str()); - element.name = new char[objectName.length() + 1]; strcpy(element.name, objectName.c_str()); pos += n; count++; @@ -2427,7 +2578,10 @@ NdbDictInterface::execLIST_TABLES_CONF(NdbApiSignal* signal, { const unsigned off = ListTablesConf::HeaderLength; const unsigned len = (signal->getLength() - off); - m_buffer.append(signal->getDataPtr() + off, len << 2); + if (m_buffer.append(signal->getDataPtr() + off, len << 2)) + { + m_error.code= 4000; + } if (signal->getLength() < ListTablesConf::SignalLength) { // last signal has less than full length m_waiter.signal(NO_WAIT); diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.hpp b/ndb/src/ndbapi/NdbDictionaryImpl.hpp index 6d58a703a3c..819de921235 100644 --- a/ndb/src/ndbapi/NdbDictionaryImpl.hpp +++ b/ndb/src/ndbapi/NdbDictionaryImpl.hpp @@ -103,7 +103,7 @@ public: ~NdbTableImpl(); void init(); - void setName(const char * name); + int setName(const char * name); const char * getName() const; Uint32 m_changeMask; @@ -120,7 +120,7 @@ public: Uint32 m_columnHashMask; Vector<Uint32> m_columnHash; Vector<NdbColumnImpl *> m_columns; - void buildColumnHash(); + int buildColumnHash(); /** * Fragment info @@ -166,7 +166,7 @@ public: * Equality/assign */ bool equal(const NdbTableImpl&) const; - void assign(const NdbTableImpl&); + int assign(const NdbTableImpl&); static NdbTableImpl & getImpl(NdbDictionary::Table & t); static NdbTableImpl & getImpl(const NdbDictionary::Table & t); @@ -185,9 +185,9 @@ public: ~NdbIndexImpl(); void init(); - void setName(const char * name); + int setName(const char * name); const char * getName() const; - void setTable(const char * table); + int setTable(const char * table); const char * getTable() const; const NdbTableImpl * getIndexTable() const; diff --git a/ndb/src/ndbapi/NdbImpl.hpp b/ndb/src/ndbapi/NdbImpl.hpp index 90b81dabff6..ec386074692 100644 --- a/ndb/src/ndbapi/NdbImpl.hpp +++ b/ndb/src/ndbapi/NdbImpl.hpp @@ -37,7 +37,7 @@ struct Ndb_free_list_t Ndb_free_list_t(); ~Ndb_free_list_t(); - void fill(Ndb*, Uint32 cnt); + int fill(Ndb*, Uint32 cnt); T* seize(Ndb*); void release(T*); void clear(); @@ -79,10 +79,14 @@ public: BaseString m_prefix; // Buffer for preformatted internal name <db>/<schema>/ - void update_prefix() + int update_prefix() { - m_prefix.assfmt("%s%c%s%c", m_dbname.c_str(), table_name_separator, - m_schemaname.c_str(), table_name_separator); + if (!m_prefix.assfmt("%s%c%s%c", m_dbname.c_str(), table_name_separator, + m_schemaname.c_str(), table_name_separator)) + { + return -1; + } + return 0; } /** @@ -194,7 +198,7 @@ Ndb_free_list_t<T>::~Ndb_free_list_t() template<class T> inline -void +int Ndb_free_list_t<T>::fill(Ndb* ndb, Uint32 cnt) { if (m_free_list == 0) @@ -202,18 +206,28 @@ Ndb_free_list_t<T>::fill(Ndb* ndb, Uint32 cnt) m_free_cnt++; m_alloc_cnt++; m_free_list = new T(ndb); + if (m_free_list == 0) + { + ndb->theError.code = 4000; + assert(false); + return -1; + } } while(m_alloc_cnt < cnt) { T* obj= new T(ndb); if(obj == 0) - return; - + { + ndb->theError.code = 4000; + assert(false); + return -1; + } obj->next(m_free_list); m_free_cnt++; m_alloc_cnt++; m_free_list = obj; } + return 0; } template<class T> @@ -234,7 +248,11 @@ Ndb_free_list_t<T>::seize(Ndb* ndb) { m_alloc_cnt++; } - + else + { + ndb->theError.code = 4000; + assert(false); + } return tmp; } diff --git a/ndb/src/ndbapi/NdbOperation.cpp b/ndb/src/ndbapi/NdbOperation.cpp index 3ab1b56a717..51b6a3f6dab 100644 --- a/ndb/src/ndbapi/NdbOperation.cpp +++ b/ndb/src/ndbapi/NdbOperation.cpp @@ -176,7 +176,11 @@ NdbOperation::init(const NdbTableImpl* tab, NdbTransaction* myConnection){ tcKeyReq->scanInfo = 0; theKEYINFOptr = &tcKeyReq->keyInfo[0]; theATTRINFOptr = &tcKeyReq->attrInfo[0]; - theReceiver.init(NdbReceiver::NDB_OPERATION, this); + if (theReceiver.init(NdbReceiver::NDB_OPERATION, this)) + { + // theReceiver sets the error code of its owner + return -1; + } return 0; } diff --git a/ndb/src/ndbapi/NdbRecAttr.cpp b/ndb/src/ndbapi/NdbRecAttr.cpp index 90808a706d4..996c0256baa 100644 --- a/ndb/src/ndbapi/NdbRecAttr.cpp +++ b/ndb/src/ndbapi/NdbRecAttr.cpp @@ -83,6 +83,7 @@ NdbRecAttr::setup(const NdbColumnImpl* anAttrInfo, char* aValue) theRef = tRef; return 0; } + errno = ENOMEM; return -1; } @@ -102,7 +103,11 @@ NdbRecAttr::copyout() NdbRecAttr * NdbRecAttr::clone() const { NdbRecAttr * ret = new NdbRecAttr(0); - + if (ret == NULL) + { + errno = ENOMEM; + return NULL; + } ret->theAttrId = theAttrId; ret->theNULLind = theNULLind; ret->theAttrSize = theAttrSize; @@ -116,6 +121,12 @@ NdbRecAttr::clone() const { ret->theValue = 0; } else { ret->theStorageX = new Uint64[((n + 7) >> 3)]; + if (ret->theStorageX == NULL) + { + delete ret; + errno = ENOMEM; + return NULL; + } ret->theRef = (char*)ret->theStorageX; ret->theValue = 0; } @@ -508,3 +519,15 @@ NdbRecAttr::double_value() const memcpy(&val,theRef,sizeof(val)); return val; } + +Int32 +NdbRecAttr::medium_value() const +{ + return sint3korr((unsigned char *)theRef); +} + +Uint32 +NdbRecAttr::u_medium_value() const +{ + return uint3korr((unsigned char*)theRef); +} diff --git a/ndb/src/ndbapi/NdbReceiver.cpp b/ndb/src/ndbapi/NdbReceiver.cpp index 9322f88a351..46ca59f2f42 100644 --- a/ndb/src/ndbapi/NdbReceiver.cpp +++ b/ndb/src/ndbapi/NdbReceiver.cpp @@ -32,7 +32,7 @@ NdbReceiver::NdbReceiver(Ndb *aNdb) : { theCurrentRecAttr = theFirstRecAttr = 0; m_defined_rows = 0; - m_rows = new NdbRecAttr*[0]; + m_rows = NULL; } NdbReceiver::~NdbReceiver() @@ -45,19 +45,26 @@ NdbReceiver::~NdbReceiver() DBUG_VOID_RETURN; } -void +int NdbReceiver::init(ReceiverType type, void* owner) { theMagicNumber = 0x11223344; m_type = type; m_owner = owner; + theFirstRecAttr = NULL; + theCurrentRecAttr = NULL; if (m_id == NdbObjectIdMap::InvalidId) { if (m_ndb) + { m_id = m_ndb->theImpl->theNdbObjectIdMap.map(this); + if (m_id == NdbObjectIdMap::InvalidId) + { + setErrorCode(4000); + return -1; + } + } } - - theFirstRecAttr = NULL; - theCurrentRecAttr = NULL; + return 0; } void @@ -146,7 +153,7 @@ NdbReceiver::calculate_batch_size(Uint32 key_size, return; } -void +int NdbReceiver::do_get_value(NdbReceiver * org, Uint32 rows, Uint32 key_size, @@ -154,7 +161,11 @@ NdbReceiver::do_get_value(NdbReceiver * org, if(rows > m_defined_rows){ delete[] m_rows; m_defined_rows = rows; - m_rows = new NdbRecAttr*[rows + 1]; + if ((m_rows = new NdbRecAttr*[rows + 1]) == NULL) + { + setErrorCode(4000); + return -1; + } } m_rows[rows] = 0; @@ -174,7 +185,7 @@ NdbReceiver::do_get_value(NdbReceiver * org, // Put key-recAttr fir on each row if(key_size && !getValue(&key, (char*)0)){ abort(); - return ; // -1 + return -1; } if(range_no && @@ -193,7 +204,7 @@ NdbReceiver::do_get_value(NdbReceiver * org, if(tRecAttr){ abort(); - return ;// -1; + return -1; } // Store first recAttr for each row in m_rows[i] @@ -205,7 +216,7 @@ NdbReceiver::do_get_value(NdbReceiver * org, } prepareSend(); - return; + return 0; } NdbRecAttr* diff --git a/ndb/src/ndbapi/NdbScanFilter.cpp b/ndb/src/ndbapi/NdbScanFilter.cpp index eb0ef4ba391..fb47772fdea 100644 --- a/ndb/src/ndbapi/NdbScanFilter.cpp +++ b/ndb/src/ndbapi/NdbScanFilter.cpp @@ -78,7 +78,11 @@ NdbScanFilter::~NdbScanFilter(){ int NdbScanFilter::begin(Group group){ - m_impl.m_stack2.push_back(m_impl.m_negative); + if (m_impl.m_stack2.push_back(m_impl.m_negative)) + { + m_impl.m_operation->setErrorCodeAbort(4000); + return -1; + } switch(group){ case NdbScanFilter::AND: INT_DEBUG(("Begin(AND)")); @@ -127,7 +131,11 @@ NdbScanFilter::begin(Group group){ } NdbScanFilterImpl::State tmp = m_impl.m_current; - m_impl.m_stack.push_back(m_impl.m_current); + if (m_impl.m_stack.push_back(m_impl.m_current)) + { + m_impl.m_operation->setErrorCodeAbort(4000); + return -1; + } m_impl.m_current.m_group = group; m_impl.m_current.m_ownLabel = m_impl.m_label++; m_impl.m_current.m_popCount = 0; diff --git a/ndb/src/ndbapi/NdbScanOperation.cpp b/ndb/src/ndbapi/NdbScanOperation.cpp index 8433b70f0b2..91c788b0088 100644 --- a/ndb/src/ndbapi/NdbScanOperation.cpp +++ b/ndb/src/ndbapi/NdbScanOperation.cpp @@ -797,9 +797,12 @@ int NdbScanOperation::prepareSendScan(Uint32 aTC_ConnectPtr, req->requestInfo = reqInfo; for(Uint32 i = 0; i<theParallelism; i++){ - m_receivers[i]->do_get_value(&theReceiver, batch_size, - key_size, - m_read_range_no); + if (m_receivers[i]->do_get_value(&theReceiver, batch_size, + key_size, + m_read_range_no)) + { + return -1; + } } return 0; } diff --git a/ndb/src/ndbapi/NdbTransaction.cpp b/ndb/src/ndbapi/NdbTransaction.cpp index 2fe43b8cc21..258330b3967 100644 --- a/ndb/src/ndbapi/NdbTransaction.cpp +++ b/ndb/src/ndbapi/NdbTransaction.cpp @@ -81,6 +81,7 @@ NdbTransaction::NdbTransaction( Ndb* aNdb ) : { theListState = NotInList; theError.code = 0; + //theId = NdbObjectIdMap::InvalidId; theId = theNdb->theImpl->theNdbObjectIdMap.map(this); #define CHECK_SZ(mask, sz) assert((sizeof(mask)/sizeof(mask[0])) == sz) @@ -106,7 +107,7 @@ void init(); Remark: Initialise connection object for new transaction. *****************************************************************************/ -void +int NdbTransaction::init() { theListState = NotInList; @@ -147,6 +148,17 @@ NdbTransaction::init() // theBlobFlag = false; thePendingBlobOps = 0; + if (theId == NdbObjectIdMap::InvalidId) + { + theId = theNdb->theImpl->theNdbObjectIdMap.map(this); + if (theId == NdbObjectIdMap::InvalidId) + { + theError.code = 4000; + return -1; + } + } + return 0; + }//NdbTransaction::init() /***************************************************************************** diff --git a/ndb/src/ndbapi/Ndbif.cpp b/ndb/src/ndbapi/Ndbif.cpp index 75ec5df60cb..d404436be59 100644 --- a/ndb/src/ndbapi/Ndbif.cpp +++ b/ndb/src/ndbapi/Ndbif.cpp @@ -816,8 +816,9 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) InvalidSignal: #ifdef VM_TRACE ndbout_c("Ndbif: Error Ndb::handleReceivedSignal " - "(GSN=%d, theImpl->theWaiter.m_state=%d)" + "(tFirstDataPtr=%p, GSN=%d, theImpl->theWaiter.m_state=%d)" " sender = (Block: %d Node: %d)", + tFirstDataPtr, tSignalNumber, tWaitState, refToBlock(aSignal->theSendersBlockRef), diff --git a/ndb/src/ndbapi/Ndblist.cpp b/ndb/src/ndbapi/Ndblist.cpp index 812410e283f..443f9bb42fc 100644 --- a/ndb/src/ndbapi/Ndblist.cpp +++ b/ndb/src/ndbapi/Ndblist.cpp @@ -74,7 +74,10 @@ Ndb::checkFailedNode() int Ndb::createConIdleList(int aNrOfCon) { - theImpl->theConIdleList.fill(this, aNrOfCon); + if (theImpl->theConIdleList.fill(this, aNrOfCon)) + { + return -1; + } return aNrOfCon; } @@ -90,7 +93,10 @@ Ndb::createConIdleList(int aNrOfCon) int Ndb::createOpIdleList(int aNrOfOp) { - theImpl->theOpIdleList.fill(this, aNrOfOp); + if (theImpl->theOpIdleList.fill(this, aNrOfOp)) + { + return -1; + } return aNrOfOp; } diff --git a/ndb/src/ndbapi/ObjectMap.cpp b/ndb/src/ndbapi/ObjectMap.cpp new file mode 100644 index 00000000000..c87911a10d4 --- /dev/null +++ b/ndb/src/ndbapi/ObjectMap.cpp @@ -0,0 +1,62 @@ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include "ObjectMap.hpp" + +NdbObjectIdMap::NdbObjectIdMap(NdbMutex* mutex, Uint32 sz, Uint32 eSz) +{ + m_size = 0; + m_firstFree = InvalidId; + m_map = 0; + m_mutex = mutex; + m_expandSize = eSz; + expand(sz); +#ifdef DEBUG_OBJECTMAP + ndbout_c("NdbObjectIdMap:::NdbObjectIdMap(%u)", sz); +#endif +} + +NdbObjectIdMap::~NdbObjectIdMap() +{ + free(m_map); +} + +int NdbObjectIdMap::expand(Uint32 incSize) +{ + NdbMutex_Lock(m_mutex); + Uint32 newSize = m_size + incSize; + MapEntry * tmp = (MapEntry*)realloc(m_map, newSize * sizeof(MapEntry)); + + if (likely(tmp != 0)) + { + m_map = tmp; + + for(Uint32 i = m_size; i < newSize; i++){ + m_map[i].m_next = i + 1; + } + m_firstFree = m_size; + m_map[newSize-1].m_next = InvalidId; + m_size = newSize; + } + else + { + NdbMutex_Unlock(m_mutex); + g_eventLogger.error("NdbObjectIdMap::expand: realloc(%u*%u) failed", + newSize, sizeof(MapEntry)); + return -1; + } + NdbMutex_Unlock(m_mutex); + return 0; +} diff --git a/ndb/src/ndbapi/ObjectMap.hpp b/ndb/src/ndbapi/ObjectMap.hpp index 0e0c9668164..6a8dbcbeef5 100644 --- a/ndb/src/ndbapi/ObjectMap.hpp +++ b/ndb/src/ndbapi/ObjectMap.hpp @@ -20,6 +20,9 @@ //#include <NdbMutex.h> #include <NdbOut.hpp> +#include <EventLogger.hpp> +extern EventLogger g_eventLogger; + //#define DEBUG_OBJECTMAP /** @@ -50,24 +53,6 @@ private: }; inline -NdbObjectIdMap::NdbObjectIdMap(NdbMutex* mutex, Uint32 sz, Uint32 eSz) { - m_size = 0; - m_firstFree = InvalidId; - m_map = 0; - m_mutex = mutex; - m_expandSize = eSz; - expand(sz); -#ifdef DEBUG_OBJECTMAP - ndbout_c("NdbObjectIdMap:::NdbObjectIdMap(%u)", sz); -#endif -} - -inline -NdbObjectIdMap::~NdbObjectIdMap(){ - free(m_map); -} - -inline Uint32 NdbObjectIdMap::map(void * object){ @@ -102,7 +87,8 @@ NdbObjectIdMap::unmap(Uint32 id, void *object){ m_map[i].m_next = m_firstFree; m_firstFree = i; } else { - ndbout_c("Error: NdbObjectIdMap::::unmap(%u, 0x%x) obj=0x%x", id, object, obj); + g_eventLogger.error("NdbObjectIdMap::unmap(%u, 0x%x) obj=0x%x", + id, object, obj); return 0; } @@ -128,31 +114,4 @@ NdbObjectIdMap::getObject(Uint32 id){ } return 0; } - -inline int -NdbObjectIdMap::expand(Uint32 incSize){ - NdbMutex_Lock(m_mutex); - Uint32 newSize = m_size + incSize; - MapEntry * tmp = (MapEntry*)realloc(m_map, newSize * sizeof(MapEntry)); - - if (likely(tmp != 0)) - { - m_map = tmp; - - for(Uint32 i = m_size; i<newSize; i++){ - m_map[i].m_next = i + 1; - } - m_firstFree = m_size; - m_map[newSize-1].m_next = InvalidId; - m_size = newSize; - } - else - { - NdbMutex_Unlock(m_mutex); - return -1; - } - NdbMutex_Unlock(m_mutex); - return 0; -} - #endif diff --git a/ndb/src/ndbapi/SignalSender.cpp b/ndb/src/ndbapi/SignalSender.cpp index b6a9a0d98a1..393524bb96e 100644 --- a/ndb/src/ndbapi/SignalSender.cpp +++ b/ndb/src/ndbapi/SignalSender.cpp @@ -147,7 +147,10 @@ SignalSender::waitFor(Uint32 timeOutMillis, T & t) { SimpleSignal * s = t.check(m_jobBuffer); if(s != 0){ - m_usedBuffer.push_back(s); + if (m_usedBuffer.push_back(s)) + { + return 0; + } return s; } @@ -162,7 +165,10 @@ SignalSender::waitFor(Uint32 timeOutMillis, T & t) SimpleSignal * s = t.check(m_jobBuffer); if(s != 0){ - m_usedBuffer.push_back(s); + if (m_usedBuffer.push_back(s)) + { + return 0; + } return s; } diff --git a/ndb/src/ndbapi/ndb_cluster_connection.cpp b/ndb/src/ndbapi/ndb_cluster_connection.cpp index 1e3b678de53..9eed5db8bad 100644 --- a/ndb/src/ndbapi/ndb_cluster_connection.cpp +++ b/ndb/src/ndbapi/ndb_cluster_connection.cpp @@ -353,7 +353,7 @@ Ndb_cluster_connection_impl::set_name(const char *name) } } -void +int Ndb_cluster_connection_impl::init_nodes_vector(Uint32 nodeid, const ndb_mgm_configuration &config) @@ -402,7 +402,10 @@ Ndb_cluster_connection_impl::init_nodes_vector(Uint32 nodeid, break; } } - m_impl.m_all_nodes.push_back(Node(group,remoteNodeId)); + if (m_impl.m_all_nodes.push_back(Node(group,remoteNodeId))) + { + DBUG_RETURN(-1); + } DBUG_PRINT("info",("saved %d %d", group,remoteNodeId)); for (int i= m_impl.m_all_nodes.size()-2; i >= 0 && m_impl.m_all_nodes[i].group > m_impl.m_all_nodes[i+1].group; @@ -449,7 +452,7 @@ Ndb_cluster_connection_impl::init_nodes_vector(Uint32 nodeid, do_test(); #endif - DBUG_VOID_RETURN; + DBUG_RETURN(0); } void @@ -532,7 +535,11 @@ int Ndb_cluster_connection::connect(int no_retries, int retry_delay_in_seconds, break; m_impl.m_transporter_facade->start_instance(nodeId, props); - m_impl.init_nodes_vector(nodeId, *props); + if (m_impl.init_nodes_vector(nodeId, *props)) + { + ndbout_c("Ndb_cluster_connection::connect: malloc failure"); + DBUG_RETURN(-1); + } for(unsigned i=0; i<m_impl.m_transporter_facade->get_registry()->m_transporter_interface.size(); diff --git a/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp b/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp index 5bb5f0a0fca..d3ff7610e18 100644 --- a/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp +++ b/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp @@ -68,7 +68,7 @@ private: }; Vector<Node> m_all_nodes; - void init_nodes_vector(Uint32 nodeid, const ndb_mgm_configuration &config); + int init_nodes_vector(Uint32 nodeid, const ndb_mgm_configuration &config); void connect_thread(); void set_name(const char *name); diff --git a/ndb/tools/restore/Restore.hpp b/ndb/tools/restore/Restore.hpp index 66e00d88dfe..c1545159ce4 100644 --- a/ndb/tools/restore/Restore.hpp +++ b/ndb/tools/restore/Restore.hpp @@ -219,6 +219,9 @@ public: memcpy(&val.u32,data,4); v= val.u32; break; + case 24: + v= uint3korr((unsigned char*)data); + break; case 16: memcpy(&val.u16,data,2); v= val.u16; diff --git a/ndb/tools/restore/consumer_restore.cpp b/ndb/tools/restore/consumer_restore.cpp index c955570eaa3..811868f3e77 100644 --- a/ndb/tools/restore/consumer_restore.cpp +++ b/ndb/tools/restore/consumer_restore.cpp @@ -205,7 +205,7 @@ BackupRestore::table(const TableS & table){ BaseString tmp(name); Vector<BaseString> split; if(tmp.split(split, "/") != 3){ - err << "Invalid table name format " << name << endl; + err << "Invalid table name format `" << name << "`" << endl; return false; } @@ -230,16 +230,17 @@ BackupRestore::table(const TableS & table){ if (dict->createTable(copy) == -1) { - err << "Create table " << table.getTableName() << " failed: " + err << "Create table `" << table.getTableName() << "` failed: " << dict->getNdbError() << endl; return false; } - info << "Successfully restored table " << table.getTableName()<< endl ; + info << "Successfully restored table `" + << table.getTableName() << "`" << endl; } const NdbDictionary::Table* tab = dict->getTable(split[2].c_str()); if(tab == 0){ - err << "Unable to find table: " << split[2].c_str() << endl; + err << "Unable to find table: `" << split[2].c_str() << "`" << endl; return false; } const NdbDictionary::Table* null = 0; @@ -257,12 +258,15 @@ BackupRestore::endOfTables(){ for(size_t i = 0; i<m_indexes.size(); i++){ NdbTableImpl & indtab = NdbTableImpl::getImpl(* m_indexes[i]); - BaseString tmp(indtab.m_primaryTable.c_str()); Vector<BaseString> split; - if(tmp.split(split, "/") != 3){ - err << "Invalid table name format " << indtab.m_primaryTable.c_str() - << endl; - return false; + { + BaseString tmp(indtab.m_primaryTable.c_str()); + if (tmp.split(split, "/") != 3) + { + err << "Invalid table name format `" << indtab.m_primaryTable.c_str() + << "`" << endl; + return false; + } } m_ndb->setDatabaseName(split[0].c_str()); @@ -270,39 +274,41 @@ BackupRestore::endOfTables(){ const NdbDictionary::Table * prim = dict->getTable(split[2].c_str()); if(prim == 0){ - err << "Unable to find base table \"" << split[2].c_str() - << "\" for index " - << indtab.getName() << endl; + err << "Unable to find base table `" << split[2].c_str() + << "` for index `" + << indtab.getName() << "`" << endl; return false; } NdbTableImpl& base = NdbTableImpl::getImpl(*prim); NdbIndexImpl* idx; - int id; - char idxName[255], buf[255]; - if(sscanf(indtab.getName(), "%[^/]/%[^/]/%d/%s", - buf, buf, &id, idxName) != 4){ - err << "Invalid index name format " << indtab.getName() << endl; - return false; + Vector<BaseString> split_idx; + { + BaseString tmp(indtab.getName()); + if (tmp.split(split_idx, "/") != 4) + { + err << "Invalid index name format `" << indtab.getName() << "`" << endl; + return false; + } } if(NdbDictInterface::create_index_obj_from_table(&idx, &indtab, &base)) { - err << "Failed to create index " << idxName - << " on " << split[2].c_str() << endl; + err << "Failed to create index `" << split_idx[3] + << "` on " << split[2].c_str() << endl; return false; } - idx->setName(idxName); + idx->setName(split_idx[3].c_str()); if(dict->createIndex(* idx) != 0) { delete idx; - err << "Failed to create index " << idxName - << " on " << split[2].c_str() << endl + err << "Failed to create index `" << split_idx[3].c_str() + << "` on `" << split[2].c_str() << "`" << endl << dict->getNdbError() << endl; return false; } delete idx; - info << "Successfully created index " << idxName - << " on " << split[2].c_str() << endl; + info << "Successfully created index `" << split_idx[3].c_str() + << "` on `" << split[2].c_str() << "`" << endl; } return true; } @@ -382,7 +388,7 @@ void BackupRestore::tuple_a(restore_callback_t *cb) Uint32 length = (size * arraySize) / 8; if (j == 0 && tup.getTable()->have_auto_inc(i)) - tup.getTable()->update_max_auto_val(dataPtr,size); + tup.getTable()->update_max_auto_val(dataPtr,size*arraySize); if (attr_desc->m_column->getPrimaryKey()) { @@ -596,7 +602,7 @@ BackupRestore::logEntry(const LogEntry & tup) const char * dataPtr = attr->Data.string_value; if (tup.m_table->have_auto_inc(attr->Desc->attrId)) - tup.m_table->update_max_auto_val(dataPtr,size); + tup.m_table->update_max_auto_val(dataPtr,size*arraySize); const Uint32 length = (size / 8) * arraySize; if (attr->Desc->m_column->getPrimaryKey()) diff --git a/ndb/tools/restore/restore_main.cpp b/ndb/tools/restore/restore_main.cpp index 52a913d73b4..9ec59b9b4a6 100644 --- a/ndb/tools/restore/restore_main.cpp +++ b/ndb/tools/restore/restore_main.cpp @@ -559,8 +559,8 @@ main(int argc, char** argv) for(Uint32 j= 0; j < g_consumers.size(); j++) if (!g_consumers[j]->table(* table)) { - err << "Restore: Failed to restore table: "; - err << table->getTableName() << " ... Exiting " << endl; + err << "Restore: Failed to restore table: `"; + err << table->getTableName() << "` ... Exiting " << endl; exitHandler(NDBT_FAILED); } } diff --git a/scripts/make_binary_distribution.sh b/scripts/make_binary_distribution.sh index 7d7918975f2..e8bf39bd016 100644 --- a/scripts/make_binary_distribution.sh +++ b/scripts/make_binary_distribution.sh @@ -115,7 +115,12 @@ if [ $BASE_SYSTEM != "netware" ] ; then chmod o-rwx $BASE/data $BASE/data/* fi -# Copy files if they exists, warn for those that don't +# Copy files if they exists, warn for those that don't. +# Note that when listing files to copy, we might list the file name +# twice, once in the directory location where it is build, and a +# second time in the ".libs" location. In the case the firs one +# is a wrapper script, the second one will overwrite it with the +# binary file. copyfileto() { destdir=$1 @@ -165,6 +170,7 @@ if [ $BASE_SYSTEM = "netware" ] ; then # For all other platforms: else BIN_FILES="$BIN_FILES \ + server-tools/instance-manager/.libs/mysqlmanager \ client/mysqltestmanagerc \ client/mysqltestmanager-pwgen tools/mysqltestmanager \ client/.libs/mysql client/.libs/mysqlshow client/.libs/mysqladmin \ diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 93ca6b7f96d..71050bc73e4 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -203,6 +203,7 @@ static const err_code_mapping err_map[]= { 284, HA_ERR_TABLE_DEF_CHANGED, 0 }, + {4000, HA_ERR_OUT_OF_MEM, 1 }, {4009, HA_ERR_NO_CONNECTION, 1 }, { 0, 1, 0 }, @@ -372,7 +373,10 @@ int ha_ndbcluster::records_update() { Ndb *ndb= get_ndb(); struct Ndb_statistics stat; - ndb->setDatabaseName(m_dbname); + if (ndb->setDatabaseName(m_dbname)) + { + return my_errno= HA_ERR_OUT_OF_MEM; + } result= ndb_get_table_statistics(this, true, ndb, m_tabname, &stat); if (result == 0) { @@ -841,7 +845,11 @@ int ha_ndbcluster::get_ndb_blobs_value(NdbBlob *last_ndb_blob, DBUG_PRINT("value", ("allocate blobs buffer size %u", offset)); m_blobs_buffer= my_malloc(offset, MYF(MY_WME)); if (m_blobs_buffer == NULL) + { + sql_print_error("ha_ndbcluster::get_ndb_blobs_value: " + "my_malloc(%u) failed", offset); DBUG_RETURN(-1); + } m_blobs_buffer_size= offset; } } @@ -1026,6 +1034,12 @@ static int fix_unique_index_attr_order(NDB_INDEX_DATA &data, if (data.unique_index_attrid_map) my_free((char*)data.unique_index_attrid_map, MYF(0)); data.unique_index_attrid_map= (unsigned char*)my_malloc(sz,MYF(MY_WME)); + if (data.unique_index_attrid_map == 0) + { + sql_print_error("fix_unique_index_attr_order: my_malloc(%u) failure", + (unsigned int)sz); + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + } KEY_PART_INFO* key_part= key_info->key_part; KEY_PART_INFO* end= key_part+key_info->key_parts; @@ -1134,14 +1148,16 @@ int ha_ndbcluster::build_index_list(Ndb *ndb, TABLE *tab, enum ILBP phase) { DBUG_PRINT("info", ("Get handle to index %s", index_name)); const NDBINDEX *index= dict->getIndex(index_name, m_tabname); - if (!index) DBUG_RETURN(1); + if (!index) + ERR_RETURN(dict->getNdbError()); m_index[i].index= (void *) index; } if (idx_type == UNIQUE_ORDERED_INDEX || idx_type == UNIQUE_INDEX) { DBUG_PRINT("info", ("Get handle to unique_index %s", unique_index_name)); const NDBINDEX *index= dict->getIndex(unique_index_name, m_tabname); - if (!index) DBUG_RETURN(1); + if (!index) + ERR_RETURN(dict->getNdbError()); m_index[i].unique_index= (void *) index; error= fix_unique_index_attr_order(m_index[i], index, key_info); } @@ -3228,7 +3244,10 @@ int ha_ndbcluster::info(uint flag) DBUG_RETURN(my_errno); Ndb *ndb= get_ndb(); struct Ndb_statistics stat; - ndb->setDatabaseName(m_dbname); + if (ndb->setDatabaseName(m_dbname)) + { + DBUG_RETURN(my_errno= HA_ERR_OUT_OF_MEM); + } if (current_thd->variables.ndb_use_exact_count && (result= ndb_get_table_statistics(this, true, ndb, m_tabname, &stat)) == 0) @@ -4038,7 +4057,10 @@ static int create_ndb_column(NDBCOL &col, HA_CREATE_INFO *info) { // Set name - col.setName(field->field_name); + if (col.setName(field->field_name)) + { + return (my_errno= errno); + } // Get char set CHARSET_INFO *cs= field->charset(); // Set type and sizes @@ -4410,7 +4432,10 @@ int ha_ndbcluster::create(const char *name, } DBUG_PRINT("table", ("name: %s", m_tabname)); - tab.setName(m_tabname); + if (tab.setName(m_tabname)) + { + DBUG_RETURN(my_errno= errno); + } tab.setLogging(!(create_info->options & HA_LEX_CREATE_TMP_TABLE)); // Save frm data for this table @@ -4435,7 +4460,10 @@ int ha_ndbcluster::create(const char *name, field->pack_length())); if ((my_errno= create_ndb_column(col, field, create_info))) DBUG_RETURN(my_errno); - tab.addColumn(col); + if (tab.addColumn(col)) + { + DBUG_RETURN(my_errno= errno); + } if (col.getPrimaryKey()) pk_length += (field->pack_length() + 3) / 4; } @@ -4444,13 +4472,19 @@ int ha_ndbcluster::create(const char *name, if (form->s->primary_key == MAX_KEY) { DBUG_PRINT("info", ("Generating shadow key")); - col.setName("$PK"); + if (col.setName("$PK")) + { + DBUG_RETURN(my_errno= errno); + } col.setType(NdbDictionary::Column::Bigunsigned); col.setLength(1); col.setNullable(FALSE); col.setPrimaryKey(TRUE); col.setAutoIncrement(TRUE); - tab.addColumn(col); + if (tab.addColumn(col)) + { + DBUG_RETURN(my_errno= errno); + } pk_length += 2; } @@ -4556,13 +4590,19 @@ int ha_ndbcluster::create_index(const char *name, // TODO Only temporary ordered indexes supported ndb_index.setLogging(FALSE); } - ndb_index.setTable(m_tabname); + if (ndb_index.setTable(m_tabname)) + { + DBUG_RETURN(my_errno= errno); + } for (; key_part != end; key_part++) { Field *field= key_part->field; DBUG_PRINT("info", ("attr: %s", field->field_name)); - ndb_index.addColumnName(field->field_name); + if (ndb_index.addColumnName(field->field_name)) + { + DBUG_RETURN(my_errno= errno); + } } if (dict->createIndex(ndb_index)) @@ -4617,7 +4657,10 @@ int ha_ndbcluster::rename_table(const char *from, const char *to) m_table= (void *)orig_tab; // Change current database to that of target table set_dbname(to); - ndb->setDatabaseName(m_dbname); + if (ndb->setDatabaseName(m_dbname)) + { + ERR_RETURN(ndb->getNdbError()); + } if (!(result= alter_table_name(new_tabname))) { // Rename .ndb file @@ -4636,10 +4679,16 @@ int ha_ndbcluster::rename_table(const char *from, const char *to) for (unsigned i = 0; i < index_list.count; i++) { NDBDICT::List::Element& index_el = index_list.elements[i]; set_dbname(from); - ndb->setDatabaseName(m_dbname); + if (ndb->setDatabaseName(m_dbname)) + { + ERR_RETURN(ndb->getNdbError()); + } const NDBINDEX * index= dict->getIndex(index_el.name, *new_tab); set_dbname(to); - ndb->setDatabaseName(m_dbname); + if (ndb->setDatabaseName(m_dbname)) + { + ERR_RETURN(ndb->getNdbError()); + } DBUG_PRINT("info", ("Creating index %s/%s", m_dbname, index->getName())); dict->createIndex(*index); @@ -4647,7 +4696,10 @@ int ha_ndbcluster::rename_table(const char *from, const char *to) m_dbname, index->getName())); set_dbname(from); - ndb->setDatabaseName(m_dbname); + if (ndb->setDatabaseName(m_dbname)) + { + ERR_RETURN(ndb->getNdbError()); + } dict->dropIndex(*index); } } @@ -4668,7 +4720,10 @@ int ha_ndbcluster::alter_table_name(const char *to) DBUG_ENTER("alter_table_name_table"); NdbDictionary::Table new_tab= *orig_tab; - new_tab.setName(to); + if (new_tab.setName(to)) + { + DBUG_RETURN(my_errno= errno); + } if (dict->alterTable(new_tab) != 0) ERR_RETURN(dict->getNdbError()); @@ -4914,7 +4969,10 @@ int ha_ndbcluster::open(const char *name, int mode, uint test_if_locked) if (!res) { Ndb *ndb= get_ndb(); - ndb->setDatabaseName(m_dbname); + if (ndb->setDatabaseName(m_dbname)) + { + ERR_RETURN(ndb->getNdbError()); + } struct Ndb_statistics stat; res= ndb_get_table_statistics(NULL, false, ndb, m_tabname, &stat); records= stat.row_count; @@ -4946,6 +5004,11 @@ Thd_ndb* ha_ndbcluster::seize_thd_ndb() DBUG_ENTER("seize_thd_ndb"); thd_ndb= new Thd_ndb(); + if (thd_ndb == NULL) + { + my_errno= HA_ERR_OUT_OF_MEM; + return NULL; + } thd_ndb->ndb->getDictionary()->set_local_table_data_size( sizeof(Ndb_local_table_statistics) ); @@ -5001,7 +5064,10 @@ int ha_ndbcluster::check_ndb_connection(THD* thd) if (!(ndb= check_ndb_in_thd(thd))) DBUG_RETURN(HA_ERR_NO_CONNECTION); - ndb->setDatabaseName(m_dbname); + if (ndb->setDatabaseName(m_dbname)) + { + ERR_RETURN(ndb->getNdbError()); + } DBUG_RETURN(0); } @@ -5035,8 +5101,10 @@ int ndbcluster_discover(THD* thd, const char *db, const char *name, if (!(ndb= check_ndb_in_thd(thd))) DBUG_RETURN(HA_ERR_NO_CONNECTION); - ndb->setDatabaseName(db); - + if (ndb->setDatabaseName(db)) + { + ERR_RETURN(ndb->getNdbError()); + } NDBDICT* dict= ndb->getDictionary(); dict->set_local_table_data_size(sizeof(Ndb_local_table_statistics)); dict->invalidateTable(name); @@ -5082,8 +5150,10 @@ int ndbcluster_table_exists_in_engine(THD* thd, const char *db, const char *name if (!(ndb= check_ndb_in_thd(thd))) DBUG_RETURN(HA_ERR_NO_CONNECTION); - ndb->setDatabaseName(db); - + if (ndb->setDatabaseName(db)) + { + ERR_RETURN(ndb->getNdbError()); + } NDBDICT* dict= ndb->getDictionary(); dict->set_local_table_data_size(sizeof(Ndb_local_table_statistics)); dict->invalidateTable(name); @@ -5144,7 +5214,10 @@ int ndbcluster_drop_database(const char *path) drop_list.push_back(thd->strdup(t.name)); } // Drop any tables belonging to database - ndb->setDatabaseName(dbname); + if (ndb->setDatabaseName(dbname)) + { + ERR_RETURN(ndb->getNdbError()); + } List_iterator_fast<char> it(drop_list); while ((tabname=it++)) { @@ -5373,6 +5446,7 @@ bool ndbcluster_init() { DBUG_PRINT("error",("Ndb_cluster_connection(%s)", opt_ndbcluster_connectstring)); + my_errno= HA_ERR_OUT_OF_MEM; goto ndbcluster_init_error; } { @@ -5387,6 +5461,7 @@ bool ndbcluster_init() if ( (g_ndb= new Ndb(g_ndb_cluster_connection, "sys")) == 0 ) { DBUG_PRINT("error", ("failed to create global ndb object")); + my_errno= HA_ERR_OUT_OF_MEM; goto ndbcluster_init_error; } g_ndb->getDictionary()->set_local_table_data_size(sizeof(Ndb_local_table_statistics)); @@ -5742,7 +5817,10 @@ uint ndb_get_commitcount(THD *thd, char *dbname, char *tabname, Ndb *ndb; if (!(ndb= check_ndb_in_thd(thd))) DBUG_RETURN(1); - ndb->setDatabaseName(dbname); + if (ndb->setDatabaseName(dbname)) + { + ERR_RETURN(ndb->getNdbError()); + } uint lock= share->commit_count_lock; pthread_mutex_unlock(&share->mutex); @@ -5955,6 +6033,8 @@ static NDB_SHARE* get_share(const char *table_name) { DBUG_PRINT("error", ("Failed to alloc share")); pthread_mutex_unlock(&ndbcluster_mutex); + sql_print_error("get_share: my_malloc(%u) failed", + (unsigned int)(sizeof(*share)+length+1)); return 0; } } @@ -6015,16 +6095,22 @@ static int packfrm(const void *data, uint len, error= 1; org_len= len; if (my_compress((byte*)data, &org_len, &comp_len)) + { + sql_print_error("packfrm: my_compress(org_len: %u)", + (unsigned int)org_len); goto err; - + } + DBUG_PRINT("info", ("org_len: %lu comp_len: %lu", org_len, comp_len)); DBUG_DUMP("compressed", (char*)data, org_len); error= 2; blob_len= sizeof(frm_blob_struct::frm_blob_header)+org_len; if (!(blob= (frm_blob_struct*) my_malloc(blob_len,MYF(MY_WME)))) + { + sql_print_error("packfrm: my_malloc(%u)", blob_len); goto err; - + } // Store compressed blob in machine independent format int4store((char*)(&blob->head.ver), 1); int4store((char*)(&blob->head.orglen), comp_len); @@ -6062,14 +6148,23 @@ static int unpackfrm(const void **unpack_data, uint *unpack_len, DBUG_DUMP("blob->data", (char*) blob->data, complen); if (ver != 1) + { + sql_print_error("unpackfrm: ver != 1"); DBUG_RETURN(1); + } if (!(data= my_malloc(max(orglen, complen), MYF(MY_WME)))) - DBUG_RETURN(2); + { + sql_print_error("unpackfrm: my_malloc(%u)", + (unsigned int)max(orglen, complen)); + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + } memcpy(data, blob->data, complen); if (my_uncompress(data, &complen, &orglen)) { my_free((char*)data, MYF(0)); + sql_print_error("unpackfrm: my_uncompress(complen: %u, orglen: %u)", + (unsigned int)complen, (unsigned int)orglen); DBUG_RETURN(3); } @@ -6663,7 +6758,10 @@ ha_ndbcluster::update_table_comment( return((char*)comment); } - ndb->setDatabaseName(m_dbname); + if (ndb->setDatabaseName(m_dbname)) + { + return((char*)comment); + } NDBDICT* dict= ndb->getDictionary(); const NDBTAB* tab; if (!(tab= dict->getTable(m_tabname))) @@ -6676,6 +6774,8 @@ ha_ndbcluster::update_table_comment( const unsigned fmt_len_plus_extra= length + strlen(fmt); if ((str= my_malloc(fmt_len_plus_extra, MYF(0))) == NULL) { + sql_print_error("ha_ndbcluster::update_table_comment: " + "my_malloc(%u) failed", (unsigned int)fmt_len_plus_extra); return (char*)comment; } @@ -6698,9 +6798,19 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused))) DBUG_PRINT("enter", ("ndb_cache_check_time: %lu", ndb_cache_check_time)); thd= new THD; /* note that contructor of THD uses DBUG_ */ + if (thd == NULL) + { + my_errno= HA_ERR_OUT_OF_MEM; + DBUG_RETURN(NULL); + } THD_CHECK_SENTRY(thd); ndb= new Ndb(g_ndb_cluster_connection, ""); - + if (ndb == NULL) + { + thd->cleanup(); + delete thd; + DBUG_RETURN(NULL); + } pthread_detach_this_thread(); ndb_util_thread= pthread_self(); @@ -6789,14 +6899,15 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused))) share->table_name)); /* Contact NDB to get commit count for table */ - ndb->setDatabaseName(db); struct Ndb_statistics stat; - uint lock; pthread_mutex_lock(&share->mutex); lock= share->commit_count_lock; pthread_mutex_unlock(&share->mutex); - + if (ndb->setDatabaseName(db)) + { + goto loop_next; + } if (ndb_get_table_statistics(NULL, false, ndb, tabname, &stat) == 0) { #ifndef DBUG_OFF @@ -6815,7 +6926,7 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused))) share->table_name)); stat.commit_count= 0; } - + loop_next: pthread_mutex_lock(&share->mutex); if (share->commit_count_lock == lock) share->commit_count= stat.commit_count; @@ -6884,6 +6995,11 @@ ha_ndbcluster::cond_push(const COND *cond) { DBUG_ENTER("cond_push"); Ndb_cond_stack *ndb_cond = new Ndb_cond_stack(); + if (ndb_cond == NULL) + { + my_errno= HA_ERR_OUT_OF_MEM; + DBUG_RETURN(NULL); + } DBUG_EXECUTE("where",print_where((COND *)cond, m_tabname);); if (m_cond_stack) ndb_cond->next= m_cond_stack; diff --git a/sql/item.cc b/sql/item.cc index 8568a44c547..ed5bd67d096 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1610,7 +1610,7 @@ void Item_ident_for_show::make_field(Send_field *tmp_field) Item_field::Item_field(Field *f) :Item_ident(0, NullS, *f->table_name, f->field_name), item_equal(0), no_const_subst(0), - have_privileges(0), any_privileges(0), fixed_as_field(0) + have_privileges(0), any_privileges(0) { set_field(f); /* @@ -1624,7 +1624,7 @@ Item_field::Item_field(THD *thd, Name_resolution_context *context_arg, Field *f) :Item_ident(context_arg, f->table->s->db, *f->table_name, f->field_name), item_equal(0), no_const_subst(0), - have_privileges(0), any_privileges(0), fixed_as_field(0) + have_privileges(0), any_privileges(0) { /* We always need to provide Item_field with a fully qualified field @@ -1663,7 +1663,7 @@ Item_field::Item_field(Name_resolution_context *context_arg, const char *field_name_arg) :Item_ident(context_arg, db_arg,table_name_arg,field_name_arg), field(0), result_field(0), item_equal(0), no_const_subst(0), - have_privileges(0), any_privileges(0), fixed_as_field(0) + have_privileges(0), any_privileges(0) { SELECT_LEX *select= current_thd->lex->current_select; collation.set(DERIVATION_IMPLICIT); @@ -1679,8 +1679,7 @@ Item_field::Item_field(THD *thd, Item_field *item) item_equal(item->item_equal), no_const_subst(item->no_const_subst), have_privileges(item->have_privileges), - any_privileges(item->any_privileges), - fixed_as_field(item->fixed_as_field) + any_privileges(item->any_privileges) { collation.set(DERIVATION_IMPLICIT); } @@ -3447,6 +3446,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) Item **ref= (Item **) not_found_item; SELECT_LEX *current_sel= (SELECT_LEX *) thd->lex->current_select; Name_resolution_context *outer_context= 0; + SELECT_LEX *select= 0; /* Currently derived tables cannot be correlated */ if (current_sel->master_unit()->first_select()->linkage != DERIVED_TABLE_TYPE) @@ -3455,7 +3455,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) outer_context; outer_context= outer_context->outer_context) { - SELECT_LEX *select= outer_context->select_lex; + select= outer_context->select_lex; Item_subselect *prev_subselect_item= last_checked_context->select_lex->master_unit()->item; last_checked_context= outer_context; @@ -3498,45 +3498,28 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) } if (*from_field != view_ref_found) { - prev_subselect_item->used_tables_cache|= (*from_field)->table->map; prev_subselect_item->const_item_cache= 0; + set_field(*from_field); if (!last_checked_context->select_lex->having_fix_field && - !fixed_as_field) + select->group_list.elements) { Item_outer_ref *rf; - Query_arena *arena= 0, backup; /* - Each outer field is replaced for an Item_outer_ref object. - This is done in order to get correct results when the outer - select employs a temporary table. - The original fields are saved in the inner_fields_list of the - outer select. This list is created by the following reasons: - 1. We can't add field items to the outer select list directly - because the outer select hasn't been fully fixed yet. - 2. We need a location to refer to in the Item_ref object - so the inner_fields_list is used as such temporary - reference storage. - The new Item_outer_ref object replaces the original field and is - also saved in the inner_refs_list of the outer select. Here - it is only created. It can be fixed only after the original - field has been fixed and this is done in the fix_inner_refs() - function. + If an outer field is resolved in a grouping select then it + is replaced for an Item_outer_ref object. Otherwise an + Item_field object is used. + The new Item_outer_ref object is saved in the inner_refs_list of + the outer select. Here it is only created. It can be fixed only + after the original field has been fixed and this is done in the + fix_inner_refs() function. */ - set_field(*from_field); - arena= thd->activate_stmt_arena_if_needed(&backup); - rf= new Item_outer_ref(context, this); - if (!rf) - { - if (arena) - thd->restore_active_arena(arena, &backup); + ; + if (!(rf= new Item_outer_ref(context, this))) return -1; - } - *reference= rf; + thd->change_item_tree(reference, rf); select->inner_refs_list.push_back(rf); - if (arena) - thd->restore_active_arena(arena, &backup); - fixed_as_field= 1; + rf->in_sum_func= thd->lex->in_sum_func; } if (thd->lex->in_sum_func && thd->lex->in_sum_func->nest_level == @@ -3642,11 +3625,20 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) rf= (place == IN_HAVING ? new Item_ref(context, ref, (char*) table_name, (char*) field_name, alias_name_used) : + (!select->group_list.elements ? new Item_direct_ref(context, ref, (char*) table_name, - (char*) field_name, alias_name_used)); + (char*) field_name, alias_name_used) : + new Item_outer_ref(context, ref, (char*) table_name, + (char*) field_name, alias_name_used))); *ref= save; if (!rf) return -1; + + if (place != IN_HAVING && select->group_list.elements) + { + outer_context->select_lex->inner_refs_list.push_back((Item_outer_ref*)rf); + ((Item_outer_ref*)rf)->in_sum_func= thd->lex->in_sum_func; + } thd->change_item_tree(reference, rf); /* rf is Item_ref => never substitute other items (in this case) @@ -5550,16 +5542,19 @@ bool Item_direct_view_ref::fix_fields(THD *thd, Item **reference) bool Item_outer_ref::fix_fields(THD *thd, Item **reference) { - DBUG_ASSERT(*ref); - /* outer_field->check_cols() will be made in Item_direct_ref::fix_fields */ - outer_field->fixed_as_field= 1; - if (!outer_field->fixed && - (outer_field->fix_fields(thd, reference))) + bool err; + /* outer_ref->check_cols() will be made in Item_direct_ref::fix_fields */ + if ((*ref) && !(*ref)->fixed && ((*ref)->fix_fields(thd, reference))) return TRUE; - table_name= outer_field->table_name; - return Item_direct_ref::fix_fields(thd, reference); + err= Item_direct_ref::fix_fields(thd, reference); + if (!outer_ref) + outer_ref= *ref; + if ((*ref)->type() == Item::FIELD_ITEM) + table_name= ((Item_field*)outer_ref)->table_name; + return err; } + /* Compare two view column references for equality. diff --git a/sql/item.h b/sql/item.h index 2c4943bea6e..094c45642da 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1220,7 +1220,6 @@ public: uint have_privileges; /* field need any privileges (for VIEW creation) */ bool any_privileges; - bool fixed_as_field; Item_field(Name_resolution_context *context_arg, const char *db_arg,const char *table_name_arg, const char *field_name_arg); @@ -1978,30 +1977,49 @@ public: }; +/* + Class for outer fields. + An object of this class is created when the select where the outer field was + resolved is a grouping one. After it has been fixed the ref field will point + to either an Item_ref or an Item_direct_ref object which will be used to + access the field. + See also comments for the fix_inner_refs() and the + Item_field::fix_outer_field() functions. +*/ + +class Item_sum; class Item_outer_ref :public Item_direct_ref { public: - Item_field *outer_field; + Item *outer_ref; + /* The aggregate function under which this outer ref is used, if any. */ + Item_sum *in_sum_func; + /* + TRUE <=> that the outer_ref is already present in the select list + of the outer select. + */ + bool found_in_select_list; Item_outer_ref(Name_resolution_context *context_arg, Item_field *outer_field_arg) :Item_direct_ref(context_arg, 0, outer_field_arg->table_name, - outer_field_arg->field_name), - outer_field(outer_field_arg) + outer_field_arg->field_name), + outer_ref(outer_field_arg), in_sum_func(0), + found_in_select_list(0) { - ref= (Item**)&outer_field; + ref= &outer_ref; set_properties(); fixed= 0; } - void cleanup() - { - ref= (Item**)&outer_field; - fixed= 0; - Item_direct_ref::cleanup(); - outer_field->cleanup(); - } + Item_outer_ref(Name_resolution_context *context_arg, Item **item, + const char *table_name_arg, const char *field_name_arg, + bool alias_name_used_arg) + :Item_direct_ref(context_arg, item, table_name_arg, field_name_arg, + alias_name_used_arg), + outer_ref(0), in_sum_func(0), found_in_select_list(1) + {} void save_in_result_field(bool no_conversions) { - outer_field->save_org_in_field(result_field); + outer_ref->save_org_in_field(result_field); } bool fix_fields(THD *, Item **); table_map used_tables() const diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index ac1adc235c3..f9844f6d36e 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -69,6 +69,42 @@ static void agg_result_type(Item_result *type, Item **items, uint nitems) /* + Compare row signature of two expressions + + SYNOPSIS: + cmp_row_type() + item1 the first expression + item2 the second expression + + DESCRIPTION + The function checks that two expressions have compatible row signatures + i.e. that the number of columns they return are the same and that if they + are both row expressions then each component from the first expression has + a row signature compatible with the signature of the corresponding component + of the second expression. + + RETURN VALUES + 1 type incompatibility has been detected + 0 otherwise +*/ + +static int cmp_row_type(Item* item1, Item* item2) +{ + uint n= item1->cols(); + if (item2->check_cols(n)) + return 1; + for (uint i=0; i<n; i++) + { + if (item2->element_index(i)->check_cols(item1->element_index(i)->cols()) || + (item1->element_index(i)->result_type() == ROW_RESULT && + cmp_row_type(item1->element_index(i), item2->element_index(i)))) + return 1; + } + return 0; +} + + +/* Aggregates result types from the array of items. SYNOPSIS: @@ -82,14 +118,32 @@ static void agg_result_type(Item_result *type, Item **items, uint nitems) This function aggregates result types from the array of items. Found type supposed to be used later for comparison of values of these items. Aggregation itself is performed by the item_cmp_type() function. + The function also checks compatibility of row signatures for the + submitted items (see the spec for the cmp_row_type function). + + RETURN VALUES + 1 type incompatibility has been detected + 0 otherwise */ -static void agg_cmp_type(THD *thd, Item_result *type, Item **items, uint nitems) +static int agg_cmp_type(THD *thd, Item_result *type, Item **items, uint nitems) { uint i; type[0]= items[0]->result_type(); for (i= 1 ; i < nitems ; i++) + { type[0]= item_cmp_type(type[0], items[i]->result_type()); + /* + When aggregating types of two row expressions we have to check + that they have the same cardinality and that each component + of the first row expression has a compatible row signature with + the signature of the corresponding component of the second row + expression. + */ + if (type[0] == ROW_RESULT && cmp_row_type(items[0], items[i])) + return 1; // error found: invalid usage of rows + } + return 0; } @@ -1305,7 +1359,8 @@ void Item_func_between::fix_length_and_dec() */ if (!args[0] || !args[1] || !args[2]) return; - agg_cmp_type(thd, &cmp_type, args, 3); + if ( agg_cmp_type(thd, &cmp_type, args, 3)) + return; if (cmp_type == STRING_RESULT && agg_arg_charsets(cmp_collation, args, 3, MY_COLL_CMP_CONV, 1)) return; @@ -2021,7 +2076,8 @@ void Item_func_case::fix_length_and_dec() for (nagg= 0; nagg < ncases/2 ; nagg++) agg[nagg+1]= args[nagg*2]; nagg++; - agg_cmp_type(thd, &cmp_type, agg, nagg); + if (agg_cmp_type(thd, &cmp_type, agg, nagg)) + return; if ((cmp_type == STRING_RESULT) && agg_arg_charsets(cmp_collation, agg, nagg, MY_COLL_CMP_CONV, 1)) return; @@ -2710,7 +2766,8 @@ void Item_func_in::fix_length_and_dec() uint const_itm= 1; THD *thd= current_thd; - agg_cmp_type(thd, &cmp_type, args, arg_count); + if (agg_cmp_type(thd, &cmp_type, args, arg_count)) + return; if (cmp_type == STRING_RESULT && agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV, 1)) diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 19f3135c594..6956e5cfe91 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -369,6 +369,8 @@ bool mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds) { Item *fake_conds= 0; SELECT_LEX *select_lex= &thd->lex->select_lex; + const char *operation = thd->lex->sql_command == SQLCOM_TRUNCATE ? + "TRUNCATE" : "DELETE"; DBUG_ENTER("mysql_prepare_delete"); List<Item> all_fields; @@ -383,14 +385,14 @@ bool mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds) DBUG_RETURN(TRUE); if (!table_list->updatable || check_key_in_view(thd, table_list)) { - my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "DELETE"); + my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, operation); DBUG_RETURN(TRUE); } { TABLE_LIST *duplicate; if ((duplicate= unique_table(thd, table_list, table_list->next_global, 0))) { - update_non_unique_table_error(table_list, "DELETE", duplicate); + update_non_unique_table_error(table_list, operation, duplicate); DBUG_RETURN(TRUE); } } @@ -895,7 +897,8 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) if (!dont_send_ok) { db_type table_type; - mysql_frm_type(thd, path, &table_type); + if (mysql_frm_type(thd, path, &table_type) == FRMTYPE_VIEW) + goto trunc_by_del; if (table_type == DB_TYPE_UNKNOWN) { my_error(ER_NO_SUCH_TABLE, MYF(0), diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 3be844b6761..4be0aca3ea7 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1834,6 +1834,7 @@ bool st_lex::can_use_merged() case SQLCOM_UPDATE_MULTI: case SQLCOM_DELETE: case SQLCOM_DELETE_MULTI: + case SQLCOM_TRUNCATE: case SQLCOM_INSERT: case SQLCOM_INSERT_SELECT: case SQLCOM_REPLACE: diff --git a/sql/sql_select.cc b/sql/sql_select.cc index d65ecb6fa3b..dc018dd43bb 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -278,15 +278,30 @@ bool handle_select(THD *thd, LEX *lex, select_result *result, ref_pointer_array Array of references to Items used in current select DESCRIPTION - The function fixes fields referenced from inner selects and - also fixes references (Item_ref objects) to these fields. Each field - is fixed as a usual hidden field of the current select - it is added - to the all_fields list and the pointer to it is saved in the - ref_pointer_array if latter is provided. - After the field has been fixed we proceed with fixing references - (Item_ref objects) to this field from inner subqueries. If the - ref_pointer_array is provided then Item_ref objects is set to - reference element in that array with the pointer to the field. + The function serves 3 purposes - adds fields referenced from inner + selects to the current select list, resolves which class to use + to access referenced item (Item_ref of Item_direct_ref) and fixes + references (Item_ref objects) to these fields. + + If a field isn't already in the select list and the ref_pointer_array + is provided then it is added to the all_fields list and the pointer to + it is saved in the ref_pointer_array. + + The class to access the outer field is determined by the following rules: + 1. If the outer field isn't used under an aggregate function + then the Item_ref class should be used. + 2. If the outer field is used under an aggregate function and this + function is aggregated in the select where the outer field was + resolved or in some more inner select then the Item_direct_ref + class should be used. + The resolution is done here and not at the fix_fields() stage as + it can be done only after sum functions are fixed and pulled up to + selects where they are have to be aggregated. + When the class is chosen it substitutes the original field in the + Item_outer_ref object. + + After this we proceed with fixing references (Item_outer_ref objects) to + this field from inner subqueries. RETURN TRUE an error occured @@ -299,33 +314,64 @@ fix_inner_refs(THD *thd, List<Item> &all_fields, SELECT_LEX *select, { Item_outer_ref *ref; bool res= FALSE; + bool direct_ref= FALSE; + List_iterator<Item_outer_ref> ref_it(select->inner_refs_list); while ((ref= ref_it++)) { - Item_field *item= ref->outer_field; + Item *item= ref->outer_ref; + Item **item_ref= ref->ref; + Item_ref *new_ref; /* TODO: this field item already might be present in the select list. In this case instead of adding new field item we could use an existing one. The change will lead to less operations for copying fields, smaller temporary tables and less data passed through filesort. */ - if (ref_pointer_array) + if (ref_pointer_array && !ref->found_in_select_list) { int el= all_fields.elements; - ref_pointer_array[el]= (Item*)item; + ref_pointer_array[el]= item; /* Add the field item to the select list of the current select. */ - all_fields.push_front((Item*)item); + all_fields.push_front(item); /* If it's needed reset each Item_ref item that refers this field with a new reference taken from ref_pointer_array. */ - ref->ref= ref_pointer_array + el; + item_ref= ref_pointer_array + el; } - if (!ref->fixed && ref->fix_fields(thd, 0)) + + if (ref->in_sum_func) { - res= TRUE; - break; + Item_sum *sum_func; + if (ref->in_sum_func->nest_level > select->nest_level) + direct_ref= TRUE; + else + { + for (sum_func= ref->in_sum_func; sum_func && + sum_func->aggr_level >= select->nest_level; + sum_func= sum_func->in_sum_func) + { + if (sum_func->aggr_level == select->nest_level) + { + direct_ref= TRUE; + break; + } + } + } } + new_ref= direct_ref ? + new Item_direct_ref(ref->context, item_ref, ref->field_name, + ref->table_name, ref->alias_name_used) : + new Item_ref(ref->context, item_ref, ref->field_name, + ref->table_name, ref->alias_name_used); + if (!new_ref) + return TRUE; + ref->outer_ref= new_ref; + ref->ref= &ref->outer_ref; + + if (!ref->fixed && ref->fix_fields(thd, 0)) + return TRUE; thd->used_tables|= item->used_tables(); } return res; @@ -478,10 +524,6 @@ JOIN::prepare(Item ***rref_pointer_array, if (having && having->with_sum_func) having->split_sum_func2(thd, ref_pointer_array, all_fields, &having, TRUE); - if (select_lex->inner_refs_list.elements && - fix_inner_refs(thd, all_fields, select_lex, ref_pointer_array)) - DBUG_RETURN(-1); - if (select_lex->inner_sum_func_list) { Item_sum *end=select_lex->inner_sum_func_list; @@ -494,6 +536,10 @@ JOIN::prepare(Item ***rref_pointer_array, } while (item_sum != end); } + if (select_lex->inner_refs_list.elements && + fix_inner_refs(thd, all_fields, select_lex, ref_pointer_array)) + DBUG_RETURN(-1); + if (setup_ftfuncs(select_lex)) /* should be after having->fix_fields */ DBUG_RETURN(-1); @@ -5214,7 +5260,9 @@ get_store_key(THD *thd, KEYUSE *keyuse, table_map used_tables, } else if (keyuse->val->type() == Item::FIELD_ITEM || (keyuse->val->type() == Item::REF_ITEM && - ((Item_ref*)keyuse->val)->ref_type() == Item_ref::OUTER_REF) ) + ((Item_ref*)keyuse->val)->ref_type() == Item_ref::OUTER_REF && + (*(Item_ref**)((Item_ref*)keyuse->val)->ref)->ref_type() == + Item_ref::DIRECT_REF) ) return new store_key_field(thd, key_part->field, key_buff + maybe_null, @@ -13539,9 +13587,7 @@ create_distinct_group(THD *thd, Item **ref_pointer_array, ORDER *ord_iter; for (ord_iter= group; ord_iter; ord_iter= ord_iter->next) if ((*ord_iter->item)->eq(item, 1)) - break; - if (ord_iter) - continue; + goto next_item; ORDER *ord=(ORDER*) thd->calloc(sizeof(ORDER)); if (!ord) @@ -13556,6 +13602,7 @@ create_distinct_group(THD *thd, Item **ref_pointer_array, *prev=ord; prev= &ord->next; } +next_item: ref_pointer_array++; } *prev=0; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 57da29e2646..efbb7db4bcb 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -414,10 +414,11 @@ static int sort_keys(KEY *a, KEY *b) which has some duplicates on its right RETURN VALUES - void + 0 ok + 1 Error */ -void check_duplicates_in_interval(const char *set_or_name, +bool check_duplicates_in_interval(const char *set_or_name, const char *name, TYPELIB *typelib, CHARSET_INFO *cs, unsigned int *dup_val_count) { @@ -433,6 +434,13 @@ void check_duplicates_in_interval(const char *set_or_name, tmp.count--; if (find_type2(&tmp, (const char*)*cur_value, *cur_length, cs)) { + if ((current_thd->variables.sql_mode & + (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES))) + { + my_error(ER_DUPLICATED_VALUE_IN_TYPE, MYF(0), + name,*cur_value,set_or_name); + return 1; + } push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_NOTE, ER_DUPLICATED_VALUE_IN_TYPE, ER(ER_DUPLICATED_VALUE_IN_TYPE), @@ -440,6 +448,7 @@ void check_duplicates_in_interval(const char *set_or_name, (*dup_val_count)++; } } + return 0; } @@ -575,9 +584,10 @@ int prepare_create_field(create_field *sql_field, if (sql_field->charset->state & MY_CS_BINSORT) sql_field->pack_flag|=FIELDFLAG_BINARY; sql_field->unireg_check=Field::INTERVAL_FIELD; - check_duplicates_in_interval("ENUM",sql_field->field_name, - sql_field->interval, - sql_field->charset, &dup_val_count); + if (check_duplicates_in_interval("ENUM",sql_field->field_name, + sql_field->interval, + sql_field->charset, &dup_val_count)) + DBUG_RETURN(1); break; case FIELD_TYPE_SET: sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) | @@ -585,9 +595,10 @@ int prepare_create_field(create_field *sql_field, if (sql_field->charset->state & MY_CS_BINSORT) sql_field->pack_flag|=FIELDFLAG_BINARY; sql_field->unireg_check=Field::BIT_FIELD; - check_duplicates_in_interval("SET",sql_field->field_name, - sql_field->interval, - sql_field->charset, &dup_val_count); + if (check_duplicates_in_interval("SET",sql_field->field_name, + sql_field->interval, + sql_field->charset, &dup_val_count)) + DBUG_RETURN(1); /* Check that count of unique members is not more then 64 */ if (sql_field->interval->count - dup_val_count > sizeof(longlong)*8) { diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 1ec724a6338..7fb75732012 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -743,6 +743,7 @@ bool st_select_lex::cleanup() error= (bool) ((uint) error | (uint) lex_unit->cleanup()); } non_agg_fields.empty(); + inner_refs_list.empty(); DBUG_RETURN(error); } diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 8cb425edcec..54e2a6adba6 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -14,7 +14,7 @@ # Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston # MA 02110-1301 USA. -%define mysql_version @VERSION@ +%define mysql_version @VERSION@ # use "rpmbuild --with static" or "rpm --define '_with_static 1'" (for RPM 3.x) # to enable static linking (off by default) @@ -32,10 +32,10 @@ %define release 0.glibc23 %endif %define license GPL -%define mysqld_user mysql -%define mysqld_group mysql -%define server_suffix -standard -%define mysqldatadir /var/lib/mysql +%define mysqld_user mysql +%define mysqld_group mysql +%define server_suffix -community +%define mysqldatadir /var/lib/mysql # We don't package all files installed into the build root by intention - # See BUG#998 for details. @@ -99,7 +99,7 @@ Summary: MySQL: a very fast and reliable SQL database server Group: Applications/Databases Requires: coreutils grep procps /usr/sbin/useradd /usr/sbin/groupadd /sbin/chkconfig Provides: msqlormysql mysql-server mysql MySQL -Obsoletes: MySQL mysql mysql-server +Obsoletes: MySQL mysql mysql-server mysql-Max %description server The MySQL(TM) software delivers a very fast, multi-threaded, multi-user, @@ -120,7 +120,7 @@ This package includes the MySQL server binary (incl. InnoDB) as well as related utilities to run and administrate a MySQL server. If you want to access and work with the database, you have to install -package "MySQL-client" as well! +the package "MySQL-client" as well! %package client Summary: MySQL - Client @@ -141,8 +141,6 @@ Group: Applications/Databases This package contains the ndbcluster storage engine. It is necessary to have this package installed on all computers that should store ndbcluster table data. -Note that this storage engine can only be used in conjunction -with the MySQL Max server. %{see_base} @@ -211,29 +209,6 @@ Obsoletes: mysql-shared This package contains the shared libraries (*.so*) which certain languages and applications need to dynamically load and use MySQL. -%package Max -Summary: MySQL - server with extended functionality -Group: Applications/Databases -Provides: mysql-Max -Obsoletes: mysql-Max -Requires: MySQL-server >= @MYSQL_BASE_VERSION@ - -%description Max -Optional MySQL server binary that supports additional features like: - - - Berkeley DB Storage Engine - - Ndbcluster Storage Engine interface - - Archive Storage Engine - - CSV Storage Engine - - Example Storage Engine - - Federated Storage Engine - - User Defined Functions (UDFs). - -To activate this binary, just install this package in addition to -the standard MySQL package. - -Please note that this is a dynamically linked binary! - #%package embedded #Requires: %{name}-devel #Summary: MySQL - embedded library @@ -323,9 +298,6 @@ mkdir -p $RBR%{_libdir}/mysql PATH=${MYSQL_BUILD_PATH:-/bin:/usr/bin} export PATH -# Build the Max binary (includes BDB and UDFs and therefore -# cannot be linked statically against the patched glibc) - # Use gcc for C and C++ code (to avoid a dependency on libstdc++ and # including exceptions into the code if [ -z "$CXX" -a -z "$CC" ] @@ -334,76 +306,44 @@ then export CXX="gcc" fi -BuildMySQL "--enable-shared \ - --with-extra-charsets=all \ - --with-berkeley-db \ - --with-innodb \ - --with-ndbcluster \ - --with-archive-storage-engine \ - --with-csv-storage-engine \ - --with-example-storage-engine \ - --with-blackhole-storage-engine \ - --with-federated-storage-engine \ - --with-big-tables \ - --with-comment=\"MySQL Community Edition - Experimental (GPL)\" \ - --with-server-suffix='-max'" - -# We might want to save the config log file -if test -n "$MYSQL_MAXCONFLOG_DEST" -then - cp -fp config.log "$MYSQL_MAXCONFLOG_DEST" -fi - -make test-bt - -# Save mysqld-max -./libtool --mode=execute cp sql/mysqld sql/mysqld-max -./libtool --mode=execute nm --numeric-sort sql/mysqld-max > sql/mysqld-max.sym - -# Save the perror binary so it supports the NDB error codes (BUG#13740) -./libtool --mode=execute cp extra/perror extra/perror.ndb - -# Install the ndb binaries -(cd ndb; make install DESTDIR=$RBR) - -# Include libgcc.a in the devel subpackage (BUG 4921) -if expr "$CC" : ".*gcc.*" > /dev/null ; -then - libgcc=`$CC $CFLAGS --print-libgcc-file` - if [ -f $libgcc ] - then - %define have_libgcc 1 - install -m 644 $libgcc $RBR%{_libdir}/mysql/libmygcc.a - fi -fi - -# Save libraries -(cd libmysql/.libs; tar cf $RBR/shared-libs.tar *.so*) -(cd libmysql_r/.libs; tar rf $RBR/shared-libs.tar *.so*) -(cd ndb/src/.libs; tar rf $RBR/shared-libs.tar *.so*) - -# Now clean up -make clean - # # Only link statically on our i386 build host (which has a specially # patched static glibc installed) - ia64 and x86_64 run glibc-2.3 (unpatched) # so don't link statically there # -BuildMySQL "--disable-shared \ +for servertype in '--with-debug=full' ' ' +do + BuildMySQL "\ %if %{STATIC_BUILD} + --disable-shared \ --with-mysqld-ldflags='-all-static' \ --with-client-ldflags='-all-static' \ $USE_OTHER_LIBC_DIR \ %else + --enable-shared \ --with-zlib-dir=bundled \ %endif --with-extra-charsets=complex \ - --with-comment=\"MySQL Community Edition - Standard (GPL)\" \ + --with-comment=\"MySQL Community Edition (GPL)\" \ --with-server-suffix='%{server_suffix}' \ --with-archive-storage-engine \ --with-innodb \ - --with-big-tables" + --with-ndbcluster \ + --with-csv-storage-engine \ + --with-example-storage-engine \ + --with-blackhole-storage-engine \ + --with-federated-storage-engine \ + --with-big-tables $servertype" + if test "$servertype" != ' ' + then + # if this is not the regular build, we save the server binary + ./libtool --mode=execute cp sql/mysqld sql/mysqld-debug + ./libtool --mode=execute nm --numeric-sort sql/mysqld-debug > sql/mysqld-debug.sym + echo "# debug" + make test-bt + make clean + fi +done ./libtool --mode=execute nm --numeric-sort sql/mysqld > sql/mysqld.sym @@ -413,6 +353,7 @@ then cp -fp config.log "$MYSQL_CONFLOG_DEST" fi +echo "# standard" make test-bt %install @@ -428,22 +369,33 @@ install -d $RBR%{_libdir} install -d $RBR%{_mandir} install -d $RBR%{_sbindir} - # Install all binaries stripped make install-strip DESTDIR=$RBR benchdir_root=%{_datadir} -# Install shared libraries (Disable for architectures that don't support it) -(cd $RBR%{_libdir}; tar xf $RBR/shared-libs.tar; rm -f $RBR/shared-libs.tar) +# Install the ndb binaries +(cd ndb; make install DESTDIR=$RBR) -# install saved mysqld-max -install -s -m 755 $MBD/sql/mysqld-max $RBR%{_sbindir}/mysqld-max +# Install the saved debug server +install -s -m 755 $MBD/sql/mysqld-debug $RBR%{_sbindir}/mysqld-debug -# install saved perror binary with NDB support (BUG#13740) -install -s -m 755 $MBD/extra/perror.ndb $RBR%{_bindir}/perror +# Install shared libraries (Disable for architectures that don't support it) +# (cd $RBR%{_libdir}; tar xf $RBR/shared-libs.tar; rm -f $RBR/shared-libs.tar) + +# Include libgcc.a in the devel subpackage (BUG 4921) +if expr "$CC" : ".*gcc.*" > /dev/null ; +then + libgcc=`$CC $CFLAGS --print-libgcc-file` + if [ -f $libgcc ] + then + %define have_libgcc 1 + install -m 644 $libgcc $RBR%{_libdir}/mysql/libmygcc.a + fi +fi # install symbol files ( for stack trace resolution) -install -m 644 $MBD/sql/mysqld-max.sym $RBR%{_libdir}/mysql/mysqld-max.sym +# install -m 644 $MBD/sql/mysqld-max.sym $RBR%{_libdir}/mysql/mysqld-max.sym install -m 644 $MBD/sql/mysqld.sym $RBR%{_libdir}/mysql/mysqld.sym +install -m 644 $MBD/sql/mysqld-debug.sym $RBR%{_libdir}/mysql/mysqld-debug.sym # Install logrotate and autostart install -m 644 $MBD/support-files/mysql-log-rotate $RBR%{_sysconfdir}/logrotate.d/mysql @@ -529,19 +481,12 @@ chmod -R og-rw $mysql_datadir/mysql # Allow safe_mysqld to start mysqld and print a message before we exit sleep 2 - %post ndb-storage mysql_clusterdir=/var/lib/mysql-cluster # Create cluster directory if needed if test ! -d $mysql_clusterdir; then mkdir -m 755 $mysql_clusterdir; fi - -%post Max -# Restart mysqld, to use the new binary. -echo "Restarting mysqld." -%{_sysconfdir}/init.d/mysql restart > /dev/null 2>&1 - %preun server if test $1 = 0 then @@ -611,7 +556,6 @@ fi %attr(755, root, root) %{_bindir}/myisamlog %attr(755, root, root) %{_bindir}/myisampack %attr(755, root, root) %{_bindir}/mysql_convert_table_format -%attr(755, root, root) %{_bindir}/mysql_create_system_tables %attr(755, root, root) %{_bindir}/mysql_explain_log %attr(755, root, root) %{_bindir}/mysql_fix_extensions %attr(755, root, root) %{_bindir}/mysql_fix_privilege_tables @@ -634,6 +578,7 @@ fi %attr(755, root, root) %{_bindir}/safe_mysqld %attr(755, root, root) %{_sbindir}/mysqld +%attr(755, root, root) %{_sbindir}/mysqld-debug %attr(755, root, root) %{_sbindir}/mysqlmanager %attr(755, root, root) %{_sbindir}/rcmysql %attr(644, root, root) %{_libdir}/mysql/mysqld.sym @@ -762,11 +707,6 @@ fi %doc %attr(644, root, man) %{_mandir}/man1/mysql-stress-test.pl.1* %doc %attr(644, root, man) %{_mandir}/man1/mysql-test-run.pl.1* -%files Max -%defattr(-, root, root, 0755) -%attr(755, root, root) %{_sbindir}/mysqld-max -%attr(644, root, root) %{_libdir}/mysql/mysqld-max.sym - #%files embedded #%defattr(-, root, root, 0755) # %attr(644, root, root) %{_libdir}/mysql/libmysqld.a @@ -774,7 +714,20 @@ fi # The spec file changelog only includes changes made to the spec file # itself - note that they must be ordered by date (important when # merging BK trees) -%changelog +%changelog +* Sat Apr 07 2007 Kent Boortz <kent@mysql.com> + +- Removed man page for "mysql_create_system_tables" + +* Wed Mar 21 2007 Daniel Fischer <df@mysql.com> + +- Add debug server. + +* Mon Mar 19 2007 Daniel Fischer <df@mysql.com> + +- Remove Max RPMs; the server RPMs contain a mysqld compiled with all + features that previously only were built into Max. + * Fri Mar 02 2007 Joerg Bruehe <joerg@mysql.com> - Add several man pages for NDB which are now created. diff --git a/zlib/Makefile.am b/zlib/Makefile.am index c40c922851e..edcbd5f4a75 100644 --- a/zlib/Makefile.am +++ b/zlib/Makefile.am @@ -19,16 +19,18 @@ INCLUDES= -I$(top_builddir)/include -I$(top_srcdir)/include LIBS= $(NON_THREADED_LIBS) -pkglib_LTLIBRARIES=libz.la +pkglib_LTLIBRARIES = libz.la +noinst_LTLIBRARIES = libzlt.la -libz_la_LDFLAGS= -version-info 3:3:2 +libz_la_LDFLAGS = -static -noinst_HEADERS= crc32.h deflate.h inffast.h inffixed.h inflate.h \ - inftrees.h trees.h zconf.h zlib.h zutil.h +noinst_HEADERS = crc32.h deflate.h inffast.h inffixed.h inflate.h \ + inftrees.h trees.h zconf.h zlib.h zutil.h -libz_la_SOURCES= adler32.c compress.c crc32.c deflate.c gzio.c \ - infback.c inffast.c inflate.c inftrees.c trees.c \ - uncompr.c zutil.c +libz_la_SOURCES = adler32.c compress.c crc32.c deflate.c gzio.c \ + infback.c inffast.c inflate.c inftrees.c trees.c \ + uncompr.c zutil.c +libzlt_la_SOURCES = $(libz_la_SOURCES) EXTRA_DIST= README FAQ INDEX ChangeLog algorithm.txt zlib.3 CMakeLists.txt |