diff --git a/BitKeeper/etc/gone b/BitKeeper/etc/gone index aa676accb71..126bd4e38d3 100644 --- a/BitKeeper/etc/gone +++ b/BitKeeper/etc/gone @@ -1181,26 +1181,15 @@ sasha@mysql.sashanet.com|build-tags|20011125054855|05181|7afb7e785b80f97 sasha@mysql.sashanet.com|build-tags|20011201050944|25384|b6f6fff142121618 sasha@mysql.sashanet.com|libmysql_r/acconfig.h|20001128060846|51084|65f1202b3b5c345f sasha@mysql.sashanet.com|mysql-test/README.gcov|20001012045950|28177|5a6da067a30780ce -sasha@mysql.sashanet.com|mysql-test/README.gcov|20001214012355|41825|2de7575ca81155e5 sasha@mysql.sashanet.com|mysql-test/README|20001010001022|12739|108667adaeabe3f5 sasha@mysql.sashanet.com|mysql-test/r/3.23/alt000001.result|20001122072330|24729|393103dbf15f35c9 sasha@mysql.sashanet.com|mysql-test/r/3.23/ins000001.result|20001018175743|49824|f45c599efdf8352b sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000001.a.result|20001118063528|39426|2987b17db06808c3 sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000001.b.result|20001118063528|44057|62e1fa91167cacc3 -sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000002.result|20001118063528|46039|109f5ceed1e0d64 sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000003.result|20001118063528|48148|68d6ee00beaa011 sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000004.a.result|20001118063528|50132|3415f066cb91c460 sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000004.b.result|20001118063528|52094|352b35351551485 -sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000005.result|20001118063528|54071|a50962bc2340ab9a -sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000006.result|20001118063528|56081|5653051e8ce6b4aa -sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000007.result|20001121063807|21606|e0c3b6134e0884da -sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000008.result|20001121063807|23636|c5cfee19ca5a7da9 -sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000009.result|20001121063807|25633|ed8042446ab97926 -sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000010.result|20001122072330|29430|3228109b8965b0f8 -sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000011.result|20001125024912|48851|c29dce30aa97f265 -sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000012.result|20001126062901|05938|35d6596da7b90fc5 sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000012.status.result|20001126062901|09395|bbbd650b5beea32f -sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000013.result|20001202171150|03876|ac5024e6cf6daac6 sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000013.status.result|20001202171150|06069|6bee190c298cc9fd sasha@mysql.sashanet.com|mysql-test/r/3.23/sel000003.result|20001011230020|64653|d7b657b1e3a286a7 sasha@mysql.sashanet.com|mysql-test/r/3.23/sel000100.res|20001205131218|23520|84ed46856cb3a69f @@ -1209,7 +1198,6 @@ sasha@mysql.sashanet.com|mysql-test/r/binlog-backup-restore.result|2001042423392 sasha@mysql.sashanet.com|mysql-test/r/df_crash.result|20010406010433|59989|4a3dbee64843953d sasha@mysql.sashanet.com|mysql-test/r/identity.result|20010910233028|16331|e41453a364242503 sasha@mysql.sashanet.com|mysql-test/r/mrg000002.result|20001212152450|11492|745be0854aaaaf5e -sasha@mysql.sashanet.com|mysql-test/r/slave-running.result|20001208141122|24303|f73e49462cf59e1f sasha@mysql.sashanet.com|mysql-test/r/slave-stopped.result|20001208141122|28916|25c134b1a4f1993a sasha@mysql.sashanet.com|mysql-test/std_data/m.MRG|20001212152450|17736|3f5632c37af00f18 sasha@mysql.sashanet.com|mysql-test/std_data/m.frm|20001212152450|13897|e351dfe0b6824c0c diff --git a/Build-tools/mysql-copyright-2 b/Build-tools/mysql-copyright-2 index 2ea2e8ef441..972d5483d54 100755 --- a/Build-tools/mysql-copyright-2 +++ b/Build-tools/mysql-copyright-2 @@ -109,6 +109,12 @@ sub add_copyright $line_copyright= "! "; $end_copyright= ""; } + elsif ($ARGV =~ /\.sql$/) + { + $start_copyright="-- "; + $line_copyright= "-- "; + $end_copyright= ""; + } elsif ($ARGV =~ /\.asm$/) { $start_copyright="; "; diff --git a/VC++Files/mysql.dsw b/VC++Files/mysql.dsw index b0a36f1bd24..43cfab4b915 100644 --- a/VC++Files/mysql.dsw +++ b/VC++Files/mysql.dsw @@ -735,15 +735,15 @@ Package=<4> ############################################################################### -Project: "mysqltest"=.\client\mysqltest.dsp - Package Owner=<4> - -Package=<5> +Project: "mysqltest"=.\client\mysqltest.dsp - Package Owner=<4> + +Package=<5> {{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency + }}} + + +Package=<4> +{{{ Begin Project Dependency Project_Dep_Name libmysql End Project Dependency Begin Project Dependency @@ -754,24 +754,40 @@ Package=<4> End Project Dependency }}} -############################################################################### +############################################################################### + +Project: "mysql_client_test"=.\tests\mysql_client_test.dsp - Package Owner=<4> + + Package=<5> +{{{ + }}} + + Package=<4> + {{{ + }}} -Project: "mysql_test_run_new"=".\mysql-test\mysql_test_run_new.dsp" - Package Owner=<4> + ############################################################################### -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency + +Project: "mysql_test_run_new"=".\mysql-test\mysql_test_run_new.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ Begin Project Dependency Project_Dep_Name mysqltest End Project Dependency Begin Project Dependency Project_Dep_Name mysqladmin End Project Dependency + Begin Project Dependency + Project_Dep_Name mysql_client_test + End Project Dependency }}} + ############################################################################### Global: diff --git a/VC++Files/tests/mysql_client_test.dsp b/VC++Files/tests/mysql_client_test.dsp new file mode 100644 index 00000000000..07014487bd1 --- /dev/null +++ b/VC++Files/tests/mysql_client_test.dsp @@ -0,0 +1,94 @@ +# Microsoft Developer Studio Project File - Name="mysql_client_test" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=mysql_client_test - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mysql_client_test.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mysql_client_test.mak" CFG="mysql_client_test - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mysql_client_test - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "mysql_client_test - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mysql_client_test - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir ".\Debug" +# PROP BASE Intermediate_Dir ".\Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir ".\Debug" +# PROP Intermediate_Dir ".\Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /I "../include" /I "../" /Z7 /W3 /Od /G6 /D "_DEBUG" /D "_WINDOWS" /D "SAFE_MUTEX" /D "USE_TLS" /D "MYSQL_CLIENT" /D "__WIN__" /D "_WIN32" /Fp".\Debug/mysql_client_test.pch" /Fo".\Debug/" /Fd".\Debug/" /GZ /c /GX +# ADD CPP /nologo /MTd /I "../include" /I "../" /Z7 /W3 /Od /G6 /D "_DEBUG" /D "_WINDOWS" /D "SAFE_MUTEX" /D "USE_TLS" /D "MYSQL_CLIENT" /D "__WIN__" /D "_WIN32" /Fp".\Debug/mysql_client_test.pch" /Fo".\Debug/" /Fd".\Debug/" /GZ /c /GX +# ADD BASE MTL /nologo /tlb".\Debug\mysql_client_test.tlb" /win32 +# ADD MTL /nologo /tlb".\Debug\mysql_client_test.tlb" /win32 +# ADD BASE RSC /l 1033 +# ADD RSC /l 1033 +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib odbc32.lib odbccp32.lib mysqlclient.lib wsock32.lib mysys.lib regex.lib /nologo /out:"..\tests\mysql_client_test.exe" /incremental:yes /libpath:"..\lib_debug\" /debug /pdb:".\Debug\mysql_client_test.pdb" /pdbtype:sept /map:".\Debug\mysql_client_test.map" /subsystem:console +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib odbc32.lib odbccp32.lib mysqlclient.lib wsock32.lib mysys.lib regex.lib /nologo /out:"..\tests\mysql_client_test.exe" /incremental:yes /libpath:"..\lib_debug\" /debug /pdb:".\Debug\mysql_client_test.pdb" /pdbtype:sept /map:".\Debug\mysql_client_test.map" /subsystem:console + +!ELSEIF "$(CFG)" == "mysql_client_test - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir ".\Release" +# PROP BASE Intermediate_Dir ".\Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir ".\Release" +# PROP Intermediate_Dir ".\Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /I "../include" /I "../" /W3 /Ob1 /G6 /D "DBUG_OFF" /D "_WINDOWS" /D "SAFE_MUTEX" /D "USE_TLS" /D "MYSQL_CLIENT" /D "__WIN__" /D "_WIN32" /GF /Gy /Fp".\Release/client_test.pch" /Fo".\Release/" /Fd".\Release/" /c /GX +# ADD CPP /nologo /MTd /I "../include" /I "../" /W3 /Ob1 /G6 /D "DBUG_OFF" /D "_WINDOWS" /D "SAFE_MUTEX" /D "USE_TLS" /D "MYSQL_CLIENT" /D "__WIN__" /D "_WIN32" /GF /Gy /Fp".\Release/client_test.pch" /Fo".\Release/" /Fd".\Release/" /c /GX +# ADD BASE MTL /nologo /tlb".\Release\client_test.tlb" /win32 +# ADD MTL /nologo /tlb".\Release\client_test.tlb" /win32 +# ADD BASE RSC /l 1033 +# ADD RSC /l 1033 +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib odbc32.lib odbccp32.lib Ws2_32.lib /nologo /out:"..\tests\client_test.exe" /incremental:no /pdb:".\Release\client_test.pdb" /pdbtype:sept /subsystem:console +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib odbc32.lib odbccp32.lib Ws2_32.lib /nologo /out:"..\tests\client_test.exe" /incremental:no /pdb:".\Release\client_test.pdb" /pdbtype:sept /subsystem:console + +!ENDIF + +# Begin Target + +# Name "mysql_client_test - Win32 Debug" +# Name "mysql_client_test - Win32 Release" +# Begin Source File + +SOURCE=tests\mysql_client_test.c +# End Source File +# End Target +# End Project + diff --git a/client/mysqltest.c b/client/mysqltest.c index 4d03746a5e5..7bdcf6db3e5 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -2379,6 +2379,8 @@ void usage() #include +#include + static my_bool get_one_option(int optid, const struct my_option *opt __attribute__((unused)), diff --git a/config/ac-macros/zlib.m4 b/config/ac-macros/zlib.m4 index 6c92d561e5a..94a26f33dd3 100644 --- a/config/ac-macros/zlib.m4 +++ b/config/ac-macros/zlib.m4 @@ -3,6 +3,8 @@ 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" +dnl Omit -L$pkglibdir as it's always in the list of mysql_config deps. +ZLIB_DEPS="-lz" zlib_dir="zlib" AC_SUBST([zlib_dir]) mysql_cv_compress="yes" @@ -44,8 +46,13 @@ dnl $prefix/lib. If zlib headers or binaries weren't found at $prefix, the dnl macro bails out with error. dnl dnl If the library was found, this function #defines HAVE_COMPRESS -dnl and configure variables ZLIB_INCLUDES (i.e. -I/path/to/zlib/include) and -dnl ZLIB_LIBS (i. e. -L/path/to/zlib/lib -lz). +dnl and configure variables ZLIB_INCLUDES (i.e. -I/path/to/zlib/include), +dnl ZLIB_LIBS (i. e. -L/path/to/zlib/lib -lz) and ZLIB_DEPS which is +dnl used in mysql_config and is always the same as ZLIB_LIBS except to +dnl when we use the bundled zlib. In the latter case ZLIB_LIBS points to the +dnl build dir ($top_builddir/zlib), while mysql_config must point to the +dnl installation dir ($pkglibdir), so ZLIB_DEPS is set to point to +dnl $pkglibdir. AC_DEFUN([MYSQL_CHECK_ZLIB_WITH_COMPRESS], [ AC_MSG_CHECKING([for zlib compression library]) @@ -94,7 +101,11 @@ case $SYSTEM_TYPE in ;; esac if test "$mysql_cv_compress" = "yes"; then + if test "x$ZLIB_DEPS" = "x"; then + ZLIB_DEPS="$ZLIB_LIBS" + fi AC_SUBST([ZLIB_LIBS]) + AC_SUBST([ZLIB_DEPS]) AC_SUBST([ZLIB_INCLUDES]) AC_DEFINE([HAVE_COMPRESS], [1], [Define to enable compression support]) fi diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am index 3d5833c47be..8735c4c1fff 100644 --- a/mysql-test/Makefile.am +++ b/mysql-test/Makefile.am @@ -47,7 +47,7 @@ dist-hook: $(distdir)/std_data $(INSTALL_DATA) $(srcdir)/t/*.test $(srcdir)/t/*.opt $(srcdir)/t/*.sh $(srcdir)/t/*.slave-mi $(distdir)/t $(INSTALL_DATA) $(srcdir)/include/*.inc $(distdir)/include - $(INSTALL_DATA) $(srcdir)/r/*.result $(srcdir)/r/*.require $(distdir)/r + $(INSTALL_DATA) $(srcdir)/r/*.result $(srcdir)/r/*.result.es $(srcdir)/r/*.require $(distdir)/r $(INSTALL_DATA) $(srcdir)/std_data/Moscow_leap $(distdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/*.dat $(srcdir)/std_data/*.000001 $(distdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/des_key_file $(distdir)/std_data @@ -65,7 +65,7 @@ install-data-local: $(INSTALL_DATA) $(srcdir)/t/*.opt $(DESTDIR)$(testdir)/t $(INSTALL_DATA) $(srcdir)/t/*.sh $(DESTDIR)$(testdir)/t $(INSTALL_DATA) $(srcdir)/t/*.slave-mi $(DESTDIR)$(testdir)/t - $(INSTALL_DATA) $(srcdir)/r/*.result $(DESTDIR)$(testdir)/r + $(INSTALL_DATA) $(srcdir)/r/*.result $(srcdir)/r/*.result.es $(DESTDIR)$(testdir)/r $(INSTALL_DATA) $(srcdir)/r/*.require $(DESTDIR)$(testdir)/r $(INSTALL_DATA) $(srcdir)/include/*.inc $(DESTDIR)$(testdir)/include $(INSTALL_DATA) $(srcdir)/std_data/*.dat $(DESTDIR)$(testdir)/std_data diff --git a/mysql-test/my_create_tables.c b/mysql-test/my_create_tables.c index 405f66dc8df..06a6fabf022 100644 --- a/mysql-test/my_create_tables.c +++ b/mysql-test/my_create_tables.c @@ -96,6 +96,8 @@ bool create_system_files(const char *mdata,const char *output_file, bool test) "Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL," "PRIMARY KEY Host (Host,Db,User)," "KEY User (User))" + "engine=MyISAM " + "CHARACTER SET utf8 COLLATE utf8_bin " "comment='Database privileges';\n"); if (test) @@ -126,10 +128,12 @@ bool create_system_files(const char *mdata,const char *output_file, bool test) "Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL," "Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL," "PRIMARY KEY Host (Host,Db))" - "comment='Host privileges;" - " Merged with database privileges';\n"); + "engine=MyISAM " + "CHARACTER SET utf8 COLLATE utf8_bin " + "comment='Host privileges; Merged with database privileges';\n"); } + if (test_sys_file(mdata,"mysql/user.frm")) { #ifdef __WIN__ @@ -184,7 +188,10 @@ bool create_system_files(const char *mdata,const char *output_file, bool test) "max_updates int(11) unsigned DEFAULT 0 NOT NULL," "max_connections int(11) unsigned DEFAULT 0 NOT NULL," "PRIMARY KEY Host (Host,User)" - ") comment='Users and global privileges';\n"); + ") engine=MyISAM " + "CHARACTER SET utf8 COLLATE utf8_bin " + "comment='Users and global privileges';\n"); + if (test) { @@ -238,7 +245,9 @@ bool create_system_files(const char *mdata,const char *output_file, bool test) "dl char(128) DEFAULT '' NOT NULL," "type enum ('function','aggregate') NOT NULL," "PRIMARY KEY (name)" - ") comment='User defined functions';\n"); + ") engine=MyISAM " + "CHARACTER SET utf8 COLLATE utf8_bin " + "comment='User defined functions';\n"); } if (test_sys_file(mdata,"mysql/tables_priv.frm")) @@ -258,7 +267,9 @@ bool create_system_files(const char *mdata,const char *output_file, bool test) " DEFAULT '' NOT NULL," "PRIMARY KEY (Host,Db,User,Table_name)," "KEY Grantor (Grantor)" - ") comment='Table privileges';\n"); + ") engine=MyISAM " + "CHARACTER SET utf8 COLLATE utf8_bin " + "comment='Table privileges';\n"); } if (test_sys_file(mdata,"mysql/columns_priv.frm")) @@ -274,7 +285,9 @@ bool create_system_files(const char *mdata,const char *output_file, bool test) "Column_priv set('Select','Insert','Update','References')" " DEFAULT '' NOT NULL," "PRIMARY KEY (Host,Db,User,Table_name,Column_name)" - ") comment='Column privileges';\n"); + ") engine=MyISAM " + "CHARACTER SET utf8 COLLATE utf8_bin " + "comment='Column privileges';\n"); } if (test_sys_file(mdata,"mysql/help_topic.frm")) @@ -289,7 +302,9 @@ bool create_system_files(const char *mdata,const char *output_file, bool test) "url varchar(128) not null," "primary key (help_topic_id)," "unique index (name)" - ") comment='help topics';\n"); + ") engine=MyISAM " + "CHARACTER SET utf8 " + "comment='help topics';\n"); } if (test_sys_file(mdata,"mysql/help_category.frm")) @@ -302,7 +317,9 @@ bool create_system_files(const char *mdata,const char *output_file, bool test) "url varchar(128) not null," "primary key (help_category_id)," "unique index (name)" - ") comment='help categories';\n"); + ") engine=MyISAM " + "CHARACTER SET utf8 " + "comment='help categories';\n"); } if (test_sys_file(mdata,"mysql/help_keyword.frm")) @@ -313,7 +330,9 @@ bool create_system_files(const char *mdata,const char *output_file, bool test) "name varchar(64) not null," "primary key (help_keyword_id)," "unique index (name)" - ") comment='help keywords';\n"); + ") engine=MyISAM " + "CHARACTER SET utf8 " + "comment='help keywords';\n"); } if (test_sys_file(mdata,"mysql/help_relation.frm")) @@ -323,7 +342,9 @@ bool create_system_files(const char *mdata,const char *output_file, bool test) "help_topic_id int unsigned not null references help_topic," "help_keyword_id int unsigned not null references help_keyword," "primary key (help_keyword_id, help_topic_id)" - ") comment='keyword-topic relation';\n"); + ") engine=MyISAM " + "CHARACTER SET utf8 " + "comment='keyword-topic relation';\n"); } if (test_sys_file(mdata,"mysql/time_zone_name.frm")) @@ -333,7 +354,7 @@ bool create_system_files(const char *mdata,const char *output_file, bool test) "Name char(64) NOT NULL," "Time_zone_id int unsigned NOT NULL," "PRIMARY KEY Name (Name)" - ") DEFAULT CHARACTER SET latin1 " + ") engine=MyISAM CHARACTER SET utf8 " "comment='Time zone names';\n"); if (test) @@ -341,7 +362,9 @@ bool create_system_files(const char *mdata,const char *output_file, bool test) fprintf(out, "INSERT INTO time_zone_name (Name, Time_Zone_id) VALUES" "('MET', 1), ('UTC', 2), ('Universal', 2), " - "('Europe/Moscow',3), ('leap/Europe/Moscow',4);\n"); + "('Europe/Moscow',3), ('leap/Europe/Moscow',4)," + "('Japan', 5);\n"); + } } @@ -353,13 +376,13 @@ bool create_system_files(const char *mdata,const char *output_file, bool test) "Time_zone_id int unsigned NOT NULL auto_increment," "Use_leap_seconds enum('Y','N') DEFAULT 'N' NOT NULL," "PRIMARY KEY TzId (Time_zone_id)" - ") DEFAULT CHARACTER SET latin1 " + ") engine=MyISAM CHARACTER SET utf8 " "comment='Time zones';\n"); if (test) { fprintf(out,"INSERT INTO time_zone (Time_zone_id, Use_leap_seconds)" - "VALUES (1,'N'), (2,'N'), (3,'N'), (4,'Y');\n"); + "VALUES (1,'N'), (2,'N'), (3,'N'), (4,'Y'), (5,'N');\n"); } } @@ -371,7 +394,7 @@ bool create_system_files(const char *mdata,const char *output_file, bool test) "Transition_time bigint signed NOT NULL," "Transition_type_id int unsigned NOT NULL," "PRIMARY KEY TzIdTranTime (Time_zone_id, Transition_time)" - ") DEFAULT CHARACTER SET latin1 " + ") engine=MyISAM CHARACTER SET utf8 " "comment='Time zone transitions';\n"); if (test) @@ -576,7 +599,9 @@ bool create_system_files(const char *mdata,const char *output_file, bool test) ",(4, 2045689222, 8) ,(4, 2058390022, 9)" ",(4, 2077138822, 8) ,(4, 2090444422, 9)" ",(4, 2108588422, 8) ,(4, 2121894022, 9)" - ",(4, 2140038022, 8);\n"); + ",(4, 2140038022, 8), (5, -1009875600, 1);\n"); + + } } @@ -590,7 +615,7 @@ bool create_system_files(const char *mdata,const char *output_file, bool test) "Is_DST tinyint unsigned DEFAULT 0 NOT NULL," "Abbreviation char(8) DEFAULT '' NOT NULL," "PRIMARY KEY TzIdTrTId (Time_zone_id, Transition_type_id)" - ") DEFAULT CHARACTER SET latin1 " + ") engine=MyISAM CHARACTER SET utf8 " "comment='Time zone transition types';\n"); if (test) @@ -612,7 +637,9 @@ bool create_system_files(const char *mdata,const char *output_file, bool test) ",(4, 4, 10800, 0, 'MSK') ,(4, 5, 14400, 1, 'MSD')" ",(4, 6, 18000, 1, 'MSD') ,(4, 7, 7200, 0, 'EET')" ",(4, 8, 10800, 0, 'MSK') ,(4, 9, 14400, 1, 'MSD')" - ",(4, 10, 10800, 1, 'EEST') ,(4, 11, 7200, 0, 'EET');\n"); + ",(4, 10, 10800, 1, 'EEST') ,(4, 11, 7200, 0, 'EET')" + ",(5, 0, 32400, 0, 'CJT') ,(5, 1, 32400, 0, 'JST');\n"); + } } @@ -623,7 +650,7 @@ bool create_system_files(const char *mdata,const char *output_file, bool test) "Transition_time bigint signed NOT NULL," "Correction int signed NOT NULL," "PRIMARY KEY TranTime (Transition_time)" - ") DEFAULT CHARACTER SET latin1 " + ") engine=MyISAM CHARACTER SET utf8 " "comment='Leap seconds information for time zones';\n"); if (test) diff --git a/mysql-test/my_manage.c b/mysql-test/my_manage.c index 1f006f7ab90..88e68dfc27e 100644 --- a/mysql-test/my_manage.c +++ b/mysql-test/my_manage.c @@ -122,7 +122,7 @@ void add_arg(arg_list_t *al, const char *format, ...) al->argv[al->argc]= malloc(strlen(temp)+1); ASSERT(al->argv[al->argc] != NULL); strcpy(al->argv[al->argc], temp); - + ++(al->argc); } else @@ -644,7 +644,7 @@ void del_tree(char *dir) if (lstat(entry->d_name, &st) == -1) { /* FIXME error */ - return; + return; } if (S_ISDIR(st.st_mode)) #else @@ -800,9 +800,12 @@ int removef(const char *format, ...) #ifndef STRUCT_DIRENT_HAS_D_TYPE struct stat st; - if (lstat(entry->d_name, &st) == -1) + /* create long name */ + snprintf(temp, FN_REFLEN, "%s/%s", path, entry->d_name); + + if (lstat(temp, &st) == -1) { - return 1; + return 1; /* Error couldn't lstat file */ } if (!S_ISDIR(st.st_mode) && !fnmatch(p, entry->d_name,0)) diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index b1604fea2a6..e3f6f1eb69e 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -441,7 +441,7 @@ while test $# -gt 0; do STRACE_CLIENT=1 ;; --debug) - EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT \ + EXTRA_MASTER_MYSQLD_TRACE=" \ --debug=d:t:i:A,$MYSQL_TEST_DIR/var/log/master.trace" EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT \ --debug=d:t:i:A,$MYSQL_TEST_DIR/var/log/slave.trace" @@ -1149,6 +1149,10 @@ start_master() this_master_myport=$MASTER_MYPORT NOT_FIRST_MASTER_EXTRA_OPTS="" fi + if [ -n "$EXTRA_MASTER_MYSQLD_TRACE" ] + then + CURR_MASTER_MYSQLD_TRACE="$EXTRA_MASTER_MYSQLD_TRACE$1" + fi if [ -z "$DO_BENCH" ] then master_args="--no-defaults --log-bin=$MYSQL_TEST_DIR/var/log/master-bin$1 \ @@ -1172,7 +1176,7 @@ start_master() $MASTER_40_ARGS \ $SMALL_SERVER \ $EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT \ - $NOT_FIRST_MASTER_EXTRA_OPTS" + $NOT_FIRST_MASTER_EXTRA_OPTS $CURR_MASTER_MYSQLD_TRACE" else master_args="--no-defaults --log-bin=$MYSQL_TEST_DIR/var/log/master-bin$1 \ --server-id=$id --rpl-recovery-rank=1 \ diff --git a/mysql-test/mysql_test_run_new.c b/mysql-test/mysql_test_run_new.c index bdebe912b97..41cd4706e0b 100644 --- a/mysql-test/mysql_test_run_new.c +++ b/mysql-test/mysql_test_run_new.c @@ -132,7 +132,13 @@ static char skip_test[FN_REFLEN]= " repair ," " rpl_trunc_binlog ," " mysqldump ," -" rpl000001 "; +" rpl000001 ," + +" derived ," +" group_by ," +" select ," +" rpl000015 ," +" subselect "; #endif static char ignore_test[FN_REFLEN]= ""; @@ -143,6 +149,8 @@ static char mysql_tmp_dir[FN_REFLEN]; static char result_dir[FN_REFLEN]; static char master_dir[FN_REFLEN]; static char slave_dir[FN_REFLEN]; +static char slave1_dir[FN_REFLEN]; +static char slave2_dir[FN_REFLEN]; static char lang_dir[FN_REFLEN]; static char char_dir[FN_REFLEN]; @@ -190,6 +198,8 @@ int restarts= 0; FILE *log_fd= NULL; +static char argument[FN_REFLEN]; + /****************************************************************************** functions @@ -221,7 +231,7 @@ void log_info(const char *, ...); void log_error(const char *, ...); void log_errno(const char *, ...); void die(const char *); -char *str_tok(char *string, const char *delim); +char *str_tok(char* dest, char *string, const char *delim); #ifndef __WIN__ void run_init_script(const char *script_name); #endif @@ -289,11 +299,15 @@ void install_db(char *datadir) add_arg(&al, "--basedir=%s", base_dir); add_arg(&al, "--datadir=%s", datadir); add_arg(&al, "--skip-innodb"); + add_arg(&al, "--skip-ndbcluster"); add_arg(&al, "--skip-bdb"); #ifndef __NETWARE__ add_arg(&al, "--character-sets-dir=%s", char_dir); add_arg(&al, "--language=%s", lang_dir); #endif +// added + add_arg(&al, "--default-character-set=latin1"); + add_arg(&al, "--innodb_data_file_path=ibdata1:50M"); /* spawn */ if ((err= spawn(mysqld_file, &al, TRUE, input, output, error, NULL)) != 0) @@ -335,12 +349,27 @@ void mysql_install_db() mkdir(temp, S_IRWXU); snprintf(temp, FN_REFLEN, "%s/var/master-data/test", mysql_test_dir); mkdir(temp, S_IRWXU); + snprintf(temp, FN_REFLEN, "%s/var/slave-data", mysql_test_dir); mkdir(temp, S_IRWXU); snprintf(temp, FN_REFLEN, "%s/var/slave-data/mysql", mysql_test_dir); mkdir(temp, S_IRWXU); snprintf(temp, FN_REFLEN, "%s/var/slave-data/test", mysql_test_dir); mkdir(temp, S_IRWXU); + + snprintf(temp, FN_REFLEN, "%s/var/slave1-data", mysql_test_dir); + mkdir(temp, S_IRWXU); + snprintf(temp, FN_REFLEN, "%s/var/slave1-data/mysql", mysql_test_dir); + mkdir(temp, S_IRWXU); + snprintf(temp, FN_REFLEN, "%s/var/slave1-data/test", mysql_test_dir); + mkdir(temp, S_IRWXU); + + snprintf(temp, FN_REFLEN, "%s/var/slave2-data", mysql_test_dir); + mkdir(temp, S_IRWXU); + snprintf(temp, FN_REFLEN, "%s/var/slave2-data/mysql", mysql_test_dir); + mkdir(temp, S_IRWXU); + snprintf(temp, FN_REFLEN, "%s/var/slave2-data/test", mysql_test_dir); + mkdir(temp, S_IRWXU); #else mkdir(temp); /* create subdirectories */ @@ -368,6 +397,8 @@ void mysql_install_db() install_db(master_dir); mlog("Creating test databases for slave... \n"); install_db(slave_dir); + install_db(slave1_dir); + install_db(slave2_dir); } /****************************************************************************** @@ -384,7 +415,6 @@ void start_master() int err; char master_out[FN_REFLEN]; char master_err[FN_REFLEN]; -/* char temp[FN_REFLEN]; */ char temp2[FN_REFLEN]; /* remove old berkeley db log files that can confuse the server */ @@ -463,6 +493,11 @@ void start_master() add_arg(&al, "--character-sets-dir=%s", char_dir); add_arg(&al, "--tmpdir=%s", mysql_tmp_dir); add_arg(&al, "--language=%s", lang_dir); + + add_arg(&al, "--rpl-recovery-rank=1"); + add_arg(&al, "--init-rpl-role=master"); + add_arg(&al, "--default-character-set=latin1"); +// add_arg(&al, "--innodb_data_file_path=ibdata1:50M"); #ifdef DEBUG /* only for debug builds */ add_arg(&al, "--debug"); #endif @@ -491,13 +526,13 @@ void start_master() { char *p; - p= (char *)str_tok(master_opt, " \t"); + p= (char *)str_tok(argument, master_opt, " \t"); if (!strstr(master_opt, "timezone")) { while (p) { add_arg(&al, "%s", p); - p= (char *)str_tok(NULL, " \t"); + p= (char *)str_tok(argument, NULL, " \t"); } } } @@ -624,10 +659,10 @@ void start_slave() add_arg(&al, "--log-bin=slave-bin"); add_arg(&al, "--relay_log=slave-relay-bin"); add_arg(&al, "--basedir=%s", base_dir); - add_arg(&al, "--port=%u", slave_port); #if !defined(__NETWARE__) && !defined(__WIN__) add_arg(&al, "--socket=%s",slave_socket); #endif + add_arg(&al, "--port=%u", slave_port); add_arg(&al, "--datadir=%s", slave_dir); #ifndef __WIN__ add_arg(&al, "--pid-file=%s", slave_pid); @@ -651,10 +686,15 @@ void start_slave() add_arg(&al, "--master-retry-count=10"); add_arg(&al, "-O"); add_arg(&al, "slave_net_timeout=10"); + add_arg(&al, "--log-slave-updates"); + add_arg(&al, "--log=%s/var/log/slave.log", mysql_test_dir); + add_arg(&al, "--default-character-set=latin1"); + add_arg(&al, "--skip-ndbcluster"); + #ifdef DEBUG /* only for debug builds */ add_arg(&al, "--debug"); -#endif - +#endif + if (use_openssl) { add_arg(&al, "--ssl-ca=%s", ca_cert); @@ -667,12 +707,12 @@ void start_slave() { char *p; - p= (char *)str_tok(slave_master_info, " \t"); + p= (char *)str_tok(argument, slave_master_info, " \t"); while (p) { add_arg(&al, "%s", p); - p= (char *)str_tok(NULL, " \t"); + p= (char *)str_tok(argument, NULL, " \t"); } } else @@ -700,13 +740,13 @@ void start_slave() { char *p; - p= (char *)str_tok(slave_opt, " \t"); + p= (char *)str_tok(argument, slave_opt, " \t"); while (p) { add_arg(&al, "%s", p); - p= (char *)str_tok(NULL, " \t"); - } + p= (char *)str_tok(argument, NULL, " \t"); + } } /* remove the pid file if it exists */ @@ -753,9 +793,12 @@ void start_slave() void mysql_start() { -/* log_info("Starting the MySQL server(s): %u", ++restarts); */ + + + printf("loading master...\r"); start_master(); + printf("loading slave...\r"); start_slave(); /* activate the test screen */ @@ -853,6 +896,7 @@ void mysql_restart() mysql_stop(); mlog(DASH); + sleep(1); mysql_start(); } @@ -912,7 +956,7 @@ int read_option(char *opt_file, char *opt) if ((p= strstr(opt, "\\\\")) != NULL) { /* bmove is guranteed to work byte by byte */ - bmove(p, p+1, strlen(p+1)); + bmove(p, p+1, strlen(p)+1); } } else @@ -977,14 +1021,6 @@ void run_test(char *test) char err_file[FN_REFLEN]; int err; arg_list_t al; -#ifdef __WIN__ - /* Clean test database */ - removef("%s/test/*.*", master_dir); - removef("%s/test/*.*", slave_dir); - removef("%s/mysqltest/*.*", master_dir); - removef("%s/mysqltest/*.*", slave_dir); - -#endif /* skip slave? */ flag= skip_slave; skip_slave= (strncmp(test, "rpl", 3) != 0); @@ -1045,9 +1081,6 @@ void run_test(char *test) if (!master_running) mysql_start(); else if (restart) mysql_restart(); - /* let the system stabalize */ - sleep(1); - /* show test */ mlog("%-46s ", test); @@ -1066,10 +1099,12 @@ void run_test(char *test) add_arg(&al, "--silent"); add_arg(&al, "--basedir=%s/", mysql_test_dir); add_arg(&al, "--host=127.0.0.1"); + add_arg(&al, "--skip-safemalloc"); add_arg(&al, "-v"); add_arg(&al, "-R"); add_arg(&al, "%s", result_file); - + + if (use_openssl) { add_arg(&al, "--ssl-ca=%s", ca_cert); @@ -1079,7 +1114,6 @@ void run_test(char *test) /* spawn */ err= spawn(mysqltest_file, &al, TRUE, test_file, out_file, err_file, NULL); - /* free args */ free_args(&al); @@ -1259,7 +1293,9 @@ void die(const char *msg) void setup(char *file __attribute__((unused))) { char temp[FN_REFLEN]; +#if defined(__WIN__) || defined(__NETWARE__) char file_path[FN_REFLEN*2]; +#endif char *p; int position; @@ -1349,7 +1385,11 @@ void setup(char *file __attribute__((unused))) snprintf(client_key, FN_REFLEN, "%s/SSL/client-key.pem", base_dir); /* setup files */ +#ifdef _DEBUG + snprintf(mysqld_file, FN_REFLEN, "%s/mysqld-debug.exe", bin_dir); +#else snprintf(mysqld_file, FN_REFLEN, "%s/mysqld.exe", bin_dir); +#endif snprintf(mysqltest_file, FN_REFLEN, "%s/mysqltest.exe", bin_dir); snprintf(mysqladmin_file, FN_REFLEN, "%s/mysqladmin.exe", bin_dir); #else @@ -1361,6 +1401,8 @@ void setup(char *file __attribute__((unused))) snprintf(result_dir, FN_REFLEN, "%s/r", mysql_test_dir); snprintf(master_dir, FN_REFLEN, "%s/var/master-data", mysql_test_dir); snprintf(slave_dir, FN_REFLEN, "%s/var/slave-data", mysql_test_dir); + snprintf(slave1_dir, FN_REFLEN, "%s/var/slave1-data", mysql_test_dir); + snprintf(slave2_dir, FN_REFLEN, "%s/var/slave2-data", mysql_test_dir); snprintf(lang_dir, FN_REFLEN, "%s/sql/share/english", base_dir); snprintf(char_dir, FN_REFLEN, "%s/sql/share/charsets", base_dir); @@ -1413,30 +1455,147 @@ void setup(char *file __attribute__((unused))) snprintf(file_path,FN_REFLEN,"MYSQL_TEST_DIR=%s",mysql_test_dir); _putenv(file_path); snprintf(file_path, FN_REFLEN*2, - "MYSQL_DUMP=%s/mysqldump.exe --no-defaults -u root --port=%u", + "MYSQL_DUMP=%s/mysqldump.exe --no-defaults -uroot --port=%u", bin_dir, master_port); _putenv(file_path); snprintf(file_path, FN_REFLEN*2, - "MYSQL_BINLOG=%s/mysqlbinlog.exe --no-defaults --local-load=%s", + "MYSQL_BINLOG=%s/mysqlbinlog.exe --no-defaults --local-load=%s", bin_dir, mysql_tmp_dir); _putenv(file_path); + + snprintf(file_path, FN_REFLEN*2, + "TESTS_BINDIR=%s/tests", base_dir); + _putenv(file_path); + + snprintf(file_path, FN_REFLEN*2, + "CHARSETSDIR=%s/sql/share/charsets", base_dir); + _putenv(file_path); + + snprintf(file_path, FN_REFLEN*2, + "MYSQL=%s/mysql --port=%u ", + bin_dir, master_port); + _putenv(file_path); + + snprintf(file_path, FN_REFLEN*2, + "MYSQL_FIX_SYSTEM_TABLES=%s/scripts/mysql_fix_privilege_tables --no-defaults " + "--host=localhost --port=%u " + "--basedir=%s --bindir=%s --verbose", + base_dir,master_port, base_dir, bin_dir); + _putenv(file_path); + + snprintf(file_path, FN_REFLEN*2, + "NDB_TOOLS_DIR=%s/ndb/tools", base_dir); + _putenv(file_path); + + snprintf(file_path, FN_REFLEN*2, + "CLIENT_BINDIR=%s", bin_dir); + _putenv(file_path); + + snprintf(file_path, FN_REFLEN*2, + "MYSQL_CLIENT_TEST=%s/tests/mysql_client_test --no-defaults --testcase " + "--user=root --port=%u --silent", + base_dir, master_port); + _putenv(file_path); + #else - snprintf(file_path,FN_REFLEN,"MYSQL_TEST_DIR=%s",mysql_test_dir); - putenv(file_path); - snprintf(file_path, FN_REFLEN*2, - "MYSQL_DUMP=%s/mysqldump --no-defaults -u root --port=%u --socket=%s", - bin_dir, master_port, master_socket); - putenv(file_path); - snprintf(file_path, FN_REFLEN*2, - "MYSQL_BINLOG=%s/mysqlbinlog --no-defaults --local-load=%s", - bin_dir, mysql_tmp_dir); - putenv(file_path); + { + static char env_MYSQL_TEST_DIR[FN_REFLEN*2]; + static char env_MYSQL_DUMP[FN_REFLEN*2]; + static char env_MYSQL_BINLOG[FN_REFLEN*2]; + static char env_MASTER_MYSOCK[FN_REFLEN*2]; + static char env_TESTS_BINDIR[FN_REFLEN*2]; + static char env_CHARSETSDIR[FN_REFLEN*2]; + static char env_MYSQL[FN_REFLEN*2]; + static char env_MYSQL_FIX_SYSTEM_TABLES[FN_REFLEN*2]; + static char env_CLIENT_BINDIR[FN_REFLEN*2]; + static char env_MYSQL_CLIENT_TEST[FN_REFLEN*2]; + static char env_NDB_TOOLS_DIR[FN_REFLEN*2]; + static char env_NDB_MGM[FN_REFLEN*2]; + static char env_NDB_BACKUP_DIR[FN_REFLEN*2]; + static char env_NDB_TOOLS_OUTPUT[FN_REFLEN*2]; + + snprintf(env_MYSQL_TEST_DIR,FN_REFLEN*2, + "MYSQL_TEST_DIR=%s",mysql_test_dir); + putenv(env_MYSQL_TEST_DIR); + + snprintf(env_MYSQL_DUMP, FN_REFLEN*2,"MYSQL_DUMP=%s/mysqldump --no-defaults " + "-uroot --port=%u --socket=%s ", + bin_dir, master_port, master_socket); + putenv(env_MYSQL_DUMP); + + snprintf(env_MYSQL_BINLOG, FN_REFLEN*2, + "MYSQL_BINLOG=%s/mysqlbinlog --no-defaults --local-load=%s -uroot ", + bin_dir, mysql_tmp_dir); + putenv(env_MYSQL_BINLOG); + + snprintf(env_MASTER_MYSOCK, FN_REFLEN*2, + "MASTER_MYSOCK=%s", master_socket); + putenv(env_MASTER_MYSOCK); + + snprintf(env_TESTS_BINDIR, FN_REFLEN*2, + "TESTS_BINDIR=%s/tests", base_dir); + putenv(env_TESTS_BINDIR); + + snprintf(env_CHARSETSDIR, FN_REFLEN*2, + "CHARSETSDIR=%s/sql/share/charsets", base_dir); + putenv(env_CHARSETSDIR); + + snprintf(env_MYSQL, FN_REFLEN*2, + "MYSQL=%s/mysql --port=%u --socket=%s -uroot ", + bin_dir, master_port, master_socket); + putenv(env_MYSQL); + + snprintf(env_MYSQL_FIX_SYSTEM_TABLES, FN_REFLEN*2, + "MYSQL_FIX_SYSTEM_TABLES=%s/scripts/mysql_fix_privilege_tables --no-defaults " + "--host=localhost --port=%u --socket=%s " + "--basedir=%s --bindir=%s --verbose -uroot ", + base_dir,master_port, master_socket, base_dir, bin_dir); + putenv(env_MYSQL_FIX_SYSTEM_TABLES); + + + snprintf(env_CLIENT_BINDIR, FN_REFLEN*2, + "CLIENT_BINDIR=%s", bin_dir); + putenv(env_CLIENT_BINDIR); + + snprintf(env_MYSQL_CLIENT_TEST, FN_REFLEN*2, + "MYSQL_CLIENT_TEST=%s/tests/mysql_client_test --no-defaults --testcase " + "--user=root --socket=%s --port=%u --silent", + base_dir, master_socket, master_port); + putenv(env_MYSQL_CLIENT_TEST); + + // NDB + + snprintf(env_NDB_TOOLS_DIR, FN_REFLEN*2, + "NDB_TOOLS_DIR=%s/ndb/tools", base_dir); + putenv(env_NDB_TOOLS_DIR); + + snprintf(env_NDB_MGM, FN_REFLEN*2, + "NDB_MGM=%s/ndb/src/mgmclient/ndb_mgm", base_dir); + putenv(env_NDB_MGM); + + //NDBCLUSTER_PORT=9350 + snprintf(env_NDB_BACKUP_DIR, FN_REFLEN*2, + "NDB_BACKUP_DIR=%s/var/ndbcluster-%i", mysql_test_dir, 9350); + putenv(env_NDB_BACKUP_DIR); + + snprintf(env_NDB_TOOLS_OUTPUT, FN_REFLEN*2, + "NDB_TOOLS_OUTPUT=%s/var/log/ndb_tools.log", mysql_test_dir); + putenv(env_NDB_TOOLS_OUTPUT); + + putenv((char *)"NDB_STATUS_OK=1"); + +// NDB_MGM="$BASEDIR/ndb/src/mgmclient/ndb_mgm" +// NDB_BACKUP_DIR=$MYSQL_TEST_DIR/var/ndbcluster-$NDBCLUSTER_PORT +// NDB_TOOLS_OUTPUT=$MYSQL_TEST_DIR/var/log/ndb_tools.log + } + #endif #ifndef __WIN__ putenv((char *)"MASTER_MYPORT=9306"); putenv((char *)"SLAVE_MYPORT=9307"); putenv((char *)"MYSQL_TCP_PORT=3306"); + #else _putenv("MASTER_MYPORT=9306"); _putenv("SLAVE_MYPORT=9307"); @@ -1468,8 +1627,13 @@ int main(int argc, char **argv) char **testes= 0; int name_index; int index; + char var_dir[FN_REFLEN]; /* setup */ setup(argv[0]); + + /* delete all file in var */ + snprintf(var_dir,FN_REFLEN,"%s/var",mysql_test_dir); + del_tree(var_dir); /* The --ignore option is comma saperated list of test cases to skip and @@ -1484,7 +1648,8 @@ int main(int argc, char **argv) { char *temp, *token; temp= strdup(strchr(argv[1],'=') + 1); - for (token=str_tok(temp, ","); token != NULL; token=str_tok(NULL, ",")) + for (token=str_tok(argument, temp, ","); token != NULL; + token=str_tok(argument, NULL, ",")) { if (strlen(ignore_test) + strlen(token) + 2 <= FN_REFLEN-1) sprintf(ignore_test+strlen(ignore_test), " %s ", token); @@ -1508,7 +1673,7 @@ int main(int argc, char **argv) /* install test databases */ mysql_install_db(); - + mlog("Starting Tests...\n"); mlog("\n"); @@ -1671,105 +1836,70 @@ Arguments: Output: return the null terminated token of NULL. */ - -char *str_tok(char *string, const char *delim) +char *str_tok(char* dest, char *string, const char *delim) { - char *token; /* current token received from strtok */ - char *qt_token; /* token delimeted by the matching pair of quote */ - /* - if there are any quote chars found in the token then this variable - will hold the concatenated string to return to the caller - */ - char *ptr_token=NULL; - /* pointer to the quote character in the token from strtok */ - char *ptr_quote=NULL; + char *token; + char *ptr_end_token= NULL; + char *ptr_quote= NULL; + char *ptr_token= NULL; + int count_quotes= 0; - /* See if the delimeter contains any quote character */ + *dest = '\0'; if (strchr(delim,'\'') || strchr(delim,'\"')) return NULL; - /* repeate till we are getting some token from strtok */ - while ((token= (char*)strtok(string, delim) ) != NULL) + token= (char*)strtok(string, delim); + if (token) { - /* - make the input string NULL so that next time onward strtok can - be called with NULL input string. - */ - string= NULL; - /* We don't need to remove any quote character for Windows version */ + /* double quote is found */ + if (strchr(token,'\"')) + { + do + { + if (count_quotes & 1) + { + if (*dest == '\0') + sprintf(dest,"%s", ptr_token); + else + sprintf(dest,"%s %s", dest, ptr_token); + ptr_token= (char*)strtok(NULL, delim); + if (!ptr_token) + break; + } + else + { + ptr_token= token; + } + if (ptr_quote = strchr(ptr_token,'\"')) + { + ptr_end_token= ptr_token + strlen(ptr_token); + do + { #ifndef __WIN__ - /* check if the current token contain double quote character*/ - if ((ptr_quote= (char*)strchr(token,'\"')) != NULL) - { - /* - get the matching the matching double quote in the remaining - input string - */ - qt_token= (char*)strtok(NULL,"\""); - } - /* check if the current token contain single quote character*/ - else if ((ptr_quote= (char*)strchr(token,'\'')) != NULL) - { - /* - get the matching the matching single quote in the remaining - input string - */ - qt_token= (char*)strtok(NULL,"\'"); - } + bmove(ptr_quote, ptr_quote+1, ptr_end_token - ptr_quote); #endif - /* - if the current token does not contains any quote character then - return to the caller. - */ - if (ptr_quote == NULL) - { - /* - if there is any earlier token i.e. ptr_token then append the - current token in it and return it else return the current - token directly - */ - return ptr_token ? strcat(ptr_token,token) : token; - } - - /* - remove the quote character i.e. make NULL so that the token will - be devided in two part and later both part can be concatenated - and hence quote will be removed - */ - *ptr_quote= 0; - - /* check if ptr_token has been initialized or not */ - if (ptr_token == NULL) - { - /* initialize the ptr_token with current token */ - ptr_token= token; - /* copy entire string between matching pair of quote*/ - sprintf(ptr_token+strlen(ptr_token),"%s %s", ptr_quote+1, qt_token); + count_quotes++; + } while (ptr_quote != NULL && (ptr_quote = strchr(ptr_quote+1,'\"'))); + } + /* there are unpair quotes we have to search next quote*/ + } while (count_quotes & 1); + if (ptr_token != NULL) + { + if (*dest == '\0') + sprintf(dest,"%s", ptr_token); + else + sprintf(dest,"%s %s",dest,ptr_token); + } } else { - /* - copy the current token and entire string between matching pair - of quote - */ - if (qt_token == NULL) - { - sprintf(ptr_token+strlen(ptr_token),"%s%s", token, ptr_quote+1); - } - else - { - sprintf(ptr_token+strlen(ptr_token),"%s%s %s", token, ptr_quote+1, - qt_token ); - } + sprintf(dest,"%s",token); } } - - /* return the concatenated token */ - return ptr_token; + return token ? dest : NULL; } #ifndef __WIN__ - /* Synopsis: This function run scripts files on Linux and Netware diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result index 24740442821..a43e67d57e6 100644 --- a/mysql-test/r/group_by.result +++ b/mysql-test/r/group_by.result @@ -655,9 +655,9 @@ insert into t1 (a,b) values (1,2),(1,3),(2,5); select a, 0.1*0+1 r2, sum(1) r1 from t1 where a = 1 group by a having r1>1 and r2=1; a r2 r1 1 1.0 2 -select a, rand()*0+1 r2, sum(1) r1 from t1 where a = 1 group by a having r1>1 and r2=1; +select a, round(rand(100)*10) r2, sum(1) r1 from t1 where a = 1 group by a having r1>1 and r2<=2; a r2 r1 -1 1 2 +1 2 2 select a,sum(b) from t1 where a=1 group by c; a sum(b) 1 5 diff --git a/mysql-test/r/heap_hash.result b/mysql-test/r/heap_hash.result index 287e17a264d..1e6eb866fd6 100644 --- a/mysql-test/r/heap_hash.result +++ b/mysql-test/r/heap_hash.result @@ -355,3 +355,13 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t3 ref a a 44 const,const 6 Using where 1 SIMPLE t1 ref heap_idx heap_idx 22 const 7 Using where drop table t1, t2, t3; +create temporary table t1 ( a int, index (a) ) engine=memory; +insert into t1 values (1),(2),(3),(4),(5); +select a from t1 where a in (1,3); +a +1 +3 +explain select a from t1 where a in (1,3); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a a 5 NULL 2 Using where +drop table t1; diff --git a/mysql-test/r/ps_2myisam.result b/mysql-test/r/ps_2myisam.result index 78436b69ec7..14b7e8a7069 100644 --- a/mysql-test/r/ps_2myisam.result +++ b/mysql-test/r/ps_2myisam.result @@ -2666,7 +2666,6 @@ Warning 1264 Out of range value adjusted for column 'c4' at row 1 Warning 1264 Out of range value adjusted for column 'c5' at row 1 Warning 1264 Out of range value adjusted for column 'c6' at row 1 Warning 1264 Out of range value adjusted for column 'c7' at row 1 -Note 1265 Data truncated for column 'c12' at row 1 Warning 1264 Out of range value adjusted for column 'c12' at row 1 execute my_select ; c1 127 @@ -2717,7 +2716,6 @@ Warning 1264 Out of range value adjusted for column 'c4' at row 1 Warning 1264 Out of range value adjusted for column 'c5' at row 1 Warning 1264 Out of range value adjusted for column 'c6' at row 1 Warning 1264 Out of range value adjusted for column 'c7' at row 1 -Note 1265 Data truncated for column 'c12' at row 1 Warning 1264 Out of range value adjusted for column 'c12' at row 1 execute my_select ; c1 -128 diff --git a/mysql-test/r/ps_3innodb.result b/mysql-test/r/ps_3innodb.result index e5db53e1c18..940f5e8cbac 100644 --- a/mysql-test/r/ps_3innodb.result +++ b/mysql-test/r/ps_3innodb.result @@ -2649,7 +2649,6 @@ Warning 1264 Out of range value adjusted for column 'c4' at row 1 Warning 1264 Out of range value adjusted for column 'c5' at row 1 Warning 1264 Out of range value adjusted for column 'c6' at row 1 Warning 1264 Out of range value adjusted for column 'c7' at row 1 -Note 1265 Data truncated for column 'c12' at row 1 Warning 1264 Out of range value adjusted for column 'c12' at row 1 execute my_select ; c1 127 @@ -2700,7 +2699,6 @@ Warning 1264 Out of range value adjusted for column 'c4' at row 1 Warning 1264 Out of range value adjusted for column 'c5' at row 1 Warning 1264 Out of range value adjusted for column 'c6' at row 1 Warning 1264 Out of range value adjusted for column 'c7' at row 1 -Note 1265 Data truncated for column 'c12' at row 1 Warning 1264 Out of range value adjusted for column 'c12' at row 1 execute my_select ; c1 -128 diff --git a/mysql-test/r/ps_4heap.result b/mysql-test/r/ps_4heap.result index ad02de1110c..37dd8cb263e 100644 --- a/mysql-test/r/ps_4heap.result +++ b/mysql-test/r/ps_4heap.result @@ -2650,7 +2650,6 @@ Warning 1264 Out of range value adjusted for column 'c4' at row 1 Warning 1264 Out of range value adjusted for column 'c5' at row 1 Warning 1264 Out of range value adjusted for column 'c6' at row 1 Warning 1264 Out of range value adjusted for column 'c7' at row 1 -Note 1265 Data truncated for column 'c12' at row 1 Warning 1264 Out of range value adjusted for column 'c12' at row 1 execute my_select ; c1 127 @@ -2701,7 +2700,6 @@ Warning 1264 Out of range value adjusted for column 'c4' at row 1 Warning 1264 Out of range value adjusted for column 'c5' at row 1 Warning 1264 Out of range value adjusted for column 'c6' at row 1 Warning 1264 Out of range value adjusted for column 'c7' at row 1 -Note 1265 Data truncated for column 'c12' at row 1 Warning 1264 Out of range value adjusted for column 'c12' at row 1 execute my_select ; c1 -128 diff --git a/mysql-test/r/ps_5merge.result b/mysql-test/r/ps_5merge.result index 374f6142c44..867d410ebf1 100644 --- a/mysql-test/r/ps_5merge.result +++ b/mysql-test/r/ps_5merge.result @@ -2586,7 +2586,6 @@ Warning 1264 Out of range value adjusted for column 'c4' at row 1 Warning 1264 Out of range value adjusted for column 'c5' at row 1 Warning 1264 Out of range value adjusted for column 'c6' at row 1 Warning 1264 Out of range value adjusted for column 'c7' at row 1 -Note 1265 Data truncated for column 'c12' at row 1 Warning 1264 Out of range value adjusted for column 'c12' at row 1 execute my_select ; c1 127 @@ -2637,7 +2636,6 @@ Warning 1264 Out of range value adjusted for column 'c4' at row 1 Warning 1264 Out of range value adjusted for column 'c5' at row 1 Warning 1264 Out of range value adjusted for column 'c6' at row 1 Warning 1264 Out of range value adjusted for column 'c7' at row 1 -Note 1265 Data truncated for column 'c12' at row 1 Warning 1264 Out of range value adjusted for column 'c12' at row 1 execute my_select ; c1 -128 @@ -5597,7 +5595,6 @@ Warning 1264 Out of range value adjusted for column 'c4' at row 1 Warning 1264 Out of range value adjusted for column 'c5' at row 1 Warning 1264 Out of range value adjusted for column 'c6' at row 1 Warning 1264 Out of range value adjusted for column 'c7' at row 1 -Note 1265 Data truncated for column 'c12' at row 1 Warning 1264 Out of range value adjusted for column 'c12' at row 1 execute my_select ; c1 127 @@ -5648,7 +5645,6 @@ Warning 1264 Out of range value adjusted for column 'c4' at row 1 Warning 1264 Out of range value adjusted for column 'c5' at row 1 Warning 1264 Out of range value adjusted for column 'c6' at row 1 Warning 1264 Out of range value adjusted for column 'c7' at row 1 -Note 1265 Data truncated for column 'c12' at row 1 Warning 1264 Out of range value adjusted for column 'c12' at row 1 execute my_select ; c1 -128 diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 2e9f199e8bb..67d3287c16f 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -1433,7 +1433,7 @@ Note 1003 (select `test`.`t1`.`s1` AS `s1` from `test`.`t1`) s1 tttt drop table t1; -create table t1 (s1 char(5) not null, index s1(s1)); +create table t1 (s1 char(5), index s1(s1)); create table t2 (s1 char(5), index s1(s1)); insert into t1 values ('a1'),('a2'),('a3'); insert into t2 values ('a1'),('a2'); @@ -1459,25 +1459,25 @@ a2 1 a3 1 explain extended select s1, s1 NOT IN (SELECT s1 FROM t2) from t1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 index NULL s1 5 NULL 3 Using index +1 PRIMARY t1 index NULL s1 6 NULL 3 Using index 2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 Using index Warnings: Note 1003 select `test`.`t1`.`s1` AS `s1`,not((`test`.`t1`.`s1`,(((`test`.`t1`.`s1`) in t2 on s1 checking NULL)))) AS `s1 NOT IN (SELECT s1 FROM t2)` from `test`.`t1` explain extended select s1, s1 = ANY (SELECT s1 FROM t2) from t1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 index NULL s1 5 NULL 3 Using index +1 PRIMARY t1 index NULL s1 6 NULL 3 Using index 2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 Using index Warnings: Note 1003 select `test`.`t1`.`s1` AS `s1`,(`test`.`t1`.`s1`,(((`test`.`t1`.`s1`) in t2 on s1 checking NULL))) AS `s1 = ANY (SELECT s1 FROM t2)` from `test`.`t1` explain extended select s1, s1 <> ALL (SELECT s1 FROM t2) from t1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 index NULL s1 5 NULL 3 Using index +1 PRIMARY t1 index NULL s1 6 NULL 3 Using index 2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 Using index Warnings: Note 1003 select `test`.`t1`.`s1` AS `s1`,not((`test`.`t1`.`s1`,(((`test`.`t1`.`s1`) in t2 on s1 checking NULL)))) AS `s1 <> ALL (SELECT s1 FROM t2)` from `test`.`t1` explain extended select s1, s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2') from t1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 index NULL s1 5 NULL 3 Using index +1 PRIMARY t1 index NULL s1 6 NULL 3 Using index 2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 1 Using index; Using where Warnings: Note 1003 select `test`.`t1`.`s1` AS `s1`,not((`test`.`t1`.`s1`,(((`test`.`t1`.`s1`) in t2 on s1 checking NULL where (`test`.`t2`.`s1` < _latin1'a2'))))) AS `s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2')` from `test`.`t1` @@ -2133,34 +2133,6 @@ SELECT DISTINCT Continent AS c FROM t1 WHERE Code <> SOME ( SELECT Code FROM t1 c Oceania drop table t1; -CREATE TABLE t1 ( f1 BIGINT ); -INSERT INTO t1 SET f1= NULL; -INSERT INTO t1 SET f1= 1; -CREATE TABLE t2 ( f1 BIGINT ); -SELECT f1 FROM t1 -WHERE f1 <> ALL ( SELECT f1 FROM t2 ); -f1 -NULL -1 -INSERT INTO t2 VALUES (1), (2); -SELECT f1 FROM t1 -WHERE f1 <> ALL ( SELECT f1 FROM t2 WHERE f1 > 2 ); -f1 -NULL -1 -SELECT f1 FROM t1 -WHERE f1 <> ALL ( SELECT f1 FROM t2 WHERE f1 > 2 -UNION -SELECT f1 FROM t2 WHERE f1 > 3); -f1 -NULL -1 -SELECT f1 FROM t1 -WHERE f1 <> ALL ( SELECT SUM(f1) AS sf1 FROM t2 HAVING sf1 > 10000); -f1 -NULL -1 -drop table t1,t2; create table t1 (a1 int); create table t2 (b1 int); select * from t1 where a2 > any(select b1 from t2); diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result index ba5cb264013..bacd8311a1e 100644 --- a/mysql-test/r/user_var.result +++ b/mysql-test/r/user_var.result @@ -113,8 +113,8 @@ select @a:=0; select @a, @a:=@a+count(*), count(*), @a from t1 group by i; @a @a:=@a+count(*) count(*) @a 0 1 1 0 -0 3 2 0 -0 6 3 0 +0 2 2 0 +0 3 3 0 select @a:=0; @a:=0 0 diff --git a/mysql-test/t/group_by.test b/mysql-test/t/group_by.test index 379f668df1a..afd479c520e 100644 --- a/mysql-test/t/group_by.test +++ b/mysql-test/t/group_by.test @@ -480,7 +480,8 @@ drop table t1; create table t1 (a integer, b integer, c integer); insert into t1 (a,b) values (1,2),(1,3),(2,5); select a, 0.1*0+1 r2, sum(1) r1 from t1 where a = 1 group by a having r1>1 and r2=1; -select a, rand()*0+1 r2, sum(1) r1 from t1 where a = 1 group by a having r1>1 and r2=1; +# rand(100)*10 will be < 2 only for the first row (of 6) +select a, round(rand(100)*10) r2, sum(1) r1 from t1 where a = 1 group by a having r1>1 and r2<=2; select a,sum(b) from t1 where a=1 group by c; select a*sum(b) from t1 where a=1 group by c; select sum(a)*sum(b) from t1 where a=1 group by c; diff --git a/mysql-test/t/heap_hash.test b/mysql-test/t/heap_hash.test index 6d8fdec4b9e..6d27f19dfad 100644 --- a/mysql-test/t/heap_hash.test +++ b/mysql-test/t/heap_hash.test @@ -251,3 +251,9 @@ explain select * from t1 ignore key(btree_idx), t3 where t1.name='matt' and t3.a drop table t1, t2, t3; +# Fix for BUG#8371: wrong rec_per_key value for hash index on temporary table +create temporary table t1 ( a int, index (a) ) engine=memory; +insert into t1 values (1),(2),(3),(4),(5); +select a from t1 where a in (1,3); +explain select a from t1 where a in (1,3); +drop table t1; diff --git a/mysql-test/t/ps_1general.test b/mysql-test/t/ps_1general.test index ed51b820652..aaff899bf82 100644 --- a/mysql-test/t/ps_1general.test +++ b/mysql-test/t/ps_1general.test @@ -329,7 +329,7 @@ prepare stmt4 from ' show engine bdb logs '; execute stmt4; --enable_result_log prepare stmt4 from ' show full processlist '; ---replace_column 1 number 6 time +--replace_column 1 number 6 time 3 localhost execute stmt4; prepare stmt4 from ' show grants for user '; --error 1295 diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 9baf082487f..7b75686ab4e 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -894,7 +894,7 @@ drop table t1; # # IN optimisation test results # -create table t1 (s1 char(5) not null, index s1(s1)); +create table t1 (s1 char(5), index s1(s1)); create table t2 (s1 char(5), index s1(s1)); insert into t1 values ('a1'),('a2'),('a3'); insert into t2 values ('a1'),('a2'); @@ -1392,34 +1392,6 @@ INSERT INTO t1 VALUES ('UMI','United States Minor Outlying Islands','Oceania','M SELECT DISTINCT Continent AS c FROM t1 WHERE Code <> SOME ( SELECT Code FROM t1 WHERE Continent = c AND Population < 200); drop table t1; -# -# Test cases for bug #7351: -# quantified predicate with subquery returning empty result set -# - -CREATE TABLE t1 ( f1 BIGINT ); -INSERT INTO t1 SET f1= NULL; -INSERT INTO t1 SET f1= 1; -CREATE TABLE t2 ( f1 BIGINT ); - -SELECT f1 FROM t1 - WHERE f1 <> ALL ( SELECT f1 FROM t2 ); - -INSERT INTO t2 VALUES (1), (2); - -SELECT f1 FROM t1 - WHERE f1 <> ALL ( SELECT f1 FROM t2 WHERE f1 > 2 ); - -SELECT f1 FROM t1 - WHERE f1 <> ALL ( SELECT f1 FROM t2 WHERE f1 > 2 - UNION - SELECT f1 FROM t2 WHERE f1 > 3); - -SELECT f1 FROM t1 - WHERE f1 <> ALL ( SELECT SUM(f1) AS sf1 FROM t2 HAVING sf1 > 10000); - -drop table t1,t2; - # # Test for BUG#7885: Server crash when 'any' subselect compared to # non-existant field. diff --git a/mysys/my_rename.c b/mysys/my_rename.c index d4f99e83247..b5d813ad787 100644 --- a/mysys/my_rename.c +++ b/mysys/my_rename.c @@ -45,7 +45,7 @@ int my_rename(const char *from, const char *to, myf MyFlags) } #endif #if defined(HAVE_RENAME) -#ifdef __WIN__ +#if defined(__WIN__) || defined(__NETWARE__) /* On windows we can't rename over an existing file: Remove any conflicting files: diff --git a/ndb/test/ndbapi/Makefile.am b/ndb/test/ndbapi/Makefile.am index 7d12714b3bd..5eb3c215ee5 100644 --- a/ndb/test/ndbapi/Makefile.am +++ b/ndb/test/ndbapi/Makefile.am @@ -32,7 +32,8 @@ testTransactions \ testDeadlock \ test_event ndbapi_slow_select testReadPerf testLcp \ testPartitioning \ -testBitfield +testBitfield \ +DbCreate DbAsyncGenerator #flexTimedAsynch #testBlobs @@ -73,6 +74,8 @@ testReadPerf_SOURCES = testReadPerf.cpp testLcp_SOURCES = testLcp.cpp testPartitioning_SOURCES = testPartitioning.cpp testBitfield_SOURCES = testBitfield.cpp +DbCreate_SOURCES= bench/mainPopulate.cpp bench/dbPopulate.cpp bench/userInterface.cpp +DbAsyncGenerator_SOURCES= bench/mainAsyncGenerator.cpp bench/asyncGenerator.cpp bench/ndb_async2.cpp INCLUDES_LOC = -I$(top_srcdir)/ndb/include/kernel diff --git a/ndb/test/ndbapi/bench/asyncGenerator.cpp b/ndb/test/ndbapi/bench/asyncGenerator.cpp new file mode 100644 index 00000000000..d91e38dff1a --- /dev/null +++ b/ndb/test/ndbapi/bench/asyncGenerator.cpp @@ -0,0 +1,571 @@ +/* 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; either version 2 of the License, or + (at your option) any later version. + + 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 */ + +/*************************************************************** +* I N C L U D E D F I L E S * +***************************************************************/ + +#include + +#include "dbGenerator.h" +#include +#include +#include + +/*************************************************************** +* L O C A L C O N S T A N T S * +***************************************************************/ + +/*************************************************************** +* L O C A L D A T A S T R U C T U R E S * +***************************************************************/ + +/*************************************************************** +* L O C A L F U N C T I O N S * +***************************************************************/ + +static void getRandomSubscriberNumber(SubscriberNumber number); +static void getRandomServerId(ServerId *serverId); +static void getRandomChangedBy(ChangedBy changedBy); +static void getRandomChangedTime(ChangedTime changedTime); + +static void clearTransaction(TransactionDefinition *trans); +static void initGeneratorStatistics(GeneratorStatistics *gen); + +static void doOneTransaction(ThreadData * td, + int parallellism, + int millisSendPoll, + int minEventSendPoll, + int forceSendPoll); +static void doTransaction_T1(Ndb * pNDB, ThreadData * td, int async); +static void doTransaction_T2(Ndb * pNDB, ThreadData * td, int async); +static void doTransaction_T3(Ndb * pNDB, ThreadData * td, int async); +static void doTransaction_T4(Ndb * pNDB, ThreadData * td, int async); +static void doTransaction_T5(Ndb * pNDB, ThreadData * td, int async); + +/*************************************************************** +* L O C A L D A T A * +***************************************************************/ + +static SequenceValues transactionDefinition[] = { + {25, 1}, + {25, 2}, + {20, 3}, + {15, 4}, + {15, 5}, + {0, 0} +}; + +static SequenceValues rollbackDefinition[] = { + {98, 0}, + {2 , 1}, + {0, 0} +}; + +static int maxsize = 0; + +/*************************************************************** +* P U B L I C D A T A * +***************************************************************/ + +/*************************************************************** +**************************************************************** +* L O C A L F U N C T I O N S C O D E S E C T I O N * +**************************************************************** +***************************************************************/ + +static void getRandomSubscriberNumber(SubscriberNumber number) +{ + uint32 tmp; + char sbuf[SUBSCRIBER_NUMBER_LENGTH + 1]; + tmp = myRandom48(NO_OF_SUBSCRIBERS); + sprintf(sbuf, "%.*d", SUBSCRIBER_NUMBER_LENGTH, tmp); + memcpy(number, sbuf, SUBSCRIBER_NUMBER_LENGTH); +} + +static void getRandomServerId(ServerId *serverId) +{ + *serverId = myRandom48(NO_OF_SERVERS); +} + +static void getRandomChangedBy(ChangedBy changedBy) +{ + memset(changedBy, myRandom48(26)+'A', CHANGED_BY_LENGTH); + changedBy[CHANGED_BY_LENGTH] = 0; +} + +static void getRandomChangedTime(ChangedTime changedTime) +{ + memset(changedTime, myRandom48(26)+'A', CHANGED_TIME_LENGTH); + changedTime[CHANGED_TIME_LENGTH] = 0; +} + +static void clearTransaction(TransactionDefinition *trans) +{ + trans->count = 0; + trans->branchExecuted = 0; + trans->rollbackExecuted = 0; + trans->latencyCounter = myRandom48(127); + trans->latency.reset(); +} + +static int listFull(SessionList *list) +{ + return(list->numberInList == SESSION_LIST_LENGTH); +} + +static int listEmpty(SessionList *list) +{ + return(list->numberInList == 0); +} + +static void insertSession(SessionList *list, + SubscriberNumber number, + ServerId serverId) +{ + SessionElement *e; + if( listFull(list) ) return; + + e = &list->list[list->writeIndex]; + + strcpy(e->subscriberNumber, number); + e->serverId = serverId; + + list->writeIndex = (list->writeIndex + 1) % SESSION_LIST_LENGTH; + list->numberInList++; + + if( list->numberInList > maxsize ) + maxsize = list->numberInList; +} + +static SessionElement *getNextSession(SessionList *list) +{ + if( listEmpty(list) ) return(0); + + return(&list->list[list->readIndex]); +} + +static void deleteSession(SessionList *list) +{ + if( listEmpty(list) ) return; + + list->readIndex = (list->readIndex + 1) % SESSION_LIST_LENGTH; + list->numberInList--; +} + +static void initGeneratorStatistics(GeneratorStatistics *gen) +{ + int i; + + if( initSequence(&gen->transactionSequence, + transactionDefinition) != 0 ) { + ndbout_c("could not set the transaction types"); + exit(0); + } + + if( initSequence(&gen->rollbackSequenceT4, + rollbackDefinition) != 0 ) { + ndbout_c("could not set the rollback sequence"); + exit(0); + } + + if( initSequence(&gen->rollbackSequenceT5, + rollbackDefinition) != 0 ) { + ndbout_c("could not set the rollback sequence"); + exit(0); + } + + for(i = 0; i < NUM_TRANSACTION_TYPES; i++ ) + clearTransaction(&gen->transactions[i]); + + gen->totalTransactions = 0; + + gen->activeSessions.numberInList = 0; + gen->activeSessions.readIndex = 0; + gen->activeSessions.writeIndex = 0; +} + + +static +void +doOneTransaction(ThreadData * td, int p, int millis, int minEvents, int force) +{ + int i; + unsigned int transactionType; + int async = 1; + if (p == 1) { + async = 0; + }//if + for(i = 0; isendPollNdb(millis, minEvents, force); + }//if +} + +static +void +doTransaction_T1(Ndb * pNDB, ThreadData * td, int async) +{ + /*----------------*/ + /* Init arguments */ + /*----------------*/ + getRandomSubscriberNumber(td->transactionData.number); + getRandomChangedBy(td->transactionData.changed_by); + BaseString::snprintf(td->transactionData.changed_time, + sizeof(td->transactionData.changed_time), + "%ld - %d", td->changedTime++, myRandom48(65536*1024)); + //getRandomChangedTime(td->transactionData.changed_time); + td->transactionData.location = td->transactionData.changed_by[0]; + + /*-----------------*/ + /* Run transaction */ + /*-----------------*/ + td->runState = Running; + td->generator.transactions[0].startLatency(); + + start_T1(pNDB, td, async); +} + +static +void +doTransaction_T2(Ndb * pNDB, ThreadData * td, int async) +{ + /*----------------*/ + /* Init arguments */ + /*----------------*/ + getRandomSubscriberNumber(td->transactionData.number); + + /*-----------------*/ + /* Run transaction */ + /*-----------------*/ + td->runState = Running; + td->generator.transactions[1].startLatency(); + + start_T2(pNDB, td, async); +} + +static +void +doTransaction_T3(Ndb * pNDB, ThreadData * td, int async) +{ + SessionElement *se; + + /*----------------*/ + /* Init arguments */ + /*----------------*/ + se = getNextSession(&td->generator.activeSessions); + if( se ) { + strcpy(td->transactionData.number, se->subscriberNumber); + td->transactionData.server_id = se->serverId; + td->transactionData.sessionElement = 1; + } else { + getRandomSubscriberNumber(td->transactionData.number); + getRandomServerId(&td->transactionData.server_id); + td->transactionData.sessionElement = 0; + } + + td->transactionData.server_bit = (1 << td->transactionData.server_id); + + /*-----------------*/ + /* Run transaction */ + /*-----------------*/ + td->runState = Running; + td->generator.transactions[2].startLatency(); + start_T3(pNDB, td, async); +} + +static +void +doTransaction_T4(Ndb * pNDB, ThreadData * td, int async) +{ + /*----------------*/ + /* Init arguments */ + /*----------------*/ + getRandomSubscriberNumber(td->transactionData.number); + getRandomServerId(&td->transactionData.server_id); + + td->transactionData.server_bit = (1 << td->transactionData.server_id); + td->transactionData.do_rollback = + getNextRandom(&td->generator.rollbackSequenceT4); + +#if 0 + memset(td->transactionData.session_details, + myRandom48(26)+'A', SESSION_DETAILS_LENGTH); +#endif + td->transactionData.session_details[SESSION_DETAILS_LENGTH] = 0; + + /*-----------------*/ + /* Run transaction */ + /*-----------------*/ + td->runState = Running; + td->generator.transactions[3].startLatency(); + start_T4(pNDB, td, async); +} + +static +void +doTransaction_T5(Ndb * pNDB, ThreadData * td, int async) +{ + SessionElement * se; + se = getNextSession(&td->generator.activeSessions); + if( se ) { + strcpy(td->transactionData.number, se->subscriberNumber); + td->transactionData.server_id = se->serverId; + td->transactionData.sessionElement = 1; + } + else { + getRandomSubscriberNumber(td->transactionData.number); + getRandomServerId(&td->transactionData.server_id); + td->transactionData.sessionElement = 0; + } + + td->transactionData.server_bit = (1 << td->transactionData.server_id); + td->transactionData.do_rollback + = getNextRandom(&td->generator.rollbackSequenceT5); + + /*-----------------*/ + /* Run transaction */ + /*-----------------*/ + td->runState = Running; + td->generator.transactions[4].startLatency(); + start_T5(pNDB, td, async); +} + +void +complete_T1(ThreadData * data){ + data->generator.transactions[0].stopLatency(); + data->generator.transactions[0].count++; + + data->runState = Runnable; + data->generator.totalTransactions++; +} + +void +complete_T2(ThreadData * data){ + data->generator.transactions[1].stopLatency(); + data->generator.transactions[1].count++; + + data->runState = Runnable; + data->generator.totalTransactions++; +} + +void +complete_T3(ThreadData * data){ + + data->generator.transactions[2].stopLatency(); + data->generator.transactions[2].count++; + + if(data->transactionData.branchExecuted) + data->generator.transactions[2].branchExecuted++; + + data->runState = Runnable; + data->generator.totalTransactions++; +} + +void +complete_T4(ThreadData * data){ + + data->generator.transactions[3].stopLatency(); + data->generator.transactions[3].count++; + + if(data->transactionData.branchExecuted) + data->generator.transactions[3].branchExecuted++; + if(data->transactionData.do_rollback) + data->generator.transactions[3].rollbackExecuted++; + + if(data->transactionData.branchExecuted && + !data->transactionData.do_rollback){ + insertSession(&data->generator.activeSessions, + data->transactionData.number, + data->transactionData.server_id); + } + + data->runState = Runnable; + data->generator.totalTransactions++; + +} +void +complete_T5(ThreadData * data){ + + data->generator.transactions[4].stopLatency(); + data->generator.transactions[4].count++; + + if(data->transactionData.branchExecuted) + data->generator.transactions[4].branchExecuted++; + if(data->transactionData.do_rollback) + data->generator.transactions[4].rollbackExecuted++; + + if(data->transactionData.sessionElement && + !data->transactionData.do_rollback){ + deleteSession(&data->generator.activeSessions); + } + + data->runState = Runnable; + data->generator.totalTransactions++; +} + +/*************************************************************** +**************************************************************** +* P U B L I C F U N C T I O N S C O D E S E C T I O N * +**************************************************************** +***************************************************************/ +void +asyncGenerator(ThreadData *data, + int parallellism, + int millisSendPoll, + int minEventSendPoll, + int forceSendPoll) +{ + ThreadData * startUp; + + GeneratorStatistics *st; + double periodStop; + double benchTimeStart; + double benchTimeEnd; + int i, j, done; + + myRandom48Init(data->randomSeed); + + for(i = 0; isendPollNdb(); + } + } + ndbout_c("Benchmark period starts"); + + /*-------------------------*/ + /* normal benchmark period */ + /*-------------------------*/ + benchTimeStart = userGetTime(); + + periodStop = benchTimeStart + (double)data[0].testSeconds; + while(userGetTime() < periodStop) + doOneTransaction(data, parallellism, + millisSendPoll, minEventSendPoll, forceSendPoll); + + benchTimeEnd = userGetTime(); + + ndbout_c("Benchmark period done"); + + /** + * Wait for all transactions + */ + done = 0; + while(!done){ + done = 1; + for(i = 0; isendPollNdb(); + } + } + + /*------------------*/ + /* cool down period */ + /*------------------*/ + periodStop = userGetTime() + (double)data[0].coolDownSeconds; + while(userGetTime() < periodStop){ + doOneTransaction(startUp, parallellism, + millisSendPoll, minEventSendPoll, forceSendPoll); + } + + done = 0; + while(!done){ + done = 1; + for(i = 0; isendPollNdb(); + } + } + + + /*---------------------------------------------------------*/ + /* add the times for all transaction for inner loop timing */ + /*---------------------------------------------------------*/ + for(j = 0; jouterLoopTime = benchTimeEnd - benchTimeStart; + st->outerTps = getTps(st->totalTransactions, st->outerLoopTime); + } + /* ndbout_c("maxsize = %d\n",maxsize); */ + + free(startUp); +} + diff --git a/ndb/test/ndbapi/bench/dbGenerator.h b/ndb/test/ndbapi/bench/dbGenerator.h new file mode 100644 index 00000000000..2256498e151 --- /dev/null +++ b/ndb/test/ndbapi/bench/dbGenerator.h @@ -0,0 +1,63 @@ +/* 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; either version 2 of the License, or + (at your option) any later version. + + 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 */ + +#ifndef DBGENERATOR_H +#define DBGENERATOR_H + +/*************************************************************** +* I N C L U D E D F I L E S * +***************************************************************/ + +#include "testData.h" +#include "userInterface.h" + +/*************************************************************** +* M A C R O S * +***************************************************************/ + +/***************************************************************/ +/* C O N S T A N T S */ +/***************************************************************/ + +/*************************************************************** +* D A T A S T R U C T U R E S * +***************************************************************/ + +/*************************************************************** +* P U B L I C F U N C T I O N S * +***************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +extern void asyncGenerator(ThreadData *d, int parallellism, + int millisSendPoll, + int minEventSendPoll, + int forceSendPoll); + +#ifdef __cplusplus +} +#endif + +/*************************************************************** +* E X T E R N A L D A T A * +***************************************************************/ + + + +#endif /* DBGENERATOR_H */ + diff --git a/ndb/test/ndbapi/bench/dbPopulate.cpp b/ndb/test/ndbapi/bench/dbPopulate.cpp new file mode 100644 index 00000000000..42fbb52f3b2 --- /dev/null +++ b/ndb/test/ndbapi/bench/dbPopulate.cpp @@ -0,0 +1,244 @@ +/* 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; either version 2 of the License, or + (at your option) any later version. + + 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 */ + +/*************************************************************** +* I N C L U D E D F I L E S * +***************************************************************/ + +#include + +#include "userInterface.h" + +#include "dbPopulate.h" +#include +#include + +/*************************************************************** +* L O C A L C O N S T A N T S * +***************************************************************/ + +/*************************************************************** +* L O C A L D A T A S T R U C T U R E S * +***************************************************************/ + +/*************************************************************** +* L O C A L F U N C T I O N S * +***************************************************************/ + +static void getRandomSubscriberData(int subscriberNo, + SubscriberNumber number, + SubscriberName name); + +static void populate(char *title, + int count, + void (*func)(UserHandle*,int), + UserHandle *uh); + +static void populateServers(UserHandle *uh, int count); +static void populateSubscribers(UserHandle *uh, int count); +static void populateGroups(UserHandle *uh, int count); + +/*************************************************************** +* L O C A L D A T A * +***************************************************************/ + +static SequenceValues permissionsDefinition[] = { + {90, 1}, + {10, 0}, + {0, 0} +}; + +/*************************************************************** +* P U B L I C D A T A * +***************************************************************/ + + +/*************************************************************** +**************************************************************** +* L O C A L F U N C T I O N S C O D E S E C T I O N * +**************************************************************** +***************************************************************/ + +static void getRandomSubscriberData(int subscriberNo, + SubscriberNumber number, + SubscriberName name) +{ + char sbuf[SUBSCRIBER_NUMBER_LENGTH + 1]; + sprintf(sbuf, "%.*d", SUBSCRIBER_NUMBER_LENGTH, subscriberNo); + memcpy(number, sbuf, SUBSCRIBER_NUMBER_LENGTH); + + memset(name, myRandom48(26)+'A', SUBSCRIBER_NAME_LENGTH); +} + +static void populate(char *title, + int count, + void (*func)(UserHandle*, int), + UserHandle *uh) +{ + ndbout_c("Populating %d '%s' ... ",count, title); + /* fflush(stdout); */ + func(uh,count); + ndbout_c("done"); +} + +static void populateServers(UserHandle *uh, int count) +{ + int i, j; + int len; + char tmp[80]; + int suffix_length = 1; + ServerName serverName; + SubscriberSuffix suffix; + + int commitCount = 0; + + for(i = 0; i < SUBSCRIBER_NUMBER_SUFFIX_LENGTH; i++) + suffix_length *= 10; + + for(i = 0; i < count; i++) { + sprintf(tmp, "-Server %d-", i); + + len = strlen(tmp); + for(j = 0; j < SERVER_NAME_LENGTH; j++){ + serverName[j] = tmp[j % len]; + } + /* serverName[j] = 0; not null-terminated */ + + for(j = 0; j < suffix_length; j++){ + char sbuf[SUBSCRIBER_NUMBER_SUFFIX_LENGTH + 1]; + sprintf(sbuf, "%.*d", SUBSCRIBER_NUMBER_SUFFIX_LENGTH, j); + memcpy(suffix, sbuf, SUBSCRIBER_NUMBER_SUFFIX_LENGTH); + userDbInsertServer(uh, i, suffix, serverName); + commitCount ++; + if((commitCount % OP_PER_TRANS) == 0) + userDbCommit(uh); + } + } + if((commitCount % OP_PER_TRANS) != 0) + userDbCommit(uh); +} + +static void populateSubscribers(UserHandle *uh, int count) +{ + SubscriberNumber number; + SubscriberName name; + int i, j, k; + int res; + + SequenceValues values[NO_OF_GROUPS+1]; + RandomSequence seq; + + for(i = 0; i < NO_OF_GROUPS; i++) { + values[i].length = 1; + values[i].value = i; + } + + values[i].length = 0; + values[i].value = 0; + + if( initSequence(&seq, values) != 0 ) { + ndbout_c("could not set the sequence of random groups"); + exit(0); + } + +#define RETRIES 25 + + for(i = 0; i < count; i+= OP_PER_TRANS) { + for(j = 0; j +#include + +#define ERROR(x) {ndbout_c((x));} +#define ERROR1(x,y) {ndbout_c((x), (y));} +#define ERROR2(x,y,z) {ndbout_c((x), (y), (z));} +#define ERROR3(x,y,z,u) {ndbout_c((x), (y), (z), (u));} +#define ERROR4(x,y,z,u,w) {ndbout_c((x), (y), (z), (u), (w));} + +#define INIT_RANDOM(x) srand48((x)) +#define UI_RANDOM(x) ((unsigned int)(lrand48()%(x))) + +#define ASSERT(cond, message) \ + { if(!(cond)) { ERROR(message); exit(-1); }} + +#ifdef DEBUG_ON +#define DEBUG(x) {ndbout_c((x));} +#define DEBUG1(x,y) {ndbout_c((x), (y));} +#define DEBUG2(x,y,z) {ndbout_c((x), (y), (z));} +#define DEBUG3(x,y,z,u) {ndbout_c((x), (y), (z), (u));} +#define DEBUG4(x,y,z,u,w) {ndbout_c((x), (y), (z), (u), (w));} +#define DEBUG5(x,y,z,u,w, v) {ndbout_c((x), (y), (z), (u), (w), (v));} +#else +#define DEBUG(x) +#define DEBUG1(x,y) +#define DEBUG2(x,y,z) +#define DEBUG3(x,y,z,u) +#define DEBUG4(x,y,z,u,w) +#define DEBUG5(x,y,z,u,w, v) +#endif + +#endif diff --git a/ndb/test/ndbapi/bench/mainAsyncGenerator.cpp b/ndb/test/ndbapi/bench/mainAsyncGenerator.cpp new file mode 100644 index 00000000000..828b924582f --- /dev/null +++ b/ndb/test/ndbapi/bench/mainAsyncGenerator.cpp @@ -0,0 +1,503 @@ +/* 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; either version 2 of the License, or + (at your option) any later version. + + 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 + +#include +#include +#include +#include +#include +#include +#include + +#include "userInterface.h" +#include "dbGenerator.h" + +static int numProcesses; +static int numSeconds; +static int numWarmSeconds; +static int parallellism; +static int millisSendPoll; +static int minEventSendPoll; +static int forceSendPoll; + +static ThreadData *data; +static Ndb_cluster_connection *g_cluster_connection= 0; + + +static void usage(const char *prog) +{ + const char *progname; + + /*--------------------------------------------*/ + /* Get the name of the program (without path) */ + /*--------------------------------------------*/ + progname = strrchr(prog, '/'); + + if (progname == 0) + progname = prog; + else + ++progname; + + ndbout_c( + "Usage: %s [-proc ] [-warm ] [-time ] [ -p ] " + "[-t ] [ -e ] [ -f ] \n" + " -proc Specifies that is the number of\n" + " threads. The default is 1.\n" + " -time Specifies that the test will run for sec.\n" + " The default is 10 sec\n" + " -warm Specifies the warm-up/cooldown period of " + "sec.\n" + " The default is 10 sec\n" + " -p The no of parallell transactions started by " + "one thread\n" + " -e Minimum no of events before wake up in call to " + "sendPoll\n" + " Default is 1\n" + " -f force parameter to sendPoll\n" + " Default is 0\n", + progname); +} + +static +int +parse_args(int argc, const char **argv) +{ + int i; + + numProcesses = 1; + numSeconds = 10; + numWarmSeconds = 10; + parallellism = 1; + millisSendPoll = 10000; + minEventSendPoll = 1; + forceSendPoll = 0; + + + i = 1; + while (i < argc){ + if (strcmp("-proc",argv[i]) == 0) { + if (i + 1 >= argc) { + return 1; + } + if (sscanf(argv[i+1], "%d", &numProcesses) == -1 || + numProcesses <= 0 || numProcesses > 127) { + ndbout_c("-proc flag requires a positive integer argument [1..127]"); + return 1; + } + i += 2; + } else if (strcmp("-p", argv[i]) == 0){ + if(i + 1 >= argc){ + usage(argv[0]); + return 1; + } + if (sscanf(argv[i+1], "%d", ¶llellism) == -1 || + parallellism <= 0){ + ndbout_c("-p flag requires a positive integer argument"); + return 1; + } + i += 2; + } + else if (strcmp("-time",argv[i]) == 0) { + if (i + 1 >= argc) { + return 1; + } + if (sscanf(argv[i+1], "%d", &numSeconds) == -1 || + numSeconds < 0) { + ndbout_c("-time flag requires a positive integer argument"); + return 1; + } + i += 2; + } + else if (strcmp("-warm",argv[i]) == 0) { + if (i + 1 >= argc) { + return 1; + } + if (sscanf(argv[i+1], "%d", &numWarmSeconds) == -1 || + numWarmSeconds < 0) { + ndbout_c("-warm flag requires a positive integer argument"); + return 1; + } + i += 2; + } + else if (strcmp("-e",argv[i]) == 0) { + if (i + 1 >= argc) { + return 1; + } + if (sscanf(argv[i+1], "%d", &minEventSendPoll) == -1 || + minEventSendPoll < 0) { + ndbout_c("-e flag requires a positive integer argument"); + return 1; + } + i += 2; + } + else if (strcmp("-f",argv[i]) == 0) { + if (i + 1 >= argc) { + usage(argv[0]); + return 1; + } + if (sscanf(argv[i+1], "%d", &forceSendPoll) == -1 || + forceSendPoll < 0) { + ndbout_c("-f flag requires a positive integer argument"); + return 1; + } + i += 2; + } + else { + return 1; + } + } + + if(minEventSendPoll > parallellism){ + ndbout_c("minEventSendPoll(%d) > parallellism(%d)", + minEventSendPoll, parallellism); + ndbout_c("not very good..."); + ndbout_c("very bad..."); + ndbout_c("exiting..."); + return 1; + } + return 0; +} + +static +void +print_transaction(const char *header, + unsigned long totalCount, + TransactionDefinition *trans, + unsigned int printBranch, + unsigned int printRollback) +{ + double f; + + ndbout_c(" %s: %d (%.2f%%) " + "Latency(ms) avg: %d min: %d max: %d std: %d n: %d", + header, + trans->count, + (double)trans->count / (double)totalCount * 100.0, + (int)trans->latency.getMean(), + (int)trans->latency.getMin(), + (int)trans->latency.getMax(), + (int)trans->latency.getStddev(), + (int)trans->latency.getCount() + ); + + if( printBranch ){ + if( trans->count == 0 ) + f = 0.0; + else + f = (double)trans->branchExecuted / (double)trans->count * 100.0; + ndbout_c(" Branches Executed: %d (%.2f%%)", trans->branchExecuted, f); + } + + if( printRollback ){ + if( trans->count == 0 ) + f = 0.0; + else + f = (double)trans->rollbackExecuted / (double)trans->count * 100.0; + ndbout_c(" Rollback Executed: %d (%.2f%%)",trans->rollbackExecuted,f); + } +} + +void +print_stats(const char *title, + unsigned int length, + unsigned int transactionFlag, + GeneratorStatistics *gen, + int numProc, int parallellism) +{ + int i; + char buf[10]; + char name[MAXHOSTNAMELEN]; + + name[0] = 0; + NdbHost_GetHostName(name); + + ndbout_c("\n------ %s ------",title); + ndbout_c("Length : %d %s", + length, + transactionFlag ? "Transactions" : "sec"); + ndbout_c("Processor : %s", name); + ndbout_c("Number of Proc: %d",numProc); + ndbout_c("Parallellism : %d", parallellism); + ndbout_c("\n"); + + if( gen->totalTransactions == 0 ) { + ndbout_c(" No Transactions for this test"); + } + else { + for(i = 0; i < 5; i++) { + sprintf(buf, "T%d",i+1); + print_transaction(buf, + gen->totalTransactions, + &gen->transactions[i], + i >= 2, + i >= 3 ); + } + + ndbout_c("\n"); + ndbout_c(" Overall Statistics:"); + ndbout_c(" Transactions: %d", gen->totalTransactions); + ndbout_c(" Outer : %.0f TPS",gen->outerTps); + ndbout_c("\n"); + } +} + +static +void * +threadRoutine(void *arg) +{ + int i; + ThreadData *data = (ThreadData *)arg; + Ndb * pNDB; + + pNDB = asyncDbConnect(parallellism); + /* NdbSleep_MilliSleep(rand() % 10); */ + + for(i = 0; ipThread = pThread; + } else { + perror("Failed to create thread"); + rc = NDBT_FAILED; + } + } + + showTime(); + + /*--------------------------------*/ + /* Wait for all processes to exit */ + /*--------------------------------*/ + for(i = 0; i < numProcesses; i++) { + NdbThread_WaitFor(data[i*parallellism].pThread, &tmp); + NdbThread_Destroy(&data[i*parallellism].pThread); + } + + ndbout_c("All threads have finished"); + + /*-------------------------------------------*/ + /* Clear all structures for total statistics */ + /*-------------------------------------------*/ + stats.totalTransactions = 0; + stats.outerTps = 0.0; + + for(i = 0; i < NUM_TRANSACTION_TYPES; i++ ) { + stats.transactions[i].count = 0; + stats.transactions[i].branchExecuted = 0; + stats.transactions[i].rollbackExecuted = 0; + stats.transactions[i].latency.reset(); + } + + /*--------------------------------*/ + /* Add the values for all Threads */ + /*--------------------------------*/ + for(i = 0; i < numProcesses; i++) { + for(k = 0; ktotalTransactions; + stats.outerTps += p->outerTps; + + for(j = 0; j < NUM_TRANSACTION_TYPES; j++ ) { + stats.transactions[j].count += + p->transactions[j].count; + stats.transactions[j].branchExecuted += + p->transactions[j].branchExecuted; + stats.transactions[j].rollbackExecuted += + p->transactions[j].rollbackExecuted; + stats.transactions[j].latency += + p->transactions[j].latency; + } + } + } + + print_stats("Test Results", + numSeconds, + 0, + &stats, + numProcesses, + parallellism); + + free(data); + + NDBT_ProgramExit(rc); +} +/*************************************************************** +* I N C L U D E D F I L E S * +***************************************************************/ + +#include +#include +#include +#include + +#include "ndb_schema.hpp" +#include "ndb_error.hpp" +#include "userInterface.h" +#include +#include +#include +#include +#include + +/*************************************************************** +* L O C A L C O N S T A N T S * +***************************************************************/ + +/*************************************************************** +* L O C A L D A T A S T R U C T U R E S * +***************************************************************/ + +/*************************************************************** +* L O C A L F U N C T I O N S * +***************************************************************/ + +#ifndef NDB_WIN32 +#include +#endif + +Ndb* +asyncDbConnect(int parallellism){ + Ndb * pNDB = new Ndb(g_cluster_connection, "TEST_DB"); + + pNDB->init(parallellism + 1); + + while(pNDB->waitUntilReady() != 0){ + } + + return pNDB; +} + +void +asyncDbDisconnect(Ndb* pNDB) +{ + delete pNDB; +} + +double +userGetTime(void) +{ + static bool initialized = false; + static NDB_TICKS initSecs = 0; + static Uint32 initMicros = 0; + double timeValue = 0; + + if ( !initialized ) { + initialized = true; + NdbTick_CurrentMicrosecond(&initSecs, &initMicros); + timeValue = 0.0; + } else { + NDB_TICKS secs = 0; + Uint32 micros = 0; + + NdbTick_CurrentMicrosecond(&secs, µs); + double s = (double)secs - (double)initSecs; + double us = (double)micros - (double)initMicros; + + timeValue = s + (us / 1000000.0); + } + return timeValue; +} + +void showTime() +{ + char buf[128]; + struct tm* tm_now; + time_t now; + now = ::time((time_t*)NULL); + tm_now = ::gmtime(&now); + + ::snprintf(buf, 128, + "%d-%.2d-%.2d %.2d:%.2d:%.2d", + tm_now->tm_year + 1900, + tm_now->tm_mon, + tm_now->tm_mday, + tm_now->tm_hour, + tm_now->tm_min, + tm_now->tm_sec); + + ndbout_c("Time: %s", buf); +} + diff --git a/ndb/test/ndbapi/bench/mainPopulate.cpp b/ndb/test/ndbapi/bench/mainPopulate.cpp new file mode 100644 index 00000000000..5f4b73a3eff --- /dev/null +++ b/ndb/test/ndbapi/bench/mainPopulate.cpp @@ -0,0 +1,84 @@ +/* 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; either version 2 of the License, or + (at your option) any later version. + + 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 +#include + +#include "userInterface.h" +#include "dbPopulate.h" +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +int useTableLogging; +int useIndexTables; +#ifdef __cplusplus +} +#endif + + +static void usage() +{ +} + +static +void usage(const char *prog) +{ + + ndbout_c( + "Usage: %s [-l]\n" + " -l Use logging and checkpointing on tables\n", + " -i Use index tables\n", + prog); + + exit(1); +} + +NDB_STD_OPTS_VARS; + +NDB_COMMAND(DbCreate, "DbCreate", "DbCreate", "DbCreate", 16384) +{ + int i; + UserHandle *uh; + + useTableLogging = useIndexTables = 0; + NDB_INIT(argv[0]); + + for(i = 1; i + +inline +NdbConnection * +startTransaction(Ndb * pNDB, + ServerId inServerId, + const SubscriberNumber inNumber){ + + const int keyDataLenBytes = sizeof(ServerId)+SUBSCRIBER_NUMBER_LENGTH; + const int keyDataLen_64Words = keyDataLenBytes >> 3; + + Uint64 keyDataBuf[keyDataLen_64Words+1]; // The "+1" is for rounding... + + char * keyDataBuf_charP = (char *)&keyDataBuf[0]; + Uint32 * keyDataBuf_wo32P = (Uint32 *)&keyDataBuf[0]; + + // Server Id comes first + keyDataBuf_wo32P[0] = inServerId; + // Then subscriber number + memcpy(&keyDataBuf_charP[sizeof(ServerId)], inNumber, + SUBSCRIBER_NUMBER_LENGTH); + + return pNDB->startTransaction(0, keyDataBuf_charP, keyDataLenBytes); +} + +void T1_Callback(int result, NdbConnection * pCon, void * threadData); +void T2_Callback(int result, NdbConnection * pCon, void * threadData); +void T3_Callback_1(int result, NdbConnection * pCon, void * threadData); +void T3_Callback_2(int result, NdbConnection * pCon, void * threadData); +void T3_Callback_3(int result, NdbConnection * pCon, void * threadData); +void T4_Callback_1(int result, NdbConnection * pCon, void * threadData); +void T4_Callback_2(int result, NdbConnection * pCon, void * threadData); +void T4_Callback_3(int result, NdbConnection * pCon, void * threadData); +void T5_Callback_1(int result, NdbConnection * pCon, void * threadData); +void T5_Callback_2(int result, NdbConnection * pCon, void * threadData); +void T5_Callback_3(int result, NdbConnection * pCon, void * threadData); + +/** + * Transaction 1 - T1 + * + * Update location and changed by/time on a subscriber + * + * Input: + * SubscriberNumber, + * Location, + * ChangedBy, + * ChangedTime + * + * Output: + */ +void +start_T1(Ndb * pNDB, ThreadData * td){ + + DEBUG2("T1(%.*s): - Starting\n", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number); + + int check; + NdbConnection * pCON = pNDB->startTransaction(); + if (pCON != NULL) { + NdbOperation *MyOp = pCON->getNdbOperation(SUBSCRIBER_TABLE); + if (MyOp != NULL) { + MyOp->updateTuple(); + MyOp->equal(IND_SUBSCRIBER_NUMBER, + td->transactionData.number); + MyOp->setValue(IND_SUBSCRIBER_LOCATION, + (char *)&td->transactionData.location); + MyOp->setValue(IND_SUBSCRIBER_CHANGED_BY, + td->transactionData.changed_by); + MyOp->setValue(IND_SUBSCRIBER_CHANGED_TIME, + td->transactionData.changed_time); + pCON->executeAsynchPrepare( Commit , T1_Callback, td); + } else { + CHECK_NULL(MyOp, "T1: getNdbOperation", pCON); + }//if + } else { + error_handler("T1-1: startTranscation", + pNDB->getNdbErrorString(), + pNDB->getNdbError()); + }//if +} + +void +T1_Callback(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + + DEBUG2("T1(%.*s): - Completing\n", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number); + + CHECK_MINUS_ONE(result, "T1: Commit", + pCON); + td->pNDB->closeTransaction(pCON); + complete_T1(td); +} + +/** + * Transaction 2 - T2 + * + * Read from Subscriber: + * + * Input: + * SubscriberNumber + * + * Output: + * Location + * Changed by + * Changed Timestamp + * Name + */ +void +start_T2(Ndb * pNDB, ThreadData * td){ + + DEBUG3("T2(%.*s, %p): - Starting\n", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.location); + + int check; + NdbRecAttr * check2; + + NdbConnection * pCON = pNDB->startTransaction(); + if (pCON == NULL) + error_handler("T2-1: startTransaction", + pNDB->getNdbErrorString(), + pNDB->getNdbError()); + + NdbOperation *MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOp, "T2: getNdbOperation", + pCON); + + MyOp->readTuple(); + MyOp->equal(IND_SUBSCRIBER_NUMBER, + td->transactionData.number); + MyOp->getValue(IND_SUBSCRIBER_LOCATION, + (char *)&td->transactionData.location); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, + td->transactionData.changed_by); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, + td->transactionData.changed_time); + MyOp->getValue(IND_SUBSCRIBER_NAME, + td->transactionData.name); + pCON->executeAsynchPrepare( Commit, T2_Callback, td ); +} + +void +T2_Callback(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + DEBUG3("T2(%.*s, %p): - Completing\n", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.location); + + CHECK_MINUS_ONE(result, "T2: Commit", pCON); + td->pNDB->closeTransaction(pCON); + complete_T2(td); +} + +/** + * Transaction 3 - T3 + * + * Read session details + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * + * Output: + * BranchExecuted + * SessionDetails + * ChangedBy + * ChangedTime + * Location + */ +void +start_T3(Ndb * pNDB, ThreadData * td){ + + DEBUG3("T3(%.*s, %.2d): - Starting\n", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + int check; + NdbRecAttr * check2; + + NdbConnection * pCON = startTransaction(pNDB, + td->transactionData.server_id, + td->transactionData.number); + if (pCON == NULL) + error_handler("T3-1: startTranscation", + pNDB->getNdbErrorString(), + pNDB->getNdbError()); + + NdbOperation *MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOp, "T3-1: getNdbOperation", + pCON); + + MyOp->readTuple(); + MyOp->equal(IND_SUBSCRIBER_NUMBER, + td->transactionData.number); + MyOp->getValue(IND_SUBSCRIBER_LOCATION, + (char *)&td->transactionData.location); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, + td->transactionData.changed_by); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, + td->transactionData.changed_time); + MyOp->getValue(IND_SUBSCRIBER_GROUP, + (char *)&td->transactionData.group_id); + MyOp->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&td->transactionData.sessions); + pCON->executeAsynchPrepare( NoCommit , T3_Callback_1, td); +} + +void +T3_Callback_1(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + DEBUG3("T3(%.*s, %.2d): - Callback 1\n", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + CHECK_MINUS_ONE(result, "T3-1: NoCommit", pCON); + + NdbOperation * MyOp = pCON->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOp, "T3-2: getNdbOperation", + pCON); + + MyOp->readTuple(); + MyOp->equal(IND_GROUP_ID, + (char*)&td->transactionData.group_id); + MyOp->getValue(IND_GROUP_ALLOW_READ, + (char *)&td->transactionData.permission); + pCON->executeAsynchPrepare( NoCommit, T3_Callback_2, td ); +} + +void +T3_Callback_2(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + + CHECK_MINUS_ONE(result, "T3-2: NoCommit", pCON); + + Uint32 permission = td->transactionData.permission; + Uint32 sessions = td->transactionData.sessions; + Uint32 server_bit = td->transactionData.server_bit; + + if(((permission & server_bit) == server_bit) && + ((sessions & server_bit) == server_bit)){ + + memcpy(td->transactionData.suffix, + &td->transactionData.number + [SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH], + SUBSCRIBER_NUMBER_SUFFIX_LENGTH); + DEBUG5("T3(%.*s, %.2d): - Callback 2 - reading(%.*s)\n", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id, + SUBSCRIBER_NUMBER_SUFFIX_LENGTH, + td->transactionData.suffix); + + /* Operation 3 */ + NdbOperation * MyOp = pCON->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOp, "T3-3: getNdbOperation", + pCON); + + MyOp->simpleRead(); + MyOp->equal(IND_SESSION_SUBSCRIBER, + (char*)td->transactionData.number); + MyOp->equal(IND_SESSION_SERVER, + (char*)&td->transactionData.server_id); + MyOp->getValue(IND_SESSION_DATA, + (char *)td->transactionData.session_details); + + /* Operation 4 */ + MyOp = pCON->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOp, "T3-4: getNdbOperation", + pCON); + + MyOp->interpretedUpdateTuple(); + MyOp->equal(IND_SERVER_ID, + (char*)&td->transactionData.server_id); + MyOp->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)td->transactionData.suffix); + MyOp->incValue(IND_SERVER_READS, (uint32)1); + td->transactionData.branchExecuted = 1; + } else { + DEBUG3("T3(%.*s, %.2d): - Callback 2 - no read\n", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + td->transactionData.branchExecuted = 0; + } + pCON->executeAsynchPrepare( Commit, T3_Callback_3, td ); +} + +void +T3_Callback_3(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + DEBUG3("T3(%.*s, %.2d): - Completing\n", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + CHECK_MINUS_ONE(result, "T3-3: Commit", pCON); + + td->pNDB->closeTransaction(pCON); + complete_T3(td); +} + +/** + * Transaction 4 - T4 + * + * Create session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * SessionDetails, + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +void +start_T4(Ndb * pNDB, ThreadData * td){ + + DEBUG3("T4(%.*s, %.2d): - Starting\n", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + int check; + NdbRecAttr * check2; + + NdbConnection * pCON = startTransaction(pNDB, + td->transactionData.server_id, + td->transactionData.number); + if (pCON == NULL) + error_handler("T4-1: startTranscation", + pNDB->getNdbErrorString(), + pNDB->getNdbError()); + + NdbOperation *MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOp, "T4-1: getNdbOperation", + pCON); + + MyOp->interpretedUpdateTuple(); + MyOp->equal(IND_SUBSCRIBER_NUMBER, + td->transactionData.number); + MyOp->getValue(IND_SUBSCRIBER_LOCATION, + (char *)&td->transactionData.location); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, + td->transactionData.changed_by); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, + td->transactionData.changed_time); + MyOp->getValue(IND_SUBSCRIBER_GROUP, + (char *)&td->transactionData.group_id); + MyOp->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&td->transactionData.sessions); + MyOp->incValue(IND_SUBSCRIBER_SESSIONS, + (uint32)td->transactionData.server_bit); + pCON->executeAsynchPrepare( NoCommit , T4_Callback_1, td); +} + +void +T4_Callback_1(int result, NdbConnection * pCON, void * threadData){ + CHECK_MINUS_ONE(result, "T4-1: NoCommit", pCON); + ThreadData * td = (ThreadData *)threadData; + + DEBUG3("T4(%.*s, %.2d): - Callback 1\n", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + + NdbOperation * MyOp = pCON->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOp, "T4-2: getNdbOperation", + pCON); + + MyOp->readTuple(); + MyOp->equal(IND_GROUP_ID, + (char*)&td->transactionData.group_id); + MyOp->getValue(IND_GROUP_ALLOW_INSERT, + (char *)&td->transactionData.permission); + pCON->executeAsynchPrepare( NoCommit , T4_Callback_2, td); +} + +void +T4_Callback_2(int result, NdbConnection * pCON, void * threadData){ + CHECK_MINUS_ONE(result, "T4-2: NoCommit", pCON); + ThreadData * td = (ThreadData *)threadData; + + Uint32 permission = td->transactionData.permission; + Uint32 sessions = td->transactionData.sessions; + Uint32 server_bit = td->transactionData.server_bit; + + if(((permission & server_bit) == server_bit) && + ((sessions & server_bit) == 0)){ + + memcpy(td->transactionData.suffix, + &td->transactionData.number + [SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH], + SUBSCRIBER_NUMBER_SUFFIX_LENGTH); + + DEBUG5("T4(%.*s, %.2d): - Callback 2 - inserting(%.*s)\n", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id, + SUBSCRIBER_NUMBER_SUFFIX_LENGTH, + td->transactionData.suffix); + + /* Operation 3 */ + + NdbOperation * MyOp = pCON->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOp, "T4-3: getNdbOperation", + pCON); + + MyOp->insertTuple(); + MyOp->equal(IND_SESSION_SUBSCRIBER, + (char*)td->transactionData.number); + MyOp->equal(IND_SESSION_SERVER, + (char*)&td->transactionData.server_id); + MyOp->setValue(SESSION_DATA, + (char *)td->transactionData.session_details); + /* Operation 4 */ + + /* Operation 5 */ + MyOp = pCON->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOp, "T4-5: getNdbOperation", + pCON); + + MyOp->interpretedUpdateTuple(); + MyOp->equal(IND_SERVER_ID, + (char*)&td->transactionData.server_id); + MyOp->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)td->transactionData.suffix); + MyOp->incValue(IND_SERVER_INSERTS, (uint32)1); + td->transactionData.branchExecuted = 1; + } else { + td->transactionData.branchExecuted = 0; + DEBUG5("T4(%.*s, %.2d): - Callback 2 - %s %s\n", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id, + ((permission & server_bit) ? + "permission - " : "no permission - "), + ((sessions & server_bit) ? + "in session - " : "no in session - ")); + } + + if(!td->transactionData.do_rollback && td->transactionData.branchExecuted){ + pCON->executeAsynchPrepare(Commit, T4_Callback_3, td); + } else { + pCON->executeAsynchPrepare(Rollback, T4_Callback_3, td); + } +} + +void +T4_Callback_3(int result, NdbConnection * pCON, void * threadData){ + CHECK_MINUS_ONE(result, "T4-3: Commit", pCON); + ThreadData * td = (ThreadData *)threadData; + + DEBUG3("T4(%.*s, %.2d): - Completing\n", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + td->pNDB->closeTransaction(pCON); + complete_T4(td); +} + +/** + * Transaction 5 - T5 + * + * Delete session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +void +start_T5(Ndb * pNDB, ThreadData * td){ + + DEBUG3("T5(%.*s, %.2d): - Starting\n", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + int check; + NdbRecAttr * check2; + + NdbConnection * pCON = pNDB->startTransaction(); + if (pCON == NULL) + error_handler("T5-1: startTranscation", + pNDB->getNdbErrorString(), + pNDB->getNdbError()); + + NdbOperation * MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOp, "T5-1: getNdbOperation", + pCON); + + MyOp->interpretedUpdateTuple(); + MyOp->equal(IND_SUBSCRIBER_NUMBER, + td->transactionData.number); + MyOp->getValue(IND_SUBSCRIBER_LOCATION, + (char *)&td->transactionData.location); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, + td->transactionData.changed_by); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, + td->transactionData.changed_time); + MyOp->getValue(IND_SUBSCRIBER_GROUP, + (char *)&td->transactionData.group_id); + MyOp->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&td->transactionData.sessions); + MyOp->subValue(IND_SUBSCRIBER_SESSIONS, + (uint32)td->transactionData.server_bit); + pCON->executeAsynchPrepare( NoCommit, T5_Callback_1, td ); +} + +void +T5_Callback_1(int result, NdbConnection * pCON, void * threadData){ + CHECK_MINUS_ONE(result, "T5-1: NoCommit", pCON); + ThreadData * td = (ThreadData *)threadData; + + DEBUG3("T5(%.*s, %.2d): - Callback 1\n", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + NdbOperation * MyOp = pCON->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOp, "T5-2: getNdbOperation", + pCON); + + MyOp->readTuple(); + MyOp->equal(IND_GROUP_ID, + (char*)&td->transactionData.group_id); + MyOp->getValue(IND_GROUP_ALLOW_DELETE, + (char *)&td->transactionData.permission); + pCON->executeAsynchPrepare( NoCommit, T5_Callback_2, td ); +} + +void +T5_Callback_2(int result, NdbConnection * pCON, void * threadData){ + CHECK_MINUS_ONE(result, "T5-2: NoCommit", pCON); + ThreadData * td = (ThreadData *)threadData; + + Uint32 permission = td->transactionData.permission; + Uint32 sessions = td->transactionData.sessions; + Uint32 server_bit = td->transactionData.server_bit; + + if(((permission & server_bit) == server_bit) && + ((sessions & server_bit) == server_bit)){ + + memcpy(td->transactionData.suffix, + &td->transactionData.number + [SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH], + SUBSCRIBER_NUMBER_SUFFIX_LENGTH); + + DEBUG5("T5(%.*s, %.2d): - Callback 2 - deleting(%.*s)\n", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id, + SUBSCRIBER_NUMBER_SUFFIX_LENGTH, + td->transactionData.suffix); + + /* Operation 3 */ + NdbOperation * MyOp = pCON->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOp, "T5-3: getNdbOperation", + pCON); + + MyOp->deleteTuple(); + MyOp->equal(IND_SESSION_SUBSCRIBER, + (char*)td->transactionData.number); + MyOp->equal(IND_SESSION_SERVER, + (char*)&td->transactionData.server_id); + /* Operation 4 */ + + /* Operation 5 */ + MyOp = pCON->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOp, "T5-5: getNdbOperation", + pCON); + + MyOp->interpretedUpdateTuple(); + MyOp->equal(IND_SERVER_ID, + (char*)&td->transactionData.server_id); + MyOp->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)td->transactionData.suffix); + MyOp->incValue(IND_SERVER_DELETES, (uint32)1); + td->transactionData.branchExecuted = 1; + } else { + td->transactionData.branchExecuted = 0; + + DEBUG5("T5(%.*s, %.2d): - Callback 2 - no delete - %s %s\n", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id, + ((permission & server_bit) ? + "permission - " : "no permission - "), + ((sessions & server_bit) ? + "in session - " : "no in session - ")); + } + + if(!td->transactionData.do_rollback && td->transactionData.branchExecuted){ + pCON->executeAsynchPrepare(Commit, T5_Callback_3, td); + } else { + pCON->executeAsynchPrepare(Rollback, T5_Callback_3, td); + } +} + +void +T5_Callback_3(int result, NdbConnection * pCON, void * threadData){ + CHECK_MINUS_ONE(result, "T5-3: Commit", pCON); + ThreadData * td = (ThreadData *)threadData; + + DEBUG3("T5(%.*s, %.2d): - Completing\n", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + td->pNDB->closeTransaction(pCON); + complete_T5(td); +} diff --git a/ndb/test/ndbapi/bench/ndb_async2.cpp b/ndb/test/ndbapi/bench/ndb_async2.cpp new file mode 100644 index 00000000000..31cf1d8310a --- /dev/null +++ b/ndb/test/ndbapi/bench/ndb_async2.cpp @@ -0,0 +1,757 @@ +/* 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; either version 2 of the License, or + (at your option) any later version. + + 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 */ + +//#define DEBUG_ON + +#include +#include "userInterface.h" + +#include "macros.h" +#include "ndb_schema.hpp" +#include "ndb_error.hpp" +#include + +#include + +void T1_Callback(int result, NdbConnection * pCon, void * threadData); +void T2_Callback(int result, NdbConnection * pCon, void * threadData); +void T3_Callback_1(int result, NdbConnection * pCon, void * threadData); +void T3_Callback_2(int result, NdbConnection * pCon, void * threadData); +void T3_Callback_3(int result, NdbConnection * pCon, void * threadData); +void T4_Callback_1(int result, NdbConnection * pCon, void * threadData); +void T4_Callback_2(int result, NdbConnection * pCon, void * threadData); +void T4_Callback_3(int result, NdbConnection * pCon, void * threadData); +void T5_Callback_1(int result, NdbConnection * pCon, void * threadData); +void T5_Callback_2(int result, NdbConnection * pCon, void * threadData); +void T5_Callback_3(int result, NdbConnection * pCon, void * threadData); + +static int stat_async = 0; + +/** + * Transaction 1 - T1 + * + * Update location and changed by/time on a subscriber + * + * Input: + * SubscriberNumber, + * Location, + * ChangedBy, + * ChangedTime + * + * Output: + */ + +#define SFX_START (SUBSCRIBER_NUMBER_LENGTH - SUBSCRIBER_NUMBER_SUFFIX_LENGTH) + +inline +NdbConnection * +startTransaction(Ndb * pNDB, ThreadData * td){ + return pNDB->startTransaction(); +#ifdef OLD_CODE + return pNDB->startTransactionDGroup (0, + &td->transactionData.number[SFX_START], + 1); +#endif +} + +void +start_T1(Ndb * pNDB, ThreadData * td, int async){ + + DEBUG2("T1(%.*s): - Starting", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number); + + NdbConnection * pCON = 0; + while((pCON = startTransaction(pNDB, td)) == 0){ + CHECK_ALLOWED_ERROR("T1: startTransaction", td, pNDB->getNdbError()); + NdbSleep_MilliSleep(10); + } + + NdbOperation *MyOp = pCON->getNdbOperation(SUBSCRIBER_TABLE); + if (MyOp != NULL) { + MyOp->updateTuple(); + MyOp->equal(IND_SUBSCRIBER_NUMBER, + td->transactionData.number); + MyOp->setValue(IND_SUBSCRIBER_LOCATION, + (char *)&td->transactionData.location); + MyOp->setValue(IND_SUBSCRIBER_CHANGED_BY, + td->transactionData.changed_by); + MyOp->setValue(IND_SUBSCRIBER_CHANGED_TIME, + td->transactionData.changed_time); + if (async == 1) { + pCON->executeAsynchPrepare( Commit , T1_Callback, td); + } else { + int result = pCON->execute(Commit); + T1_Callback(result, pCON, (void*)td); + return; + }//if + } else { + CHECK_NULL(MyOp, "T1: getNdbOperation", td, pCON->getNdbError()); + }//if +} + +void +T1_Callback(int result, NdbConnection * pCON, void * threadData) { + ThreadData * td = (ThreadData *)threadData; + + DEBUG2("T1(%.*s): - Completing", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number); + + if (result == -1) { + CHECK_ALLOWED_ERROR("T1: Commit", td, pCON->getNdbError()); + td->pNDB->closeTransaction(pCON); + start_T1(td->pNDB, td, stat_async); + return; + }//if + td->pNDB->closeTransaction(pCON); + complete_T1(td); +} + +/** + * Transaction 2 - T2 + * + * Read from Subscriber: + * + * Input: + * SubscriberNumber + * + * Output: + * Location + * Changed by + * Changed Timestamp + * Name + */ +void +start_T2(Ndb * pNDB, ThreadData * td, int async){ + + DEBUG3("T2(%.*s, %d): - Starting", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.location); + + NdbConnection * pCON = 0; + + while((pCON = startTransaction(pNDB, td)) == 0){ + CHECK_ALLOWED_ERROR("T2-1: startTransaction", td, pNDB->getNdbError()); + NdbSleep_MilliSleep(10); + } + + NdbOperation *MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOp, "T2: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->readTuple(); + MyOp->equal(IND_SUBSCRIBER_NUMBER, + td->transactionData.number); + MyOp->getValue(IND_SUBSCRIBER_LOCATION, + (char *)&td->transactionData.location); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, + td->transactionData.changed_by); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, + td->transactionData.changed_time); + MyOp->getValue(IND_SUBSCRIBER_NAME, + td->transactionData.name); + if (async == 1) { + pCON->executeAsynchPrepare( Commit , T2_Callback, td); + } else { + int result = pCON->execute(Commit); + T2_Callback(result, pCON, (void*)td); + return; + }//if +} + +void +T2_Callback(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + DEBUG3("T2(%.*s, %d): - Completing", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.location); + + if (result == -1) { + CHECK_ALLOWED_ERROR("T2: Commit", td, pCON->getNdbError()); + td->pNDB->closeTransaction(pCON); + start_T2(td->pNDB, td, stat_async); + return; + }//if + td->pNDB->closeTransaction(pCON); + complete_T2(td); +} + +/** + * Transaction 3 - T3 + * + * Read session details + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * + * Output: + * BranchExecuted + * SessionDetails + * ChangedBy + * ChangedTime + * Location + */ +void +start_T3(Ndb * pNDB, ThreadData * td, int async){ + + DEBUG3("T3(%.*s, %.2d): - Starting", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + NdbConnection * pCON = 0; + + while((pCON = startTransaction(pNDB, td)) == 0){ + CHECK_ALLOWED_ERROR("T3-1: startTransaction", td, pNDB->getNdbError()); + NdbSleep_MilliSleep(10); + } + + NdbOperation *MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOp, "T3-1: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->readTuple(); + MyOp->equal(IND_SUBSCRIBER_NUMBER, + td->transactionData.number); + MyOp->getValue(IND_SUBSCRIBER_LOCATION, + (char *)&td->transactionData.location); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, + td->transactionData.changed_by); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, + td->transactionData.changed_time); + MyOp->getValue(IND_SUBSCRIBER_GROUP, + (char *)&td->transactionData.group_id); + MyOp->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&td->transactionData.sessions); + stat_async = async; + if (async == 1) { + pCON->executeAsynchPrepare( NoCommit , T3_Callback_1, td); + } else { + int result = pCON->execute( NoCommit ); + T3_Callback_1(result, pCON, (void*)td); + return; + }//if +} + +void +T3_Callback_1(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + DEBUG3("T3(%.*s, %.2d): - Callback 1", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + if (result == -1) { + CHECK_ALLOWED_ERROR("T3-1: execute", td, pCON->getNdbError()); + td->pNDB->closeTransaction(pCON); + start_T3(td->pNDB, td, stat_async); + return; + }//if + + NdbOperation * MyOp = pCON->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOp, "T3-2: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->readTuple(); + MyOp->equal(IND_GROUP_ID, + (char*)&td->transactionData.group_id); + MyOp->getValue(IND_GROUP_ALLOW_READ, + (char *)&td->transactionData.permission); + if (stat_async == 1) { + pCON->executeAsynchPrepare( NoCommit , T3_Callback_2, td); + } else { + int result = pCON->execute( NoCommit ); + T3_Callback_2(result, pCON, (void*)td); + return; + }//if +} + +void +T3_Callback_2(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + + if (result == -1) { + CHECK_ALLOWED_ERROR("T3-2: execute", td, pCON->getNdbError()); + td->pNDB->closeTransaction(pCON); + start_T3(td->pNDB, td, stat_async); + return; + }//if + + Uint32 permission = td->transactionData.permission; + Uint32 sessions = td->transactionData.sessions; + Uint32 server_bit = td->transactionData.server_bit; + + if(((permission & server_bit) == server_bit) && + ((sessions & server_bit) == server_bit)){ + + memcpy(td->transactionData.suffix, + &td->transactionData.number[SFX_START], + SUBSCRIBER_NUMBER_SUFFIX_LENGTH); + DEBUG5("T3(%.*s, %.2d): - Callback 2 - reading(%.*s)", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id, + SUBSCRIBER_NUMBER_SUFFIX_LENGTH, + td->transactionData.suffix); + + /* Operation 3 */ + NdbOperation * MyOp = pCON->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOp, "T3-3: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->simpleRead(); + MyOp->equal(IND_SESSION_SUBSCRIBER, + (char*)td->transactionData.number); + MyOp->equal(IND_SESSION_SERVER, + (char*)&td->transactionData.server_id); + MyOp->getValue(IND_SESSION_DATA, + (char *)td->transactionData.session_details); + + /* Operation 4 */ + MyOp = pCON->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOp, "T3-4: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->interpretedUpdateTuple(); + MyOp->equal(IND_SERVER_ID, + (char*)&td->transactionData.server_id); + MyOp->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)td->transactionData.suffix); + MyOp->incValue(IND_SERVER_READS, (uint32)1); + td->transactionData.branchExecuted = 1; + } else { + DEBUG3("T3(%.*s, %.2d): - Callback 2 - no read", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + td->transactionData.branchExecuted = 0; + } + if (stat_async == 1) { + pCON->executeAsynchPrepare( Commit , T3_Callback_3, td); + } else { + int result = pCON->execute( Commit ); + T3_Callback_3(result, pCON, (void*)td); + return; + }//if +} + +void +T3_Callback_3(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + DEBUG3("T3(%.*s, %.2d): - Completing", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + if (result == -1) { + CHECK_ALLOWED_ERROR("T3-3: Commit", td, pCON->getNdbError()); + td->pNDB->closeTransaction(pCON); + start_T3(td->pNDB, td, stat_async); + return; + }//if + td->pNDB->closeTransaction(pCON); + complete_T3(td); +} + +/** + * Transaction 4 - T4 + * + * Create session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * SessionDetails, + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +void +start_T4(Ndb * pNDB, ThreadData * td, int async){ + + DEBUG3("T4(%.*s, %.2d): - Starting", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + NdbConnection * pCON = 0; + while((pCON = startTransaction(pNDB, td)) == 0){ + CHECK_ALLOWED_ERROR("T4-1: startTransaction", td, pNDB->getNdbError()); + NdbSleep_MilliSleep(10); + } + + NdbOperation *MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOp, "T4-1: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->interpretedUpdateTuple(); + MyOp->equal(IND_SUBSCRIBER_NUMBER, + td->transactionData.number); + MyOp->getValue(IND_SUBSCRIBER_LOCATION, + (char *)&td->transactionData.location); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, + td->transactionData.changed_by); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, + td->transactionData.changed_time); + MyOp->getValue(IND_SUBSCRIBER_GROUP, + (char *)&td->transactionData.group_id); + MyOp->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&td->transactionData.sessions); + MyOp->incValue(IND_SUBSCRIBER_SESSIONS, + (uint32)td->transactionData.server_bit); + stat_async = async; + if (async == 1) { + pCON->executeAsynchPrepare( NoCommit , T4_Callback_1, td); + } else { + int result = pCON->execute( NoCommit ); + T4_Callback_1(result, pCON, (void*)td); + return; + }//if +} + +void +T4_Callback_1(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + if (result == -1) { + CHECK_ALLOWED_ERROR("T4-1: execute", td, pCON->getNdbError()); + td->pNDB->closeTransaction(pCON); + start_T4(td->pNDB, td, stat_async); + return; + }//if + + DEBUG3("T4(%.*s, %.2d): - Callback 1", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + + NdbOperation * MyOp = pCON->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOp, "T4-2: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->readTuple(); + MyOp->equal(IND_GROUP_ID, + (char*)&td->transactionData.group_id); + MyOp->getValue(IND_GROUP_ALLOW_INSERT, + (char *)&td->transactionData.permission); + if (stat_async == 1) { + pCON->executeAsynchPrepare( NoCommit , T4_Callback_2, td); + } else { + int result = pCON->execute( NoCommit ); + T4_Callback_2(result, pCON, (void*)td); + return; + }//if +} + +void +T4_Callback_2(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + if (result == -1) { + CHECK_ALLOWED_ERROR("T4-2: execute", td, pCON->getNdbError()); + td->pNDB->closeTransaction(pCON); + start_T4(td->pNDB, td, stat_async); + return; + }//if + + Uint32 permission = td->transactionData.permission; + Uint32 sessions = td->transactionData.sessions; + Uint32 server_bit = td->transactionData.server_bit; + + if(((permission & server_bit) == server_bit) && + ((sessions & server_bit) == 0)){ + + memcpy(td->transactionData.suffix, + &td->transactionData.number[SFX_START], + SUBSCRIBER_NUMBER_SUFFIX_LENGTH); + + DEBUG5("T4(%.*s, %.2d): - Callback 2 - inserting(%.*s)", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id, + SUBSCRIBER_NUMBER_SUFFIX_LENGTH, + td->transactionData.suffix); + + /* Operation 3 */ + + NdbOperation * MyOp = pCON->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOp, "T4-3: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->insertTuple(); + MyOp->equal(IND_SESSION_SUBSCRIBER, + (char*)td->transactionData.number); + MyOp->equal(IND_SESSION_SERVER, + (char*)&td->transactionData.server_id); + MyOp->setValue(SESSION_DATA, + (char *)td->transactionData.session_details); + /* Operation 4 */ + + /* Operation 5 */ + MyOp = pCON->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOp, "T4-5: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->interpretedUpdateTuple(); + MyOp->equal(IND_SERVER_ID, + (char*)&td->transactionData.server_id); + MyOp->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)td->transactionData.suffix); + MyOp->incValue(IND_SERVER_INSERTS, (uint32)1); + td->transactionData.branchExecuted = 1; + } else { + td->transactionData.branchExecuted = 0; + DEBUG5("T4(%.*s, %.2d): - Callback 2 - %s %s", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id, + ((permission & server_bit) ? + "permission - " : "no permission - "), + ((sessions & server_bit) ? + "in session - " : "no in session - ")); + } + + if(!td->transactionData.do_rollback && td->transactionData.branchExecuted){ + if (stat_async == 1) { + pCON->executeAsynchPrepare( Commit , T4_Callback_3, td); + } else { + int result = pCON->execute( Commit ); + T4_Callback_3(result, pCON, (void*)td); + return; + }//if + } else { + if (stat_async == 1) { + pCON->executeAsynchPrepare( Rollback , T4_Callback_3, td); + } else { + int result = pCON->execute( Rollback ); + T4_Callback_3(result, pCON, (void*)td); + return; + }//if + } +} + +void +T4_Callback_3(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + if (result == -1) { + CHECK_ALLOWED_ERROR("T4-3: Commit", td, pCON->getNdbError()); + td->pNDB->closeTransaction(pCON); + start_T4(td->pNDB, td, stat_async); + return; + }//if + + DEBUG3("T4(%.*s, %.2d): - Completing", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + td->pNDB->closeTransaction(pCON); + complete_T4(td); +} + +/** + * Transaction 5 - T5 + * + * Delete session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +void +start_T5(Ndb * pNDB, ThreadData * td, int async){ + + DEBUG3("T5(%.*s, %.2d): - Starting", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + NdbConnection * pCON = 0; + while((pCON = startTransaction(pNDB, td)) == 0){ + CHECK_ALLOWED_ERROR("T5-1: startTransaction", td, pNDB->getNdbError()); + NdbSleep_MilliSleep(10); + } + + NdbOperation * MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOp, "T5-1: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->interpretedUpdateTuple(); + MyOp->equal(IND_SUBSCRIBER_NUMBER, + td->transactionData.number); + MyOp->getValue(IND_SUBSCRIBER_LOCATION, + (char *)&td->transactionData.location); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, + td->transactionData.changed_by); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, + td->transactionData.changed_time); + MyOp->getValue(IND_SUBSCRIBER_GROUP, + (char *)&td->transactionData.group_id); + MyOp->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&td->transactionData.sessions); + MyOp->subValue(IND_SUBSCRIBER_SESSIONS, + (uint32)td->transactionData.server_bit); + stat_async = async; + if (async == 1) { + pCON->executeAsynchPrepare( NoCommit , T5_Callback_1, td); + } else { + int result = pCON->execute( NoCommit ); + T5_Callback_1(result, pCON, (void*)td); + return; + }//if +} + +void +T5_Callback_1(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + if (result == -1) { + CHECK_ALLOWED_ERROR("T5-1: execute", td, pCON->getNdbError()); + td->pNDB->closeTransaction(pCON); + start_T5(td->pNDB, td, stat_async); + return; + }//if + + DEBUG3("T5(%.*s, %.2d): - Callback 1", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + NdbOperation * MyOp = pCON->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOp, "T5-2: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->readTuple(); + MyOp->equal(IND_GROUP_ID, + (char*)&td->transactionData.group_id); + MyOp->getValue(IND_GROUP_ALLOW_DELETE, + (char *)&td->transactionData.permission); + if (stat_async == 1) { + pCON->executeAsynchPrepare( NoCommit , T5_Callback_2, td); + } else { + int result = pCON->execute( NoCommit ); + T5_Callback_2(result, pCON, (void*)td); + return; + }//if +} + +void +T5_Callback_2(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + if (result == -1) { + CHECK_ALLOWED_ERROR("T5-2: execute", td, pCON->getNdbError()); + td->pNDB->closeTransaction(pCON); + start_T5(td->pNDB, td, stat_async); + return; + }//if + + Uint32 permission = td->transactionData.permission; + Uint32 sessions = td->transactionData.sessions; + Uint32 server_bit = td->transactionData.server_bit; + + if(((permission & server_bit) == server_bit) && + ((sessions & server_bit) == server_bit)){ + + memcpy(td->transactionData.suffix, + &td->transactionData.number[SFX_START], + SUBSCRIBER_NUMBER_SUFFIX_LENGTH); + + DEBUG5("T5(%.*s, %.2d): - Callback 2 - deleting(%.*s)", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id, + SUBSCRIBER_NUMBER_SUFFIX_LENGTH, + td->transactionData.suffix); + + /* Operation 3 */ + NdbOperation * MyOp = pCON->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOp, "T5-3: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->deleteTuple(); + MyOp->equal(IND_SESSION_SUBSCRIBER, + (char*)td->transactionData.number); + MyOp->equal(IND_SESSION_SERVER, + (char*)&td->transactionData.server_id); + /* Operation 4 */ + + /* Operation 5 */ + MyOp = pCON->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOp, "T5-5: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->interpretedUpdateTuple(); + MyOp->equal(IND_SERVER_ID, + (char*)&td->transactionData.server_id); + MyOp->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)td->transactionData.suffix); + MyOp->incValue(IND_SERVER_DELETES, (uint32)1); + td->transactionData.branchExecuted = 1; + } else { + td->transactionData.branchExecuted = 0; + + DEBUG5("T5(%.*s, %.2d): - Callback 2 - no delete - %s %s", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id, + ((permission & server_bit) ? + "permission - " : "no permission - "), + ((sessions & server_bit) ? + "in session - " : "no in session - ")); + } + + if(!td->transactionData.do_rollback && td->transactionData.branchExecuted){ + if (stat_async == 1) { + pCON->executeAsynchPrepare( Commit , T5_Callback_3, td); + } else { + int result = pCON->execute( Commit ); + T5_Callback_3(result, pCON, (void*)td); + return; + }//if + } else { + if (stat_async == 1) { + pCON->executeAsynchPrepare( Rollback , T5_Callback_3, td); + } else { + int result = pCON->execute( Rollback ); + T5_Callback_3(result, pCON, (void*)td); + return; + }//if + } +} + +void +T5_Callback_3(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + if (result == -1) { + CHECK_ALLOWED_ERROR("T5-3: Commit", td, pCON->getNdbError()); + td->pNDB->closeTransaction(pCON); + start_T5(td->pNDB, td, stat_async); + return; + }//if + + DEBUG3("T5(%.*s, %.2d): - Completing", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + td->pNDB->closeTransaction(pCON); + complete_T5(td); +} diff --git a/ndb/test/ndbapi/bench/ndb_error.hpp b/ndb/test/ndbapi/bench/ndb_error.hpp new file mode 100644 index 00000000000..d90f5506813 --- /dev/null +++ b/ndb/test/ndbapi/bench/ndb_error.hpp @@ -0,0 +1,81 @@ +/* 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; either version 2 of the License, or + (at your option) any later version. + + 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 */ + +#ifndef NDB_ERROR_H +#define NDB_ERROR_H + +#include +#include +#include "userInterface.h" +#include +#include + +#define error_handler(x,y, z) { \ + ndbout << x << " " << y << endl; \ + exit(-1); } + +#define CHECK_MINUS_ONE(x, y, z) if(x == -1) \ + error_handler(y,(z->getNdbError()), 0) + +inline +void +CHECK_ALLOWED_ERROR(const char * str, + const ThreadData * td, + const struct NdbError & error){ + + char buf[100]; + snprintf(buf, sizeof(buf), "subscriber = %.*s ", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number); + ndbout << str << " " << error << endl + << buf; + showTime(); + + switch(error.classification) { + case NdbError::TimeoutExpired: + case NdbError::OverloadError: + case NdbError::TemporaryResourceError: + case NdbError::NodeRecoveryError: + break; + default: + if(error.status != NdbError::TemporaryError) + exit(-1); + } +} + +inline +void +CHECK_NULL(void * null, + const char * str, + const ThreadData * td, + const struct NdbError & err){ + if(null == 0){ + CHECK_ALLOWED_ERROR(str, td, err); + exit(-1); + } +} + +inline +void +CHECK_NULL(void * null, const char* msg, NdbConnection* obj) +{ + if(null == 0) + { + error_handler(msg, obj->getNdbError(), 0); + } +} + +#endif diff --git a/ndb/test/ndbapi/bench/ndb_schema.hpp b/ndb/test/ndbapi/bench/ndb_schema.hpp new file mode 100644 index 00000000000..af08bc2eecd --- /dev/null +++ b/ndb/test/ndbapi/bench/ndb_schema.hpp @@ -0,0 +1,78 @@ +/* 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; either version 2 of the License, or + (at your option) any later version. + + 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 */ + +#ifndef NDB_SCHEMA_H +#define NDB_SCHEMA_H + +#include "testDefinitions.h" + +#define SUBSCRIBER_TABLE "SUBSCRIBER" +#define SUBSCRIBER_NUMBER "NUMBER" +#define SUBSCRIBER_LOCATION "LOCATION" +#define SUBSCRIBER_NAME "NAME" +#define SUBSCRIBER_GROUP "GROUP_ID" +#define SUBSCRIBER_SESSIONS "SESSIONS" +#define SUBSCRIBER_CHANGED_BY "CHANGED_BY" +#define SUBSCRIBER_CHANGED_TIME "CHANGED_TIME" + +#define SERVER_TABLE "SERVER" +#define SERVER_ID "SERVER_ID" +#define SERVER_SUBSCRIBER_SUFFIX "SUFFIX" +#define SERVER_NAME "NAME" +#define SERVER_READS "NO_OF_READ" +#define SERVER_INSERTS "NO_OF_INSERT" +#define SERVER_DELETES "NO_OF_DELETE" + +#define GROUP_TABLE "GROUP" +#define GROUP_ID "GROUP_ID" +#define GROUP_NAME "GROUP_NAME" +#define GROUP_ALLOW_READ "ALLOW_READ" +#define GROUP_ALLOW_INSERT "ALLOW_INSERT" +#define GROUP_ALLOW_DELETE "ALLOW_DELETE" + +#define SESSION_TABLE "SESSION" +#define SESSION_SERVER "SERVER_ID" +#define SESSION_SUBSCRIBER "NUMBER" +#define SESSION_DATA "DATA" + +/** Numbers */ + +#define IND_SUBSCRIBER_NUMBER (unsigned)0 +#define IND_SUBSCRIBER_NAME (unsigned)1 +#define IND_SUBSCRIBER_GROUP (unsigned)2 +#define IND_SUBSCRIBER_LOCATION (unsigned)3 +#define IND_SUBSCRIBER_SESSIONS (unsigned)4 +#define IND_SUBSCRIBER_CHANGED_BY (unsigned)5 +#define IND_SUBSCRIBER_CHANGED_TIME (unsigned)6 + +#define IND_SERVER_SUBSCRIBER_SUFFIX (unsigned)0 +#define IND_SERVER_ID (unsigned)1 +#define IND_SERVER_NAME (unsigned)2 +#define IND_SERVER_READS (unsigned)3 +#define IND_SERVER_INSERTS (unsigned)4 +#define IND_SERVER_DELETES (unsigned)5 + +#define IND_GROUP_ID (unsigned)0 +#define IND_GROUP_NAME (unsigned)1 +#define IND_GROUP_ALLOW_READ (unsigned)2 +#define IND_GROUP_ALLOW_INSERT (unsigned)3 +#define IND_GROUP_ALLOW_DELETE (unsigned)4 + +#define IND_SESSION_SUBSCRIBER (unsigned)0 +#define IND_SESSION_SERVER (unsigned)1 +#define IND_SESSION_DATA (unsigned)2 + +#endif diff --git a/ndb/test/ndbapi/bench/ndb_user_transaction.cpp b/ndb/test/ndbapi/bench/ndb_user_transaction.cpp new file mode 100644 index 00000000000..182f1f99586 --- /dev/null +++ b/ndb/test/ndbapi/bench/ndb_user_transaction.cpp @@ -0,0 +1,825 @@ +/* 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; either version 2 of the License, or + (at your option) any later version. + + 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 */ + +//#define DEBUG_ON + +extern "C" { +#include "user_transaction.h" +}; + +#include "macros.h" +#include "ndb_schema.hpp" +#include "ndb_error.hpp" + +#include +#include + +/** + * Transaction 1 - T1 + * + * Update location and changed by/time on a subscriber + * + * Input: + * SubscriberNumber, + * Location, + * ChangedBy, + * ChangedTime + * + * Output: + */ +int +T1(void * obj, + const SubscriberNumber number, + const Location new_location, + const ChangedBy changed_by, + const ChangedTime changed_time, + BenchmarkTime * transaction_time){ + + Ndb * pNDB = (Ndb *) obj; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T1: getNdbOperation", MyTransaction); + + check = MyOperation->updateTuple(); + CHECK_MINUS_ONE(check, "T1: updateTuple", + MyTransaction); + + check = MyOperation->equal(SUBSCRIBER_NUMBER, + number); + CHECK_MINUS_ONE(check, "T1: equal subscriber", + MyTransaction); + + check = MyOperation->setValue(SUBSCRIBER_LOCATION, + (char *)&new_location); + CHECK_MINUS_ONE(check, "T1: setValue location", + MyTransaction); + + check = MyOperation->setValue(SUBSCRIBER_CHANGED_BY, + changed_by); + CHECK_MINUS_ONE(check, "T1: setValue changed_by", + MyTransaction); + + check = MyOperation->setValue(SUBSCRIBER_CHANGED_TIME, + changed_time); + CHECK_MINUS_ONE(check, "T1: setValue changed_time", + MyTransaction); + + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T1: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(transaction_time); + time_diff(transaction_time, &start); + return 0; +} + +/** + * Transaction 2 - T2 + * + * Read from Subscriber: + * + * Input: + * SubscriberNumber + * + * Output: + * Location + * Changed by + * Changed Timestamp + * Name + */ +int +T2(void * obj, + const SubscriberNumber number, + Location * readLocation, + ChangedBy changed_by, + ChangedTime changed_time, + SubscriberName subscriberName, + BenchmarkTime * transaction_time){ + + Ndb * pNDB = (Ndb *) obj; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T2: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T2: readTuple", + MyTransaction); + + check = MyOperation->equal(SUBSCRIBER_NUMBER, + number); + CHECK_MINUS_ONE(check, "T2: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_LOCATION, + (char *)readLocation); + CHECK_NULL(check2, "T2: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_CHANGED_BY, + changed_by); + CHECK_NULL(check2, "T2: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_CHANGED_TIME, + changed_time); + CHECK_NULL(check2, "T2: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_NAME, + subscriberName); + CHECK_NULL(check2, "T2: getValue name", + MyTransaction); + + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T2: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(transaction_time); + time_diff(transaction_time, &start); + return 0; +} + +/** + * Transaction 3 - T3 + * + * Read session details + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * + * Output: + * BranchExecuted + * SessionDetails + * ChangedBy + * ChangedTime + * Location + */ +int +T3(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + SessionDetails outSessionDetails, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + Ndb * pNDB = (Ndb *) obj; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T3-1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T3-1: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-1: readTuple", + MyTransaction); + + check = MyOperation->equal(SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T3-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T3-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T3-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T3-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T3-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T3-1: getValue sessions", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T3-2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-2: readTuple", + MyTransaction); + + check = MyOperation->equal(GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T3-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(GROUP_ALLOW_READ, + (char *)&permission); + CHECK_NULL(check2, "T3-2: getValue allow_read", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-2: NoCommit", + MyTransaction); + + DEBUG3("T3(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == inServerBit)){ + + DEBUG("reading - "); + + /* Operation 3 */ + + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T3-3: getNdbOperation", + MyTransaction); + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-3: readTuple", + MyTransaction); + + check = MyOperation->equal(SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T3-3: equal number", + MyTransaction); + + check = MyOperation->equal(SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T3-3: equal server id", + MyTransaction); + + check2 = MyOperation->getValue(SESSION_DATA, + (char *)outSessionDetails); + CHECK_NULL(check2, "T3-3: getValue session details", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-3: NoCommit", + MyTransaction); + + /* Operation 4 */ + + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T3-4: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T3-4: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T3-4: equal serverId", + MyTransaction); + + check = MyOperation->equal(SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T3-4: equal suffix", + MyTransaction); + + check = MyOperation->incValue(SERVER_READS, (uint32)1); + CHECK_MINUS_ONE(check, "T3-4: inc value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-4: NoCommit", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + (* outBranchExecuted) = 0; + } + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T3: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + + +/** + * Transaction 4 - T4 + * + * Create session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * SessionDetails, + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +int +T4(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + const SessionDetails inSessionDetails, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + DoRollback inDoRollback, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + Ndb * pNDB = (Ndb *) obj; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T4-1: startTranscation", pNDB->getNdbErrorString(), 0); + + DEBUG3("T4(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + NdbOperation * MyOperation = 0; + + MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T4-1: getNdbOperation", + MyTransaction); + + check = MyOperation->readTupleExclusive(); + CHECK_MINUS_ONE(check, "T4-1: readTuple", + MyTransaction); + + check = MyOperation->equal(SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T4-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T4-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T4-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T4-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T4-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T4-1: getValue sessions", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T4-2: getNdbOperation", + MyTransaction); + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T4-2: readTuple", + MyTransaction); + + check = MyOperation->equal(GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T4-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(GROUP_ALLOW_INSERT, + (char *)&permission); + CHECK_NULL(check2, "T4-2: getValue allow_insert", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-2: NoCommit", + MyTransaction); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == 0)){ + + DEBUG("inserting - "); + + /* Operation 3 */ + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T4-3: getNdbOperation", + MyTransaction); + + check = MyOperation->insertTuple(); + CHECK_MINUS_ONE(check, "T4-3: insertTuple", + MyTransaction); + + check = MyOperation->equal(SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T4-3: equal number", + MyTransaction); + + check = MyOperation->equal(SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T4-3: equal server id", + MyTransaction); + + check = MyOperation->setValue(SESSION_DATA, + (char *)inSessionDetails); + CHECK_MINUS_ONE(check, "T4-3: setValue session details", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-3: NoCommit", + MyTransaction); + + /* Operation 4 */ + MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T4-4: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T4-4: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(SUBSCRIBER_NUMBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T4-4: equal number", + MyTransaction); + + check = MyOperation->incValue(SUBSCRIBER_SESSIONS, + (uint32)inServerBit); + CHECK_MINUS_ONE(check, "T4-4: inc value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-4: NoCommit", + MyTransaction); + + /* Operation 5 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T4-5: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T4-5: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T4-5: equal serverId", + MyTransaction); + + check = MyOperation->equal(SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T4-5: equal suffix", + MyTransaction); + + check = MyOperation->incValue(SERVER_INSERTS, (uint32)1); + CHECK_MINUS_ONE(check, "T4-5: inc value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-5: NoCommit", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); + DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); + (* outBranchExecuted) = 0; + } + + if(!inDoRollback){ + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T4: Commit", + MyTransaction); + } else { + DEBUG("rollback\n"); + check = MyTransaction->execute(Rollback); + CHECK_MINUS_ONE(check, "T4:Rollback", + MyTransaction); + + } + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + + +/** + * Transaction 5 - T5 + * + * Delete session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +int +T5(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + DoRollback inDoRollback, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + Ndb * pNDB = (Ndb *) obj; + NdbConnection * MyTransaction = 0; + NdbOperation * MyOperation = 0; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T5-1: startTranscation", pNDB->getNdbErrorString(), 0); + + MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T5-1: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTupleExclusive(); + CHECK_MINUS_ONE(check, "T5-1: readTuple", + MyTransaction); + + check = MyOperation->equal(SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T5-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T5-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T5-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T5-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T5-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T5-1: getValue sessions", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T5-2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T5-2: readTuple", + MyTransaction); + + check = MyOperation->equal(GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T5-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(GROUP_ALLOW_DELETE, + (char *)&permission); + CHECK_NULL(check2, "T5-2: getValue allow_delete", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-2: NoCommit", + MyTransaction); + + DEBUG3("T5(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == inServerBit)){ + + DEBUG("deleting - "); + + /* Operation 3 */ + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T5-3: getNdbOperation", + MyTransaction); + + check = MyOperation->deleteTuple(); + CHECK_MINUS_ONE(check, "T5-3: deleteTuple", + MyTransaction); + + check = MyOperation->equal(SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T5-3: equal number", + MyTransaction); + + check = MyOperation->equal(SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T5-3: equal server id", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-3: NoCommit", + MyTransaction); + + /* Operation 4 */ + MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T5-4: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T5-4: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(SUBSCRIBER_NUMBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T5-4: equal number", + MyTransaction); + + check = MyOperation->subValue(SUBSCRIBER_SESSIONS, + (uint32)inServerBit); + CHECK_MINUS_ONE(check, "T5-4: dec value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-4: NoCommit", + MyTransaction); + + /* Operation 5 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T5-5: getNdbOperation", + MyTransaction); + + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T5-5: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T5-5: equal serverId", + MyTransaction); + + check = MyOperation->equal(SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T5-5: equal suffix", + MyTransaction); + + check = MyOperation->incValue(SERVER_DELETES, (uint32)1); + CHECK_MINUS_ONE(check, "T5-5: inc value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-5: NoCommit", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); + DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); + (* outBranchExecuted) = 0; + } + + if(!inDoRollback){ + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T5: Commit", + MyTransaction); + } else { + DEBUG("rollback\n"); + check = MyTransaction->execute(Rollback); + CHECK_MINUS_ONE(check, "T5:Rollback", + MyTransaction); + + } + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + diff --git a/ndb/test/ndbapi/bench/ndb_user_transaction2.cpp b/ndb/test/ndbapi/bench/ndb_user_transaction2.cpp new file mode 100644 index 00000000000..df3c7a7989e --- /dev/null +++ b/ndb/test/ndbapi/bench/ndb_user_transaction2.cpp @@ -0,0 +1,825 @@ +/* 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; either version 2 of the License, or + (at your option) any later version. + + 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 */ + +//#define DEBUG_ON + +extern "C" { +#include "user_transaction.h" +}; + +#include "macros.h" +#include "ndb_schema.hpp" +#include "ndb_error.hpp" + +#include +#include + +/** + * Transaction 1 - T1 + * + * Update location and changed by/time on a subscriber + * + * Input: + * SubscriberNumber, + * Location, + * ChangedBy, + * ChangedTime + * + * Output: + */ +int +T1(void * obj, + const SubscriberNumber number, + const Location new_location, + const ChangedBy changed_by, + const ChangedTime changed_time, + BenchmarkTime * transaction_time){ + + Ndb * pNDB = (Ndb *) obj; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T1: getNdbOperation", MyTransaction); + + check = MyOperation->updateTuple(); + CHECK_MINUS_ONE(check, "T1: updateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + number); + CHECK_MINUS_ONE(check, "T1: equal subscriber", + MyTransaction); + + check = MyOperation->setValue(IND_SUBSCRIBER_LOCATION, + (char *)&new_location); + CHECK_MINUS_ONE(check, "T1: setValue location", + MyTransaction); + + check = MyOperation->setValue(IND_SUBSCRIBER_CHANGED_BY, + changed_by); + CHECK_MINUS_ONE(check, "T1: setValue changed_by", + MyTransaction); + + check = MyOperation->setValue(IND_SUBSCRIBER_CHANGED_TIME, + changed_time); + CHECK_MINUS_ONE(check, "T1: setValue changed_time", + MyTransaction); + + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T1: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(transaction_time); + time_diff(transaction_time, &start); + return 0; +} + +/** + * Transaction 2 - T2 + * + * Read from Subscriber: + * + * Input: + * SubscriberNumber + * + * Output: + * Location + * Changed by + * Changed Timestamp + * Name + */ +int +T2(void * obj, + const SubscriberNumber number, + Location * readLocation, + ChangedBy changed_by, + ChangedTime changed_time, + SubscriberName subscriberName, + BenchmarkTime * transaction_time){ + + Ndb * pNDB = (Ndb *) obj; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T2: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + number); + CHECK_MINUS_ONE(check, "T2: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)readLocation); + CHECK_NULL(check2, "T2: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + changed_by); + CHECK_NULL(check2, "T2: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + changed_time); + CHECK_NULL(check2, "T2: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_NAME, + subscriberName); + CHECK_NULL(check2, "T2: getValue name", + MyTransaction); + + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T2: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(transaction_time); + time_diff(transaction_time, &start); + return 0; +} + +/** + * Transaction 3 - T3 + * + * Read session details + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * + * Output: + * BranchExecuted + * SessionDetails + * ChangedBy + * ChangedTime + * Location + */ +int +T3(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + SessionDetails outSessionDetails, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + Ndb * pNDB = (Ndb *) obj; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T3-1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T3-1: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-1: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T3-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T3-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T3-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T3-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T3-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T3-1: getValue sessions", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T3-2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T3-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(IND_GROUP_ALLOW_READ, + (char *)&permission); + CHECK_NULL(check2, "T3-2: getValue allow_read", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-2: NoCommit", + MyTransaction); + + DEBUG3("T3(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == inServerBit)){ + + DEBUG("reading - "); + + /* Operation 3 */ + + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T3-3: getNdbOperation", + MyTransaction); + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-3: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T3-3: equal number", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T3-3: equal server id", + MyTransaction); + + check2 = MyOperation->getValue(IND_SESSION_DATA, + (char *)outSessionDetails); + CHECK_NULL(check2, "T3-3: getValue session details", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-3: NoCommit", + MyTransaction); + + /* Operation 4 */ + + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T3-4: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T3-4: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T3-4: equal serverId", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T3-4: equal suffix", + MyTransaction); + + check = MyOperation->incValue(IND_SERVER_READS, (uint32)1); + CHECK_MINUS_ONE(check, "T3-4: inc value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-4: NoCommit", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + (* outBranchExecuted) = 0; + } + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T3: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + + +/** + * Transaction 4 - T4 + * + * Create session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * SessionDetails, + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +int +T4(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + const SessionDetails inSessionDetails, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + DoRollback inDoRollback, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + Ndb * pNDB = (Ndb *) obj; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T4-1: startTranscation", pNDB->getNdbErrorString(), 0); + + DEBUG3("T4(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + NdbOperation * MyOperation = 0; + + MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T4-1: getNdbOperation", + MyTransaction); + + check = MyOperation->readTupleExclusive(); + CHECK_MINUS_ONE(check, "T4-1: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T4-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T4-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T4-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T4-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T4-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T4-1: getValue sessions", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T4-2: getNdbOperation", + MyTransaction); + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T4-2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T4-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(IND_GROUP_ALLOW_INSERT, + (char *)&permission); + CHECK_NULL(check2, "T4-2: getValue allow_insert", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-2: NoCommit", + MyTransaction); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == 0)){ + + DEBUG("inserting - "); + + /* Operation 3 */ + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T4-3: getNdbOperation", + MyTransaction); + + check = MyOperation->insertTuple(); + CHECK_MINUS_ONE(check, "T4-3: insertTuple", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T4-3: equal number", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T4-3: equal server id", + MyTransaction); + + check = MyOperation->setValue(SESSION_DATA, + (char *)inSessionDetails); + CHECK_MINUS_ONE(check, "T4-3: setValue session details", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-3: NoCommit", + MyTransaction); + + /* Operation 4 */ + MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T4-4: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T4-4: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T4-4: equal number", + MyTransaction); + + check = MyOperation->incValue(IND_SUBSCRIBER_SESSIONS, + (uint32)inServerBit); + CHECK_MINUS_ONE(check, "T4-4: inc value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-4: NoCommit", + MyTransaction); + + /* Operation 5 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T4-5: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T4-5: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T4-5: equal serverId", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T4-5: equal suffix", + MyTransaction); + + check = MyOperation->incValue(IND_SERVER_INSERTS, (uint32)1); + CHECK_MINUS_ONE(check, "T4-5: inc value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-5: NoCommit", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); + DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); + (* outBranchExecuted) = 0; + } + + if(!inDoRollback){ + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T4: Commit", + MyTransaction); + } else { + DEBUG("rollback\n"); + check = MyTransaction->execute(Rollback); + CHECK_MINUS_ONE(check, "T4:Rollback", + MyTransaction); + + } + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + + +/** + * Transaction 5 - T5 + * + * Delete session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +int +T5(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + DoRollback inDoRollback, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + Ndb * pNDB = (Ndb *) obj; + NdbConnection * MyTransaction = 0; + NdbOperation * MyOperation = 0; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T5-1: startTranscation", pNDB->getNdbErrorString(), 0); + + MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T5-1: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTupleExclusive(); + CHECK_MINUS_ONE(check, "T5-1: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T5-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T5-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T5-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T5-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T5-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T5-1: getValue sessions", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T5-2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T5-2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T5-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(IND_GROUP_ALLOW_DELETE, + (char *)&permission); + CHECK_NULL(check2, "T5-2: getValue allow_delete", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-2: NoCommit", + MyTransaction); + + DEBUG3("T5(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == inServerBit)){ + + DEBUG("deleting - "); + + /* Operation 3 */ + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T5-3: getNdbOperation", + MyTransaction); + + check = MyOperation->deleteTuple(); + CHECK_MINUS_ONE(check, "T5-3: deleteTuple", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T5-3: equal number", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T5-3: equal server id", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-3: NoCommit", + MyTransaction); + + /* Operation 4 */ + MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T5-4: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T5-4: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T5-4: equal number", + MyTransaction); + + check = MyOperation->subValue(IND_SUBSCRIBER_SESSIONS, + (uint32)inServerBit); + CHECK_MINUS_ONE(check, "T5-4: dec value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-4: NoCommit", + MyTransaction); + + /* Operation 5 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T5-5: getNdbOperation", + MyTransaction); + + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T5-5: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T5-5: equal serverId", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T5-5: equal suffix", + MyTransaction); + + check = MyOperation->incValue(IND_SERVER_DELETES, (uint32)1); + CHECK_MINUS_ONE(check, "T5-5: inc value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-5: NoCommit", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); + DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); + (* outBranchExecuted) = 0; + } + + if(!inDoRollback){ + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T5: Commit", + MyTransaction); + } else { + DEBUG("rollback\n"); + check = MyTransaction->execute(Rollback); + CHECK_MINUS_ONE(check, "T5:Rollback", + MyTransaction); + + } + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + diff --git a/ndb/test/ndbapi/bench/ndb_user_transaction3.cpp b/ndb/test/ndbapi/bench/ndb_user_transaction3.cpp new file mode 100644 index 00000000000..d2c92ecd424 --- /dev/null +++ b/ndb/test/ndbapi/bench/ndb_user_transaction3.cpp @@ -0,0 +1,793 @@ +/* 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; either version 2 of the License, or + (at your option) any later version. + + 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 */ + +//#define DEBUG_ON + +extern "C" { +#include "user_transaction.h" +}; + +#include "macros.h" +#include "ndb_schema.hpp" +#include "ndb_error.hpp" + +#include +#include + +/** + * Transaction 1 - T1 + * + * Update location and changed by/time on a subscriber + * + * Input: + * SubscriberNumber, + * Location, + * ChangedBy, + * ChangedTime + * + * Output: + */ +int +T1(void * obj, + const SubscriberNumber number, + const Location new_location, + const ChangedBy changed_by, + const ChangedTime changed_time, + BenchmarkTime * transaction_time){ + + Ndb * pNDB = (Ndb *) obj; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T1: getNdbOperation", MyTransaction); + + check = MyOperation->updateTuple(); + CHECK_MINUS_ONE(check, "T1: updateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + number); + CHECK_MINUS_ONE(check, "T1: equal subscriber", + MyTransaction); + + check = MyOperation->setValue(IND_SUBSCRIBER_LOCATION, + (char *)&new_location); + CHECK_MINUS_ONE(check, "T1: setValue location", + MyTransaction); + + check = MyOperation->setValue(IND_SUBSCRIBER_CHANGED_BY, + changed_by); + CHECK_MINUS_ONE(check, "T1: setValue changed_by", + MyTransaction); + + check = MyOperation->setValue(IND_SUBSCRIBER_CHANGED_TIME, + changed_time); + CHECK_MINUS_ONE(check, "T1: setValue changed_time", + MyTransaction); + + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T1: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(transaction_time); + time_diff(transaction_time, &start); + return 0; +} + +/** + * Transaction 2 - T2 + * + * Read from Subscriber: + * + * Input: + * SubscriberNumber + * + * Output: + * Location + * Changed by + * Changed Timestamp + * Name + */ +int +T2(void * obj, + const SubscriberNumber number, + Location * readLocation, + ChangedBy changed_by, + ChangedTime changed_time, + SubscriberName subscriberName, + BenchmarkTime * transaction_time){ + + Ndb * pNDB = (Ndb *) obj; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T2: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + number); + CHECK_MINUS_ONE(check, "T2: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)readLocation); + CHECK_NULL(check2, "T2: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + changed_by); + CHECK_NULL(check2, "T2: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + changed_time); + CHECK_NULL(check2, "T2: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_NAME, + subscriberName); + CHECK_NULL(check2, "T2: getValue name", + MyTransaction); + + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T2: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(transaction_time); + time_diff(transaction_time, &start); + return 0; +} + +/** + * Transaction 3 - T3 + * + * Read session details + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * + * Output: + * BranchExecuted + * SessionDetails + * ChangedBy + * ChangedTime + * Location + */ +int +T3(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + SessionDetails outSessionDetails, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + Ndb * pNDB = (Ndb *) obj; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T3-1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T3-1: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-1: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T3-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T3-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T3-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T3-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T3-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T3-1: getValue sessions", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T3-2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T3-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(IND_GROUP_ALLOW_READ, + (char *)&permission); + CHECK_NULL(check2, "T3-2: getValue allow_read", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-2: NoCommit", + MyTransaction); + + DEBUG3("T3(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == inServerBit)){ + + DEBUG("reading - "); + + /* Operation 3 */ + + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T3-3: getNdbOperation", + MyTransaction); + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-3: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T3-3: equal number", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T3-3: equal server id", + MyTransaction); + + check2 = MyOperation->getValue(IND_SESSION_DATA, + (char *)outSessionDetails); + CHECK_NULL(check2, "T3-3: getValue session details", + MyTransaction); + + /* Operation 4 */ + + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T3-4: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T3-4: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T3-4: equal serverId", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T3-4: equal suffix", + MyTransaction); + + check = MyOperation->incValue(IND_SERVER_READS, (uint32)1); + CHECK_MINUS_ONE(check, "T3-4: inc value", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + (* outBranchExecuted) = 0; + } + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T3: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + + +/** + * Transaction 4 - T4 + * + * Create session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * SessionDetails, + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +int +T4(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + const SessionDetails inSessionDetails, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + DoRollback inDoRollback, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + Ndb * pNDB = (Ndb *) obj; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T4-1: startTranscation", pNDB->getNdbErrorString(), 0); + + DEBUG3("T4(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + NdbOperation * MyOperation = 0; + + MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T4-1: getNdbOperation", + MyTransaction); + + check = MyOperation->readTupleExclusive(); + CHECK_MINUS_ONE(check, "T4-1: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T4-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T4-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T4-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T4-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T4-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T4-1: getValue sessions", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T4-2: getNdbOperation", + MyTransaction); + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T4-2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T4-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(IND_GROUP_ALLOW_INSERT, + (char *)&permission); + CHECK_NULL(check2, "T4-2: getValue allow_insert", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-2: NoCommit", + MyTransaction); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == 0)){ + + DEBUG("inserting - "); + + /* Operation 3 */ + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T4-3: getNdbOperation", + MyTransaction); + + check = MyOperation->insertTuple(); + CHECK_MINUS_ONE(check, "T4-3: insertTuple", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T4-3: equal number", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T4-3: equal server id", + MyTransaction); + + check = MyOperation->setValue(SESSION_DATA, + (char *)inSessionDetails); + CHECK_MINUS_ONE(check, "T4-3: setValue session details", + MyTransaction); + + /* Operation 4 */ + MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T4-4: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T4-4: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T4-4: equal number", + MyTransaction); + + check = MyOperation->incValue(IND_SUBSCRIBER_SESSIONS, + (uint32)inServerBit); + CHECK_MINUS_ONE(check, "T4-4: inc value", + MyTransaction); + + /* Operation 5 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T4-5: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T4-5: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T4-5: equal serverId", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T4-5: equal suffix", + MyTransaction); + + check = MyOperation->incValue(IND_SERVER_INSERTS, (uint32)1); + CHECK_MINUS_ONE(check, "T4-5: inc value", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); + DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); + (* outBranchExecuted) = 0; + } + + if(!inDoRollback){ + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T4: Commit", + MyTransaction); + } else { + DEBUG("rollback\n"); + check = MyTransaction->execute(Rollback); + CHECK_MINUS_ONE(check, "T4:Rollback", + MyTransaction); + + } + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + + +/** + * Transaction 5 - T5 + * + * Delete session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +int +T5(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + DoRollback inDoRollback, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + Ndb * pNDB = (Ndb *) obj; + NdbConnection * MyTransaction = 0; + NdbOperation * MyOperation = 0; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T5-1: startTranscation", pNDB->getNdbErrorString(), 0); + + MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T5-1: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTupleExclusive(); + CHECK_MINUS_ONE(check, "T5-1: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T5-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T5-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T5-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T5-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T5-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T5-1: getValue sessions", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T5-2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T5-2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T5-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(IND_GROUP_ALLOW_DELETE, + (char *)&permission); + CHECK_NULL(check2, "T5-2: getValue allow_delete", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-2: NoCommit", + MyTransaction); + + DEBUG3("T5(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == inServerBit)){ + + DEBUG("deleting - "); + + /* Operation 3 */ + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T5-3: getNdbOperation", + MyTransaction); + + check = MyOperation->deleteTuple(); + CHECK_MINUS_ONE(check, "T5-3: deleteTuple", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T5-3: equal number", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T5-3: equal server id", + MyTransaction); + + /* Operation 4 */ + MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T5-4: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T5-4: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T5-4: equal number", + MyTransaction); + + check = MyOperation->subValue(IND_SUBSCRIBER_SESSIONS, + (uint32)inServerBit); + CHECK_MINUS_ONE(check, "T5-4: dec value", + MyTransaction); + + /* Operation 5 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T5-5: getNdbOperation", + MyTransaction); + + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T5-5: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T5-5: equal serverId", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T5-5: equal suffix", + MyTransaction); + + check = MyOperation->incValue(IND_SERVER_DELETES, (uint32)1); + CHECK_MINUS_ONE(check, "T5-5: inc value", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); + DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); + (* outBranchExecuted) = 0; + } + + if(!inDoRollback){ + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T5: Commit", + MyTransaction); + } else { + DEBUG("rollback\n"); + check = MyTransaction->execute(Rollback); + CHECK_MINUS_ONE(check, "T5:Rollback", + MyTransaction); + + } + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + diff --git a/ndb/test/ndbapi/bench/ndb_user_transaction4.cpp b/ndb/test/ndbapi/bench/ndb_user_transaction4.cpp new file mode 100644 index 00000000000..e652c7bfed8 --- /dev/null +++ b/ndb/test/ndbapi/bench/ndb_user_transaction4.cpp @@ -0,0 +1,770 @@ +/* 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; either version 2 of the License, or + (at your option) any later version. + + 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 */ + +//#define DEBUG_ON + +extern "C" { +#include "user_transaction.h" +}; + +#include "macros.h" +#include "ndb_schema.hpp" +#include "ndb_error.hpp" + +#include +#include + +/** + * Transaction 1 - T1 + * + * Update location and changed by/time on a subscriber + * + * Input: + * SubscriberNumber, + * Location, + * ChangedBy, + * ChangedTime + * + * Output: + */ +int +T1(void * obj, + const SubscriberNumber number, + const Location new_location, + const ChangedBy changed_by, + const ChangedTime changed_time, + BenchmarkTime * transaction_time){ + + Ndb * pNDB = (Ndb *) obj; + + DEBUG2("T1(%.*s):\n", SUBSCRIBER_NUMBER_LENGTH, number); + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T1-1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T1: getNdbOperation", MyTransaction); + + check = MyOperation->updateTuple(); + CHECK_MINUS_ONE(check, "T1: updateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + number); + CHECK_MINUS_ONE(check, "T1: equal subscriber", + MyTransaction); + + check = MyOperation->setValue(IND_SUBSCRIBER_LOCATION, + (char *)&new_location); + CHECK_MINUS_ONE(check, "T1: setValue location", + MyTransaction); + + check = MyOperation->setValue(IND_SUBSCRIBER_CHANGED_BY, + changed_by); + CHECK_MINUS_ONE(check, "T1: setValue changed_by", + MyTransaction); + + check = MyOperation->setValue(IND_SUBSCRIBER_CHANGED_TIME, + changed_time); + CHECK_MINUS_ONE(check, "T1: setValue changed_time", + MyTransaction); + + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T1: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(transaction_time); + time_diff(transaction_time, &start); + return 0; +} + +/** + * Transaction 2 - T2 + * + * Read from Subscriber: + * + * Input: + * SubscriberNumber + * + * Output: + * Location + * Changed by + * Changed Timestamp + * Name + */ +int +T2(void * obj, + const SubscriberNumber number, + Location * readLocation, + ChangedBy changed_by, + ChangedTime changed_time, + SubscriberName subscriberName, + BenchmarkTime * transaction_time){ + + Ndb * pNDB = (Ndb *) obj; + + DEBUG2("T2(%.*s):\n", SUBSCRIBER_NUMBER_LENGTH, number); + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T2-1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + number); + CHECK_MINUS_ONE(check, "T2: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)readLocation); + CHECK_NULL(check2, "T2: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + changed_by); + CHECK_NULL(check2, "T2: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + changed_time); + CHECK_NULL(check2, "T2: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_NAME, + subscriberName); + CHECK_NULL(check2, "T2: getValue name", + MyTransaction); + + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T2: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(transaction_time); + time_diff(transaction_time, &start); + return 0; +} + +/** + * Transaction 3 - T3 + * + * Read session details + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * + * Output: + * BranchExecuted + * SessionDetails + * ChangedBy + * ChangedTime + * Location + */ +int +T3(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + SessionDetails outSessionDetails, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + DEBUG3("T3(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + Ndb * pNDB = (Ndb *) obj; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T3-1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T3-1: getNdbOperation", + MyTransaction); + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-1: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T3-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T3-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T3-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T3-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T3-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T3-1: getValue sessions", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T3-2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T3-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(IND_GROUP_ALLOW_READ, + (char *)&permission); + CHECK_NULL(check2, "T3-2: getValue allow_read", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-2: NoCommit", + MyTransaction); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == inServerBit)){ + + DEBUG("reading - "); + + /* Operation 3 */ + + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T3-3: getNdbOperation", + MyTransaction); + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-3: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T3-3: equal number", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T3-3: equal server id", + MyTransaction); + + check2 = MyOperation->getValue(IND_SESSION_DATA, + (char *)outSessionDetails); + CHECK_NULL(check2, "T3-3: getValue session details", + MyTransaction); + + /* Operation 4 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T3-4: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T3-4: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T3-4: equal serverId", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T3-4: equal suffix", + MyTransaction); + + check = MyOperation->incValue(IND_SERVER_READS, (uint32)1); + CHECK_MINUS_ONE(check, "T3-4: inc value", + MyTransaction); + (* outBranchExecuted) = 1; + } else { + (* outBranchExecuted) = 0; + } + DEBUG("commit..."); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T3: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + DEBUG("done\n"); + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + + +/** + * Transaction 4 - T4 + * + * Create session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * SessionDetails, + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +int +T4(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + const SessionDetails inSessionDetails, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + DoRollback inDoRollback, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + DEBUG3("T4(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + Ndb * pNDB = (Ndb *) obj; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T4-1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T4-1: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T4-1: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T4-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T4-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T4-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T4-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T4-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T4-1: getValue sessions", + MyTransaction); + + check = MyOperation->incValue(IND_SUBSCRIBER_SESSIONS, + (uint32)inServerBit); + CHECK_MINUS_ONE(check, "T4-4: inc value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T4-2: getNdbOperation", + MyTransaction); + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T4-2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T4-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(IND_GROUP_ALLOW_INSERT, + (char *)&permission); + CHECK_NULL(check2, "T4-2: getValue allow_insert", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-2: NoCommit", + MyTransaction); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == 0)){ + + DEBUG("inserting - "); + + /* Operation 3 */ + + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T4-3: getNdbOperation", + MyTransaction); + + check = MyOperation->insertTuple(); + CHECK_MINUS_ONE(check, "T4-3: insertTuple", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T4-3: equal number", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T4-3: equal server id", + MyTransaction); + + check = MyOperation->setValue(SESSION_DATA, + (char *)inSessionDetails); + CHECK_MINUS_ONE(check, "T4-3: setValue session details", + MyTransaction); + + /* Operation 4 */ + + /* Operation 5 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T4-5: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T4-5: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T4-5: equal serverId", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T4-5: equal suffix", + MyTransaction); + + check = MyOperation->incValue(IND_SERVER_INSERTS, (uint32)1); + CHECK_MINUS_ONE(check, "T4-5: inc value", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); + DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); + (* outBranchExecuted) = 0; + } + + if(!inDoRollback && (* outBranchExecuted)){ + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T4: Commit", + MyTransaction); + } else { + DEBUG("rollback\n"); + check = MyTransaction->execute(Rollback); + CHECK_MINUS_ONE(check, "T4:Rollback", + MyTransaction); + + } + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + + +/** + * Transaction 5 - T5 + * + * Delete session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +int +T5(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + DoRollback inDoRollback, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + DEBUG3("T5(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + Ndb * pNDB = (Ndb *) obj; + NdbConnection * MyTransaction = 0; + NdbOperation * MyOperation = 0; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T5-1: startTranscation", pNDB->getNdbErrorString(), 0); + + MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T5-1: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T5-1: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T5-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T5-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T5-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T5-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T5-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T5-1: getValue sessions", + MyTransaction); + + check = MyOperation->subValue(IND_SUBSCRIBER_SESSIONS, + (uint32)inServerBit); + CHECK_MINUS_ONE(check, "T5-4: dec value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T5-2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T5-2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T5-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(IND_GROUP_ALLOW_DELETE, + (char *)&permission); + CHECK_NULL(check2, "T5-2: getValue allow_delete", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-2: NoCommit", + MyTransaction); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == inServerBit)){ + + DEBUG("deleting - "); + + /* Operation 3 */ + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T5-3: getNdbOperation", + MyTransaction); + + check = MyOperation->deleteTuple(); + CHECK_MINUS_ONE(check, "T5-3: deleteTuple", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T5-3: equal number", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T5-3: equal server id", + MyTransaction); + + /* Operation 4 */ + + /* Operation 5 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T5-5: getNdbOperation", + MyTransaction); + + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T5-5: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T5-5: equal serverId", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T5-5: equal suffix", + MyTransaction); + + check = MyOperation->incValue(IND_SERVER_DELETES, (uint32)1); + CHECK_MINUS_ONE(check, "T5-5: inc value", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); + DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); + (* outBranchExecuted) = 0; + } + + if(!inDoRollback && (* outBranchExecuted)){ + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T5: Commit", + MyTransaction); + } else { + DEBUG("rollback\n"); + check = MyTransaction->execute(Rollback); + CHECK_MINUS_ONE(check, "T5:Rollback", + MyTransaction); + + } + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + diff --git a/ndb/test/ndbapi/bench/ndb_user_transaction5.cpp b/ndb/test/ndbapi/bench/ndb_user_transaction5.cpp new file mode 100644 index 00000000000..86580008d10 --- /dev/null +++ b/ndb/test/ndbapi/bench/ndb_user_transaction5.cpp @@ -0,0 +1,769 @@ +/* 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; either version 2 of the License, or + (at your option) any later version. + + 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 */ + +//#define DEBUG_ON + +extern "C" { +#include "user_transaction.h" +}; + +#include "macros.h" +#include "ndb_schema.hpp" +#include "ndb_error.hpp" + +#include +#include + +/** + * Transaction 1 - T1 + * + * Update location and changed by/time on a subscriber + * + * Input: + * SubscriberNumber, + * Location, + * ChangedBy, + * ChangedTime + * + * Output: + */ +int +T1(void * obj, + const SubscriberNumber number, + const Location new_location, + const ChangedBy changed_by, + const ChangedTime changed_time, + BenchmarkTime * transaction_time){ + + Ndb * pNDB = (Ndb *) obj; + + DEBUG2("T1(%.*s):\n", SUBSCRIBER_NUMBER_LENGTH, number); + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T1-1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T1: getNdbOperation", MyTransaction); + + check = MyOperation->updateTuple(); + CHECK_MINUS_ONE(check, "T1: updateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + number); + CHECK_MINUS_ONE(check, "T1: equal subscriber", + MyTransaction); + + check = MyOperation->setValue(IND_SUBSCRIBER_LOCATION, + (char *)&new_location); + CHECK_MINUS_ONE(check, "T1: setValue location", + MyTransaction); + + check = MyOperation->setValue(IND_SUBSCRIBER_CHANGED_BY, + changed_by); + CHECK_MINUS_ONE(check, "T1: setValue changed_by", + MyTransaction); + + check = MyOperation->setValue(IND_SUBSCRIBER_CHANGED_TIME, + changed_time); + CHECK_MINUS_ONE(check, "T1: setValue changed_time", + MyTransaction); + + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T1: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(transaction_time); + time_diff(transaction_time, &start); + return 0; +} + +/** + * Transaction 2 - T2 + * + * Read from Subscriber: + * + * Input: + * SubscriberNumber + * + * Output: + * Location + * Changed by + * Changed Timestamp + * Name + */ +int +T2(void * obj, + const SubscriberNumber number, + Location * readLocation, + ChangedBy changed_by, + ChangedTime changed_time, + SubscriberName subscriberName, + BenchmarkTime * transaction_time){ + + Ndb * pNDB = (Ndb *) obj; + + DEBUG2("T2(%.*s):\n", SUBSCRIBER_NUMBER_LENGTH, number); + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T2-1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + number); + CHECK_MINUS_ONE(check, "T2: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)readLocation); + CHECK_NULL(check2, "T2: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + changed_by); + CHECK_NULL(check2, "T2: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + changed_time); + CHECK_NULL(check2, "T2: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_NAME, + subscriberName); + CHECK_NULL(check2, "T2: getValue name", + MyTransaction); + + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T2: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(transaction_time); + time_diff(transaction_time, &start); + return 0; +} + +/** + * Transaction 3 - T3 + * + * Read session details + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * + * Output: + * BranchExecuted + * SessionDetails + * ChangedBy + * ChangedTime + * Location + */ +int +T3(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + SessionDetails outSessionDetails, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + Ndb * pNDB = (Ndb *) obj; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T3-1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T3-1: getNdbOperation", + MyTransaction); + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-1: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T3-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T3-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T3-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T3-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T3-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T3-1: getValue sessions", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T3-2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T3-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(IND_GROUP_ALLOW_READ, + (char *)&permission); + CHECK_NULL(check2, "T3-2: getValue allow_read", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-2: NoCommit", + MyTransaction); + + DEBUG3("T3(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == inServerBit)){ + + DEBUG("reading - "); + + /* Operation 3 */ + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T3-3: getNdbOperation", + MyTransaction); + + check = MyOperation->simpleRead(); + CHECK_MINUS_ONE(check, "T3-3: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T3-3: equal number", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T3-3: equal server id", + MyTransaction); + + check2 = MyOperation->getValue(IND_SESSION_DATA, + (char *)outSessionDetails); + CHECK_NULL(check2, "T3-3: getValue session details", + MyTransaction); + + /* Operation 4 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T3-4: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T3-4: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T3-4: equal serverId", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T3-4: equal suffix", + MyTransaction); + + check = MyOperation->incValue(IND_SERVER_READS, (uint32)1); + CHECK_MINUS_ONE(check, "T3-4: inc value", + MyTransaction); + (* outBranchExecuted) = 1; + } else { + (* outBranchExecuted) = 0; + } + DEBUG("commit..."); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T3: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + DEBUG("done\n"); + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + + +/** + * Transaction 4 - T4 + * + * Create session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * SessionDetails, + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +int +T4(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + const SessionDetails inSessionDetails, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + DoRollback inDoRollback, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + Ndb * pNDB = (Ndb *) obj; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T4-1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T4-1: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T4-1: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T4-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T4-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T4-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T4-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T4-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T4-1: getValue sessions", + MyTransaction); + + check = MyOperation->incValue(IND_SUBSCRIBER_SESSIONS, + (uint32)inServerBit); + CHECK_MINUS_ONE(check, "T4-4: inc value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T4-2: getNdbOperation", + MyTransaction); + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T4-2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T4-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(IND_GROUP_ALLOW_INSERT, + (char *)&permission); + CHECK_NULL(check2, "T4-2: getValue allow_insert", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-2: NoCommit", + MyTransaction); + + DEBUG3("T4(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == 0)){ + + DEBUG("inserting - "); + + /* Operation 3 */ + + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T4-3: getNdbOperation", + MyTransaction); + + check = MyOperation->insertTuple(); + CHECK_MINUS_ONE(check, "T4-3: insertTuple", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T4-3: equal number", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T4-3: equal server id", + MyTransaction); + + check = MyOperation->setValue(SESSION_DATA, + (char *)inSessionDetails); + CHECK_MINUS_ONE(check, "T4-3: setValue session details", + MyTransaction); + + /* Operation 4 */ + + /* Operation 5 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T4-5: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T4-5: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T4-5: equal serverId", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T4-5: equal suffix", + MyTransaction); + + check = MyOperation->incValue(IND_SERVER_INSERTS, (uint32)1); + CHECK_MINUS_ONE(check, "T4-5: inc value", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); + DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); + (* outBranchExecuted) = 0; + } + + if(!inDoRollback && (* outBranchExecuted)){ + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T4: Commit", + MyTransaction); + } else { + DEBUG("rollback\n"); + check = MyTransaction->execute(Rollback); + CHECK_MINUS_ONE(check, "T4:Rollback", + MyTransaction); + + } + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + + +/** + * Transaction 5 - T5 + * + * Delete session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +int +T5(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + DoRollback inDoRollback, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + Ndb * pNDB = (Ndb *) obj; + NdbConnection * MyTransaction = 0; + NdbOperation * MyOperation = 0; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T5-1: startTranscation", pNDB->getNdbErrorString(), 0); + + MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T5-1: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T5-1: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T5-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T5-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T5-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T5-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T5-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T5-1: getValue sessions", + MyTransaction); + + check = MyOperation->subValue(IND_SUBSCRIBER_SESSIONS, + (uint32)inServerBit); + CHECK_MINUS_ONE(check, "T5-4: dec value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T5-2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T5-2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T5-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(IND_GROUP_ALLOW_DELETE, + (char *)&permission); + CHECK_NULL(check2, "T5-2: getValue allow_delete", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-2: NoCommit", + MyTransaction); + + DEBUG3("T5(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == inServerBit)){ + + DEBUG("deleting - "); + + /* Operation 3 */ + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T5-3: getNdbOperation", + MyTransaction); + + check = MyOperation->deleteTuple(); + CHECK_MINUS_ONE(check, "T5-3: deleteTuple", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T5-3: equal number", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T5-3: equal server id", + MyTransaction); + + /* Operation 4 */ + + /* Operation 5 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T5-5: getNdbOperation", + MyTransaction); + + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T5-5: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T5-5: equal serverId", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T5-5: equal suffix", + MyTransaction); + + check = MyOperation->incValue(IND_SERVER_DELETES, (uint32)1); + CHECK_MINUS_ONE(check, "T5-5: inc value", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); + DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); + (* outBranchExecuted) = 0; + } + + if(!inDoRollback && (* outBranchExecuted)){ + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T5: Commit", + MyTransaction); + } else { + DEBUG("rollback\n"); + check = MyTransaction->execute(Rollback); + CHECK_MINUS_ONE(check, "T5:Rollback", + MyTransaction); + + } + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + diff --git a/ndb/test/ndbapi/bench/ndb_user_transaction6.cpp b/ndb/test/ndbapi/bench/ndb_user_transaction6.cpp new file mode 100644 index 00000000000..262f38e9ffb --- /dev/null +++ b/ndb/test/ndbapi/bench/ndb_user_transaction6.cpp @@ -0,0 +1,561 @@ +/* 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; either version 2 of the License, or + (at your option) any later version. + + 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 */ + +//#define DEBUG_ON + +#include +#include "userHandle.h" +#include "userInterface.h" + +#include "macros.h" +#include "ndb_schema.hpp" +#include "ndb_error.hpp" + +#include + + +void +userCheckpoint(UserHandle *uh){ +} + +inline +NdbConnection * +startTransaction(Ndb * pNDB, ServerId inServerId, const SubscriberNumber inNumber){ + + const int keyDataLenBytes = sizeof(ServerId)+SUBSCRIBER_NUMBER_LENGTH; + const int keyDataLen_64Words = keyDataLenBytes >> 3; + + Uint64 keyDataBuf[keyDataLen_64Words+1]; // The "+1" is for rounding... + + char * keyDataBuf_charP = (char *)&keyDataBuf[0]; + Uint32 * keyDataBuf_wo32P = (Uint32 *)&keyDataBuf[0]; + + // Server Id comes first + keyDataBuf_wo32P[0] = inServerId; + // Then subscriber number + memcpy(&keyDataBuf_charP[sizeof(ServerId)], inNumber, SUBSCRIBER_NUMBER_LENGTH); + + return pNDB->startTransaction(0, keyDataBuf_charP, keyDataLenBytes); +} + +/** + * Transaction 1 - T1 + * + * Update location and changed by/time on a subscriber + * + * Input: + * SubscriberNumber, + * Location, + * ChangedBy, + * ChangedTime + * + * Output: + */ +void +userTransaction_T1(UserHandle * uh, + SubscriberNumber number, + Location new_location, + ChangedBy changed_by, + ChangedTime changed_time){ + Ndb * pNDB = uh->pNDB; + + DEBUG2("T1(%.*s):\n", SUBSCRIBER_NUMBER_LENGTH, number); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction != NULL) { + NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + if (MyOperation != NULL) { + MyOperation->updateTuple(); + MyOperation->equal(IND_SUBSCRIBER_NUMBER, + number); + MyOperation->setValue(IND_SUBSCRIBER_LOCATION, + (char *)&new_location); + MyOperation->setValue(IND_SUBSCRIBER_CHANGED_BY, + changed_by); + MyOperation->setValue(IND_SUBSCRIBER_CHANGED_TIME, + changed_time); + check = MyTransaction->execute( Commit ); + if (check != -1) { + pNDB->closeTransaction(MyTransaction); + return; + } else { + CHECK_MINUS_ONE(check, "T1: Commit", + MyTransaction); + }//if + } else { + CHECK_NULL(MyOperation, "T1: getNdbOperation", MyTransaction); + }//if + } else { + error_handler("T1-1: startTranscation", pNDB->getNdbErrorString(), pNDB->getNdbError()); + }//if +} + +/** + * Transaction 2 - T2 + * + * Read from Subscriber: + * + * Input: + * SubscriberNumber + * + * Output: + * Location + * Changed by + * Changed Timestamp + * Name + */ +void +userTransaction_T2(UserHandle * uh, + SubscriberNumber number, + Location * readLocation, + ChangedBy changed_by, + ChangedTime changed_time, + SubscriberName subscriberName){ + Ndb * pNDB = uh->pNDB; + + DEBUG2("T2(%.*s):\n", SUBSCRIBER_NUMBER_LENGTH, number); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T2-1: startTransaction", pNDB->getNdbErrorString(), pNDB->getNdbError()); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T2: getNdbOperation", + MyTransaction); + + MyOperation->readTuple(); + MyOperation->equal(IND_SUBSCRIBER_NUMBER, + number); + MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)readLocation); + MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + changed_by); + MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + changed_time); + MyOperation->getValue(IND_SUBSCRIBER_NAME, + subscriberName); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T2: Commit", + MyTransaction); + pNDB->closeTransaction(MyTransaction); +} + +/** + * Transaction 3 - T3 + * + * Read session details + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * + * Output: + * BranchExecuted + * SessionDetails + * ChangedBy + * ChangedTime + * Location + */ +void +userTransaction_T3(UserHandle * uh, + SubscriberNumber inNumber, + ServerId inServerId, + ServerBit inServerBit, + SessionDetails outSessionDetails, + BranchExecuted * outBranchExecuted){ + Ndb * pNDB = uh->pNDB; + + char outChangedBy [sizeof(ChangedBy) +(4-(sizeof(ChangedBy) & 3))]; + char outChangedTime [sizeof(ChangedTime)+(4-(sizeof(ChangedTime) & 3))]; + Location outLocation; + GroupId groupId; + ActiveSessions sessions; + Permission permission; + SubscriberSuffix inSuffix; + + DEBUG3("T3(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = startTransaction(pNDB, inServerId, inNumber); + if (MyTransaction == NULL) + error_handler("T3-1: startTranscation", pNDB->getNdbErrorString(), pNDB->getNdbError()); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T3-1: getNdbOperation", + MyTransaction); + + MyOperation->readTuple(); + MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)&outLocation); + MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T3-2: getNdbOperation", + MyTransaction); + + + MyOperation->readTuple(); + MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + MyOperation->getValue(IND_GROUP_ALLOW_READ, + (char *)&permission); + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-2: NoCommit", + MyTransaction); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == inServerBit)){ + + memcpy(inSuffix, + &inNumber[SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH], SUBSCRIBER_NUMBER_SUFFIX_LENGTH); + DEBUG2("reading(%.*s) - ", SUBSCRIBER_NUMBER_SUFFIX_LENGTH, inSuffix); + + /* Operation 3 */ + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T3-3: getNdbOperation", + MyTransaction); + + MyOperation->simpleRead(); + + MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + MyOperation->getValue(IND_SESSION_DATA, + (char *)outSessionDetails); + /* Operation 4 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T3-4: getNdbOperation", + MyTransaction); + + MyOperation->interpretedUpdateTuple(); + MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + MyOperation->incValue(IND_SERVER_READS, (uint32)1); + (* outBranchExecuted) = 1; + } else { + (* outBranchExecuted) = 0; + } + DEBUG("commit..."); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T3: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + DEBUG("done\n"); +} + + +/** + * Transaction 4 - T4 + * + * Create session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * SessionDetails, + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +void +userTransaction_T4(UserHandle * uh, + SubscriberNumber inNumber, + ServerId inServerId, + ServerBit inServerBit, + SessionDetails inSessionDetails, + DoRollback inDoRollback, + BranchExecuted * outBranchExecuted){ + + Ndb * pNDB = uh->pNDB; + + char outChangedBy [sizeof(ChangedBy) +(4-(sizeof(ChangedBy) & 3))]; + char outChangedTime [sizeof(ChangedTime)+(4-(sizeof(ChangedTime) & 3))]; + Location outLocation; + GroupId groupId; + ActiveSessions sessions; + Permission permission; + SubscriberSuffix inSuffix; + + DEBUG3("T4(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = startTransaction(pNDB, inServerId, inNumber); + if (MyTransaction == NULL) + error_handler("T4-1: startTranscation", pNDB->getNdbErrorString(), pNDB->getNdbError()); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T4-1: getNdbOperation", + MyTransaction); + + MyOperation->interpretedUpdateTuple(); + MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)&outLocation); + MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + MyOperation->incValue(IND_SUBSCRIBER_SESSIONS, + (uint32)inServerBit); + check = MyTransaction->execute( NoCommit ); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T4-2: getNdbOperation", + MyTransaction); + + MyOperation->readTuple(); + MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + MyOperation->getValue(IND_GROUP_ALLOW_INSERT, + (char *)&permission); + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-2: NoCommit", + MyTransaction); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == 0)){ + + memcpy(inSuffix, + &inNumber[SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH], SUBSCRIBER_NUMBER_SUFFIX_LENGTH); + + DEBUG2("inserting(%.*s) - ", SUBSCRIBER_NUMBER_SUFFIX_LENGTH, inSuffix); + + /* Operation 3 */ + + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T4-3: getNdbOperation", + MyTransaction); + + MyOperation->insertTuple(); + MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + MyOperation->setValue(SESSION_DATA, + (char *)inSessionDetails); + /* Operation 4 */ + + /* Operation 5 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T4-5: getNdbOperation", + MyTransaction); + + MyOperation->interpretedUpdateTuple(); + MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + MyOperation->incValue(IND_SERVER_INSERTS, (uint32)1); + (* outBranchExecuted) = 1; + } else { + (* outBranchExecuted) = 0; + DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); + DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); + } + + if(!inDoRollback && (* outBranchExecuted)){ + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T4: Commit", + MyTransaction); + } else { + DEBUG("rollback\n"); + check = MyTransaction->execute(Rollback); + CHECK_MINUS_ONE(check, "T4:Rollback", + MyTransaction); + + } + + pNDB->closeTransaction(MyTransaction); +} + + +/** + * Transaction 5 - T5 + * + * Delete session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +void +userTransaction_T5(UserHandle * uh, + SubscriberNumber inNumber, + ServerId inServerId, + ServerBit inServerBit, + DoRollback inDoRollback, + BranchExecuted * outBranchExecuted){ + Ndb * pNDB = uh->pNDB; + + DEBUG3("T5(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + NdbConnection * MyTransaction = 0; + NdbOperation * MyOperation = 0; + + char outChangedBy [sizeof(ChangedBy) +(4-(sizeof(ChangedBy) & 3))]; + char outChangedTime [sizeof(ChangedTime)+(4-(sizeof(ChangedTime) & 3))]; + Location outLocation; + GroupId groupId; + ActiveSessions sessions; + Permission permission; + SubscriberSuffix inSuffix; + + int check; + NdbRecAttr * check2; + + MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T5-1: startTranscation", pNDB->getNdbErrorString(), pNDB->getNdbError()); + + MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T5-1: getNdbOperation", + MyTransaction); + + MyOperation->interpretedUpdateTuple(); + MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)&outLocation); + MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + &outChangedBy[0]); + MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + &outChangedTime[0]); + MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + MyOperation->subValue(IND_SUBSCRIBER_SESSIONS, + (uint32)inServerBit); + MyTransaction->execute( NoCommit ); + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T5-2: getNdbOperation", + MyTransaction); + + MyOperation->readTuple(); + MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + MyOperation->getValue(IND_GROUP_ALLOW_DELETE, + (char *)&permission); + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-2: NoCommit", + MyTransaction); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == inServerBit)){ + + memcpy(inSuffix, + &inNumber[SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH], SUBSCRIBER_NUMBER_SUFFIX_LENGTH); + + DEBUG2("deleting(%.*s) - ", SUBSCRIBER_NUMBER_SUFFIX_LENGTH, inSuffix); + + /* Operation 3 */ + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T5-3: getNdbOperation", + MyTransaction); + + MyOperation->deleteTuple(); + MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + /* Operation 4 */ + + /* Operation 5 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T5-5: getNdbOperation", + MyTransaction); + + + MyOperation->interpretedUpdateTuple(); + MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + MyOperation->incValue(IND_SERVER_DELETES, (uint32)1); + (* outBranchExecuted) = 1; + } else { + (* outBranchExecuted) = 0; + DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); + DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); + } + + if(!inDoRollback && (* outBranchExecuted)){ + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T5: Commit", + MyTransaction); + } else { + DEBUG("rollback\n"); + check = MyTransaction->execute(Rollback); + CHECK_MINUS_ONE(check, "T5:Rollback", + MyTransaction); + + } + + pNDB->closeTransaction(MyTransaction); +} + diff --git a/ndb/test/ndbapi/bench/testData.h b/ndb/test/ndbapi/bench/testData.h new file mode 100644 index 00000000000..3db85e7342e --- /dev/null +++ b/ndb/test/ndbapi/bench/testData.h @@ -0,0 +1,156 @@ +/* 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; either version 2 of the License, or + (at your option) any later version. + + 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 */ + +#ifndef TESTDATA_H +#define TESTDATA_H + +/*************************************************************** +* I N C L U D E D F I L E S * +***************************************************************/ +#include +#include +#include +#include +#include "testDefinitions.h" + +/*************************************************************** +* M A C R O S * +***************************************************************/ + +/***************************************************************/ +/* C O N S T A N T S */ +/***************************************************************/ + +#define NUM_TRANSACTION_TYPES 5 +#define SESSION_LIST_LENGTH 1000 + +/*************************************************************** +* D A T A S T R U C T U R E S * +***************************************************************/ + +typedef struct { + SubscriberNumber subscriberNumber; + ServerId serverId; +} SessionElement; + +typedef struct { + SessionElement list[SESSION_LIST_LENGTH]; + unsigned int readIndex; + unsigned int writeIndex; + unsigned int numberInList; +} SessionList; + +typedef struct { + unsigned int count; + unsigned int branchExecuted; + unsigned int rollbackExecuted; + + /** + * Latency measures + */ + NDB_TICKS startTime; + NDBT_Stats latency; + unsigned int latencyCounter; + + inline void startLatency(){ + if((latencyCounter & 127) == 127) + startTime = NdbTick_CurrentMillisecond(); + } + + inline void stopLatency(){ + if((latencyCounter & 127) == 127){ + const NDB_TICKS tmp = NdbTick_CurrentMillisecond() - startTime; + latency.addObservation(tmp); + } + latencyCounter++; + } +} TransactionDefinition; + +typedef struct { + RandomSequence transactionSequence; + RandomSequence rollbackSequenceT4; + RandomSequence rollbackSequenceT5; + + TransactionDefinition transactions[NUM_TRANSACTION_TYPES]; + + unsigned int totalTransactions; + + double outerLoopTime; + double outerTps; + + SessionList activeSessions; + +} GeneratorStatistics; + +typedef enum{ + Runnable, + Running +} RunState ; + +typedef struct { + SubscriberNumber number; + SubscriberSuffix suffix; + SubscriberName name; + Location location; + ChangedBy changed_by; + ChangedTime changed_time; + ServerId server_id; + ServerBit server_bit; + SessionDetails session_details; + + GroupId group_id; + ActiveSessions sessions; + Permission permission; + + unsigned int do_rollback; + + unsigned int branchExecuted; + unsigned int sessionElement; +} TransactionData ; + +typedef struct { + struct NdbThread* pThread; + + unsigned long randomSeed; + unsigned long changedTime; + + unsigned int warmUpSeconds; + unsigned int testSeconds; + unsigned int coolDownSeconds; + + GeneratorStatistics generator; + + /** + * For async execution + */ + RunState runState; + double startTime; + TransactionData transactionData; + struct Ndb * pNDB; +} ThreadData; + +/*************************************************************** + * P U B L I C F U N C T I O N S * + ***************************************************************/ + +/*************************************************************** + * E X T E R N A L D A T A * + ***************************************************************/ + + + +#endif /* TESTDATA_H */ + diff --git a/ndb/test/ndbapi/bench/testDefinitions.h b/ndb/test/ndbapi/bench/testDefinitions.h new file mode 100644 index 00000000000..2f4aeb30975 --- /dev/null +++ b/ndb/test/ndbapi/bench/testDefinitions.h @@ -0,0 +1,90 @@ +/* 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; either version 2 of the License, or + (at your option) any later version. + + 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 */ + +#ifndef TESTDEFINITIONS_H +#define TESTDEFINITIONS_H + +/***************************************************************/ +/* I N C L U D E D F I L E S */ +/***************************************************************/ + +#include + +/***************************************************************/ +/* C O N S T A N T S */ +/***************************************************************/ + +#define OP_PER_TRANS 200 +#define NO_OF_SUBSCRIBERS 500000 +#define NO_OF_GROUPS 100 +#define NO_OF_SERVERS 20 + +#define SUBSCRIBER_NUMBER_LENGTH 12 +#define SUBSCRIBER_NUMBER_SUFFIX_LENGTH 2 + +#define SUBSCRIBER_NAME_LENGTH 32 +#define CHANGED_BY_LENGTH 32 +#define CHANGED_TIME_LENGTH 32 +#define SESSION_DETAILS_LENGTH 2000 +#define SERVER_NAME_LENGTH 32 +#define GROUP_NAME_LENGTH 32 + +/*************************************************************** +* D A T A S T R U C T U R E S * +***************************************************************/ + +#define PADDING 4 + +typedef char SubscriberNumber[SUBSCRIBER_NUMBER_LENGTH]; +typedef char SubscriberSuffix[SUBSCRIBER_NUMBER_SUFFIX_LENGTH + 2]; +typedef char SubscriberName[SUBSCRIBER_NAME_LENGTH]; +typedef char ServerName[SERVER_NAME_LENGTH]; +typedef char GroupName[GROUP_NAME_LENGTH]; +typedef char ChangedBy[CHANGED_BY_LENGTH]; +typedef char ChangedTime[CHANGED_TIME_LENGTH]; +typedef char SessionDetails[SESSION_DETAILS_LENGTH]; +typedef Uint32 ServerId; +typedef Uint32 ServerBit; +typedef Uint32 GroupId; +typedef Uint32 Location; +typedef Uint32 Permission; + +typedef Uint32 Counter; +typedef Uint32 ActiveSessions; +typedef unsigned int BranchExecuted; +typedef unsigned int DoRollback; + +/*************************************************************** +* P U B L I C F U N C T I O N S * +***************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef __cplusplus +} +#endif + +/*************************************************************** +* E X T E R N A L D A T A * +***************************************************************/ + + + +#endif /* TESTDEFINITIONS_H */ + diff --git a/ndb/test/ndbapi/bench/userInterface.cpp b/ndb/test/ndbapi/bench/userInterface.cpp new file mode 100644 index 00000000000..128d20dc9bb --- /dev/null +++ b/ndb/test/ndbapi/bench/userInterface.cpp @@ -0,0 +1,745 @@ +/* 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; either version 2 of the License, or + (at your option) any later version. + + 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 */ + +/*************************************************************** +* I N C L U D E D F I L E S * +***************************************************************/ + +#include +#ifndef NDB_WIN32 +#include +#endif + +#include "ndb_error.hpp" +#include "userInterface.h" +#include +#include +#include +#include +#include "ndb_schema.hpp" +#include +#include + +/*************************************************************** +* L O C A L C O N S T A N T S * +***************************************************************/ + +/*************************************************************** +* L O C A L D A T A S T R U C T U R E S * +***************************************************************/ + +/*************************************************************** +* L O C A L F U N C T I O N S * +***************************************************************/ + +extern int localDbPrepare(UserHandle *uh); + +static int dbCreate(UserHandle *uh); + +/*************************************************************** +* L O C A L D A T A * +***************************************************************/ + +/*************************************************************** +* P U B L I C D A T A * +***************************************************************/ + + +/*************************************************************** +**************************************************************** +* L O C A L F U N C T I O N S C O D E S E C T I O N * +**************************************************************** +***************************************************************/ + +/*************************************************************** +**************************************************************** +* P U B L I C F U N C T I O N S C O D E S E C T I O N * +**************************************************************** +***************************************************************/ + +/*-----------------------------------*/ +/* Time related Functions */ +/* */ +/* Returns a double value in seconds */ +/*-----------------------------------*/ +double userGetTimeSync(void) +{ + static int initialized = 0; + static NDB_TICKS initSecs = 0; + static Uint32 initMicros = 0; + double timeValue = 0; + + if ( !initialized ) { + initialized = 1; + NdbTick_CurrentMicrosecond(&initSecs, &initMicros); + timeValue = 0.0; + } else { + NDB_TICKS secs = 0; + Uint32 micros = 0; + + NdbTick_CurrentMicrosecond(&secs, µs); + + double s = (double)secs - (double)initSecs; + double us = (double)secs - (double)initMicros; + + timeValue = s + (us / 1000000.0); + } + + return timeValue; +} + +// 0 - OK +// 1 - Retry transaction +// 2 - Permanent +int +userDbCommit(UserHandle *uh){ + if(uh->pCurrTrans != 0){ + int check = uh->pCurrTrans->execute( Commit ); + NdbError err = uh->pCurrTrans->getNdbError(); + uh->pNDB->closeTransaction(uh->pCurrTrans); + uh->pCurrTrans = 0; + + if(err.status != NdbError::Success) + ndbout << err << endl; + + if(err.status == NdbError::TemporaryError && + err.classification == NdbError::OverloadError){ + NdbSleep_SecSleep(3); + } + + return err.status; + } + return 2; +} + +/** + * TRUE - Normal table + * FALSE - Table w.o. checkpoing and logging + */ + +#ifdef __cplusplus +extern "C" { +#endif +extern int useTableLogging; +extern int useIndexTables; +#ifdef __cplusplus +} +#endif + + +int +create_table_server(Ndb * pNdb){ + int check; + NdbSchemaCon * MySchemaTransaction = NdbSchemaCon::startSchemaTrans(pNdb); + if( MySchemaTransaction == NULL ) + error_handler("startSchemaTransaction", pNdb->getNdbError(), 0); + + NdbSchemaOp * MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); + if( MySchemaOp == NULL ) + error_handler("getNdbSchemaOp", MySchemaTransaction->getNdbError(), 0); + + // Create table + check = MySchemaOp->createTable( SERVER_TABLE, + 8, // Table size + TupleKey, // Key Type + 1 // Nr of Pages + ,DistributionGroup, + 6, + 78, + 80, + 1, + useTableLogging + ); + if( check == -1 ) + error_handler("createTable", MySchemaTransaction->getNdbError(), 0); + + check = MySchemaOp->createAttribute + ( SERVER_SUBSCRIBER_SUFFIX, + TupleKey, + sizeof(char) << 3, + SUBSCRIBER_NUMBER_SUFFIX_LENGTH, + String, + MMBased, + NotNullAttribute, + NormalStorageAttribute, + 0, + 1, + 16); + if( check == -1 ) + error_handler("createAttribute (subscriber suffix)", + MySchemaTransaction->getNdbError(), 0); + + // Create first column, primary key + check = MySchemaOp->createAttribute( SERVER_ID, + TupleKey, + sizeof(ServerId) << 3, + 1, + UnSigned, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (serverid)", + MySchemaTransaction->getNdbError(), 0); + + + check = MySchemaOp->createAttribute( SERVER_NAME, + NoKey, + sizeof(char) << 3, + SERVER_NAME_LENGTH, + String, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (server name)", + MySchemaTransaction->getNdbError(), 0); + + + check = MySchemaOp->createAttribute( SERVER_READS, + NoKey, + sizeof(Counter) << 3, + 1, + UnSigned, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (server reads)", + MySchemaTransaction->getNdbError(), 0); + + check = MySchemaOp->createAttribute( SERVER_INSERTS, + NoKey, + sizeof(Counter) << 3, + 1, + UnSigned, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (server inserts)", + MySchemaTransaction->getNdbError(), 0); + + check = MySchemaOp->createAttribute( SERVER_DELETES, + NoKey, + sizeof(Counter) << 3, + 1, + UnSigned, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (server deletes)", + MySchemaTransaction->getNdbError(), 0); + + if( MySchemaTransaction->execute() == -1 ) { + error_handler("schemaTransaction->execute()", + MySchemaTransaction->getNdbError(), 0); + } + NdbSchemaCon::closeSchemaTrans(MySchemaTransaction); + return 0; +} + +int +create_table_group(Ndb * pNdb){ + int check; + + NdbSchemaCon * MySchemaTransaction = NdbSchemaCon::startSchemaTrans(pNdb); + if( MySchemaTransaction == NULL ) + error_handler("startSchemaTransaction", pNdb->getNdbError(), 0); + + NdbSchemaOp * MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); + if( MySchemaOp == NULL ) + error_handler("getNdbSchemaOp", MySchemaTransaction->getNdbError(), 0); + + // Create table + check = MySchemaOp->createTable( GROUP_TABLE, + 8, // Table size + TupleKey, // Key Type + 1 // Nr of Pages + ,All, + 6, + 78, + 80, + 1, + useTableLogging + ); + + if( check == -1 ) + error_handler("createTable", MySchemaTransaction->getNdbError(), 0); + + // Create first column, primary key + check = MySchemaOp->createAttribute( GROUP_ID, + TupleKey, + sizeof(GroupId) << 3, + 1, + UnSigned, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (group id)", + MySchemaTransaction->getNdbError(), 0); + + check = MySchemaOp->createAttribute( GROUP_NAME, + NoKey, + sizeof(char) << 3, + GROUP_NAME_LENGTH, + String, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (group name)", + MySchemaTransaction->getNdbError(), 0); + + + check = MySchemaOp->createAttribute( GROUP_ALLOW_READ, + NoKey, + sizeof(Permission) << 3, + 1, + String, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (group read)", + MySchemaTransaction->getNdbError(), 0); + + + check = MySchemaOp->createAttribute( GROUP_ALLOW_INSERT, + NoKey, + sizeof(Permission) << 3, + 1, + UnSigned, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (group insert)", + MySchemaTransaction->getNdbError(), 0); + + check = MySchemaOp->createAttribute( GROUP_ALLOW_DELETE, + NoKey, + sizeof(Permission) << 3, + 1, + UnSigned, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (group delete)", + MySchemaTransaction->getNdbError(), 0); + + if( MySchemaTransaction->execute() == -1 ) { + error_handler("schemaTransaction->execute()", + MySchemaTransaction->getNdbError(), 0); + } + NdbSchemaCon::closeSchemaTrans(MySchemaTransaction); + return 0; +} + +int +create_table_subscriber(Ndb * pNdb){ + int check; + NdbSchemaCon * MySchemaTransaction = NdbSchemaCon::startSchemaTrans(pNdb); + if( MySchemaTransaction == NULL ) + error_handler("startSchemaTransaction", pNdb->getNdbError(), 0); + + NdbSchemaOp * MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); + if( MySchemaOp == NULL ) + error_handler("getNdbSchemaOp", MySchemaTransaction->getNdbError(), 0); + + // Create table + check = MySchemaOp->createTable( SUBSCRIBER_TABLE, + 8, // Table size + TupleKey, // Key Type + 1 // Nr of Pages + ,DistributionGroup, + 6, + 78, + 80, + 1, + useTableLogging + ); + if( check == -1 ) + error_handler("createTable", MySchemaTransaction->getNdbError(), 0); + + // Create first column, primary key + check = MySchemaOp->createAttribute + ( SUBSCRIBER_NUMBER, + TupleKey, + sizeof(char) << 3, + SUBSCRIBER_NUMBER_LENGTH, + String, + MMBased, + NotNullAttribute, + (useIndexTables ? IndexStorageAttribute : NormalStorageAttribute), + 0, + 1, + 16); + if( check == -1 ) + error_handler("createAttribute (subscriber number)", + MySchemaTransaction->getNdbError(), 0); + + check = MySchemaOp->createAttribute( SUBSCRIBER_NAME, + NoKey, + sizeof(char) << 3, + SUBSCRIBER_NAME_LENGTH, + String, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (subscriber name)", + MySchemaTransaction->getNdbError(), 0); + + + check = MySchemaOp->createAttribute( SUBSCRIBER_GROUP, + NoKey, + sizeof(GroupId) << 3, + 1, + UnSigned, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (subscriber_group)", + MySchemaTransaction->getNdbError(), 0); + + + check = MySchemaOp->createAttribute( SUBSCRIBER_LOCATION, + NoKey, + sizeof(Location) << 3, + 1, + UnSigned, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (server reads)", + MySchemaTransaction->getNdbError(), 0); + + check = MySchemaOp->createAttribute( SUBSCRIBER_SESSIONS, + NoKey, + sizeof(ActiveSessions) << 3, + 1, + UnSigned, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (subscriber_sessions)", + MySchemaTransaction->getNdbError(), 0); + + check = MySchemaOp->createAttribute( SUBSCRIBER_CHANGED_BY, + NoKey, + sizeof(char) << 3, + CHANGED_BY_LENGTH, + String, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (subscriber_changed_by)", + MySchemaTransaction->getNdbError(), 0); + + check = MySchemaOp->createAttribute( SUBSCRIBER_CHANGED_TIME, + NoKey, + sizeof(char) << 3, + CHANGED_TIME_LENGTH, + String, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (subscriber_changed_time)", + MySchemaTransaction->getNdbError(), 0); + + if( MySchemaTransaction->execute() == -1 ) { + error_handler("schemaTransaction->execute()", + MySchemaTransaction->getNdbError(), 0); + } + NdbSchemaCon::closeSchemaTrans(MySchemaTransaction); + return 0; +} + +int +create_table_session(Ndb * pNdb){ + int check; + NdbSchemaCon * MySchemaTransaction = NdbSchemaCon::startSchemaTrans(pNdb); + if( MySchemaTransaction == NULL ) + error_handler("startSchemaTransaction", pNdb->getNdbError(), 0); + + NdbSchemaOp * MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); + if( MySchemaOp == NULL ) + error_handler("getNdbSchemaOp", + MySchemaTransaction->getNdbError(), 0); + + // Create table + check = MySchemaOp->createTable( SESSION_TABLE, + 8, // Table size + TupleKey, // Key Type + 1 // Nr of Pages + ,DistributionGroup, + 6, + 78, + 80, + 1, + useTableLogging + ); + if( check == -1 ) + error_handler("createTable", MySchemaTransaction->getNdbError(), 0); + + check = MySchemaOp->createAttribute( SESSION_SUBSCRIBER, + TupleKey, + sizeof(char) << 3, + SUBSCRIBER_NUMBER_LENGTH, + String, + MMBased, + NotNullAttribute, + NormalStorageAttribute, + 0, + 1, + 16); + if( check == -1 ) + error_handler("createAttribute (session_subscriber)", + MySchemaTransaction->getNdbError(), 0); + + // Create first column, primary key + check = MySchemaOp->createAttribute( SESSION_SERVER, + TupleKey, + sizeof(ServerId) << 3, + 1, + UnSigned, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (session_server)", + MySchemaTransaction->getNdbError(), 0); + + + check = MySchemaOp->createAttribute( SESSION_DATA, + NoKey, + sizeof(char) << 3, + SESSION_DETAILS_LENGTH, + String, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (session_data)", + MySchemaTransaction->getNdbError(), 0); + + if( MySchemaTransaction->execute() == -1 ) { + error_handler("schemaTransaction->execute()", + MySchemaTransaction->getNdbError(), 0); + } + NdbSchemaCon::closeSchemaTrans(MySchemaTransaction); + return 0; +} + +void +create_table(const char * name, int (* function)(Ndb * pNdb), Ndb* pNdb){ + printf("creating table %s...", name); + if(pNdb->getDictionary()->getTable(name) != 0){ + printf(" it already exists\n"); + return; + } else { + printf("\n"); + } + function(pNdb); + printf("creating table %s... done\n", name); +} + +static int dbCreate(Ndb * pNdb) +{ + create_table(SUBSCRIBER_TABLE, create_table_subscriber, pNdb); + create_table(GROUP_TABLE , create_table_group, pNdb); + create_table(SESSION_TABLE , create_table_session, pNdb); + create_table(SERVER_TABLE , create_table_server, pNdb); + return 0; +} + +#ifndef NDB_WIN32 +#include +#endif + +UserHandle* +userDbConnect(uint32 createDb, char *dbName) +{ + Ndb_cluster_connection *con= new Ndb_cluster_connection(); + if(con->connect(12, 5, 1) != 0) + { + ndbout << "Unable to connect to management server." << endl; + return 0; + } + if (con->wait_until_ready(30,0) < 0) + { + ndbout << "Cluster nodes not ready in 30 seconds." << endl; + return 0; + } + + Ndb * pNdb = new Ndb(con, dbName); + + //printf("Initializing...\n"); + pNdb->init(); + + //printf("Waiting..."); + while(pNdb->waitUntilReady() != 0){ + //printf("..."); + } + // printf("done\n"); + + if( createDb ) + dbCreate(pNdb); + + + UserHandle * uh = new UserHandle; + uh->pNCC = con; + uh->pNDB = pNdb; + uh->pCurrTrans = 0; + + return uh; +} + +void userDbDisconnect(UserHandle *uh) +{ + delete uh; +} + +int userDbInsertServer(UserHandle *uh, + ServerId serverId, + SubscriberSuffix suffix, + ServerName name) +{ + int check; + + uint32 noOfRead = 0; + uint32 noOfInsert = 0; + uint32 noOfDelete = 0; + + NdbConnection * MyTransaction = 0; + if(uh->pCurrTrans != 0){ + MyTransaction = uh->pCurrTrans; + } else { + uh->pCurrTrans = MyTransaction = uh->pNDB->startTransaction(); + } + if (MyTransaction == NULL) + error_handler("startTranscation", uh->pNDB->getNdbError(), 0); + + NdbOperation *MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "getNdbOperation", MyTransaction); + + check = MyOperation->insertTuple(); + CHECK_MINUS_ONE(check, "insert tuple", MyTransaction); + + check = MyOperation->equal(SERVER_ID, (char*)&serverId); + CHECK_MINUS_ONE(check, "setValue id", MyTransaction); + + check = MyOperation->setValue(SERVER_SUBSCRIBER_SUFFIX, suffix); + CHECK_MINUS_ONE(check, "setValue suffix", MyTransaction); + + check = MyOperation->setValue(SERVER_NAME, name); + CHECK_MINUS_ONE(check, "setValue name", MyTransaction); + + check = MyOperation->setValue(SERVER_READS, (char*)&noOfRead); + CHECK_MINUS_ONE(check, "setValue reads", MyTransaction); + + check = MyOperation->setValue(SERVER_INSERTS, (char*)&noOfInsert); + CHECK_MINUS_ONE(check, "setValue inserts", MyTransaction); + + check = MyOperation->setValue(SERVER_DELETES, (char*)&noOfDelete); + CHECK_MINUS_ONE(check, "setValue deletes", MyTransaction); + + return 0; +} + +int userDbInsertSubscriber(UserHandle *uh, + SubscriberNumber number, + uint32 groupId, + SubscriberName name) +{ + int check; + uint32 activeSessions = 0; + Location l = 0; + ChangedBy changedBy; snprintf(changedBy, sizeof(changedBy), "ChangedBy"); + ChangedTime changedTime; snprintf(changedTime, sizeof(changedTime), "ChangedTime"); + + NdbConnection * MyTransaction = 0; + if(uh->pCurrTrans != 0){ + MyTransaction = uh->pCurrTrans; + } else { + uh->pCurrTrans = MyTransaction = uh->pNDB->startTransaction(); + } + if (MyTransaction == NULL) + error_handler("startTranscation", uh->pNDB->getNdbError(), 0); + + NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "getNdbOperation", MyTransaction); + + check = MyOperation->insertTuple(); + CHECK_MINUS_ONE(check, "insertTuple", MyTransaction); + + check = MyOperation->equal(SUBSCRIBER_NUMBER, number); + CHECK_MINUS_ONE(check, "equal", MyTransaction); + + check = MyOperation->setValue(SUBSCRIBER_NAME, name); + CHECK_MINUS_ONE(check, "setValue name", MyTransaction); + + check = MyOperation->setValue(SUBSCRIBER_GROUP, (char*)&groupId); + CHECK_MINUS_ONE(check, "setValue group", MyTransaction); + + check = MyOperation->setValue(SUBSCRIBER_LOCATION, (char*)&l); + CHECK_MINUS_ONE(check, "setValue location", MyTransaction); + + check = MyOperation->setValue(SUBSCRIBER_SESSIONS, (char*)&activeSessions); + CHECK_MINUS_ONE(check, "setValue sessions", MyTransaction); + + check = MyOperation->setValue(SUBSCRIBER_CHANGED_BY, changedBy); + CHECK_MINUS_ONE(check, "setValue changedBy", MyTransaction); + + check = MyOperation->setValue(SUBSCRIBER_CHANGED_TIME, changedTime); + CHECK_MINUS_ONE(check, "setValue changedTime", MyTransaction); + + return 0; +} + +int userDbInsertGroup(UserHandle *uh, + GroupId groupId, + GroupName name, + Permission allowRead, + Permission allowInsert, + Permission allowDelete) +{ + int check; + + NdbConnection * MyTransaction = 0; + if(uh->pCurrTrans != 0){ + MyTransaction = uh->pCurrTrans; + } else { + uh->pCurrTrans = MyTransaction = uh->pNDB->startTransaction(); + } + if (MyTransaction == NULL) + error_handler("startTranscation", uh->pNDB->getNdbError(), 0); + + NdbOperation *MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "getNdbOperation", MyTransaction); + + check = MyOperation->insertTuple(); + CHECK_MINUS_ONE(check, "insertTuple", MyTransaction); + + check = MyOperation->equal(GROUP_ID, (char*)&groupId); + CHECK_MINUS_ONE(check, "equal", MyTransaction); + + check = MyOperation->setValue(GROUP_NAME, name); + CHECK_MINUS_ONE(check, "setValue name", MyTransaction); + + check = MyOperation->setValue(GROUP_ALLOW_READ, (char*)&allowRead); + CHECK_MINUS_ONE(check, "setValue allowRead", MyTransaction); + + check = MyOperation->setValue(GROUP_ALLOW_INSERT, (char*)&allowInsert); + CHECK_MINUS_ONE(check, "setValue allowInsert", MyTransaction); + + check = MyOperation->setValue(GROUP_ALLOW_DELETE, (char*)&allowDelete); + CHECK_MINUS_ONE(check, "setValue allowDelete", MyTransaction); + + return 0; +} + diff --git a/ndb/test/ndbapi/bench/userInterface.h b/ndb/test/ndbapi/bench/userInterface.h new file mode 100644 index 00000000000..9e3b6f8f2a5 --- /dev/null +++ b/ndb/test/ndbapi/bench/userInterface.h @@ -0,0 +1,151 @@ +/* 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; either version 2 of the License, or + (at your option) any later version. + + 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 */ + +#ifndef DBINTERFACE_H +#define DBINTERFACE_H + +/***************************************************************/ +/* I N C L U D E D F I L E S */ +/***************************************************************/ + +#include "testDefinitions.h" +#include "testData.h" + +/*************************************************************** +* M A C R O S * +***************************************************************/ + +/***************************************************************/ +/* C O N S T A N T S */ +/***************************************************************/ + +/*-----------------------*/ +/* Default Database Name */ +/*-----------------------*/ +#define DEFAULTDB "TestDbClient" + +/*************************************************************** +* D A T A S T R U C T U R E S * +***************************************************************/ + +/*************************************************************** +* P U B L I C F U N C T I O N S * +***************************************************************/ + +typedef struct Ndb Ndb; + +#ifdef __cplusplus +extern "C" { +#endif + extern void showTime(); + extern double userGetTime(void); + extern Ndb *asyncDbConnect(int parallellism); + extern void asyncDbDisconnect(Ndb* pNDB); + + extern void start_T1(Ndb * uh, ThreadData * data, int async); + extern void start_T2(Ndb * uh, ThreadData * data, int async); + extern void start_T3(Ndb * uh, ThreadData * data, int async); + extern void start_T4(Ndb * uh, ThreadData * data, int async); + extern void start_T5(Ndb * uh, ThreadData * data, int async); + + extern void complete_T1(ThreadData * data); + extern void complete_T2(ThreadData * data); + extern void complete_T3(ThreadData * data); + extern void complete_T4(ThreadData * data); + extern void complete_T5(ThreadData * data); + + + +#ifdef __cplusplus +} +#endif + + + +/***************************************************************/ +/* I N C L U D E D F I L E S */ +/***************************************************************/ + +#include "testDefinitions.h" + +/*************************************************************** +* M A C R O S * +***************************************************************/ + +/***************************************************************/ +/* C O N S T A N T S */ +/***************************************************************/ + +/*-----------------------*/ +/* Default Database Name */ +/*-----------------------*/ +#define DEFAULTDB "TestDbClient" + +/*************************************************************** +* D A T A S T R U C T U R E S * +***************************************************************/ + +typedef struct { + struct Ndb_cluster_connection* pNCC; + struct Ndb * pNDB; + struct NdbConnection * pCurrTrans; +} UserHandle; + +/*************************************************************** +* P U B L I C F U N C T I O N S * +***************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +extern double userGetTimeSync(void); + +extern void userCheckpoint(UserHandle *uh); + +extern UserHandle *userDbConnect(uint32 createDb, char *dbName); +extern void userDbDisconnect(UserHandle *uh); + +extern int userDbInsertServer(UserHandle *uh, + ServerId serverId, + SubscriberSuffix suffix, + ServerName name); + +extern int userDbInsertSubscriber(UserHandle *uh, + SubscriberNumber number, + uint32 groupId, + SubscriberName name); + +extern int userDbInsertGroup(UserHandle *uh, + GroupId groupId, + GroupName name, + Permission allowRead, + Permission allowInsert, + Permission allowDelete); + + extern int userDbCommit(UserHandle *uh); + extern int userDbRollback(UserHandle *uh); + +#ifdef __cplusplus +} +#endif + +/*************************************************************** +* E X T E R N A L D A T A * +***************************************************************/ + +#endif /* DBINTERFACE_H */ + diff --git a/netware/mysql_test_run.c b/netware/mysql_test_run.c index fd5725a6414..d8cfb79c1cb 100644 --- a/netware/mysql_test_run.c +++ b/netware/mysql_test_run.c @@ -192,7 +192,7 @@ void install_db(char *datadir) char error[PATH_MAX]; // input file - snprintf(input, PATH_MAX, "%s/bin/init_db.sql", base_dir); + snprintf(input, PATH_MAX, "%s/bin/test_db.sql", base_dir); snprintf(output, PATH_MAX, "%s/install.out", datadir); snprintf(error, PATH_MAX, "%s/install.err", datadir); @@ -1160,7 +1160,8 @@ void setup(char *file) setenv("MASTER_MYPORT", "9306", 1); setenv("SLAVE_MYPORT", "9307", 1); setenv("MYSQL_TCP_PORT", "3306", 1); - + snprintf(file_path, PATH_MAX*2, "%s/mysql_client_test --no-defaults --testcase--user=root --port=%u ", bin_dir, master_port); + setenv("MYSQL_CLIENT_TEST",file_path,1); } /****************************************************************************** diff --git a/scripts/fill_help_tables.sh b/scripts/fill_help_tables.sh index fbe7c597b34..fc0c684c2dc 100644 --- a/scripts/fill_help_tables.sh +++ b/scripts/fill_help_tables.sh @@ -493,6 +493,24 @@ sub print_insert_header } } +print <in_use->got_warning= 0; + } + if (store_value(&decimal_value)) + err= 1; + else if (err && !table->in_use->got_warning) + err= warn_if_overflow(err); + DBUG_RETURN(err); } @@ -1649,10 +1669,19 @@ int Field_new_decimal::store(longlong nr) { my_decimal decimal_value; int err; - if ((err= check_overflow(int2my_decimal(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW, - nr, unsigned_flag, &decimal_value)))) - set_value_on_overflow(&decimal_value, decimal_value.sign()); - store_value(&decimal_value); + + if ((err= int2my_decimal(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW, + nr, unsigned_flag, &decimal_value))) + { + if (check_overflow(err)) + set_value_on_overflow(&decimal_value, decimal_value.sign()); + /* Only issue a warning if store_value doesn't issue an warning */ + table->in_use->got_warning= 0; + } + if (store_value(&decimal_value)) + err= 1; + else if (err && !table->in_use->got_warning) + err= warn_if_overflow(err); return err; } @@ -1694,7 +1723,7 @@ my_decimal* Field_new_decimal::val_decimal(my_decimal *decimal_value) String *Field_new_decimal::val_str(String *val_buffer, - String *val_ptr __attribute__((unused))) + String *val_ptr __attribute__((unused))) { my_decimal decimal_value; int fixed_precision= (zerofill ? @@ -1728,6 +1757,7 @@ void Field_new_decimal::sql_type(String &str) const add_zerofill_and_unsigned(str); } + /**************************************************************************** ** tiny int ****************************************************************************/ diff --git a/sql/field.h b/sql/field.h index d0b43e77e5a..327fb4c885b 100644 --- a/sql/field.h +++ b/sql/field.h @@ -290,7 +290,11 @@ public: int cuted_increment); void set_datetime_warning(const uint level, const uint code, double nr, timestamp_type ts_type); - int check_overflow(int op_result); + inline bool check_overflow(int op_result) + { + return (op_result == E_DEC_OVERFLOW); + } + int warn_if_overflow(int op_result); virtual field_cast_enum field_cast_type()= 0; bool field_cast_compatible(field_cast_enum type); /* maximum possible display length */ diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index 02d81882e7a..d30435310dc 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -60,8 +60,7 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked) { /* Initialize variables for the opened table */ set_keys_for_scanning(); - if (table->s->tmp_table == NO_TMP_TABLE) - update_key_stats(); + update_key_stats(); } return (file ? 0 : 1); } @@ -104,6 +103,8 @@ void ha_heap::update_key_stats() for (uint i= 0; i < table->s->keys; i++) { KEY *key=table->key_info+i; + if (!key->rec_per_key) + continue; if (key->algorithm != HA_KEY_ALG_BTREE) { ha_rows hash_buckets= file->s->keydef[i].hash_buckets; @@ -124,8 +125,8 @@ int ha_heap::write_row(byte * buf) if (table->next_number_field && buf == table->record[0]) update_auto_increment(); res= heap_write(file,buf); - if (!res && table->s->tmp_table == NO_TMP_TABLE && - ++records_changed*HEAP_STATS_UPDATE_THRESHOLD > file->s->records) + if (!res && (++records_changed*HEAP_STATS_UPDATE_THRESHOLD > + file->s->records)) update_key_stats(); return res; } @@ -137,8 +138,8 @@ int ha_heap::update_row(const byte * old_data, byte * new_data) if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE) table->timestamp_field->set_time(); res= heap_update(file,old_data,new_data); - if (!res && table->s->tmp_table == NO_TMP_TABLE && - ++records_changed*HEAP_STATS_UPDATE_THRESHOLD > file->s->records) + if (!res && ++records_changed*HEAP_STATS_UPDATE_THRESHOLD > + file->s->records) update_key_stats(); return res; } diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index f77136a548e..58f744438fc 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -2357,22 +2357,21 @@ void ha_ndbcluster::print_results() if (!_db_on_) DBUG_VOID_RETURN; - + char buf_type[MAX_FIELD_WIDTH], buf_val[MAX_FIELD_WIDTH]; - String type(buf_type, sizeof(buf_type), &my_charset_bin); + String type(buf_type, sizeof(buf_type), &my_charset_bin); String val(buf_val, sizeof(buf_val), &my_charset_bin); for (uint f=0; fs->fields;f++) { - // Use DBUG_PRINT since DBUG_FILE cannot be filtered out + /* Use DBUG_PRINT since DBUG_FILE cannot be filtered out */ char buf[2000]; Field *field; void* ptr; - const NDBCOL *col= NULL; NdbValue value; NdbBlob *ndb_blob; buf[0]= 0; - field= table->field[f]; + field= table->field[f]; if (!(value= m_value[f]).ptr) { my_snprintf(buf, sizeof(buf), "not read"); @@ -2380,8 +2379,6 @@ void ha_ndbcluster::print_results() } ptr= field->ptr; - DBUG_DUMP("field->ptr", (char*)ptr, field->pack_length()); - col= tab->getColumn(f); if (! (field->flags & BLOB_FLAG)) { @@ -2407,9 +2404,9 @@ void ha_ndbcluster::print_results() goto print_value; } } - + print_value: - DBUG_PRINT("value", ("%u,%s: %s", f, col->getName(), buf)); + DBUG_PRINT("value", ("%u,%s: %s", f, field->field_name, buf)); } #endif DBUG_VOID_RETURN; diff --git a/sql/item.cc b/sql/item.cc index 17ded05766f..96806ea2ed1 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -542,6 +542,58 @@ void Item_splocal::print(String *str) +/* + Move SUM items out from item tree and replace with reference + + SYNOPSIS + split_sum_func2() + thd Thread handler + ref_pointer_array Pointer to array of reference fields + fields All fields in select + ref Pointer to item + + NOTES + This is from split_sum_func2() for items that should be split + + All found SUM items are added FIRST in the fields list and + we replace the item with a reference. + + thd->fatal_error() may be called if we are out of memory +*/ + + +void Item::split_sum_func2(THD *thd, Item **ref_pointer_array, + List &fields, Item **ref) +{ + if (type() != SUM_FUNC_ITEM && with_sum_func) + { + /* Will split complicated items and ignore simple ones */ + split_sum_func(thd, ref_pointer_array, fields); + } + else if ((type() == SUM_FUNC_ITEM || + (used_tables() & ~PARAM_TABLE_BIT)) && + type() != REF_ITEM) + { + /* + Replace item with a reference so that we can easily calculate + it (in case of sum functions) or copy it (in case of fields) + + The test above is to ensure we don't do a reference for things + that are constants (PARAM_TABLE_BIT is in effect a constant) + or already referenced (for example an item in HAVING) + */ + uint el= fields.elements; + Item *new_item; + ref_pointer_array[el]= this; + if (!(new_item= new Item_ref(ref_pointer_array + el, 0, name))) + return; // fatal_error is set + fields.push_front(this); + ref_pointer_array[el]= this; + thd->change_item_tree(ref, new_item); + } +} + + /* Aggregate two collations together taking into account their coercibility (aka derivation): diff --git a/sql/item.h b/sql/item.h index ccbc00470e5..e2e72dbee40 100644 --- a/sql/item.h +++ b/sql/item.h @@ -334,6 +334,9 @@ public: virtual void update_used_tables() {} virtual void split_sum_func(THD *thd, Item **ref_pointer_array, List &fields) {} + /* Called for items that really have to be split */ + void split_sum_func2(THD *thd, Item **ref_pointer_array, List &fields, + Item **ref); virtual bool get_date(TIME *ltime,uint fuzzydate); virtual bool get_time(TIME *ltime); virtual bool get_date_result(TIME *ltime,uint fuzzydate) diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 71a4e4dda53..c26365e3f0e 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -704,13 +704,12 @@ longlong Item_in_optimizer::val_int() { DBUG_ASSERT(fixed == 1); cache->store(args[0]); - longlong tmp= args[1]->val_int_result(); if (cache->null_value) { - if (tmp) - null_value= 1; + null_value= 1; return 0; } + longlong tmp= args[1]->val_int_result(); null_value= args[1]->null_value; return tmp; } @@ -2349,10 +2348,10 @@ Item *Item_cond::transform(Item_transformer transformer, byte *arg) Move SUM items out from item tree and replace with reference SYNOPSIS - split_sum_func() - thd Thread handler - ref_pointer_array Pointer to array of reference fields - fields All fields in select + split_sum_func() + thd Thread handler + ref_pointer_array Pointer to array of reference fields + fields All fields in select NOTES This function is run on all expression (SELECT list, WHERE, HAVING etc) @@ -2362,16 +2361,6 @@ Item *Item_cond::transform(Item_transformer transformer, byte *arg) so that we can easily find and calculate them. (Calculation done by update_sum_func() and copy_sum_funcs() in sql_select.cc) - - All found SUM items are added FIRST in the fields list and - we replace the item with a reference. - - We also replace all functions without side effects (like RAND() or UDF's) - that uses columns as arguments. - For functions with side effects, we just remember any fields referred - by the function to ensure that we get a copy of the field value for the - first accepted row. This ensures that we can do things like - SELECT a*SUM(b) FROM t1 WHERE a=1 */ void Item_cond::split_sum_func(THD *thd, Item **ref_pointer_array, @@ -2379,37 +2368,8 @@ void Item_cond::split_sum_func(THD *thd, Item **ref_pointer_array, { List_iterator li(list); Item *item; - used_tables_cache=0; - const_item_cache=1; - while ((item=li++)) - { - /* with_sum_func is set for items that contains a SUM expression */ - if (item->type() != SUM_FUNC_ITEM && - (item->with_sum_func || - (item->used_tables() & PSEUDO_TABLE_BITS))) - item->split_sum_func(thd, ref_pointer_array, fields); - else if (item->type() == SUM_FUNC_ITEM || - (item->used_tables() && item->type() != REF_ITEM)) - { - /* - Replace item with a reference so that we can easily calculate - it (in case of sum functions) or copy it (in case of fields) - - The test above is to ensure we don't do a reference for things - that are constants or are not yet calculated as in: - SELECT RAND() as r1, SUM(a) as r2 FROM t1 HAVING r1 > 1 AND r2 > 0 - */ - Item **ref= li.ref(); - uint el= fields.elements; - ref_pointer_array[el]= item; - Item *new_item= new Item_ref(ref_pointer_array + el, 0, item->name); - fields.push_front(item); - thd->change_item_tree(ref, new_item); - } - item->update_used_tables(); - used_tables_cache|=item->used_tables(); - const_item_cache&=item->const_item(); - } + while ((item= li++)) + item->split_sum_func2(thd, ref_pointer_array, fields, li.ref()); } diff --git a/sql/item_func.cc b/sql/item_func.cc index a4c1110da32..1e61474f412 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -401,27 +401,14 @@ Item *Item_func::transform(Item_transformer transformer, byte *argument) } +/* See comments in Item_cmp_func::split_sum_func() */ + void Item_func::split_sum_func(THD *thd, Item **ref_pointer_array, List &fields) { Item **arg, **arg_end; for (arg= args, arg_end= args+arg_count; arg != arg_end ; arg++) - { - Item *item=* arg; - if (item->type() != SUM_FUNC_ITEM && - (item->with_sum_func || - (item->used_tables() & PSEUDO_TABLE_BITS))) - item->split_sum_func(thd, ref_pointer_array, fields); - else if (item->type() == SUM_FUNC_ITEM || - (item->used_tables() && item->type() != REF_ITEM)) - { - uint el= fields.elements; - ref_pointer_array[el]= item; - Item *new_item= new Item_ref(ref_pointer_array + el, 0, item->name); - fields.push_front(item); - thd->change_item_tree(arg, new_item); - } - } + (*arg)->split_sum_func2(thd, ref_pointer_array, fields, arg); } diff --git a/sql/item_row.cc b/sql/item_row.cc index 08c682afa85..00d849e55de 100644 --- a/sql/item_row.cc +++ b/sql/item_row.cc @@ -90,24 +90,10 @@ void Item_row::split_sum_func(THD *thd, Item **ref_pointer_array, { Item **arg, **arg_end; for (arg= items, arg_end= items+arg_count; arg != arg_end ; arg++) - { - Item *item= *arg; - if (item->type() != SUM_FUNC_ITEM && - (item->with_sum_func || - (item->used_tables() & PSEUDO_TABLE_BITS))) - item->split_sum_func(thd, ref_pointer_array, fields); - else if (item->type() == SUM_FUNC_ITEM || - (item->used_tables() && item->type() != REF_ITEM)) - { - uint el= fields.elements; - ref_pointer_array[el]= *arg; - Item *new_item= new Item_ref(ref_pointer_array + el, 0, (*arg)->name); - fields.push_front(*arg); - thd->change_item_tree(arg, new_item); - } - } + (*arg)->split_sum_func2(thd, ref_pointer_array, fields, arg); } + void Item_row::update_used_tables() { used_tables_cache= 0; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 55185a5f75b..02f33d39465 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1778,19 +1778,7 @@ String *Item_func_elt::val_str(String *str) void Item_func_make_set::split_sum_func(THD *thd, Item **ref_pointer_array, List &fields) { - if (item->type() != SUM_FUNC_ITEM && - (item->with_sum_func || - (item->used_tables() & PSEUDO_TABLE_BITS))) - item->split_sum_func(thd, ref_pointer_array, fields); - else if (item->type() == SUM_FUNC_ITEM || - (item->used_tables() && item->type() != REF_ITEM)) - { - uint el= fields.elements; - ref_pointer_array[el]= item; - Item *new_item= new Item_ref(ref_pointer_array + el, 0, item->name); - fields.push_front(item); - thd->change_item_tree(&item, new_item); - } + item->split_sum_func2(thd, ref_pointer_array, fields, &item); Item_str_func::split_sum_func(thd, ref_pointer_array, fields); } diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 8d392232f02..fe849bd213a 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -889,8 +889,10 @@ Item_in_subselect::single_value_transformer(JOIN *join, ref_pointer_array, (char *)"", this->full_name())); +#ifdef CORRECT_BUT_TOO_SLOW_TO_BE_USABLE if (!abort_on_null && left_expr->maybe_null) item= new Item_cond_or(new Item_func_isnull(left_expr), item); +#endif /* AND and comparison functions can't be changed during fix_fields() we can assign select_lex->having here, and pass 0 as last @@ -944,8 +946,10 @@ Item_in_subselect::single_value_transformer(JOIN *join, goto err; item= new Item_cond_or(item, new Item_func_isnull(orig_item)); +#ifdef CORRECT_BUT_TOO_SLOW_TO_BE_USABLE if (left_expr->maybe_null) item= new Item_cond_or(new Item_func_isnull(left_expr), item); +#endif } item->name= (char *)in_additional_cond; /* @@ -975,8 +979,10 @@ Item_in_subselect::single_value_transformer(JOIN *join, new Item_null_helper(this, item, (char *)"", (char *)"")); +#ifdef CORRECT_BUT_TOO_SLOW_TO_BE_USABLE if (!abort_on_null && left_expr->maybe_null) item= new Item_cond_or(new Item_func_isnull(left_expr), item); +#endif select_lex->having= join->having= item; select_lex->having_fix_field= 1; /* diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 668ef033414..2998d367a36 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3302,12 +3302,14 @@ default_service_handling(char **argv, if (Service.got_service_option(argv, "install")) { - Service.Install(1, servicename, displayname, path_and_service, account_name); + Service.Install(1, servicename, displayname, path_and_service, + account_name); return 0; } if (Service.got_service_option(argv, "install-manual")) { - Service.Install(0, servicename, displayname, path_and_service, account_name); + Service.Install(0, servicename, displayname, path_and_service, + account_name); return 0; } if (Service.got_service_option(argv, "remove")) @@ -3327,7 +3329,7 @@ int main(int argc, char **argv) application PID e.g.: MySQLShutdown1890; MySQLShutdown2342 */ int10_to_str((int) GetCurrentProcessId(),strmov(shutdown_event_name, - "MySQLShutdown"), 10); + "MySQLShutdown"), 10); /* Must be initialized early for comparison of service name */ system_charset_info= &my_charset_utf8_general_ci; @@ -3361,7 +3363,8 @@ int main(int argc, char **argv) } else if (argc == 3) /* install or remove any optional service */ { - if (!default_service_handling(argv, argv[2], argv[2], file_path, "", NULL)) + if (!default_service_handling(argv, argv[2], argv[2], file_path, "", + NULL)) return 0; if (Service.IsService(argv[2])) { @@ -3388,24 +3391,20 @@ int main(int argc, char **argv) --defaults-file=file, but that was not enforced in 4.1, so we don't enforce it here.) */ - char *extra_opt= NULL; - char *account_name = NULL; + const char *extra_opt= NullS; + const char *account_name = NullS; int index; for (index = 3; index < argc; index++) { - if (strncmp(argv[index], "--local-service", 15) == 0) - { - account_name=(char*)malloc(27); - strmov(account_name, "NT AUTHORITY\\LocalService\0"); - } + if (!strcmp(argv[index], "--local-service")) + account_name= "NT AUTHORITY\\LocalService"; else - { extra_opt= argv[index]; - } } - if (argc != 5 || account_name) - if (!default_service_handling(argv, argv[2], argv[2], file_path, extra_opt, account_name)) + if (argc == 4 || account_name) + if (!default_service_handling(argv, argv[2], argv[2], file_path, + extra_opt, account_name)) return 0; } else if (argc == 1 && Service.IsService(MYSQL_SERVICENAME)) diff --git a/sql/nt_servc.h b/sql/nt_servc.h index 6d74eaccea2..a3c12569114 100644 --- a/sql/nt_servc.h +++ b/sql/nt_servc.h @@ -48,8 +48,9 @@ class NTService //service install / un-install - BOOL Install(int startType,LPCSTR szInternName,LPCSTR szDisplayName,LPCSTR szFullPath, - LPCSTR szAccountName=NULL,LPCSTR szPassword=NULL); + BOOL Install(int startType,LPCSTR szInternName,LPCSTR szDisplayName, + LPCSTR szFullPath, LPCSTR szAccountName=NULL, + LPCSTR szPassword=NULL); BOOL SeekStatus(LPCSTR szInternName, int OperationType); BOOL Remove(LPCSTR szInternName); BOOL IsService(LPCSTR ServiceName); diff --git a/sql/sql_class.h b/sql/sql_class.h index b04ad449ba3..32a2390a402 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1027,6 +1027,7 @@ public: bool charset_is_system_charset, charset_is_collation_connection; bool slow_command; bool no_trans_update, abort_on_warning; + bool got_warning; /* Set on call to push_warning() */ longlong row_count_func; /* For the ROW_COUNT() function */ sp_rcontext *spcont; // SP runtime context sp_cache *sp_proc_cache; diff --git a/sql/sql_error.cc b/sql/sql_error.cc index adae481d608..d0f06c47edb 100644 --- a/sql/sql_error.cc +++ b/sql/sql_error.cc @@ -108,6 +108,7 @@ MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level, if (thd->query_id != thd->warn_id) mysql_reset_errors(thd); + thd->got_warning= 1; if (thd->spcont && thd->spcont->find_handler(code, ((int) level >= diff --git a/sql/sql_list.h b/sql/sql_list.h index 657943f1e69..85da553f64a 100644 --- a/sql/sql_list.h +++ b/sql/sql_list.h @@ -140,15 +140,6 @@ public: delete *prev; *prev=node; } - inline void *pop(void) - { - if (first == &end_of_list) return 0; - list_node *tmp=first; - first=first->next; - if (!--elements) - last= &first; - return tmp->info; - } inline void concat(base_list *list) { if (!list->is_empty()) @@ -158,6 +149,15 @@ public: elements+= list->elements; } } + inline void *pop(void) + { + if (first == &end_of_list) return 0; + list_node *tmp=first; + first=first->next; + if (!--elements) + last= &first; + return tmp->info; + } inline void disjoin(base_list *list) { list_node **prev= &first; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 6af257893d4..f49f980f364 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -8247,6 +8247,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, keyinfo->key_length=(uint16) reclength; keyinfo->name= (char*) "distinct_key"; keyinfo->algorithm= HA_KEY_ALG_UNDEF; + keyinfo->rec_per_key=0; if (null_pack_length) { key_part_info->null_bit=0; @@ -11831,6 +11832,7 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param, res_selected_fields.empty(); res_all_fields.empty(); List_iterator_fast itr(res_all_fields); + List extra_funcs; uint i, border= all_fields.elements - elements; DBUG_ENTER("setup_copy_fields"); @@ -11892,7 +11894,12 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param, */ if (!(pos=new Item_copy_string(pos))) goto err; - if (param->copy_funcs.push_back(pos)) + if (i < border) // HAVING, ORDER and GROUP BY + { + if (extra_funcs.push_back(pos)) + goto err; + } + else if (param->copy_funcs.push_back(pos)) goto err; } res_all_fields.push_back(pos); @@ -11904,6 +11911,12 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param, for (i= 0; i < border; i++) itr++; itr.sublist(res_selected_fields, elements); + /* + Put elements from HAVING, ORDER BY and GROUP BY last to ensure that any + reference used in these will resolve to a item that is already calculated + */ + param->copy_funcs.concat(&extra_funcs); + DBUG_RETURN(0); err: