$what\n", __LINE__));
&html_push('TR');
if ($deferred_ref)
@@ -1463,11 +1477,7 @@ print "# end of pass 4\n" if $verbose;
# #
#---############################################################################
-$header = <
-EOT
-
+ $header = '';
$full_title = $value{'_title'} || $value{'_settitle'} || "Untitled Document";
$title = $value{'_settitle'} || $full_title;
$_ = &substitute_style($full_title);
@@ -1815,8 +1825,10 @@ sub fix_image
die "error in image: '$text'" unless defined($1);
$arg1 = $1;
$arg1 =~ s/@@/@/g;
- $ext = "jpg" if -f "$arg1.jpg";
- $ext = "gif" if -f "$arg1.gif";
+ foreach (@include_dirs) {
+ $ext = "jpg" if -f "$_/$arg1.jpg";
+ $ext = "gif" if -f "$_/$arg1.gif";
+ }
if (defined($ext))
{
" ";
@@ -2010,7 +2022,7 @@ sub print_toplevel_header
{
local($_);
- &print_header; # pass given arg...
+ &print_header unless $opt_empty_headers; # pass given arg...
print FILE $full_title;
if ($value{'_subtitle'}) {
$value{'_subtitle'} =~ s/\n+$//;
@@ -2042,13 +2054,7 @@ EOT
sub print_toplevel_footer
{
- &print_ruler;
- print FILE <texi2html
-translator version 1.52 (extended by davida\@detron.se).
-EOT
- &print_footer;
+ &print_footer unless $opt_empty_headers;
}
sub protect_texi
@@ -2065,8 +2071,10 @@ sub protect_html
{
local($what) = @_;
# protect & < >
- # Avoid loop in & replacement. This instead bugs out for in text..
- $what =~ s/\&([^#]|$)/\&\#38;$1/g;
+ # hack for the two entity-like variable reference in existing examples
+ $what =~ s/\&(length|ts);/\&\#38;$1;/g;
+ # this leaves alone entities, but encodes standalone ampersands
+ $what =~ s/\&(?!([a-z0-9]+|#\d+);)/\&\#38;/ig;
$what =~ s/\\&\#60;/g;
$what =~ s/\>/\&\#62;/g;
# but recognize some HTML things
From 6b720d93be6c63b4f340ef1add6db4cb96f90fe2 Mon Sep 17 00:00:00 2001
From: "lenz@mysql.com" <>
Date: Wed, 27 Oct 2004 21:51:27 +0200
Subject: [PATCH 05/59] - Applied some Windows portability fixes for
myisampack.c and sql_handler.cc (backports from fixes made in 4.1)
---
myisam/myisampack.c | 2 +-
sql/sql_handler.cc | 8 +-------
2 files changed, 2 insertions(+), 8 deletions(-)
diff --git a/myisam/myisampack.c b/myisam/myisampack.c
index 0dde1916f03..9f4e3bde65a 100644
--- a/myisam/myisampack.c
+++ b/myisam/myisampack.c
@@ -2047,7 +2047,7 @@ static int save_state(MI_INFO *isam_file,PACK_MRG_INFO *mrg,my_off_t new_length,
share->state.dellink= HA_OFFSET_ERROR;
share->state.split=(ha_rows) mrg->records;
share->state.version=(ulong) time((time_t*) 0);
- if (share->state.key_map != (1ULL << share->base.keys) - 1)
+ if (share->state.key_map != (((ulonglong)1) << share->base.keys) - 1)
{
/*
Some indexes are disabled, cannot use current key_file_length value
diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc
index 44ffb713dcc..5bfcc897fc7 100644
--- a/sql/sql_handler.cc
+++ b/sql/sql_handler.cc
@@ -265,8 +265,6 @@ int mysql_ha_close(THD *thd, TABLE_LIST *tables)
{
TABLE_LIST *hash_tables;
TABLE **table_ptr;
- bool was_flushed= FALSE;
- bool not_opened;
DBUG_ENTER("mysql_ha_close");
DBUG_PRINT("enter",("'%s'.'%s' as '%s'",
tables->db, tables->real_name, tables->alias));
@@ -363,7 +361,6 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
int err;
int keyno=-1;
uint num_rows;
- bool was_flushed;
MYSQL_LOCK *lock;
DBUG_ENTER("mysql_ha_read");
DBUG_PRINT("enter",("'%s'.'%s' as '%s'",
@@ -615,10 +612,8 @@ err0:
int mysql_ha_flush(THD *thd, TABLE_LIST *tables, uint mode_flags)
{
- TABLE_LIST **tmp_tables_p;
TABLE_LIST *tmp_tables;
TABLE **table_ptr;
- bool was_flushed;
DBUG_ENTER("mysql_ha_flush");
DBUG_PRINT("enter", ("tables: %p mode_flags: 0x%02x", tables, mode_flags));
@@ -692,14 +687,13 @@ static int mysql_ha_flush_table(THD *thd, TABLE **table_ptr, uint mode_flags)
{
TABLE_LIST *hash_tables;
TABLE *table= *table_ptr;
- bool was_flushed;
DBUG_ENTER("mysql_ha_flush_table");
DBUG_PRINT("enter",("'%s'.'%s' as '%s' flags: 0x%02x",
table->table_cache_key, table->real_name,
table->table_name, mode_flags));
if ((hash_tables= (TABLE_LIST*) hash_search(&thd->handler_tables_hash,
- (*table_ptr)->table_name,
+ (byte*) (*table_ptr)->table_name,
strlen((*table_ptr)->table_name) + 1)))
{
if (! (mode_flags & MYSQL_HA_REOPEN_ON_USAGE))
From a206cb757450b3c807ec2204e060792b8e4b66d5 Mon Sep 17 00:00:00 2001
From: "joreland@mysql.com" <>
Date: Thu, 28 Oct 2004 10:50:39 +0200
Subject: [PATCH 06/59] Fix for aix4 which defines clock_gettime, but it only
returns ENOSYS
---
configure.in | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/configure.in b/configure.in
index 979782fe511..9376f8748ee 100644
--- a/configure.in
+++ b/configure.in
@@ -1913,7 +1913,7 @@ AC_CHECK_FUNCS(alarm bcmp bfill bmove bzero chsize cuserid fchmod fcntl \
getcwd gethostbyaddr_r gethostbyname_r getpass getpassphrase getpwnam \
getpwuid getrlimit getrusage getwd gmtime_r index initgroups isnan \
localtime_r locking longjmp lrand48 madvise mallinfo memcpy memmove \
- mkstemp mlockall perror poll pread pthread_attr_create clock_gettime \
+ mkstemp mlockall perror poll pread pthread_attr_create \
pthread_attr_getstacksize pthread_attr_setprio pthread_attr_setschedparam \
pthread_attr_setstacksize pthread_condattr_create pthread_getsequence_np \
pthread_key_delete pthread_rwlock_rdlock pthread_setprio \
@@ -1922,6 +1922,18 @@ AC_CHECK_FUNCS(alarm bcmp bfill bmove bzero chsize cuserid fchmod fcntl \
snprintf socket stpcpy strcasecmp strerror strnlen strpbrk strstr strtol \
strtoll strtoul strtoull tell tempnam thr_setconcurrency vidattr)
+#
+#
+#
+case "$target" in
+ *-*-aix4*)
+ # (grr) aix 4.3 has a stub for clock_gettime, (returning ENOSYS)
+ # and using AC_TRY_RUN is hard when cross-compiling
+ ;;
+ *) AC_CHECK_FUNCS(clock_gettime)
+ ;;
+esac
+
# isinf() could be a function or a macro (HPUX)
AC_MSG_CHECKING(for isinf with )
AC_TRY_LINK([#include ], [float f = 0.0; isinf(f)],
From 0003a8d5a0b541563888ca667d86ee5ea3964940 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Thu, 28 Oct 2004 11:19:51 +0000
Subject: [PATCH 07/59] added test for max limit of 128 attributes in table
new define for long signal section size bumbed up limit for attributes
to 128 use new define in SectionSegment some bug fixing of send
fragmented signal + make chunk size a multiple the dew define for
SectionSegment size
---
mysql-test/r/ndb_basic.result | 131 ++++++++++++++++++++++++++
mysql-test/t/ndb_basic.test | 136 +++++++++++++++++++++++++++
ndb/include/kernel/ndb_limits.h | 5 +
ndb/include/ndbapi/ndbapi_limits.h | 2 +-
ndb/src/kernel/vm/LongSignal.hpp | 2 +-
ndb/src/ndbapi/TransporterFacade.cpp | 64 +++++++------
6 files changed, 311 insertions(+), 29 deletions(-)
diff --git a/mysql-test/r/ndb_basic.result b/mysql-test/r/ndb_basic.result
index abe1b98b536..37083beac89 100644
--- a/mysql-test/r/ndb_basic.result
+++ b/mysql-test/r/ndb_basic.result
@@ -414,3 +414,134 @@ select * from t1 where b IS NOT NULL;
a b
1
drop table t1;
+create table t1 (
+c1 int,
+c2 int,
+c3 int,
+c4 int,
+c5 int,
+c6 int,
+c7 int,
+c8 int,
+c9 int,
+c10 int,
+c11 int,
+c12 int,
+c13 int,
+c14 int,
+c15 int,
+c16 int,
+c17 int,
+c18 int,
+c19 int,
+c20 int,
+c21 int,
+c22 int,
+c23 int,
+c24 int,
+c25 int,
+c26 int,
+c27 int,
+c28 int,
+c29 int,
+c30 int,
+c31 int,
+c32 int,
+c33 int,
+c34 int,
+c35 int,
+c36 int,
+c37 int,
+c38 int,
+c39 int,
+c40 int,
+c41 int,
+c42 int,
+c43 int,
+c44 int,
+c45 int,
+c46 int,
+c47 int,
+c48 int,
+c49 int,
+c50 int,
+c51 int,
+c52 int,
+c53 int,
+c54 int,
+c55 int,
+c56 int,
+c57 int,
+c58 int,
+c59 int,
+c60 int,
+c61 int,
+c62 int,
+c63 int,
+c64 int,
+c65 int,
+c66 int,
+c67 int,
+c68 int,
+c69 int,
+c70 int,
+c71 int,
+c72 int,
+c73 int,
+c74 int,
+c75 int,
+c76 int,
+c77 int,
+c78 int,
+c79 int,
+c80 int,
+c81 int,
+c82 int,
+c83 int,
+c84 int,
+c85 int,
+c86 int,
+c87 int,
+c88 int,
+c89 int,
+c90 int,
+c91 int,
+c92 int,
+c93 int,
+c94 int,
+c95 int,
+c96 int,
+c97 int,
+c98 int,
+c99 int,
+c100 int,
+c101 int,
+c102 int,
+c103 int,
+c104 int,
+c105 int,
+c106 int,
+c107 int,
+c108 int,
+c109 int,
+c110 int,
+c111 int,
+c112 int,
+c113 int,
+c114 int,
+c115 int,
+c116 int,
+c117 int,
+c118 int,
+c119 int,
+c120 int,
+c121 int,
+c122 int,
+c123 int,
+c124 int,
+c125 int,
+c126 int,
+c127 int,
+c128 int,
+primary key(c1)) engine=ndb;
+drop table t1;
diff --git a/mysql-test/t/ndb_basic.test b/mysql-test/t/ndb_basic.test
index e79815bbeb1..0d4bffce80d 100644
--- a/mysql-test/t/ndb_basic.test
+++ b/mysql-test/t/ndb_basic.test
@@ -371,3 +371,139 @@ select * from t1 order by b;
select * from t1 where b IS NULL;
select * from t1 where b IS NOT NULL;
drop table t1;
+
+#
+# test the limit of no of attributes in one table
+#
+
+create table t1 (
+c1 int,
+c2 int,
+c3 int,
+c4 int,
+c5 int,
+c6 int,
+c7 int,
+c8 int,
+c9 int,
+c10 int,
+c11 int,
+c12 int,
+c13 int,
+c14 int,
+c15 int,
+c16 int,
+c17 int,
+c18 int,
+c19 int,
+c20 int,
+c21 int,
+c22 int,
+c23 int,
+c24 int,
+c25 int,
+c26 int,
+c27 int,
+c28 int,
+c29 int,
+c30 int,
+c31 int,
+c32 int,
+c33 int,
+c34 int,
+c35 int,
+c36 int,
+c37 int,
+c38 int,
+c39 int,
+c40 int,
+c41 int,
+c42 int,
+c43 int,
+c44 int,
+c45 int,
+c46 int,
+c47 int,
+c48 int,
+c49 int,
+c50 int,
+c51 int,
+c52 int,
+c53 int,
+c54 int,
+c55 int,
+c56 int,
+c57 int,
+c58 int,
+c59 int,
+c60 int,
+c61 int,
+c62 int,
+c63 int,
+c64 int,
+c65 int,
+c66 int,
+c67 int,
+c68 int,
+c69 int,
+c70 int,
+c71 int,
+c72 int,
+c73 int,
+c74 int,
+c75 int,
+c76 int,
+c77 int,
+c78 int,
+c79 int,
+c80 int,
+c81 int,
+c82 int,
+c83 int,
+c84 int,
+c85 int,
+c86 int,
+c87 int,
+c88 int,
+c89 int,
+c90 int,
+c91 int,
+c92 int,
+c93 int,
+c94 int,
+c95 int,
+c96 int,
+c97 int,
+c98 int,
+c99 int,
+c100 int,
+c101 int,
+c102 int,
+c103 int,
+c104 int,
+c105 int,
+c106 int,
+c107 int,
+c108 int,
+c109 int,
+c110 int,
+c111 int,
+c112 int,
+c113 int,
+c114 int,
+c115 int,
+c116 int,
+c117 int,
+c118 int,
+c119 int,
+c120 int,
+c121 int,
+c122 int,
+c123 int,
+c124 int,
+c125 int,
+c126 int,
+c127 int,
+c128 int,
+primary key(c1)) engine=ndb;
+drop table t1;
diff --git a/ndb/include/kernel/ndb_limits.h b/ndb/include/kernel/ndb_limits.h
index 88fcff22da7..48a56c019bb 100644
--- a/ndb/include/kernel/ndb_limits.h
+++ b/ndb/include/kernel/ndb_limits.h
@@ -117,4 +117,9 @@
*/
#define NDB_BLOB_HEAD_SIZE 2 /* sizeof(NdbBlob::Head) >> 2 */
+/*
+ * Long signals
+ */
+#define NDB_SECTION_SEGMENT_SZ 60
+
#endif
diff --git a/ndb/include/ndbapi/ndbapi_limits.h b/ndb/include/ndbapi/ndbapi_limits.h
index 1cf2d9b342d..6b8787d587d 100644
--- a/ndb/include/ndbapi/ndbapi_limits.h
+++ b/ndb/include/ndbapi/ndbapi_limits.h
@@ -22,7 +22,7 @@
#define NDB_MAX_DATABASE_NAME_SIZE 128
#define NDB_MAX_SCHEMA_NAME_SIZE 128
#define NDB_MAX_TAB_NAME_SIZE 128
-#define NDB_MAX_ATTRIBUTES_IN_TABLE 91
+#define NDB_MAX_ATTRIBUTES_IN_TABLE 128
#define NDB_MAX_TUPLE_SIZE_IN_WORDS 1023
#define NDB_MAX_KEYSIZE_IN_WORDS 1023
diff --git a/ndb/src/kernel/vm/LongSignal.hpp b/ndb/src/kernel/vm/LongSignal.hpp
index f9ed443d995..9818358011f 100644
--- a/ndb/src/kernel/vm/LongSignal.hpp
+++ b/ndb/src/kernel/vm/LongSignal.hpp
@@ -25,7 +25,7 @@
*/
struct SectionSegment {
- STATIC_CONST( DataLength = 60 );
+ STATIC_CONST( DataLength = NDB_SECTION_SEGMENT_SZ );
Uint32 m_ownerRef;
Uint32 m_sz;
diff --git a/ndb/src/ndbapi/TransporterFacade.cpp b/ndb/src/ndbapi/TransporterFacade.cpp
index 0377cf0c84b..6495fee444a 100644
--- a/ndb/src/ndbapi/TransporterFacade.cpp
+++ b/ndb/src/ndbapi/TransporterFacade.cpp
@@ -34,6 +34,7 @@
#include
#include
#include
+#include
//#define REPORT_TRANSPORTER
//#define API_TRACE;
@@ -834,10 +835,14 @@ TransporterFacade::sendSignalUnCond(NdbApiSignal * aSignal, NodeId aNode){
return (ss == SEND_OK ? 0 : -1);
}
-#define CHUNK_SZ 100u
+#define CHUNK_SZ NDB_SECTION_SEGMENT_SZ*1
int
TransporterFacade::sendFragmentedSignal(NdbApiSignal* aSignal, NodeId aNode,
- LinearSectionPtr ptr[3], Uint32 secs){
+ LinearSectionPtr ptr[3], Uint32 secs)
+{
+ if(getIsNodeSendable(aNode) != true)
+ return -1;
+
NdbApiSignal tmp_signal(*(SignalHeader*)aSignal);
LinearSectionPtr tmp_ptr[3];
Uint32 unique_id= m_fragmented_signal_id++; // next unique id
@@ -855,41 +860,47 @@ TransporterFacade::sendFragmentedSignal(NdbApiSignal* aSignal, NodeId aNode,
if (chunk_sz + save_sz > CHUNK_SZ) {
// truncate
unsigned send_sz= CHUNK_SZ - chunk_sz;
+ if (i != start_i) // first piece of a new section has to be a multiple of NDB_SECTION_SEGMENT_SZ
+ {
+ send_sz=
+ NDB_SECTION_SEGMENT_SZ
+ *(send_sz+NDB_SECTION_SEGMENT_SZ-1)
+ /NDB_SECTION_SEGMENT_SZ;
+ if (send_sz > save_sz)
+ send_sz= save_sz;
+ }
tmp_ptr[i].sz= send_sz;
- if (fragment_info < 2)
+
+ if (fragment_info < 2) // 1 = first fragment, 2 = middle fragments
fragment_info++;
// send tmp_signal
tmp_data[i-start_i+1]= unique_id;
tmp_signal.setLength(i-start_i+2);
tmp_signal.m_fragmentInfo= fragment_info;
+ tmp_signal.m_noOfSections= i-start_i+1;
// do prepare send
{
- int ret;
- if(getIsNodeSendable(aNode) == true){
- SendStatus ss = theTransporterRegistry->prepareSend
- (&tmp_signal,
- 1, // JBB
- tmp_signal.getDataPtrSend(),
- aNode,
- &ptr[start_i]);
- assert(ss != SEND_MESSAGE_TOO_BIG);
- ret = (ss == SEND_OK ? 0 : -1);
- } else
- ret = -1;
- if (ret != SEND_OK)
- return ret;
+ SendStatus ss = theTransporterRegistry->prepareSend
+ (&tmp_signal,
+ 1, /*JBB*/
+ tmp_data,
+ aNode,
+ &tmp_ptr[start_i]);
+ assert(ss != SEND_MESSAGE_TOO_BIG);
+ if (ss != SEND_OK) return -1;
}
-
// setup variables for next signal
start_i= i;
chunk_sz= 0;
tmp_ptr[i].sz= save_sz-send_sz;
tmp_ptr[i].p+= send_sz;
+ if (tmp_ptr[i].sz == 0)
+ i++;
}
else
{
- chunk_sz+= save_sz;
+ chunk_sz+=save_sz;
i++;
}
}
@@ -907,7 +918,7 @@ TransporterFacade::sendFragmentedSignal(NdbApiSignal* aSignal, NodeId aNode,
aSignal->setLength(a_sz+tmp_sz+1);
// send last fragment
- aSignal->m_fragmentInfo= 3;
+ aSignal->m_fragmentInfo= 3; // 3 = last fragment
aSignal->m_noOfSections= i-start_i;
} else {
aSignal->m_noOfSections= secs;
@@ -915,17 +926,16 @@ TransporterFacade::sendFragmentedSignal(NdbApiSignal* aSignal, NodeId aNode,
// send aSignal
int ret;
- if(getIsNodeSendable(aNode) == true){
+ {
SendStatus ss = theTransporterRegistry->prepareSend
- (aSignal,
- 1, // JBB
+ (aSignal,
+ 1/*JBB*/,
aSignal->getDataPtrSend(),
- aNode,
- &ptr[start_i]);
+ aNode,
+ &tmp_ptr[start_i]);
assert(ss != SEND_MESSAGE_TOO_BIG);
ret = (ss == SEND_OK ? 0 : -1);
- } else
- ret = -1;
+ }
aSignal->m_noOfSections = 0;
aSignal->m_fragmentInfo = 0;
aSignal->setLength(a_sz);
From 2d455470b695f91a6bcec0f440a488b44e5dd262 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Thu, 28 Oct 2004 11:24:59 +0000
Subject: [PATCH 08/59] ndbapi_limits.h: corrected define for
NDB_MAX_TUPLE_SIZE_IN_WORDS
---
ndb/include/ndbapi/ndbapi_limits.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ndb/include/ndbapi/ndbapi_limits.h b/ndb/include/ndbapi/ndbapi_limits.h
index 6b8787d587d..b3577119e33 100644
--- a/ndb/include/ndbapi/ndbapi_limits.h
+++ b/ndb/include/ndbapi/ndbapi_limits.h
@@ -24,7 +24,7 @@
#define NDB_MAX_TAB_NAME_SIZE 128
#define NDB_MAX_ATTRIBUTES_IN_TABLE 128
-#define NDB_MAX_TUPLE_SIZE_IN_WORDS 1023
+#define NDB_MAX_TUPLE_SIZE_IN_WORDS 2013
#define NDB_MAX_KEYSIZE_IN_WORDS 1023
#define NDB_MAX_KEY_SIZE NDB_MAX_KEYSIZE_IN_WORDS*sizeof(Uint32)
#define NDB_MAX_TUPLE_SIZE NDB_MAX_TUPLE_SIZE_IN_WORDS*sizeof(uint32)
From af5f0b95c4cd308b21187131dddc77cedace619a Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Thu, 28 Oct 2004 11:56:09 +0000
Subject: [PATCH 09/59] Dbdict.cpp: changed to using fragmented signals for
CREATE_TABLE_REQ
---
ndb/src/kernel/blocks/dbdict/Dbdict.cpp | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
index d1a8128ea7f..882557daae1 100644
--- a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
+++ b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
@@ -3661,9 +3661,8 @@ Dbdict::execCREATE_FRAGMENTATION_CONF(Signal* signal){
req->tableId = tabPtr.i;
req->tableVersion = tabEntry->m_tableVersion + 1;
- sendSignal(rg, GSN_CREATE_TAB_REQ, signal,
- CreateTabReq::SignalLength, JBB);
-
+ sendFragmentedSignal(rg, GSN_CREATE_TAB_REQ, signal,
+ CreateTabReq::SignalLength, JBB);
return;
}
From 1f646ecc7ce9347eca5548729172d59a31d5e095 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Thu, 28 Oct 2004 13:50:46 +0000
Subject: [PATCH 10/59] set set "CHUNK_SZ" for fragmented signal to real value
added API_TRACE code removed old implementation of fragmented signal
---
ndb/src/ndbapi/TransporterFacade.cpp | 80 +++++-----------------------
1 file changed, 14 insertions(+), 66 deletions(-)
diff --git a/ndb/src/ndbapi/TransporterFacade.cpp b/ndb/src/ndbapi/TransporterFacade.cpp
index 6495fee444a..2bf2b39f9a6 100644
--- a/ndb/src/ndbapi/TransporterFacade.cpp
+++ b/ndb/src/ndbapi/TransporterFacade.cpp
@@ -835,7 +835,7 @@ TransporterFacade::sendSignalUnCond(NdbApiSignal * aSignal, NodeId aNode){
return (ss == SEND_OK ? 0 : -1);
}
-#define CHUNK_SZ NDB_SECTION_SEGMENT_SZ*1
+#define CHUNK_SZ NDB_SECTION_SEGMENT_SZ*64 // related to MAX_MESSAGE_SIZE
int
TransporterFacade::sendFragmentedSignal(NdbApiSignal* aSignal, NodeId aNode,
LinearSectionPtr ptr[3], Uint32 secs)
@@ -843,6 +843,19 @@ TransporterFacade::sendFragmentedSignal(NdbApiSignal* aSignal, NodeId aNode,
if(getIsNodeSendable(aNode) != true)
return -1;
+#ifdef API_TRACE
+ if(setSignalLog() && TRACE_GSN(aSignal->theVerId_signalNumber)){
+ Uint32 tmp = aSignal->theSendersBlockRef;
+ aSignal->theSendersBlockRef = numberToRef(tmp, theOwnId);
+ signalLogger.sendSignal(* aSignal,
+ 1,
+ aSignal->getDataPtrSend(),
+ aNode,
+ ptr, secs);
+ aSignal->theSendersBlockRef = tmp;
+ }
+#endif
+
NdbApiSignal tmp_signal(*(SignalHeader*)aSignal);
LinearSectionPtr tmp_ptr[3];
Uint32 unique_id= m_fragmented_signal_id++; // next unique id
@@ -942,71 +955,6 @@ TransporterFacade::sendFragmentedSignal(NdbApiSignal* aSignal, NodeId aNode,
return ret;
}
-#if 0
-int
-TransporterFacade::sendFragmentedSignal(NdbApiSignal* aSignal, NodeId aNode,
- LinearSectionPtr ptr[3], Uint32 secs){
- aSignal->m_noOfSections = secs;
- if(getIsNodeSendable(aNode) == true){
-#ifdef API_TRACE
- if(setSignalLog() && TRACE_GSN(aSignal->theVerId_signalNumber)){
- Uint32 tmp = aSignal->theSendersBlockRef;
- aSignal->theSendersBlockRef = numberToRef(tmp, theOwnId);
- signalLogger.sendSignal(* aSignal,
- 1,
- aSignal->getDataPtrSend(),
- aNode,
- ptr, secs);
- signalLogger.flushSignalLog();
- aSignal->theSendersBlockRef = tmp;
- }
-#endif
- SendStatus ss = theTransporterRegistry->prepareSend
- (aSignal,
- 1, // JBB
- aSignal->getDataPtrSend(),
- aNode,
- ptr);
- assert(ss != SEND_MESSAGE_TOO_BIG);
- aSignal->m_noOfSections = 0;
- return (ss == SEND_OK ? 0 : -1);
- }
- aSignal->m_noOfSections = 0;
- return -1;
-}
-#endif
-
-
-int
-TransporterFacade::sendFragmentedSignalUnCond(NdbApiSignal* aSignal,
- NodeId aNode,
- LinearSectionPtr ptr[3],
- Uint32 secs){
- aSignal->m_noOfSections = secs;
-
-#ifdef API_TRACE
- if(setSignalLog() && TRACE_GSN(aSignal->theVerId_signalNumber)){
- Uint32 tmp = aSignal->theSendersBlockRef;
- aSignal->theSendersBlockRef = numberToRef(tmp, theOwnId);
- signalLogger.sendSignal(* aSignal,
- 1,
- aSignal->getDataPtrSend(),
- aNode,
- ptr, secs);
- aSignal->theSendersBlockRef = tmp;
- }
-#endif
- SendStatus ss =
- theTransporterRegistry->prepareSend(aSignal, 1, // JBB
- aSignal->getDataPtrSend(),
- aNode, ptr);
- assert(ss != SEND_MESSAGE_TOO_BIG);
- aSignal->m_noOfSections = 0;
- return (ss == SEND_OK ? 0 : -1);
-}
-
-
-
/******************************************************************************
* CONNECTION METHODS Etc
******************************************************************************/
From bbe970beabf0439fc11ffbea60d60e98755fdbac Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Thu, 28 Oct 2004 14:49:40 +0000
Subject: [PATCH 11/59] scan should not send fragmented signal use new
sendSignal method instead new send signal method which sends segments
remove unused method sendFragmentedSignalUnCond
---
ndb/src/ndbapi/NdbScanOperation.cpp | 4 ++--
ndb/src/ndbapi/TransporterFacade.cpp | 32 ++++++++++++++++++++++++++++
ndb/src/ndbapi/TransporterFacade.hpp | 7 ++----
3 files changed, 36 insertions(+), 7 deletions(-)
diff --git a/ndb/src/ndbapi/NdbScanOperation.cpp b/ndb/src/ndbapi/NdbScanOperation.cpp
index fd63ce96f25..86bac7deb16 100644
--- a/ndb/src/ndbapi/NdbScanOperation.cpp
+++ b/ndb/src/ndbapi/NdbScanOperation.cpp
@@ -612,7 +612,7 @@ NdbScanOperation::send_next_scan(Uint32 cnt, bool stopScanFlag){
LinearSectionPtr ptr[3];
ptr[0].p = prep_array;
ptr[0].sz = cnt;
- ret = tp->sendFragmentedSignal(&tSignal, nodeId, ptr, 1);
+ ret = tp->sendSignal(&tSignal, nodeId, ptr, 1);
} else {
tSignal.setLength(4+cnt);
ret = tp->sendSignal(&tSignal, nodeId);
@@ -803,7 +803,7 @@ NdbScanOperation::doSendScan(int aProcessorId)
LinearSectionPtr ptr[3];
ptr[0].p = m_prepared_receivers;
ptr[0].sz = theParallelism;
- if (tp->sendFragmentedSignal(tSignal, aProcessorId, ptr, 1) == -1) {
+ if (tp->sendSignal(tSignal, aProcessorId, ptr, 1) == -1) {
setErrorCode(4002);
return -1;
}
diff --git a/ndb/src/ndbapi/TransporterFacade.cpp b/ndb/src/ndbapi/TransporterFacade.cpp
index 2bf2b39f9a6..dfb090c8416 100644
--- a/ndb/src/ndbapi/TransporterFacade.cpp
+++ b/ndb/src/ndbapi/TransporterFacade.cpp
@@ -955,6 +955,38 @@ TransporterFacade::sendFragmentedSignal(NdbApiSignal* aSignal, NodeId aNode,
return ret;
}
+int
+TransporterFacade::sendSignal(NdbApiSignal* aSignal, NodeId aNode,
+ LinearSectionPtr ptr[3], Uint32 secs){
+ aSignal->m_noOfSections = secs;
+ if(getIsNodeSendable(aNode) == true){
+#ifdef API_TRACE
+ if(setSignalLog() && TRACE_GSN(aSignal->theVerId_signalNumber)){
+ Uint32 tmp = aSignal->theSendersBlockRef;
+ aSignal->theSendersBlockRef = numberToRef(tmp, theOwnId);
+ signalLogger.sendSignal(* aSignal,
+ 1,
+ aSignal->getDataPtrSend(),
+ aNode,
+ ptr, secs);
+ signalLogger.flushSignalLog();
+ aSignal->theSendersBlockRef = tmp;
+ }
+#endif
+ SendStatus ss = theTransporterRegistry->prepareSend
+ (aSignal,
+ 1, // JBB
+ aSignal->getDataPtrSend(),
+ aNode,
+ ptr);
+ assert(ss != SEND_MESSAGE_TOO_BIG);
+ aSignal->m_noOfSections = 0;
+ return (ss == SEND_OK ? 0 : -1);
+ }
+ aSignal->m_noOfSections = 0;
+ return -1;
+}
+
/******************************************************************************
* CONNECTION METHODS Etc
******************************************************************************/
diff --git a/ndb/src/ndbapi/TransporterFacade.hpp b/ndb/src/ndbapi/TransporterFacade.hpp
index b288e2ee8e6..5680e3a6f03 100644
--- a/ndb/src/ndbapi/TransporterFacade.hpp
+++ b/ndb/src/ndbapi/TransporterFacade.hpp
@@ -69,14 +69,11 @@ public:
// Only sends to nodes which are alive
int sendSignal(NdbApiSignal * signal, NodeId nodeId);
+ int sendSignal(NdbApiSignal*, NodeId,
+ LinearSectionPtr ptr[3], Uint32 secs);
int sendFragmentedSignal(NdbApiSignal*, NodeId,
LinearSectionPtr ptr[3], Uint32 secs);
- //Dirrrrty
- int sendFragmentedSignalUnCond(NdbApiSignal*, NodeId,
- LinearSectionPtr ptr[3], Uint32 secs);
-
-
// Is node available for running transactions
bool get_node_alive(NodeId nodeId) const;
bool get_node_stopping(NodeId nodeId) const;
From 289f68a1b97d5e2236efc9d05e8aba94490791ac Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Thu, 28 Oct 2004 15:35:06 +0000
Subject: [PATCH 12/59] test that attribute name truncation works
exposed the attribute name size limit for handler added field name
truncation to ndb handler
---
mysql-test/t/ndb_basic.test | 15 +++++++++++++++
ndb/include/ndbapi/ndbapi_limits.h | 1 +
sql/ha_ndbcluster.cc | 21 ++++++++++++++++++---
3 files changed, 34 insertions(+), 3 deletions(-)
diff --git a/mysql-test/t/ndb_basic.test b/mysql-test/t/ndb_basic.test
index 0d4bffce80d..f5bed3dcdff 100644
--- a/mysql-test/t/ndb_basic.test
+++ b/mysql-test/t/ndb_basic.test
@@ -507,3 +507,18 @@ c127 int,
c128 int,
primary key(c1)) engine=ndb;
drop table t1;
+
+#
+# test max size of attribute name and truncation
+#
+
+create table t1 (
+a1234567890123456789012345678901234567890 int primary key,
+a12345678901234567890123456789a1234567890 int,
+index(a12345678901234567890123456789a1234567890)
+) engine=ndb;
+show tables;
+insert into t1 values (1,1),(2,1),(3,1),(4,1),(5,2),(6,1),(7,1);
+explain select * from t1 where a12345678901234567890123456789a1234567890=2;
+select * from t1 where a12345678901234567890123456789a1234567890=2;
+drop table t1;
diff --git a/ndb/include/ndbapi/ndbapi_limits.h b/ndb/include/ndbapi/ndbapi_limits.h
index b3577119e33..05556ab2f5f 100644
--- a/ndb/include/ndbapi/ndbapi_limits.h
+++ b/ndb/include/ndbapi/ndbapi_limits.h
@@ -22,6 +22,7 @@
#define NDB_MAX_DATABASE_NAME_SIZE 128
#define NDB_MAX_SCHEMA_NAME_SIZE 128
#define NDB_MAX_TAB_NAME_SIZE 128
+#define NDB_MAX_ATTR_NAME_SIZE 32
#define NDB_MAX_ATTRIBUTES_IN_TABLE 128
#define NDB_MAX_TUPLE_SIZE_IN_WORDS 2013
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index 044cb85b913..838cf69855a 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -1393,8 +1393,13 @@ int ha_ndbcluster::set_bounds(NdbIndexScanOperation *op,
// Set bound if not cancelled via type -1
if (p.bound_type != -1)
- if (op->setBound(field->field_name, p.bound_type, p.bound_ptr))
+ {
+ char truncated_field_name[NDB_MAX_ATTR_NAME_SIZE];
+ strnmov(truncated_field_name,field->field_name,sizeof(truncated_field_name));
+ truncated_field_name[sizeof(truncated_field_name)-1]= '\0';
+ if (op->setBound(truncated_field_name, p.bound_type, p.bound_ptr))
ERR_RETURN(op->getNdbError());
+ }
}
}
@@ -3102,7 +3107,12 @@ static int create_ndb_column(NDBCOL &col,
HA_CREATE_INFO *info)
{
// Set name
- col.setName(field->field_name);
+ {
+ char truncated_field_name[NDB_MAX_ATTR_NAME_SIZE];
+ strnmov(truncated_field_name,field->field_name,sizeof(truncated_field_name));
+ truncated_field_name[sizeof(truncated_field_name)-1]= '\0';
+ col.setName(truncated_field_name);
+ }
// Get char set
CHARSET_INFO *cs= field->charset();
// Set type and sizes
@@ -3430,7 +3440,12 @@ int ha_ndbcluster::create_index(const char *name,
{
Field *field= key_part->field;
DBUG_PRINT("info", ("attr: %s", field->field_name));
- ndb_index.addColumnName(field->field_name);
+ {
+ char truncated_field_name[NDB_MAX_ATTR_NAME_SIZE];
+ strnmov(truncated_field_name,field->field_name,sizeof(truncated_field_name));
+ truncated_field_name[sizeof(truncated_field_name)-1]= '\0';
+ ndb_index.addColumnName(truncated_field_name);
+ }
}
if (dict->createIndex(ndb_index))
From 54e72c72071972d4051d8e6f96ed25ad688483ff Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Thu, 28 Oct 2004 15:43:16 +0000
Subject: [PATCH 13/59] ndb_basic.result: forgot to commit new result
---
mysql-test/r/ndb_basic.result | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/mysql-test/r/ndb_basic.result b/mysql-test/r/ndb_basic.result
index 37083beac89..604084a72c2 100644
--- a/mysql-test/r/ndb_basic.result
+++ b/mysql-test/r/ndb_basic.result
@@ -545,3 +545,19 @@ c127 int,
c128 int,
primary key(c1)) engine=ndb;
drop table t1;
+create table t1 (
+a1234567890123456789012345678901234567890 int primary key,
+a12345678901234567890123456789a1234567890 int,
+index(a12345678901234567890123456789a1234567890)
+) engine=ndb;
+show tables;
+Tables_in_test
+t1
+insert into t1 values (1,1),(2,1),(3,1),(4,1),(5,2),(6,1),(7,1);
+explain select * from t1 where a12345678901234567890123456789a1234567890=2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref a12345678901234567890123456789a1234567890 a12345678901234567890123456789a1234567890 5 const 10 Using where
+select * from t1 where a12345678901234567890123456789a1234567890=2;
+a1234567890123456789012345678901234567890 a12345678901234567890123456789a1234567890
+5 2
+drop table t1;
From 8894a6bb73be7cfdc649a97e08c0ad4888cc14f3 Mon Sep 17 00:00:00 2001
From: "bell@sanja.is.com.ua" <>
Date: Thu, 28 Oct 2004 21:14:00 +0300
Subject: [PATCH 14/59] close table before next iteration of table proccesing
in mysql_admin_table (to allow open next table)
---
sql/sql_table.cc | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 8190e31bc0b..65690e56039 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1268,9 +1268,13 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
if (prepare_func)
{
switch ((*prepare_func)(thd, table, check_opt)) {
- case 1: continue; // error, message written to net
- case -1: goto err; // error, message could be written to net
- default: ; // should be 0 otherwise
+ case 1: // error, message written to net
+ close_thread_tables(thd);
+ continue;
+ case -1: // error, message could be written to net
+ goto err;
+ default: // should be 0 otherwise
+ ;
}
}
From 35e8670301f854b5b1541cd39deaab2f0c046bbd Mon Sep 17 00:00:00 2001
From: "lenz@mysql.com" <>
Date: Fri, 29 Oct 2004 09:24:21 +0200
Subject: [PATCH 15/59] - bumped up version number from 4.0.22 to 4.0.23 in
configure.in - tagged ChangeSet@1.2048.1.2 as "mysql-4.0.22"
---
configure.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/configure.in b/configure.in
index d4073ea441b..d4ede468435 100644
--- a/configure.in
+++ b/configure.in
@@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script.
AC_INIT(sql/mysqld.cc)
AC_CANONICAL_SYSTEM
# The Docs Makefile.am parses this line!
-AM_INIT_AUTOMAKE(mysql, 4.0.22)
+AM_INIT_AUTOMAKE(mysql, 4.0.23)
AM_CONFIG_HEADER(config.h)
PROTOCOL_VERSION=10
From 19bc50957fdc53d3df7f803ed7b8202b6a18c2e4 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Fri, 29 Oct 2004 09:49:04 +0000
Subject: [PATCH 16/59] Tru64 cxx compiler fix cxx does not include
-I/ust/include.dtk as it should removed dependency on ndb_types
---
configure.in | 3 ++-
ndb/include/ndbapi/ndbapi_limits.h | 4 ++--
sql/ha_ndbcluster.h | 1 -
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/configure.in b/configure.in
index 656af354607..ec003b55cb5 100644
--- a/configure.in
+++ b/configure.in
@@ -1144,7 +1144,8 @@ dnl Is this the right match for DEC OSF on alpha?
# gethostbyname_r is deprecated and doesn't work ok on OSF1
CFLAGS="$CFLAGS -DUNDEF_HAVE_GETHOSTBYNAME_R"
CXXFLAGS="$CXXFLAGS -DUNDEF_HAVE_GETHOSTBYNAME_R"
- ndb_cxxflags_fix="$ndb_cxxflags_fix -I/usr/include.dtk"
+ # fix to handle include of correctly on OSF1 with cxx compiler
+ CXXFLAGS="$CXXFLAGS -I/usr/include/cxx -I/usr/include/cxx_cname -I/usr/include.dtk"
;;
*netware*)
# No need for curses library so set it to null
diff --git a/ndb/include/ndbapi/ndbapi_limits.h b/ndb/include/ndbapi/ndbapi_limits.h
index 1cf2d9b342d..f812fa2d69d 100644
--- a/ndb/include/ndbapi/ndbapi_limits.h
+++ b/ndb/include/ndbapi/ndbapi_limits.h
@@ -26,8 +26,8 @@
#define NDB_MAX_TUPLE_SIZE_IN_WORDS 1023
#define NDB_MAX_KEYSIZE_IN_WORDS 1023
-#define NDB_MAX_KEY_SIZE NDB_MAX_KEYSIZE_IN_WORDS*sizeof(Uint32)
-#define NDB_MAX_TUPLE_SIZE NDB_MAX_TUPLE_SIZE_IN_WORDS*sizeof(uint32)
+#define NDB_MAX_KEY_SIZE (NDB_MAX_KEYSIZE_IN_WORDS*4)
+#define NDB_MAX_TUPLE_SIZE (NDB_MAX_TUPLE_SIZE_IN_WORDS*4)
#define NDB_MAX_ACTIVE_EVENTS 100
#endif
diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h
index 8224d1c4167..b33a0657d4f 100644
--- a/sql/ha_ndbcluster.h
+++ b/sql/ha_ndbcluster.h
@@ -26,7 +26,6 @@
#endif
#include
-#include
class Ndb; // Forward declaration
class NdbOperation; // Forward declaration
From ea49a5181ae9ae0b0bca6d1b9e1ca26023a68b4c Mon Sep 17 00:00:00 2001
From: "bar@mysql.com" <>
Date: Fri, 29 Oct 2004 16:00:03 +0500
Subject: [PATCH 17/59] Allow to convert to non-Unicode charset when mixing a
string constant with a column. The string is converted into the column
character set. It conversion doesn't lose data, then operation is possible.
Otherwise, give an error, as it was earlier.
---
mysql-test/r/ctype_recoding.result | 12 +++
mysql-test/t/ctype_recoding.test | 22 ++++++
sql/item.cc | 81 +++++++++++++++-----
sql/item.h | 16 +++-
sql/item_cmpfunc.cc | 118 +++++++++++++++++------------
sql/item_func.cc | 8 +-
sql/item_func.h | 4 +-
7 files changed, 187 insertions(+), 74 deletions(-)
diff --git a/mysql-test/r/ctype_recoding.result b/mysql-test/r/ctype_recoding.result
index 72d19885101..dc1f4c12e25 100644
--- a/mysql-test/r/ctype_recoding.result
+++ b/mysql-test/r/ctype_recoding.result
@@ -174,3 +174,15 @@ Warnings:
Warning 1265 Data truncated for column 'a' at row 1
Warning 1265 Data truncated for column 'b' at row 1
drop table t1;
+set names koi8r;
+create table t1 (a char(10) character set cp1251);
+insert into t1 values (_koi8r'×ÁÓÑ');
+select * from t1 where a=_koi8r'×ÁÓÑ';
+a
+×ÁÓÑ
+select * from t1 where a=concat(_koi8r'×ÁÓÑ');
+ERROR HY000: Illegal mix of collations (cp1251_general_ci,IMPLICIT) and (koi8r_general_ci,COERCIBLE) for operation '='
+select * from t1 where a=_latin1'×ÁÓÑ';
+ERROR HY000: Illegal mix of collations (cp1251_general_ci,IMPLICIT) and (latin1_swedish_ci,COERCIBLE) for operation '='
+drop table t1;
+set names latin1;
diff --git a/mysql-test/t/ctype_recoding.test b/mysql-test/t/ctype_recoding.test
index 5f417352d95..dab898e9f2c 100644
--- a/mysql-test/t/ctype_recoding.test
+++ b/mysql-test/t/ctype_recoding.test
@@ -131,3 +131,25 @@ create table t1 (a char(10) character set koi8r, b text character set koi8r);
insert into t1 values ('test','test');
insert into t1 values ('ÊÃÕË','ÊÃÕË');
drop table t1;
+
+#
+# Try to apply an automatic conversion in some cases:
+# E.g. when mixing a column to a string, the string
+# is converted into the column character set.
+# If conversion loses data, then error. Otherwise,
+# the string is replaced by its converted representation
+#
+set names koi8r;
+create table t1 (a char(10) character set cp1251);
+insert into t1 values (_koi8r'×ÁÓÑ');
+# this is possible:
+select * from t1 where a=_koi8r'×ÁÓÑ';
+# this is not possible, because we have a function, not just a constant:
+--error 1267
+select * from t1 where a=concat(_koi8r'×ÁÓÑ');
+# this is not posible, cannot convert _latin1'×ÁÓÑ' into cp1251:
+--error 1267
+select * from t1 where a=_latin1'×ÁÓÑ';
+drop table t1;
+set names latin1;
+
diff --git a/sql/item.cc b/sql/item.cc
index b4c416e7741..18025d6d689 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -259,7 +259,43 @@ CHARSET_INFO *Item::default_charset()
return current_thd->variables.collation_connection;
}
-bool DTCollation::aggregate(DTCollation &dt, bool superset_conversion)
+
+/*
+ Aggregate two collations together taking
+ into account their coercibility (aka derivation):
+
+ 0 == DERIVATION_EXPLICIT - an explicitely written COLLATE clause
+ 1 == DERIVATION_NONE - a mix of two different collations
+ 2 == DERIVATION_IMPLICIT - a column
+ 3 == DERIVATION_COERCIBLE - a string constant
+
+ The most important rules are:
+
+ 1. If collations are the same:
+ chose this collation, and the strongest derivation.
+
+ 2. If collations are different:
+ - Character sets may differ, but only if conversion without
+ data loss is possible. The caller provides flags whether
+ character set conversion attempts should be done. If no
+ flags are substituted, then the character sets must be the same.
+ Currently processed flags are:
+ MY_COLL_ALLOW_SUPERSET_CONV - allow conversion to a superset
+ MY_COLL_ALLOW_COERCIBLE_CONV - allow conversion of a coercible value
+ - two EXPLICIT collations produce an error, e.g. this is wrong:
+ CONCAT(expr1 collate latin1_swedish_ci, expr2 collate latin1_german_ci)
+ - the side with smaller derivation value wins,
+ i.e. a column is stronger than a string constant,
+ an explicit COLLATE clause is stronger than a column.
+ - if derivations are the same, we have DERIVATION_NONE,
+ we'll wait for an explicit COLLATE clause which possibly can
+ come from another argument later: for example, this is valid,
+ but we don't know yet when collecting the first two arguments:
+ CONCAT(latin1_swedish_ci_column,
+ latin1_german1_ci_column,
+ expr COLLATE latin1_german2_ci)
+*/
+bool DTCollation::aggregate(DTCollation &dt, uint flags)
{
nagg++;
if (!my_charset_same(collation, dt.collation))
@@ -290,28 +326,37 @@ bool DTCollation::aggregate(DTCollation &dt, bool superset_conversion)
else
; // Do nothing
}
- else if (superset_conversion)
+ else if ((flags & MY_COLL_ALLOW_SUPERSET_CONV) &&
+ derivation < dt.derivation &&
+ collation->state & MY_CS_UNICODE)
{
- if (derivation < dt.derivation &&
- collation->state & MY_CS_UNICODE)
- ; // Do nothing
- else if (dt.derivation < derivation &&
- dt.collation->state & MY_CS_UNICODE)
- {
- set(dt);
- strong= nagg;
- }
- else
- {
- // Cannot convert to superset
- set(0, DERIVATION_NONE);
- return 1;
- }
+ // Do nothing
+ }
+ else if ((flags & MY_COLL_ALLOW_SUPERSET_CONV) &&
+ dt.derivation < derivation &&
+ dt.collation->state & MY_CS_UNICODE)
+ {
+ set(dt);
+ strong= nagg;
+ }
+ else if ((flags & MY_COLL_ALLOW_COERCIBLE_CONV) &&
+ derivation < dt.derivation &&
+ dt.derivation == DERIVATION_COERCIBLE)
+ {
+ // Do nothing;
+ }
+ else if ((flags & MY_COLL_ALLOW_COERCIBLE_CONV) &&
+ dt.derivation < derivation &&
+ derivation == DERIVATION_COERCIBLE)
+ {
+ set(dt);
+ strong= nagg;
}
else
{
+ // Cannot apply conversion
set(0, DERIVATION_NONE);
- return 1;
+ return 1;
}
}
else if (derivation < dt.derivation)
diff --git a/sql/item.h b/sql/item.h
index e22cef7ba7f..2c0c3306c44 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -37,6 +37,16 @@ enum Derivation
DERIVATION_EXPLICIT= 0
};
+/*
+ Flags for collation aggregation modes:
+ allow conversion to a superset
+ allow conversion of a coercible value (i.e. constant).
+*/
+
+#define MY_COLL_ALLOW_SUPERSET_CONV 1
+#define MY_COLL_ALLOW_COERCIBLE_CONV 2
+
+
class DTCollation {
public:
CHARSET_INFO *collation;
@@ -72,9 +82,9 @@ public:
{ collation= collation_arg; }
void set(Derivation derivation_arg)
{ derivation= derivation_arg; }
- bool aggregate(DTCollation &dt, bool superset_conversion= FALSE);
- bool set(DTCollation &dt1, DTCollation &dt2, bool superset_conversion= FALSE)
- { set(dt1); return aggregate(dt2, superset_conversion); }
+ bool aggregate(DTCollation &dt, uint flags= 0);
+ bool set(DTCollation &dt1, DTCollation &dt2, uint flags= 0)
+ { set(dt1); return aggregate(dt2, flags); }
const char *derivation_name() const
{
switch(derivation)
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index c9396aaa67c..dc0377c791f 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -174,62 +174,87 @@ void Item_bool_func2::fix_length_and_dec()
return;
/*
- We allow to convert to Unicode character sets in some cases.
+ We allow to apply automatic character set conversion in some cases.
The conditions when conversion is possible are:
- arguments A and B have different charsets
- A wins according to coercibility rules
- - character set of A is superset for character set of B
-
+ (i.e. a column is stronger than a string constant,
+ an explicit COLLATE clause is stronger than a column)
+ - character set of A is either superset for character set of B,
+ or B is a string constant which can be converted into the
+ character set of A without data loss.
+
If all of the above is true, then it's possible to convert
B into the character set of A, and then compare according
to the collation of A.
*/
- if (args[0] && args[1])
- {
- uint strong= 0;
- uint weak= 0;
- uint32 dummy_offset;
- DTCollation coll;
+ uint32 dummy_offset;
+ DTCollation coll;
- if (args[0]->result_type() == STRING_RESULT &&
- args[1]->result_type() == STRING_RESULT &&
- String::needs_conversion(0, args[0]->collation.collation,
- args[1]->collation.collation,
- &dummy_offset) &&
- !coll.set(args[0]->collation, args[1]->collation, TRUE))
+ if (args[0]->result_type() == STRING_RESULT &&
+ args[1]->result_type() == STRING_RESULT &&
+ String::needs_conversion(0, args[0]->collation.collation,
+ args[1]->collation.collation,
+ &dummy_offset) &&
+ !coll.set(args[0]->collation, args[1]->collation,
+ MY_COLL_ALLOW_SUPERSET_CONV |
+ MY_COLL_ALLOW_COERCIBLE_CONV))
+ {
+ Item* conv= 0;
+ Item_arena *arena= thd->current_arena, backup;
+ uint strong= coll.strong;
+ uint weak= strong ? 0 : 1;
+ /*
+ In case we're in statement prepare, create conversion item
+ in its memory: it will be reused on each execute.
+ */
+ if (arena->is_stmt_prepare())
+ thd->set_n_backup_item_arena(arena, &backup);
+ if (args[weak]->type() == STRING_ITEM)
{
- Item* conv= 0;
- Item_arena *arena= thd->current_arena, backup;
- strong= coll.strong;
- weak= strong ? 0 : 1;
- /*
- In case we're in statement prepare, create conversion item
- in its memory: it will be reused on each execute.
- */
- if (arena->is_stmt_prepare())
- thd->set_n_backup_item_arena(arena, &backup);
- if (args[weak]->type() == STRING_ITEM)
+ uint conv_errors;
+ String tmp, cstr, *ostr= args[weak]->val_str(&tmp);
+ cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(),
+ args[strong]->collation.collation, &conv_errors);
+ if (conv_errors)
{
- String tmp, cstr;
- String *ostr= args[weak]->val_str(&tmp);
- cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(),
- args[strong]->collation.collation);
- conv= new Item_string(cstr.ptr(),cstr.length(),cstr.charset(),
- args[weak]->collation.derivation);
- ((Item_string*)conv)->str_value.copy();
+ /*
+ We could not convert a string into the character set
+ of the stronger side of the operation without data loss.
+ It can happen if we tried to combine a column with a string
+ constant, and the column charset does not cover all the
+ characters from the string. Operation cannot be done
+ correctly. Return an error.
+ */
+ my_coll_agg_error(args[0]->collation, args[1]->collation,
+ func_name());
+ return;
}
- else
- {
- conv= new Item_func_conv_charset(args[weak],
- args[strong]->collation.collation);
- conv->collation.set(args[weak]->collation.derivation);
- conv->fix_fields(thd, 0, &conv);
- }
- if (arena->is_stmt_prepare())
- thd->restore_backup_item_arena(arena, &backup);
- args[weak]= conv ? conv : args[weak];
+ conv= new Item_string(cstr.ptr(),cstr.length(),cstr.charset(),
+ args[weak]->collation.derivation);
+ ((Item_string*)conv)->str_value.copy();
}
+ else
+ {
+ if (!(coll.collation->state & MY_CS_UNICODE))
+ {
+ /*
+ Don't allow automatic conversion to non-Unicode charsets,
+ as it potentially loses data.
+ */
+ my_coll_agg_error(args[0]->collation, args[1]->collation,
+ func_name());
+ return;
+ }
+ conv= new Item_func_conv_charset(args[weak],
+ args[strong]->collation.collation);
+ conv->collation.set(args[weak]->collation.derivation);
+ conv->fix_fields(thd, 0, &conv);
+ }
+ if (arena->is_stmt_prepare())
+ thd->restore_backup_item_arena(arena, &backup);
+ args[weak]= conv ? conv : args[weak];
}
// Make a special case of compare with fields to get nicer DATE comparisons
@@ -1782,14 +1807,13 @@ void Item_func_in::fix_length_and_dec()
via creating Item_func_conv_charset().
*/
- if (agg_arg_collations_for_comparison(cmp_collation,
- args, arg_count, TRUE))
+ if (agg_arg_collations_for_comparison(cmp_collation, args, arg_count,
+ MY_COLL_ALLOW_SUPERSET_CONV))
return;
if ((!my_charset_same(args[0]->collation.collation,
cmp_collation.collation) || !const_itm))
{
- if (agg_arg_collations_for_comparison(cmp_collation,
- args, arg_count, FALSE))
+ if (agg_arg_collations_for_comparison(cmp_collation, args, arg_count))
return;
}
else
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 879c0b36bdd..3cb125d2868 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -76,7 +76,7 @@ static void my_coll_agg_error(Item** args, uint count, const char *fname)
bool Item_func::agg_arg_collations(DTCollation &c, Item **av, uint count,
- bool allow_superset_conversion)
+ uint flags)
{
uint i;
c.nagg= 0;
@@ -84,7 +84,7 @@ bool Item_func::agg_arg_collations(DTCollation &c, Item **av, uint count,
c.set(av[0]->collation);
for (i= 1; i < count; i++)
{
- if (c.aggregate(av[i]->collation, allow_superset_conversion))
+ if (c.aggregate(av[i]->collation, flags))
{
my_coll_agg_error(av, count, func_name());
return TRUE;
@@ -96,9 +96,9 @@ bool Item_func::agg_arg_collations(DTCollation &c, Item **av, uint count,
bool Item_func::agg_arg_collations_for_comparison(DTCollation &c,
Item **av, uint count,
- bool allow_superset_conv)
+ uint flags)
{
- if (agg_arg_collations(c, av, count, allow_superset_conv))
+ if (agg_arg_collations(c, av, count, flags))
return TRUE;
if (c.derivation == DERIVATION_NONE)
diff --git a/sql/item_func.h b/sql/item_func.h
index 6e43d66a32d..963038227a2 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -141,10 +141,10 @@ public:
Item *get_tmp_table_item(THD *thd);
bool agg_arg_collations(DTCollation &c, Item **items, uint nitems,
- bool allow_superset_conversion= FALSE);
+ uint flags= 0);
bool agg_arg_collations_for_comparison(DTCollation &c,
Item **items, uint nitems,
- bool allow_superset_comversion= FALSE);
+ uint flags= 0);
bool walk(Item_processor processor, byte *arg);
};
From 0a3d9a43b246cdaf57afa725134344d74e7ff07b Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Fri, 29 Oct 2004 11:06:06 +0000
Subject: [PATCH 18/59] configure.in: -I/usr/include needed for cxx on Tru64
---
configure.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/configure.in b/configure.in
index 7c6b9ff7b51..a361e11935c 100644
--- a/configure.in
+++ b/configure.in
@@ -1145,7 +1145,7 @@ dnl Is this the right match for DEC OSF on alpha?
CFLAGS="$CFLAGS -DUNDEF_HAVE_GETHOSTBYNAME_R"
CXXFLAGS="$CXXFLAGS -DUNDEF_HAVE_GETHOSTBYNAME_R"
# fix to handle include of correctly on OSF1 with cxx compiler
- CXXFLAGS="$CXXFLAGS -I/usr/include/cxx -I/usr/include/cxx_cname -I/usr/include.dtk"
+ CXXFLAGS="$CXXFLAGS -I/usr/include/cxx -I/usr/include/cxx_cname -I/usr/include -I/usr/include.dtk"
;;
*netware*)
# No need for curses library so set it to null
From 64c59b37f899e520f6ba3ff8d0f9724423eb9b88 Mon Sep 17 00:00:00 2001
From: "bar@mysql.com" <>
Date: Fri, 29 Oct 2004 16:06:51 +0500
Subject: [PATCH 19/59] item_strfunc.cc: Unnecessary code was removed.
---
sql/item_strfunc.cc | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index c51894afde4..2d9f7e7bff8 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -643,7 +643,12 @@ void Item_func_concat_ws::fix_length_and_dec()
if (agg_arg_collations(collation, args, arg_count))
return;
- max_length= arg_count > 1 ? args[0]->max_length * (arg_count - 2) : 0;
+ /*
+ arg_count cannot be less than 2,
+ it is done on parser level in sql_yacc.yy
+ so, (arg_count - 2) is safe here.
+ */
+ max_length= args[0]->max_length * (arg_count - 2);
for (uint i=1 ; i < arg_count ; i++)
max_length+=args[i]->max_length;
From d6481499cfb822c1891d1f7fc2c3f2f4b780f1ab Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Fri, 29 Oct 2004 11:25:16 +0000
Subject: [PATCH 20/59] bumped up version for ndb protocal change in
create table, now allows for more than 91 attributes upgrade compatability
with 3.5.3
---
configure.in | 2 +-
ndb/src/common/util/version.c | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/configure.in b/configure.in
index 9901ef5d4fd..392aaba2cda 100644
--- a/configure.in
+++ b/configure.in
@@ -15,7 +15,7 @@ SHARED_LIB_VERSION=14:0:0
# ndb version
NDB_VERSION_MAJOR=3
NDB_VERSION_MINOR=5
-NDB_VERSION_BUILD=3
+NDB_VERSION_BUILD=4
NDB_VERSION_STATUS=""
# Set all version vars based on $VERSION. How do we do this more elegant ?
diff --git a/ndb/src/common/util/version.c b/ndb/src/common/util/version.c
index e2515b243b1..f2b3d5bd522 100644
--- a/ndb/src/common/util/version.c
+++ b/ndb/src/common/util/version.c
@@ -74,6 +74,7 @@ struct NdbUpGradeCompatible ndbCompatibleTable_full[] = {
};
struct NdbUpGradeCompatible ndbCompatibleTable_upgrade[] = {
+ { MAKE_VERSION(3,5,4), MAKE_VERSION(3,5,3), UG_Exact },
{ 0, 0, UG_Null }
};
From 7577c8bfc9efb21b8a8a3c08e342054e754370ab Mon Sep 17 00:00:00 2001
From: "bar@mysql.com" <>
Date: Fri, 29 Oct 2004 17:00:39 +0500
Subject: [PATCH 21/59] A fix according to Monty's request: "uint *errors" is
now a non-optional parameter in String:copy() and copy_and_convert().
---
sql/field.cc | 15 ++++++++++-----
sql/item.cc | 4 +++-
sql/item_cmpfunc.cc | 3 ++-
sql/item_create.cc | 5 ++++-
sql/item_func.cc | 3 ++-
sql/item_strfunc.cc | 9 ++++++---
sql/item_timefunc.cc | 4 +++-
sql/protocol.cc | 3 ++-
sql/sql_class.cc | 6 ++++--
sql/sql_parse.cc | 17 ++++++++++++-----
sql/sql_show.cc | 6 ++++--
sql/sql_string.cc | 25 ++++++++++++++-----------
sql/sql_string.h | 4 ++--
sql/thr_malloc.cc | 5 ++++-
14 files changed, 72 insertions(+), 37 deletions(-)
diff --git a/sql/field.cc b/sql/field.cc
index 261494d2125..4b833874221 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -531,7 +531,8 @@ int Field_decimal::store(const char *from, uint len, CHARSET_INFO *cs)
/* Convert character set if the old one is multi byte */
if (cs->mbmaxlen > 1)
{
- tmp.copy(from, len, cs, &my_charset_bin);
+ uint dummy_errors;
+ tmp.copy(from, len, cs, &my_charset_bin, &dummy_errors);
from= tmp.ptr();
len= tmp.length();
}
@@ -5502,7 +5503,8 @@ int Field_enum::store(const char *from,uint length,CHARSET_INFO *cs)
/* Convert character set if nesessary */
if (String::needs_conversion(length, cs, field_charset, ¬_used))
{
- tmpstr.copy(from, length, cs, field_charset);
+ uint dummy_errors;
+ tmpstr.copy(from, length, cs, field_charset, &dummy_errors);
from= tmpstr.ptr();
length= tmpstr.length();
}
@@ -5650,10 +5652,11 @@ void Field_enum::sql_type(String &res) const
bool flag=0;
for (const char **pos= typelib->type_names; *pos; pos++)
{
+ uint dummy_errors;
if (flag)
res.append(',');
/* convert to res.charset() == utf8, then quote */
- enum_item.copy(*pos, strlen(*pos), charset(), res.charset());
+ enum_item.copy(*pos, strlen(*pos), charset(), res.charset(), &dummy_errors);
append_unescaped(&res, enum_item.ptr(), enum_item.length());
flag= 1;
}
@@ -5684,7 +5687,8 @@ int Field_set::store(const char *from,uint length,CHARSET_INFO *cs)
/* Convert character set if nesessary */
if (String::needs_conversion(length, cs, field_charset, ¬_used_offset))
{
- tmpstr.copy(from, length, cs, field_charset);
+ uint dummy_errors;
+ tmpstr.copy(from, length, cs, field_charset, &dummy_errors);
from= tmpstr.ptr();
length= tmpstr.length();
}
@@ -5760,10 +5764,11 @@ void Field_set::sql_type(String &res) const
bool flag=0;
for (const char **pos= typelib->type_names; *pos; pos++)
{
+ uint dummy_errors;
if (flag)
res.append(',');
/* convert to res.charset() == utf8, then quote */
- set_item.copy(*pos, strlen(*pos), charset(), res.charset());
+ set_item.copy(*pos, strlen(*pos), charset(), res.charset(), &dummy_errors);
append_unescaped(&res, set_item.ptr(), set_item.length());
flag= 1;
}
diff --git a/sql/item.cc b/sql/item.cc
index 18025d6d689..46215fd78ed 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -818,7 +818,9 @@ bool Item_param::set_str(const char *str, ulong length)
Assign string with no conversion: data is converted only after it's
been written to the binary log.
*/
- if (str_value.copy(str, length, &my_charset_bin, &my_charset_bin))
+ uint dummy_errors;
+ if (str_value.copy(str, length, &my_charset_bin, &my_charset_bin,
+ &dummy_errors))
DBUG_RETURN(TRUE);
state= STRING_VALUE;
maybe_null= 0;
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index dc0377c791f..d9db07e2289 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -1832,8 +1832,9 @@ void Item_func_in::fix_length_and_dec()
{
Item_string *conv;
String tmp, cstr, *ostr= arg[0]->val_str(&tmp);
+ uint dummy_errors;
cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(),
- cmp_collation.collation);
+ cmp_collation.collation, &dummy_errors);
conv= new Item_string(cstr.ptr(),cstr.length(), cstr.charset(),
arg[0]->collation.derivation);
conv->str_value.copy();
diff --git a/sql/item_create.cc b/sql/item_create.cc
index c98c7892c26..800489a6a72 100644
--- a/sql/item_create.cc
+++ b/sql/item_create.cc
@@ -377,7 +377,10 @@ Item *create_func_space(Item *a)
{
sp= new Item_string("",0,cs);
if (sp)
- sp->str_value.copy(" ",1,&my_charset_latin1,cs);
+ {
+ uint dummy_errors;
+ sp->str_value.copy(" ", 1, &my_charset_latin1, cs, &dummy_errors);
+ }
}
else
{
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 3cb125d2868..50843d3bf76 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -2906,8 +2906,9 @@ void Item_func_match::init_search(bool no_order)
if (ft_tmp->charset() != cmp_collation.collation)
{
+ uint dummy_errors;
search_value.copy(ft_tmp->ptr(), ft_tmp->length(), ft_tmp->charset(),
- cmp_collation.collation);
+ cmp_collation.collation, &dummy_errors);
ft_tmp= &search_value;
}
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 2d9f7e7bff8..5eda89ef21e 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -2160,13 +2160,14 @@ String *Item_func_conv_charset::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
String *arg= args[0]->val_str(str);
+ uint dummy_errors;
if (!arg)
{
null_value=1;
return 0;
}
null_value= str_value.copy(arg->ptr(),arg->length(),arg->charset(),
- conv_charset);
+ conv_charset, &dummy_errors);
return null_value ? 0 : &str_value;
}
@@ -2249,11 +2250,12 @@ String *Item_func_charset::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
String *res = args[0]->val_str(str);
+ uint dummy_errors;
if ((null_value=(args[0]->null_value || !res->charset())))
return 0;
str->copy(res->charset()->csname,strlen(res->charset()->csname),
- &my_charset_latin1, collation.collation);
+ &my_charset_latin1, collation.collation, &dummy_errors);
return str;
}
@@ -2261,11 +2263,12 @@ String *Item_func_collation::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
String *res = args[0]->val_str(str);
+ uint dummy_errors;
if ((null_value=(args[0]->null_value || !res->charset())))
return 0;
str->copy(res->charset()->name,strlen(res->charset()->name),
- &my_charset_latin1, collation.collation);
+ &my_charset_latin1, collation.collation, &dummy_errors);
return str;
}
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 3c8dbb013a9..f621953a5bc 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -2121,8 +2121,10 @@ String *Item_char_typecast::val_str(String *str)
else
{
// Convert character set if differ
+ uint dummy_errors;
if (!(res1= args[0]->val_str(&tmp_value)) ||
- str->copy(res1->ptr(), res1->length(),res1->charset(), cast_cs))
+ str->copy(res1->ptr(), res1->length(), res1->charset(),
+ cast_cs, &dummy_errors))
{
null_value= 1;
return 0;
diff --git a/sql/protocol.cc b/sql/protocol.cc
index 887177c0a19..598d102ec29 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -713,7 +713,8 @@ bool Protocol::store_string_aux(const char *from, uint length,
fromcs != &my_charset_bin &&
tocs != &my_charset_bin)
{
- return convert->copy(from, length, fromcs, tocs) ||
+ uint dummy_errors;
+ return convert->copy(from, length, fromcs, tocs, &dummy_errors) ||
net_store_data(convert->ptr(), convert->length());
}
return net_store_data(from, length);
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index abe00027b07..7ad20967de0 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -508,13 +508,14 @@ bool THD::convert_string(LEX_STRING *to, CHARSET_INFO *to_cs,
{
DBUG_ENTER("convert_string");
size_s new_length= to_cs->mbmaxlen * from_length;
+ uint dummy_errors;
if (!(to->str= alloc(new_length+1)))
{
to->length= 0; // Safety fix
DBUG_RETURN(1); // EOM
}
to->length= copy_and_convert((char*) to->str, new_length, to_cs,
- from, from_length, from_cs);
+ from, from_length, from_cs, &dummy_errors);
to->str[to->length]=0; // Safety
DBUG_RETURN(0);
}
@@ -537,7 +538,8 @@ bool THD::convert_string(LEX_STRING *to, CHARSET_INFO *to_cs,
bool THD::convert_string(String *s, CHARSET_INFO *from_cs, CHARSET_INFO *to_cs)
{
- if (convert_buffer.copy(s->ptr(), s->length(), from_cs, to_cs))
+ uint dummy_errors;
+ if (convert_buffer.copy(s->ptr(), s->length(), from_cs, to_cs, &dummy_errors))
return TRUE;
/* If convert_buffer >> s copying is more efficient long term */
if (convert_buffer.alloced_length() >= convert_buffer.length() * 2 ||
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index d1f460d918e..dce32720184 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -882,18 +882,20 @@ static int check_connection(THD *thd)
/* Since 4.1 all database names are stored in utf8 */
if (db)
{
+ uint dummy_errors;
db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
system_charset_info,
db, strlen(db),
- thd->charset())]= 0;
+ thd->charset(), &dummy_errors)]= 0;
db= db_buff;
}
if (user)
{
+ uint dummy_errors;
user_buff[copy_and_convert(user_buff, sizeof(user_buff)-1,
system_charset_info, user, strlen(user),
- thd->charset())]= '\0';
+ thd->charset(), &dummy_errors)]= '\0';
user= user_buff;
}
@@ -1380,9 +1382,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
}
#endif
/* Convert database name to utf8 */
+ uint dummy_errors;
db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
system_charset_info, db, strlen(db),
- thd->charset())]= 0;
+ thd->charset(), &dummy_errors)]= 0;
db= db_buff;
/* Save user and privileges */
@@ -2066,8 +2069,12 @@ mysql_execute_command(THD *thd)
}
if (need_conversion)
- query_len= copy_and_convert(query_str, query_len, to_cs, pstr->ptr(),
- pstr->length(), pstr->charset());
+ {
+ uint dummy_errors;
+ query_len= copy_and_convert(query_str, query_len, to_cs,
+ pstr->ptr(), pstr->length(),
+ pstr->charset(), &dummy_errors);
+ }
else
memcpy(query_str, pstr->ptr(), pstr->length());
query_str[query_len]= 0;
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 3bf11c0d6b8..2af4cb3fc23 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -752,8 +752,9 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild,
String def(tmp1,sizeof(tmp1), system_charset_info);
type.set(tmp, sizeof(tmp), field->charset());
field->val_str(&type);
+ uint dummy_errors;
def.copy(type.ptr(), type.length(), type.charset(),
- system_charset_info);
+ system_charset_info, &dummy_errors);
protocol->store(def.ptr(), def.length(), def.charset());
}
else if (field->unireg_check == Field::NEXT_NUMBER ||
@@ -1338,9 +1339,10 @@ store_create_info(THD *thd, TABLE *table, String *packet)
if (type.length())
{
String def_val;
+ uint dummy_errors;
/* convert to system_charset_info == utf8 */
def_val.copy(type.ptr(), type.length(), field->charset(),
- system_charset_info);
+ system_charset_info, &dummy_errors);
append_unescaped(packet, def_val.ptr(), def_val.length());
}
else
diff --git a/sql/sql_string.cc b/sql/sql_string.cc
index 30559496fde..6b2bb07fb8c 100644
--- a/sql/sql_string.cc
+++ b/sql/sql_string.cc
@@ -121,12 +121,13 @@ bool String::set(ulonglong num, CHARSET_INFO *cs)
bool String::set(double num,uint decimals, CHARSET_INFO *cs)
{
char buff[331];
+ uint dummy_errors;
str_charset=cs;
if (decimals >= NOT_FIXED_DEC)
{
uint32 len= my_sprintf(buff,(buff, "%.14g",num));// Enough for a DATETIME
- return copy(buff, len, &my_charset_latin1, cs);
+ return copy(buff, len, &my_charset_latin1, cs, &dummy_errors);
}
#ifdef HAVE_FCONVERT
int decpt,sign;
@@ -191,7 +192,8 @@ end:
#else
sprintf(buff,"%.*f",(int) decimals,num);
#endif
- return copy(buff,(uint32) strlen(buff), &my_charset_latin1, cs);
+ return copy(buff,(uint32) strlen(buff), &my_charset_latin1, cs,
+ &dummy_errors);
#endif
}
@@ -336,14 +338,12 @@ bool String::copy(const char *str, uint32 arg_length,
uint32 offset;
if (!needs_conversion(arg_length, from_cs, to_cs, &offset))
{
- if (errors)
- *errors= 0;
+ *errors= 0;
return copy(str, arg_length, to_cs);
}
if ((from_cs == &my_charset_bin) && offset)
{
- if (errors)
- *errors= 0;
+ *errors= 0;
return copy_aligned(str, arg_length, offset, to_cs);
}
uint32 new_length= to_cs->mbmaxlen*arg_length;
@@ -382,7 +382,8 @@ bool String::set_ascii(const char *str, uint32 arg_length)
set(str, arg_length, str_charset);
return 0;
}
- return copy(str, arg_length, &my_charset_latin1, str_charset);
+ uint dummy_errors;
+ return copy(str, arg_length, &my_charset_latin1, str_charset, &dummy_errors);
}
@@ -436,10 +437,12 @@ bool String::append(const char *s,uint32 arg_length)
if (str_charset->mbminlen > 1)
{
uint32 add_length=arg_length * str_charset->mbmaxlen;
+ uint dummy_errors;
if (realloc(str_length+ add_length))
return TRUE;
str_length+= copy_and_convert(Ptr+str_length, add_length, str_charset,
- s, arg_length, &my_charset_latin1);
+ s, arg_length, &my_charset_latin1,
+ &dummy_errors);
return FALSE;
}
@@ -476,10 +479,11 @@ bool String::append(const char *s,uint32 arg_length, CHARSET_INFO *cs)
if (needs_conversion(arg_length, cs, str_charset, &dummy_offset))
{
uint32 add_length= arg_length / cs->mbminlen * str_charset->mbmaxlen;
+ uint dummy_errors;
if (realloc(str_length + add_length))
return TRUE;
str_length+= copy_and_convert(Ptr+str_length, add_length, str_charset,
- s, arg_length, cs);
+ s, arg_length, cs, &dummy_errors);
}
else
{
@@ -816,8 +820,7 @@ outp:
else
break;
}
- if (errors)
- *errors= error_count;
+ *errors= error_count;
return (uint32) (to - to_start);
}
diff --git a/sql/sql_string.h b/sql/sql_string.h
index de8f4af58d9..a8fb9574c0b 100644
--- a/sql/sql_string.h
+++ b/sql/sql_string.h
@@ -29,7 +29,7 @@ int sortcmp(const String *a,const String *b, CHARSET_INFO *cs);
String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
uint32 copy_and_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs,
const char *from, uint32 from_length,
- CHARSET_INFO *from_cs, uint *errors= 0);
+ CHARSET_INFO *from_cs, uint *errors);
class String
{
@@ -199,7 +199,7 @@ public:
CHARSET_INFO *cs);
bool set_or_copy_aligned(const char *s, uint32 arg_length, CHARSET_INFO *cs);
bool copy(const char*s,uint32 arg_length, CHARSET_INFO *csfrom,
- CHARSET_INFO *csto, uint *errors= 0);
+ CHARSET_INFO *csto, uint *errors);
bool append(const String &s);
bool append(const char *s);
bool append(const char *s,uint32 arg_length);
diff --git a/sql/thr_malloc.cc b/sql/thr_malloc.cc
index fa678ec7de2..0df60858bcb 100644
--- a/sql/thr_malloc.cc
+++ b/sql/thr_malloc.cc
@@ -108,8 +108,11 @@ char *sql_strmake_with_convert(const char *str, uint32 arg_length,
memcpy(pos, str, new_length);
}
else
+ {
+ uint dummy_errors;
new_length= copy_and_convert((char*) pos, new_length, to_cs, str,
- arg_length, from_cs);
+ arg_length, from_cs, &dummy_errors);
+ }
pos[new_length]= 0;
*result_length= new_length;
return pos;
From d2bfefc3c1e71c32fb4cad8f4c83efcd91c04e38 Mon Sep 17 00:00:00 2001
From: "serg@serg.mylan" <>
Date: Fri, 29 Oct 2004 14:24:06 +0200
Subject: [PATCH 22/59] proper max_records estimation for sort-repair of
fulltext indexes
---
myisam/mi_check.c | 2 +-
mysql-test/r/fulltext.result | 3 +++
mysql-test/t/ctype_utf8.test | 1 +
mysql-test/t/fulltext.test | 9 ++++++++-
4 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/myisam/mi_check.c b/myisam/mi_check.c
index 4da388af1c7..1df518a2712 100644
--- a/myisam/mi_check.c
+++ b/myisam/mi_check.c
@@ -2037,7 +2037,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
uint ft_max_word_len_for_sort=FT_MAX_WORD_LEN_FOR_SORT*
sort_param.keyinfo->seg->charset->mbmaxlen;
sort_info.max_records=
- (ha_rows) (sort_info.filelength/ft_max_word_len_for_sort+1);
+ (ha_rows) (sort_info.filelength/ft_min_word_len+1);
sort_param.key_read=sort_ft_key_read;
sort_param.key_write=sort_ft_key_write;
diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result
index 30c4c75f3d1..65f88932d54 100644
--- a/mysql-test/r/fulltext.result
+++ b/mysql-test/r/fulltext.result
@@ -330,6 +330,9 @@ t1_id name t2_id t1_id name
select * from t2 where match name against ('a* b* c* d* e* f*' in boolean mode);
t2_id t1_id name
drop table t1,t2;
+create table t1 (a text, fulltext key (a));
+insert into t1 select "xxxx yyyy zzzz";
+drop table t1;
SET NAMES latin1;
CREATE TABLE t1 (t text character set utf8 not null, fulltext(t));
INSERT t1 VALUES ('Mit freundlichem Grüß'), ('aus Osnabrück');
diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test
index 0c8bdd6a94d..c75b1dee63c 100644
--- a/mysql-test/t/ctype_utf8.test
+++ b/mysql-test/t/ctype_utf8.test
@@ -645,6 +645,7 @@ insert into t1 values(1,'foo'),(2,'foobar');
select * from t1 where b like 'foob%';
--disable_warnings
alter table t1 engine=bdb;
+--enable_warnings
select * from t1 where b like 'foob%';
drop table t1;
diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test
index 66df5b1cb92..5af2575ddc4 100644
--- a/mysql-test/t/fulltext.test
+++ b/mysql-test/t/fulltext.test
@@ -253,9 +253,16 @@ select * from t1 join t2 using(`t1_id`) where match (t1.name, t2.name) against('
# bug with many short (< ft_min_word_len) words in boolean search
#
select * from t2 where match name against ('a* b* c* d* e* f*' in boolean mode);
-
drop table t1,t2;
+#
+# bug with repair-by-sort and incorrect records estimation
+#
+
+create table t1 (a text, fulltext key (a));
+insert into t1 select "xxxx yyyy zzzz";
+drop table t1;
+
#
# UTF8
#
From 86143bc83262e6460a1e3f20b69d9cb1c1de4e27 Mon Sep 17 00:00:00 2001
From: "mleich@mysql.com" <>
Date: Fri, 29 Oct 2004 14:51:56 +0200
Subject: [PATCH 23/59] These modifications are the result of WL#2067 add
features to mysqltest: "disable_error_abort" + "$mysql_errno"
$mysql_errno is a new builtin variable of mysqltest and contains the
return code of the last command send to the server.
"--disable_abort_on_error" switches the abort of mysqltest
after "unmasked" failing statements off.
"--enable_abort_on_error" switches the abort of mysqltest
after "unmasked" failing statements on. (default)
"Maskings" are
!$ and --error
in the line before the statement to be checked.
The benefit of the option "--disable_abort_on_error" is that
- all statements after the failing statement are executed
- a r/.reject will be produced
- it is possible to write test cases, which perform
code sequences depending on the return code of a single
statement
---
client/mysqltest.c | 30 ++++-
mysql-test/r/mysqltest.result | 128 ++++++++++++++++++++
mysql-test/t/mysqltest.test | 219 ++++++++++++++++++++++++++++++++++
3 files changed, 376 insertions(+), 1 deletion(-)
diff --git a/client/mysqltest.c b/client/mysqltest.c
index 4c87561ab84..21f93b1fc6a 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -243,6 +243,8 @@ VAR var_reg[10];
HASH var_hash;
my_bool disable_query_log=0, disable_result_log=0, disable_warnings=0;
my_bool disable_info= 1; /* By default off */
+/* default for disable_abort_on_error: false = abort on unmasked error */
+my_bool disable_abort_on_error= 0;
struct connection cons[MAX_CONS];
struct connection* cur_con, *next_con, *cons_end;
@@ -274,6 +276,7 @@ Q_ENABLE_WARNINGS, Q_DISABLE_WARNINGS,
Q_ENABLE_INFO, Q_DISABLE_INFO,
Q_ENABLE_METADATA, Q_DISABLE_METADATA,
Q_EXEC, Q_DELIMITER,
+Q_DISABLE_ABORT_ON_ERROR, Q_ENABLE_ABORT_ON_ERROR,
Q_DISPLAY_VERTICAL_RESULTS, Q_DISPLAY_HORIZONTAL_RESULTS,
Q_QUERY_VERTICAL, Q_QUERY_HORIZONTAL,
Q_START_TIMER, Q_END_TIMER,
@@ -352,6 +355,8 @@ const char *command_names[]=
"disable_metadata",
"exec",
"delimiter",
+ "disable_abort_on_error",
+ "enable_abort_on_error",
"vertical_results",
"horizontal_results",
"query_vertical",
@@ -1239,6 +1244,18 @@ int do_let(struct st_query* q)
return var_set(var_name, var_name_end, var_val_start, q->end);
}
+/* Store an integer (typically the returncode of the last SQL) */
+/* statement in the mysqltest builtin variable $mysql_errno, by */
+/* simulating of a user statement "let $mysql_errno= " */
+int var_set_errno(int sql_errno )
+{
+ char var_name[] = "$mysql_errno", var_val[30];
+ sprintf(var_val, "%d", sql_errno);
+ /* On some odd systems, the return value from sprintf() isn't */
+ /* always the length of the string, so we use strlen() */
+ return var_set(var_name, var_name + 12, var_val, var_val + strlen(var_val));
+}
+
int do_rpl_probe(struct st_query* q __attribute__((unused)))
{
DBUG_ENTER("do_rpl_probe");
@@ -1996,7 +2013,7 @@ int read_query(struct st_query** q_ptr)
memcpy((gptr) q->expected_errno, (gptr) global_expected_errno,
sizeof(global_expected_errno));
q->expected_errors= global_expected_errors;
- q->abort_on_error= global_expected_errors == 0;
+ q->abort_on_error= (global_expected_errors == 0 && !disable_abort_on_error);
bzero((gptr) global_expected_errno, sizeof(global_expected_errno));
global_expected_errors=0;
if (p[0] == '-' && p[1] == '-')
@@ -2642,6 +2659,10 @@ end:
dynstr_free(&ds_tmp);
if (q->type == Q_EVAL)
dynstr_free(&eval_query);
+ /* We save the return code (mysql_errno(mysql)) from the last call sent */
+ /* to the server into the mysqltest builtin variable $mysql_errno. This */
+ /* variable then can be used from the test case itself. */
+ var_set_errno(mysql_errno(mysql));
DBUG_RETURN(error);
}
@@ -3395,6 +3416,11 @@ int main(int argc, char **argv)
init_var_hash(&cur_con->mysql);
+ /* Initialize $mysql_errno with -1, so we can */
+ /* - distinguish it from valid values ( >= 0 ) and */
+ /* - detect if there was never a command sent to the server */
+ var_set_errno(-1);
+
while (!read_query(&q))
{
int current_line_inc = 1, processed = 0;
@@ -3414,6 +3440,8 @@ int main(int argc, char **argv)
case Q_DISABLE_RPL_PARSE: do_disable_rpl_parse(q); break;
case Q_ENABLE_QUERY_LOG: disable_query_log=0; break;
case Q_DISABLE_QUERY_LOG: disable_query_log=1; break;
+ case Q_ENABLE_ABORT_ON_ERROR: disable_abort_on_error=0; break;
+ case Q_DISABLE_ABORT_ON_ERROR: disable_abort_on_error=1; break;
case Q_ENABLE_RESULT_LOG: disable_result_log=0; break;
case Q_DISABLE_RESULT_LOG: disable_result_log=1; break;
case Q_ENABLE_WARNINGS: disable_warnings=0; break;
diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result
index 4e30d5bc110..5dc9ede1ca6 100644
--- a/mysql-test/r/mysqltest.result
+++ b/mysql-test/r/mysqltest.result
@@ -1,3 +1,6 @@
+select -1 as "before_use_test" ;
+before_use_test
+-1
select otto from (select 1 as otto) as t1;
otto
1
@@ -21,3 +24,128 @@ select friedrich from (select 1 as otto) as t1;
ERROR 42S22: Unknown column 'friedrich' in 'field list'
select friedrich from (select 1 as otto) as t1;
ERROR 42S22: Unknown column 'friedrich' in 'field list'
+select otto from (select 1 as otto) as t1;
+otto
+1
+select 0 as "after_successful_stmt_errno" ;
+after_successful_stmt_errno
+0
+garbage ;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
+select 1064 as "after_wrong_syntax_errno" ;
+after_wrong_syntax_errno
+1064
+garbage ;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
+select 1064 as "after_let_var_equal_value" ;
+after_let_var_equal_value
+1064
+garbage ;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
+set @my_var= 'abc' ;
+select 0 as "after_set_var_equal_value" ;
+after_set_var_equal_value
+0
+garbage ;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
+select 1064 as "after_disable_warnings_command" ;
+after_disable_warnings_command
+1064
+drop table if exists t1 ;
+garbage ;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
+drop table if exists t1 ;
+select 0 as "after_disable_warnings" ;
+after_disable_warnings
+0
+garbage ;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
+select 3 from t1 ;
+ERROR 42S02: Table 'test.t1' doesn't exist
+select 1146 as "after_minus_masked" ;
+after_minus_masked
+1146
+garbage ;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
+select 3 from t1 ;
+ERROR 42S02: Table 'test.t1' doesn't exist
+select 1146 as "after_!_masked" ;
+after_!_masked
+1146
+garbage ;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
+select -1 as "after_let_errno_equal_value" ;
+after_let_errno_equal_value
+-1
+garbage ;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
+prepare stmt from "select 3 from t1" ;
+ERROR 42S02: Table 'test.t1' doesn't exist
+select 1146 as "after_failing_prepare" ;
+after_failing_prepare
+1146
+create table t1 ( f1 char(10));
+garbage ;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
+prepare stmt from "select 3 from t1" ;
+select 0 as "after_successful_prepare" ;
+after_successful_prepare
+0
+garbage ;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
+execute stmt;
+3
+select 0 as "after_successful_execute" ;
+after_successful_execute
+0
+drop table t1;
+garbage ;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
+execute stmt;
+ERROR 42S02: Table 'test.t1' doesn't exist
+select 1146 as "after_failing_execute" ;
+after_failing_execute
+1146
+garbage ;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
+execute __stmt_;
+ERROR HY000: Unknown prepared statement handler (__stmt_) given to EXECUTE
+select 1243 as "after_failing_execute" ;
+after_failing_execute
+1243
+garbage ;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
+deallocate prepare stmt;
+select 0 as "after_successful_deallocate" ;
+after_successful_deallocate
+0
+garbage ;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
+deallocate prepare __stmt_;
+ERROR HY000: Unknown prepared statement handler (__stmt_) given to DEALLOCATE PREPARE
+select 1243 as "after_failing_deallocate" ;
+after_failing_deallocate
+1243
+garbage ;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
+select 1064 as "after_--disable_abort_on_error" ;
+after_--disable_abort_on_error
+1064
+select 3 from t1 ;
+ERROR 42S02: Table 'test.t1' doesn't exist
+select 3 from t1 ;
+ERROR 42S02: Table 'test.t1' doesn't exist
+select 3 from t1 ;
+ERROR 42S02: Table 'test.t1' doesn't exist
+select 1146 as "after_!errno_masked_error" ;
+after_!errno_masked_error
+1146
+garbage ;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
+select 1064 as "after_--enable_abort_on_error" ;
+after_--enable_abort_on_error
+1064
+select 3 from t1 ;
+ERROR 42S02: Table 'test.t1' doesn't exist
+select 3 from t1 ;
+ERROR 42S02: Table 'test.t1' doesn't exist
diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test
index c18dfe1e25c..b7007e1a519 100644
--- a/mysql-test/t/mysqltest.test
+++ b/mysql-test/t/mysqltest.test
@@ -5,6 +5,15 @@
#
# ============================================================================
+# ----------------------------------------------------------------------------
+# $mysql_errno contains the return code of the last command
+# send to the server.
+# ----------------------------------------------------------------------------
+# get $mysql_errno before the first statement
+# $mysql_errno should be -1
+eval select $mysql_errno as "before_use_test" ;
+
+
# ----------------------------------------------------------------------------
# Positive case(statement)
# ----------------------------------------------------------------------------
@@ -76,3 +85,213 @@ select friedrich from (select 1 as otto) as t1;
#--error S00000
#select friedrich from (select 1 as otto) as t1;
+
+# ----------------------------------------------------------------------------
+# test cases for $mysql_errno
+#
+# $mysql_errno is a builtin variable of mysqltest and contains the return code
+# of the last command send to the server.
+#
+# The following test cases often initialize $mysql_errno to 1064 by
+# a command with wrong syntax.
+# Example: !$1064 To prevent the abort after the error.
+# garbage ;
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# 1. check mysql_errno = 0 after successful statement
+# ----------------------------------------------------------------------------
+select otto from (select 1 as otto) as t1;
+eval select $mysql_errno as "after_successful_stmt_errno" ;
+
+#----------------------------------------------------------------------------
+# 2. check mysql_errno = 1064 after statement with wrong syntax
+# ----------------------------------------------------------------------------
+!$1064
+garbage ;
+eval select $mysql_errno as "after_wrong_syntax_errno" ;
+
+# ----------------------------------------------------------------------------
+# 3. check if let $my_var= 'abc' ; affects $mysql_errno
+# ----------------------------------------------------------------------------
+!$1064
+garbage ;
+let $my_var= 'abc' ;
+eval select $mysql_errno as "after_let_var_equal_value" ;
+
+# ----------------------------------------------------------------------------
+# 4. check if set @my_var= 'abc' ; affects $mysql_errno
+# ----------------------------------------------------------------------------
+!$1064
+garbage ;
+set @my_var= 'abc' ;
+eval select $mysql_errno as "after_set_var_equal_value" ;
+
+# ----------------------------------------------------------------------------
+# 5. check if the setting of --disable-warnings itself affects $mysql_errno
+# (May be -- modifies $mysql_errno.)
+# ----------------------------------------------------------------------------
+!$1064
+garbage ;
+--disable_warnings
+eval select $mysql_errno as "after_disable_warnings_command" ;
+
+# ----------------------------------------------------------------------------
+# 6. check if --disable-warnings + command with warning affects the errno
+# stored within $mysql_errno
+# (May be disabled warnings affect $mysql_errno.)
+# ----------------------------------------------------------------------------
+drop table if exists t1 ;
+!$1064
+garbage ;
+drop table if exists t1 ;
+eval select $mysql_errno as "after_disable_warnings" ;
+--enable_warnings
+
+# ----------------------------------------------------------------------------
+# 7. check if masked errors affect $mysql_errno
+# ----------------------------------------------------------------------------
+!$1064
+garbage ;
+--error 1146
+select 3 from t1 ;
+eval select $mysql_errno as "after_minus_masked" ;
+!$1064
+garbage ;
+!$1146
+select 3 from t1 ;
+eval select $mysql_errno as "after_!_masked" ;
+
+# ----------------------------------------------------------------------------
+# 8. Will manipulations of $mysql_errno be possible and visible ?
+# ----------------------------------------------------------------------------
+!$1064
+garbage ;
+let $mysql_errno= -1;
+eval select $mysql_errno as "after_let_errno_equal_value" ;
+
+# ----------------------------------------------------------------------------
+# 9. How affect actions on prepared statements $mysql_errno ?
+# ----------------------------------------------------------------------------
+# failing prepare
+!$1064
+garbage ;
+!$1146
+prepare stmt from "select 3 from t1" ;
+eval select $mysql_errno as "after_failing_prepare" ;
+create table t1 ( f1 char(10));
+
+# successful prepare
+!$1064
+garbage ;
+prepare stmt from "select 3 from t1" ;
+eval select $mysql_errno as "after_successful_prepare" ;
+
+# successful execute
+!$1064
+garbage ;
+execute stmt;
+eval select $mysql_errno as "after_successful_execute" ;
+
+# failing execute (table dropped)
+drop table t1;
+!$1064
+garbage ;
+!$1146
+execute stmt;
+eval select $mysql_errno as "after_failing_execute" ;
+
+# failing execute (unknown statement)
+!$1064
+garbage ;
+!$1243
+execute __stmt_;
+eval select $mysql_errno as "after_failing_execute" ;
+
+# successful deallocate
+!$1064
+garbage ;
+deallocate prepare stmt;
+eval select $mysql_errno as "after_successful_deallocate" ;
+
+# failing deallocate ( statement handle does not exist )
+!$1064
+garbage ;
+!$1243
+deallocate prepare __stmt_;
+eval select $mysql_errno as "after_failing_deallocate" ;
+
+
+# ----------------------------------------------------------------------------
+# test cases for "--disable_abort_on_error"
+#
+# "--disable_abort_on_error" switches the abort of mysqltest
+# after "unmasked" failing statements off.
+#
+# The default is "--enable_abort_on_error".
+#
+# "Maskings" are
+# !$ and --error
+# in the line before the failing statement.
+#
+# There are some additional test case for $mysql_errno
+# because "--disable_abort_on_error" enables a new situation.
+# Example: "unmasked" statement fails + analysis of $mysql_errno
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# 1. Switch the abort on error off and check the effect on $mysql_errno
+# ----------------------------------------------------------------------------
+!$1064
+garbage ;
+--disable_abort_on_error
+eval select $mysql_errno as "after_--disable_abort_on_error" ;
+
+# ----------------------------------------------------------------------------
+# 2. "unmasked" failing statement should not cause an abort
+# ----------------------------------------------------------------------------
+select 3 from t1 ;
+
+# ----------------------------------------------------------------------------
+# 3. masked failing statements
+# ----------------------------------------------------------------------------
+# expected error = response
+--error 1146
+select 3 from t1 ;
+!$1146
+select 3 from t1 ;
+eval select $mysql_errno as "after_!errno_masked_error" ;
+# expected error <> response
+# --error 1000
+# select 3 from t1 ;
+# !$1000
+# select 3 from t1 ;
+
+# ----------------------------------------------------------------------------
+# 4. Switch the abort on error on and check the effect on $mysql_errno
+# ----------------------------------------------------------------------------
+!$1064
+garbage ;
+--enable_abort_on_error
+eval select $mysql_errno as "after_--enable_abort_on_error" ;
+
+# ----------------------------------------------------------------------------
+# 5. masked failing statements
+# ----------------------------------------------------------------------------
+# expected error = response
+--error 1146
+select 3 from t1 ;
+!$1146
+select 3 from t1 ;
+
+# ----------------------------------------------------------------------------
+# 6. check that the old default behaviour is not changed
+# Please remove the '#' to get the abort on error
+# ----------------------------------------------------------------------------
+#--error 1064
+#select 3 from t1 ;
+#
+#!$1064
+#select 3 from t1 ;
+#
+#select 3 from t1 ;
From 24d38aea13f12e977b19b1430474f5eff2abddb7 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Fri, 29 Oct 2004 13:59:40 +0000
Subject: [PATCH 24/59] added define flag SNPRINTF_RETURN_ZERO to indicate
that snprintf returns zero if buffer too small use flag
SNPRINTF_RETURN_ZERO emulate snprintf behavior by writing to _big_ buffer
if set use my_vsnprintf if HAVE_SNPRINTF is not set and set
SNPRINTF_RETURN_ZERO in that case
---
configure.in | 4 ++--
ndb/src/common/util/basestring_vsnprintf.c | 22 +++++++++++++++++++++-
2 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/configure.in b/configure.in
index 392aaba2cda..353e455dbac 100644
--- a/configure.in
+++ b/configure.in
@@ -1142,8 +1142,8 @@ dnl Is this the right match for DEC OSF on alpha?
fi
echo "Adding defines for OSF1"
# gethostbyname_r is deprecated and doesn't work ok on OSF1
- CFLAGS="$CFLAGS -DUNDEF_HAVE_GETHOSTBYNAME_R"
- CXXFLAGS="$CXXFLAGS -DUNDEF_HAVE_GETHOSTBYNAME_R"
+ CFLAGS="$CFLAGS -DUNDEF_HAVE_GETHOSTBYNAME_R -DSNPRINTF_RETURN_ZERO"
+ CXXFLAGS="$CXXFLAGS -DUNDEF_HAVE_GETHOSTBYNAME_R -DSNPRINTF_RETURN_ZERO"
# fix to handle include of correctly on OSF1 with cxx compiler
CXXFLAGS="$CXXFLAGS -I/usr/include/cxx -I/usr/include/cxx_cname -I/usr/include -I/usr/include.dtk"
;;
diff --git a/ndb/src/common/util/basestring_vsnprintf.c b/ndb/src/common/util/basestring_vsnprintf.c
index 10932226d18..87ffb8ad146 100644
--- a/ndb/src/common/util/basestring_vsnprintf.c
+++ b/ndb/src/common/util/basestring_vsnprintf.c
@@ -18,6 +18,7 @@
#define _XOPEN_SOURCE 500
#include
#include
+#include
int
basestring_snprintf(char *str, size_t size, const char *format, ...)
@@ -30,8 +31,27 @@ basestring_snprintf(char *str, size_t size, const char *format, ...)
return(ret);
}
+#ifdef HAVE_SNPRINTF
+ #define BASESTRING_VSNPRINTF_FUNC(a,b,c,d) vsnprintf(a,b,c,d)
+#else
+ #define SNPRINTF_RETURN_ZERO
+ #define BASESTRING_VSNPRINTF_FUNC(a,b,c,d) my_vsnprintf(a,b,c,d)
+ extern int my_vsnprintf(char *str, size_t size, const char *format, va_list ap);
+#endif
+
+#ifdef SNPRINTF_RETURN_ZERO
+static char basestring_vsnprintf_buf[16*1024];
+#endif
int
basestring_vsnprintf(char *str, size_t size, const char *format, va_list ap)
{
- return(vsnprintf(str, size, format, ap));
+ int ret= BASESTRING_VSNPRINTF_FUNC(str, size, format, ap);
+#ifdef SNPRINTF_RETURN_ZERO
+ if (ret == 0 && format != 0 && format[0] != '\0') {
+ ret= BASESTRING_VSNPRINTF_FUNC(basestring_vsnprintf_buf,
+ sizeof(basestring_vsnprintf_buf),
+ format, ap);
+ }
+#endif
+ return ret;
}
From e97a79f2ee590c8f135d60d8470bcff2a90a3ef9 Mon Sep 17 00:00:00 2001
From: "konstantin@mysql.com" <>
Date: Sat, 30 Oct 2004 17:17:52 +0400
Subject: [PATCH 25/59] Enable REPLACE ... SELECT in prepared statements.
---
mysql-test/include/ps_modify.inc | 5 ++++-
mysql-test/r/ps_2myisam.result | 4 +++-
mysql-test/r/ps_3innodb.result | 4 +++-
mysql-test/r/ps_4heap.result | 4 +++-
mysql-test/r/ps_5merge.result | 8 ++++++--
mysql-test/r/ps_6bdb.result | 4 +++-
mysql-test/r/ps_7ndb.result | 1 -
mysql-test/t/ps_7ndb.test | 2 +-
sql/sql_prepare.cc | 1 +
9 files changed, 24 insertions(+), 9 deletions(-)
diff --git a/mysql-test/include/ps_modify.inc b/mysql-test/include/ps_modify.inc
index 9cf11709e69..eb6820934f3 100644
--- a/mysql-test/include/ps_modify.inc
+++ b/mysql-test/include/ps_modify.inc
@@ -322,8 +322,11 @@ select a,b from t1 where a >= 1000 order by a ;
delete from t1 where a >= 1000 ;
## replace
---error 1295
prepare stmt1 from ' replace into t1 (a,b) select 100, ''hundred'' ';
+execute stmt1;
+execute stmt1;
+execute stmt1;
+
## multi table statements
diff --git a/mysql-test/r/ps_2myisam.result b/mysql-test/r/ps_2myisam.result
index 40b2516f0b9..efb12561950 100644
--- a/mysql-test/r/ps_2myisam.result
+++ b/mysql-test/r/ps_2myisam.result
@@ -1581,7 +1581,9 @@ a b
1200 x1000_1updatedupdated
delete from t1 where a >= 1000 ;
prepare stmt1 from ' replace into t1 (a,b) select 100, ''hundred'' ';
-ERROR HY000: This command is not supported in the prepared statement protocol yet
+execute stmt1;
+execute stmt1;
+execute stmt1;
test_sequence
------ multi table tests ------
delete from t1 ;
diff --git a/mysql-test/r/ps_3innodb.result b/mysql-test/r/ps_3innodb.result
index 11669b131a7..cb096882d13 100644
--- a/mysql-test/r/ps_3innodb.result
+++ b/mysql-test/r/ps_3innodb.result
@@ -1564,7 +1564,9 @@ a b
1200 x1000_1updatedupdated
delete from t1 where a >= 1000 ;
prepare stmt1 from ' replace into t1 (a,b) select 100, ''hundred'' ';
-ERROR HY000: This command is not supported in the prepared statement protocol yet
+execute stmt1;
+execute stmt1;
+execute stmt1;
test_sequence
------ multi table tests ------
delete from t1 ;
diff --git a/mysql-test/r/ps_4heap.result b/mysql-test/r/ps_4heap.result
index a3837650e0e..ac9946ef070 100644
--- a/mysql-test/r/ps_4heap.result
+++ b/mysql-test/r/ps_4heap.result
@@ -1565,7 +1565,9 @@ a b
1200 x1000_1updatedupdated
delete from t1 where a >= 1000 ;
prepare stmt1 from ' replace into t1 (a,b) select 100, ''hundred'' ';
-ERROR HY000: This command is not supported in the prepared statement protocol yet
+execute stmt1;
+execute stmt1;
+execute stmt1;
test_sequence
------ multi table tests ------
delete from t1 ;
diff --git a/mysql-test/r/ps_5merge.result b/mysql-test/r/ps_5merge.result
index 619b59e4e3d..15e707959ca 100644
--- a/mysql-test/r/ps_5merge.result
+++ b/mysql-test/r/ps_5merge.result
@@ -1607,7 +1607,9 @@ a b
1200 x1000_1updatedupdated
delete from t1 where a >= 1000 ;
prepare stmt1 from ' replace into t1 (a,b) select 100, ''hundred'' ';
-ERROR HY000: This command is not supported in the prepared statement protocol yet
+execute stmt1;
+execute stmt1;
+execute stmt1;
test_sequence
------ multi table tests ------
delete from t1 ;
@@ -4615,7 +4617,9 @@ a b
1200 x1000_1updatedupdated
delete from t1 where a >= 1000 ;
prepare stmt1 from ' replace into t1 (a,b) select 100, ''hundred'' ';
-ERROR HY000: This command is not supported in the prepared statement protocol yet
+execute stmt1;
+execute stmt1;
+execute stmt1;
test_sequence
------ multi table tests ------
delete from t1 ;
diff --git a/mysql-test/r/ps_6bdb.result b/mysql-test/r/ps_6bdb.result
index 5c23a574f51..3dd9c200510 100644
--- a/mysql-test/r/ps_6bdb.result
+++ b/mysql-test/r/ps_6bdb.result
@@ -1564,7 +1564,9 @@ a b
1200 x1000_1updatedupdated
delete from t1 where a >= 1000 ;
prepare stmt1 from ' replace into t1 (a,b) select 100, ''hundred'' ';
-ERROR HY000: This command is not supported in the prepared statement protocol yet
+execute stmt1;
+execute stmt1;
+execute stmt1;
test_sequence
------ multi table tests ------
delete from t1 ;
diff --git a/mysql-test/r/ps_7ndb.result b/mysql-test/r/ps_7ndb.result
index cf567750b85..85e51df776f 100644
--- a/mysql-test/r/ps_7ndb.result
+++ b/mysql-test/r/ps_7ndb.result
@@ -1543,7 +1543,6 @@ a b
1000 x1000_1
delete from t1 where a >= 1000 ;
prepare stmt1 from ' replace into t1 (a,b) select 100, ''hundred'' ';
-ERROR HY000: This command is not supported in the prepared statement protocol yet
test_sequence
------ multi table tests ------
delete from t1 ;
diff --git a/mysql-test/t/ps_7ndb.test b/mysql-test/t/ps_7ndb.test
index af669a26400..22370a7f3ac 100644
--- a/mysql-test/t/ps_7ndb.test
+++ b/mysql-test/t/ps_7ndb.test
@@ -339,8 +339,8 @@ select a,b from t1 where a >= 1000 order by a ;
delete from t1 where a >= 1000 ;
## replace
---error 1295
prepare stmt1 from ' replace into t1 (a,b) select 100, ''hundred'' ';
+--error 1031
## multi table statements
--disable_query_log
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index bccf517466d..b5e12c4d208 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1442,6 +1442,7 @@ static int send_prepare_results(Prepared_statement *stmt, bool text_protocol)
break;
case SQLCOM_INSERT_SELECT:
+ case SQLCOM_REPLACE_SELECT:
res= mysql_test_insert_select(stmt, tables);
break;
From d22a24d871bc3bfaec17621d23352f2da9473569 Mon Sep 17 00:00:00 2001
From: "heikki@hundin.mysql.fi" <>
Date: Sun, 31 Oct 2004 15:43:29 +0200
Subject: [PATCH 26/59] row0mysql.c, pars0pars.c, eval0eval.c, dict0load.c,
dict0dict.c, dict0crea.c: Fix bug #3478: InnoDB's FOREIGN KEY tables
treated table and database names as case-insensitive; RENAME TABLE t to T
would hang in an endless loop if t had a foreign key constraint defined on it
dict0dict.c: Fix bug #3478: InnoDB's FOREIGN KEY tables treated table and
database names as case-insensitive; RENAME TABLE t to T would hang in an
endless loop if t had a foreign key constraint defined on it; fix also a hang
that would occur if one tried in ALTER TABLE or RENAME TABLE to create a
foreign key constraint name that collided with another existing name
---
innobase/dict/dict0crea.c | 16 +++++++++++++++-
innobase/dict/dict0dict.c | 4 ++--
innobase/dict/dict0load.c | 21 ++++++++++++++++++---
innobase/eval/eval0eval.c | 18 +++++++++++++++++-
innobase/pars/pars0pars.c | 8 ++++++--
innobase/row/row0mysql.c | 15 +++++++++++----
6 files changed, 69 insertions(+), 13 deletions(-)
diff --git a/innobase/dict/dict0crea.c b/innobase/dict/dict0crea.c
index 31a601e68b0..e8261ab1e91 100644
--- a/innobase/dict/dict0crea.c
+++ b/innobase/dict/dict0crea.c
@@ -1011,6 +1011,12 @@ dict_create_or_check_foreign_constraint_tables(void)
there are 2 secondary indexes on SYS_FOREIGN, and they
are defined just like below */
+ /* NOTE: when designing InnoDB's foreign key support in 2001, we made
+ an error and made the table names and the foreign key id of type
+ 'CHAR' (internally, really a VARCHAR). We should have made the type
+ VARBINARY, like in other InnoDB system tables, to get a clean
+ design. */
+
str = (char *)
"PROCEDURE CREATE_FOREIGN_SYS_TABLES_PROC () IS\n"
"BEGIN\n"
@@ -1227,9 +1233,17 @@ loop:
fputs(".\nA foreign key constraint of name ", ef);
ut_print_name(ef, foreign->id);
fputs("\nalready exists."
- " (Note that internally InnoDB adds 'databasename/'\n"
+ " (Note that internally InnoDB adds 'databasename/'\n"
"in front of the user-defined constraint name).\n",
ef);
+ fputs("Note that InnoDB's FOREIGN KEY system tables store\n"
+ "constraint names as case-insensitive, with the\n"
+ "MySQL standard latin1_swedish_ci collation. If you\n"
+ "create tables or databases whose names differ only in\n"
+ "the character case, then collisions in constraint\n"
+ "names can occur. Workaround: name your constraints\n"
+ "explicitly with unique names.\n",
+ ef);
mutex_exit(&dict_foreign_err_mutex);
diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c
index 4340934ab3d..5ca31ecd422 100644
--- a/innobase/dict/dict0dict.c
+++ b/innobase/dict/dict0dict.c
@@ -132,7 +132,7 @@ dict_index_build_internal_non_clust(
dict_index_t* index); /* in: user representation of a non-clustered
index */
/**************************************************************************
-Removes a foreign constraint struct from the dictionet cache. */
+Removes a foreign constraint struct from the dictionary cache. */
static
void
dict_foreign_remove_from_cache(
@@ -581,7 +581,7 @@ dict_table_get_on_id(
dict_table_t* table;
if (ut_dulint_cmp(table_id, DICT_FIELDS_ID) <= 0
- || trx->dict_operation) {
+ || trx->dict_operation_lock_mode == RW_X_LATCH) {
/* It is a system table which will always exist in the table
cache: we avoid acquiring the dictionary mutex, because
if we are doing a rollback to handle an error in TABLE
diff --git a/innobase/dict/dict0load.c b/innobase/dict/dict0load.c
index 6a4d4c86824..a4637e09d07 100644
--- a/innobase/dict/dict0load.c
+++ b/innobase/dict/dict0load.c
@@ -19,6 +19,7 @@ Created 4/24/1996 Heikki Tuuri
#include "mach0data.h"
#include "dict0dict.h"
#include "dict0boot.h"
+#include "rem0cmp.h"
/************************************************************************
Finds the first table name in the given database. */
@@ -1121,12 +1122,26 @@ loop:
rec = btr_pcur_get_rec(&pcur);
field = rec_get_nth_field(rec, 0, &len);
- /* Check if the table name in record is the one searched for */
- if (len != ut_strlen(table_name)
- || 0 != ut_memcmp(field, table_name, len)) {
+ /* Check if the table name in the record is the one searched for; the
+ following call does the comparison in the latin1_swedish_ci
+ charset-collation, in a case-insensitive way. */
+ if (0 != cmp_data_data(dfield_get_type(dfield),
+ dfield_get_data(dfield), dfield_get_len(dfield),
+ field, len)) {
+
goto load_next_index;
}
+
+ /* Since table names in SYS_FOREIGN are stored in a case-insensitive
+ order, we have to check that the table name matches also in a binary
+ string comparison. On Unix, MySQL allows table names that only differ
+ in character case. */
+
+ if (0 != ut_memcmp(field, table_name, len)) {
+
+ goto next_rec;
+ }
if (rec_get_deleted_flag(rec)) {
diff --git a/innobase/eval/eval0eval.c b/innobase/eval/eval0eval.c
index ebb6cb1b7d9..5b2d1f857b1 100644
--- a/innobase/eval/eval0eval.c
+++ b/innobase/eval/eval0eval.c
@@ -627,7 +627,11 @@ eval_concat(
}
/*********************************************************************
-Evaluates a predefined function node. */
+Evaluates a predefined function node. If the first argument is an integer,
+this function looks at the second argument which is the integer length in
+bytes, and converts the integer to a VARCHAR.
+If the first argument is of some other type, this function converts it to
+BINARY. */
UNIV_INLINE
void
eval_to_binary(
@@ -638,12 +642,24 @@ eval_to_binary(
que_node_t* arg2;
dfield_t* dfield;
byte* str1;
+ ulint len;
ulint len1;
arg1 = func_node->args;
str1 = dfield_get_data(que_node_get_val(arg1));
+ if (dtype_get_mtype(que_node_get_data_type(arg1)) != DATA_INT) {
+
+ len = dfield_get_len(que_node_get_val(arg1));
+
+ dfield = que_node_get_val(func_node);
+
+ dfield_set_data(dfield, str1, len);
+
+ return;
+ }
+
arg2 = que_node_get_next(arg1);
len1 = (ulint)eval_node_get_int_val(arg2);
diff --git a/innobase/pars/pars0pars.c b/innobase/pars/pars0pars.c
index a4124672df0..5be0e52d0c8 100644
--- a/innobase/pars/pars0pars.c
+++ b/innobase/pars/pars0pars.c
@@ -259,9 +259,13 @@ pars_resolve_func_data_type(
dtype_set(que_node_get_data_type(node), DATA_VARCHAR,
DATA_ENGLISH, 0, 0);
} else if (func == PARS_TO_BINARY_TOKEN) {
- ut_a(dtype_get_mtype(que_node_get_data_type(arg)) == DATA_INT);
- dtype_set(que_node_get_data_type(node), DATA_VARCHAR,
+ if (dtype_get_mtype(que_node_get_data_type(arg)) == DATA_INT) {
+ dtype_set(que_node_get_data_type(node), DATA_VARCHAR,
DATA_ENGLISH, 0, 0);
+ } else {
+ dtype_set(que_node_get_data_type(node), DATA_BINARY,
+ 0, 0, 0);
+ }
} else if (func == PARS_TO_NUMBER_TOKEN) {
ut_a(dtype_get_mtype(que_node_get_data_type(arg))
== DATA_VARCHAR);
diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c
index 78b2aa8e28f..2e8f7121d2c 100644
--- a/innobase/row/row0mysql.c
+++ b/innobase/row/row0mysql.c
@@ -1981,7 +1981,8 @@ row_drop_table_for_mysql(
"WHILE found = 1 LOOP\n"
" SELECT ID INTO foreign_id\n"
" FROM SYS_FOREIGN\n"
- " WHERE FOR_NAME = table_name;\n"
+ " WHERE FOR_NAME = table_name\n"
+ " AND TO_BINARY(FOR_NAME) = TO_BINARY(table_name);\n"
" IF (SQL % NOTFOUND) THEN\n"
" found := 0;\n"
" ELSE"
@@ -2381,7 +2382,8 @@ row_rename_table_for_mysql(
"WHILE found = 1 LOOP\n"
" SELECT ID INTO foreign_id\n"
" FROM SYS_FOREIGN\n"
- " WHERE FOR_NAME = old_table_name;\n"
+ " WHERE FOR_NAME = old_table_name\n"
+ " AND TO_BINARY(FOR_NAME) = TO_BINARY(old_table_name);\n"
" IF (SQL % NOTFOUND) THEN\n"
" found := 0;\n"
" ELSE\n"
@@ -2414,7 +2416,8 @@ row_rename_table_for_mysql(
" END IF;\n"
"END LOOP;\n"
"UPDATE SYS_FOREIGN SET REF_NAME = new_table_name\n"
- "WHERE REF_NAME = old_table_name;\n";
+ "WHERE REF_NAME = old_table_name\n"
+ " AND TO_BINARY(REF_NAME) = TO_BINARY(old_table_name);\n";
static const char str5[] =
"END;\n";
@@ -2602,7 +2605,11 @@ row_rename_table_for_mysql(
if (err == DB_DUPLICATE_KEY) {
ut_print_timestamp(stderr);
- fputs(" InnoDB: Error: table ", stderr);
+ fputs(
+ " InnoDB: Error; possible reasons:\n"
+ "InnoDB: 1) Table rename would cause two FOREIGN KEY constraints\n"
+ "InnoDB: to have the same internal name in case-insensitive comparison.\n"
+ "InnoDB: 2) table ", stderr);
ut_print_name(stderr, new_name);
fputs(" exists in the InnoDB internal data\n"
"InnoDB: dictionary though MySQL is trying rename table ", stderr);
From 066964675234bde4abaca6f7d9283f626affd825 Mon Sep 17 00:00:00 2001
From: "pekka@mysql.com" <>
Date: Sun, 31 Oct 2004 15:33:56 +0100
Subject: [PATCH 27/59] NDB bug-6018 support writeTuple with blobs
---
mysql-test/r/ndb_blob.result | 269 ++++++++++-------
mysql-test/t/ndb_blob.test | 180 ++++++++----
ndb/include/ndbapi/NdbBlob.hpp | 47 ++-
ndb/include/ndbapi/NdbConnection.hpp | 4 +-
ndb/include/ndbapi/NdbIndexOperation.hpp | 4 +
ndb/include/ndbapi/NdbOperation.hpp | 9 +-
ndb/src/ndbapi/NdbBlob.cpp | 359 ++++++++++++++++-------
ndb/src/ndbapi/NdbConnection.cpp | 15 +-
ndb/src/ndbapi/NdbDictionaryImpl.cpp | 9 +-
ndb/src/ndbapi/NdbIndexOperation.cpp | 26 +-
ndb/src/ndbapi/NdbOperation.cpp | 4 +-
ndb/src/ndbapi/NdbOperationExec.cpp | 14 +-
ndb/test/ndbapi/testBlobs.cpp | 201 +++++++++----
13 files changed, 754 insertions(+), 387 deletions(-)
diff --git a/mysql-test/r/ndb_blob.result b/mysql-test/r/ndb_blob.result
index cf64ec41ae3..1f2cf33f57d 100644
--- a/mysql-test/r/ndb_blob.result
+++ b/mysql-test/r/ndb_blob.result
@@ -1,25 +1,5 @@
drop table if exists t1;
-drop database if exists mysqltest;
-create table t1 (
-a int not null primary key,
-b tinytext
-) engine=ndbcluster;
-insert into t1 values(1, 'x');
-update t1 set b = 'y';
-select * from t1;
-a b
-1 y
-delete from t1;
-drop table t1;
-create table t1 (
-a int not null primary key,
-b text not null
-) engine=ndbcluster;
-insert into t1 values(1, '');
-select * from t1;
-a b
-1
-drop table t1;
+drop database if exists test2;
set autocommit=0;
create table t1 (
a int not null primary key,
@@ -102,6 +82,53 @@ commit;
select count(*) from t1;
count(*)
0
+replace t1 set a=1,b=@b1,c=111,d=@d1;
+replace t1 set a=2,b=@b2,c=222,d=@d2;
+commit;
+explain select * from t1 where a = 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
+select a,length(b),substr(b,1+2*900,2),length(d),substr(d,1+3*900,3)
+from t1 where a=1;
+a length(b) substr(b,1+2*900,2) length(d) substr(d,1+3*900,3)
+1 2256 b1 3000 dd1
+select a,length(b),substr(b,1+2*9000,2),length(d),substr(d,1+3*9000,3)
+from t1 where a=2;
+a length(b) substr(b,1+2*9000,2) length(d) substr(d,1+3*9000,3)
+2 20000 b2 30000 dd2
+replace t1 set a=1,b=@b2,c=111,d=@d2;
+replace t1 set a=2,b=@b1,c=222,d=@d1;
+commit;
+select a,length(b),substr(b,1+2*9000,2),length(d),substr(d,1+3*9000,3)
+from t1 where a=1;
+a length(b) substr(b,1+2*9000,2) length(d) substr(d,1+3*9000,3)
+1 20000 b2 30000 dd2
+select a,length(b),substr(b,1+2*900,2),length(d),substr(d,1+3*900,3)
+from t1 where a=2;
+a length(b) substr(b,1+2*900,2) length(d) substr(d,1+3*900,3)
+2 2256 b1 3000 dd1
+replace t1 set a=1,b=concat(@b2,@b2),c=111,d=concat(@d2,@d2);
+replace t1 set a=2,b=concat(@b1,@b1),c=222,d=concat(@d1,@d1);
+commit;
+select a,length(b),substr(b,1+4*9000,2),length(d),substr(d,1+6*9000,3)
+from t1 where a=1;
+a length(b) substr(b,1+4*9000,2) length(d) substr(d,1+6*9000,3)
+1 40000 b2 60000 dd2
+select a,length(b),substr(b,1+4*900,2),length(d),substr(d,1+6*900,3)
+from t1 where a=2;
+a length(b) substr(b,1+4*900,2) length(d) substr(d,1+6*900,3)
+2 4512 b1 6000 dd1
+replace t1 set a=1,b='xyz',c=111,d=null;
+commit;
+select a,b from t1 where d is null;
+a b
+1 xyz
+delete from t1 where a=1;
+delete from t1 where a=2;
+commit;
+select count(*) from t1;
+count(*)
+0
insert into t1 values(1,@b1,111,@d1);
insert into t1 values(2,@b2,222,@d2);
commit;
@@ -241,90 +268,6 @@ a b c d
7 7xb7 777 7xdd7
8 8xb8 888 8xdd8
9 9xb9 999 9xdd9
-select * from t1 order by a;
-a b c d
-1 1xb1 111 1xdd1
-2 2xb2 222 2xdd2
-3 3xb3 333 3xdd3
-4 4xb4 444 4xdd4
-5 5xb5 555 5xdd5
-6 6xb6 666 6xdd6
-7 7xb7 777 7xdd7
-8 8xb8 888 8xdd8
-9 9xb9 999 9xdd9
-alter table t1 add x int;
-select * from t1 order by a;
-a b c d x
-1 1xb1 111 1xdd1 NULL
-2 2xb2 222 2xdd2 NULL
-3 3xb3 333 3xdd3 NULL
-4 4xb4 444 4xdd4 NULL
-5 5xb5 555 5xdd5 NULL
-6 6xb6 666 6xdd6 NULL
-7 7xb7 777 7xdd7 NULL
-8 8xb8 888 8xdd8 NULL
-9 9xb9 999 9xdd9 NULL
-alter table t1 drop x;
-select * from t1 order by a;
-a b c d
-1 1xb1 111 1xdd1
-2 2xb2 222 2xdd2
-3 3xb3 333 3xdd3
-4 4xb4 444 4xdd4
-5 5xb5 555 5xdd5
-6 6xb6 666 6xdd6
-7 7xb7 777 7xdd7
-8 8xb8 888 8xdd8
-9 9xb9 999 9xdd9
-create database mysqltest;
-use mysqltest;
-CREATE TABLE t2 (
-a bigint unsigned NOT NULL PRIMARY KEY,
-b int unsigned not null,
-c int unsigned
-) engine=ndbcluster;
-insert into t2 values (1,1,1),(2,2,2);
-select * from test.t1,t2 where test.t1.a = t2.a order by test.t1.a;
-a b c d a b c
-1 1xb1 111 1xdd1 1 1 1
-2 2xb2 222 2xdd2 2 2 2
-drop table t2;
-use test;
-select * from t1 order by a;
-a b c d
-1 1xb1 111 1xdd1
-2 2xb2 222 2xdd2
-3 3xb3 333 3xdd3
-4 4xb4 444 4xdd4
-5 5xb5 555 5xdd5
-6 6xb6 666 6xdd6
-7 7xb7 777 7xdd7
-8 8xb8 888 8xdd8
-9 9xb9 999 9xdd9
-alter table t1 add x int;
-select * from t1 order by a;
-a b c d x
-1 1xb1 111 1xdd1 NULL
-2 2xb2 222 2xdd2 NULL
-3 3xb3 333 3xdd3 NULL
-4 4xb4 444 4xdd4 NULL
-5 5xb5 555 5xdd5 NULL
-6 6xb6 666 6xdd6 NULL
-7 7xb7 777 7xdd7 NULL
-8 8xb8 888 8xdd8 NULL
-9 9xb9 999 9xdd9 NULL
-alter table t1 drop x;
-select * from t1 order by a;
-a b c d
-1 1xb1 111 1xdd1
-2 2xb2 222 2xdd2
-3 3xb3 333 3xdd3
-4 4xb4 444 4xdd4
-5 5xb5 555 5xdd5
-6 6xb6 666 6xdd6
-7 7xb7 777 7xdd7
-8 8xb8 888 8xdd8
-9 9xb9 999 9xdd9
delete from t1 where c >= 100;
commit;
select count(*) from t1;
@@ -375,8 +318,122 @@ rollback;
select count(*) from t1;
count(*)
0
+insert into t1 values(1,'b1',111,'dd1');
+insert into t1 values(2,'b2',222,'dd2');
+insert into t1 values(3,'b3',333,'dd3');
+insert into t1 values(4,'b4',444,'dd4');
+insert into t1 values(5,'b5',555,'dd5');
+insert into t1 values(6,'b6',666,'dd6');
+insert into t1 values(7,'b7',777,'dd7');
+insert into t1 values(8,'b8',888,'dd8');
+insert into t1 values(9,'b9',999,'dd9');
+commit;
+select * from t1 order by a;
+a b c d
+1 b1 111 dd1
+2 b2 222 dd2
+3 b3 333 dd3
+4 b4 444 dd4
+5 b5 555 dd5
+6 b6 666 dd6
+7 b7 777 dd7
+8 b8 888 dd8
+9 b9 999 dd9
+alter table t1 add x int;
+select * from t1 order by a;
+a b c d x
+1 b1 111 dd1 NULL
+2 b2 222 dd2 NULL
+3 b3 333 dd3 NULL
+4 b4 444 dd4 NULL
+5 b5 555 dd5 NULL
+6 b6 666 dd6 NULL
+7 b7 777 dd7 NULL
+8 b8 888 dd8 NULL
+9 b9 999 dd9 NULL
+alter table t1 drop x;
+select * from t1 order by a;
+a b c d
+1 b1 111 dd1
+2 b2 222 dd2
+3 b3 333 dd3
+4 b4 444 dd4
+5 b5 555 dd5
+6 b6 666 dd6
+7 b7 777 dd7
+8 b8 888 dd8
+9 b9 999 dd9
+create database test2;
+use test2;
+CREATE TABLE t2 (
+a bigint unsigned NOT NULL PRIMARY KEY,
+b int unsigned not null,
+c int unsigned
+) engine=ndbcluster;
+insert into t2 values (1,1,1),(2,2,2);
+select * from test.t1,t2 where test.t1.a = t2.a order by test.t1.a;
+a b c d a b c
+1 b1 111 dd1 1 1 1
+2 b2 222 dd2 2 2 2
+drop table t2;
+use test;
+select * from t1 order by a;
+a b c d
+1 b1 111 dd1
+2 b2 222 dd2
+3 b3 333 dd3
+4 b4 444 dd4
+5 b5 555 dd5
+6 b6 666 dd6
+7 b7 777 dd7
+8 b8 888 dd8
+9 b9 999 dd9
+alter table t1 add x int;
+select * from t1 order by a;
+a b c d x
+1 b1 111 dd1 NULL
+2 b2 222 dd2 NULL
+3 b3 333 dd3 NULL
+4 b4 444 dd4 NULL
+5 b5 555 dd5 NULL
+6 b6 666 dd6 NULL
+7 b7 777 dd7 NULL
+8 b8 888 dd8 NULL
+9 b9 999 dd9 NULL
+alter table t1 drop x;
+select * from t1 order by a;
+a b c d
+1 b1 111 dd1
+2 b2 222 dd2
+3 b3 333 dd3
+4 b4 444 dd4
+5 b5 555 dd5
+6 b6 666 dd6
+7 b7 777 dd7
+8 b8 888 dd8
+9 b9 999 dd9
+drop table t1;
+drop database test2;
+create table t1 (
+a int not null primary key,
+b tinytext
+) engine=ndbcluster;
+insert into t1 values(1, 'x');
+update t1 set b = 'y';
+select * from t1;
+a b
+1 x
+delete from t1;
+drop table t1;
+create table t1 (
+a int not null primary key,
+b text not null
+) engine=ndbcluster;
+insert into t1 values(1, '');
+select * from t1;
+a b
+1
drop table t1;
-drop database mysqltest;
set autocommit=1;
use test;
CREATE TABLE t1 (
diff --git a/mysql-test/t/ndb_blob.test b/mysql-test/t/ndb_blob.test
index 5454dd91d26..ba5f089b17b 100644
--- a/mysql-test/t/ndb_blob.test
+++ b/mysql-test/t/ndb_blob.test
@@ -2,7 +2,7 @@
--disable_warnings
drop table if exists t1;
-drop database if exists mysqltest;
+drop database if exists test2;
--enable_warnings
#
@@ -12,31 +12,7 @@ drop database if exists mysqltest;
# A prerequisite for this handler test is that "testBlobs" succeeds.
#
-# -- bug-5252 tinytext crashes --
-
-create table t1 (
- a int not null primary key,
- b tinytext
-) engine=ndbcluster;
-
-insert into t1 values(1, 'x');
-update t1 set b = 'y';
-select * from t1;
-delete from t1;
-drop table t1;
-
-# -- bug-5013 insert empty string to text --
-
-create table t1 (
- a int not null primary key,
- b text not null
-) engine=ndbcluster;
-
-insert into t1 values(1, '');
-select * from t1;
-drop table t1;
-
--- general test starts --
+# -- general test starts --
# make test harder with autocommit off
set autocommit=0;
@@ -117,7 +93,6 @@ from t1 where a=2;
# pk update to null
update t1 set d=null where a=1;
commit;
-# FIXME now fails at random due to weird mixup between the 2 rows
select a from t1 where d is null;
# pk delete
@@ -126,6 +101,49 @@ delete from t1 where a=2;
commit;
select count(*) from t1;
+# -- replace ( bug-6018 ) --
+
+# insert
+replace t1 set a=1,b=@b1,c=111,d=@d1;
+replace t1 set a=2,b=@b2,c=222,d=@d2;
+commit;
+explain select * from t1 where a = 1;
+
+# pk read
+select a,length(b),substr(b,1+2*900,2),length(d),substr(d,1+3*900,3)
+from t1 where a=1;
+select a,length(b),substr(b,1+2*9000,2),length(d),substr(d,1+3*9000,3)
+from t1 where a=2;
+
+# update
+replace t1 set a=1,b=@b2,c=111,d=@d2;
+replace t1 set a=2,b=@b1,c=222,d=@d1;
+commit;
+select a,length(b),substr(b,1+2*9000,2),length(d),substr(d,1+3*9000,3)
+from t1 where a=1;
+select a,length(b),substr(b,1+2*900,2),length(d),substr(d,1+3*900,3)
+from t1 where a=2;
+
+# update
+replace t1 set a=1,b=concat(@b2,@b2),c=111,d=concat(@d2,@d2);
+replace t1 set a=2,b=concat(@b1,@b1),c=222,d=concat(@d1,@d1);
+commit;
+select a,length(b),substr(b,1+4*9000,2),length(d),substr(d,1+6*9000,3)
+from t1 where a=1;
+select a,length(b),substr(b,1+4*900,2),length(d),substr(d,1+6*900,3)
+from t1 where a=2;
+
+# update to null
+replace t1 set a=1,b='xyz',c=111,d=null;
+commit;
+select a,b from t1 where d is null;
+
+# pk delete
+delete from t1 where a=1;
+delete from t1 where a=2;
+commit;
+select count(*) from t1;
+
# -- hash index ops --
insert into t1 values(1,@b1,111,@d1);
@@ -231,39 +249,6 @@ where c >= 100;
commit;
select * from t1 where c >= 100 order by a;
-# alter table
-
-select * from t1 order by a;
-alter table t1 add x int;
-select * from t1 order by a;
-alter table t1 drop x;
-select * from t1 order by a;
-
-# multi db
-
-create database mysqltest;
-use mysqltest;
-
-CREATE TABLE t2 (
- a bigint unsigned NOT NULL PRIMARY KEY,
- b int unsigned not null,
- c int unsigned
-) engine=ndbcluster;
-
-insert into t2 values (1,1,1),(2,2,2);
-select * from test.t1,t2 where test.t1.a = t2.a order by test.t1.a;
-
-drop table t2;
-use test;
-
-# alter table
-
-select * from t1 order by a;
-alter table t1 add x int;
-select * from t1 order by a;
-alter table t1 drop x;
-select * from t1 order by a;
-
# range scan delete
delete from t1 where c >= 100;
commit;
@@ -306,10 +291,77 @@ select a,length(b),substr(b,1+2*900,2),length(d),substr(d,1+3*900,3)
from t1 order by a;
rollback;
select count(*) from t1;
-drop table t1;
-drop database mysqltest;
-# bug #5349
+# -- alter table and multi db --
+
+insert into t1 values(1,'b1',111,'dd1');
+insert into t1 values(2,'b2',222,'dd2');
+insert into t1 values(3,'b3',333,'dd3');
+insert into t1 values(4,'b4',444,'dd4');
+insert into t1 values(5,'b5',555,'dd5');
+insert into t1 values(6,'b6',666,'dd6');
+insert into t1 values(7,'b7',777,'dd7');
+insert into t1 values(8,'b8',888,'dd8');
+insert into t1 values(9,'b9',999,'dd9');
+commit;
+
+select * from t1 order by a;
+alter table t1 add x int;
+select * from t1 order by a;
+alter table t1 drop x;
+select * from t1 order by a;
+
+create database test2;
+use test2;
+
+CREATE TABLE t2 (
+ a bigint unsigned NOT NULL PRIMARY KEY,
+ b int unsigned not null,
+ c int unsigned
+) engine=ndbcluster;
+
+insert into t2 values (1,1,1),(2,2,2);
+select * from test.t1,t2 where test.t1.a = t2.a order by test.t1.a;
+
+drop table t2;
+use test;
+
+select * from t1 order by a;
+alter table t1 add x int;
+select * from t1 order by a;
+alter table t1 drop x;
+select * from t1 order by a;
+
+# -- end general test --
+
+drop table t1;
+drop database test2;
+
+# -- bug-5252 tinytext crashes --
+
+create table t1 (
+ a int not null primary key,
+ b tinytext
+) engine=ndbcluster;
+
+insert into t1 values(1, 'x');
+update t1 set b = 'y';
+select * from t1;
+delete from t1;
+drop table t1;
+
+# -- bug-5013 insert empty string to text --
+
+create table t1 (
+ a int not null primary key,
+ b text not null
+) engine=ndbcluster;
+
+insert into t1 values(1, '');
+select * from t1;
+drop table t1;
+
+# -- bug #5349 --
set autocommit=1;
use test;
CREATE TABLE t1 (
@@ -327,7 +379,7 @@ select * from t1 order by a;
alter table t1 engine=ndb;
select * from t1 order by a;
-# bug #5872
+# -- bug #5872 --
alter table t1 engine=myisam;
select * from t1 order by a;
drop table t1;
diff --git a/ndb/include/ndbapi/NdbBlob.hpp b/ndb/include/ndbapi/NdbBlob.hpp
index 22e393b6c5d..b3c28c9e950 100644
--- a/ndb/include/ndbapi/NdbBlob.hpp
+++ b/ndb/include/ndbapi/NdbBlob.hpp
@@ -36,7 +36,7 @@ class NdbColumnImpl;
* Blob data is stored in 2 places:
*
* - "header" and "inline bytes" stored in the blob attribute
- * - "blob parts" stored in a separate table NDB$BLOB___
+ * - "blob parts" stored in a separate table NDB$BLOB__
*
* Inline and part sizes can be set via NdbDictionary::Column methods
* when the table is created.
@@ -74,23 +74,21 @@ class NdbColumnImpl;
* NdbBlob methods return -1 on error and 0 on success, and use output
* parameters when necessary.
*
- * Notes:
- * - table and its blob part tables are not created atomically
- * - scan must use the "new" interface NdbScanOperation
- * - to update a blob in a read op requires exclusive tuple lock
- * - update op in scan must do its own getBlobHandle
- * - delete creates implicit, not-accessible blob handles
- * - NdbOperation::writeTuple does not support blobs
- * - there is no support for an asynchronous interface
+ * Operation types:
+ * - insertTuple must use setValue if blob column is non-nullable
+ * - readTuple with exclusive lock can also update existing value
+ * - updateTuple can overwrite with setValue or update existing value
+ * - writeTuple always overwrites and must use setValue if non-nullable
+ * - deleteTuple creates implicit non-accessible blob handles
+ * - scan with exclusive lock can also update existing value
+ * - scan "lock takeover" update op must do its own getBlobHandle
*
* Bugs / limitations:
- * - scan must use exclusive locking for now
- *
- * Todo:
- * - add scan method hold-read-lock + return-keyinfo
- * - check keyinfo length when setting keys
- * - check allowed blob ops vs locking mode
- * - overload control (too many pending ops)
+ * - lock mode upgrade should be handled automatically
+ * - lock mode vs allowed operation is not checked
+ * - too many pending blob ops can blow up i/o buffers
+ * - table and its blob part tables are not created atomically
+ * - there is no support for an asynchronous interface
*/
class NdbBlob {
public:
@@ -172,19 +170,11 @@ public:
* read in the in/out bytes parameter.
*/
int readData(void* data, Uint32& bytes);
- /**
- * Read at given position. Does not use or update current position.
- */
- int readData(Uint64 pos, void* data, Uint32& bytes);
/**
* Write at current position and set new position to first byte after
* the data written. A write past blob end extends the blob value.
*/
int writeData(const void* data, Uint32 bytes);
- /**
- * Write at given position. Does not use or update current position.
- */
- int writeData(Uint64 pos, const void* data, Uint32 bytes);
/**
* Return the blob column.
*/
@@ -266,14 +256,17 @@ private:
Buf();
~Buf();
void alloc(unsigned n);
+ void copyfrom(const Buf& src);
};
Buf theKeyBuf;
Buf theAccessKeyBuf;
Buf theHeadInlineBuf;
+ Buf theHeadInlineCopyBuf; // for writeTuple
Buf thePartBuf;
Head* theHead;
char* theInlineData;
NdbRecAttr* theHeadInlineRecAttr;
+ NdbOperation* theHeadInlineReadOp;
bool theHeadInlineUpdateFlag;
// length and read/write position
int theNullFlag;
@@ -294,6 +287,7 @@ private:
bool isReadOp();
bool isInsertOp();
bool isUpdateOp();
+ bool isWriteOp();
bool isDeleteOp();
bool isScanOp();
// computations
@@ -309,12 +303,13 @@ private:
void getHeadFromRecAttr();
int setHeadInlineValue(NdbOperation* anOp);
// data operations
- int readDataPrivate(Uint64 pos, char* buf, Uint32& bytes);
- int writeDataPrivate(Uint64 pos, const char* buf, Uint32 bytes);
+ int readDataPrivate(char* buf, Uint32& bytes);
+ int writeDataPrivate(const char* buf, Uint32 bytes);
int readParts(char* buf, Uint32 part, Uint32 count);
int insertParts(const char* buf, Uint32 part, Uint32 count);
int updateParts(const char* buf, Uint32 part, Uint32 count);
int deleteParts(Uint32 part, Uint32 count);
+ int deletePartsUnknown(Uint32 part);
// pending ops
int executePendingBlobReads();
int executePendingBlobWrites();
diff --git a/ndb/include/ndbapi/NdbConnection.hpp b/ndb/include/ndbapi/NdbConnection.hpp
index 92b940e96f7..7af5d27b922 100644
--- a/ndb/include/ndbapi/NdbConnection.hpp
+++ b/ndb/include/ndbapi/NdbConnection.hpp
@@ -526,7 +526,7 @@ private:
int sendCOMMIT(); // Send a TC_COMMITREQ signal;
void setGCI(int GCI); // Set the global checkpoint identity
- int OpCompleteFailure(Uint8 abortoption);
+ int OpCompleteFailure(Uint8 abortoption, bool setFailure = true);
int OpCompleteSuccess();
void CompletedOperations(); // Move active ops to list of completed
@@ -552,7 +552,7 @@ private:
void setOperationErrorCode(int anErrorCode);
// Indicate something went wrong in the definition phase
- void setOperationErrorCodeAbort(int anErrorCode);
+ void setOperationErrorCodeAbort(int anErrorCode, int abortOption = -1);
int checkMagicNumber(); // Verify correct object
NdbOperation* getNdbOperation(const class NdbTableImpl* aTable,
diff --git a/ndb/include/ndbapi/NdbIndexOperation.hpp b/ndb/include/ndbapi/NdbIndexOperation.hpp
index 7612fe54d1b..1472f1b249e 100644
--- a/ndb/include/ndbapi/NdbIndexOperation.hpp
+++ b/ndb/include/ndbapi/NdbIndexOperation.hpp
@@ -49,6 +49,9 @@ public:
* @{
*/
+ /** insert is not allowed */
+ int insertTuple();
+
/**
* Define the NdbIndexOperation to be a standard operation of type readTuple.
* When calling NdbConnection::execute, this operation
@@ -193,6 +196,7 @@ private:
// Private attributes
const NdbIndexImpl* m_theIndex;
+ const NdbTableImpl* m_thePrimaryTable;
Uint32 m_theIndexDefined[NDB_MAX_ATTRIBUTES_IN_INDEX][3];
Uint32 m_theIndexLen; // Length of the index in words
Uint32 m_theNoOfIndexDefined; // The number of index attributes
diff --git a/ndb/include/ndbapi/NdbOperation.hpp b/ndb/include/ndbapi/NdbOperation.hpp
index 8e0294e41e6..46d4ddab0f5 100644
--- a/ndb/include/ndbapi/NdbOperation.hpp
+++ b/ndb/include/ndbapi/NdbOperation.hpp
@@ -918,6 +918,13 @@ protected:
// Blobs in this operation
NdbBlob* theBlobList;
+ /*
+ * Abort option per operation, used by blobs. Default -1. If set,
+ * overrides abort option on connection level. If set to IgnoreError,
+ * does not cause execute() to return failure. This is different from
+ * IgnoreError on connection level.
+ */
+ Int8 m_abortOption;
};
#ifdef NDB_NO_DROPPED_SIGNAL
@@ -1160,5 +1167,3 @@ NdbOperation::setValue(Uint32 anAttrId, double aPar)
}
#endif
-
-
diff --git a/ndb/src/ndbapi/NdbBlob.cpp b/ndb/src/ndbapi/NdbBlob.cpp
index feab95d8ca5..5b193870558 100644
--- a/ndb/src/ndbapi/NdbBlob.cpp
+++ b/ndb/src/ndbapi/NdbBlob.cpp
@@ -33,21 +33,24 @@
ndbout << prefix << " " << hex << (void*)this << " " << cname; \
ndbout << " " << dec << __LINE__ << " " << x << " " << *this << endl; \
} while (0)
-#else
-#define DBG(x)
-#endif
static char*
ndb_blob_debug(const Uint32* data, unsigned size)
{
- static char buf[128 + 1]; // MT irrelevant
+ static char buf[200]; // MT irrelevant
buf[0] = 0;
- for (unsigned i = 0; i < size && i < 128 / 4; i++) {
- sprintf(buf + strlen(buf), "%*s%08x", i != 0, "", data[i]);
+ for (unsigned i = 0; i < size; i++) {
+ unsigned n = strlen(buf);
+ if (n + 10 < sizeof(buf))
+ sprintf(buf + n, "%*s%08x", i != 0, "", data[i]);
}
return buf;
}
+#else
+#define DBG(x)
+#endif
+
/*
* Reading index table directly (as a table) is faster but there are
* bugs or limitations. Keep the code and make possible to choose.
@@ -162,6 +165,7 @@ NdbBlob::init()
theHead = NULL;
theInlineData = NULL;
theHeadInlineRecAttr = NULL;
+ theHeadInlineReadOp = NULL;
theHeadInlineUpdateFlag = false;
theNullFlag = -1;
theLength = 0;
@@ -206,6 +210,13 @@ NdbBlob::Buf::alloc(unsigned n)
#endif
}
+void
+NdbBlob::Buf::copyfrom(const NdbBlob::Buf& src)
+{
+ assert(size == src.size);
+ memcpy(data, src.data, size);
+}
+
// classify operations (inline)
inline bool
@@ -226,6 +237,7 @@ NdbBlob::isKeyOp()
return
theNdbOp->theOperationType == NdbOperation::InsertRequest ||
theNdbOp->theOperationType == NdbOperation::UpdateRequest ||
+ theNdbOp->theOperationType == NdbOperation::WriteRequest ||
theNdbOp->theOperationType == NdbOperation::ReadRequest ||
theNdbOp->theOperationType == NdbOperation::ReadExclusive ||
theNdbOp->theOperationType == NdbOperation::DeleteRequest;
@@ -253,6 +265,13 @@ NdbBlob::isUpdateOp()
theNdbOp->theOperationType == NdbOperation::UpdateRequest;
}
+inline bool
+NdbBlob::isWriteOp()
+{
+ return
+ theNdbOp->theOperationType == NdbOperation::WriteRequest;
+}
+
inline bool
NdbBlob::isDeleteOp()
{
@@ -289,7 +308,7 @@ inline Uint32
NdbBlob::getDistKey(Uint32 part)
{
assert(theStripeSize != 0);
- return (part / theStripeSize) % theStripeSize;
+ return part / theStripeSize;
}
// getters and setters
@@ -401,7 +420,7 @@ NdbBlob::getHeadFromRecAttr()
theNullFlag = theHeadInlineRecAttr->isNULL();
assert(theNullFlag != -1);
theLength = ! theNullFlag ? theHead->length : 0;
- DBG("getHeadFromRecAttr out");
+ DBG("getHeadFromRecAttr [out]");
}
int
@@ -453,7 +472,7 @@ NdbBlob::setValue(const void* data, Uint32 bytes)
setErrorCode(ErrState);
return -1;
}
- if (! isInsertOp() && ! isUpdateOp()) {
+ if (! isInsertOp() && ! isUpdateOp() && ! isWriteOp()) {
setErrorCode(ErrUsage);
return -1;
}
@@ -466,11 +485,12 @@ NdbBlob::setValue(const void* data, Uint32 bytes)
theGetSetBytes = bytes;
if (isInsertOp()) {
// write inline part now
- if (theSetBuf != 0) {
- unsigned n = theGetSetBytes;
+ if (theSetBuf != NULL) {
+ Uint32 n = theGetSetBytes;
if (n > theInlineSize)
n = theInlineSize;
- if (writeDataPrivate(0, theSetBuf, n) == -1)
+ assert(thePos == 0);
+ if (writeDataPrivate(theSetBuf, n) == -1)
return -1;
} else {
theNullFlag = true;
@@ -555,7 +575,7 @@ NdbBlob::getLength(Uint64& len)
int
NdbBlob::truncate(Uint64 length)
{
- DBG("truncate length=" << length);
+ DBG("truncate [in] length=" << length);
if (theNullFlag == -1) {
setErrorCode(ErrState);
return -1;
@@ -573,7 +593,10 @@ NdbBlob::truncate(Uint64 length)
}
theLength = length;
theHeadInlineUpdateFlag = true;
+ if (thePos > length)
+ thePos = length;
}
+ DBG("truncate [out]");
return 0;
}
@@ -609,33 +632,21 @@ NdbBlob::setPos(Uint64 pos)
int
NdbBlob::readData(void* data, Uint32& bytes)
-{
- if (readData(thePos, data, bytes) == -1)
- return -1;
- thePos += bytes;
- assert(thePos <= theLength);
- return 0;
-}
-
-int
-NdbBlob::readData(Uint64 pos, void* data, Uint32& bytes)
{
if (theState != Active) {
setErrorCode(ErrState);
return -1;
}
char* buf = static_cast(data);
- return readDataPrivate(pos, buf, bytes);
+ return readDataPrivate(buf, bytes);
}
int
-NdbBlob::readDataPrivate(Uint64 pos, char* buf, Uint32& bytes)
+NdbBlob::readDataPrivate(char* buf, Uint32& bytes)
{
- DBG("readData pos=" << pos << " bytes=" << bytes);
- if (pos > theLength) {
- setErrorCode(ErrSeek);
- return -1;
- }
+ DBG("readData [in] bytes=" << bytes);
+ assert(thePos <= theLength);
+ Uint64 pos = thePos;
if (bytes > theLength - pos)
bytes = theLength - pos;
Uint32 len = bytes;
@@ -709,38 +720,29 @@ NdbBlob::readDataPrivate(Uint64 pos, char* buf, Uint32& bytes)
len -= n;
}
assert(len == 0);
+ thePos = pos;
+ assert(thePos <= theLength);
+ DBG("readData [out]");
return 0;
}
int
NdbBlob::writeData(const void* data, Uint32 bytes)
-{
- if (writeData(thePos, data, bytes) == -1)
- return -1;
- thePos += bytes;
- assert(thePos <= theLength);
- return 0;
-}
-
-int
-NdbBlob::writeData(Uint64 pos, const void* data, Uint32 bytes)
{
if (theState != Active) {
setErrorCode(ErrState);
return -1;
}
const char* buf = static_cast(data);
- return writeDataPrivate(pos, buf, bytes);
+ return writeDataPrivate(buf, bytes);
}
int
-NdbBlob::writeDataPrivate(Uint64 pos, const char* buf, Uint32 bytes)
+NdbBlob::writeDataPrivate(const char* buf, Uint32 bytes)
{
- DBG("writeData pos=" << pos << " bytes=" << bytes);
- if (pos > theLength) {
- setErrorCode(ErrSeek);
- return -1;
- }
+ DBG("writeData [in] bytes=" << bytes);
+ assert(thePos <= theLength);
+ Uint64 pos = thePos;
Uint32 len = bytes;
// any write makes blob not NULL
if (theNullFlag) {
@@ -778,7 +780,7 @@ NdbBlob::writeDataPrivate(Uint64 pos, const char* buf, Uint32 bytes)
if (readParts(thePartBuf.data, part, 1) == -1)
return -1;
// need result now
- DBG("execute pending part reafs");
+ DBG("execute pending part reads");
if (executePendingBlobReads() == -1)
return -1;
Uint32 n = thePartSize - off;
@@ -855,14 +857,16 @@ NdbBlob::writeDataPrivate(Uint64 pos, const char* buf, Uint32 bytes)
theLength = pos;
theHeadInlineUpdateFlag = true;
}
- DBG("writeData out");
+ thePos = pos;
+ assert(thePos <= theLength);
+ DBG("writeData [out]");
return 0;
}
int
NdbBlob::readParts(char* buf, Uint32 part, Uint32 count)
{
- DBG("readParts part=" << part << " count=" << count);
+ DBG("readParts [in] part=" << part << " count=" << count);
Uint32 n = 0;
while (n < count) {
NdbOperation* tOp = theNdbCon->getNdbOperation(theBlobTable);
@@ -873,6 +877,7 @@ NdbBlob::readParts(char* buf, Uint32 part, Uint32 count)
setErrorCode(tOp);
return -1;
}
+ tOp->m_abortOption = AbortOnError;
buf += thePartSize;
n++;
thePendingBlobOps |= (1 << NdbOperation::ReadRequest);
@@ -884,7 +889,7 @@ NdbBlob::readParts(char* buf, Uint32 part, Uint32 count)
int
NdbBlob::insertParts(const char* buf, Uint32 part, Uint32 count)
{
- DBG("insertParts part=" << part << " count=" << count);
+ DBG("insertParts [in] part=" << part << " count=" << count);
Uint32 n = 0;
while (n < count) {
NdbOperation* tOp = theNdbCon->getNdbOperation(theBlobTable);
@@ -895,6 +900,7 @@ NdbBlob::insertParts(const char* buf, Uint32 part, Uint32 count)
setErrorCode(tOp);
return -1;
}
+ tOp->m_abortOption = AbortOnError;
buf += thePartSize;
n++;
thePendingBlobOps |= (1 << NdbOperation::InsertRequest);
@@ -906,7 +912,7 @@ NdbBlob::insertParts(const char* buf, Uint32 part, Uint32 count)
int
NdbBlob::updateParts(const char* buf, Uint32 part, Uint32 count)
{
- DBG("updateParts part=" << part << " count=" << count);
+ DBG("updateParts [in] part=" << part << " count=" << count);
Uint32 n = 0;
while (n < count) {
NdbOperation* tOp = theNdbCon->getNdbOperation(theBlobTable);
@@ -917,6 +923,7 @@ NdbBlob::updateParts(const char* buf, Uint32 part, Uint32 count)
setErrorCode(tOp);
return -1;
}
+ tOp->m_abortOption = AbortOnError;
buf += thePartSize;
n++;
thePendingBlobOps |= (1 << NdbOperation::UpdateRequest);
@@ -928,7 +935,7 @@ NdbBlob::updateParts(const char* buf, Uint32 part, Uint32 count)
int
NdbBlob::deleteParts(Uint32 part, Uint32 count)
{
- DBG("deleteParts part=" << part << " count=" << count);
+ DBG("deleteParts [in] part=" << part << " count=" << count);
Uint32 n = 0;
while (n < count) {
NdbOperation* tOp = theNdbCon->getNdbOperation(theBlobTable);
@@ -938,6 +945,7 @@ NdbBlob::deleteParts(Uint32 part, Uint32 count)
setErrorCode(tOp);
return -1;
}
+ tOp->m_abortOption = AbortOnError;
n++;
thePendingBlobOps |= (1 << NdbOperation::DeleteRequest);
theNdbCon->thePendingBlobOps |= (1 << NdbOperation::DeleteRequest);
@@ -945,6 +953,57 @@ NdbBlob::deleteParts(Uint32 part, Uint32 count)
return 0;
}
+/*
+ * Number of blob parts not known. Used to check for race condition
+ * when writeTuple is used for insert. Deletes all parts found.
+ */
+int
+NdbBlob::deletePartsUnknown(Uint32 part)
+{
+ DBG("deletePartsUnknown [in] part=" << part << " count=all");
+ static const unsigned maxbat = 256;
+ static const unsigned minbat = 1;
+ unsigned bat = minbat;
+ NdbOperation* tOpList[maxbat];
+ Uint32 count = 0;
+ while (true) {
+ Uint32 n;
+ n = 0;
+ while (n < bat) {
+ NdbOperation*& tOp = tOpList[n]; // ref
+ tOp = theNdbCon->getNdbOperation(theBlobTable);
+ if (tOp == NULL ||
+ tOp->deleteTuple() == -1 ||
+ setPartKeyValue(tOp, part + count + n) == -1) {
+ setErrorCode(tOp);
+ return -1;
+ }
+ tOp->m_abortOption = IgnoreError;
+ n++;
+ if (theNdbCon->executeNoBlobs(NoCommit) == -1)
+ return -1;
+ }
+ n = 0;
+ while (n < bat) {
+ NdbOperation* tOp = tOpList[n];
+ if (tOp->theError.code != 0) {
+ if (tOp->theError.code != 626) {
+ setErrorCode(tOp);
+ return -1;
+ }
+ // first non-existent part
+ DBG("deletePartsUnknown [out] count=" << count);
+ return 0;
+ }
+ n++;
+ count++;
+ }
+ bat *= 4;
+ if (bat > maxbat)
+ bat = maxbat;
+ }
+}
+
// pending ops
int
@@ -1007,7 +1066,7 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl*
theTable = anOp->m_currentTable;
theAccessTable = anOp->m_accessTable;
theColumn = aColumn;
- DBG("atPrepare");
+ DBG("atPrepare [in]");
NdbDictionary::Column::Type partType = NdbDictionary::Column::Undefined;
switch (theColumn->getType()) {
case NdbDictionary::Column::Blob:
@@ -1046,6 +1105,7 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl*
theKeyBuf.alloc(theTable->m_sizeOfKeysInWords << 2);
theAccessKeyBuf.alloc(theAccessTable->m_sizeOfKeysInWords << 2);
theHeadInlineBuf.alloc(sizeof(Head) + theInlineSize);
+ theHeadInlineCopyBuf.alloc(sizeof(Head) + theInlineSize);
thePartBuf.alloc(thePartSize);
theHead = (Head*)theHeadInlineBuf.data;
theInlineData = theHeadInlineBuf.data + sizeof(Head);
@@ -1080,6 +1140,12 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl*
theNullFlag = true;
theLength = 0;
}
+ if (isWriteOp()) {
+ // becomes NULL unless set before execute
+ theNullFlag = true;
+ theLength = 0;
+ theHeadInlineUpdateFlag = true;
+ }
supportedOp = true;
}
if (isScanOp()) {
@@ -1093,19 +1159,21 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl*
return -1;
}
setState(Prepared);
- DBG("atPrepare out");
+ DBG("atPrepare [out]");
return 0;
}
/*
* Before execute of prepared operation. May add new operations before
* this one. May ask that this operation and all before it (a "batch")
- * is executed immediately in no-commit mode.
+ * is executed immediately in no-commit mode. In this case remaining
+ * prepared operations are saved in a separate list. They are added
+ * back after postExecute.
*/
int
NdbBlob::preExecute(ExecType anExecType, bool& batch)
{
- DBG("preExecute");
+ DBG("preExecute [in]");
if (theState == Invalid)
return -1;
assert(theState == Prepared);
@@ -1120,11 +1188,11 @@ NdbBlob::preExecute(ExecType anExecType, bool& batch)
if (isInsertOp()) {
if (theSetFlag && theGetSetBytes > theInlineSize) {
// add ops to write rest of a setValue
- assert(theSetBuf != 0);
- Uint64 pos = theInlineSize;
+ assert(theSetBuf != NULL);
const char* buf = theSetBuf + theInlineSize;
Uint32 bytes = theGetSetBytes - theInlineSize;
- if (writeDataPrivate(pos, buf, bytes) == -1)
+ assert(thePos == theInlineSize);
+ if (writeDataPrivate(buf, bytes) == -1)
return -1;
if (theHeadInlineUpdateFlag) {
// add an operation to update head+inline
@@ -1136,11 +1204,12 @@ NdbBlob::preExecute(ExecType anExecType, bool& batch)
setErrorCode(ErrAbort);
return -1;
}
+ DBG("add op to update head+inline");
}
}
}
if (isTableOp()) {
- if (isUpdateOp() || isDeleteOp()) {
+ if (isUpdateOp() || isWriteOp() || isDeleteOp()) {
// add operation before this one to read head+inline
NdbOperation* tOp = theNdbCon->getNdbOperation(theTable, theNdbOp);
if (tOp == NULL ||
@@ -1150,8 +1219,13 @@ NdbBlob::preExecute(ExecType anExecType, bool& batch)
setErrorCode(tOp);
return -1;
}
+ if (isWriteOp()) {
+ tOp->m_abortOption = IgnoreError;
+ }
+ theHeadInlineReadOp = tOp;
// execute immediately
batch = true;
+ DBG("add op before to read head+inline");
}
}
if (isIndexOp()) {
@@ -1180,6 +1254,7 @@ NdbBlob::preExecute(ExecType anExecType, bool& batch)
}
}
}
+ DBG("added op before to read table key");
if (isUpdateOp() || isDeleteOp()) {
// add op before this one to read head+inline via index
NdbIndexOperation* tOp = theNdbCon->getNdbIndexOperation(theAccessTable->m_index, theTable, theNdbOp);
@@ -1190,15 +1265,43 @@ NdbBlob::preExecute(ExecType anExecType, bool& batch)
setErrorCode(tOp);
return -1;
}
+ if (isWriteOp()) {
+ tOp->m_abortOption = IgnoreError;
+ }
+ theHeadInlineReadOp = tOp;
// execute immediately
batch = true;
+ DBG("added index op before to read head+inline");
+ }
+ if (isWriteOp()) {
+ // XXX until IgnoreError fixed for index op
+ batch = true;
+ }
+ }
+ if (isWriteOp()) {
+ if (theSetFlag) {
+ // write head+inline now
+ theNullFlag = true;
+ theLength = 0;
+ if (theSetBuf != NULL) {
+ Uint32 n = theGetSetBytes;
+ if (n > theInlineSize)
+ n = theInlineSize;
+ assert(thePos == 0);
+ if (writeDataPrivate(theSetBuf, n) == -1)
+ return -1;
+ }
+ if (setHeadInlineValue(theNdbOp) == -1)
+ return -1;
+ // the read op before us may overwrite
+ theHeadInlineCopyBuf.copyfrom(theHeadInlineBuf);
}
}
if (theActiveHook != NULL) {
// need blob head for callback
batch = true;
}
- DBG("preExecute out batch=" << batch);
+ DBG("preExecute [out] batch=" << batch);
return 0;
}
@@ -1211,15 +1314,16 @@ NdbBlob::preExecute(ExecType anExecType, bool& batch)
int
NdbBlob::postExecute(ExecType anExecType)
{
- DBG("postExecute type=" << anExecType);
+ DBG("postExecute [in] type=" << anExecType);
if (theState == Invalid)
return -1;
if (theState == Active) {
setState(anExecType == NoCommit ? Active : Closed);
- DBG("postExecute skip");
+ DBG("postExecute [skip]");
return 0;
}
assert(theState == Prepared);
+ setState(anExecType == NoCommit ? Active : Closed);
assert(isKeyOp());
if (isIndexOp()) {
NdbBlob* tFirstBlob = theNdbOp->theBlobList;
@@ -1231,22 +1335,13 @@ NdbBlob::postExecute(ExecType anExecType)
}
if (isReadOp()) {
getHeadFromRecAttr();
- if (theGetFlag && theGetSetBytes > 0) {
- // copy inline bytes to user buffer
- assert(theGetBuf != NULL);
- unsigned n = theGetSetBytes;
- if (n > theInlineSize)
- n = theInlineSize;
- memcpy(theGetBuf, theInlineData, n);
- }
- if (theGetFlag && theGetSetBytes > theInlineSize) {
- // add ops to read rest of a getValue
- assert(anExecType == NoCommit);
- assert(theGetBuf != 0);
- Uint64 pos = theInlineSize;
- char* buf = theGetBuf + theInlineSize;
- Uint32 bytes = theGetSetBytes - theInlineSize;
- if (readDataPrivate(pos, buf, bytes) == -1)
+ if (setPos(0) == -1)
+ return -1;
+ if (theGetFlag) {
+ assert(theGetSetBytes == 0 || theGetBuf != 0);
+ assert(theGetSetBytes <= theInlineSize || anExecType == NoCommit);
+ Uint32 bytes = theGetSetBytes;
+ if (readDataPrivate(theGetBuf, bytes) == -1)
return -1;
}
}
@@ -1255,10 +1350,11 @@ NdbBlob::postExecute(ExecType anExecType)
getHeadFromRecAttr();
if (theSetFlag) {
// setValue overwrites everything
- if (theSetBuf != 0) {
+ if (theSetBuf != NULL) {
if (truncate(0) == -1)
return -1;
- if (writeDataPrivate(0, theSetBuf, theGetSetBytes) == -1)
+ assert(thePos == 0);
+ if (writeDataPrivate(theSetBuf, theGetSetBytes) == -1)
return -1;
} else {
if (setNull() == -1)
@@ -1266,6 +1362,57 @@ NdbBlob::postExecute(ExecType anExecType)
}
}
}
+ if (isWriteOp() && isTableOp()) {
+ assert(anExecType == NoCommit);
+ if (theHeadInlineReadOp->theError.code == 0) {
+ int tNullFlag = theNullFlag;
+ Uint64 tLength = theLength;
+ Uint64 tPos = thePos;
+ getHeadFromRecAttr();
+ DBG("tuple found");
+ if (truncate(0) == -1)
+ return -1;
+ // restore previous head+inline
+ theHeadInlineBuf.copyfrom(theHeadInlineCopyBuf);
+ theNullFlag = tNullFlag;
+ theLength = tLength;
+ thePos = tPos;
+ } else {
+ if (theHeadInlineReadOp->theError.code != 626) {
+ setErrorCode(theHeadInlineReadOp);
+ return -1;
+ }
+ DBG("tuple not found");
+ /*
+ * Read found no tuple but it is possible that a tuple was
+ * created after the read by another transaction. Delete all
+ * blob parts which may exist.
+ */
+ if (deletePartsUnknown(0) == -1)
+ return -1;
+ }
+ if (theSetFlag && theGetSetBytes > theInlineSize) {
+ assert(theSetBuf != NULL);
+ const char* buf = theSetBuf + theInlineSize;
+ Uint32 bytes = theGetSetBytes - theInlineSize;
+ assert(thePos == theInlineSize);
+ if (writeDataPrivate(buf, bytes) == -1)
+ return -1;
+ }
+ }
+ if (isWriteOp() && isIndexOp()) {
+ // XXX until IgnoreError fixed for index op
+ if (deletePartsUnknown(0) == -1)
+ return -1;
+ if (theSetFlag && theGetSetBytes > theInlineSize) {
+ assert(theSetBuf != NULL);
+ const char* buf = theSetBuf + theInlineSize;
+ Uint32 bytes = theGetSetBytes - theInlineSize;
+ assert(thePos == theInlineSize);
+ if (writeDataPrivate(buf, bytes) == -1)
+ return -1;
+ }
+ }
if (isDeleteOp()) {
assert(anExecType == NoCommit);
getHeadFromRecAttr();
@@ -1278,7 +1425,7 @@ NdbBlob::postExecute(ExecType anExecType)
if (invokeActiveHook() == -1)
return -1;
}
- DBG("postExecute out");
+ DBG("postExecute [out]");
return 0;
}
@@ -1289,12 +1436,12 @@ NdbBlob::postExecute(ExecType anExecType)
int
NdbBlob::preCommit()
{
- DBG("preCommit");
+ DBG("preCommit [in]");
if (theState == Invalid)
return -1;
assert(theState == Active);
assert(isKeyOp());
- if (isInsertOp() || isUpdateOp()) {
+ if (isInsertOp() || isUpdateOp() || isWriteOp()) {
if (theHeadInlineUpdateFlag) {
// add an operation to update head+inline
NdbOperation* tOp = theNdbCon->getNdbOperation(theTable);
@@ -1305,9 +1452,11 @@ NdbBlob::preCommit()
setErrorCode(ErrAbort);
return -1;
}
+ tOp->m_abortOption = AbortOnError;
+ DBG("added op to update head+inline");
}
}
- DBG("preCommit out");
+ DBG("preCommit [out]");
return 0;
}
@@ -1317,13 +1466,10 @@ NdbBlob::preCommit()
int
NdbBlob::atNextResult()
{
- DBG("atNextResult");
+ DBG("atNextResult [in]");
if (theState == Invalid)
return -1;
assert(isScanOp());
- getHeadFromRecAttr();
- // reset position
- thePos = 0;
// get primary key
{ Uint32* data = (Uint32*)theKeyBuf.data;
unsigned size = theTable->m_sizeOfKeysInWords;
@@ -1332,26 +1478,14 @@ NdbBlob::atNextResult()
return -1;
}
}
- if (! theNullFlag) {
- if (theGetFlag && theGetSetBytes > 0) {
- // copy inline bytes to user buffer
- assert(theGetBuf != NULL);
- unsigned n = theGetSetBytes;
- if (n > theLength)
- n = theLength;
- if (n > theInlineSize)
- n = theInlineSize;
- memcpy(theGetBuf, theInlineData, n);
- }
- if (theGetFlag && theGetSetBytes > theInlineSize && theLength > theInlineSize) {
- // add ops to read rest of a getValue
- assert(theGetBuf != 0);
- Uint64 pos = theInlineSize;
- char* buf = theGetBuf + theInlineSize;
- Uint32 bytes = theGetSetBytes - theInlineSize;
- if (readDataPrivate(pos, buf, bytes) == -1)
- return -1;
- }
+ getHeadFromRecAttr();
+ if (setPos(0) == -1)
+ return -1;
+ if (theGetFlag) {
+ assert(theGetSetBytes == 0 || theGetBuf != 0);
+ Uint32 bytes = theGetSetBytes;
+ if (readDataPrivate(theGetBuf, bytes) == -1)
+ return -1;
}
setState(Active);
// activation callback
@@ -1359,7 +1493,7 @@ NdbBlob::atNextResult()
if (invokeActiveHook() == -1)
return -1;
}
- DBG("atNextResult out");
+ DBG("atNextResult [out]");
return 0;
}
@@ -1444,7 +1578,8 @@ operator<<(NdbOut& out, const NdbBlob& blob)
ndbout << dec << " n=" << blob.theNullFlag;;
ndbout << dec << " l=" << blob.theLength;
ndbout << dec << " p=" << blob.thePos;
- ndbout << dec << " u=" << (Uint32) blob.theHeadInlineUpdateFlag;
+ ndbout << dec << " u=" << (Uint32)blob.theHeadInlineUpdateFlag;
+ ndbout << dec << " g=" << (Uint32)blob.theGetSetBytes;
return out;
}
#endif
diff --git a/ndb/src/ndbapi/NdbConnection.cpp b/ndb/src/ndbapi/NdbConnection.cpp
index 1457792cf28..c21a85fd24d 100644
--- a/ndb/src/ndbapi/NdbConnection.cpp
+++ b/ndb/src/ndbapi/NdbConnection.cpp
@@ -170,12 +170,14 @@ Remark: Sets an error code on the connection object from an
operation object.
*****************************************************************************/
void
-NdbConnection::setOperationErrorCodeAbort(int error)
+NdbConnection::setOperationErrorCodeAbort(int error, int abortOption)
{
DBUG_ENTER("NdbConnection::setOperationErrorCodeAbort");
+ if (abortOption == -1)
+ abortOption = m_abortOption;
if (theTransactionIsStarted == false) {
theCommitStatus = Aborted;
- } else if ((m_abortOption == AbortOnError) &&
+ } else if ((abortOption == AbortOnError) &&
(theCommitStatus != Committed) &&
(theCommitStatus != Aborted)) {
theCommitStatus = NeedAbort;
@@ -335,8 +337,11 @@ NdbConnection::execute(ExecType aTypeOfExec,
tOp = tOp->next();
}
}
+
if (executeNoBlobs(tExecType, abortOption, forceSend) == -1)
ret = -1;
+ assert(theFirstOpInList == NULL && theLastOpInList == NULL);
+
{
NdbOperation* tOp = theCompletedFirstOp;
while (tOp != NULL) {
@@ -360,6 +365,7 @@ NdbConnection::execute(ExecType aTypeOfExec,
theLastOpInList->next(tRestOp);
theLastOpInList = tLastOp;
}
+ assert(theFirstOpInList == NULL || tExecType == NoCommit);
} while (theFirstOpInList != NULL || tExecType != aTypeOfExec);
DBUG_RETURN(ret);
@@ -1806,11 +1812,12 @@ Parameters: aErrorCode: The error code.
Remark: An operation was completed with failure.
*******************************************************************************/
int
-NdbConnection::OpCompleteFailure(Uint8 abortOption)
+NdbConnection::OpCompleteFailure(Uint8 abortOption, bool setFailure)
{
Uint32 tNoComp = theNoOfOpCompleted;
Uint32 tNoSent = theNoOfOpSent;
- theCompletionStatus = NdbConnection::CompletedFailure;
+ if (setFailure)
+ theCompletionStatus = NdbConnection::CompletedFailure;
tNoComp++;
theNoOfOpCompleted = tNoComp;
if (tNoComp == tNoSent) {
diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/ndb/src/ndbapi/NdbDictionaryImpl.cpp
index cf51a30fe0b..76854cabcd7 100644
--- a/ndb/src/ndbapi/NdbDictionaryImpl.cpp
+++ b/ndb/src/ndbapi/NdbDictionaryImpl.cpp
@@ -47,13 +47,15 @@
* Column
*/
NdbColumnImpl::NdbColumnImpl()
- : NdbDictionary::Column(* this), m_facade(this)
+ : NdbDictionary::Column(* this), m_facade(this),
+ m_attrId(-1)
{
init();
}
NdbColumnImpl::NdbColumnImpl(NdbDictionary::Column & f)
- : NdbDictionary::Column(* this), m_facade(&f)
+ : NdbDictionary::Column(* this), m_facade(&f),
+ m_attrId(-1)
{
init();
}
@@ -93,8 +95,7 @@ NdbColumnImpl::init(Type t)
{
// do not use default_charset_info as it may not be initialized yet
// use binary collation until NDB tests can handle charsets
- CHARSET_INFO* default_cs = &my_charset_latin1_bin;
- m_attrId = -1;
+ CHARSET_INFO* default_cs = &my_charset_bin;
m_type = t;
switch (m_type) {
case Tinyint:
diff --git a/ndb/src/ndbapi/NdbIndexOperation.cpp b/ndb/src/ndbapi/NdbIndexOperation.cpp
index 9abde639914..3f174a61b64 100644
--- a/ndb/src/ndbapi/NdbIndexOperation.cpp
+++ b/ndb/src/ndbapi/NdbIndexOperation.cpp
@@ -71,6 +71,7 @@ NdbIndexOperation::indxInit(const NdbIndexImpl * anIndex,
return -1;
}
m_theIndex = anIndex;
+ m_thePrimaryTable = aTable;
m_accessTable = anIndex->m_table;
m_theIndexLen = 0;
m_theNoOfIndexDefined = 0;
@@ -102,6 +103,12 @@ int NdbIndexOperation::readTuple(NdbOperation::LockMode lm)
};
}
+int NdbIndexOperation::insertTuple()
+{
+ setErrorCode(4200);
+ return -1;
+}
+
int NdbIndexOperation::readTuple()
{
// First check that index is unique
@@ -341,12 +348,11 @@ int NdbIndexOperation::equal_impl(const NdbColumnImpl* tAttrInfo,
theDistrGroupIndicator = 1;
}//if
/**************************************************************************
- * If the operation is an insert request and the attribute is stored then
+ * If the operation is a write request and the attribute is stored then
* we also set the value in the stored part through putting the
* information in the INDXATTRINFO signals.
*************************************************************************/
- if ((tOpType == InsertRequest) ||
- (tOpType == WriteRequest)) {
+ if ((tOpType == WriteRequest)) {
if (!tAttrInfo->m_indexOnly){
// invalid data can crash kernel
if (cs != NULL &&
@@ -357,7 +363,13 @@ int NdbIndexOperation::equal_impl(const NdbColumnImpl* tAttrInfo,
goto equal_error4;
Uint32 ahValue;
Uint32 sz = totalSizeInWords;
- AttributeHeader::init(&ahValue, tAttrId, sz);
+ /*
+ * XXX should be linked in metadata but cannot now because
+ * things can be defined in arbitrary order
+ */
+ const NdbColumnImpl* primaryCol = m_thePrimaryTable->getColumn(tAttrInfo->m_name.c_str());
+ assert(primaryCol != NULL);
+ AttributeHeader::init(&ahValue, primaryCol->m_attrId, sz);
insertATTRINFO( ahValue );
insertATTRINFOloop((Uint32*)aValueToWrite, sizeInWords);
if (bitsInLastWord != 0) {
@@ -369,7 +381,6 @@ int NdbIndexOperation::equal_impl(const NdbColumnImpl* tAttrInfo,
}//if
}//if
}//if
-
/**************************************************************************
* Store the Key information in the TCINDXREQ and INDXKEYINFO signals.
*************************************************************************/
@@ -734,13 +745,10 @@ NdbIndexOperation::receiveTCINDXREF( NdbApiSignal* aSignal)
}//if
theStatus = Finished;
-
+
theNdbCon->theReturnStatus = NdbConnection::ReturnFailure;
Uint32 errorCode = tcIndxRef->errorCode;
theError.code = errorCode;
theNdbCon->setOperationErrorCodeAbort(errorCode);
return theNdbCon->OpCompleteFailure(theNdbCon->m_abortOption);
}//NdbIndexOperation::receiveTCINDXREF()
-
-
-
diff --git a/ndb/src/ndbapi/NdbOperation.cpp b/ndb/src/ndbapi/NdbOperation.cpp
index b0b95d0ff43..88d8a000d50 100644
--- a/ndb/src/ndbapi/NdbOperation.cpp
+++ b/ndb/src/ndbapi/NdbOperation.cpp
@@ -78,7 +78,8 @@ NdbOperation::NdbOperation(Ndb* aNdb) :
m_tcReqGSN(GSN_TCKEYREQ),
m_keyInfoGSN(GSN_KEYINFO),
m_attrInfoGSN(GSN_ATTRINFO),
- theBlobList(NULL)
+ theBlobList(NULL),
+ m_abortOption(-1)
{
theReceiver.init(NdbReceiver::NDB_OPERATION, this);
theError.code = 0;
@@ -167,6 +168,7 @@ NdbOperation::init(const NdbTableImpl* tab, NdbConnection* myConnection){
theTotalNrOfKeyWordInSignal = 8;
theMagicNumber = 0xABCDEF01;
theBlobList = NULL;
+ m_abortOption = -1;
tSignal = theNdb->getSignal();
if (tSignal == NULL)
diff --git a/ndb/src/ndbapi/NdbOperationExec.cpp b/ndb/src/ndbapi/NdbOperationExec.cpp
index f1338ae01e4..fa46e93a57f 100644
--- a/ndb/src/ndbapi/NdbOperationExec.cpp
+++ b/ndb/src/ndbapi/NdbOperationExec.cpp
@@ -191,7 +191,8 @@ NdbOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransId)
Uint8 tDirtyIndicator = theDirtyIndicator;
OperationType tOperationType = theOperationType;
Uint32 tTupKeyLen = theTupKeyLen;
- Uint8 abortOption = theNdbCon->m_abortOption;
+ Uint8 abortOption =
+ m_abortOption != -1 ? m_abortOption : theNdbCon->m_abortOption;
tcKeyReq->setDirtyFlag(tReqInfo, tDirtyIndicator);
tcKeyReq->setOperationType(tReqInfo, tOperationType);
@@ -541,17 +542,20 @@ NdbOperation::receiveTCKEYREF( NdbApiSignal* aSignal)
return -1;
}//if
- AbortOption ao = (AbortOption)theNdbCon->m_abortOption;
+ AbortOption ao = (AbortOption)
+ (m_abortOption != -1 ? m_abortOption : theNdbCon->m_abortOption);
theReceiver.m_received_result_length = ~0;
theStatus = Finished;
- theNdbCon->theReturnStatus = NdbConnection::ReturnFailure;
+ // blobs want this
+ if (m_abortOption != IgnoreError)
+ theNdbCon->theReturnStatus = NdbConnection::ReturnFailure;
theError.code = aSignal->readData(4);
- theNdbCon->setOperationErrorCodeAbort(aSignal->readData(4));
+ theNdbCon->setOperationErrorCodeAbort(aSignal->readData(4), ao);
if(theOperationType != ReadRequest || !theSimpleIndicator) // not simple read
- return theNdbCon->OpCompleteFailure(ao);
+ return theNdbCon->OpCompleteFailure(ao, m_abortOption != IgnoreError);
/**
* If TCKEYCONF has arrived
diff --git a/ndb/test/ndbapi/testBlobs.cpp b/ndb/test/ndbapi/testBlobs.cpp
index 41bb82f3e06..f7ee7921229 100644
--- a/ndb/test/ndbapi/testBlobs.cpp
+++ b/ndb/test/ndbapi/testBlobs.cpp
@@ -48,7 +48,7 @@ struct Opt {
unsigned m_rows;
unsigned m_seed;
const char* m_skip;
- const char* m_style;
+ const char* m_test;
// metadata
const char* m_tname;
const char* m_x1name; // hash index
@@ -71,8 +71,8 @@ struct Opt {
m_parts(10),
m_rows(100),
m_seed(0),
- m_skip(""),
- m_style("012"),
+ m_skip(0),
+ m_test(0),
// metadata
m_tname("TBLOB1"),
m_x1name("TBLOB1X1"),
@@ -101,45 +101,44 @@ printusage()
<< " -dbg print debug" << endl
<< " -dbgall print also NDB API debug (if compiled in)" << endl
<< " -full read/write only full blob values" << endl
- << " -inline read/write only blobs which fit inline" << endl
<< " -loop N loop N times 0=forever [" << d.m_loop << "]" << endl
<< " -parts N max parts in blob value [" << d.m_parts << "]" << endl
<< " -rows N number of rows [" << d.m_rows << "]" << endl
<< " -seed N random seed 0=loop number [" << d.m_seed << "]" << endl
- << " -skip xxx skip these tests (see list) [" << d.m_skip << endl
- << " -style xxx access styles to test (see list) [" << d.m_style << "]" << endl
+ << " -skip xxx skip given tests (see list) [no tests]" << endl
+ << " -test xxx only given tests (see list) [all tests]" << endl
<< "metadata" << endl
<< " -pk2len N length of PK2 [" << d.m_pk2len << "/" << g_max_pk2len <<"]" << endl
<< " -oneblob only 1 blob attribute [default 2]" << endl
- << "testcases for -skip" << endl
+ << "testcases for test/skip" << endl
<< " k primary key ops" << endl
<< " i hash index ops" << endl
<< " s table scans" << endl
<< " r ordered index scans" << endl
- << " u update blob value" << endl
- << "access styles for -style" << endl
+ << "additional flags for test/skip" << endl
+ << " u update existing blob value" << endl
+ << " n normal insert and update" << endl
+ << " w insert and update using writeTuple" << endl
<< " 0 getValue / setValue" << endl
<< " 1 setActiveHook" << endl
<< " 2 readData / writeData" << endl
<< "bug tests (no blob test)" << endl
<< " -bug 4088 ndb api hang with mixed ops on index table" << endl
- << " -bug 2222 delete + write gives 626" << endl
- << " -bug 3333 acc crash on delete and long key" << endl
+ << " -bug nnnn delete + write gives 626" << endl
+ << " -bug nnnn acc crash on delete and long key" << endl
;
}
static Opt g_opt;
static bool
-skipcase(int x)
+testcase(char x)
{
- return strchr(g_opt.m_skip, x) != 0;
-}
-
-static bool
-skipstyle(int x)
-{
- return strchr(g_opt.m_style, '0' + x) == 0;
+ if (x < 10)
+ x += '0';
+ return
+ (g_opt.m_test == 0 || strchr(g_opt.m_test, x) != 0) &&
+ (g_opt.m_skip == 0 || strchr(g_opt.m_skip, x) == 0);
}
static Ndb* g_ndb = 0;
@@ -435,7 +434,9 @@ getBlobLength(NdbBlob* h, unsigned& len)
CHK(h->getLength(len2) == 0);
len = (unsigned)len2;
assert(len == len2);
- DBG("getBlobLength " << h->getColumn()->getName() << " len=" << len);
+ bool isNull;
+ CHK(h->getNull(isNull) == 0);
+ DBG("getBlobLength " << h->getColumn()->getName() << " len=" << len << " null=" << isNull);
return 0;
}
@@ -911,6 +912,41 @@ updatePk(int style)
return 0;
}
+static int
+writePk(int style)
+{
+ DBG("--- writePk " << stylename[style] << " ---");
+ for (unsigned k = 0; k < g_opt.m_rows; k++) {
+ Tup& tup = g_tups[k];
+ DBG("writePk pk1=" << hex << tup.m_pk1);
+ CHK((g_con = g_ndb->startTransaction()) != 0);
+ CHK((g_opr = g_con->getNdbOperation(g_opt.m_tname)) != 0);
+ CHK(g_opr->writeTuple() == 0);
+ CHK(g_opr->equal("PK1", tup.m_pk1) == 0);
+ if (g_opt.m_pk2len != 0)
+ CHK(g_opr->equal("PK2", tup.m_pk2) == 0);
+ CHK(getBlobHandles(g_opr) == 0);
+ if (style == 0) {
+ CHK(setBlobValue(tup) == 0);
+ } else if (style == 1) {
+ // non-nullable must be set
+ CHK(g_bh1->setValue("", 0) == 0);
+ CHK(setBlobWriteHook(tup) == 0);
+ } else {
+ // non-nullable must be set
+ CHK(g_bh1->setValue("", 0) == 0);
+ CHK(g_con->execute(NoCommit) == 0);
+ CHK(writeBlobData(tup) == 0);
+ }
+ CHK(g_con->execute(Commit) == 0);
+ g_ndb->closeTransaction(g_con);
+ g_opr = 0;
+ g_con = 0;
+ tup.m_exists = true;
+ }
+ return 0;
+}
+
static int
deletePk()
{
@@ -995,6 +1031,35 @@ updateIdx(int style)
return 0;
}
+static int
+writeIdx(int style)
+{
+ DBG("--- writeIdx " << stylename[style] << " ---");
+ for (unsigned k = 0; k < g_opt.m_rows; k++) {
+ Tup& tup = g_tups[k];
+ DBG("writeIdx pk1=" << hex << tup.m_pk1);
+ CHK((g_con = g_ndb->startTransaction()) != 0);
+ CHK((g_opx = g_con->getNdbIndexOperation(g_opt.m_x1name, g_opt.m_tname)) != 0);
+ CHK(g_opx->writeTuple() == 0);
+ CHK(g_opx->equal("PK2", tup.m_pk2) == 0);
+ CHK(getBlobHandles(g_opx) == 0);
+ if (style == 0) {
+ CHK(setBlobValue(tup) == 0);
+ } else if (style == 1) {
+ CHK(setBlobWriteHook(tup) == 0);
+ } else {
+ CHK(g_con->execute(NoCommit) == 0);
+ CHK(writeBlobData(tup) == 0);
+ }
+ CHK(g_con->execute(Commit) == 0);
+ g_ndb->closeTransaction(g_con);
+ g_opx = 0;
+ g_con = 0;
+ tup.m_exists = true;
+ }
+ return 0;
+}
+
static int
deleteIdx()
{
@@ -1170,7 +1235,6 @@ deleteScan(bool idx)
static int
testmain()
{
- int style;
g_ndb = new Ndb("TEST_DB");
CHK(g_ndb->init() == 0);
CHK(g_ndb->waitUntilReady() == 0);
@@ -1194,55 +1258,88 @@ testmain()
if (g_opt.m_seed != 0)
srandom(g_opt.m_seed);
for (g_loop = 0; g_opt.m_loop == 0 || g_loop < g_opt.m_loop; g_loop++) {
+ int style;
DBG("=== loop " << g_loop << " ===");
if (g_opt.m_seed == 0)
srandom(g_loop);
// pk
for (style = 0; style <= 2; style++) {
- if (skipcase('k') || skipstyle(style))
+ if (! testcase('k') || ! testcase(style))
continue;
DBG("--- pk ops " << stylename[style] << " ---");
- calcTups(false);
- CHK(insertPk(style) == 0);
- CHK(verifyBlob() == 0);
- CHK(readPk(style) == 0);
- if (! skipcase('u')) {
- calcTups(style);
- CHK(updatePk(style) == 0);
+ if (testcase('n')) {
+ calcTups(false);
+ CHK(insertPk(style) == 0);
+ CHK(verifyBlob() == 0);
+ CHK(readPk(style) == 0);
+ if (testcase('u')) {
+ calcTups(style);
+ CHK(updatePk(style) == 0);
+ CHK(verifyBlob() == 0);
+ CHK(readPk(style) == 0);
+ }
+ CHK(deletePk() == 0);
+ CHK(verifyBlob() == 0);
+ }
+ if (testcase('w')) {
+ calcTups(false);
+ CHK(writePk(style) == 0);
+ CHK(verifyBlob() == 0);
+ CHK(readPk(style) == 0);
+ if (testcase('u')) {
+ calcTups(style);
+ CHK(writePk(style) == 0);
+ CHK(verifyBlob() == 0);
+ CHK(readPk(style) == 0);
+ }
+ CHK(deletePk() == 0);
CHK(verifyBlob() == 0);
}
- CHK(readPk(style) == 0);
- CHK(deletePk() == 0);
- CHK(verifyBlob() == 0);
}
// hash index
for (style = 0; style <= 2; style++) {
- if (skipcase('i') || skipstyle(style))
+ if (! testcase('i') || ! testcase(style))
continue;
DBG("--- idx ops " << stylename[style] << " ---");
- calcTups(false);
- CHK(insertPk(style) == 0);
- CHK(verifyBlob() == 0);
- CHK(readIdx(style) == 0);
- calcTups(style);
- if (! skipcase('u')) {
- CHK(updateIdx(style) == 0);
+ if (testcase('n')) {
+ calcTups(false);
+ CHK(insertPk(style) == 0);
CHK(verifyBlob() == 0);
CHK(readIdx(style) == 0);
+ if (testcase('u')) {
+ calcTups(style);
+ CHK(updateIdx(style) == 0);
+ CHK(verifyBlob() == 0);
+ CHK(readIdx(style) == 0);
+ }
+ CHK(deleteIdx() == 0);
+ CHK(verifyBlob() == 0);
+ }
+ if (testcase('w')) {
+ calcTups(false);
+ CHK(writePk(style) == 0);
+ CHK(verifyBlob() == 0);
+ CHK(readIdx(style) == 0);
+ if (testcase('u')) {
+ calcTups(style);
+ CHK(writeIdx(style) == 0);
+ CHK(verifyBlob() == 0);
+ CHK(readIdx(style) == 0);
+ }
+ CHK(deleteIdx() == 0);
+ CHK(verifyBlob() == 0);
}
- CHK(deleteIdx() == 0);
- CHK(verifyBlob() == 0);
}
// scan table
for (style = 0; style <= 2; style++) {
- if (skipcase('s') || skipstyle(style))
+ if (! testcase('s') || ! testcase(style))
continue;
DBG("--- table scan " << stylename[style] << " ---");
calcTups(false);
CHK(insertPk(style) == 0);
CHK(verifyBlob() == 0);
CHK(readScan(style, false) == 0);
- if (! skipcase('u')) {
+ if (testcase('u')) {
CHK(updateScan(style, false) == 0);
CHK(verifyBlob() == 0);
}
@@ -1251,14 +1348,14 @@ testmain()
}
// scan index
for (style = 0; style <= 2; style++) {
- if (skipcase('r') || skipstyle(style))
+ if (! testcase('r') || ! testcase(style))
continue;
DBG("--- index scan " << stylename[style] << " ---");
calcTups(false);
CHK(insertPk(style) == 0);
CHK(verifyBlob() == 0);
CHK(readScan(style, true) == 0);
- if (! skipcase('u')) {
+ if (testcase('u')) {
CHK(updateScan(style, true) == 0);
CHK(verifyBlob() == 0);
}
@@ -1331,9 +1428,7 @@ static struct {
int m_bug;
int (*m_test)();
} g_bugtest[] = {
- { 4088, bugtest_4088 },
- { 2222, bugtest_2222 },
- { 3333, bugtest_3333 }
+ { 4088, bugtest_4088 }
};
NDB_COMMAND(testOdbcDriver, "testBlobs", "testBlobs", "testBlobs", 65535)
@@ -1395,9 +1490,9 @@ NDB_COMMAND(testOdbcDriver, "testBlobs", "testBlobs", "testBlobs", 65535)
continue;
}
}
- if (strcmp(arg, "-style") == 0) {
+ if (strcmp(arg, "-test") == 0) {
if (++argv, --argc > 0) {
- g_opt.m_style = strdup(argv[0]);
+ g_opt.m_test = strdup(argv[0]);
continue;
}
}
@@ -1433,7 +1528,9 @@ NDB_COMMAND(testOdbcDriver, "testBlobs", "testBlobs", "testBlobs", 65535)
}
if (g_opt.m_pk2len == 0) {
char b[100];
- strcpy(b, g_opt.m_skip);
+ b[0] = 0;
+ if (g_opt.m_skip != 0)
+ strcpy(b, g_opt.m_skip);
strcat(b, "i");
strcat(b, "r");
g_opt.m_skip = strdup(b);
From ef167e52bf680523ffa9d8c1f72bc798f2be3808 Mon Sep 17 00:00:00 2001
From: "joreland@mysql.com" <>
Date: Mon, 1 Nov 2004 10:38:27 +0100
Subject: [PATCH 28/59] Fixed hanging ndb_mgmd on various platforms Move init
of node-init-mutex to before alloc node id
---
ndb/src/mgmsrv/MgmtSrvr.cpp | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/ndb/src/mgmsrv/MgmtSrvr.cpp b/ndb/src/mgmsrv/MgmtSrvr.cpp
index 29df10630f3..01dae3aeddb 100644
--- a/ndb/src/mgmsrv/MgmtSrvr.cpp
+++ b/ndb/src/mgmsrv/MgmtSrvr.cpp
@@ -480,6 +480,13 @@ MgmtSrvr::MgmtSrvr(NodeId nodeId,
_ownNodeId= 0;
NodeId tmp= nodeId;
BaseString error_string;
+
+ if ((m_node_id_mutex = NdbMutex_Create()) == 0)
+ {
+ ndbout << "mutex creation failed line = " << __LINE__ << endl;
+ exit(-1);
+ }
+
#if 0
char my_hostname[256];
struct sockaddr_in tmp_addr;
@@ -512,7 +519,6 @@ MgmtSrvr::MgmtSrvr(NodeId nodeId,
#endif
_ownNodeId = tmp;
-
{
DBUG_PRINT("info", ("verifyConfig"));
ConfigRetriever cr(m_local_config, NDB_VERSION, NDB_MGM_NODE_TYPE_MGM);
@@ -534,12 +540,6 @@ MgmtSrvr::MgmtSrvr(NodeId nodeId,
m_statisticsListner.m_logLevel = se.m_logLevel;
}
- if ((m_node_id_mutex = NdbMutex_Create()) == 0)
- {
- ndbout << "mutex creation failed line = " << __LINE__ << endl;
- exit(-1);
- }
-
DBUG_VOID_RETURN;
}
From f8e15a41f512cc471749a38b9bcfc27003a9d6e0 Mon Sep 17 00:00:00 2001
From: "joreland@mysql.com" <>
Date: Mon, 1 Nov 2004 12:49:38 +0100
Subject: [PATCH 29/59] Removed old not used/illegal declaration
---
ndb/include/kernel/signaldata/DictTabInfo.hpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/ndb/include/kernel/signaldata/DictTabInfo.hpp b/ndb/include/kernel/signaldata/DictTabInfo.hpp
index 6b4a3f34553..ae78c023c2a 100644
--- a/ndb/include/kernel/signaldata/DictTabInfo.hpp
+++ b/ndb/include/kernel/signaldata/DictTabInfo.hpp
@@ -51,7 +51,6 @@ class DictTabInfo {
friend class Trix;
friend class DbUtil;
// API
- friend class Table;
friend class NdbSchemaOp;
/**
From 6da0dd791f45ae32626fa6958142dac0124a35bc Mon Sep 17 00:00:00 2001
From: "pekka@mysql.com" <>
Date: Mon, 1 Nov 2004 13:01:20 +0100
Subject: [PATCH 30/59] NDB blob fixes. INCOMPATIBLE with existing blobs
---
ndb/src/ndbapi/NdbBlob.cpp | 43 ++++++++++++++++++-----------------
ndb/test/ndbapi/testBlobs.cpp | 7 ++++++
2 files changed, 29 insertions(+), 21 deletions(-)
diff --git a/ndb/src/ndbapi/NdbBlob.cpp b/ndb/src/ndbapi/NdbBlob.cpp
index 5b193870558..13532a413bb 100644
--- a/ndb/src/ndbapi/NdbBlob.cpp
+++ b/ndb/src/ndbapi/NdbBlob.cpp
@@ -97,6 +97,14 @@ NdbBlob::getBlobTable(NdbTableImpl& bt, const NdbTableImpl* t, const NdbColumnIm
bt.setName(btname);
bt.setLogging(t->getLogging());
bt.setFragmentType(t->getFragmentType());
+ { NdbDictionary::Column bc("PK");
+ bc.setType(NdbDictionary::Column::Unsigned);
+ assert(t->m_sizeOfKeysInWords != 0);
+ bc.setLength(t->m_sizeOfKeysInWords);
+ bc.setPrimaryKey(true);
+ bc.setDistributionKey(true);
+ bt.addColumn(bc);
+ }
{ NdbDictionary::Column bc("DIST");
bc.setType(NdbDictionary::Column::Unsigned);
bc.setPrimaryKey(true);
@@ -108,13 +116,6 @@ NdbBlob::getBlobTable(NdbTableImpl& bt, const NdbTableImpl* t, const NdbColumnIm
bc.setPrimaryKey(true);
bt.addColumn(bc);
}
- { NdbDictionary::Column bc("PK");
- bc.setType(NdbDictionary::Column::Unsigned);
- assert(t->m_sizeOfKeysInWords != 0);
- bc.setLength(t->m_sizeOfKeysInWords);
- bc.setPrimaryKey(true);
- bt.addColumn(bc);
- }
{ NdbDictionary::Column bc("DATA");
switch (c->m_type) {
case NdbDictionary::Column::Blob:
@@ -392,9 +393,9 @@ NdbBlob::setPartKeyValue(NdbOperation* anOp, Uint32 part)
Uint32* data = (Uint32*)theKeyBuf.data;
unsigned size = theTable->m_sizeOfKeysInWords;
DBG("setPartKeyValue dist=" << getDistKey(part) << " part=" << part << " key=" << ndb_blob_debug(data, size));
- if (anOp->equal((Uint32)0, getDistKey(part)) == -1 ||
- anOp->equal((Uint32)1, part) == -1 ||
- anOp->equal((Uint32)2, theKeyBuf.data) == -1) {
+ if (anOp->equal((Uint32)0, theKeyBuf.data) == -1 ||
+ anOp->equal((Uint32)1, getDistKey(part)) == -1 ||
+ anOp->equal((Uint32)2, part) == -1) {
setErrorCode(anOp);
return -1;
}
@@ -676,7 +677,6 @@ NdbBlob::readDataPrivate(char* buf, Uint32& bytes)
if (readParts(thePartBuf.data, part, 1) == -1)
return -1;
// need result now
- DBG("execute pending part reads");
if (executePendingBlobReads() == -1)
return -1;
Uint32 n = thePartSize - off;
@@ -710,7 +710,6 @@ NdbBlob::readDataPrivate(char* buf, Uint32& bytes)
if (readParts(thePartBuf.data, part, 1) == -1)
return -1;
// need result now
- DBG("execute pending part reads");
if (executePendingBlobReads() == -1)
return -1;
memcpy(buf, thePartBuf.data, len);
@@ -773,14 +772,12 @@ NdbBlob::writeDataPrivate(const char* buf, Uint32 bytes)
if (off != 0) {
DBG("partial first block pos=" << pos << " len=" << len);
// flush writes to guarantee correct read
- DBG("execute pending part writes");
if (executePendingBlobWrites() == -1)
return -1;
Uint32 part = (pos - theInlineSize) / thePartSize;
if (readParts(thePartBuf.data, part, 1) == -1)
return -1;
// need result now
- DBG("execute pending part reads");
if (executePendingBlobReads() == -1)
return -1;
Uint32 n = thePartSize - off;
@@ -824,13 +821,11 @@ NdbBlob::writeDataPrivate(const char* buf, Uint32 bytes)
Uint32 part = (pos - theInlineSize) / thePartSize;
if (theLength > pos + len) {
// flush writes to guarantee correct read
- DBG("execute pending part writes");
if (executePendingBlobWrites() == -1)
return -1;
if (readParts(thePartBuf.data, part, 1) == -1)
return -1;
// need result now
- DBG("execute pending part reads");
if (executePendingBlobReads() == -1)
return -1;
memcpy(thePartBuf.data, buf, len);
@@ -980,9 +975,11 @@ NdbBlob::deletePartsUnknown(Uint32 part)
}
tOp->m_abortOption = IgnoreError;
n++;
- if (theNdbCon->executeNoBlobs(NoCommit) == -1)
- return -1;
}
+ DBG("deletePartsUnknown: executeNoBlobs [in] bat=" << bat);
+ if (theNdbCon->executeNoBlobs(NoCommit) == -1)
+ return -1;
+ DBG("deletePartsUnknown: executeNoBlobs [out]");
n = 0;
while (n < bat) {
NdbOperation* tOp = tOpList[n];
@@ -1011,8 +1008,10 @@ NdbBlob::executePendingBlobReads()
{
Uint8 flags = (1 << NdbOperation::ReadRequest);
if (thePendingBlobOps & flags) {
+ DBG("executePendingBlobReads: executeNoBlobs [in]");
if (theNdbCon->executeNoBlobs(NoCommit) == -1)
return -1;
+ DBG("executePendingBlobReads: executeNoBlobs [out]");
thePendingBlobOps = 0;
theNdbCon->thePendingBlobOps = 0;
}
@@ -1024,8 +1023,10 @@ NdbBlob::executePendingBlobWrites()
{
Uint8 flags = 0xFF & ~(1 << NdbOperation::ReadRequest);
if (thePendingBlobOps & flags) {
+ DBG("executePendingBlobWrites: executeNoBlobs [in]");
if (theNdbCon->executeNoBlobs(NoCommit) == -1)
return -1;
+ DBG("executePendingBlobWrites: executeNoBlobs [out]");
thePendingBlobOps = 0;
theNdbCon->thePendingBlobOps = 0;
}
@@ -1037,10 +1038,10 @@ NdbBlob::executePendingBlobWrites()
int
NdbBlob::invokeActiveHook()
{
- DBG("invokeActiveHook");
+ DBG("invokeActiveHook [in]");
assert(theState == Active && theActiveHook != NULL);
int ret = (*theActiveHook)(this, theActiveHookArg);
- DBG("invokeActiveHook ret=" << ret);
+ DBG("invokeActiveHook [out] ret=" << ret);
if (ret != 0) {
// no error is set on blob level
return -1;
@@ -1244,7 +1245,7 @@ NdbBlob::preExecute(ExecType anExecType, bool& batch)
return -1;
}
} else {
- NdbOperation* tOp = theNdbCon->getNdbIndexOperation(theAccessTable->m_index, theTable, theNdbOp);
+ NdbIndexOperation* tOp = theNdbCon->getNdbIndexOperation(theAccessTable->m_index, theTable, theNdbOp);
if (tOp == NULL ||
tOp->readTuple() == -1 ||
setAccessKeyValue(tOp) == -1 ||
diff --git a/ndb/test/ndbapi/testBlobs.cpp b/ndb/test/ndbapi/testBlobs.cpp
index f7ee7921229..08bf8a2fd4b 100644
--- a/ndb/test/ndbapi/testBlobs.cpp
+++ b/ndb/test/ndbapi/testBlobs.cpp
@@ -1232,6 +1232,13 @@ deleteScan(bool idx)
// main
+// from here on print always
+#undef DBG
+#define DBG(x) \
+ do { \
+ ndbout << "line " << __LINE__ << " " << x << endl; \
+ } while (0)
+
static int
testmain()
{
From 41e39c7be32fa27484375762296f900cc21eec17 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Mon, 1 Nov 2004 13:55:43 +0000
Subject: [PATCH 31/59] aligned ndb versioning with mysql changed
define SNPRINTF_RETURN_ZERO to SNPRINTF_RETURN_TRUNC added define
NDB_INIT removed getarg, strlcat, strlcpy aligned ndb version with
mysql version cpcd: removed old way of reading config file and replaced
with mysql load_defaults changed from using getarg to my_getopts use
mysql my_progname moved getarg to test
---
configure.in | 11 +-
ndb/include/ndb_global.h | 9 +-
ndb/include/util/ndb_opts.h | 57 ++++++
ndb/src/common/editline/sysunix.c | 9 +-
ndb/src/common/util/Makefile.am | 4 +-
ndb/src/common/util/basestring_vsnprintf.c | 9 +-
ndb/src/common/util/socket_io.cpp | 39 ++--
ndb/src/common/util/strlcat.c | 48 -----
ndb/src/common/util/strlcpy.c | 57 ------
ndb/src/common/util/version.c | 1 +
ndb/src/cw/cpcd/common.cpp | 63 -------
ndb/src/cw/cpcd/common.hpp | 3 +-
ndb/src/cw/cpcd/main.cpp | 75 ++++----
ndb/src/kernel/blocks/backup/restore/main.cpp | 178 ++++++++++--------
ndb/src/kernel/error/ErrorReporter.cpp | 2 +-
ndb/src/kernel/main.cpp | 8 +-
ndb/src/kernel/vm/Configuration.cpp | 140 +++++++-------
ndb/src/kernel/vm/Configuration.hpp | 2 +-
ndb/src/mgmclient/main.cpp | 77 +++++---
ndb/src/mgmsrv/main.cpp | 114 ++++++-----
ndb/src/ndbapi/Ndb.cpp | 7 +-
ndb/{include/util => test/include}/getarg.h | 0
ndb/test/run-test/Makefile.am | 2 +-
ndb/test/src/Makefile.am | 2 +-
ndb/{src/common/util => test/src}/getarg.c | 32 +++-
ndb/tools/delete_all.cpp | 73 ++++---
ndb/tools/desc.cpp | 82 +++++---
ndb/tools/drop_index.cpp | 70 ++++---
ndb/tools/drop_tab.cpp | 78 +++++---
ndb/tools/listTables.cpp | 106 ++++++-----
ndb/tools/select_all.cpp | 122 +++++++-----
ndb/tools/select_count.cpp | 82 +++++---
ndb/tools/waiter.cpp | 79 +++++---
33 files changed, 918 insertions(+), 723 deletions(-)
create mode 100644 ndb/include/util/ndb_opts.h
delete mode 100644 ndb/src/common/util/strlcat.c
delete mode 100644 ndb/src/common/util/strlcpy.c
rename ndb/{include/util => test/include}/getarg.h (100%)
rename ndb/{src/common/util => test/src}/getarg.c (97%)
diff --git a/configure.in b/configure.in
index 353e455dbac..fe487b15557 100644
--- a/configure.in
+++ b/configure.in
@@ -4,6 +4,7 @@ dnl Process this file with autoconf to produce a configure script.
AC_INIT(sql/mysqld.cc)
AC_CANONICAL_SYSTEM
# The Docs Makefile.am parses this line!
+# remember to also change ndb version below and update version.c in ndb
AM_INIT_AUTOMAKE(mysql, 4.1.8)
AM_CONFIG_HEADER(config.h)
@@ -13,9 +14,9 @@ DOT_FRM_VERSION=6
SHARED_LIB_VERSION=14:0:0
# ndb version
-NDB_VERSION_MAJOR=3
-NDB_VERSION_MINOR=5
-NDB_VERSION_BUILD=4
+NDB_VERSION_MAJOR=4
+NDB_VERSION_MINOR=1
+NDB_VERSION_BUILD=8
NDB_VERSION_STATUS=""
# Set all version vars based on $VERSION. How do we do this more elegant ?
@@ -1142,8 +1143,8 @@ dnl Is this the right match for DEC OSF on alpha?
fi
echo "Adding defines for OSF1"
# gethostbyname_r is deprecated and doesn't work ok on OSF1
- CFLAGS="$CFLAGS -DUNDEF_HAVE_GETHOSTBYNAME_R -DSNPRINTF_RETURN_ZERO"
- CXXFLAGS="$CXXFLAGS -DUNDEF_HAVE_GETHOSTBYNAME_R -DSNPRINTF_RETURN_ZERO"
+ CFLAGS="$CFLAGS -DUNDEF_HAVE_GETHOSTBYNAME_R -DSNPRINTF_RETURN_TRUNC"
+ CXXFLAGS="$CXXFLAGS -DUNDEF_HAVE_GETHOSTBYNAME_R -DSNPRINTF_RETURN_TRUNC"
# fix to handle include of correctly on OSF1 with cxx compiler
CXXFLAGS="$CXXFLAGS -I/usr/include/cxx -I/usr/include/cxx_cname -I/usr/include -I/usr/include.dtk"
;;
diff --git a/ndb/include/ndb_global.h b/ndb/include/ndb_global.h
index 09559f6ddff..bdd4e503cc5 100644
--- a/ndb/include/ndb_global.h
+++ b/ndb/include/ndb_global.h
@@ -82,19 +82,12 @@ extern "C" {
/* call in main() - does not return on error */
extern int ndb_init(void);
extern void ndb_end(int);
+#define NDB_INIT(prog_name) {my_progname=(prog_name); ndb_init();}
#ifndef HAVE_STRDUP
extern char * strdup(const char *s);
#endif
-#ifndef HAVE_STRLCPY
-extern size_t strlcpy (char *dst, const char *src, size_t dst_sz);
-#endif
-
-#ifndef HAVE_STRLCAT
-extern size_t strlcat (char *dst, const char *src, size_t dst_sz);
-#endif
-
#ifndef HAVE_STRCASECMP
extern int strcasecmp(const char *s1, const char *s2);
extern int strncasecmp(const char *s1, const char *s2, size_t n);
diff --git a/ndb/include/util/ndb_opts.h b/ndb/include/util/ndb_opts.h
new file mode 100644
index 00000000000..6cba9c04449
--- /dev/null
+++ b/ndb/include/util/ndb_opts.h
@@ -0,0 +1,57 @@
+/* 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_OPTS_H
+#define _NDB_OPTS_H
+
+#include
+#include
+#include
+#include
+
+#ifndef DBUG_OFF
+#define NDB_STD_OPTS(prog_name) \
+ { "debug", '#', "Output debug log. Often this is 'd:t:o,filename'.", \
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0 }, \
+ { "usage", '?', "Display this help and exit.", \
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 }, \
+ { "help", '?', "Display this help and exit.", \
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 }, \
+ { "version", 'V', "Output version information and exit.", 0, 0, 0, \
+ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 }, \
+ { "connect-string", 'c', \
+ "Set connect string for connecting to ndb_mgmd. " \
+ "=\"host=[;nodeid=]\". " \
+ "Overides specifying entries in NDB_CONNECTSTRING and config file", \
+ (gptr*) &opt_connect_str, (gptr*) &opt_connect_str, 0, \
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }
+#else
+#define NDB_STD_OPTS(prog_name) \
+ { "usage", '?', "Display this help and exit.", \
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 }, \
+ { "help", '?', "Display this help and exit.", \
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 }, \
+ { "version", 'V', "Output version information and exit.", 0, 0, 0, \
+ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 }, \
+ { "connect-string", 'c', \
+ "Set connect string for connecting to ndb_mgmd. " \
+ "=\"host=[;nodeid=]\". " \
+ "Overides specifying entries in NDB_CONNECTSTRING and config file", \
+ (gptr*) &opt_connect_str, (gptr*) &opt_connect_str, 0, \
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }
+#endif
+
+#endif /*_NDB_OPTS_H */
diff --git a/ndb/src/common/editline/sysunix.c b/ndb/src/common/editline/sysunix.c
index 000bca78dfc..1339e5769e2 100644
--- a/ndb/src/common/editline/sysunix.c
+++ b/ndb/src/common/editline/sysunix.c
@@ -138,6 +138,11 @@ rl_add_slash(char *path, char *p, size_t p_len)
{
struct stat Sb;
- if (stat(path, &Sb) >= 0)
- (void)strlcat(p, S_ISDIR(Sb.st_mode) ? "/" : " ", p_len);
+ if (stat(path, &Sb) >= 0) {
+ int len= strlen(p);
+ if (len+1 < p_len) {
+ p[len]= S_ISDIR(Sb.st_mode) ? '/' : ' ';
+ p[len+1]= 0;
+ }
+ }
}
diff --git a/ndb/src/common/util/Makefile.am b/ndb/src/common/util/Makefile.am
index 0235adae7c9..61fd7992002 100644
--- a/ndb/src/common/util/Makefile.am
+++ b/ndb/src/common/util/Makefile.am
@@ -7,8 +7,8 @@ libgeneral_la_SOURCES = \
SocketServer.cpp SocketClient.cpp SocketAuthenticator.cpp\
OutputStream.cpp NdbOut.cpp BaseString.cpp Base64.cpp \
NdbSqlUtil.cpp new.cpp \
- uucode.c random.c getarg.c version.c \
- strdup.c strlcat.c strlcpy.c \
+ uucode.c random.c version.c \
+ strdup.c \
ConfigValues.cpp ndb_init.c basestring_vsnprintf.c
include $(top_srcdir)/ndb/config/common.mk.am
diff --git a/ndb/src/common/util/basestring_vsnprintf.c b/ndb/src/common/util/basestring_vsnprintf.c
index 87ffb8ad146..c96d1a300e1 100644
--- a/ndb/src/common/util/basestring_vsnprintf.c
+++ b/ndb/src/common/util/basestring_vsnprintf.c
@@ -34,20 +34,19 @@ basestring_snprintf(char *str, size_t size, const char *format, ...)
#ifdef HAVE_SNPRINTF
#define BASESTRING_VSNPRINTF_FUNC(a,b,c,d) vsnprintf(a,b,c,d)
#else
- #define SNPRINTF_RETURN_ZERO
+ #define SNPRINTF_RETURN_TRUNC
#define BASESTRING_VSNPRINTF_FUNC(a,b,c,d) my_vsnprintf(a,b,c,d)
extern int my_vsnprintf(char *str, size_t size, const char *format, va_list ap);
#endif
-
-#ifdef SNPRINTF_RETURN_ZERO
+#ifdef SNPRINTF_RETURN_TRUNC
static char basestring_vsnprintf_buf[16*1024];
#endif
int
basestring_vsnprintf(char *str, size_t size, const char *format, va_list ap)
{
int ret= BASESTRING_VSNPRINTF_FUNC(str, size, format, ap);
-#ifdef SNPRINTF_RETURN_ZERO
- if (ret == 0 && format != 0 && format[0] != '\0') {
+#ifdef SNPRINTF_RETURN_TRUNC
+ if (ret == size-1) {
ret= BASESTRING_VSNPRINTF_FUNC(basestring_vsnprintf_buf,
sizeof(basestring_vsnprintf_buf),
format, ap);
diff --git a/ndb/src/common/util/socket_io.cpp b/ndb/src/common/util/socket_io.cpp
index 6f4c7e63684..83a546de773 100644
--- a/ndb/src/common/util/socket_io.cpp
+++ b/ndb/src/common/util/socket_io.cpp
@@ -172,22 +172,21 @@ vprint_socket(NDB_SOCKET_TYPE socket, int timeout_millis,
const char * fmt, va_list ap){
char buf[1000];
char *buf2 = buf;
- size_t size = sizeof(buf);
+ size_t size;
- if (fmt != 0) {
+ if (fmt != 0 && fmt[0] != 0) {
size = BaseString::vsnprintf(buf, sizeof(buf), fmt, ap);
/* Check if the output was truncated */
- if(size >= sizeof(buf)) {
- buf2 = (char *)malloc(size+1);
+ if(size > sizeof(buf)) {
+ buf2 = (char *)malloc(size);
if(buf2 == NULL)
return -1;
BaseString::vsnprintf(buf2, size, fmt, ap);
- } else
- size = sizeof(buf);
+ }
} else
- buf[0] = 0;
+ return 0;
- int ret = write_socket(socket, timeout_millis, buf2, strlen(buf2));
+ int ret = write_socket(socket, timeout_millis, buf2, size);
if(buf2 != buf)
free(buf2);
return ret;
@@ -199,23 +198,23 @@ vprintln_socket(NDB_SOCKET_TYPE socket, int timeout_millis,
const char * fmt, va_list ap){
char buf[1000];
char *buf2 = buf;
- size_t size = sizeof(buf);
+ size_t size;
- if (fmt != 0) {
- size = BaseString::vsnprintf(buf, sizeof(buf), fmt, ap);
+ if (fmt != 0 && fmt[0] != 0) {
+ size = BaseString::vsnprintf(buf, sizeof(buf), fmt, ap)+1;// extra byte for '/n'
/* Check if the output was truncated */
- if(size >= sizeof(buf)-1) {
- buf2 = (char *)malloc(size+2);
+ if(size > sizeof(buf)) {
+ buf2 = (char *)malloc(size);
if(buf2 == NULL)
return -1;
- BaseString::vsnprintf(buf2, size+1, fmt, ap);
- } else
- size = sizeof(buf);
- } else
- buf[0] = 0;
- strlcat(buf2, "\n", size+2);
+ BaseString::vsnprintf(buf2, size, fmt, ap);
+ }
+ } else {
+ size = 1;
+ }
+ buf2[size-1]='\n';
- int ret = write_socket(socket, timeout_millis, buf2, strlen(buf2));
+ int ret = write_socket(socket, timeout_millis, buf2, size);
if(buf2 != buf)
free(buf2);
return ret;
diff --git a/ndb/src/common/util/strlcat.c b/ndb/src/common/util/strlcat.c
deleted file mode 100644
index aa282abe48d..00000000000
--- a/ndb/src/common/util/strlcat.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 1995 - 1999 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * 3. Neither the name of the Institute nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include
-
-/* RCSID("$KTH: strlcat.c,v 1.1 2000/08/16 01:23:47 lha Exp $"); */
-
-
-#ifndef HAVE_STRLCAT
-
-size_t
-strlcat (char *dst, const char *src, size_t dst_sz)
-{
- size_t len = strlen(dst);
-
- return len + strlcpy (dst + len, src, dst_sz - len);
-}
-#endif
diff --git a/ndb/src/common/util/strlcpy.c b/ndb/src/common/util/strlcpy.c
deleted file mode 100644
index 97cff177d48..00000000000
--- a/ndb/src/common/util/strlcpy.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 1995 - 1999 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * 3. Neither the name of the Institute nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include
-
-/* RCSID("$KTH: strlcpy.c,v 1.1 2000/08/16 01:23:48 lha Exp $"); */
-
-#ifndef HAVE_STRLCPY
-
-size_t
-strlcpy (char *dst, const char *src, size_t dst_sz)
-{
- size_t n;
- char *p;
-
- for (p = dst, n = 0;
- n + 1 < dst_sz && *src != '\0';
- ++p, ++src, ++n)
- *p = *src;
- *p = '\0';
- if (*src == '\0')
- return n;
- else
- return n + strlen (src);
-}
-
-#endif
diff --git a/ndb/src/common/util/version.c b/ndb/src/common/util/version.c
index f2b3d5bd522..82acd949c46 100644
--- a/ndb/src/common/util/version.c
+++ b/ndb/src/common/util/version.c
@@ -70,6 +70,7 @@ struct NdbUpGradeCompatible {
#ifndef TEST_VERSION
struct NdbUpGradeCompatible ndbCompatibleTable_full[] = {
{ MAKE_VERSION(3,5,2), MAKE_VERSION(3,5,1), UG_Exact },
+ { MAKE_VERSION(4,1,8), MAKE_VERSION(3,5,4), UG_Exact }, /* Aligned version with MySQL */
{ 0, 0, UG_Null }
};
diff --git a/ndb/src/cw/cpcd/common.cpp b/ndb/src/cw/cpcd/common.cpp
index cb1c0c37183..53c0e4d5a64 100644
--- a/ndb/src/cw/cpcd/common.cpp
+++ b/ndb/src/cw/cpcd/common.cpp
@@ -96,66 +96,3 @@ insert_file(const char * filename, class Properties& p){
if(f) fclose(f);
return res;
}
-
-int
-parse_config_file(struct getargs args[], int num_arg, const Properties& p){
- Properties::Iterator it(&p);
- for(const char * name = it.first(); name != 0; name = it.next()){
- bool found = false;
- for(int i = 0; i
#include
+#if 0
#include
+#endif
extern int debug;
@@ -30,6 +32,5 @@ int insert(const char * pair, class Properties & p);
int insert_file(const char * filename, class Properties&);
int insert_file(FILE *, class Properties&, bool break_on_empty = false);
-int parse_config_file(struct getargs args[], int num_arg, const Properties& p);
#endif /* ! __CPCD_COMMON_HPP_INCLUDED__ */
diff --git a/ndb/src/cw/cpcd/main.cpp b/ndb/src/cw/cpcd/main.cpp
index 207b81bfa89..300b51d7b5a 100644
--- a/ndb/src/cw/cpcd/main.cpp
+++ b/ndb/src/cw/cpcd/main.cpp
@@ -15,13 +15,13 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include /* Needed for mkdir(2) */
+#include
#include "CPCD.hpp"
#include "APIService.hpp"
#include
#include
#include
-#include
#include
#include
#include
@@ -29,28 +29,44 @@
#include "common.hpp"
static const char *work_dir = CPCD_DEFAULT_WORK_DIR;
-static int port = CPCD_DEFAULT_TCP_PORT;
-static int use_syslog = 0;
+static int port;
+static int use_syslog;
static const char *logfile = NULL;
static const char *config_file = CPCD_DEFAULT_CONFIG_FILE;
static const char *user = 0;
-static struct getargs args[] = {
- { "work-dir", 'w', arg_string, &work_dir,
- "Work directory", "directory" },
- { "port", 'p', arg_integer, &port,
- "TCP port to listen on", "port" },
- { "syslog", 'S', arg_flag, &use_syslog,
- "Log events to syslog", NULL},
- { "logfile", 'L', arg_string, &logfile,
- "File to log events to", "file"},
- { "debug", 'D', arg_flag, &debug,
- "Enable debug mode", NULL},
- { "config", 'c', arg_string, &config_file, "Config file", NULL },
- { "user", 'u', arg_string, &user, "Run as user", NULL }
+static struct my_option my_long_options[] =
+{
+ { "work-dir", 'w', "Work directory",
+ (gptr*) &work_dir, (gptr*) &work_dir, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+ { "port", 'p', "TCP port to listen on",
+ (gptr*) &port, (gptr*) &port, 0,
+ GET_INT, REQUIRED_ARG, CPCD_DEFAULT_TCP_PORT, 0, 0, 0, 0, 0 },
+ { "syslog", 'S', "Log events to syslog",
+ (gptr*) &use_syslog, (gptr*) &use_syslog, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
+ { "logfile", 'L', "File to log events to",
+ (gptr*) &logfile, (gptr*) &logfile, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+ { "debug", 'D', "Enable debug mode",
+ (gptr*) &debug, (gptr*) &debug, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
+ { "config", 'c', "Config file",
+ (gptr*) &config_file, (gptr*) &config_file, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+ { "user", 'u', "Run as user",
+ (gptr*) &user, (gptr*) &user, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
-static const int num_args = sizeof(args) / sizeof(args[0]);
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ return 0;
+}
static CPCD * g_cpcd = 0;
#if 0
@@ -59,23 +75,16 @@ extern "C" static void sig_child(int signo, siginfo_t*, void*);
const char *progname = "ndb_cpcd";
-NDB_MAIN(ndb_cpcd){
- int optind = 0;
+int main(int argc, char** argv){
+ int save_argc= argc;
+ char** save_argv= argv;
+ const char *load_default_groups[]= { "ndb_cpcd",0 };
+ MY_INIT(argv[0]);
- if(getarg(args, num_args, argc, argv, &optind)) {
- arg_printusage(args, num_args, progname, "");
- exit(1);
- }
-
- Properties p;
- insert_file(config_file, p);
- if(parse_config_file(args, num_args, p)){
- ndbout_c("Invalid config file: %s", config_file);
- exit(1);
- }
-
- if(getarg(args, num_args, argc, argv, &optind)) {
- arg_printusage(args, num_args, progname, "");
+ load_defaults("ndb_cpcd",load_default_groups,&argc,&argv);
+ if (handle_options(&argc, &argv, my_long_options, get_one_option)) {
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
exit(1);
}
diff --git a/ndb/src/kernel/blocks/backup/restore/main.cpp b/ndb/src/kernel/blocks/backup/restore/main.cpp
index f7b1479cc93..482212911cb 100644
--- a/ndb/src/kernel/blocks/backup/restore/main.cpp
+++ b/ndb/src/kernel/blocks/backup/restore/main.cpp
@@ -14,7 +14,8 @@
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
@@ -35,80 +36,107 @@ static Vector g_consumers;
static const char* ga_backupPath = "." DIR_SEPARATOR;
-static const char* ga_connect_NDB = NULL;
+static const char* opt_connect_str= NULL;
/**
* print and restore flags
*/
static bool ga_restore = false;
static bool ga_print = false;
-bool
-readArguments(const int argc, const char** argv)
+static int _print = 0;
+static int _print_meta = 0;
+static int _print_data = 0;
+static int _print_log = 0;
+static int _restore_data = 0;
+static int _restore_meta = 0;
+
+static struct my_option my_long_options[] =
{
+ NDB_STD_OPTS("ndb_restore"),
+ { "connect", 'c', "same as --connect-string",
+ (gptr*) &opt_connect_str, (gptr*) &opt_connect_str, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+ { "nodeid", 'n', "Backup files from node with id",
+ (gptr*) &ga_nodeId, (gptr*) &ga_nodeId, 0,
+ GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+ { "backupid", 'b', "Backup id",
+ (gptr*) &ga_backupId, (gptr*) &ga_backupId, 0,
+ GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+ { "restore_data", 'r',
+ "Restore table data/logs into NDB Cluster using NDBAPI",
+ (gptr*) &_restore_data, (gptr*) &_restore_data, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
+ { "restore_meta", 'm',
+ "Restore meta data into NDB Cluster using NDBAPI",
+ (gptr*) &_restore_meta, (gptr*) &_restore_meta, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
+ { "parallelism", 'p',
+ "No of parallel transactions during restore of data."
+ "(parallelism can be 1 to 1024)",
+ (gptr*) &ga_nParallelism, (gptr*) &ga_nParallelism, 0,
+ GET_INT, REQUIRED_ARG, 128, 0, 0, 0, 0, 0 },
+ { "print", 256, "Print data and log to stdout",
+ (gptr*) &_print, (gptr*) &_print, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
+ { "print_data", 257, "Print data to stdout",
+ (gptr*) &_print_data, (gptr*) &_print_data, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
+ { "print_meta", 258, "Print meta data to stdout",
+ (gptr*) &_print_meta, (gptr*) &_print_meta, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
+ { "print_log", 259, "Print log to stdout",
+ (gptr*) &_print_log, (gptr*) &_print_log, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
+ { "dont_ignore_systab_0", 'f',
+ "Experimental. Do not ignore system table during restore.",
+ (gptr*) &ga_dont_ignore_systab_0, (gptr*) &ga_dont_ignore_systab_0, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
- int _print = 0;
- int _print_meta = 0;
- int _print_data = 0;
- int _print_log = 0;
- int _restore_data = 0;
- int _restore_meta = 0;
-
-
- struct getargs args[] =
- {
- { "connect", 'c', arg_string, &ga_connect_NDB,
- "NDB Cluster connection", "\"nodeid=;host=\""},
- { "nodeid", 'n', arg_integer, &ga_nodeId,
- "Backup files from node", "db node id"},
- { "backupid", 'b',arg_integer, &ga_backupId, "Backup id", "backup id"},
- { "print", '\0', arg_flag, &_print,
- "Print data and log to stdout", "print data and log"},
- { "print_data", '\0', arg_flag, &_print_data,
- "Print data to stdout", "print data"},
- { "print_meta", '\0', arg_flag, &_print_meta,
- "Print meta data to stdout", "print meta data"},
- { "print_log", '\0', arg_flag, &_print_log,
- "Print log to stdout", "print log"},
- { "restore_data", 'r', arg_flag, &_restore_data,
- "Restore table data/logs into NDB Cluster using NDBAPI",
- "Restore table data/log"},
- { "restore_meta", 'm', arg_flag, &_restore_meta,
- "Restore meta data into NDB Cluster using NDBAPI", "Restore meta data"},
- { "parallelism", 'p', arg_integer, &ga_nParallelism,
- "No of parallel transactions during restore of data."
- "(parallelism can be 1 to 1024)",
- "Parallelism"},
-#ifdef USE_MYSQL
- { "use_mysql", '\0', arg_flag, &use_mysql,
- "Restore meta data via mysql. Systab will be ignored. Data is restored "
- "using NDBAPI.", "use mysql"},
- { "user", '\0', arg_string, &ga_user, "MySQL user", "Default: root"},
- { "password", '\0', arg_string, &ga_password, "MySQL user's password",
- "Default: \"\" "},
- { "host", '\0', arg_string, &ga_host, "Hostname of MySQL server",
- "Default: localhost"},
- { "socket", '\0', arg_string, &ga_socket, "Path to MySQL server socket file",
- "Default: /tmp/mysql.sock"},
- { "port", '\0', arg_integer, &ga_port, "Port number of MySQL server",
- "Default: 3306"},
-#endif
- { "dont_ignore_systab_0", 'f', arg_flag, &ga_dont_ignore_systab_0,
- "Experimental. Do not ignore system table during restore.",
- "dont_ignore_systab_0"}
-
- };
-
- int num_args = sizeof(args) / sizeof(args[0]);
- int optind = 0;
-
- if (getarg(args, num_args, argc, argv, &optind) ||
+static void short_usage_sub(void)
+{
+ printf("Usage: %s [OPTIONS] []\n", my_progname);
+}
+static void print_version()
+{
+ printf("MySQL distrib %s, for %s (%s)\n",MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
+}
+static void usage()
+{
+ short_usage_sub();
+ print_version();
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
+}
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ switch (optid) {
+ case '#':
+ DBUG_PUSH(argument ? argument : "d:t:O,/tmp/ndb_restore.trace");
+ break;
+ case 'V':
+ print_version();
+ exit(0);
+ case '?':
+ usage();
+ exit(0);
+ }
+ return 0;
+}
+bool
+readArguments(int *pargc, char*** pargv)
+{
+ const char *load_default_groups[]= { "ndb_tools","ndb_restore",0 };
+ load_defaults("my",load_default_groups,pargc,pargv);
+ if (handle_options(pargc, pargv, my_long_options, get_one_option) ||
ga_nodeId == 0 ||
ga_backupId == 0 ||
ga_nParallelism < 1 ||
- ga_nParallelism >1024)
- {
- arg_printusage(args, num_args, argv[0], "\n");
- return false;
+ ga_nParallelism >1024) {
+ exit(1);
}
BackupPrinter* printer = new BackupPrinter();
@@ -122,10 +150,6 @@ readArguments(const int argc, const char** argv)
return false;
}
- /**
- * Got segmentation fault when using the printer's attributes directly
- * in getargs... Do not have the time to found out why... this is faster...
- */
if (_print)
{
ga_print = true;
@@ -169,15 +193,14 @@ readArguments(const int argc, const char** argv)
g_consumers.push_back(c);
}
// Set backup file path
- if (argv[optind] != NULL)
+ if (*pargv[0] != NULL)
{
- ga_backupPath = argv[optind];
+ ga_backupPath = *pargv[0];
}
return true;
}
-
void
clearConsumers()
{
@@ -204,19 +227,16 @@ free_data_callback()
}
int
-main(int argc, const char** argv)
+main(int argc, char** argv)
{
- ndb_init();
- if (!readArguments(argc, argv))
+ NDB_INIT(argv[0]);
+
+ if (!readArguments(&argc, &argv))
{
return -1;
}
- if (ga_connect_NDB != NULL)
- {
- // Use connection string
- Ndb::setConnectString(ga_connect_NDB);
- }
+ Ndb::setConnectString(opt_connect_str);
/**
* we must always load meta data, even if we will only print it to stdout
diff --git a/ndb/src/kernel/error/ErrorReporter.cpp b/ndb/src/kernel/error/ErrorReporter.cpp
index 35c99b30994..35cd3f099d9 100644
--- a/ndb/src/kernel/error/ErrorReporter.cpp
+++ b/ndb/src/kernel/error/ErrorReporter.cpp
@@ -137,7 +137,7 @@ ErrorReporter::formatMessage(ErrorCategory type,
faultID,
(problemData == NULL) ? "" : problemData,
objRef,
- programName,
+ my_progname,
processId,
theNameOfTheTraceFile ? theNameOfTheTraceFile : "");
diff --git a/ndb/src/kernel/main.cpp b/ndb/src/kernel/main.cpp
index fa44704807d..926647838c9 100644
--- a/ndb/src/kernel/main.cpp
+++ b/ndb/src/kernel/main.cpp
@@ -53,11 +53,9 @@ extern "C" void handler_error(int signum); // for process signal handling
void systemInfo(const Configuration & conf,
const LogLevel & ll);
-const char programName[] = "NDB Kernel";
-
-NDB_MAIN(ndb_kernel){
-
- ndb_init();
+int main(int argc, char** argv)
+{
+ NDB_INIT(argv[0]);
// Print to stdout/console
g_eventLogger.createConsoleHandler();
g_eventLogger.setCategory("NDB");
diff --git a/ndb/src/kernel/vm/Configuration.cpp b/ndb/src/kernel/vm/Configuration.cpp
index 706f60fd9cf..b3a436275f7 100644
--- a/ndb/src/kernel/vm/Configuration.cpp
+++ b/ndb/src/kernel/vm/Configuration.cpp
@@ -15,6 +15,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include
+#include
#include
#include "Configuration.hpp"
@@ -28,8 +29,6 @@
#include
#include
-#include
-
#include
#include
#include
@@ -47,81 +46,86 @@ extern "C" {
#include
extern EventLogger g_eventLogger;
-bool
-Configuration::init(int argc, const char** argv){
-
- /**
- * Default values for arguments
- */
- int _no_start = 0;
- int _initial = 0;
- const char* _connect_str = NULL;
- int _daemon = 1;
- int _no_daemon = 0;
- int _help = 0;
- int _print_version = 0;
-#ifndef DBUG_OFF
- const char *debug_option= 0;
-#endif
-
- /**
- * Arguments to NDB process
- */
-
- struct getargs args[] = {
- { "version", 'v', arg_flag, &_print_version, "Print ndbd version", "" },
- { "nostart", 'n', arg_flag, &_no_start,
- "Don't start ndbd immediately. Ndbd will await command from ndb_mgmd", "" },
- { "daemon", 'd', arg_flag, &_daemon, "Start ndbd as daemon (default)", "" },
- { "nodaemon", 0, arg_flag, &_no_daemon, "Do not start ndbd as daemon, provided for testing purposes", "" },
-#ifndef DBUG_OFF
- { "debug", 0, arg_string, &debug_option,
- "Specify debug options e.g. d:t:i:o,out.trace", "options" },
-#endif
- { "initial", 0, arg_flag, &_initial,
- "Perform initial start of ndbd, including cleaning the file system. Consult documentation before using this", "" },
-
- { "connect-string", 'c', arg_string, &_connect_str,
- "Set connect string for connecting to ndb_mgmd. =\"host=[;nodeid=]\". Overides specifying entries in NDB_CONNECTSTRING and config file",
- "" },
- { "usage", '?', arg_flag, &_help, "Print help", "" }
- };
- int num_args = sizeof(args) / sizeof(args[0]);
- int optind = 0;
- char desc[] =
- "The MySQL Cluster kernel";
-
- if(getarg(args, num_args, argc, argv, &optind) || _help) {
- arg_printusage(args, num_args, argv[0], desc);
- for (int i = 0; i < argc; i++) {
- if (strcmp("-i",argv[i]) == 0) {
- printf("flag depricated %s, use %s\n", "-i", "--initial");
- }
- }
- return false;
+static const char* opt_connect_str= 0;
+static int _daemon, _no_daemon, _initial, _no_start;
+/**
+ * Arguments to NDB process
+ */
+static struct my_option my_long_options[] =
+{
+ NDB_STD_OPTS("ndbd"),
+ { "initial", 256,
+ "Perform initial start of ndbd, including cleaning the file system. "
+ "Consult documentation before using this",
+ (gptr*) &_initial, (gptr*) &_initial, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
+ { "nostart", 'n',
+ "Don't start ndbd immediately. Ndbd will await command from ndb_mgmd",
+ (gptr*) &_no_start, (gptr*) &_no_start, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
+ { "daemon", 'd', "Start ndbd as daemon (default)",
+ (gptr*) &_daemon, (gptr*) &_daemon, 0,
+ GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0 },
+ { "nodaemon", 257,
+ "Do not start ndbd as daemon, provided for testing purposes",
+ (gptr*) &_no_daemon, (gptr*) &_no_daemon, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
+static void short_usage_sub(void)
+{
+ printf("Usage: %s [OPTIONS]\n", my_progname);
+}
+static void print_version()
+{
+ printf("MySQL distrib %s, for %s (%s)\n",MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
+}
+static void usage()
+{
+ short_usage_sub();
+ print_version();
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
+}
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ switch (optid) {
+ case '#':
+ DBUG_PUSH(argument ? argument : "d:t:O,/tmp/ndbd.trace");
+ break;
+ case 'V':
+ print_version();
+ exit(0);
+ case '?':
+ usage();
+ exit(0);
}
+ return 0;
+}
+
+bool
+Configuration::init(int argc, char** argv)
+{
+ const char *load_default_groups[]= { "ndbd",0 };
+ load_defaults("my",load_default_groups,&argc,&argv);
+
+ int ho_error;
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
if (_no_daemon) {
_daemon= 0;
}
- // check for depricated flag '-i'
-
-#ifndef DBUG_OFF
- if (debug_option)
- DBUG_PUSH(debug_option);
-#endif
DBUG_PRINT("info", ("no_start=%d", _no_start));
DBUG_PRINT("info", ("initial=%d", _initial));
DBUG_PRINT("info", ("daemon=%d", _daemon));
- DBUG_PRINT("info", ("connect_str=%s", _connect_str));
+ DBUG_PRINT("info", ("connect_str=%s", opt_connect_str));
ndbSetOwnVersion();
- if (_print_version) {
- ndbPrintVersion();
- return false;
- }
-
// Check the start flag
if (_no_start)
globalData.theRestartFlag = initial_state;
@@ -133,8 +137,8 @@ Configuration::init(int argc, const char** argv){
_initialStart = true;
// Check connectstring
- if (_connect_str)
- _connectString = strdup(_connect_str);
+ if (opt_connect_str)
+ _connectString = strdup(opt_connect_str);
// Check daemon flag
if (_daemon)
diff --git a/ndb/src/kernel/vm/Configuration.hpp b/ndb/src/kernel/vm/Configuration.hpp
index 2ea32ffea37..e4cd64f5ca8 100644
--- a/ndb/src/kernel/vm/Configuration.hpp
+++ b/ndb/src/kernel/vm/Configuration.hpp
@@ -31,7 +31,7 @@ public:
/**
* Returns false if arguments are invalid
*/
- bool init(int argc, const char** argv);
+ bool init(int argc, char** argv);
void fetch_configuration(LocalConfig &local_config);
void setupConfiguration();
diff --git a/ndb/src/mgmclient/main.cpp b/ndb/src/mgmclient/main.cpp
index cc6d4bf600e..a37214d366b 100644
--- a/ndb/src/mgmclient/main.cpp
+++ b/ndb/src/mgmclient/main.cpp
@@ -15,11 +15,12 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include
+#include
#include
#include
-#include
#include
+#include
#include
#include "CommandInterpreter.hpp"
@@ -43,28 +44,62 @@ handler(int sig){
}
}
-int main(int argc, const char** argv){
- ndb_init();
- int optind = 0;
+
+static unsigned _try_reconnect;
+static char *opt_connect_str= 0;
+
+static struct my_option my_long_options[] =
+{
+ NDB_STD_OPTS("ndb_mgm"),
+ { "try-reconnect", 't',
+ "Specify number of retries for connecting to ndb_mgmd, default infinite",
+ (gptr*) &_try_reconnect, (gptr*) &_try_reconnect, 0,
+ GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
+static void short_usage_sub(void)
+{
+ printf("Usage: %s [OPTIONS] [hostname [port]]\n", my_progname);
+}
+static void print_version()
+{
+ printf("MySQL distrib %s, for %s (%s)\n",MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
+}
+static void usage()
+{
+ short_usage_sub();
+ print_version();
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
+}
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ switch (optid) {
+ case '#':
+ DBUG_PUSH(argument ? argument : "d:t:O,/tmp/ndb_mgm.trace");
+ break;
+ case 'V':
+ print_version();
+ exit(0);
+ case '?':
+ usage();
+ exit(0);
+ }
+ return 0;
+}
+
+int main(int argc, char** argv){
+ NDB_INIT(argv[0]);
const char *_host = 0;
int _port = 0;
- int _help = 0;
- int _try_reconnect = 0;
-
- struct getargs args[] = {
- { "try-reconnect", 't', arg_integer, &_try_reconnect, "Specify number of retries for connecting to ndb_mgmd, default infinite", "#" },
- { "usage", '?', arg_flag, &_help, "Print help", "" },
- };
- int num_args = sizeof(args) / sizeof(args[0]); /* Number of arguments */
-
-
- if(getarg(args, num_args, argc, argv, &optind) || _help) {
- arg_printusage(args, num_args, progname, "[host [port]]");
- exit(1);
- }
+ const char *load_default_groups[]= { "ndb_mgm",0 };
- argv += optind;
- argc -= optind;
+ load_defaults("my",load_default_groups,&argc,&argv);
+ int ho_error;
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ exit(ho_error);
LocalConfig cfg;
@@ -74,7 +109,7 @@ int main(int argc, const char** argv){
_port = atoi(argv[1]);
}
} else {
- if(cfg.init(0, 0) && cfg.ids.size() > 0 && cfg.ids[0].type == MgmId_TCP){
+ if(cfg.init(opt_connect_str, 0) && cfg.ids.size() > 0 && cfg.ids[0].type == MgmId_TCP){
_host = cfg.ids[0].name.c_str();
_port = cfg.ids[0].port;
} else {
diff --git a/ndb/src/mgmsrv/main.cpp b/ndb/src/mgmsrv/main.cpp
index 5ee48e4cfcc..c1876f68ea2 100644
--- a/ndb/src/mgmsrv/main.cpp
+++ b/ndb/src/mgmsrv/main.cpp
@@ -15,6 +15,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include
+#include
#include "MgmtSrvr.hpp"
#include "EventLogger.hpp"
@@ -33,7 +34,6 @@
#include
#include
#include
-#include
#include
@@ -97,41 +97,70 @@ bool g_StopServer;
extern EventLogger g_EventLogger;
extern int global_mgmt_server_check;
-int _print_version = 0;
-#ifndef DBUG_OFF
-const char *debug_option= 0;
-#endif
+static char *opt_connect_str= 0;
-struct getargs args[] = {
- { "version", 'v', arg_flag, &_print_version,
- "Print ndb_mgmd version",""},
- { "config-file", 'c', arg_string, &glob.config_filename,
- "Specify cluster configuration file (default config.ini if available)",
- "filename"},
-#ifndef DBUG_OFF
- { "debug", 0, arg_string, &debug_option,
- "Specify debug options e.g. d:t:i:o,out.trace", "options"},
-#endif
- { "daemon", 'd', arg_flag, &glob.daemon,
- "Run ndb_mgmd in daemon mode (default)",""},
- { NULL, 'l', arg_string, &glob.local_config_filename,
- "Specify configuration file connect string (default Ndb.cfg if available)",
- "filename"},
- { "interactive", 0, arg_flag, &glob.interactive,
- "Run interactive. Not supported but provided for testing purposes", ""},
- { "no-nodeid-checks", 0, arg_flag, &g_no_nodeid_checks,
- "Do not provide any node id checks", ""},
- { "nodaemon", 0, arg_flag, &glob.non_interactive,
- "Don't run as daemon, but don't read from stdin", "non-interactive"}
+static struct my_option my_long_options[] =
+{
+ NDB_STD_OPTS("ndb_mgmd"),
+ { "config-file", 'c', "Specify cluster configuration file",
+ (gptr*) &glob.config_filename, (gptr*) &glob.config_filename, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+ { "daemon", 'd', "Run ndb_mgmd in daemon mode (default)",
+ (gptr*) &glob.daemon, (gptr*) &glob.daemon, 0,
+ GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0 },
+ { "l", 'l', "Specify configuration file connect string (default Ndb.cfg if available)",
+ (gptr*) &glob.local_config_filename, (gptr*) &glob.local_config_filename, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+ { "interactive", 256, "Run interactive. Not supported but provided for testing purposes",
+ (gptr*) &glob.interactive, (gptr*) &glob.interactive, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
+ { "no-nodeid-checks", 257, "Do not provide any node id checks",
+ (gptr*) &g_no_nodeid_checks, (gptr*) &g_no_nodeid_checks, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
+ { "nodaemon", 258, "Don't run as daemon, but don't read from stdin",
+ (gptr*) &glob.non_interactive, (gptr*) &glob.non_interactive, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
-
-int num_args = sizeof(args) / sizeof(args[0]);
+static void short_usage_sub(void)
+{
+ printf("Usage: %s [OPTIONS]\n", my_progname);
+}
+static void print_version()
+{
+ printf("MySQL distrib %s, for %s (%s)\n",MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
+}
+static void usage()
+{
+ short_usage_sub();
+ print_version();
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
+}
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ switch (optid) {
+ case '#':
+ DBUG_PUSH(argument ? argument : "d:t:O,/tmp/ndb_mgmd.trace");
+ break;
+ case 'V':
+ print_version();
+ exit(0);
+ case '?':
+ usage();
+ exit(0);
+ }
+ return 0;
+}
/*
* MAIN
*/
-NDB_MAIN(mgmsrv){
- ndb_init();
+int main(int argc, char** argv)
+{
+ NDB_INIT(argv[0]);
/**
* OSE specific. Enable shared ownership of file system resources.
@@ -143,31 +172,20 @@ NDB_MAIN(mgmsrv){
#endif
global_mgmt_server_check = 1;
+ glob.config_filename= "config.ini";
- int optind = 0;
- if(getarg(args, num_args, argc, argv, &optind)) {
- arg_printusage(args, num_args, progname, "");
- exit(1);
- }
+ const char *load_default_groups[]= { "ndb_mgmd",0 };
+ load_defaults("my",load_default_groups,&argc,&argv);
+
+ int ho_error;
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ exit(ho_error);
if (glob.interactive ||
glob.non_interactive) {
glob.daemon= 0;
}
-#ifndef DBUG_OFF
- if (debug_option)
- DBUG_PUSH(debug_option);
-#endif
-
- if (_print_version) {
- ndbPrintVersion();
- exit(0);
- }
-
- if(glob.config_filename == NULL) {
- glob.config_filename= "config.ini";
- }
glob.socketServer = new SocketServer();
MgmApiService * mapi = new MgmApiService();
diff --git a/ndb/src/ndbapi/Ndb.cpp b/ndb/src/ndbapi/Ndb.cpp
index d7b8a695fe2..75ae539fc8b 100644
--- a/ndb/src/ndbapi/Ndb.cpp
+++ b/ndb/src/ndbapi/Ndb.cpp
@@ -1386,6 +1386,7 @@ Ndb::printState(const char* fmt, ...)
va_end(ap);
NdbMutex_Lock(ndb_print_state_mutex);
bool dups = false;
+ unsigned i;
ndbout << buf << " ndb=" << hex << this << dec;
#ifndef NDB_WIN32
ndbout << " thread=" << (int)pthread_self();
@@ -1406,21 +1407,21 @@ Ndb::printState(const char* fmt, ...)
ndbout << "!! DUPS !!" << endl;
dups = true;
}
- for (unsigned i = 0; i < theNoOfPreparedTransactions; i++)
+ for (i = 0; i < theNoOfPreparedTransactions; i++)
thePreparedTransactionsArray[i]->printState();
ndbout << "sent: " << theNoOfSentTransactions<< endl;
if (checkdups(theSentTransactionsArray, theNoOfSentTransactions)) {
ndbout << "!! DUPS !!" << endl;
dups = true;
}
- for (unsigned i = 0; i < theNoOfSentTransactions; i++)
+ for (i = 0; i < theNoOfSentTransactions; i++)
theSentTransactionsArray[i]->printState();
ndbout << "completed: " << theNoOfCompletedTransactions<< endl;
if (checkdups(theCompletedTransactionsArray, theNoOfCompletedTransactions)) {
ndbout << "!! DUPS !!" << endl;
dups = true;
}
- for (unsigned i = 0; i < theNoOfCompletedTransactions; i++)
+ for (i = 0; i < theNoOfCompletedTransactions; i++)
theCompletedTransactionsArray[i]->printState();
NdbMutex_Unlock(ndb_print_state_mutex);
}
diff --git a/ndb/include/util/getarg.h b/ndb/test/include/getarg.h
similarity index 100%
rename from ndb/include/util/getarg.h
rename to ndb/test/include/getarg.h
diff --git a/ndb/test/run-test/Makefile.am b/ndb/test/run-test/Makefile.am
index 3bf2edde47a..80e9e05eef7 100644
--- a/ndb/test/run-test/Makefile.am
+++ b/ndb/test/run-test/Makefile.am
@@ -11,7 +11,7 @@ test_SCRIPTS=atrt-analyze-result.sh atrt-gather-result.sh atrt-setup.sh \
atrt-clear-result.sh make-config.sh make-index.sh make-html-reports.sh
atrt_SOURCES = main.cpp
-INCLUDES_LOC = -I$(top_srcdir)/ndb/src/mgmclient
+INCLUDES_LOC = -I$(top_srcdir)/ndb/test/include -I$(top_srcdir)/ndb/src/mgmclient
LDADD_LOC = $(top_builddir)/ndb/src/mgmclient/CpcClient.o \
$(top_builddir)/ndb/src/libndbclient.la \
$(top_builddir)/dbug/libdbug.a \
diff --git a/ndb/test/src/Makefile.am b/ndb/test/src/Makefile.am
index a513086dc33..a8f34a0ea22 100644
--- a/ndb/test/src/Makefile.am
+++ b/ndb/test/src/Makefile.am
@@ -9,7 +9,7 @@ libNDBT_a_SOURCES = \
HugoAsynchTransactions.cpp UtilTransactions.cpp \
NdbRestarter.cpp NdbRestarts.cpp NDBT_Output.cpp \
NdbBackup.cpp NdbConfig.cpp NdbGrep.cpp NDBT_Table.cpp \
- NdbSchemaCon.cpp NdbSchemaOp.cpp
+ NdbSchemaCon.cpp NdbSchemaOp.cpp getarg.c
INCLUDES_LOC = -I$(top_srcdir)/ndb/src/common/mgmcommon -I$(top_srcdir)/ndb/include/mgmcommon -I$(top_srcdir)/ndb/include/kernel -I$(top_srcdir)/ndb/src/mgmapi
diff --git a/ndb/src/common/util/getarg.c b/ndb/test/src/getarg.c
similarity index 97%
rename from ndb/src/common/util/getarg.c
rename to ndb/test/src/getarg.c
index 99b2840a5a6..9f03af69824 100644
--- a/ndb/src/common/util/getarg.c
+++ b/ndb/test/src/getarg.c
@@ -36,15 +36,33 @@
#include "getarg.h"
-#define ISFLAG(X) ((X).type == arg_flag || (X).type == arg_negative_flag)
-
#ifndef HAVE_STRLCPY
-extern size_t strlcpy (char *dst, const char *src, size_t dst_sz);
-#endif /* !HAVE_STRLCPY */
-
+static size_t
+strlcpy (char *dst, const char *src, size_t dst_sz)
+{
+ size_t n;
+ char *p;
+ for (p = dst, n = 0;
+ n + 1 < dst_sz && *src != '\0';
+ ++p, ++src, ++n)
+ *p = *src;
+ *p = '\0';
+ if (*src == '\0')
+ return n;
+ else
+ return n + strlen (src);
+}
+#endif
#ifndef HAVE_STRLCAT
-extern size_t strlcat (char *dst, const char *src, size_t dst_sz);
-#endif /* !HAVE_STRLCAT */
+static size_t
+strlcat (char *dst, const char *src, size_t dst_sz)
+{
+ size_t len = strlen(dst);
+ return len + strlcpy (dst + len, src, dst_sz - len);
+}
+#endif
+
+#define ISFLAG(X) ((X).type == arg_flag || (X).type == arg_negative_flag)
#ifndef max
#define max(a, b) (a) > (b) ? (a) : (b)
diff --git a/ndb/tools/delete_all.cpp b/ndb/tools/delete_all.cpp
index aa5798376ae..a4fd73a5128 100644
--- a/ndb/tools/delete_all.cpp
+++ b/ndb/tools/delete_all.cpp
@@ -15,41 +15,65 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include
+#include
#include
#include
#include
#include
-#include
-
static int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab, int parallelism=240);
-int main(int argc, const char** argv){
- ndb_init();
-
- const char* _tabname = NULL;
- const char* _dbname = "TEST_DB";
- int _help = 0;
-
- struct getargs args[] = {
- { "usage", '?', arg_flag, &_help, "Print help", "" },
- { "database", 'd', arg_string, &_dbname, "dbname",
- "Name of database table is in"}
- };
- int num_args = sizeof(args) / sizeof(args[0]);
- int optind = 0;
+static const char* opt_connect_str= 0;
+static const char* _dbname = "TEST_DB";
+static struct my_option my_long_options[] =
+{
+ NDB_STD_OPTS("ndb_desc"),
+ { "database", 'd', "Name of database table is in",
+ (gptr*) &_dbname, (gptr*) &_dbname, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
+static void print_version()
+{
+ printf("MySQL distrib %s, for %s (%s)\n",MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
+}
+static void usage()
+{
char desc[] =
"tabname\n"\
"This program will delete all records in the specified table using scan delete.\n";
-
- if(getarg(args, num_args, argc, argv, &optind) ||
- argv[optind] == NULL || _help) {
- arg_printusage(args, num_args, argv[0], desc);
- return NDBT_ProgramExit(NDBT_WRONGARGS);
+ print_version();
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
+}
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ switch (optid) {
+ case '#':
+ DBUG_PUSH(argument ? argument : "d:t:O,/tmp/ndb_delete_all.trace");
+ break;
+ case 'V':
+ print_version();
+ exit(0);
+ case '?':
+ usage();
+ exit(0);
}
- _tabname = argv[optind];
+ return 0;
+}
+int main(int argc, char** argv){
+ NDB_INIT(argv[0]);
+ const char *load_default_groups[]= { "ndb_tools",0 };
+ load_defaults("my",load_default_groups,&argc,&argv);
+ int ho_error;
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ return NDBT_ProgramExit(NDBT_WRONGARGS);
+
+ Ndb::setConnectString(opt_connect_str);
// Connect to Ndb
Ndb MyNdb(_dbname);
@@ -64,13 +88,12 @@ int main(int argc, const char** argv){
// Check if table exists in db
int res = NDBT_OK;
- for(int i = optind; i
+#include
+#include
#include
#include
-
-
-
-int main(int argc, const char** argv){
- ndb_init();
- const char* _tabname = NULL;
- const char* _dbname = "TEST_DB";
- int _unqualified = 0;
- int _help = 0;
-
- struct getargs args[] = {
- { "unqualified", 'u', arg_flag, &_unqualified, "unqualified",
- "Use unqualified table names"},
- { "database", 'd', arg_string, &_dbname, "dbname",
- "Name of database table is in"},
- { "usage", '?', arg_flag, &_help, "Print help", "" }
- };
- int num_args = sizeof(args) / sizeof(args[0]);
- int optind = 0;
+static const char* opt_connect_str= 0;
+static const char* _dbname = "TEST_DB";
+static int _unqualified = 0;
+static struct my_option my_long_options[] =
+{
+ NDB_STD_OPTS("ndb_desc"),
+ { "database", 'd', "Name of database table is in",
+ (gptr*) &_dbname, (gptr*) &_dbname, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+ { "unqualified", 'u', "Use unqualified table names",
+ (gptr*) &_unqualified, (gptr*) &_unqualified, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
+static void print_version()
+{
+ printf("MySQL distrib %s, for %s (%s)\n",MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
+}
+static void usage()
+{
char desc[] =
"tabname\n"\
"This program list all properties of table(s) in NDB Cluster.\n"\
- " ex: desc T1 T2 T4\n";
-
- if(getarg(args, num_args, argc, argv, &optind) ||
- argv[optind] == NULL ||_help) {
- arg_printusage(args, num_args, argv[0], desc);
- return NDBT_ProgramExit(NDBT_WRONGARGS);
+ " ex: desc T1 T2 T4\n";
+ print_version();
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
+}
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ switch (optid) {
+ case '#':
+ DBUG_PUSH(argument ? argument : "d:t:O,/tmp/ndb_desc.trace");
+ break;
+ case 'V':
+ print_version();
+ exit(0);
+ case '?':
+ usage();
+ exit(0);
}
- _tabname = argv[optind];
+ return 0;
+}
+
+int main(int argc, char** argv){
+ NDB_INIT(argv[0]);
+ const char *load_default_groups[]= { "ndb_tools",0 };
+ load_defaults("my",load_default_groups,&argc,&argv);
+ int ho_error;
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ return NDBT_ProgramExit(NDBT_WRONGARGS);
+
+ Ndb::setConnectString(opt_connect_str);
Ndb* pMyNdb;
pMyNdb = new Ndb(_dbname);
@@ -60,7 +86,7 @@ int main(int argc, const char** argv){
ndbout << endl;
NdbDictionary::Dictionary * dict = pMyNdb->getDictionary();
- for (int i = optind; i < argc; i++) {
+ for (int i = 0; i < argc; i++) {
NDBT_Table* pTab = (NDBT_Table*)dict->getTable(argv[i]);
if (pTab != 0){
ndbout << (* pTab) << endl;
diff --git a/ndb/tools/drop_index.cpp b/ndb/tools/drop_index.cpp
index 70c29461c23..1d4b454682f 100644
--- a/ndb/tools/drop_index.cpp
+++ b/ndb/tools/drop_index.cpp
@@ -15,38 +15,66 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include
+#include
#include
#include
#include
-#include
-
-int main(int argc, const char** argv){
- ndb_init();
-
- const char* _tabname = NULL;
- const char* _dbname = "TEST_DB";
- int _help = 0;
-
- struct getargs args[] = {
- { "database", 'd', arg_string, &_dbname, "dbname",
- "Name of database table is in"},
- { "usage", '?', arg_flag, &_help, "Print help", "" }
- };
- int num_args = sizeof(args) / sizeof(args[0]);
- int optind = 0;
+static const char* opt_connect_str= 0;
+static const char* _dbname = "TEST_DB";
+static struct my_option my_long_options[] =
+{
+ NDB_STD_OPTS("ndb_desc"),
+ { "database", 'd', "Name of database table is in",
+ (gptr*) &_dbname, (gptr*) &_dbname, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
+static void print_version()
+{
+ printf("MySQL distrib %s, for %s (%s)\n",MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
+}
+static void usage()
+{
char desc[] =
"+\n"\
"This program will drop index(es) in Ndb\n";
+ print_version();
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
+}
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ switch (optid) {
+ case '#':
+ DBUG_PUSH(argument ? argument : "d:t:O,/tmp/ndb_drop_index.trace");
+ break;
+ case 'V':
+ print_version();
+ exit(0);
+ case '?':
+ usage();
+ exit(0);
+ }
+ return 0;
+}
- if(getarg(args, num_args, argc, argv, &optind) ||
- argv[optind] == NULL || _help){
- arg_printusage(args, num_args, argv[0], desc);
+int main(int argc, char** argv){
+ NDB_INIT(argv[0]);
+ const char *load_default_groups[]= { "ndb_tools",0 };
+ load_defaults("my",load_default_groups,&argc,&argv);
+ int ho_error;
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ return NDBT_ProgramExit(NDBT_WRONGARGS);
+ if (argc < 1) {
+ usage();
return NDBT_ProgramExit(NDBT_WRONGARGS);
}
- _tabname = argv[optind];
+ Ndb::setConnectString(opt_connect_str);
// Connect to Ndb
Ndb MyNdb(_dbname);
if(MyNdb.init() != 0){
@@ -58,7 +86,7 @@ int main(int argc, const char** argv){
ndbout << "Waiting for ndb to become ready..." << endl;
int res = 0;
- for(int i = optind; idropIndex(argv[i], 0)) != 0){
diff --git a/ndb/tools/drop_tab.cpp b/ndb/tools/drop_tab.cpp
index 15c229cb0fb..428730419fa 100644
--- a/ndb/tools/drop_tab.cpp
+++ b/ndb/tools/drop_tab.cpp
@@ -15,43 +15,67 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include
+#include
#include
#include
#include
-#include
-
-int main(int argc, const char** argv){
- ndb_init();
-
- const char* _tabname = NULL;
- const char* _dbname = "TEST_DB";
- const char* _connectstr = NULL;
- int _help = 0;
-
- struct getargs args[] = {
- { "database", 'd', arg_string, &_dbname, "dbname",
- "Name of database table is in"},
- { "connstr", 'c', arg_string, &_connectstr, "connect string",
- "How to connect to NDB"},
- { "usage", '?', arg_flag, &_help, "Print help", "" }
- };
- int num_args = sizeof(args) / sizeof(args[0]);
- int optind = 0;
+static const char* opt_connect_str= 0;
+static const char* _dbname = "TEST_DB";
+static struct my_option my_long_options[] =
+{
+ NDB_STD_OPTS("ndb_desc"),
+ { "database", 'd', "Name of database table is in",
+ (gptr*) &_dbname, (gptr*) &_dbname, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
+static void print_version()
+{
+ printf("MySQL distrib %s, for %s (%s)\n",MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
+ ndbPrintVersion();
+}
+static void usage()
+{
char desc[] =
"tabname\n"\
"This program will drop one table in Ndb\n";
+ print_version();
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
+}
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ switch (optid) {
+ case '#':
+ DBUG_PUSH(argument ? argument : "d:t:O,/tmp/ndb_drop_table.trace");
+ break;
+ case 'V':
+ print_version();
+ exit(0);
+ case '?':
+ usage();
+ exit(0);
+ }
+ return 0;
+}
- if(getarg(args, num_args, argc, argv, &optind) ||
- argv[optind] == NULL || _help){
- arg_printusage(args, num_args, argv[0], desc);
+int main(int argc, char** argv){
+ NDB_INIT(argv[0]);
+ const char *load_default_groups[]= { "ndb_tools",0 };
+ load_defaults("my",load_default_groups,&argc,&argv);
+ int ho_error;
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ return NDBT_ProgramExit(NDBT_WRONGARGS);
+ if (argc < 1) {
+ usage();
return NDBT_ProgramExit(NDBT_WRONGARGS);
}
- _tabname = argv[optind];
-
- if (_connectstr)
- Ndb::setConnectString(_connectstr);
+
+ Ndb::setConnectString(opt_connect_str);
Ndb MyNdb(_dbname);
if(MyNdb.init() != 0){
ERR(MyNdb.getNdbError());
@@ -62,7 +86,7 @@ int main(int argc, const char** argv){
ndbout << "Waiting for ndb to become ready..." << endl;
int res = 0;
- for(int i = optind; idropTable(argv[i])) != 0){
diff --git a/ndb/tools/listTables.cpp b/ndb/tools/listTables.cpp
index 4fc5bcd7f21..2fc34394a9c 100644
--- a/ndb/tools/listTables.cpp
+++ b/ndb/tools/listTables.cpp
@@ -22,7 +22,7 @@
*/
#include
-#include
+#include
#include
#include
@@ -161,39 +161,34 @@ list(const char * tabname,
}
}
-#ifndef DBUG_OFF
-const char *debug_option= 0;
-#endif
-
-int main(int argc, const char** argv){
- ndb_init();
- int _loops = 1;
- const char* _tabname = NULL;
- const char* _dbname = "TEST_DB";
- int _type = 0;
- int _help = 0;
- const char* _connect_str = NULL;
-
- struct getargs args[] = {
- { "loops", 'l', arg_integer, &_loops, "loops",
- "Number of times to run(default = 1)" },
- { "unqualified", 'u', arg_flag, &_unqualified, "unqualified",
- "Use unqualified table names"},
- { "database", 'd', arg_string, &_dbname, "dbname",
- "Name of database table is in"},
- { "type", 't', arg_integer, &_type, "type",
- "Type of objects to show, see NdbDictionary.hpp for numbers(default = 0)" },
- { "connect-string", 'c', arg_string, &_connect_str,
- "Set connect string for connecting to ndb_mgmd. =\"host=[;nodeid=]\". Overides specifying entries in NDB_CONNECTSTRING and config file",
- "" },
-#ifndef DBUG_OFF
- { "debug", 0, arg_string, &debug_option,
- "Specify debug options e.g. d:t:i:o,out.trace", "options" },
-#endif
- { "usage", '?', arg_flag, &_help, "Print help", "" }
- };
- int num_args = sizeof(args) / sizeof(args[0]);
- int optind = 0;
+static const char* opt_connect_str= 0;
+static const char* _dbname = "TEST_DB";
+static int _loops;
+static int _type;
+static struct my_option my_long_options[] =
+{
+ NDB_STD_OPTS("ndb_desc"),
+ { "database", 'd', "Name of database table is in",
+ (gptr*) &_dbname, (gptr*) &_dbname, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+ { "loops", 'l', "loops",
+ (gptr*) &_loops, (gptr*) &_loops, 0,
+ GET_INT, REQUIRED_ARG, 1, 0, 0, 0, 0, 0 },
+ { "type", 't', "type",
+ (gptr*) &_type, (gptr*) &_type, 0,
+ GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+ { "unqualified", 'u', "Use unqualified table names",
+ (gptr*) &_unqualified, (gptr*) &_unqualified, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
+static void print_version()
+{
+ printf("MySQL distrib %s, for %s (%s)\n",MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
+ ndbPrintVersion();
+}
+static void usage()
+{
char desc[] =
"tabname\n"\
"This program list all system objects in NDB Cluster.\n"\
@@ -201,19 +196,42 @@ int main(int argc, const char** argv){
" ex: list_tables -t 2 would show all UserTables\n"\
"To show all indexes for a table write table name as final argument\n"\
" ex: list_tables T1\n";
-
- if(getarg(args, num_args, argc, argv, &optind) || _help) {
- arg_printusage(args, num_args, argv[0], desc);
+ print_version();
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
+}
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ switch (optid) {
+ case '#':
+ DBUG_PUSH(argument ? argument : "d:t:O,/tmp/ndb_show_tables.trace");
+ break;
+ case 'V':
+ print_version();
+ exit(0);
+ case '?':
+ usage();
+ exit(0);
+ }
+ return 0;
+}
+
+int main(int argc, char** argv){
+ NDB_INIT(argv[0]);
+ const char* _tabname;
+ const char *load_default_groups[]= { "ndb_tools",0 };
+ load_defaults("my",load_default_groups,&argc,&argv);
+ int ho_error;
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ return NDBT_ProgramExit(NDBT_WRONGARGS);
+ if ((_tabname = argv[0]) == 0) {
+ usage();
return NDBT_ProgramExit(NDBT_WRONGARGS);
}
- _tabname = argv[optind];
-
-#ifndef DBUG_OFF
- if (debug_option)
- DBUG_PUSH(debug_option);
-#endif
- ndb_cluster_connection = new Ndb_cluster_connection(_connect_str);
+ ndb_cluster_connection = new Ndb_cluster_connection(opt_connect_str);
ndb = new Ndb(ndb_cluster_connection, _dbname);
if (ndb->init() != 0)
fatal("init");
diff --git a/ndb/tools/select_all.cpp b/ndb/tools/select_all.cpp
index 9f8108d9f32..758c1e48c88 100644
--- a/ndb/tools/select_all.cpp
+++ b/ndb/tools/select_all.cpp
@@ -16,6 +16,7 @@
#include
+#include
#include
@@ -23,13 +24,8 @@
#include
#include
#include
-#include
#include
-#ifndef DBUG_OFF
-const char *debug_option= 0;
-#endif
-
int scanReadRecords(Ndb*,
const NdbDictionary::Table*,
const NdbDictionary::Index*,
@@ -40,39 +36,44 @@ int scanReadRecords(Ndb*,
char delim,
bool orderby);
-int main(int argc, const char** argv){
- ndb_init();
- int _parallelism = 240;
- const char* _delimiter = "\t";
- int _header = true;
- int _useHexFormat = false;
- const char* _tabname = NULL;
- const char* _dbname = "TEST_DB";
- int _help = 0;
- int _lock = 0;
- int _order = 0;
+static const char* opt_connect_str= 0;
+static const char* _dbname = "TEST_DB";
+static const char* _delimiter = "\t";
+static int _unqualified, _header, _parallelism, _useHexFormat, _lock,
+ _order;
- struct getargs args[] = {
- { "database", 'd', arg_string, &_dbname, "dbname",
- "Name of database table is in"},
- { "parallelism", 'p', arg_integer, &_parallelism, "parallelism",
- "parallelism" },
- { "header", 'h', arg_flag, &_header, "Print header", "header" },
- { "useHexFormat", 'x', arg_flag, &_useHexFormat,
- "Output numbers in hexadecimal format", "useHexFormat" },
- { "delimiter", 'd', arg_string, &_delimiter, "Column delimiter",
- "delimiter" },
-#ifndef DBUG_OFF
- { "debug", 0, arg_string, &debug_option,
- "Specify debug options e.g. d:t:i:o,out.trace", "options" },
-#endif
- { "usage", '?', arg_flag, &_help, "Print help", "" },
- { "lock", 'l', arg_integer, &_lock,
- "Read(0), Read-hold(1), Exclusive(2)", "lock"},
- { "order", 'o', arg_flag, &_order, "Sort resultset according to index", ""}
- };
- int num_args = sizeof(args) / sizeof(args[0]);
- int optind = 0;
+static struct my_option my_long_options[] =
+{
+ NDB_STD_OPTS("ndb_desc"),
+ { "database", 'd', "Name of database table is in",
+ (gptr*) &_dbname, (gptr*) &_dbname, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+ { "parallelism", 'p', "parallelism",
+ (gptr*) &_parallelism, (gptr*) &_parallelism, 0,
+ GET_INT, REQUIRED_ARG, 240, 0, 0, 0, 0, 0 },
+ { "lock", 'l', "Read(0), Read-hold(1), Exclusive(2)",
+ (gptr*) &_lock, (gptr*) &_lock, 0,
+ GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+ { "order", 'o', "Sort resultset according to index",
+ (gptr*) &_order, (gptr*) &_order, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
+ { "header", 'h', "Print header",
+ (gptr*) &_header, (gptr*) &_header, 0,
+ GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0 },
+ { "useHexFormat", 'x', "Output numbers in hexadecimal format",
+ (gptr*) &_useHexFormat, (gptr*) &_useHexFormat, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
+ { "delimiter", 'D', "Column delimiter",
+ (gptr*) &_delimiter, (gptr*) &_delimiter, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
+static void print_version()
+{
+ printf("MySQL distrib %s, for %s (%s)\n",MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
+}
+static void usage()
+{
char desc[] =
"tabname\n"\
"This program reads all records from one table in NDB Cluster\n"\
@@ -80,19 +81,42 @@ int main(int argc, const char** argv){
"(It only print error messages if it encounters a permanent error.)\n"\
"It can also be used to dump the content of a table to file \n"\
" ex: select_all --no-header --delimiter=';' T4 > T4.data\n";
-
- if(getarg(args, num_args, argc, argv, &optind) ||
- argv[optind] == NULL || _help) {
- arg_printusage(args, num_args, argv[0], desc);
+ print_version();
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
+}
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ switch (optid) {
+ case '#':
+ DBUG_PUSH(argument ? argument : "d:t:O,/tmp/ndb_select_all.trace");
+ break;
+ case 'V':
+ print_version();
+ exit(0);
+ case '?':
+ usage();
+ exit(0);
+ }
+ return 0;
+}
+
+int main(int argc, char** argv){
+ NDB_INIT(argv[0]);
+ const char *load_default_groups[]= { "ndb_tools",0 };
+ load_defaults("my",load_default_groups,&argc,&argv);
+ const char* _tabname;
+ int ho_error;
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ return NDBT_ProgramExit(NDBT_WRONGARGS);
+ if ((_tabname = argv[0]) == 0) {
+ usage();
return NDBT_ProgramExit(NDBT_WRONGARGS);
}
- _tabname = argv[optind];
-
-#ifndef DBUG_OFF
- if (debug_option)
- DBUG_PUSH(debug_option);
-#endif
+ Ndb::setConnectString(opt_connect_str);
// Connect to Ndb
Ndb MyNdb(_dbname);
@@ -108,8 +132,8 @@ int main(int argc, const char** argv){
// Check if table exists in db
const NdbDictionary::Table* pTab = NDBT_Table::discoverTableFromDb(&MyNdb, _tabname);
const NdbDictionary::Index * pIdx = 0;
- if(optind+1 < argc){
- pIdx = MyNdb.getDictionary()->getIndex(argv[optind+1], _tabname);
+ if(argc > 1){
+ pIdx = MyNdb.getDictionary()->getIndex(argv[0], _tabname);
}
if(pTab == NULL){
diff --git a/ndb/tools/select_count.cpp b/ndb/tools/select_count.cpp
index 6650421e637..6ee49ddbff0 100644
--- a/ndb/tools/select_count.cpp
+++ b/ndb/tools/select_count.cpp
@@ -16,6 +16,7 @@
#include
+#include
#include
@@ -23,7 +24,6 @@
#include
#include
#include
-#include
#include
static int
@@ -32,34 +32,68 @@ select_count(Ndb* pNdb, const NdbDictionary::Table* pTab,
int* count_rows,
UtilTransactions::ScanLock lock);
-int main(int argc, const char** argv){
- ndb_init();
- const char* _dbname = "TEST_DB";
- int _parallelism = 240;
- int _help = 0;
- int _lock = 0;
-
- struct getargs args[] = {
- { "database", 'd', arg_string, &_dbname, "dbname",
- "Name of database table is in"},
- { "parallelism", 's', arg_integer, &_parallelism, "parallelism", "parallelism" },
- { "usage", '?', arg_flag, &_help, "Print help", "" },
- { "lock", 'l', arg_integer, &_lock,
- "Read(0), Read-hold(1), Exclusive(2)", "lock"}
-
- };
- int num_args = sizeof(args) / sizeof(args[0]);
- int optind = 0;
+static const char* opt_connect_str= 0;
+static const char* _dbname = "TEST_DB";
+static int _parallelism = 240;
+static int _lock = 0;
+static struct my_option my_long_options[] =
+{
+ NDB_STD_OPTS("ndb_desc"),
+ { "database", 'd', "Name of database table is in",
+ (gptr*) &_dbname, (gptr*) &_dbname, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+ { "parallelism", 'p', "parallelism",
+ (gptr*) &_parallelism, (gptr*) &_parallelism, 0,
+ GET_INT, REQUIRED_ARG, 240, 0, 0, 0, 0, 0 },
+ { "lock", 'l', "Read(0), Read-hold(1), Exclusive(2)",
+ (gptr*) &_lock, (gptr*) &_lock, 0,
+ GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
+static void print_version()
+{
+ printf("MySQL distrib %s, for %s (%s)\n",MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
+}
+static void usage()
+{
char desc[] =
"tabname1 ... tabnameN\n"\
"This program will count the number of records in tables\n";
-
- if(getarg(args, num_args, argc, argv, &optind) ||
- argv[optind] == NULL || _help) {
- arg_printusage(args, num_args, argv[0], desc);
+ print_version();
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
+}
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ switch (optid) {
+ case '#':
+ DBUG_PUSH(argument ? argument : "d:t:O,/tmp/ndb_select_count.trace");
+ break;
+ case 'V':
+ print_version();
+ exit(0);
+ case '?':
+ usage();
+ exit(0);
+ }
+ return 0;
+}
+
+int main(int argc, char** argv){
+ NDB_INIT(argv[0]);
+ const char *load_default_groups[]= { "ndb_tools",0 };
+ load_defaults("my",load_default_groups,&argc,&argv);
+ int ho_error;
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ return NDBT_ProgramExit(NDBT_WRONGARGS);
+ if (argc < 1) {
+ usage();
return NDBT_ProgramExit(NDBT_WRONGARGS);
}
+ Ndb::setConnectString(opt_connect_str);
// Connect to Ndb
Ndb MyNdb(_dbname);
@@ -72,7 +106,7 @@ int main(int argc, const char** argv){
while(MyNdb.waitUntilReady() != 0)
ndbout << "Waiting for ndb to become ready..." << endl;
- for(int i = optind; i
+#include
+
#include
#include
#include
#include
-#include
#include
#include "../include/mgmcommon/LocalConfig.hpp"
@@ -29,34 +30,60 @@
int
waitClusterStatus(const char* _addr, ndb_mgm_node_status _status, unsigned int _timeout);
-int main(int argc, const char** argv){
- ndb_init();
-
- const char* _hostName = NULL;
- int _no_contact = 0;
- int _help = 0;
- int _timeout = 120;
-
- struct getargs args[] = {
- { "timeout", 0, arg_integer, &_timeout, "Timeout to wait", "#" },
- { "no-contact", 0, arg_flag, &_no_contact, "Wait for cluster no contact", "" },
- { "usage", '?', arg_flag, &_help, "Print help", "" }
- };
-
- int num_args = sizeof(args) / sizeof(args[0]);
- int optind = 0;
- char desc[] =
- "hostname:port\n"\
- "This program will connect to the mgmsrv of a NDB cluster.\n"\
- "It will then wait for all nodes to be started\n";
-
- if(getarg(args, num_args, argc, argv, &optind) || _help) {
- arg_printusage(args, num_args, argv[0], desc);
- return NDBT_ProgramExit(NDBT_WRONGARGS);
+static const char* opt_connect_str= 0;
+static int _no_contact = 0;
+static int _timeout = 120;
+static struct my_option my_long_options[] =
+{
+ NDB_STD_OPTS("ndb_desc"),
+ { "no-contact", 'n', "Wait for cluster no contact",
+ (gptr*) &_no_contact, (gptr*) &_no_contact, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
+ { "timeout", 't', "Timeout to wait",
+ (gptr*) &_timeout, (gptr*) &_timeout, 0,
+ GET_INT, REQUIRED_ARG, 120, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
+static void print_version()
+{
+ printf("MySQL distrib %s, for %s (%s)\n",MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
+ ndbPrintVersion();
+}
+static void usage()
+{
+ print_version();
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
+}
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ switch (optid) {
+ case '#':
+ DBUG_PUSH(argument ? argument : "d:t:O,/tmp/ndb_drop_table.trace");
+ break;
+ case 'V':
+ print_version();
+ exit(0);
+ case '?':
+ usage();
+ exit(0);
}
+ return 0;
+}
+
+int main(int argc, char** argv){
+ NDB_INIT(argv[0]);
+ const char *load_default_groups[]= { "ndb_tools",0 };
+ load_defaults("my",load_default_groups,&argc,&argv);
+ const char* _hostName = NULL;
+ int ho_error;
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ return NDBT_ProgramExit(NDBT_WRONGARGS);
char buf[255];
- _hostName = argv[optind];
+ _hostName = argv[0];
if (_hostName == NULL){
LocalConfig lcfg;
From d129fffe572089b3008f694c3cface0f35aff16e Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Mon, 1 Nov 2004 14:25:07 +0000
Subject: [PATCH 32/59] configure.in: added flag on sun forte,
-instances=static (check is only made for "non-gcc", hopefully enough)
---
configure.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/configure.in b/configure.in
index fe487b15557..95d241ad669 100644
--- a/configure.in
+++ b/configure.in
@@ -975,7 +975,7 @@ case $SYSTEM_TYPE-$MACHINE_TYPE-$ac_cv_prog_gcc in
CXXFLAGS="$CXXFLAGS -DBIG_TABLES"
;;
# workaround for Sun Forte compile problem for ndb
- *solaris2.10*-sparc-no)
+ *solaris2.*-no)
ndb_cxxflags_fix="$ndb_cxxflags_fix -instances=static"
;;
*) ;;
From 1827256ac55dd195fff309c8475541bc335aa7ec Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Mon, 1 Nov 2004 14:43:53 +0000
Subject: [PATCH 33/59] fix call of string::copy() if HAVE_FCONVERT is set
---
sql/sql_string.cc | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/sql/sql_string.cc b/sql/sql_string.cc
index 6b2bb07fb8c..c1701e7e9bf 100644
--- a/sql/sql_string.cc
+++ b/sql/sql_string.cc
@@ -142,7 +142,8 @@ bool String::set(double num,uint decimals, CHARSET_INFO *cs)
buff[0]='-';
pos=buff;
}
- return copy(pos,(uint32) strlen(pos), &my_charset_latin1, cs);
+ uint dummy_errors;
+ return copy(pos,(uint32) strlen(pos), &my_charset_latin1, cs, &dummy_errors);
}
if (alloc((uint32) ((uint32) decpt+3+decimals)))
return TRUE;
From ff7e440bb04280a19ece143c27eed793c3f57755 Mon Sep 17 00:00:00 2001
From: "pekka@mysql.com" <>
Date: Mon, 1 Nov 2004 16:04:36 +0100
Subject: [PATCH 34/59] NDB blobs restore backwards compatibility
---
ndb/src/ndbapi/NdbBlob.cpp | 23 +++++++++++------------
1 file changed, 11 insertions(+), 12 deletions(-)
diff --git a/ndb/src/ndbapi/NdbBlob.cpp b/ndb/src/ndbapi/NdbBlob.cpp
index 13532a413bb..731f32ba916 100644
--- a/ndb/src/ndbapi/NdbBlob.cpp
+++ b/ndb/src/ndbapi/NdbBlob.cpp
@@ -97,14 +97,6 @@ NdbBlob::getBlobTable(NdbTableImpl& bt, const NdbTableImpl* t, const NdbColumnIm
bt.setName(btname);
bt.setLogging(t->getLogging());
bt.setFragmentType(t->getFragmentType());
- { NdbDictionary::Column bc("PK");
- bc.setType(NdbDictionary::Column::Unsigned);
- assert(t->m_sizeOfKeysInWords != 0);
- bc.setLength(t->m_sizeOfKeysInWords);
- bc.setPrimaryKey(true);
- bc.setDistributionKey(true);
- bt.addColumn(bc);
- }
{ NdbDictionary::Column bc("DIST");
bc.setType(NdbDictionary::Column::Unsigned);
bc.setPrimaryKey(true);
@@ -116,6 +108,13 @@ NdbBlob::getBlobTable(NdbTableImpl& bt, const NdbTableImpl* t, const NdbColumnIm
bc.setPrimaryKey(true);
bt.addColumn(bc);
}
+ { NdbDictionary::Column bc("PK");
+ bc.setType(NdbDictionary::Column::Unsigned);
+ assert(t->m_sizeOfKeysInWords != 0);
+ bc.setLength(t->m_sizeOfKeysInWords);
+ bc.setPrimaryKey(true);
+ bt.addColumn(bc);
+ }
{ NdbDictionary::Column bc("DATA");
switch (c->m_type) {
case NdbDictionary::Column::Blob:
@@ -309,7 +308,7 @@ inline Uint32
NdbBlob::getDistKey(Uint32 part)
{
assert(theStripeSize != 0);
- return part / theStripeSize;
+ return (part / theStripeSize) % theStripeSize;
}
// getters and setters
@@ -393,9 +392,9 @@ NdbBlob::setPartKeyValue(NdbOperation* anOp, Uint32 part)
Uint32* data = (Uint32*)theKeyBuf.data;
unsigned size = theTable->m_sizeOfKeysInWords;
DBG("setPartKeyValue dist=" << getDistKey(part) << " part=" << part << " key=" << ndb_blob_debug(data, size));
- if (anOp->equal((Uint32)0, theKeyBuf.data) == -1 ||
- anOp->equal((Uint32)1, getDistKey(part)) == -1 ||
- anOp->equal((Uint32)2, part) == -1) {
+ if (anOp->equal((Uint32)0, getDistKey(part)) == -1 ||
+ anOp->equal((Uint32)1, part) == -1 ||
+ anOp->equal((Uint32)2, theKeyBuf.data) == -1) {
setErrorCode(anOp);
return -1;
}
From 96829a4639dec81803fa32c7e98d9641b81cea25 Mon Sep 17 00:00:00 2001
From: "konstantin@mysql.com" <>
Date: Mon, 1 Nov 2004 19:01:50 +0300
Subject: [PATCH 35/59] Remove support for obsolete 4.1.1 prepared statements C
API names: having approval for it since 4.1.4, I also have some assurance
that very few people actually used this: to enable these calls a user had to
#define HAVE_DEPRECATED_411_API and recompile the client library.
---
include/mysql.h | 17 -----------------
libmysql/libmysql.c | 16 ----------------
2 files changed, 33 deletions(-)
diff --git a/include/mysql.h b/include/mysql.h
index 1c886020fdb..156d749234b 100644
--- a/include/mysql.h
+++ b/include/mysql.h
@@ -642,23 +642,6 @@ typedef struct st_mysql_methods
#endif
} MYSQL_METHODS;
-#ifdef HAVE_DEPRECATED_411_API
-/* Deprecated calls (since MySQL 4.1.2) */
-
-/* Use mysql_stmt_init + mysql_stmt_prepare instead */
-MYSQL_STMT * STDCALL mysql_prepare(MYSQL * mysql, const char *query,
- unsigned long length);
-#define mysql_execute mysql_stmt_execute
-#define mysql_fetch mysql_stmt_fetch
-#define mysql_fetch_column mysql_stmt_fetch_column
-#define mysql_bind_param mysql_stmt_bind_param
-#define mysql_bind_result mysql_stmt_bind_result
-#define mysql_param_count mysql_stmt_param_count
-#define mysql_param_result mysql_stmt_param_metadata
-#define mysql_get_metadata mysql_stmt_result_metadata
-#define mysql_send_long_data mysql_stmt_send_long_data
-
-#endif /* HAVE_DEPRECATED_411_API */
MYSQL_STMT * STDCALL mysql_stmt_init(MYSQL *mysql);
int STDCALL mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query,
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index 9195f0a5bc5..88f46ce19e7 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -1886,22 +1886,6 @@ my_bool cli_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt)
DBUG_RETURN(0);
}
-#ifdef HAVE_DEPRECATED_411_API
-MYSQL_STMT * STDCALL mysql_prepare(MYSQL *mysql, const char *query,
- unsigned long query_length)
-{
- MYSQL_STMT *stmt;
- DBUG_ENTER("mysql_prepare");
-
- stmt= mysql_stmt_init(mysql);
- if (stmt && mysql_stmt_prepare(stmt, query, query_length))
- {
- mysql_stmt_close(stmt);
- DBUG_RETURN(0);
- }
- DBUG_RETURN(stmt);
-}
-#endif
/*
Allocate memory and init prepared statement structure.
From ebd0ee4a0dfe60b8e2a97691980283025765037c Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Mon, 1 Nov 2004 18:21:57 +0000
Subject: [PATCH 36/59] fix for solaris forte -instances=static added
libNDBT.a removed printout fixed error that ndb_show_tables required
table name
---
configure.in | 5 ++++-
ndb/test/run-test/Makefile.am | 1 +
ndb/tools/drop_tab.cpp | 1 -
ndb/tools/listTables.cpp | 6 +-----
ndb/tools/waiter.cpp | 1 -
5 files changed, 6 insertions(+), 8 deletions(-)
diff --git a/configure.in b/configure.in
index 95d241ad669..d63859720a3 100644
--- a/configure.in
+++ b/configure.in
@@ -974,8 +974,11 @@ case $SYSTEM_TYPE-$MACHINE_TYPE-$ac_cv_prog_gcc in
CFLAGS="$CFLAGS -DBIG_TABLES"
CXXFLAGS="$CXXFLAGS -DBIG_TABLES"
;;
+ *) ;;
+esac
+case $SYSTEM_TYPE-$ac_cv_prog_gcc in
# workaround for Sun Forte compile problem for ndb
- *solaris2.*-no)
+ *solaris*-no)
ndb_cxxflags_fix="$ndb_cxxflags_fix -instances=static"
;;
*) ;;
diff --git a/ndb/test/run-test/Makefile.am b/ndb/test/run-test/Makefile.am
index 80e9e05eef7..1eac96e7ac7 100644
--- a/ndb/test/run-test/Makefile.am
+++ b/ndb/test/run-test/Makefile.am
@@ -13,6 +13,7 @@ test_SCRIPTS=atrt-analyze-result.sh atrt-gather-result.sh atrt-setup.sh \
atrt_SOURCES = main.cpp
INCLUDES_LOC = -I$(top_srcdir)/ndb/test/include -I$(top_srcdir)/ndb/src/mgmclient
LDADD_LOC = $(top_builddir)/ndb/src/mgmclient/CpcClient.o \
+ $(top_builddir)/ndb/test/src/libNDBT.a \
$(top_builddir)/ndb/src/libndbclient.la \
$(top_builddir)/dbug/libdbug.a \
$(top_builddir)/mysys/libmysys.a \
diff --git a/ndb/tools/drop_tab.cpp b/ndb/tools/drop_tab.cpp
index 428730419fa..3362c7de47b 100644
--- a/ndb/tools/drop_tab.cpp
+++ b/ndb/tools/drop_tab.cpp
@@ -34,7 +34,6 @@ static struct my_option my_long_options[] =
static void print_version()
{
printf("MySQL distrib %s, for %s (%s)\n",MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
- ndbPrintVersion();
}
static void usage()
{
diff --git a/ndb/tools/listTables.cpp b/ndb/tools/listTables.cpp
index 2fc34394a9c..05e864a35c4 100644
--- a/ndb/tools/listTables.cpp
+++ b/ndb/tools/listTables.cpp
@@ -185,7 +185,6 @@ static struct my_option my_long_options[] =
static void print_version()
{
printf("MySQL distrib %s, for %s (%s)\n",MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
- ndbPrintVersion();
}
static void usage()
{
@@ -226,10 +225,7 @@ int main(int argc, char** argv){
int ho_error;
if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
return NDBT_ProgramExit(NDBT_WRONGARGS);
- if ((_tabname = argv[0]) == 0) {
- usage();
- return NDBT_ProgramExit(NDBT_WRONGARGS);
- }
+ _tabname = argv[0];
ndb_cluster_connection = new Ndb_cluster_connection(opt_connect_str);
ndb = new Ndb(ndb_cluster_connection, _dbname);
diff --git a/ndb/tools/waiter.cpp b/ndb/tools/waiter.cpp
index 1ff852b90cb..c9e76bb8ed3 100644
--- a/ndb/tools/waiter.cpp
+++ b/ndb/tools/waiter.cpp
@@ -47,7 +47,6 @@ static struct my_option my_long_options[] =
static void print_version()
{
printf("MySQL distrib %s, for %s (%s)\n",MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
- ndbPrintVersion();
}
static void usage()
{
From 4768c8387243226194aada0db2fce68611f7aa5f Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Mon, 1 Nov 2004 22:27:29 +0000
Subject: [PATCH 37/59] removed unused member variable (probably causing some
of the problems we've seen with ndb_mgmd)
---
ndb/src/mgmsrv/MgmtSrvr.cpp | 1 -
ndb/src/mgmsrv/MgmtSrvr.hpp | 1 -
2 files changed, 2 deletions(-)
diff --git a/ndb/src/mgmsrv/MgmtSrvr.cpp b/ndb/src/mgmsrv/MgmtSrvr.cpp
index 01dae3aeddb..2e30d73290b 100644
--- a/ndb/src/mgmsrv/MgmtSrvr.cpp
+++ b/ndb/src/mgmsrv/MgmtSrvr.cpp
@@ -407,7 +407,6 @@ MgmtSrvr::MgmtSrvr(NodeId nodeId,
// signals to other management servers.
_ownReference(0),
m_local_config(local_config),
- m_allocated_resources(*this),
theSignalIdleList(NULL),
theWaitState(WAIT_SUBSCRIBE_CONF),
m_statisticsListner(this)
diff --git a/ndb/src/mgmsrv/MgmtSrvr.hpp b/ndb/src/mgmsrv/MgmtSrvr.hpp
index a5f21b6bc4a..c796e1e9219 100644
--- a/ndb/src/mgmsrv/MgmtSrvr.hpp
+++ b/ndb/src/mgmsrv/MgmtSrvr.hpp
@@ -534,7 +534,6 @@ private:
Uint32 m_nextConfigGenerationNumber;
NodeBitmask m_reserved_nodes;
- Allocated_resources m_allocated_resources;
struct in_addr m_connect_address[MAX_NODES];
//**************************************************************************
From bc6bbebbc8ddde60cd2430987377d7122842f88a Mon Sep 17 00:00:00 2001
From: "bar@mysql.com" <>
Date: Tue, 2 Nov 2004 09:00:46 +0400
Subject: [PATCH 38/59] ctype_sjis.result, ctype_sjis.test, ctype-sjis.c: Bug
#6223 Japanese half-width kana characters get truncated. Bytes 0xA1..0xDF
were not treated as a single byte sequence in a mistake.
---
mysql-test/r/ctype_sjis.result | 11 +++++++++++
mysql-test/t/ctype_sjis.test | 11 +++++++++++
strings/ctype-sjis.c | 9 +++++++--
3 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/mysql-test/r/ctype_sjis.result b/mysql-test/r/ctype_sjis.result
index b0edbed1a41..944fa0602a9 100644
--- a/mysql-test/r/ctype_sjis.result
+++ b/mysql-test/r/ctype_sjis.result
@@ -60,3 +60,14 @@ hex(c)
9353
9373
drop table t1;
+SET NAMES sjis;
+CREATE TABLE t1 (
+c char(16) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=sjis;
+insert into t1 values(0xb1),(0xb2),(0xb3);
+select hex(c) from t1;
+hex(c)
+B1
+B2
+B3
+drop table t1;
diff --git a/mysql-test/t/ctype_sjis.test b/mysql-test/t/ctype_sjis.test
index c910812ef8a..a3a44789975 100644
--- a/mysql-test/t/ctype_sjis.test
+++ b/mysql-test/t/ctype_sjis.test
@@ -51,3 +51,14 @@ insert into t1 values (0x9353);
insert into t1 values (0x9373);
select hex(c) from t1;
drop table t1;
+
+#
+# Bug #6223 Japanese half-width kana characters get truncated
+#
+SET NAMES sjis;
+CREATE TABLE t1 (
+ c char(16) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=sjis;
+insert into t1 values(0xb1),(0xb2),(0xb3);
+select hex(c) from t1;
+drop table t1;
diff --git a/strings/ctype-sjis.c b/strings/ctype-sjis.c
index 4176ff2e538..a8b5394f8c5 100644
--- a/strings/ctype-sjis.c
+++ b/strings/ctype-sjis.c
@@ -4581,14 +4581,19 @@ uint my_well_formed_len_sjis(CHARSET_INFO *cs __attribute__((unused)),
*/
if (((int8)b[0]) >= 0)
{
- /* Single byte character */
- b+= 1;
+ /* Single byte ascii character */
+ b++;
}
else if (issjishead((uchar)*b) && (e-b)>1 && issjistail((uchar)b[1]))
{
/* Double byte character */
b+= 2;
}
+ else if (((uchar)*b) >= 0xA1 && ((uchar)*b) <= 0xDF)
+ {
+ /* Half width kana */
+ b++;
+ }
else
{
/* Wrong byte sequence */
From c0061627d8b1c04cf96d82366cc91f2b742b309a Mon Sep 17 00:00:00 2001
From: "heikki@hundin.mysql.fi" <>
Date: Tue, 2 Nov 2004 09:46:23 +0200
Subject: [PATCH 39/59] dict0load.c: Raise fatal semaphore wait timeout to 2
hours when we are printing the InnoDB table monitor output
---
innobase/dict/dict0load.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/innobase/dict/dict0load.c b/innobase/dict/dict0load.c
index d430eadc97b..c2b778f77c3 100644
--- a/innobase/dict/dict0load.c
+++ b/innobase/dict/dict0load.c
@@ -20,6 +20,7 @@ Created 4/24/1996 Heikki Tuuri
#include "dict0dict.h"
#include "dict0boot.h"
#include "srv0start.h"
+#include "srv0srv.h"
/************************************************************************
Finds the first table name in the given database. */
@@ -123,6 +124,13 @@ dict_print(void)
ulint len;
mtr_t mtr;
+ /* Enlarge the fatal semaphore wait timeout during the InnoDB table
+ monitor printout */
+
+ mutex_enter(&kernel_mutex);
+ srv_fatal_semaphore_wait_threshold += 7200; /* 2 hours */
+ mutex_exit(&kernel_mutex);
+
mutex_enter(&(dict_sys->mutex));
mtr_start(&mtr);
@@ -145,6 +153,12 @@ loop:
mutex_exit(&(dict_sys->mutex));
+ /* Restore the fatal semaphore wait timeout */
+
+ mutex_enter(&kernel_mutex);
+ srv_fatal_semaphore_wait_threshold -= 7200; /* 2 hours */
+ mutex_exit(&kernel_mutex);
+
return;
}
From e1979f25800de279b7135972dc4e1bd596293769 Mon Sep 17 00:00:00 2001
From: "ram@gw.mysql.r18.ru" <>
Date: Tue, 2 Nov 2004 13:14:07 +0400
Subject: [PATCH 40/59] A fix (bug #6309: myisamchk compiled without debug
support , --help shows vise versa bug #6380: mysqlcheck --help prints
wrong --debug msg for non-debug version).
---
client/mysqlcheck.c | 5 +++++
myisam/myisamchk.c | 8 ++++++--
2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c
index 8182b95fb83..c670b84db44 100644
--- a/client/mysqlcheck.c
+++ b/client/mysqlcheck.c
@@ -81,8 +81,13 @@ static struct my_option my_long_options[] =
"To check several databases. Note the difference in usage; In this case no tables are given. All name arguments are regarded as databasenames.",
(gptr*) &opt_databases, (gptr*) &opt_databases, 0, GET_BOOL, NO_ARG,
0, 0, 0, 0, 0, 0},
+#ifdef DBUG_OFF
+ {"debug", '#', "This is a non-debug version. Catch this and exit.",
+ 0, 0, 0, GET_DISABLED, OPT_ARG, 0, 0, 0, 0, 0, 0},
+#else
{"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.",
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+#endif
{"default-character-set", OPT_DEFAULT_CHARSET,
"Set the default character set.", (gptr*) &default_charset,
(gptr*) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c
index 648e29e1e9e..c89abca9cad 100644
--- a/myisam/myisamchk.c
+++ b/myisam/myisamchk.c
@@ -354,8 +354,12 @@ static void usage(void)
puts("Description, check and repair of MyISAM tables.");
puts("Used without options all tables on the command will be checked for errors");
printf("Usage: %s [OPTIONS] tables[.MYI]\n", my_progname_short);
- printf("\nGlobal options:\n\
- -#, --debug=... Output debug log. Often this is 'd:t:o,filename'.\n\
+ printf("\nGlobal options:\n");
+#ifndef DBUG_OFF
+ printf("\
+ -#, --debug=... Output debug log. Often this is 'd:t:o,filename'.\n");
+#endif
+ printf("\
-?, --help Display this help and exit.\n\
-O, --set-variable var=option.\n\
Change the value of a variable. Please note that\n\
From c68ea1665cffe0b8af1308942e0de0cc6baa4852 Mon Sep 17 00:00:00 2001
From: "heikki@hundin.mysql.fi" <>
Date: Tue, 2 Nov 2004 13:34:11 +0200
Subject: [PATCH 41/59] ha_innodb.cc: Correct English grammar
---
sql/ha_innodb.cc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 8d9ecb95fc0..0bcb7062437 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -2464,7 +2464,7 @@ ha_innobase::write_row(
NOTE that a REPLACE command and LOAD DATA INFILE REPLACE
handles a duplicate key error
itself, and we must not decrement the autoinc counter
- if we are performing a those statements.
+ if we are performing those statements.
NOTE 2: if there was an error, for example a deadlock,
which caused InnoDB to roll back the whole transaction
already in the call of row_insert_for_mysql(), we may no
From 6a3b1d443fc461210235d2ea5237ab30a77eb8ef Mon Sep 17 00:00:00 2001
From: "bar@mysql.com" <>
Date: Tue, 2 Nov 2004 16:02:12 +0400
Subject: [PATCH 42/59] Many files: Allow mixing of different character sets
for more SQL functions. item_func.h: Allow mixing of different character
sets for more SQL functions..
---
mysql-test/r/ctype_recoding.result | 54 +++++++++++++++
mysql-test/t/ctype_recoding.test | 26 +++++++
sql/item.cc | 41 +++++++++++
sql/item.h | 18 ++++-
sql/item_cmpfunc.cc | 96 +++-----------------------
sql/item_func.cc | 105 +++++++++++++++++++++++++----
sql/item_func.h | 3 +-
sql/item_strfunc.cc | 58 +++++++++-------
8 files changed, 274 insertions(+), 127 deletions(-)
diff --git a/mysql-test/r/ctype_recoding.result b/mysql-test/r/ctype_recoding.result
index dc1f4c12e25..1c75988fd21 100644
--- a/mysql-test/r/ctype_recoding.result
+++ b/mysql-test/r/ctype_recoding.result
@@ -186,3 +186,57 @@ select * from t1 where a=_latin1'
ERROR HY000: Illegal mix of collations (cp1251_general_ci,IMPLICIT) and (latin1_swedish_ci,COERCIBLE) for operation '='
drop table t1;
set names latin1;
+set names koi8r;
+create table t1 (c1 char(10) character set cp1251);
+insert into t1 values ('ß');
+select c1 from t1 where c1 between 'ß' and 'ß';
+c1
+ß
+select ifnull(c1,'ß'), ifnull(null,c1) from t1;
+ifnull(c1,'ß') ifnull(null,c1)
+ß ß
+select if(1,c1,'ö'), if(0,c1,'ö') from t1;
+if(1,c1,'ö') if(0,c1,'ö')
+ß ö
+select coalesce('ö',c1), coalesce(null,c1) from t1;
+coalesce('ö',c1) coalesce(null,c1)
+ö ß
+select least(c1,'ö'), greatest(c1,'ö') from t1;
+least(c1,'ö') greatest(c1,'ö')
+ö ß
+select locate(c1,'ß'), locate('ß',c1) from t1;
+locate(c1,'ß') locate('ß',c1)
+1 1
+select field(c1,'ß'),field('ß',c1) from t1;
+field(c1,'ß') field('ß',c1)
+1 1
+select concat(c1,'ö'), concat('ö',c1) from t1;
+concat(c1,'ö') concat('ö',c1)
+ßö öß
+select concat_ws(c1,'ö','ß'), concat_ws('ö',c1,'ß') from t1;
+concat_ws(c1,'ö','ß') concat_ws('ö',c1,'ß')
+ößß ßöß
+select replace(c1,'ß','ö'), replace('ß',c1,'ö') from t1;
+replace(c1,'ß','ö') replace('ß',c1,'ö')
+ö ö
+select substring_index(c1,'öößß',2) from t1;
+substring_index(c1,'öößß',2)
+ß
+select elt(1,c1,'ö'),elt(1,'ö',c1) from t1;
+elt(1,c1,'ö') elt(1,'ö',c1)
+ß ö
+select make_set(3,c1,'ö'), make_set(3,'ö',c1) from t1;
+make_set(3,c1,'ö') make_set(3,'ö',c1)
+ß,ö ö,ß
+select insert(c1,1,2,'ö'),insert('ö',1,2,c1) from t1;
+insert(c1,1,2,'ö') insert('ö',1,2,c1)
+ö ß
+select trim(c1 from 'ß'),trim('ß' from c1) from t1;
+trim(c1 from 'ß') trim('ß' from c1)
+
+select lpad(c1,3,'ö'), lpad('ö',3,c1) from t1;
+lpad(c1,3,'ö') lpad('ö',3,c1)
+ööß ßßö
+select rpad(c1,3,'ö'), rpad('ö',3,c1) from t1;
+rpad(c1,3,'ö') rpad('ö',3,c1)
+ßöö ößß
diff --git a/mysql-test/t/ctype_recoding.test b/mysql-test/t/ctype_recoding.test
index dab898e9f2c..0e5e954c720 100644
--- a/mysql-test/t/ctype_recoding.test
+++ b/mysql-test/t/ctype_recoding.test
@@ -153,3 +153,29 @@ select * from t1 where a=_latin1'
drop table t1;
set names latin1;
+#
+# Check more automatic conversion
+#
+set names koi8r;
+create table t1 (c1 char(10) character set cp1251);
+insert into t1 values ('ß');
+select c1 from t1 where c1 between 'ß' and 'ß';
+select ifnull(c1,'ß'), ifnull(null,c1) from t1;
+select if(1,c1,'ö'), if(0,c1,'ö') from t1;
+select coalesce('ö',c1), coalesce(null,c1) from t1;
+select least(c1,'ö'), greatest(c1,'ö') from t1;
+select locate(c1,'ß'), locate('ß',c1) from t1;
+select field(c1,'ß'),field('ß',c1) from t1;
+select concat(c1,'ö'), concat('ö',c1) from t1;
+select concat_ws(c1,'ö','ß'), concat_ws('ö',c1,'ß') from t1;
+select replace(c1,'ß','ö'), replace('ß',c1,'ö') from t1;
+select substring_index(c1,'öößß',2) from t1;
+select elt(1,c1,'ö'),elt(1,'ö',c1) from t1;
+select make_set(3,c1,'ö'), make_set(3,'ö',c1) from t1;
+select insert(c1,1,2,'ö'),insert('ö',1,2,c1) from t1;
+select trim(c1 from 'ß'),trim('ß' from c1) from t1;
+select lpad(c1,3,'ö'), lpad('ö',3,c1) from t1;
+select rpad(c1,3,'ö'), rpad('ö',3,c1) from t1;
+# TODO
+#select case c1 when 'ß' then 'ß' when 'ö' then 'ö' else 'c' end from t1;
+#select export_set(5,c1,'ö'), export_set(5,'ö',c1) from t1;
diff --git a/sql/item.cc b/sql/item.cc
index 46215fd78ed..7dc7e9e542c 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -205,6 +205,41 @@ bool Item::eq(const Item *item, bool binary_cmp) const
}
+Item *Item::safe_charset_converter(CHARSET_INFO *tocs)
+{
+ /*
+ Don't allow automatic conversion to non-Unicode charsets,
+ as it potentially loses data.
+ */
+ if (!(tocs->state & MY_CS_UNICODE))
+ return NULL; // safe conversion is not possible
+ return new Item_func_conv_charset(this, tocs);
+}
+
+
+Item *Item_string::safe_charset_converter(CHARSET_INFO *tocs)
+{
+ Item_string *conv;
+ uint conv_errors;
+ String tmp, cstr, *ostr= val_str(&tmp);
+ cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, &conv_errors);
+ if (conv_errors || !(conv= new Item_string(cstr.ptr(), cstr.length(),
+ cstr.charset(),
+ collation.derivation)))
+ {
+ /*
+ Safe conversion is not possible (or EOM).
+ We could not convert a string into the requested character set
+ without data loss. The target charset does not cover all the
+ characters from the string. Operation cannot be done correctly.
+ */
+ return NULL;
+ }
+ conv->str_value.copy();
+ return conv;
+}
+
+
bool Item_string::eq(const Item *item, bool binary_cmp) const
{
if (type() == item->type())
@@ -723,6 +758,12 @@ String *Item_null::val_str(String *str)
}
+Item *Item_null::safe_charset_converter(CHARSET_INFO *tocs)
+{
+ collation.set(tocs);
+ return this;
+}
+
/*********************** Item_param related ******************************/
/*
diff --git a/sql/item.h b/sql/item.h
index 2c0c3306c44..fea3aa010a8 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -39,13 +39,22 @@ enum Derivation
/*
Flags for collation aggregation modes:
- allow conversion to a superset
- allow conversion of a coercible value (i.e. constant).
+ MY_COLL_ALLOW_SUPERSET_CONV - allow conversion to a superset
+ MY_COLL_ALLOW_COERCIBLE_CONV - allow conversion of a coercible value
+ (i.e. constant).
+ MY_COLL_ALLOW_CONV - allow any kind of conversion
+ (combintion of the above two)
+ MY_COLL_DISALLOW_NONE - don't allow return DERIVATION_NONE
+ (e.g. when aggregating for comparison)
+ MY_COLL_CMP_CONV - combination of MY_COLL_ALLOW_CONV
+ and MY_COLL_DISALLOW_NONE
*/
#define MY_COLL_ALLOW_SUPERSET_CONV 1
#define MY_COLL_ALLOW_COERCIBLE_CONV 2
-
+#define MY_COLL_ALLOW_CONV 3
+#define MY_COLL_DISALLOW_NONE 4
+#define MY_COLL_CMP_CONV 7
class DTCollation {
public:
@@ -302,6 +311,7 @@ public:
Field *tmp_table_field_from_field_type(TABLE *table);
virtual Item *neg_transformer(THD *thd) { return NULL; }
+ virtual Item *safe_charset_converter(CHARSET_INFO *tocs);
void delete_self()
{
cleanup();
@@ -447,6 +457,7 @@ public:
Item *new_item() { return new Item_null(name); }
bool is_null() { return 1; }
void print(String *str) { str->append("NULL", 4); }
+ Item *safe_charset_converter(CHARSET_INFO *tocs);
};
@@ -717,6 +728,7 @@ public:
return new Item_string(name, str_value.ptr(),
str_value.length(), &my_charset_bin);
}
+ Item *safe_charset_converter(CHARSET_INFO *tocs);
String *const_string() { return &str_value; }
inline void append(char *str, uint length) { str_value.append(str, length); }
void print(String *str);
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index d9db07e2289..701894cacb5 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -173,89 +173,11 @@ void Item_bool_func2::fix_length_and_dec()
if (!args[0] || !args[1])
return;
- /*
- We allow to apply automatic character set conversion in some cases.
- The conditions when conversion is possible are:
- - arguments A and B have different charsets
- - A wins according to coercibility rules
- (i.e. a column is stronger than a string constant,
- an explicit COLLATE clause is stronger than a column)
- - character set of A is either superset for character set of B,
- or B is a string constant which can be converted into the
- character set of A without data loss.
-
- If all of the above is true, then it's possible to convert
- B into the character set of A, and then compare according
- to the collation of A.
- */
-
- uint32 dummy_offset;
DTCollation coll;
-
if (args[0]->result_type() == STRING_RESULT &&
args[1]->result_type() == STRING_RESULT &&
- String::needs_conversion(0, args[0]->collation.collation,
- args[1]->collation.collation,
- &dummy_offset) &&
- !coll.set(args[0]->collation, args[1]->collation,
- MY_COLL_ALLOW_SUPERSET_CONV |
- MY_COLL_ALLOW_COERCIBLE_CONV))
- {
- Item* conv= 0;
- Item_arena *arena= thd->current_arena, backup;
- uint strong= coll.strong;
- uint weak= strong ? 0 : 1;
- /*
- In case we're in statement prepare, create conversion item
- in its memory: it will be reused on each execute.
- */
- if (arena->is_stmt_prepare())
- thd->set_n_backup_item_arena(arena, &backup);
- if (args[weak]->type() == STRING_ITEM)
- {
- uint conv_errors;
- String tmp, cstr, *ostr= args[weak]->val_str(&tmp);
- cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(),
- args[strong]->collation.collation, &conv_errors);
- if (conv_errors)
- {
- /*
- We could not convert a string into the character set
- of the stronger side of the operation without data loss.
- It can happen if we tried to combine a column with a string
- constant, and the column charset does not cover all the
- characters from the string. Operation cannot be done
- correctly. Return an error.
- */
- my_coll_agg_error(args[0]->collation, args[1]->collation,
- func_name());
- return;
- }
- conv= new Item_string(cstr.ptr(),cstr.length(),cstr.charset(),
- args[weak]->collation.derivation);
- ((Item_string*)conv)->str_value.copy();
- }
- else
- {
- if (!(coll.collation->state & MY_CS_UNICODE))
- {
- /*
- Don't allow automatic conversion to non-Unicode charsets,
- as it potentially loses data.
- */
- my_coll_agg_error(args[0]->collation, args[1]->collation,
- func_name());
- return;
- }
- conv= new Item_func_conv_charset(args[weak],
- args[strong]->collation.collation);
- conv->collation.set(args[weak]->collation.derivation);
- conv->fix_fields(thd, 0, &conv);
- }
- if (arena->is_stmt_prepare())
- thd->restore_backup_item_arena(arena, &backup);
- args[weak]= conv ? conv : args[weak];
- }
+ agg_arg_charsets(coll, args, 2, MY_COLL_CMP_CONV))
+ return;
// Make a special case of compare with fields to get nicer DATE comparisons
@@ -871,7 +793,7 @@ void Item_func_between::fix_length_and_dec()
return;
agg_cmp_type(&cmp_type, args, 3);
if (cmp_type == STRING_RESULT &&
- agg_arg_collations_for_comparison(cmp_collation, args, 3))
+ agg_arg_charsets(cmp_collation, args, 3, MY_COLL_CMP_CONV))
return;
/*
@@ -987,7 +909,7 @@ Item_func_ifnull::fix_length_and_dec()
decimals=max(args[0]->decimals,args[1]->decimals);
agg_result_type(&cached_result_type, args, 2);
if (cached_result_type == STRING_RESULT)
- agg_arg_collations(collation, args, arg_count);
+ agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV);
else if (cached_result_type != REAL_RESULT)
decimals= 0;
@@ -1083,7 +1005,7 @@ Item_func_if::fix_length_and_dec()
agg_result_type(&cached_result_type, args+1, 2);
if (cached_result_type == STRING_RESULT)
{
- if (agg_arg_collations(collation, args+1, 2))
+ if (agg_arg_charsets(collation, args+1, 2, MY_COLL_ALLOW_CONV))
return;
}
else
@@ -1354,7 +1276,7 @@ void Item_func_case::fix_length_and_dec()
agg_result_type(&cached_result_type, agg, nagg);
if ((cached_result_type == STRING_RESULT) &&
- agg_arg_collations(collation, agg, nagg))
+ agg_arg_charsets(collation, agg, nagg, MY_COLL_ALLOW_CONV))
return;
@@ -1370,7 +1292,7 @@ void Item_func_case::fix_length_and_dec()
nagg++;
agg_cmp_type(&cmp_type, agg, nagg);
if ((cmp_type == STRING_RESULT) &&
- agg_arg_collations_for_comparison(cmp_collation, agg, nagg))
+ agg_arg_charsets(cmp_collation, agg, nagg, MY_COLL_CMP_CONV))
return;
}
@@ -1477,7 +1399,7 @@ void Item_func_coalesce::fix_length_and_dec()
set_if_bigger(decimals,args[i]->decimals);
}
if (cached_result_type == STRING_RESULT)
- agg_arg_collations(collation, args, arg_count);
+ agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV);
else if (cached_result_type != REAL_RESULT)
decimals= 0;
}
@@ -2423,7 +2345,7 @@ Item_func_regex::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
max_length= 1;
decimals= 0;
- if (agg_arg_collations(cmp_collation, args, 2))
+ if (agg_arg_charsets(cmp_collation, args, 2, MY_COLL_CMP_CONV))
return 1;
used_tables_cache=args[0]->used_tables() | args[1]->used_tables();
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 50843d3bf76..09d7e50eaa3 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -90,6 +90,12 @@ bool Item_func::agg_arg_collations(DTCollation &c, Item **av, uint count,
return TRUE;
}
}
+ if ((flags & MY_COLL_DISALLOW_NONE) &&
+ c.derivation == DERIVATION_NONE)
+ {
+ my_coll_agg_error(av, count, func_name());
+ return TRUE;
+ }
return FALSE;
}
@@ -98,15 +104,7 @@ bool Item_func::agg_arg_collations_for_comparison(DTCollation &c,
Item **av, uint count,
uint flags)
{
- if (agg_arg_collations(c, av, count, flags))
- return TRUE;
-
- if (c.derivation == DERIVATION_NONE)
- {
- my_coll_agg_error(av, count, func_name());
- return TRUE;
- }
- return FALSE;
+ return (agg_arg_collations(c, av, count, flags | MY_COLL_DISALLOW_NONE));
}
@@ -119,6 +117,89 @@ eval_const_cond(COND *cond)
}
+
+/*
+ Collect arguments' character sets together.
+ We allow to apply automatic character set conversion in some cases.
+ The conditions when conversion is possible are:
+ - arguments A and B have different charsets
+ - A wins according to coercibility rules
+ (i.e. a column is stronger than a string constant,
+ an explicit COLLATE clause is stronger than a column)
+ - character set of A is either superset for character set of B,
+ or B is a string constant which can be converted into the
+ character set of A without data loss.
+
+ If all of the above is true, then it's possible to convert
+ B into the character set of A, and then compare according
+ to the collation of A.
+
+ For functions with more than two arguments:
+
+ collect(A,B,C) ::= collect(collect(A,B),C)
+*/
+
+bool Item_func::agg_arg_charsets(DTCollation &coll,
+ Item **args, uint nargs, uint flags)
+{
+ Item **arg, **last, *safe_args[2];
+ if (agg_arg_collations(coll, args, nargs, flags))
+ return TRUE;
+
+ /*
+ For better error reporting: save the first and the second argument.
+ We need this only if the the number of args is 3 or 2:
+ - for a longer argument list, "Illegal mix of collations"
+ doesn't display each argument's characteristics.
+ - if nargs is 1, then this error cannot happen.
+ */
+ if (nargs >=2 && nargs <= 3)
+ {
+ safe_args[0]= args[0];
+ safe_args[1]= args[1];
+ }
+
+ THD *thd= current_thd;
+ Item_arena *arena= thd->current_arena, backup;
+ bool res= FALSE;
+ /*
+ In case we're in statement prepare, create conversion item
+ in its memory: it will be reused on each execute.
+ */
+ if (arena->is_stmt_prepare())
+ thd->set_n_backup_item_arena(arena, &backup);
+
+ for (arg= args, last= args + nargs; arg < last; arg++)
+ {
+ Item* conv;
+ uint dummy_offset;
+ if (!String::needs_conversion(0, coll.collation,
+ (*arg)->collation.collation,
+ &dummy_offset))
+ continue;
+
+ if (!(conv= (*arg)->safe_charset_converter(coll.collation)))
+ {
+ if (nargs >=2 && nargs <= 3)
+ {
+ /* restore the original arguments for better error message */
+ args[0]= safe_args[0];
+ args[1]= safe_args[1];
+ }
+ my_coll_agg_error(args, nargs, func_name());
+ res= TRUE;
+ break; // we cannot return here, we need to restore "arena".
+ }
+ conv->fix_fields(thd, 0, &conv);
+ *arg= conv;
+ }
+ if (arena->is_stmt_prepare())
+ thd->restore_backup_item_arena(arena, &backup);
+ return res;
+}
+
+
+
void Item_func::set_arguments(List- &list)
{
allowed_arg_cols= 1;
@@ -1105,7 +1186,7 @@ void Item_func_min_max::fix_length_and_dec()
cmp_type=item_cmp_type(cmp_type,args[i]->result_type());
}
if (cmp_type == STRING_RESULT)
- agg_arg_collations_for_comparison(collation, args, arg_count);
+ agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV);
}
@@ -1259,7 +1340,7 @@ longlong Item_func_coercibility::val_int()
void Item_func_locate::fix_length_and_dec()
{
maybe_null=0; max_length=11;
- agg_arg_collations_for_comparison(cmp_collation, args, 2);
+ agg_arg_charsets(cmp_collation, args, 2, MY_COLL_CMP_CONV);
}
@@ -1358,7 +1439,7 @@ void Item_func_field::fix_length_and_dec()
for (uint i=1; i < arg_count ; i++)
cmp_type= item_cmp_type(cmp_type, args[i]->result_type());
if (cmp_type == STRING_RESULT)
- agg_arg_collations_for_comparison(cmp_collation, args, arg_count);
+ agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV);
}
diff --git a/sql/item_func.h b/sql/item_func.h
index 963038227a2..ce2b34499d6 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -145,7 +145,8 @@ public:
bool agg_arg_collations_for_comparison(DTCollation &c,
Item **items, uint nitems,
uint flags= 0);
-
+ bool agg_arg_charsets(DTCollation &c, Item **items, uint nitems,
+ uint flags= 0);
bool walk(Item_processor processor, byte *arg);
};
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 5eda89ef21e..81fff899ec7 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -346,7 +346,7 @@ void Item_func_concat::fix_length_and_dec()
{
max_length=0;
- if (agg_arg_collations(collation, args, arg_count))
+ if (agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV))
return;
for (uint i=0 ; i < arg_count ; i++)
@@ -640,7 +640,7 @@ void Item_func_concat_ws::fix_length_and_dec()
{
max_length=0;
- if (agg_arg_collations(collation, args, arg_count))
+ if (agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV))
return;
/*
@@ -848,7 +848,7 @@ void Item_func_replace::fix_length_and_dec()
maybe_null=1;
}
- if (agg_arg_collations_for_comparison(collation, args, 3))
+ if (agg_arg_charsets(collation, args, 3, MY_COLL_CMP_CONV))
return;
}
@@ -893,11 +893,13 @@ null:
void Item_func_insert::fix_length_and_dec()
{
- if (collation.set(args[0]->collation, args[3]->collation))
- {
- my_coll_agg_error(args[0]->collation, args[3]->collation, func_name());
- return;
- }
+ Item *cargs[2];
+ cargs[0]= args[0];
+ cargs[1]= args[3];
+ if (agg_arg_charsets(collation, cargs, 2, MY_COLL_ALLOW_CONV))
+ return;
+ args[0]= cargs[0];
+ args[3]= cargs[1];
max_length=args[0]->max_length+args[3]->max_length;
if (max_length > MAX_BLOB_WIDTH)
{
@@ -1063,7 +1065,7 @@ void Item_func_substr_index::fix_length_and_dec()
{
max_length= args[0]->max_length;
- if (agg_arg_collations_for_comparison(collation, args, 2))
+ if (agg_arg_charsets(collation, args, 2, MY_COLL_CMP_CONV))
return;
}
@@ -1355,10 +1357,14 @@ void Item_func_trim::fix_length_and_dec()
remove.set_ascii(" ",1);
}
else
- if (collation.set(args[1]->collation, args[0]->collation) ||
- collation.derivation == DERIVATION_NONE)
{
- my_coll_agg_error(args[1]->collation, args[0]->collation, func_name());
+ Item *cargs[2];
+ cargs[0]= args[1];
+ cargs[1]= args[0];
+ if (agg_arg_charsets(collation, cargs, 2, MY_COLL_CMP_CONV))
+ return;
+ args[0]= cargs[1];
+ args[1]= cargs[0];
}
}
@@ -1679,7 +1685,7 @@ void Item_func_elt::fix_length_and_dec()
max_length=0;
decimals=0;
- if (agg_arg_collations(collation, args+1, arg_count-1))
+ if (agg_arg_charsets(collation, args+1, arg_count-1, MY_COLL_ALLOW_CONV))
return;
for (uint i= 1 ; i < arg_count ; i++)
@@ -1755,7 +1761,7 @@ void Item_func_make_set::fix_length_and_dec()
{
max_length=arg_count-1;
- if (agg_arg_collations(collation, args, arg_count))
+ if (agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV))
return;
for (uint i=0 ; i < arg_count ; i++)
@@ -1963,12 +1969,13 @@ err:
void Item_func_rpad::fix_length_and_dec()
{
- if (collation.set(args[0]->collation, args[2]->collation))
- {
- my_coll_agg_error(args[0]->collation, args[2]->collation, func_name());
+ Item *cargs[2];
+ cargs[0]= args[0];
+ cargs[1]= args[2];
+ if (agg_arg_charsets(collation, cargs, 2, MY_COLL_ALLOW_CONV))
return;
- }
-
+ args[0]= cargs[0];
+ args[2]= cargs[1];
if (args[1]->const_item())
{
uint32 length= (uint32) args[1]->val_int() * collation.collation->mbmaxlen;
@@ -2047,11 +2054,13 @@ String *Item_func_rpad::val_str(String *str)
void Item_func_lpad::fix_length_and_dec()
{
- if (collation.set(args[0]->collation, args[2]->collation))
- {
- my_coll_agg_error(args[0]->collation, args[2]->collation, func_name());
+ Item *cargs[2];
+ cargs[0]= args[0];
+ cargs[1]= args[2];
+ if (agg_arg_charsets(collation, cargs, 2, MY_COLL_ALLOW_CONV))
return;
- }
+ args[0]= cargs[0];
+ args[2]= cargs[1];
if (args[1]->const_item())
{
@@ -2495,7 +2504,8 @@ void Item_func_export_set::fix_length_and_dec()
uint sep_length=(arg_count > 3 ? args[3]->max_length : 1);
max_length=length*64+sep_length*63;
- if (agg_arg_collations(collation, args+1, min(4,arg_count)-1))
+ if (agg_arg_charsets(collation, args+1, min(4,arg_count)-1),
+ MY_COLL_ALLOW_CONV)
return;
}
From 6563fa1c8be4844f205b9cba2726927ac7abd844 Mon Sep 17 00:00:00 2001
From: "pekka@mysql.com" <>
Date: Tue, 2 Nov 2004 13:15:55 +0100
Subject: [PATCH 43/59] NDB fix blob parts distribution - backwards compatible
---
ndb/src/ndbapi/NdbBlob.cpp | 23 +++++++++++++----------
1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/ndb/src/ndbapi/NdbBlob.cpp b/ndb/src/ndbapi/NdbBlob.cpp
index 731f32ba916..9d21304939a 100644
--- a/ndb/src/ndbapi/NdbBlob.cpp
+++ b/ndb/src/ndbapi/NdbBlob.cpp
@@ -97,6 +97,14 @@ NdbBlob::getBlobTable(NdbTableImpl& bt, const NdbTableImpl* t, const NdbColumnIm
bt.setName(btname);
bt.setLogging(t->getLogging());
bt.setFragmentType(t->getFragmentType());
+ { NdbDictionary::Column bc("PK");
+ bc.setType(NdbDictionary::Column::Unsigned);
+ assert(t->m_sizeOfKeysInWords != 0);
+ bc.setLength(t->m_sizeOfKeysInWords);
+ bc.setPrimaryKey(true);
+ bc.setDistributionKey(true);
+ bt.addColumn(bc);
+ }
{ NdbDictionary::Column bc("DIST");
bc.setType(NdbDictionary::Column::Unsigned);
bc.setPrimaryKey(true);
@@ -106,13 +114,7 @@ NdbBlob::getBlobTable(NdbTableImpl& bt, const NdbTableImpl* t, const NdbColumnIm
{ NdbDictionary::Column bc("PART");
bc.setType(NdbDictionary::Column::Unsigned);
bc.setPrimaryKey(true);
- bt.addColumn(bc);
- }
- { NdbDictionary::Column bc("PK");
- bc.setType(NdbDictionary::Column::Unsigned);
- assert(t->m_sizeOfKeysInWords != 0);
- bc.setLength(t->m_sizeOfKeysInWords);
- bc.setPrimaryKey(true);
+ bc.setDistributionKey(false);
bt.addColumn(bc);
}
{ NdbDictionary::Column bc("DATA");
@@ -392,9 +394,10 @@ NdbBlob::setPartKeyValue(NdbOperation* anOp, Uint32 part)
Uint32* data = (Uint32*)theKeyBuf.data;
unsigned size = theTable->m_sizeOfKeysInWords;
DBG("setPartKeyValue dist=" << getDistKey(part) << " part=" << part << " key=" << ndb_blob_debug(data, size));
- if (anOp->equal((Uint32)0, getDistKey(part)) == -1 ||
- anOp->equal((Uint32)1, part) == -1 ||
- anOp->equal((Uint32)2, theKeyBuf.data) == -1) {
+ // TODO use attr ids after compatibility with 4.1.7 not needed
+ if (anOp->equal("PK", theKeyBuf.data) == -1 ||
+ anOp->equal("DIST", getDistKey(part)) == -1 ||
+ anOp->equal("PART", part) == -1) {
setErrorCode(anOp);
return -1;
}
From 8d34e2d45bec2583ad67cc6d6e76bcc85b4d8ba7 Mon Sep 17 00:00:00 2001
From: "joreland@mysql.com" <>
Date: Tue, 2 Nov 2004 13:58:22 +0100
Subject: [PATCH 44/59] build issue Fix so that signed/unsigned char does not
matter in comparision
---
ndb/src/ndbapi/NdbOperationExec.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/ndb/src/ndbapi/NdbOperationExec.cpp b/ndb/src/ndbapi/NdbOperationExec.cpp
index fa46e93a57f..6d7a3817e04 100644
--- a/ndb/src/ndbapi/NdbOperationExec.cpp
+++ b/ndb/src/ndbapi/NdbOperationExec.cpp
@@ -192,7 +192,7 @@ NdbOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransId)
OperationType tOperationType = theOperationType;
Uint32 tTupKeyLen = theTupKeyLen;
Uint8 abortOption =
- m_abortOption != -1 ? m_abortOption : theNdbCon->m_abortOption;
+ m_abortOption != (Int8)-1 ? m_abortOption : theNdbCon->m_abortOption;
tcKeyReq->setDirtyFlag(tReqInfo, tDirtyIndicator);
tcKeyReq->setOperationType(tReqInfo, tOperationType);
@@ -543,7 +543,7 @@ NdbOperation::receiveTCKEYREF( NdbApiSignal* aSignal)
}//if
AbortOption ao = (AbortOption)
- (m_abortOption != -1 ? m_abortOption : theNdbCon->m_abortOption);
+ (m_abortOption != (Int8)-1 ? m_abortOption : theNdbCon->m_abortOption);
theReceiver.m_received_result_length = ~0;
theStatus = Finished;
From 1b94652bded12ff0cc61638299c6c93cede24de1 Mon Sep 17 00:00:00 2001
From: "joerg@mysql.com" <>
Date: Tue, 2 Nov 2004 15:09:57 +0100
Subject: [PATCH 45/59] Test expansion: "MOD" on non-integral first operand.
---
mysql-test/r/ps_10nestset.result | 11 +++++++++++
mysql-test/t/ps_10nestset.test | 13 ++++++-------
2 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/mysql-test/r/ps_10nestset.result b/mysql-test/r/ps_10nestset.result
index 68f58a03674..ff63485a5f9 100644
--- a/mysql-test/r/ps_10nestset.result
+++ b/mysql-test/r/ps_10nestset.result
@@ -62,4 +62,15 @@ id emp salary l r
4 Donna 1064.80 5 6
5 Eddie 931.70 7 8
6 Fred 798.60 9 10
+prepare st_round from 'update t1 set salary = salary + ? - ( salary MOD ? )';
+set @arg_round= 50;
+execute st_round using @arg_round, @arg_round;
+select * from t1;
+id emp salary l r
+1 Jerry 1350.00 1 12
+2 Bert 1200.00 2 3
+3 Chuck 1250.00 4 11
+4 Donna 1100.00 5 6
+5 Eddie 950.00 7 8
+6 Fred 800.00 9 10
drop table t1;
diff --git a/mysql-test/t/ps_10nestset.test b/mysql-test/t/ps_10nestset.test
index d2adaca689e..53e84f7a47d 100644
--- a/mysql-test/t/ps_10nestset.test
+++ b/mysql-test/t/ps_10nestset.test
@@ -61,12 +61,11 @@ while ($1)
select * from t1;
-# Waiting for the resolution of bug#6138
-# # Now, increase salary to a multiple of 50
-# prepare st_round from 'update t1 set salary = salary + ? - ( salary MOD ? )';
-# set @arg_round= 50;
-# execute st_round using @arg_round, @arg_round;
-#
-# select * from t1;
+# Now, increase salary to a multiple of 50 (checks for bug#6138)
+prepare st_round from 'update t1 set salary = salary + ? - ( salary MOD ? )';
+set @arg_round= 50;
+execute st_round using @arg_round, @arg_round;
+
+select * from t1;
drop table t1;
From 86b33f360bd002ef4848de6666feacaae7f1d1dd Mon Sep 17 00:00:00 2001
From: "ram@gw.mysql.r18.ru" <>
Date: Tue, 2 Nov 2004 19:48:37 +0400
Subject: [PATCH 46/59] A fix (bug #6331: INSERT IGNORE .. SELECT breaks
subsequent inserts).
---
mysql-test/r/ndb_insert.result | 29 +++++++++++++++++++++++++++++
mysql-test/t/ndb_insert.test | 15 +++++++++++++++
sql/ha_ndbcluster.cc | 3 ++-
3 files changed, 46 insertions(+), 1 deletion(-)
diff --git a/mysql-test/r/ndb_insert.result b/mysql-test/r/ndb_insert.result
index cdc445558b9..16c76f39680 100644
--- a/mysql-test/r/ndb_insert.result
+++ b/mysql-test/r/ndb_insert.result
@@ -557,3 +557,32 @@ select * from t1 where pk1=1;
pk1 b c
1 2 3
DROP TABLE t1;
+CREATE TABLE t1(a INT) ENGINE=ndb;
+INSERT IGNORE INTO t1 VALUES (1);
+INSERT IGNORE INTO t1 VALUES (1);
+INSERT IGNORE INTO t1 SELECT a FROM t1;
+INSERT IGNORE INTO t1 SELECT a FROM t1;
+INSERT IGNORE INTO t1 SELECT a FROM t1;
+INSERT IGNORE INTO t1 VALUES (1);
+INSERT IGNORE INTO t1 VALUES (1);
+SELECT * FROM t1;
+a
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+DROP TABLE t1;
diff --git a/mysql-test/t/ndb_insert.test b/mysql-test/t/ndb_insert.test
index 310c16de3d8..c3da4641014 100644
--- a/mysql-test/t/ndb_insert.test
+++ b/mysql-test/t/ndb_insert.test
@@ -583,3 +583,18 @@ INSERT INTO t1 VALUES(1,1,1) ON DUPLICATE KEY UPDATE b=79;
select * from t1 where pk1=1;
DROP TABLE t1;
+
+#
+# Bug #6331: problem with 'insert ignore'
+#
+
+CREATE TABLE t1(a INT) ENGINE=ndb;
+INSERT IGNORE INTO t1 VALUES (1);
+INSERT IGNORE INTO t1 VALUES (1);
+INSERT IGNORE INTO t1 SELECT a FROM t1;
+INSERT IGNORE INTO t1 SELECT a FROM t1;
+INSERT IGNORE INTO t1 SELECT a FROM t1;
+INSERT IGNORE INTO t1 VALUES (1);
+INSERT IGNORE INTO t1 VALUES (1);
+SELECT * FROM t1;
+DROP TABLE t1;
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index 838cf69855a..4f0bd1f99ec 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -2650,7 +2650,8 @@ int ha_ndbcluster::extra(enum ha_extra_function operation)
m_use_write= TRUE;
} else
{
- m_ignore_dup_key_not_supported= TRUE;
+ if (table->keys)
+ m_ignore_dup_key_not_supported= TRUE;
}
break;
case HA_EXTRA_NO_IGNORE_DUP_KEY:
From 8b472a76059e7286a1fcf862b9d877bf13e6151b Mon Sep 17 00:00:00 2001
From: "rburnett@build.mysql.com" <>
Date: Tue, 2 Nov 2004 18:18:21 +0100
Subject: [PATCH 47/59] Bug# 5303 Windows --log-error option doesn't work
correctly
---
sql/mysqld.cc | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 7062334edbb..2159fd5e402 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -2918,11 +2918,10 @@ we force server id to 2, but this MySQL server will not act as a slave.");
exit(1);
#ifdef __WIN__
-#define MYSQL_ERR_FILE "mysql.err"
if (!opt_console)
{
- freopen(MYSQL_ERR_FILE,"a+",stdout);
- freopen(MYSQL_ERR_FILE,"a+",stderr);
+ freopen(log_error_file,"a+",stdout);
+ freopen(log_error_file,"a+",stderr);
FreeConsole(); // Remove window
}
#endif
From 2185f1a56c72a6bab11335277232ee87abdcaa54 Mon Sep 17 00:00:00 2001
From: "monty@mysql.com" <>
Date: Tue, 2 Nov 2004 20:13:27 +0200
Subject: [PATCH 48/59] Remove usage of !$ from mysql-tests Added
protocol::flush() for easier embedded-server code Increase block allocation
variables a bit as they where a bit too small for MySQL 4.1 Added option
--silent to client_test
---
client/mysqltest.c | 90 +--
include/mysql_com.h | 6 -
mysql-test/r/mysqltest.result | 7 -
mysql-test/t/client_test.test | 2 +-
mysql-test/t/comments.test | 3 +-
mysql-test/t/join_outer.test | 15 +-
mysql-test/t/key.test | 3 +-
mysql-test/t/mysqltest.test | 97 ++-
mysql-test/t/show_check.test | 3 +-
mysql-test/t/temp_table.test | 6 +-
mysql-test/t/type_ranges.test | 3 +-
sql/mysqld.cc | 4 +-
sql/net_serv.cc | 12 +-
sql/protocol.cc | 9 +
sql/protocol.h | 1 +
sql/sql_prepare.cc | 26 +-
sql/sql_show.cc | 6 +-
tests/client_test.c | 1105 ++++++++++++++++++++-------------
18 files changed, 836 insertions(+), 562 deletions(-)
diff --git a/client/mysqltest.c b/client/mysqltest.c
index 21f93b1fc6a..aef36823dfc 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -42,7 +42,7 @@
**********************************************************************/
-#define MTEST_VERSION "2.3"
+#define MTEST_VERSION "2.4"
#include
#include
@@ -243,8 +243,7 @@ VAR var_reg[10];
HASH var_hash;
my_bool disable_query_log=0, disable_result_log=0, disable_warnings=0;
my_bool disable_info= 1; /* By default off */
-/* default for disable_abort_on_error: false = abort on unmasked error */
-my_bool disable_abort_on_error= 0;
+my_bool abort_on_error= 1;
struct connection cons[MAX_CONS];
struct connection* cur_con, *next_con, *cons_end;
@@ -370,7 +369,7 @@ const char *command_names[]=
};
TYPELIB command_typelib= {array_elements(command_names),"",
- command_names};
+ command_names, 0};
DYNAMIC_STRING ds_res;
static void die(const char *fmt, ...);
@@ -744,7 +743,7 @@ err:
DBUG_RETURN(0);
}
-static VAR* var_obtain(char* name, int len)
+static VAR *var_obtain(const char* name, int len)
{
VAR* v;
if ((v = (VAR*)hash_search(&var_hash, name, len)))
@@ -754,28 +753,33 @@ static VAR* var_obtain(char* name, int len)
return v;
}
-int var_set(char* var_name, char* var_name_end, char* var_val,
- char* var_val_end)
+int var_set(const char *var_name, const char *var_name_end,
+ const char *var_val, const char *var_val_end)
{
int digit;
VAR* v;
+ DBUG_ENTER("var_set");
+ DBUG_PRINT("enter", ("var_name: '%.*s' = '%.*s' (length: %d)",
+ (int) (var_name_end - var_name), var_name,
+ (int) (var_val_end - var_val), var_val,
+ (int) (var_val_end - var_val)));
+
if (*var_name++ != '$')
- {
- --var_name;
- *var_name_end = 0;
- die("Variable name in %s does not start with '$'", var_name);
- }
+ {
+ var_name--;
+ die("Variable name in %s does not start with '$'", var_name);
+ }
digit = *var_name - '0';
if (!(digit < 10 && digit >= 0))
- {
- v = var_obtain(var_name, var_name_end - var_name);
- }
+ {
+ v = var_obtain(var_name, (uint) (var_name_end - var_name));
+ }
else
- v = var_reg + digit;
-
+ v = var_reg + digit;
return eval_expr(v, var_val, (const char**)&var_val_end);
}
+
int open_file(const char* name)
{
char buff[FN_REFLEN];
@@ -1244,18 +1248,22 @@ int do_let(struct st_query* q)
return var_set(var_name, var_name_end, var_val_start, q->end);
}
-/* Store an integer (typically the returncode of the last SQL) */
-/* statement in the mysqltest builtin variable $mysql_errno, by */
-/* simulating of a user statement "let $mysql_errno= " */
-int var_set_errno(int sql_errno )
+
+/*
+ Store an integer (typically the returncode of the last SQL)
+ statement in the mysqltest builtin variable $mysql_errno, by
+ simulating of a user statement "let $mysql_errno= "
+*/
+
+int var_set_errno(int sql_errno)
{
- char var_name[] = "$mysql_errno", var_val[30];
- sprintf(var_val, "%d", sql_errno);
- /* On some odd systems, the return value from sprintf() isn't */
- /* always the length of the string, so we use strlen() */
- return var_set(var_name, var_name + 12, var_val, var_val + strlen(var_val));
+ const char *var_name= "$mysql_errno";
+ char var_val[21];
+ uint length= my_sprintf(var_val, (var_val, "%d", sql_errno));
+ return var_set(var_name, var_name + 12, var_val, var_val + length);
}
+
int do_rpl_probe(struct st_query* q __attribute__((unused)))
{
DBUG_ENTER("do_rpl_probe");
@@ -1264,12 +1272,14 @@ int do_rpl_probe(struct st_query* q __attribute__((unused)))
DBUG_RETURN(0);
}
+
int do_enable_rpl_parse(struct st_query* q __attribute__((unused)))
{
mysql_enable_rpl_parse(&cur_con->mysql);
return 0;
}
+
int do_disable_rpl_parse(struct st_query* q __attribute__((unused)))
{
mysql_disable_rpl_parse(&cur_con->mysql);
@@ -2013,7 +2023,7 @@ int read_query(struct st_query** q_ptr)
memcpy((gptr) q->expected_errno, (gptr) global_expected_errno,
sizeof(global_expected_errno));
q->expected_errors= global_expected_errors;
- q->abort_on_error= (global_expected_errors == 0 && !disable_abort_on_error);
+ q->abort_on_error= (global_expected_errors == 0 && abort_on_error);
bzero((gptr) global_expected_errno, sizeof(global_expected_errno));
global_expected_errors=0;
if (p[0] == '-' && p[1] == '-')
@@ -2422,7 +2432,7 @@ static int run_query(MYSQL *mysql, struct st_query *q, int flags)
if (ps_protocol_enabled && disable_info &&
(flags & QUERY_SEND) && (flags & QUERY_REAP) && ps_match_re(q->query))
- return run_query_stmt (mysql, q, flags);
+ return run_query_stmt(mysql, q, flags);
return run_query_normal(mysql, q, flags);
}
@@ -2659,9 +2669,12 @@ end:
dynstr_free(&ds_tmp);
if (q->type == Q_EVAL)
dynstr_free(&eval_query);
- /* We save the return code (mysql_errno(mysql)) from the last call sent */
- /* to the server into the mysqltest builtin variable $mysql_errno. This */
- /* variable then can be used from the test case itself. */
+
+ /*
+ We save the return code (mysql_errno(mysql)) from the last call sent
+ to the server into the mysqltest builtin variable $mysql_errno. This
+ variable then can be used from the test case itself.
+ */
var_set_errno(mysql_errno(mysql));
DBUG_RETURN(error);
}
@@ -3012,6 +3025,7 @@ end:
dynstr_free(&ds_tmp);
if (q->type == Q_EVAL)
dynstr_free(&eval_query);
+ var_set_errno(mysql_stmt_errno(stmt));
mysql_stmt_close(stmt);
DBUG_RETURN(error);
}
@@ -3319,7 +3333,7 @@ static VAR* var_from_env(const char *name, const char *def_val)
if (!(tmp = getenv(name)))
tmp = def_val;
- v = var_init(0, name, 0, tmp, 0);
+ v = var_init(0, name, strlen(name), tmp, strlen(tmp));
my_hash_insert(&var_hash, (byte*)v);
return v;
}
@@ -3416,9 +3430,11 @@ int main(int argc, char **argv)
init_var_hash(&cur_con->mysql);
- /* Initialize $mysql_errno with -1, so we can */
- /* - distinguish it from valid values ( >= 0 ) and */
- /* - detect if there was never a command sent to the server */
+ /*
+ Initialize $mysql_errno with -1, so we can
+ - distinguish it from valid values ( >= 0 ) and
+ - detect if there was never a command sent to the server
+ */
var_set_errno(-1);
while (!read_query(&q))
@@ -3440,8 +3456,8 @@ int main(int argc, char **argv)
case Q_DISABLE_RPL_PARSE: do_disable_rpl_parse(q); break;
case Q_ENABLE_QUERY_LOG: disable_query_log=0; break;
case Q_DISABLE_QUERY_LOG: disable_query_log=1; break;
- case Q_ENABLE_ABORT_ON_ERROR: disable_abort_on_error=0; break;
- case Q_DISABLE_ABORT_ON_ERROR: disable_abort_on_error=1; break;
+ case Q_ENABLE_ABORT_ON_ERROR: abort_on_error=1; break;
+ case Q_DISABLE_ABORT_ON_ERROR: abort_on_error=0; break;
case Q_ENABLE_RESULT_LOG: disable_result_log=0; break;
case Q_DISABLE_RESULT_LOG: disable_result_log=1; break;
case Q_ENABLE_WARNINGS: disable_warnings=0; break;
diff --git a/include/mysql_com.h b/include/mysql_com.h
index 4686acc098f..6a6136bd974 100644
--- a/include/mysql_com.h
+++ b/include/mysql_com.h
@@ -282,13 +282,7 @@ void my_net_local_init(NET *net);
void net_end(NET *net);
void net_clear(NET *net);
my_bool net_realloc(NET *net, unsigned long length);
-
-#ifndef EMBEDDED_LIBRARY /* To be removed by HF */
my_bool net_flush(NET *net);
-#else
-#define net_flush(A)
-#endif
-
my_bool my_net_write(NET *net,const char *packet,unsigned long len);
my_bool net_write_command(NET *net,unsigned char command,
const char *header, unsigned long head_len,
diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result
index 5dc9ede1ca6..d75dbd5d00c 100644
--- a/mysql-test/r/mysqltest.result
+++ b/mysql-test/r/mysqltest.result
@@ -7,11 +7,6 @@ otto
select otto from (select 1 as otto) as t1;
otto
1
-select otto from (select 1 as otto) as t1;
-otto
-1
-select friedrich from (select 1 as otto) as t1;
-ERROR 42S22: Unknown column 'friedrich' in 'field list'
select friedrich from (select 1 as otto) as t1;
ERROR 42S22: Unknown column 'friedrich' in 'field list'
select otto from (select 1 as otto) as t1;
@@ -147,5 +142,3 @@ after_--enable_abort_on_error
1064
select 3 from t1 ;
ERROR 42S02: Table 'test.t1' doesn't exist
-select 3 from t1 ;
-ERROR 42S02: Table 'test.t1' doesn't exist
diff --git a/mysql-test/t/client_test.test b/mysql-test/t/client_test.test
index b56e8038d9b..830c5f1b8a2 100644
--- a/mysql-test/t/client_test.test
+++ b/mysql-test/t/client_test.test
@@ -1,2 +1,2 @@
--disable_result_log
---exec $TESTS_BINDIR/client_test --testcase --user=root --socket=$MASTER_MYSOCK --port=$MYSQL_TCP_PORT
+--exec $TESTS_BINDIR/client_test --testcase --user=root --socket=$MASTER_MYSOCK --port=$MYSQL_TCP_PORT --silent
diff --git a/mysql-test/t/comments.test b/mysql-test/t/comments.test
index 2fc6237907c..087df60f3f5 100644
--- a/mysql-test/t/comments.test
+++ b/mysql-test/t/comments.test
@@ -5,7 +5,8 @@
select 1+2/*hello*/+3;
select 1 /* long
multi line comment */;
-!$1065 ;
+--error 1065
+ ;
select 1 /*!32301 +1 */;
select 1 /*!52301 +1 */;
select 1--1;
diff --git a/mysql-test/t/join_outer.test b/mysql-test/t/join_outer.test
index 0c4c9614d88..bc96318ae2e 100644
--- a/mysql-test/t/join_outer.test
+++ b/mysql-test/t/join_outer.test
@@ -34,11 +34,14 @@ explain select t1.*,t2.* from t1 left join t2 on t1.a=t2.a where isnull(t2.a)=1;
select t1.*,t2.*,t3.a from t1 left join t2 on (t1.a=t2.a) left join t1 as t3 on (t2.a=t3.a);
# The next query should rearange the left joins to get this to work
-!$1120 explain select t1.*,t2.*,t3.a from t1 left join t2 on (t3.a=t2.a) left join t1 as t3 on (t1.a=t3.a);
-!$1120 select t1.*,t2.*,t3.a from t1 left join t2 on (t3.a=t2.a) left join t1 as t3 on (t1.a=t3.a);
+--error 1120
+explain select t1.*,t2.*,t3.a from t1 left join t2 on (t3.a=t2.a) left join t1 as t3 on (t1.a=t3.a);
+--error 1120
+select t1.*,t2.*,t3.a from t1 left join t2 on (t3.a=t2.a) left join t1 as t3 on (t1.a=t3.a);
# The next query should give an error in MySQL
-!$1120 select t1.*,t2.*,t3.a from t1 left join t2 on (t3.a=t2.a) left join t1 as t3 on (t2.a=t3.a);
+--error 1120
+select t1.*,t2.*,t3.a from t1 left join t2 on (t3.a=t2.a) left join t1 as t3 on (t2.a=t3.a);
# Test of inner join
select t1.*,t2.* from t1 inner join t2 using (a);
@@ -94,7 +97,8 @@ WHERE t1.uniq_id = 4
ORDER BY t2.c_amount;
INSERT INTO t2 VALUES (2,3,3000,6000,0,0,746584,837484,'yes');
-!$1062 INSERT INTO t2 VALUES (2,3,3000,6000,0,0,746584,837484,'yes');
+--error 1062
+INSERT INTO t2 VALUES (2,3,3000,6000,0,0,746584,837484,'yes');
INSERT INTO t2 VALUES (7,3,1000,2000,0,0,746294,937484,'yes');
#3rd select should show that one record is returned with null entries for the
@@ -288,7 +292,8 @@ insert into t3 values (1);
insert into t4 values (1,1);
insert into t5 values (1,1);
-!$1120 explain select * from t3 left join t4 on t4.seq_1_id = t2.t2_id left join t1 on t1.t1_id = t4.seq_0_id left join t5 on t5.seq_0_id = t1.t1_id left join t2 on t2.t2_id = t5.seq_1_id where t3.t3_id = 23;
+--error 1120
+explain select * from t3 left join t4 on t4.seq_1_id = t2.t2_id left join t1 on t1.t1_id = t4.seq_0_id left join t5 on t5.seq_0_id = t1.t1_id left join t2 on t2.t2_id = t5.seq_1_id where t3.t3_id = 23;
drop table t1,t2,t3,t4,t5;
diff --git a/mysql-test/t/key.test b/mysql-test/t/key.test
index 4be34cac30e..5ee2f68ab83 100644
--- a/mysql-test/t/key.test
+++ b/mysql-test/t/key.test
@@ -146,7 +146,8 @@ create table t1
);
INSERT INTO t1 VALUES (1, 1, 1, 1, 'a');
INSERT INTO t1 VALUES (1, 1, 1, 1, 'b');
-!$1062 INSERT INTO t1 VALUES (1, 1, 1, 1, 'a');
+--error 1062
+INSERT INTO t1 VALUES (1, 1, 1, 1, 'a');
drop table t1;
#
diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test
index b7007e1a519..0802c18ed6c 100644
--- a/mysql-test/t/mysqltest.test
+++ b/mysql-test/t/mysqltest.test
@@ -20,12 +20,10 @@ eval select $mysql_errno as "before_use_test" ;
select otto from (select 1 as otto) as t1;
# expectation = response
-!$0 select otto from (select 1 as otto) as t1;
--error 0
select otto from (select 1 as otto) as t1;
# expectation <> response
--- // !$1054 select otto from (select 1 as otto) as t1;
-- // --error 1054
-- // select otto from (select 1 as otto) as t1;
@@ -38,12 +36,10 @@ select otto from (select 1 as otto) as t1;
# ----------------------------------------------------------------------------
# expectation <> response
-#!$0 select friedrich from (select 1 as otto) as t1;
#--error 0
#select friedrich from (select 1 as otto) as t1;
# expectation = response
-!$1054 select friedrich from (select 1 as otto) as t1;
--error 1054
select friedrich from (select 1 as otto) as t1;
@@ -94,130 +90,130 @@ select friedrich from (select 1 as otto) as t1;
#
# The following test cases often initialize $mysql_errno to 1064 by
# a command with wrong syntax.
-# Example: !$1064 To prevent the abort after the error.
+# Example: --error 1064 To prevent the abort after the error.
# garbage ;
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
-# 1. check mysql_errno = 0 after successful statement
+# check mysql_errno = 0 after successful statement
# ----------------------------------------------------------------------------
select otto from (select 1 as otto) as t1;
eval select $mysql_errno as "after_successful_stmt_errno" ;
#----------------------------------------------------------------------------
-# 2. check mysql_errno = 1064 after statement with wrong syntax
+# check mysql_errno = 1064 after statement with wrong syntax
# ----------------------------------------------------------------------------
-!$1064
+--error 1064
garbage ;
eval select $mysql_errno as "after_wrong_syntax_errno" ;
# ----------------------------------------------------------------------------
-# 3. check if let $my_var= 'abc' ; affects $mysql_errno
+# check if let $my_var= 'abc' ; affects $mysql_errno
# ----------------------------------------------------------------------------
-!$1064
+--error 1064
garbage ;
let $my_var= 'abc' ;
eval select $mysql_errno as "after_let_var_equal_value" ;
# ----------------------------------------------------------------------------
-# 4. check if set @my_var= 'abc' ; affects $mysql_errno
+# check if set @my_var= 'abc' ; affects $mysql_errno
# ----------------------------------------------------------------------------
-!$1064
+--error 1064
garbage ;
set @my_var= 'abc' ;
eval select $mysql_errno as "after_set_var_equal_value" ;
# ----------------------------------------------------------------------------
-# 5. check if the setting of --disable-warnings itself affects $mysql_errno
-# (May be -- modifies $mysql_errno.)
+# check if the setting of --disable-warnings itself affects $mysql_errno
+# (May be -- modifies $mysql_errno.)
# ----------------------------------------------------------------------------
-!$1064
+--error 1064
garbage ;
--disable_warnings
eval select $mysql_errno as "after_disable_warnings_command" ;
# ----------------------------------------------------------------------------
-# 6. check if --disable-warnings + command with warning affects the errno
-# stored within $mysql_errno
-# (May be disabled warnings affect $mysql_errno.)
+# check if --disable-warnings + command with warning affects the errno
+# stored within $mysql_errno
+# (May be disabled warnings affect $mysql_errno.)
# ----------------------------------------------------------------------------
drop table if exists t1 ;
-!$1064
+--error 1064
garbage ;
drop table if exists t1 ;
eval select $mysql_errno as "after_disable_warnings" ;
--enable_warnings
# ----------------------------------------------------------------------------
-# 7. check if masked errors affect $mysql_errno
+# check if masked errors affect $mysql_errno
# ----------------------------------------------------------------------------
-!$1064
+--error 1064
garbage ;
--error 1146
select 3 from t1 ;
eval select $mysql_errno as "after_minus_masked" ;
-!$1064
+--error 1064
garbage ;
-!$1146
+--error 1146
select 3 from t1 ;
eval select $mysql_errno as "after_!_masked" ;
# ----------------------------------------------------------------------------
-# 8. Will manipulations of $mysql_errno be possible and visible ?
+# Will manipulations of $mysql_errno be possible and visible ?
# ----------------------------------------------------------------------------
-!$1064
+--error 1064
garbage ;
let $mysql_errno= -1;
eval select $mysql_errno as "after_let_errno_equal_value" ;
# ----------------------------------------------------------------------------
-# 9. How affect actions on prepared statements $mysql_errno ?
+# How affect actions on prepared statements $mysql_errno ?
# ----------------------------------------------------------------------------
# failing prepare
-!$1064
+--error 1064
garbage ;
-!$1146
+--error 1146
prepare stmt from "select 3 from t1" ;
eval select $mysql_errno as "after_failing_prepare" ;
create table t1 ( f1 char(10));
# successful prepare
-!$1064
+--error 1064
garbage ;
prepare stmt from "select 3 from t1" ;
eval select $mysql_errno as "after_successful_prepare" ;
# successful execute
-!$1064
+--error 1064
garbage ;
execute stmt;
eval select $mysql_errno as "after_successful_execute" ;
# failing execute (table dropped)
drop table t1;
-!$1064
+--error 1064
garbage ;
-!$1146
+--error 1146
execute stmt;
eval select $mysql_errno as "after_failing_execute" ;
# failing execute (unknown statement)
-!$1064
+--error 1064
garbage ;
-!$1243
+--error 1243
execute __stmt_;
eval select $mysql_errno as "after_failing_execute" ;
# successful deallocate
-!$1064
+--error 1064
garbage ;
deallocate prepare stmt;
eval select $mysql_errno as "after_successful_deallocate" ;
# failing deallocate ( statement handle does not exist )
-!$1064
+--error 1064
garbage ;
-!$1243
+--error 1243
deallocate prepare __stmt_;
eval select $mysql_errno as "after_failing_deallocate" ;
@@ -231,7 +227,7 @@ eval select $mysql_errno as "after_failing_deallocate" ;
# The default is "--enable_abort_on_error".
#
# "Maskings" are
-# !$ and --error
+# --error and --error
# in the line before the failing statement.
#
# There are some additional test case for $mysql_errno
@@ -240,58 +236,53 @@ eval select $mysql_errno as "after_failing_deallocate" ;
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
-# 1. Switch the abort on error off and check the effect on $mysql_errno
+# Switch the abort on error off and check the effect on $mysql_errno
# ----------------------------------------------------------------------------
-!$1064
+--error 1064
garbage ;
--disable_abort_on_error
eval select $mysql_errno as "after_--disable_abort_on_error" ;
# ----------------------------------------------------------------------------
-# 2. "unmasked" failing statement should not cause an abort
+# "unmasked" failing statement should not cause an abort
# ----------------------------------------------------------------------------
select 3 from t1 ;
# ----------------------------------------------------------------------------
-# 3. masked failing statements
+# masked failing statements
# ----------------------------------------------------------------------------
# expected error = response
--error 1146
select 3 from t1 ;
-!$1146
+--error 1146
select 3 from t1 ;
eval select $mysql_errno as "after_!errno_masked_error" ;
# expected error <> response
# --error 1000
# select 3 from t1 ;
-# !$1000
+# --error 1000
# select 3 from t1 ;
# ----------------------------------------------------------------------------
-# 4. Switch the abort on error on and check the effect on $mysql_errno
+# Switch the abort on error on and check the effect on $mysql_errno
# ----------------------------------------------------------------------------
-!$1064
+--error 1064
garbage ;
--enable_abort_on_error
eval select $mysql_errno as "after_--enable_abort_on_error" ;
# ----------------------------------------------------------------------------
-# 5. masked failing statements
+# masked failing statements
# ----------------------------------------------------------------------------
# expected error = response
--error 1146
select 3 from t1 ;
-!$1146
-select 3 from t1 ;
# ----------------------------------------------------------------------------
-# 6. check that the old default behaviour is not changed
+# check that the old default behaviour is not changed
# Please remove the '#' to get the abort on error
# ----------------------------------------------------------------------------
#--error 1064
#select 3 from t1 ;
#
-#!$1064
-#select 3 from t1 ;
-#
#select 3 from t1 ;
diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test
index 681127eab5e..efbe2e9371d 100644
--- a/mysql-test/t/show_check.test
+++ b/mysql-test/t/show_check.test
@@ -21,7 +21,8 @@ check table t1 changed;
check table t1 medium;
check table t1 extended;
show index from t1;
-!$1062 insert into t1 values (5,5,5);
+--error 1062
+insert into t1 values (5,5,5);
optimize table t1;
optimize table t1;
drop table t1;
diff --git a/mysql-test/t/temp_table.test b/mysql-test/t/temp_table.test
index 2181d3eb74c..74276c7668c 100644
--- a/mysql-test/t/temp_table.test
+++ b/mysql-test/t/temp_table.test
@@ -20,8 +20,10 @@ create TEMPORARY TABLE t2 engine=heap select * from t1;
create TEMPORARY TABLE IF NOT EXISTS t2 (a int) engine=heap;
# This should give errors
-!$1050 CREATE TEMPORARY TABLE t1 (a int not null, b char (10) not null);
-!$1050 ALTER TABLE t1 RENAME t2;
+--error 1050
+CREATE TEMPORARY TABLE t1 (a int not null, b char (10) not null);
+--error 1050
+ALTER TABLE t1 RENAME t2;
select * from t2;
alter table t2 add primary key (a,b);
diff --git a/mysql-test/t/type_ranges.test b/mysql-test/t/type_ranges.test
index 09b5867e7a8..572dc0af313 100644
--- a/mysql-test/t/type_ranges.test
+++ b/mysql-test/t/type_ranges.test
@@ -135,7 +135,8 @@ drop table t1,t2;
create table t1 (c int);
insert into t1 values(1),(2);
create table t2 select * from t1;
-!$1060 create table t3 select * from t1, t2; # Should give an error
+--error 1060
+create table t3 select * from t1, t2; # Should give an error
create table t3 select t1.c AS c1, t2.c AS c2,1 as "const" from t1, t2;
show full columns from t3;
drop table t1,t2,t3;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 7062334edbb..d06aba3387e 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -5026,12 +5026,12 @@ The minimum value for this variable is 4096.",
"Persistent buffer for query parsing and execution",
(gptr*) &global_system_variables.query_prealloc_size,
(gptr*) &max_system_variables.query_prealloc_size, 0, GET_ULONG,
- REQUIRED_ARG, QUERY_ALLOC_PREALLOC_SIZE, 1024, ~0L, 0, 1024, 0},
+ REQUIRED_ARG, QUERY_ALLOC_PREALLOC_SIZE, 16384, ~0L, 0, 1024, 0},
{"range_alloc_block_size", OPT_RANGE_ALLOC_BLOCK_SIZE,
"Allocation block size for storing ranges during optimization",
(gptr*) &global_system_variables.range_alloc_block_size,
(gptr*) &max_system_variables.range_alloc_block_size, 0, GET_ULONG,
- REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, 1024, ~0L, 0, 1024, 0},
+ REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, 4096, ~0L, 0, 1024, 0},
{"read_buffer_size", OPT_RECORD_BUFFER,
"Each thread that does a sequential scan allocates a buffer of this size for each table it scans. If you do many sequential scans, you may want to increase this value.",
(gptr*) &global_system_variables.read_buff_size,
diff --git a/sql/net_serv.cc b/sql/net_serv.cc
index 457b2052a45..5985cf63ed6 100644
--- a/sql/net_serv.cc
+++ b/sql/net_serv.cc
@@ -53,19 +53,9 @@
#include
#ifdef EMBEDDED_LIBRARY
-
#undef MYSQL_SERVER
-
-#ifndef MYSQL_CLIENT
+#undef MYSQL_CLIENT
#define MYSQL_CLIENT
-#endif
-
-#undef net_flush
-
-extern "C" {
-my_bool net_flush(NET *net);
-}
-
#endif /*EMBEDDED_LIBRARY */
diff --git a/sql/protocol.cc b/sql/protocol.cc
index 598d102ec29..eaa0fd55b25 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -470,6 +470,15 @@ void Protocol::init(THD *thd_arg)
}
+bool Protocol::flush()
+{
+#ifndef EMBEDDED_LIBRARY
+ return net_flush(&thd->net);
+#else
+ return 0;
+#endif
+}
+
/*
Send name and type of result to client.
diff --git a/sql/protocol.h b/sql/protocol.h
index d7ce5425ad1..a3b6da55da3 100644
--- a/sql/protocol.h
+++ b/sql/protocol.h
@@ -75,6 +75,7 @@ public:
field_count=item_list->elements;
return 0;
}
+ virtual bool flush();
virtual void prepare_for_resend()=0;
virtual bool store_null()=0;
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index b5e12c4d208..4ae69e40342 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -153,6 +153,8 @@ static bool send_prep_stmt(Prepared_statement *stmt, uint columns)
{
NET *net= &stmt->thd->net;
char buff[9];
+ DBUG_ENTER("send_prep_stmt");
+
buff[0]= 0; /* OK packet indicator */
int4store(buff+1, stmt->id);
int2store(buff+5, columns);
@@ -161,12 +163,11 @@ static bool send_prep_stmt(Prepared_statement *stmt, uint columns)
Send types and names of placeholders to the client
XXX: fix this nasty upcast from List to List
-
*/
- return my_net_write(net, buff, sizeof(buff)) ||
- (stmt->param_count &&
- stmt->thd->protocol_simple.send_fields((List
- *)
- &stmt->lex->param_list, 0)) ||
- net_flush(net);
- return 0;
+ DBUG_RETURN(my_net_write(net, buff, sizeof(buff)) ||
+ (stmt->param_count &&
+ stmt->thd->protocol_simple.send_fields((List
- *)
+ &stmt->lex->param_list,
+ 0)));
}
#else
static bool send_prep_stmt(Prepared_statement *stmt,
@@ -1088,7 +1089,7 @@ static int mysql_test_select(Prepared_statement *stmt,
{
if (lex->describe)
{
- if (send_prep_stmt(stmt, 0))
+ if (send_prep_stmt(stmt, 0) || thd->protocol->flush())
goto err_prep;
}
else
@@ -1106,11 +1107,8 @@ static int mysql_test_select(Prepared_statement *stmt,
prepared in unit->prepare call above.
*/
if (send_prep_stmt(stmt, lex->result->field_count(fields)) ||
- lex->result->send_fields(fields, 0)
-#ifndef EMBEDDED_LIBRARY
- || net_flush(&thd->net)
-#endif
- )
+ lex->result->send_fields(fields, 0) ||
+ thd->protocol->flush())
goto err_prep;
}
}
@@ -1389,7 +1387,6 @@ static int send_prepare_results(Prepared_statement *stmt, bool text_protocol)
enum enum_sql_command sql_command= lex->sql_command;
int res= 0;
DBUG_ENTER("send_prepare_results");
-
DBUG_PRINT("enter",("command: %d, param_count: %ld",
sql_command, stmt->param_count));
@@ -1475,7 +1472,8 @@ static int send_prepare_results(Prepared_statement *stmt, bool text_protocol)
goto error;
}
if (res == 0)
- DBUG_RETURN(text_protocol? 0 : send_prep_stmt(stmt, 0));
+ DBUG_RETURN(text_protocol? 0 : (send_prep_stmt(stmt, 0) ||
+ thd->protocol->flush()));
error:
if (res < 0)
send_error(thd, thd->killed ? ER_SERVER_SHUTDOWN : 0);
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 2af4cb3fc23..bda490e2916 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1081,7 +1081,7 @@ mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild)
restore_record(table,default_values); // Get empty record
if (thd->protocol->send_fields(&field_list,2))
DBUG_VOID_RETURN;
- net_flush(&thd->net);
+ thd->protocol->flush();
DBUG_VOID_RETURN;
}
@@ -1098,13 +1098,11 @@ mysqld_dump_create_info(THD *thd, TABLE *table, int fd)
if (store_create_info(thd, table, packet))
DBUG_RETURN(-1);
- //if (protocol->convert)
- // protocol->convert->convert((char*) packet->ptr(), packet->length());
if (fd < 0)
{
if (protocol->write())
DBUG_RETURN(-1);
- net_flush(&thd->net);
+ protocol->flush();
}
else
{
diff --git a/tests/client_test.c b/tests/client_test.c
index 48676ae7e12..70e1b26aeaa 100644
--- a/tests/client_test.c
+++ b/tests/client_test.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 MySQL AB
+/* Copyright (C) 2003-2004 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
@@ -27,6 +27,7 @@
#include
#include
+#define VER "2.0"
#define MAX_TEST_QUERY_LENGTH 300 /* MAX QUERY BUFFER LENGTH */
/* set default options */
@@ -37,7 +38,7 @@ static char *opt_password= 0;
static char *opt_host= 0;
static char *opt_unix_socket= 0;
static unsigned int opt_port;
-static my_bool tty_password= 0;
+static my_bool tty_password= 0, opt_silent= 0;
static MYSQL *mysql= 0;
static char query[MAX_TEST_QUERY_LENGTH];
@@ -52,6 +53,7 @@ static double total_time;
const char *default_dbug_option= "d:t:o,/tmp/client_test.trace";
#define myheader(str) \
+if (opt_silent < 2) \
{ \
fprintf(stdout, "\n\n#####################################\n"); \
fprintf(stdout, "%d of (%d/%d): %s", test_count++, iter_count, \
@@ -59,6 +61,7 @@ const char *default_dbug_option= "d:t:o,/tmp/client_test.trace";
fprintf(stdout, " \n#####################################\n"); \
}
#define myheader_r(str) \
+if (!opt_silent) \
{ \
fprintf(stdout, "\n\n#####################################\n"); \
fprintf(stdout, "%s", str); \
@@ -144,32 +147,39 @@ DIE_UNLESS(stmt == 0);\
static void print_error(const char *msg)
{
- if (mysql && mysql_errno(mysql))
+ if (!opt_silent)
{
- if (mysql->server_version)
- fprintf(stdout, "\n [MySQL-%s]", mysql->server_version);
- else
- fprintf(stdout, "\n [MySQL]");
- fprintf(stdout, "[%d] %s\n", mysql_errno(mysql), mysql_error(mysql));
+ if (mysql && mysql_errno(mysql))
+ {
+ if (mysql->server_version)
+ fprintf(stdout, "\n [MySQL-%s]", mysql->server_version);
+ else
+ fprintf(stdout, "\n [MySQL]");
+ fprintf(stdout, "[%d] %s\n", mysql_errno(mysql), mysql_error(mysql));
+ }
+ else if (msg)
+ fprintf(stderr, " [MySQL] %s\n", msg);
}
- else if (msg) fprintf(stderr, " [MySQL] %s\n", msg);
}
static void print_st_error(MYSQL_STMT *stmt, const char *msg)
{
- if (stmt && mysql_stmt_errno(stmt))
+ if (!opt_silent)
{
- if (stmt->mysql && stmt->mysql->server_version)
- fprintf(stdout, "\n [MySQL-%s]", stmt->mysql->server_version);
- else
- fprintf(stdout, "\n [MySQL]");
+ if (stmt && mysql_stmt_errno(stmt))
+ {
+ if (stmt->mysql && stmt->mysql->server_version)
+ fprintf(stdout, "\n [MySQL-%s]", stmt->mysql->server_version);
+ else
+ fprintf(stdout, "\n [MySQL]");
- fprintf(stdout, "[%d] %s\n", mysql_stmt_errno(stmt),
- mysql_stmt_error(stmt));
+ fprintf(stdout, "[%d] %s\n", mysql_stmt_errno(stmt),
+ mysql_stmt_error(stmt));
+ }
+ else if (msg)
+ fprintf(stderr, " [MySQL] %s\n", msg);
}
- else if (msg)
- fprintf(stderr, " [MySQL] %s\n", msg);
}
@@ -198,8 +208,9 @@ static void client_connect()
int rc;
myheader_r("client_connect");
- fprintf(stdout, "\n Establishing a connection to '%s' ...",
- opt_host ? opt_host : "");
+ if (!opt_silent)
+ fprintf(stdout, "\n Establishing a connection to '%s' ...",
+ opt_host ? opt_host : "");
if (!(mysql= mysql_init(NULL)))
{
@@ -217,12 +228,14 @@ static void client_connect()
exit(1);
}
- fprintf(stdout, " OK");
+ if (!opt_silent)
+ fprintf(stdout, " OK");
/* set AUTOCOMMIT to ON*/
mysql_autocommit(mysql, TRUE);
- fprintf(stdout, "\n Creating a test database '%s' ...", current_db);
+ if (!opt_silent)
+ fprintf(stdout, "\n Creating a test database '%s' ...", current_db);
strxmov(query, "CREATE DATABASE IF NOT EXISTS ", current_db, NullS);
rc= mysql_query(mysql, query);
@@ -232,7 +245,8 @@ static void client_connect()
rc= mysql_query(mysql, query);
myquery(rc);
- fprintf(stdout, " OK");
+ if (!opt_silent)
+ fprintf(stdout, " OK");
}
@@ -244,13 +258,16 @@ static void client_disconnect()
if (mysql)
{
- fprintf(stdout, "\n dropping the test database '%s' ...", current_db);
+ if (!opt_silent)
+ fprintf(stdout, "\n dropping the test database '%s' ...", current_db);
strxmov(query, "DROP DATABASE IF EXISTS ", current_db, NullS);
mysql_query(mysql, query);
- fprintf(stdout, " OK");
+ if (!opt_silent)
+ fprintf(stdout, " OK");
- fprintf(stdout, "\n closing the connection ...");
+ if (!opt_silent)
+ fprintf(stdout, "\n closing the connection ...");
mysql_close(mysql);
fprintf(stdout, " OK\n");
}
@@ -331,8 +348,11 @@ static void my_print_result_metadata(MYSQL_RES *result)
unsigned int field_count;
mysql_field_seek(result, 0);
- fputc('\n', stdout);
- fputc('\n', stdout);
+ if (!opt_silent)
+ {
+ fputc('\n', stdout);
+ fputc('\n', stdout);
+ }
field_count= mysql_num_fields(result);
for(i= 0; i< field_count; i++)
@@ -345,18 +365,25 @@ static void my_print_result_metadata(MYSQL_RES *result)
j= 4;
field->max_length= j;
}
- my_print_dashes(result);
- fputc('\t', stdout);
- fputc('|', stdout);
+ if (!opt_silent)
+ {
+ my_print_dashes(result);
+ fputc('\t', stdout);
+ fputc('|', stdout);
+ }
mysql_field_seek(result, 0);
for(i= 0; i< field_count; i++)
{
field= mysql_fetch_field(result);
- fprintf(stdout, " %-*s |", (int) field->max_length, field->name);
+ if (!opt_silent)
+ fprintf(stdout, " %-*s |", (int) field->max_length, field->name);
+ }
+ if (!opt_silent)
+ {
+ fputc('\n', stdout);
+ my_print_dashes(result);
}
- fputc('\n', stdout);
- my_print_dashes(result);
}
@@ -377,31 +404,43 @@ int my_process_result_set(MYSQL_RES *result)
while ((row= mysql_fetch_row(result)) != NULL)
{
mysql_field_seek(result, 0);
- fputc('\t', stdout);
- fputc('|', stdout);
+ if (!opt_silent)
+ {
+ fputc('\t', stdout);
+ fputc('|', stdout);
+ }
for(i= 0; i< mysql_num_fields(result); i++)
{
field= mysql_fetch_field(result);
- if (row[i] == NULL)
- fprintf(stdout, " %-*s |", (int) field->max_length, "NULL");
- else if (IS_NUM(field->type))
- fprintf(stdout, " %*s |", (int) field->max_length, row[i]);
- else
- fprintf(stdout, " %-*s |", (int) field->max_length, row[i]);
+ if (!opt_silent)
+ {
+ if (row[i] == NULL)
+ fprintf(stdout, " %-*s |", (int) field->max_length, "NULL");
+ else if (IS_NUM(field->type))
+ fprintf(stdout, " %*s |", (int) field->max_length, row[i]);
+ else
+ fprintf(stdout, " %-*s |", (int) field->max_length, row[i]);
+ }
+ }
+ if (!opt_silent)
+ {
+ fputc('\t', stdout);
+ fputc('\n', stdout);
}
- fputc('\t', stdout);
- fputc('\n', stdout);
row_count++;
}
- if (row_count)
- my_print_dashes(result);
+ if (!opt_silent)
+ {
+ if (row_count)
+ my_print_dashes(result);
- if (mysql_errno(mysql) != 0)
- fprintf(stderr, "\n\tmysql_fetch_row() failed\n");
- else
- fprintf(stdout, "\n\t%d %s returned\n", row_count,
- row_count == 1 ? "row" : "rows");
+ if (mysql_errno(mysql) != 0)
+ fprintf(stderr, "\n\tmysql_fetch_row() failed\n");
+ else
+ fprintf(stdout, "\n\t%d %s returned\n", row_count,
+ row_count == 1 ? "row" : "rows");
+ }
return row_count;
}
@@ -470,34 +509,44 @@ int my_process_stmt_result(MYSQL_STMT *stmt)
mysql_field_seek(result, 0);
while (mysql_stmt_fetch(stmt) == 0)
{
- fputc('\t', stdout);
- fputc('|', stdout);
-
+ if (!opt_silent)
+ {
+ fputc('\t', stdout);
+ fputc('|', stdout);
+ }
mysql_field_seek(result, 0);
for (i= 0; i < field_count; i++)
{
field= mysql_fetch_field(result);
- if (is_null[i])
- fprintf(stdout, " %-*s |", (int) field->max_length, "NULL");
- else if (length[i] == 0)
+ if (!opt_silent)
{
- data[i][0]= '\0'; /* unmodified buffer */
- fprintf(stdout, " %*s |", (int) field->max_length, data[i]);
+ if (is_null[i])
+ fprintf(stdout, " %-*s |", (int) field->max_length, "NULL");
+ else if (length[i] == 0)
+ {
+ data[i][0]= '\0'; /* unmodified buffer */
+ fprintf(stdout, " %*s |", (int) field->max_length, data[i]);
+ }
+ else if (IS_NUM(field->type))
+ fprintf(stdout, " %*s |", (int) field->max_length, data[i]);
+ else
+ fprintf(stdout, " %-*s |", (int) field->max_length, data[i]);
}
- else if (IS_NUM(field->type))
- fprintf(stdout, " %*s |", (int) field->max_length, data[i]);
- else
- fprintf(stdout, " %-*s |", (int) field->max_length, data[i]);
}
- fputc('\t', stdout);
- fputc('\n', stdout);
+ if (!opt_silent)
+ {
+ fputc('\t', stdout);
+ fputc('\n', stdout);
+ }
row_count++;
}
- if (row_count)
- my_print_dashes(result);
-
- fprintf(stdout, "\n\t%d %s returned\n", row_count,
- row_count == 1 ? "row" : "rows");
+ if (!opt_silent)
+ {
+ if (row_count)
+ my_print_dashes(result);
+ fprintf(stdout, "\n\t%d %s returned\n", row_count,
+ row_count == 1 ? "row" : "rows");
+ }
mysql_free_result(result);
return row_count;
}
@@ -511,7 +560,8 @@ int my_stmt_result(const char *buff)
int row_count;
int rc;
- fprintf(stdout, "\n\n %s", buff);
+ if (!opt_silent)
+ fprintf(stdout, "\n\n %s", buff);
stmt= mysql_simple_prepare(mysql, buff);
check_stmt(stmt);
@@ -537,7 +587,8 @@ static void verify_col_data(const char *table, const char *col,
if (table && col)
{
strxmov(query, "SELECT ", col, " FROM ", table, " LIMIT 1", NullS);
- fprintf(stdout, "\n %s", query);
+ if (!opt_silent)
+ fprintf(stdout, "\n %s", query);
rc= mysql_query(mysql, query);
myquery(rc);
@@ -565,10 +616,12 @@ static void verify_col_data(const char *table, const char *col,
/* Utility function to verify the field members */
static void verify_prepare_field(MYSQL_RES *result,
- unsigned int no, const char *name, const char *org_name,
- enum enum_field_types type, const char *table,
- const char *org_table, const char *db,
- unsigned long length, const char *def)
+ unsigned int no, const char *name,
+ const char *org_name,
+ enum enum_field_types type,
+ const char *table,
+ const char *org_table, const char *db,
+ unsigned long length, const char *def)
{
MYSQL_FIELD *field;
@@ -577,23 +630,26 @@ static void verify_prepare_field(MYSQL_RES *result,
fprintf(stdout, "\n *** ERROR: FAILED TO GET THE RESULT ***");
exit(1);
}
- fprintf(stdout, "\n field[%d]:", no);
- fprintf(stdout, "\n name :`%s`\t(expected: `%s`)", field->name, name);
- fprintf(stdout, "\n org_name :`%s`\t(expected: `%s`)",
- field->org_name, org_name);
- fprintf(stdout, "\n type :`%d`\t(expected: `%d`)", field->type, type);
- fprintf(stdout, "\n table :`%s`\t(expected: `%s`)",
- field->table, table);
- fprintf(stdout, "\n org_table:`%s`\t(expected: `%s`)",
- field->org_table, org_table);
- fprintf(stdout, "\n database :`%s`\t(expected: `%s`)", field->db, db);
- fprintf(stdout, "\n length :`%ld`\t(expected: `%ld`)",
- field->length, length);
- fprintf(stdout, "\n maxlength:`%ld`", field->max_length);
- fprintf(stdout, "\n charsetnr:`%d`", field->charsetnr);
- fprintf(stdout, "\n default :`%s`\t(expected: `%s`)",
- field->def ? field->def : "(null)", def ? def: "(null)");
- fprintf(stdout, "\n");
+ if (!opt_silent)
+ {
+ fprintf(stdout, "\n field[%d]:", no);
+ fprintf(stdout, "\n name :`%s`\t(expected: `%s`)", field->name, name);
+ fprintf(stdout, "\n org_name :`%s`\t(expected: `%s`)",
+ field->org_name, org_name);
+ fprintf(stdout, "\n type :`%d`\t(expected: `%d`)", field->type, type);
+ fprintf(stdout, "\n table :`%s`\t(expected: `%s`)",
+ field->table, table);
+ fprintf(stdout, "\n org_table:`%s`\t(expected: `%s`)",
+ field->org_table, org_table);
+ fprintf(stdout, "\n database :`%s`\t(expected: `%s`)", field->db, db);
+ fprintf(stdout, "\n length :`%ld`\t(expected: `%ld`)",
+ field->length, length);
+ fprintf(stdout, "\n maxlength:`%ld`", field->max_length);
+ fprintf(stdout, "\n charsetnr:`%d`", field->charsetnr);
+ fprintf(stdout, "\n default :`%s`\t(expected: `%s`)",
+ field->def ? field->def : "(null)", def ? def: "(null)");
+ fprintf(stdout, "\n");
+ }
DIE_UNLESS(strcmp(field->name, name) == 0);
DIE_UNLESS(strcmp(field->org_name, org_name) == 0);
DIE_UNLESS(field->type == type);
@@ -611,8 +667,9 @@ static void verify_prepare_field(MYSQL_RES *result,
static void verify_param_count(MYSQL_STMT *stmt, long exp_count)
{
long param_count= mysql_stmt_param_count(stmt);
- fprintf(stdout, "\n total parameters in stmt: `%ld` (expected: `%ld`)",
- param_count, exp_count);
+ if (!opt_silent)
+ fprintf(stdout, "\n total parameters in stmt: `%ld` (expected: `%ld`)",
+ param_count, exp_count);
DIE_UNLESS(param_count == exp_count);
}
@@ -622,8 +679,9 @@ static void verify_param_count(MYSQL_STMT *stmt, long exp_count)
static void verify_st_affected_rows(MYSQL_STMT *stmt, ulonglong exp_count)
{
ulonglong affected_rows= mysql_stmt_affected_rows(stmt);
- fprintf(stdout, "\n total affected rows: `%lld` (expected: `%lld`)",
- affected_rows, exp_count);
+ if (!opt_silent)
+ fprintf(stdout, "\n total affected rows: `%lld` (expected: `%lld`)",
+ affected_rows, exp_count);
DIE_UNLESS(affected_rows == exp_count);
}
@@ -633,7 +691,8 @@ static void verify_st_affected_rows(MYSQL_STMT *stmt, ulonglong exp_count)
static void verify_affected_rows(ulonglong exp_count)
{
ulonglong affected_rows= mysql_affected_rows(mysql);
- fprintf(stdout, "\n total affected rows: `%lld` (expected: `%lld`)",
+ if (!opt_silent)
+ fprintf(stdout, "\n total affected rows: `%lld` (expected: `%lld`)",
affected_rows, exp_count);
DIE_UNLESS(affected_rows == exp_count);
}
@@ -644,8 +703,9 @@ static void verify_affected_rows(ulonglong exp_count)
static void verify_field_count(MYSQL_RES *result, uint exp_count)
{
uint field_count= mysql_num_fields(result);
- fprintf(stdout, "\n total fields in the result set: `%d` (expected: `%d`)",
- field_count, exp_count);
+ if (!opt_silent)
+ fprintf(stdout, "\n total fields in the result set: `%d` (expected: `%d`)",
+ field_count, exp_count);
DIE_UNLESS(field_count == exp_count);
}
@@ -665,8 +725,9 @@ static void execute_prepare_query(const char *query, ulonglong exp_count)
myquery(rc);
affected_rows= mysql_stmt_affected_rows(stmt);
- fprintf(stdout, "\n total affected rows: `%lld` (expected: `%lld`)",
- affected_rows, exp_count);
+ if (!opt_silent)
+ fprintf(stdout, "\n total affected rows: `%lld` (expected: `%lld`)",
+ affected_rows, exp_count);
DIE_UNLESS(affected_rows == exp_count);
mysql_stmt_close(stmt);
@@ -722,7 +783,8 @@ static my_bool thread_query(char *query)
my_bool error;
error= 0;
- fprintf(stdout, "\n in thread_query(%s)", query);
+ if (!opt_silent)
+ fprintf(stdout, "\n in thread_query(%s)", query);
if (!(l_mysql= mysql_init(NULL)))
{
myerror("mysql_init() failed");
@@ -753,6 +815,7 @@ end:
static void test_debug_example()
{
+ DBUG_ENTER("fill_tables");
int rc;
MYSQL_RES *result;
@@ -1033,7 +1096,8 @@ static void test_prepare_field_result()
my_print_result_metadata(result);
- fprintf(stdout, "\n\n field attributes:\n");
+ if (!opt_silent)
+ fprintf(stdout, "\n\n field attributes:\n");
verify_prepare_field(result, 0, "int_c", "int_c", MYSQL_TYPE_LONG,
"t1", "test_prepare_field_result", current_db, 11, 0);
verify_prepare_field(result, 1, "var_c", "var_c", MYSQL_TYPE_VAR_STRING,
@@ -1207,17 +1271,20 @@ static void test_prepare()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n");
+ if (!opt_silent)
+ {
+ fprintf(stdout, "\n");
- fprintf(stdout, "\n\t tiny : %d (%lu)", tiny_data, length[0]);
- fprintf(stdout, "\n\t short : %d (%lu)", small_data, length[3]);
- fprintf(stdout, "\n\t int : %d (%lu)", int_data, length[2]);
- fprintf(stdout, "\n\t big : %lld (%lu)", big_data, length[4]);
+ fprintf(stdout, "\n\t tiny : %d (%lu)", tiny_data, length[0]);
+ fprintf(stdout, "\n\t short : %d (%lu)", small_data, length[3]);
+ fprintf(stdout, "\n\t int : %d (%lu)", int_data, length[2]);
+ fprintf(stdout, "\n\t big : %lld (%lu)", big_data, length[4]);
- fprintf(stdout, "\n\t float : %f (%lu)", real_data, length[5]);
- fprintf(stdout, "\n\t double : %f (%lu)", double_data, length[6]);
+ fprintf(stdout, "\n\t float : %f (%lu)", real_data, length[5]);
+ fprintf(stdout, "\n\t double : %f (%lu)", double_data, length[6]);
- fprintf(stdout, "\n\t str : %s (%lu)", str_data, length[1]);
+ fprintf(stdout, "\n\t str : %s (%lu)", str_data, length[1]);
+ }
DIE_UNLESS(tiny_data == o_tiny_data);
DIE_UNLESS(is_null[0] == 0);
@@ -1578,11 +1645,13 @@ static void test_fetch_null()
rc++;
for (i= 0; i < 10; i++)
{
- fprintf(stdout, "\n data[%d] : %s", i,
- is_null[i] ? "NULL" : "NOT NULL");
+ if (!opt_silent)
+ fprintf(stdout, "\n data[%d] : %s", i,
+ is_null[i] ? "NULL" : "NOT NULL");
DIE_UNLESS(is_null[i]);
}
- fprintf(stdout, "\n data[%d]: %d", i, nData);
+ if (!opt_silent)
+ fprintf(stdout, "\n data[%d]: %d", i, nData);
DIE_UNLESS(nData == 1000 || nData == 88 || nData == 389789);
DIE_UNLESS(is_null[i] == 0);
DIE_UNLESS(length[i] == 4);
@@ -2367,7 +2436,8 @@ static void test_long_data()
/* execute */
rc= mysql_stmt_execute(stmt);
- fprintf(stdout, " mysql_stmt_execute() returned %d\n", rc);
+ if (!opt_silent)
+ fprintf(stdout, " mysql_stmt_execute() returned %d\n", rc);
check_execute(stmt, rc);
rc= mysql_commit(mysql);
@@ -2450,7 +2520,8 @@ static void test_long_data_str()
}
/* execute */
rc= mysql_stmt_execute(stmt);
- fprintf(stdout, " mysql_stmt_execute() returned %d\n", rc);
+ if (!opt_silent)
+ fprintf(stdout, " mysql_stmt_execute() returned %d\n", rc);
check_execute(stmt, rc);
mysql_stmt_close(stmt);
@@ -2541,7 +2612,8 @@ static void test_long_data_str1()
/* execute */
rc= mysql_stmt_execute(stmt);
- fprintf(stdout, " mysql_stmt_execute() returned %d\n", rc);
+ if (!opt_silent)
+ fprintf(stdout, " mysql_stmt_execute() returned %d\n", rc);
check_execute(stmt, rc);
mysql_stmt_close(stmt);
@@ -2692,7 +2764,8 @@ static void test_long_data_bin()
}
/* execute */
rc= mysql_stmt_execute(stmt);
- fprintf(stdout, " mysql_stmt_execute() returned %d\n", rc);
+ if (!opt_silent)
+ fprintf(stdout, " mysql_stmt_execute() returned %d\n", rc);
check_execute(stmt, rc);
mysql_stmt_close(stmt);
@@ -2999,7 +3072,8 @@ static void test_bind_result()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n row 1: %d, %s(%lu)", nData, szData, length1);
+ if (!opt_silent)
+ fprintf(stdout, "\n row 1: %d, %s(%lu)", nData, szData, length1);
DIE_UNLESS(nData == 10);
DIE_UNLESS(strcmp(szData, "venu") == 0);
DIE_UNLESS(length1 == 4);
@@ -3007,7 +3081,8 @@ static void test_bind_result()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n row 2: %d, %s(%lu)", nData, szData, length1);
+ if (!opt_silent)
+ fprintf(stdout, "\n row 2: %d, %s(%lu)", nData, szData, length1);
DIE_UNLESS(nData == 20);
DIE_UNLESS(strcmp(szData, "MySQL") == 0);
DIE_UNLESS(length1 == 5);
@@ -3016,7 +3091,7 @@ static void test_bind_result()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- if (is_null[0])
+ if (!opt_silent && is_null[0])
fprintf(stdout, "\n row 3: NULL, %s(%lu)", szData, length1);
DIE_UNLESS(is_null[0]);
DIE_UNLESS(strcmp(szData, "monty") == 0);
@@ -3114,19 +3189,21 @@ static void test_bind_result_ext()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n data (tiny) : %d", t_data);
- fprintf(stdout, "\n data (short) : %d", s_data);
- fprintf(stdout, "\n data (int) : %d", i_data);
- fprintf(stdout, "\n data (big) : %lld", b_data);
+ if (!opt_silent)
+ {
+ fprintf(stdout, "\n data (tiny) : %d", t_data);
+ fprintf(stdout, "\n data (short) : %d", s_data);
+ fprintf(stdout, "\n data (int) : %d", i_data);
+ fprintf(stdout, "\n data (big) : %lld", b_data);
- fprintf(stdout, "\n data (float) : %f", f_data);
- fprintf(stdout, "\n data (double) : %f", d_data);
+ fprintf(stdout, "\n data (float) : %f", f_data);
+ fprintf(stdout, "\n data (double) : %f", d_data);
- fprintf(stdout, "\n data (str) : %s(%lu)", szData, szLength);
-
- bData[bLength]= '\0'; /* bData is binary */
- fprintf(stdout, "\n data (bin) : %s(%lu)", bData, bLength);
+ fprintf(stdout, "\n data (str) : %s(%lu)", szData, szLength);
+ bData[bLength]= '\0'; /* bData is binary */
+ fprintf(stdout, "\n data (bin) : %s(%lu)", bData, bLength);
+ }
DIE_UNLESS(t_data == 19);
DIE_UNLESS(s_data == 2999);
@@ -3234,16 +3311,19 @@ static void test_bind_result_ext1()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n data (tiny) : %s(%lu)", t_data, length[0]);
- fprintf(stdout, "\n data (short) : %f(%lu)", s_data, length[1]);
- fprintf(stdout, "\n data (int) : %d(%lu)", i_data, length[2]);
- fprintf(stdout, "\n data (big) : %d(%lu)", b_data, length[3]);
+ if (!opt_silent)
+ {
+ fprintf(stdout, "\n data (tiny) : %s(%lu)", t_data, length[0]);
+ fprintf(stdout, "\n data (short) : %f(%lu)", s_data, length[1]);
+ fprintf(stdout, "\n data (int) : %d(%lu)", i_data, length[2]);
+ fprintf(stdout, "\n data (big) : %d(%lu)", b_data, length[3]);
- fprintf(stdout, "\n data (float) : %d(%lu)", f_data, length[4]);
- fprintf(stdout, "\n data (double) : %s(%lu)", d_data, length[5]);
+ fprintf(stdout, "\n data (float) : %d(%lu)", f_data, length[4]);
+ fprintf(stdout, "\n data (double) : %s(%lu)", d_data, length[5]);
- fprintf(stdout, "\n data (bin) : %ld(%lu)", bData, length[6]);
- fprintf(stdout, "\n data (str) : %g(%lu)", szData, length[7]);
+ fprintf(stdout, "\n data (bin) : %ld(%lu)", bData, length[6]);
+ fprintf(stdout, "\n data (str) : %g(%lu)", szData, length[7]);
+ }
DIE_UNLESS(strcmp(t_data, "120") == 0);
DIE_UNLESS(i_data == 3999);
@@ -3368,15 +3448,17 @@ static void bind_fetch(int row_count)
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n");
- fprintf(stdout, "\n tiny : %ld(%lu)", (ulong) i8_data, length[0]);
- fprintf(stdout, "\n short : %ld(%lu)", (ulong) i16_data, length[1]);
- fprintf(stdout, "\n int : %ld(%lu)", (ulong) i32_data, length[2]);
- fprintf(stdout, "\n longlong : %ld(%lu)", (ulong) i64_data, length[3]);
- fprintf(stdout, "\n float : %f(%lu)", f_data, length[4]);
- fprintf(stdout, "\n double : %g(%lu)", d_data, length[5]);
- fprintf(stdout, "\n char : %s(%lu)", s_data, length[6]);
-
+ if (!opt_silent)
+ {
+ fprintf(stdout, "\n");
+ fprintf(stdout, "\n tiny : %ld(%lu)", (ulong) i8_data, length[0]);
+ fprintf(stdout, "\n short : %ld(%lu)", (ulong) i16_data, length[1]);
+ fprintf(stdout, "\n int : %ld(%lu)", (ulong) i32_data, length[2]);
+ fprintf(stdout, "\n longlong : %ld(%lu)", (ulong) i64_data, length[3]);
+ fprintf(stdout, "\n float : %f(%lu)", f_data, length[4]);
+ fprintf(stdout, "\n double : %g(%lu)", d_data, length[5]);
+ fprintf(stdout, "\n char : %s(%lu)", s_data, length[6]);
+ }
rc= 10+row_count;
/* TINY */
@@ -3518,13 +3600,16 @@ static void test_fetch_date()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n date : %s(%lu)", date, d_length);
- fprintf(stdout, "\n time : %s(%lu)", time, t_length);
- fprintf(stdout, "\n ts : %s(%lu)", ts, ts_length);
- fprintf(stdout, "\n year : %d(%lu)", year, y_length);
- fprintf(stdout, "\n dt : %s(%lu)", dt, dt_length);
- fprintf(stdout, "\n ts(4) : %s(%lu)", ts_4, ts4_length);
- fprintf(stdout, "\n ts(6) : %s(%lu)", ts_6, ts6_length);
+ if (!opt_silent)
+ {
+ fprintf(stdout, "\n date : %s(%lu)", date, d_length);
+ fprintf(stdout, "\n time : %s(%lu)", time, t_length);
+ fprintf(stdout, "\n ts : %s(%lu)", ts, ts_length);
+ fprintf(stdout, "\n year : %d(%lu)", year, y_length);
+ fprintf(stdout, "\n dt : %s(%lu)", dt, dt_length);
+ fprintf(stdout, "\n ts(4) : %s(%lu)", ts_4, ts4_length);
+ fprintf(stdout, "\n ts(6) : %s(%lu)", ts_6, ts6_length);
+ }
DIE_UNLESS(strcmp(date, "2002-01-02") == 0);
DIE_UNLESS(d_length == 10);
@@ -3851,7 +3936,8 @@ static void test_field_names()
myheader("test_field_names");
- fprintf(stdout, "\n %d, %d, %d", MYSQL_TYPE_DECIMAL, MYSQL_TYPE_NEWDATE, MYSQL_TYPE_ENUM);
+ if (!opt_silent)
+ fprintf(stdout, "\n %d, %d, %d", MYSQL_TYPE_DECIMAL, MYSQL_TYPE_NEWDATE, MYSQL_TYPE_ENUM);
rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_field_names1");
myquery(rc);
@@ -3902,7 +3988,8 @@ static void test_warnings()
rc= mysql_query(mysql, "DROP TABLE if exists test_non_exists");
myquery(rc);
- fprintf(stdout, "\n total warnings: %d", mysql_warning_count(mysql));
+ if (!opt_silent)
+ fprintf(stdout, "\n total warnings: %d", mysql_warning_count(mysql));
rc= mysql_query(mysql, "SHOW WARNINGS");
myquery(rc);
@@ -4084,23 +4171,27 @@ static void test_field_flags()
mytest(result);
mysql_field_seek(result, 0);
- fputc('\n', stdout);
+ if (!opt_silent)
+ fputc('\n', stdout);
for(i= 0; i< mysql_num_fields(result); i++)
{
field= mysql_fetch_field(result);
- fprintf(stdout, "\n field:%d", i);
- if (field->flags & NOT_NULL_FLAG)
- fprintf(stdout, "\n NOT_NULL_FLAG");
- if (field->flags & PRI_KEY_FLAG)
- fprintf(stdout, "\n PRI_KEY_FLAG");
- if (field->flags & UNIQUE_KEY_FLAG)
- fprintf(stdout, "\n UNIQUE_KEY_FLAG");
- if (field->flags & MULTIPLE_KEY_FLAG)
- fprintf(stdout, "\n MULTIPLE_KEY_FLAG");
- if (field->flags & AUTO_INCREMENT_FLAG)
- fprintf(stdout, "\n AUTO_INCREMENT_FLAG");
+ if (!opt_silent)
+ {
+ fprintf(stdout, "\n field:%d", i);
+ if (field->flags & NOT_NULL_FLAG)
+ fprintf(stdout, "\n NOT_NULL_FLAG");
+ if (field->flags & PRI_KEY_FLAG)
+ fprintf(stdout, "\n PRI_KEY_FLAG");
+ if (field->flags & UNIQUE_KEY_FLAG)
+ fprintf(stdout, "\n UNIQUE_KEY_FLAG");
+ if (field->flags & MULTIPLE_KEY_FLAG)
+ fprintf(stdout, "\n MULTIPLE_KEY_FLAG");
+ if (field->flags & AUTO_INCREMENT_FLAG)
+ fprintf(stdout, "\n AUTO_INCREMENT_FLAG");
+ }
}
mysql_free_result(result);
}
@@ -4119,7 +4210,8 @@ static void test_stmt_close()
myheader("test_stmt_close");
- fprintf(stdout, "\n Establishing a test connection ...");
+ if (!opt_silent)
+ fprintf(stdout, "\n Establishing a test connection ...");
if (!(lmysql= mysql_init(NULL)))
{
myerror("mysql_init() failed");
@@ -4132,7 +4224,8 @@ static void test_stmt_close()
myerror("connection failed");
exit(1);
}
- fprintf(stdout, " OK");
+ if (!opt_silent)
+ fprintf(stdout, " OK");
/* set AUTOCOMMIT to ON*/
@@ -4169,7 +4262,8 @@ static void test_stmt_close()
verify_param_count(stmt2, 1);
rc= mysql_stmt_close(stmt1);
- fprintf(stdout, "\n mysql_close_stmt(1) returned: %d", rc);
+ if (!opt_silent)
+ fprintf(stdout, "\n mysql_close_stmt(1) returned: %d", rc);
DIE_UNLESS(rc == 0);
/*
@@ -4203,7 +4297,8 @@ static void test_stmt_close()
verify_st_affected_rows(stmt_x, 1);
rc= mysql_stmt_close(stmt_x);
- fprintf(stdout, "\n mysql_close_stmt(x) returned: %d", rc);
+ if (!opt_silent)
+ fprintf(stdout, "\n mysql_close_stmt(x) returned: %d", rc);
DIE_UNLESS( rc == 0);
rc= mysql_query(mysql, "SELECT id FROM test_stmt_close");
@@ -4262,7 +4357,8 @@ static void test_set_variable()
rc= mysql_stmt_fetch(stmt1);
check_execute(stmt1, rc);
- fprintf(stdout, "\n max_error_count(default): %d", get_count);
+ if (!opt_silent)
+ fprintf(stdout, "\n max_error_count(default): %d", get_count);
def_count= get_count;
DIE_UNLESS(strcmp(var, "max_error_count") == 0);
@@ -4292,7 +4388,8 @@ static void test_set_variable()
rc= mysql_stmt_fetch(stmt1);
check_execute(stmt1, rc);
- fprintf(stdout, "\n max_error_count : %d", get_count);
+ if (!opt_silent)
+ fprintf(stdout, "\n max_error_count : %d", get_count);
DIE_UNLESS(get_count == set_count);
rc= mysql_stmt_fetch(stmt1);
@@ -4309,7 +4406,8 @@ static void test_set_variable()
rc= mysql_stmt_fetch(stmt1);
check_execute(stmt1, rc);
- fprintf(stdout, "\n max_error_count(default): %d", get_count);
+ if (!opt_silent)
+ fprintf(stdout, "\n max_error_count(default): %d", get_count);
DIE_UNLESS(get_count == set_count);
rc= mysql_stmt_fetch(stmt1);
@@ -4367,12 +4465,14 @@ static void test_insert_meta()
mysql_field_seek(result, 0);
field= mysql_fetch_field(result);
mytest(field);
- fprintf(stdout, "\n obtained: `%s` (expected: `%s`)", field->name, "col1");
+ if (!opt_silent)
+ fprintf(stdout, "\n obtained: `%s` (expected: `%s`)", field->name, "col1");
DIE_UNLESS(strcmp(field->name, "col1") == 0);
field= mysql_fetch_field(result);
mytest(field);
- fprintf(stdout, "\n obtained: `%s` (expected: `%s`)", field->name, "col3");
+ if (!opt_silent)
+ fprintf(stdout, "\n obtained: `%s` (expected: `%s`)", field->name, "col3");
DIE_UNLESS(strcmp(field->name, "col3") == 0);
field= mysql_fetch_field(result);
@@ -4429,15 +4529,21 @@ static void test_update_meta()
mysql_field_seek(result, 0);
field= mysql_fetch_field(result);
mytest(field);
- fprintf(stdout, "\n col obtained: `%s` (expected: `%s`)", field->name, "col1");
- fprintf(stdout, "\n tab obtained: `%s` (expected: `%s`)", field->table, "test_prep_update");
+ if (!opt_silent)
+ {
+ fprintf(stdout, "\n col obtained: `%s` (expected: `%s`)", field->name, "col1");
+ fprintf(stdout, "\n tab obtained: `%s` (expected: `%s`)", field->table, "test_prep_update");
+ }
DIE_UNLESS(strcmp(field->name, "col1") == 0);
DIE_UNLESS(strcmp(field->table, "test_prep_update") == 0);
field= mysql_fetch_field(result);
mytest(field);
- fprintf(stdout, "\n col obtained: `%s` (expected: `%s`)", field->name, "col3");
- fprintf(stdout, "\n tab obtained: `%s` (expected: `%s`)", field->table, "test_prep_update");
+ if (!opt_silent)
+ {
+ fprintf(stdout, "\n col obtained: `%s` (expected: `%s`)", field->name, "col3");
+ fprintf(stdout, "\n tab obtained: `%s` (expected: `%s`)", field->table, "test_prep_update");
+ }
DIE_UNLESS(strcmp(field->name, "col3") == 0);
DIE_UNLESS(strcmp(field->table, "test_prep_update") == 0);
@@ -4493,15 +4599,21 @@ static void test_select_meta()
mysql_field_seek(result, 0);
field= mysql_fetch_field(result);
mytest(field);
- fprintf(stdout, "\n col obtained: `%s` (expected: `%s`)", field->name, "col1");
- fprintf(stdout, "\n tab obtained: `%s` (expected: `%s`)", field->table, "test_prep_select");
+ if (!opt_silent)
+ {
+ fprintf(stdout, "\n col obtained: `%s` (expected: `%s`)", field->name, "col1");
+ fprintf(stdout, "\n tab obtained: `%s` (expected: `%s`)", field->table, "test_prep_select");
+ }
DIE_UNLESS(strcmp(field->name, "col1") == 0);
DIE_UNLESS(strcmp(field->table, "test_prep_select") == 0);
field= mysql_fetch_field(result);
mytest(field);
- fprintf(stdout, "\n col obtained: `%s` (expected: `%s`)", field->name, "col2");
- fprintf(stdout, "\n tab obtained: `%s` (expected: `%s`)", field->table, "test_prep_select");
+ if (!opt_silent)
+ {
+ fprintf(stdout, "\n col obtained: `%s` (expected: `%s`)", field->name, "col2");
+ fprintf(stdout, "\n tab obtained: `%s` (expected: `%s`)", field->table, "test_prep_select");
+ }
DIE_UNLESS(strcmp(field->name, "col2") == 0);
DIE_UNLESS(strcmp(field->table, "test_prep_select") == 0);
@@ -4545,8 +4657,9 @@ static void test_func_fields()
field= mysql_fetch_field(result);
mytest(field);
- fprintf(stdout, "\n table name: `%s` (expected: `%s`)", field->table,
- "test_dateformat");
+ if (!opt_silent)
+ fprintf(stdout, "\n table name: `%s` (expected: `%s`)", field->table,
+ "test_dateformat");
DIE_UNLESS(strcmp(field->table, "test_dateformat") == 0);
field= mysql_fetch_field(result);
@@ -4563,7 +4676,8 @@ static void test_func_fields()
field= mysql_fetch_field(result);
mytest(field);
- fprintf(stdout, "\n table name: `%s` (expected: `%s`)", field->table, "");
+ if (!opt_silent)
+ fprintf(stdout, "\n table name: `%s` (expected: `%s`)", field->table, "");
DIE_UNLESS(field->table[0] == '\0');
field= mysql_fetch_field(result);
@@ -4580,8 +4694,11 @@ static void test_func_fields()
field= mysql_fetch_field(result);
mytest(field);
- fprintf(stdout, "\n field name: `%s` (expected: `%s`)", field->name, "YEAR");
- fprintf(stdout, "\n field org name: `%s` (expected: `%s`)", field->org_name, "");
+ if (!opt_silent)
+ {
+ printf("\n field name: `%s` (expected: `%s`)", field->name, "YEAR");
+ printf("\n field org name: `%s` (expected: `%s`)", field->org_name, "");
+ }
DIE_UNLESS(strcmp(field->name, "YEAR") == 0);
DIE_UNLESS(field->org_name[0] == '\0');
@@ -4658,8 +4775,11 @@ static void test_multi_stmt()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n int_data: %lu(%lu)", (ulong) id, length[0]);
- fprintf(stdout, "\n str_data: %s(%lu)", name, length[1]);
+ if (!opt_silent)
+ {
+ fprintf(stdout, "\n int_data: %lu(%lu)", (ulong) id, length[0]);
+ fprintf(stdout, "\n str_data: %s(%lu)", name, length[1]);
+ }
DIE_UNLESS(id == 10);
DIE_UNLESS(strcmp(name, "mysql") == 0);
@@ -4687,8 +4807,11 @@ static void test_multi_stmt()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n int_data: %lu(%lu)", (ulong) id, length[0]);
- fprintf(stdout, "\n str_data: %s(%lu)", name, length[1]);
+ if (!opt_silent)
+ {
+ fprintf(stdout, "\n int_data: %lu(%lu)", (ulong) id, length[0]);
+ fprintf(stdout, "\n str_data: %s(%lu)", name, length[1]);
+ }
DIE_UNLESS(id == 10);
DIE_UNLESS(strcmp(name, "updated") == 0);
@@ -4762,12 +4885,14 @@ static void test_manual_sample()
fprintf(stderr, "\n %s", mysql_error(mysql));
exit(1);
}
- fprintf(stdout, "\n prepare, insert successful");
+ if (!opt_silent)
+ fprintf(stdout, "\n prepare, insert successful");
/* Get the parameter count from the statement */
param_count= mysql_stmt_param_count(stmt);
- fprintf(stdout, "\n total parameters in insert: %d", param_count);
+ if (!opt_silent)
+ fprintf(stdout, "\n total parameters in insert: %d", param_count);
if (param_count != 3) /* validate parameter count */
{
fprintf(stderr, "\n invalid parameter count returned by MySQL");
@@ -4823,7 +4948,8 @@ static void test_manual_sample()
/* Get the total rows affected */
affected_rows= mysql_stmt_affected_rows(stmt);
- fprintf(stdout, "\n total affected rows: %lld", affected_rows);
+ if (!opt_silent)
+ fprintf(stdout, "\n total affected rows: %lld", affected_rows);
if (affected_rows != 1) /* validate affected rows */
{
fprintf(stderr, "\n invalid affected rows by MySQL");
@@ -4847,7 +4973,8 @@ static void test_manual_sample()
/* Get the total rows affected */
affected_rows= mysql_stmt_affected_rows(stmt);
- fprintf(stdout, "\n total affected rows: %lld", affected_rows);
+ if (!opt_silent)
+ fprintf(stdout, "\n total affected rows: %lld", affected_rows);
if (affected_rows != 1) /* validate affected rows */
{
fprintf(stderr, "\n invalid affected rows by MySQL");
@@ -4871,7 +4998,8 @@ static void test_manual_sample()
fprintf(stderr, "\n %s", mysql_error(mysql));
exit(1);
}
- fprintf(stdout, "Success !!!");
+ if (!opt_silent)
+ fprintf(stdout, "Success !!!");
}
@@ -4993,13 +5121,14 @@ DROP TABLE IF EXISTS test_multi_tab";
for (count= 0 ; count < array_elements(rows) ; count++)
{
- fprintf(stdout, "\n Query %d: ", count);
+ if (!opt_silent)
+ fprintf(stdout, "\n Query %d: ", count);
if ((result= mysql_store_result(mysql_local)))
{
(void) my_process_result_set(result);
mysql_free_result(result);
}
- else
+ else if (!opt_silent)
fprintf(stdout, "OK, %lld row(s) affected, %d warning(s)\n",
mysql_affected_rows(mysql_local),
mysql_warning_count(mysql_local));
@@ -5007,7 +5136,7 @@ DROP TABLE IF EXISTS test_multi_tab";
exp_value= (uint) mysql_affected_rows(mysql_local);
if (rows[count] != exp_value)
{
- fprintf(stdout, "row %d had affected rows: %d, should be %d\n",
+ fprintf(stderr, "row %d had affected rows: %d, should be %d\n",
count, exp_value, rows[count]);
exit(1);
}
@@ -5083,7 +5212,7 @@ static void test_prepare_multi_statements()
if (!(mysql_local= mysql_init(NULL)))
{
- fprintf(stdout, "\n mysql_init() failed");
+ fprintf(stderr, "\n mysql_init() failed");
exit(1);
}
@@ -5091,7 +5220,7 @@ static void test_prepare_multi_statements()
opt_password, current_db, opt_port,
opt_unix_socket, CLIENT_MULTI_STATEMENTS)))
{
- fprintf(stdout, "\n connection failed(%s)", mysql_error(mysql_local));
+ fprintf(stderr, "\n connection failed(%s)", mysql_error(mysql_local));
exit(1);
}
strmov(query, "select 1; select 'another value'");
@@ -5159,7 +5288,8 @@ static void test_store_result()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n row 1: %ld, %s(%lu)", (long) nData, szData, length1);
+ if (!opt_silent)
+ fprintf(stdout, "\n row 1: %ld, %s(%lu)", (long) nData, szData, length1);
DIE_UNLESS(nData == 10);
DIE_UNLESS(strcmp(szData, "venu") == 0);
DIE_UNLESS(length1 == 4);
@@ -5167,7 +5297,8 @@ static void test_store_result()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n row 2: %ld, %s(%lu)", (long) nData, szData, length1);
+ if (!opt_silent)
+ fprintf(stdout, "\n row 2: %ld, %s(%lu)", (long) nData, szData, length1);
DIE_UNLESS(nData == 20);
DIE_UNLESS(strcmp(szData, "mysql") == 0);
DIE_UNLESS(length1 == 5);
@@ -5176,7 +5307,7 @@ static void test_store_result()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- if (is_null[0])
+ if (!opt_silent && is_null[0])
fprintf(stdout, "\n row 3: NULL, %s(%lu)", szData, length1);
DIE_UNLESS(is_null[0]);
DIE_UNLESS(strcmp(szData, "monty") == 0);
@@ -5194,7 +5325,8 @@ static void test_store_result()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n row 1: %ld, %s(%lu)", (long) nData, szData, length1);
+ if (!opt_silent)
+ fprintf(stdout, "\n row 1: %ld, %s(%lu)", (long) nData, szData, length1);
DIE_UNLESS(nData == 10);
DIE_UNLESS(strcmp(szData, "venu") == 0);
DIE_UNLESS(length1 == 4);
@@ -5202,7 +5334,8 @@ static void test_store_result()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n row 2: %ld, %s(%lu)", (long) nData, szData, length1);
+ if (!opt_silent)
+ fprintf(stdout, "\n row 2: %ld, %s(%lu)", (long) nData, szData, length1);
DIE_UNLESS(nData == 20);
DIE_UNLESS(strcmp(szData, "mysql") == 0);
DIE_UNLESS(length1 == 5);
@@ -5211,7 +5344,7 @@ static void test_store_result()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- if (is_null[0])
+ if (!opt_silent && is_null[0])
fprintf(stdout, "\n row 3: NULL, %s(%lu)", szData, length1);
DIE_UNLESS(is_null[0]);
DIE_UNLESS(strcmp(szData, "monty") == 0);
@@ -5260,7 +5393,8 @@ static void test_store_result1()
rc= 0;
while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
rc++;
- fprintf(stdout, "\n total rows: %d", rc);
+ if (!opt_silent)
+ fprintf(stdout, "\n total rows: %d", rc);
DIE_UNLESS(rc == 3);
rc= mysql_stmt_execute(stmt);
@@ -5272,7 +5406,8 @@ static void test_store_result1()
rc= 0;
while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
rc++;
- fprintf(stdout, "\n total rows: %d", rc);
+ if (!opt_silent)
+ fprintf(stdout, "\n total rows: %d", rc);
DIE_UNLESS(rc == 3);
mysql_stmt_close(stmt);
@@ -5338,7 +5473,8 @@ static void test_store_result2()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n row 1: %d", nData);
+ if (!opt_silent)
+ fprintf(stdout, "\n row 1: %d", nData);
DIE_UNLESS(nData == 10);
rc= mysql_stmt_fetch(stmt);
@@ -5355,7 +5491,8 @@ static void test_store_result2()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n row 1: %d", nData);
+ if (!opt_silent)
+ fprintf(stdout, "\n row 1: %d", nData);
DIE_UNLESS(nData == 20);
rc= mysql_stmt_fetch(stmt);
@@ -5458,7 +5595,8 @@ static void test_subselect()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n row 1: %d", id);
+ if (!opt_silent)
+ fprintf(stdout, "\n row 1: %d", id);
DIE_UNLESS(id == 1);
rc= mysql_stmt_fetch(stmt);
@@ -5471,7 +5609,8 @@ static void test_subselect()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n row 1: %d", id);
+ if (!opt_silent)
+ fprintf(stdout, "\n row 1: %d", id);
DIE_UNLESS(id == 0);
rc= mysql_stmt_fetch(stmt);
@@ -5587,21 +5726,21 @@ static void test_bind_date_conv(uint row_count)
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n");
+ if (!opt_silent)
+ fprintf(stdout, "\n");
for (i= 0; i < array_elements(bind); i++)
{
- fprintf(stdout, "\n");
- fprintf(stdout, " time[%d]: %02d-%02d-%02d %02d:%02d:%02d.%02lu",
- i, tm[i].year, tm[i].month, tm[i].day,
- tm[i].hour, tm[i].minute, tm[i].second,
- tm[i].second_part);
-
+ if (!opt_silent)
+ fprintf(stdout, "\ntime[%d]: %02d-%02d-%02d %02d:%02d:%02d.%02lu",
+ i, tm[i].year, tm[i].month, tm[i].day,
+ tm[i].hour, tm[i].minute, tm[i].second,
+ tm[i].second_part);
DIE_UNLESS(tm[i].year == 0 || tm[i].year == year+count);
DIE_UNLESS(tm[i].month == 0 || tm[i].month == month+count);
DIE_UNLESS(tm[i].day == 0 || tm[i].day == day+count);
DIE_UNLESS(tm[i].hour == 0 || tm[i].hour == hour+count);
-#if 0
+#ifdef NOT_USED
/*
minute causes problems from date<->time, don't assert, instead
validate separatly in another routine
@@ -5856,7 +5995,8 @@ static void test_buffers()
buffer[1]= 'X';
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n data: %s (%lu)", buffer, length);
+ if (!opt_silent)
+ fprintf(stdout, "\n data: %s (%lu)", buffer, length);
DIE_UNLESS(buffer[0] == 'M');
DIE_UNLESS(buffer[1] == 'X');
DIE_UNLESS(length == 5);
@@ -5867,7 +6007,8 @@ static void test_buffers()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n data: %s (%lu)", buffer, length);
+ if (!opt_silent)
+ fprintf(stdout, "\n data: %s (%lu)", buffer, length);
DIE_UNLESS(strncmp(buffer, "Database", 8) == 0);
DIE_UNLESS(length == 8);
@@ -5877,7 +6018,8 @@ static void test_buffers()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n data: %s (%lu)", buffer, length);
+ if (!opt_silent)
+ fprintf(stdout, "\n data: %s (%lu)", buffer, length);
DIE_UNLESS(strcmp(buffer, "Open-Source") == 0);
DIE_UNLESS(length == 11);
@@ -5887,7 +6029,8 @@ static void test_buffers()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n data: %s (%lu)", buffer, length);
+ if (!opt_silent)
+ fprintf(stdout, "\n data: %s (%lu)", buffer, length);
DIE_UNLESS(strncmp(buffer, "Popula", 6) == 0);
DIE_UNLESS(length == 7);
@@ -6018,7 +6161,8 @@ static void test_fetch_nobuffs()
while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
rc++;
- fprintf(stdout, "\n total rows : %d", rc);
+ if (!opt_silent)
+ fprintf(stdout, "\n total rows : %d", rc);
DIE_UNLESS(rc == 1);
bind[0].buffer_type= MYSQL_TYPE_STRING;
@@ -6041,12 +6185,16 @@ static void test_fetch_nobuffs()
while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
{
rc++;
- fprintf(stdout, "\n CURRENT_DATABASE(): %s", str[0]);
- fprintf(stdout, "\n CURRENT_USER() : %s", str[1]);
- fprintf(stdout, "\n CURRENT_DATE() : %s", str[2]);
- fprintf(stdout, "\n CURRENT_TIME() : %s", str[3]);
+ if (!opt_silent)
+ {
+ fprintf(stdout, "\n CURRENT_DATABASE(): %s", str[0]);
+ fprintf(stdout, "\n CURRENT_USER() : %s", str[1]);
+ fprintf(stdout, "\n CURRENT_DATE() : %s", str[2]);
+ fprintf(stdout, "\n CURRENT_TIME() : %s", str[3]);
+ }
}
- fprintf(stdout, "\n total rows : %d", rc);
+ if (!opt_silent)
+ fprintf(stdout, "\n total rows : %d", rc);
DIE_UNLESS(rc == 1);
mysql_stmt_close(stmt);
@@ -6113,10 +6261,13 @@ static void test_ushort_bug()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n ushort : %d (%ld)", short_value, s_length);
- fprintf(stdout, "\n ulong : %lu (%ld)", (ulong) long_value, l_length);
- fprintf(stdout, "\n longlong : %lld (%ld)", longlong_value, ll_length);
- fprintf(stdout, "\n tinyint : %d (%ld)", tiny_value, t_length);
+ if (!opt_silent)
+ {
+ fprintf(stdout, "\n ushort : %d (%ld)", short_value, s_length);
+ fprintf(stdout, "\n ulong : %lu (%ld)", (ulong) long_value, l_length);
+ fprintf(stdout, "\n longlong : %lld (%ld)", longlong_value, ll_length);
+ fprintf(stdout, "\n tinyint : %d (%ld)", tiny_value, t_length);
+ }
DIE_UNLESS(short_value == 35999);
DIE_UNLESS(s_length == 2);
@@ -6197,10 +6348,13 @@ static void test_sshort_bug()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n sshort : %d (%ld)", short_value, s_length);
- fprintf(stdout, "\n slong : %ld (%ld)", (long) long_value, l_length);
- fprintf(stdout, "\n longlong : %lld (%ld)", longlong_value, ll_length);
- fprintf(stdout, "\n tinyint : %d (%ld)", tiny_value, t_length);
+ if (!opt_silent)
+ {
+ fprintf(stdout, "\n sshort : %d (%ld)", short_value, s_length);
+ fprintf(stdout, "\n slong : %ld (%ld)", (long) long_value, l_length);
+ fprintf(stdout, "\n longlong : %lld (%ld)", longlong_value, ll_length);
+ fprintf(stdout, "\n tinyint : %d (%ld)", tiny_value, t_length);
+ }
DIE_UNLESS(short_value == -5999);
DIE_UNLESS(s_length == 2);
@@ -6281,10 +6435,13 @@ static void test_stiny_bug()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n sshort : %d (%ld)", short_value, s_length);
- fprintf(stdout, "\n slong : %ld (%ld)", (long) long_value, l_length);
- fprintf(stdout, "\n longlong : %lld (%ld)", longlong_value, ll_length);
- fprintf(stdout, "\n tinyint : %d (%ld)", tiny_value, t_length);
+ if (!opt_silent)
+ {
+ fprintf(stdout, "\n sshort : %d (%ld)", short_value, s_length);
+ fprintf(stdout, "\n slong : %ld (%ld)", (long) long_value, l_length);
+ fprintf(stdout, "\n longlong : %lld (%ld)", longlong_value, ll_length);
+ fprintf(stdout, "\n tinyint : %d (%ld)", tiny_value, t_length);
+ }
DIE_UNLESS(short_value == -128);
DIE_UNLESS(s_length == 2);
@@ -6373,7 +6530,8 @@ static void test_field_misc()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n default table type: %s(%ld)", table_type, type_length);
+ if (!opt_silent)
+ fprintf(stdout, "\n default table type: %s(%ld)", table_type, type_length);
rc= mysql_stmt_fetch(stmt);
DIE_UNLESS(rc == MYSQL_NO_DATA);
@@ -6493,7 +6651,8 @@ static void test_set_option()
rc= mysql_query(mysql, "INSERT INTO test_limit VALUES(10), (20), (30), (40)");
myquery(rc);
- fprintf(stdout, "\n with SQL_SELECT_LIMIT= 2 (direct)");
+ if (!opt_silent)
+ fprintf(stdout, "\n with SQL_SELECT_LIMIT= 2 (direct)");
rc= mysql_query(mysql, "SELECT * FROM test_limit");
myquery(rc);
@@ -6505,7 +6664,8 @@ static void test_set_option()
mysql_free_result(result);
- fprintf(stdout, "\n with SQL_SELECT_LIMIT=2 (prepare)");
+ if (!opt_silent)
+ fprintf(stdout, "\n with SQL_SELECT_LIMIT=2 (prepare)");
stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_limit");
check_stmt(stmt);
@@ -6518,7 +6678,8 @@ static void test_set_option()
mysql_stmt_close(stmt);
/* RESET the LIMIT the rows count to 0 */
- fprintf(stdout, "\n with SQL_SELECT_LIMIT=DEFAULT (prepare)");
+ if (!opt_silent)
+ fprintf(stdout, "\n with SQL_SELECT_LIMIT=DEFAULT (prepare)");
rc= mysql_query(mysql, "SET OPTION SQL_SELECT_LIMIT=DEFAULT");
myquery(rc);
@@ -6576,7 +6737,8 @@ static void test_prepare_grant()
MYSQL *org_mysql= mysql, *lmysql;
MYSQL_STMT *stmt;
- fprintf(stdout, "\n Establishing a test connection ...");
+ if (!opt_silent)
+ fprintf(stdout, "\n Establishing a test connection ...");
if (!(lmysql= mysql_init(NULL)))
{
myerror("mysql_init() failed");
@@ -6590,7 +6752,8 @@ static void test_prepare_grant()
mysql_close(lmysql);
exit(1);
}
- fprintf(stdout, " OK");
+ if (!opt_silent)
+ fprintf(stdout, " OK");
mysql= lmysql;
rc= mysql_query(mysql, "INSERT INTO test_grant VALUES(NULL)");
@@ -6677,14 +6840,16 @@ static void test_frm_bug()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n data directory: %s", data_dir);
+ if (!opt_silent)
+ fprintf(stdout, "\n data directory: %s", data_dir);
rc= mysql_stmt_fetch(stmt);
DIE_UNLESS(rc == MYSQL_NO_DATA);
strxmov(test_frm, data_dir, "/", current_db, "/", "test_frm_bug.frm", NullS);
- fprintf(stdout, "\n test_frm: %s", test_frm);
+ if (!opt_silent)
+ fprintf(stdout, "\n test_frm: %s", test_frm);
if (!(test_file= my_fopen(test_frm, (int) (O_RDWR | O_CREAT), MYF(MY_WME))))
{
@@ -6692,7 +6857,8 @@ static void test_frm_bug()
fprintf(stdout, "\n test cancelled");
exit(1);
}
- fprintf(test_file, "this is a junk file for test");
+ if (!opt_silent)
+ fprintf(test_file, "this is a junk file for test");
rc= mysql_query(mysql, "SHOW TABLE STATUS like 'test_frm_bug'");
myquery(rc);
@@ -6708,7 +6874,8 @@ static void test_frm_bug()
row= mysql_fetch_row(result);
mytest(row);
- fprintf(stdout, "\n Comment: %s", row[17]);
+ if (!opt_silent)
+ fprintf(stdout, "\n Comment: %s", row[17]);
DIE_UNLESS(row[17] != 0);
mysql_free_result(result);
@@ -6771,7 +6938,8 @@ static void test_decimal_bug()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n data: %s", data);
+ if (!opt_silent)
+ fprintf(stdout, "\n data: %s", data);
DIE_UNLESS(strcmp(data, "8.00") == 0);
rc= mysql_stmt_fetch(stmt);
@@ -6788,7 +6956,8 @@ static void test_decimal_bug()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n data: %s", data);
+ if (!opt_silent)
+ fprintf(stdout, "\n data: %s", data);
DIE_UNLESS(strcmp(data, "5.61") == 0);
rc= mysql_stmt_fetch(stmt);
@@ -6812,7 +6981,8 @@ static void test_decimal_bug()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n data: %s", data);
+ if (!opt_silent)
+ fprintf(stdout, "\n data: %s", data);
DIE_UNLESS(strcmp(data, "10.22") == 0);
rc= mysql_stmt_fetch(stmt);
@@ -6852,8 +7022,9 @@ static void test_explain_bug()
result= mysql_stmt_result_metadata(stmt);
mytest(result);
- fprintf(stdout, "\n total fields in the result: %d",
- mysql_num_fields(result));
+ if (!opt_silent)
+ fprintf(stdout, "\n total fields in the result: %d",
+ mysql_num_fields(result));
DIE_UNLESS(6 == mysql_num_fields(result));
verify_prepare_field(result, 0, "Field", "", MYSQL_TYPE_VAR_STRING,
@@ -6889,8 +7060,9 @@ static void test_explain_bug()
result= mysql_stmt_result_metadata(stmt);
mytest(result);
- fprintf(stdout, "\n total fields in the result: %d",
- mysql_num_fields(result));
+ if (!opt_silent)
+ fprintf(stdout, "\n total fields in the result: %d",
+ mysql_num_fields(result));
DIE_UNLESS(10 == mysql_num_fields(result));
verify_prepare_field(result, 0, "id", "", MYSQL_TYPE_LONGLONG,
@@ -6911,8 +7083,12 @@ static void test_explain_bug()
verify_prepare_field(result, 5, "key", "", MYSQL_TYPE_VAR_STRING,
"", "", "", NAME_LEN, 0);
- verify_prepare_field(result, 6, "key_len", "", MYSQL_TYPE_LONGLONG,
- "", "", "", 3, 0);
+ verify_prepare_field(result, 6, "key_len", "",
+ (mysql_get_server_version(mysql) <= 50000 ?
+ MYSQL_TYPE_LONGLONG : MYSQL_TYPE_VAR_STRING),
+ "", "", "",
+ (mysql_get_server_version(mysql) <= 50000 ? 3 : 4096),
+ 0);
verify_prepare_field(result, 7, "ref", "", MYSQL_TYPE_VAR_STRING,
"", "", "", NAME_LEN*16, 0);
@@ -6938,11 +7114,14 @@ static void test_explain_bug()
static void check_errcode(const unsigned int err)
{
- if (mysql->server_version)
- fprintf(stdout, "\n [MySQL-%s]", mysql->server_version);
- else
- fprintf(stdout, "\n [MySQL]");
- fprintf(stdout, "[%d] %s\n", mysql_errno(mysql), mysql_error(mysql));
+ if (!opt_silent || mysql_errno(mysql) != err)
+ {
+ if (mysql->server_version)
+ fprintf(stdout, "\n [MySQL-%s]", mysql->server_version);
+ else
+ fprintf(stdout, "\n [MySQL]");
+ fprintf(stdout, "[%d] %s\n", mysql_errno(mysql), mysql_error(mysql));
+ }
DIE_UNLESS(mysql_errno(mysql) == err);
}
@@ -6988,7 +7167,8 @@ static void test_drop_temp()
{
MYSQL *org_mysql= mysql, *lmysql;
- fprintf(stdout, "\n Establishing a test connection ...");
+ if (!opt_silent)
+ fprintf(stdout, "\n Establishing a test connection ...");
if (!(lmysql= mysql_init(NULL)))
{
myerror("mysql_init() failed");
@@ -7007,7 +7187,8 @@ static void test_drop_temp()
mysql_close(lmysql);
exit(1);
}
- fprintf(stdout, " OK");
+ if (!opt_silent)
+ fprintf(stdout, " OK");
mysql= lmysql;
rc= mysql_query(mysql, "INSERT INTO t1 VALUES(10, 'C')");
@@ -7076,14 +7257,16 @@ static void test_cuted_rows()
myquery(rc);
count= mysql_warning_count(mysql);
- fprintf(stdout, "\n total warnings: %d", count);
+ if (!opt_silent)
+ fprintf(stdout, "\n total warnings: %d", count);
DIE_UNLESS(count == 0);
rc= mysql_query(mysql, "INSERT INTO t2 SELECT * FROM t1");
myquery(rc);
count= mysql_warning_count(mysql);
- fprintf(stdout, "\n total warnings: %d", count);
+ if (!opt_silent)
+ fprintf(stdout, "\n total warnings: %d", count);
DIE_UNLESS(count == 2);
rc= mysql_query(mysql, "SHOW WARNINGS");
@@ -7100,7 +7283,8 @@ static void test_cuted_rows()
myquery(rc);
count= mysql_warning_count(mysql);
- fprintf(stdout, "\n total warnings: %d", count);
+ if (!opt_silent)
+ fprintf(stdout, "\n total warnings: %d", count);
DIE_UNLESS(count == 2);
rc= mysql_query(mysql, "SHOW WARNINGS");
@@ -7213,8 +7397,11 @@ static void test_logs()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n id : %d", id);
- fprintf(stdout, "\n name : %s(%ld)", data, length);
+ if (!opt_silent)
+ {
+ fprintf(stdout, "\n id : %d", id);
+ fprintf(stdout, "\n name : %s(%ld)", data, length);
+ }
DIE_UNLESS(id == 9876);
DIE_UNLESS(length == 19); /* Due to VARCHAR(20) */
@@ -7223,7 +7410,8 @@ static void test_logs()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n name : %s(%ld)", data, length);
+ if (!opt_silent)
+ fprintf(stdout, "\n name : %s(%ld)", data, length);
DIE_UNLESS(length == 1);
DIE_UNLESS(strcmp(data, "'") == 0);
@@ -7231,7 +7419,8 @@ static void test_logs()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n name : %s(%ld)", data, length);
+ if (!opt_silent)
+ fprintf(stdout, "\n name : %s(%ld)", data, length);
DIE_UNLESS(length == 1);
DIE_UNLESS(strcmp(data, "\"") == 0);
@@ -7239,7 +7428,8 @@ static void test_logs()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n name : %s(%ld)", data, length);
+ if (!opt_silent)
+ fprintf(stdout, "\n name : %s(%ld)", data, length);
DIE_UNLESS(length == 7);
DIE_UNLESS(strcmp(data, "my\'sql\'") == 0);
@@ -7247,7 +7437,8 @@ static void test_logs()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n name : %s(%ld)", data, length);
+ if (!opt_silent)
+ fprintf(stdout, "\n name : %s(%ld)", data, length);
DIE_UNLESS(length == 7);
/*DIE_UNLESS(strcmp(data, "my\"sql\"") == 0); */
@@ -7293,7 +7484,8 @@ static void test_nstmts()
for (i= 0; i < total_stmts; i++)
{
- fprintf(stdout, "\r stmt: %d", i);
+ if (!opt_silent)
+ fprintf(stdout, "\r stmt: %d", i);
strmov(query, "insert into test_nstmts values(?)");
stmt= mysql_simple_prepare(mysql, query);
@@ -7320,7 +7512,8 @@ static void test_nstmts()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n total rows: %d", i);
+ if (!opt_silent)
+ fprintf(stdout, "\n total rows: %d", i);
DIE_UNLESS( i == total_stmts);
rc= mysql_stmt_fetch(stmt);
@@ -7386,7 +7579,8 @@ static void test_fetch_seek()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n row 0: %ld, %s, %s", (long) c1, c2, c3);
+ if (!opt_silent)
+ fprintf(stdout, "\n row 0: %ld, %s, %s", (long) c1, c2, c3);
row= mysql_stmt_row_tell(stmt);
@@ -7395,21 +7589,24 @@ static void test_fetch_seek()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n row 2: %ld, %s, %s", (long) c1, c2, c3);
+ if (!opt_silent)
+ fprintf(stdout, "\n row 2: %ld, %s, %s", (long) c1, c2, c3);
row= mysql_stmt_row_seek(stmt, row);
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n row 2: %ld, %s, %s", (long) c1, c2, c3);
+ if (!opt_silent)
+ fprintf(stdout, "\n row 2: %ld, %s, %s", (long) c1, c2, c3);
mysql_stmt_data_seek(stmt, 0);
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n row 0: %ld, %s, %s", (long) c1, c2, c3);
+ if (!opt_silent)
+ fprintf(stdout, "\n row 0: %ld, %s, %s", (long) c1, c2, c3);
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
@@ -7477,17 +7674,20 @@ static void test_fetch_offset()
data[0]= '\0';
rc= mysql_stmt_fetch_column(stmt, bind, 0, 0);
check_execute(stmt, rc);
- fprintf(stdout, "\n col 1: %s (%ld)", data, length);
+ if (!opt_silent)
+ fprintf(stdout, "\n col 1: %s (%ld)", data, length);
DIE_UNLESS(strncmp(data, "abcd", 4) == 0 && length == 10);
rc= mysql_stmt_fetch_column(stmt, bind, 0, 5);
check_execute(stmt, rc);
- fprintf(stdout, "\n col 1: %s (%ld)", data, length);
+ if (!opt_silent)
+ fprintf(stdout, "\n col 1: %s (%ld)", data, length);
DIE_UNLESS(strncmp(data, "fg", 2) == 0 && length == 10);
rc= mysql_stmt_fetch_column(stmt, bind, 0, 9);
check_execute(stmt, rc);
- fprintf(stdout, "\n col 0: %s (%ld)", data, length);
+ if (!opt_silent)
+ fprintf(stdout, "\n col 0: %s (%ld)", data, length);
DIE_UNLESS(strncmp(data, "j", 1) == 0 && length == 10);
rc= mysql_stmt_fetch(stmt);
@@ -7560,7 +7760,8 @@ static void test_fetch_column()
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n row 0: %d, %s", bc1, bc2);
+ if (!opt_silent)
+ fprintf(stdout, "\n row 0: %d, %s", bc1, bc2);
c2[0]= '\0'; l2= 0;
bind[0].buffer_type= MYSQL_TYPE_STRING;
@@ -7571,13 +7772,15 @@ static void test_fetch_column()
rc= mysql_stmt_fetch_column(stmt, bind, 1, 0);
check_execute(stmt, rc);
- fprintf(stdout, "\n col 1: %s(%ld)", c2, l2);
+ if (!opt_silent)
+ fprintf(stdout, "\n col 1: %s(%ld)", c2, l2);
DIE_UNLESS(strncmp(c2, "venu", 4) == 0 && l2 == 4);
c2[0]= '\0'; l2= 0;
rc= mysql_stmt_fetch_column(stmt, bind, 1, 0);
check_execute(stmt, rc);
- fprintf(stdout, "\n col 1: %s(%ld)", c2, l2);
+ if (!opt_silent)
+ fprintf(stdout, "\n col 1: %s(%ld)", c2, l2);
DIE_UNLESS(strcmp(c2, "venu") == 0 && l2 == 4);
c1= 0;
@@ -7589,13 +7792,15 @@ static void test_fetch_column()
rc= mysql_stmt_fetch_column(stmt, bind, 0, 0);
check_execute(stmt, rc);
- fprintf(stdout, "\n col 0: %d(%ld)", c1, l1);
+ if (!opt_silent)
+ fprintf(stdout, "\n col 0: %d(%ld)", c1, l1);
DIE_UNLESS(c1 == 1 && l1 == 4);
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "\n row 1: %d, %s", bc1, bc2);
+ if (!opt_silent)
+ fprintf(stdout, "\n row 1: %d, %s", bc1, bc2);
c2[0]= '\0'; l2= 0;
bind[0].buffer_type= MYSQL_TYPE_STRING;
@@ -7606,13 +7811,15 @@ static void test_fetch_column()
rc= mysql_stmt_fetch_column(stmt, bind, 1, 0);
check_execute(stmt, rc);
- fprintf(stdout, "\n col 1: %s(%ld)", c2, l2);
+ if (!opt_silent)
+ fprintf(stdout, "\n col 1: %s(%ld)", c2, l2);
DIE_UNLESS(strncmp(c2, "mysq", 4) == 0 && l2 == 5);
c2[0]= '\0'; l2= 0;
rc= mysql_stmt_fetch_column(stmt, bind, 1, 0);
check_execute(stmt, rc);
- fprintf(stdout, "\n col 1: %si(%ld)", c2, l2);
+ if (!opt_silent)
+ fprintf(stdout, "\n col 1: %si(%ld)", c2, l2);
DIE_UNLESS(strcmp(c2, "mysql") == 0 && l2 == 5);
c1= 0;
@@ -7624,7 +7831,8 @@ static void test_fetch_column()
rc= mysql_stmt_fetch_column(stmt, bind, 0, 0);
check_execute(stmt, rc);
- fprintf(stdout, "\n col 0: %d(%ld)", c1, l1);
+ if (!opt_silent)
+ fprintf(stdout, "\n col 0: %d(%ld)", c1, l1);
DIE_UNLESS(c1 == 2 && l1 == 4);
rc= mysql_stmt_fetch(stmt);
@@ -7678,7 +7886,6 @@ static void test_mem_overun()
MYSQL_RES *field_res;
int rc, i, length;
-
myheader("test_mem_overun");
/*
@@ -7728,7 +7935,8 @@ static void test_mem_overun()
field_res= mysql_stmt_result_metadata(stmt);
mytest(field_res);
- fprintf(stdout, "\n total fields : %d", mysql_num_fields(field_res));
+ if (!opt_silent)
+ fprintf(stdout, "\n total fields : %d", mysql_num_fields(field_res));
DIE_UNLESS( 1000 == mysql_num_fields(field_res));
rc= mysql_stmt_store_result(stmt);
@@ -7795,7 +8003,8 @@ static void test_free_result()
rc= mysql_stmt_fetch_column(stmt, bind, 0, 0);
check_execute(stmt, rc);
- fprintf(stdout, "\n col 0: %s(%ld)", c2, l2);
+ if (!opt_silent)
+ fprintf(stdout, "\n col 0: %s(%ld)", c2, l2);
DIE_UNLESS(strncmp(c2, "1", 1) == 0 && l2 == 1);
rc= mysql_stmt_fetch(stmt);
@@ -7810,7 +8019,8 @@ static void test_free_result()
rc= mysql_stmt_fetch_column(stmt, bind, 0, 0);
check_execute(stmt, rc);
- fprintf(stdout, "\n col 0: %d(%ld)", c1, l2);
+ if (!opt_silent)
+ fprintf(stdout, "\n col 0: %d(%ld)", c1, l2);
DIE_UNLESS(c1 == 2 && l2 == 4);
rc= mysql_query(mysql, "drop table test_free_result");
@@ -7877,7 +8087,8 @@ static void test_free_store_result()
rc= mysql_stmt_fetch_column(stmt, bind, 0, 0);
check_execute(stmt, rc);
- fprintf(stdout, "\n col 1: %s(%ld)", c2, l2);
+ if (!opt_silent)
+ fprintf(stdout, "\n col 1: %s(%ld)", c2, l2);
DIE_UNLESS(strncmp(c2, "1", 1) == 0 && l2 == 1);
rc= mysql_stmt_fetch(stmt);
@@ -7892,7 +8103,8 @@ static void test_free_store_result()
rc= mysql_stmt_fetch_column(stmt, bind, 0, 0);
check_execute(stmt, rc);
- fprintf(stdout, "\n col 0: %d(%ld)", c1, l2);
+ if (!opt_silent)
+ fprintf(stdout, "\n col 0: %d(%ld)", c1, l2);
DIE_UNLESS(c1 == 2 && l2 == 4);
rc= mysql_stmt_free_result(stmt);
@@ -7924,16 +8136,19 @@ static void test_sqlmode()
/* PIPES_AS_CONCAT */
strcpy(query, "SET SQL_MODE= \"PIPES_AS_CONCAT\"");
- fprintf(stdout, "\n With %s", query);
+ if (!opt_silent)
+ fprintf(stdout, "\n With %s", query);
rc= mysql_query(mysql, query);
myquery(rc);
strcpy(query, "INSERT INTO test_piping VALUES(?||?)");
- fprintf(stdout, "\n query: %s", query);
+ if (!opt_silent)
+ fprintf(stdout, "\n query: %s", query);
stmt= mysql_simple_prepare(mysql, query);
check_stmt(stmt);
- fprintf(stdout, "\n total parameters: %ld", mysql_stmt_param_count(stmt));
+ if (!opt_silent)
+ fprintf(stdout, "\n total parameters: %ld", mysql_stmt_param_count(stmt));
/*
We need to bzero bind structure because mysql_stmt_bind_param checks all
@@ -7963,21 +8178,25 @@ static void test_sqlmode()
myquery(rc);
strcpy(query, "SELECT connection_id ()");
- fprintf(stdout, "\n query: %s", query);
+ if (!opt_silent)
+ fprintf(stdout, "\n query: %s", query);
stmt= mysql_simple_prepare(mysql, query);
check_stmt_r(stmt);
/* ANSI */
strcpy(query, "SET SQL_MODE= \"ANSI\"");
- fprintf(stdout, "\n With %s", query);
+ if (!opt_silent)
+ fprintf(stdout, "\n With %s", query);
rc= mysql_query(mysql, query);
myquery(rc);
strcpy(query, "INSERT INTO test_piping VALUES(?||?)");
- fprintf(stdout, "\n query: %s", query);
+ if (!opt_silent)
+ fprintf(stdout, "\n query: %s", query);
stmt= mysql_simple_prepare(mysql, query);
check_stmt(stmt);
- fprintf(stdout, "\n total parameters: %ld", mysql_stmt_param_count(stmt));
+ if (!opt_silent)
+ fprintf(stdout, "\n total parameters: %ld", mysql_stmt_param_count(stmt));
rc= mysql_stmt_bind_param(stmt, bind);
check_execute(stmt, rc);
@@ -7991,7 +8210,8 @@ static void test_sqlmode()
/* ANSI mode spaces ... */
strcpy(query, "SELECT connection_id ()");
- fprintf(stdout, "\n query: %s", query);
+ if (!opt_silent)
+ fprintf(stdout, "\n query: %s", query);
stmt= mysql_simple_prepare(mysql, query);
check_stmt(stmt);
@@ -8003,18 +8223,21 @@ static void test_sqlmode()
rc= mysql_stmt_fetch(stmt);
DIE_UNLESS(rc == MYSQL_NO_DATA);
- fprintf(stdout, "\n returned 1 row\n");
+ if (!opt_silent)
+ fprintf(stdout, "\n returned 1 row\n");
mysql_stmt_close(stmt);
/* IGNORE SPACE MODE */
strcpy(query, "SET SQL_MODE= \"IGNORE_SPACE\"");
- fprintf(stdout, "\n With %s", query);
+ if (!opt_silent)
+ fprintf(stdout, "\n With %s", query);
rc= mysql_query(mysql, query);
myquery(rc);
strcpy(query, "SELECT connection_id ()");
- fprintf(stdout, "\n query: %s", query);
+ if (!opt_silent)
+ fprintf(stdout, "\n query: %s", query);
stmt= mysql_simple_prepare(mysql, query);
check_stmt(stmt);
@@ -8026,7 +8249,8 @@ static void test_sqlmode()
rc= mysql_stmt_fetch(stmt);
DIE_UNLESS(rc == MYSQL_NO_DATA);
- fprintf(stdout, "\n returned 1 row");
+ if (!opt_silent)
+ fprintf(stdout, "\n returned 1 row");
mysql_stmt_close(stmt);
}
@@ -8118,7 +8342,8 @@ static void test_ts()
sprintf(query, "SELECT a, b, c FROM test_ts WHERE %c=?", name);
- fprintf(stdout, "\n %s", query);
+ if (!opt_silent)
+ fprintf(stdout, "\n %s", query);
stmt= mysql_simple_prepare(mysql, query);
check_stmt(stmt);
@@ -8131,7 +8356,8 @@ static void test_ts()
while (mysql_stmt_fetch(stmt) == 0)
row_count++;
- fprintf(stdout, "\n returned '%d' rows", row_count);
+ if (!opt_silent)
+ fprintf(stdout, "\n returned '%d' rows", row_count);
DIE_UNLESS(row_count == 2);
mysql_stmt_close(stmt);
}
@@ -8273,7 +8499,8 @@ static void test_bug1946()
check_stmt(stmt);
rc= mysql_real_query(mysql, query, strlen(query));
DIE_UNLESS(rc != 0);
- fprintf(stdout, "Got error (as expected):\n");
+ if (!opt_silent)
+ fprintf(stdout, "Got error (as expected):\n");
myerror(NULL);
mysql_stmt_close(stmt);
@@ -8291,19 +8518,23 @@ static void test_parse_error_and_bad_length()
rc= mysql_query(mysql, "SHOW DATABAAAA");
DIE_UNLESS(rc);
- fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql));
+ if (!opt_silent)
+ fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql));
rc= mysql_real_query(mysql, "SHOW DATABASES", 100);
DIE_UNLESS(rc);
- fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql));
+ if (!opt_silent)
+ fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql));
stmt= mysql_simple_prepare(mysql, "SHOW DATABAAAA");
DIE_UNLESS(!stmt);
- fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql));
+ if (!opt_silent)
+ fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql));
stmt= mysql_stmt_init(mysql);
DIE_UNLESS(stmt);
rc= mysql_stmt_prepare(stmt, "SHOW DATABASES", 100);
DIE_UNLESS(rc != 0);
- fprintf(stdout, "Got error (as expected): '%s'\n", mysql_stmt_error(stmt));
+ if (!opt_silent)
+ fprintf(stdout, "Got error (as expected): '%s'\n", mysql_stmt_error(stmt));
mysql_stmt_close(stmt);
}
@@ -8324,7 +8555,8 @@ static void test_bug2247()
myheader("test_bug2247");
- fprintf(stdout, "\nChecking if stmt_affected_rows is not affected by\n"
+ if (!opt_silent)
+ fprintf(stdout, "\nChecking if stmt_affected_rows is not affected by\n"
"mysql_query ... ");
/* create table and insert few rows */
rc= mysql_query(mysql, drop);
@@ -8381,7 +8613,8 @@ static void test_bug2247()
DIE_UNLESS(mysql_stmt_affected_rows(stmt) == exp_count);
mysql_stmt_close(stmt);
- fprintf(stdout, "OK");
+ if (!opt_silent)
+ fprintf(stdout, "OK");
}
@@ -8659,7 +8892,8 @@ static void test_bug3117()
check_execute(stmt, rc);
DIE_UNLESS(is_null == 0 && lii == 1);
- fprintf(stdout, "\n\tLAST_INSERT_ID()= 1 ok\n");
+ if (!opt_silent)
+ fprintf(stdout, "\n\tLAST_INSERT_ID()= 1 ok\n");
rc= mysql_query(mysql, "INSERT INTO t1 VALUES (NULL)");
myquery(rc);
@@ -8671,7 +8905,8 @@ static void test_bug3117()
check_execute(stmt, rc);
DIE_UNLESS(is_null == 0 && lii == 2);
- fprintf(stdout, "\tLAST_INSERT_ID()= 2 ok\n");
+ if (!opt_silent)
+ fprintf(stdout, "\tLAST_INSERT_ID()= 2 ok\n");
mysql_stmt_close(stmt);
@@ -8821,7 +9056,8 @@ static void test_create_drop()
{
rc= mysql_stmt_execute(stmt_create);
check_execute(stmt_create, rc);
- fprintf(stdout, "created %i\n", i);
+ if (!opt_silent)
+ fprintf(stdout, "created %i\n", i);
rc= mysql_stmt_execute(stmt_select);
check_execute(stmt_select, rc);
@@ -8830,11 +9066,13 @@ static void test_create_drop()
rc= mysql_stmt_execute(stmt_drop);
check_execute(stmt_drop, rc);
- fprintf(stdout, "droped %i\n", i);
+ if (!opt_silent)
+ fprintf(stdout, "droped %i\n", i);
rc= mysql_stmt_execute(stmt_create_select);
check_execute(stmt_create, rc);
- fprintf(stdout, "created select %i\n", i);
+ if (!opt_silent)
+ fprintf(stdout, "created select %i\n", i);
rc= mysql_stmt_execute(stmt_select);
check_execute(stmt_select, rc);
@@ -8843,7 +9081,8 @@ static void test_create_drop()
rc= mysql_stmt_execute(stmt_drop);
check_execute(stmt_drop, rc);
- fprintf(stdout, "droped %i\n", i);
+ if (!opt_silent)
+ fprintf(stdout, "droped %i\n", i);
}
mysql_stmt_close(stmt_create);
@@ -8874,25 +9113,29 @@ static void test_rename()
rc= mysql_stmt_execute(stmt);
check_execute_r(stmt, rc);
- fprintf(stdout, "rename without t3\n");
+ if (!opt_silent)
+ fprintf(stdout, "rename without t3\n");
rc= mysql_query(mysql, "create table t3 (a int)");
myquery(rc);
rc= mysql_stmt_execute(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "rename with t3\n");
+ if (!opt_silent)
+ fprintf(stdout, "rename with t3\n");
rc= mysql_stmt_execute(stmt);
check_execute_r(stmt, rc);
- fprintf(stdout, "rename renamed\n");
+ if (!opt_silent)
+ fprintf(stdout, "rename renamed\n");
rc= mysql_query(mysql, "rename table t2 to t1, t4 to t3");
myquery(rc);
rc= mysql_stmt_execute(stmt);
check_execute(stmt, rc);
- fprintf(stdout, "rename reverted\n");
+ if (!opt_silent)
+ fprintf(stdout, "rename reverted\n");
mysql_stmt_close(stmt);
@@ -8926,10 +9169,12 @@ static void test_do_set()
{
rc= mysql_stmt_execute(stmt_do);
check_execute(stmt_do, rc);
- fprintf(stdout, "do %i\n", i);
+ if (!opt_silent)
+ fprintf(stdout, "do %i\n", i);
rc= mysql_stmt_execute(stmt_set);
check_execute(stmt_set, rc);
- fprintf(stdout, "set %i\n", i);
+ if (!opt_silent)
+ fprintf(stdout, "set %i\n", i);
}
mysql_stmt_close(stmt_do);
@@ -8995,11 +9240,13 @@ static void test_multi()
rc= mysql_stmt_execute(stmt_update);
check_execute(stmt_update, rc);
- fprintf(stdout, "update %ld\n", (long) param);
+ if (!opt_silent)
+ fprintf(stdout, "update %ld\n", (long) param);
rc= mysql_stmt_execute(stmt_delete);
check_execute(stmt_delete, rc);
- fprintf(stdout, "delete %ld\n", (long) param);
+ if (!opt_silent)
+ fprintf(stdout, "delete %ld\n", (long) param);
rc= mysql_stmt_execute(stmt_select1);
check_execute(stmt_select1, rc);
@@ -9055,7 +9302,8 @@ static void test_insert_select()
{
rc= mysql_stmt_execute(stmt_insert);
check_execute(stmt_insert, rc);
- fprintf(stdout, "insert %u\n", i);
+ if (!opt_silent)
+ fprintf(stdout, "insert %u\n", i);
rc= mysql_stmt_execute(stmt_select);
check_execute(stmt_select, rc);
@@ -9915,7 +10163,8 @@ static void test_bug3796()
mysql_stmt_bind_result(stmt, bind);
rc= mysql_stmt_fetch(stmt);
- printf("Concat result: '%s'\n", out_buff);
+ if (!opt_silent)
+ printf("Concat result: '%s'\n", out_buff);
check_execute(stmt, rc);
strcpy(canonical_buff, concat_arg0);
strcat(canonical_buff, "ONE");
@@ -9927,7 +10176,8 @@ static void test_bug3796()
strcpy(canonical_buff + strlen(concat_arg0), "TWO");
DIE_UNLESS(strlen(canonical_buff) == out_length &&
strncmp(out_buff, canonical_buff, out_length) == 0);
- printf("Concat result: '%s'\n", out_buff);
+ if (!opt_silent)
+ printf("Concat result: '%s'\n", out_buff);
rc= mysql_stmt_fetch(stmt);
DIE_UNLESS(rc == MYSQL_NO_DATA);
@@ -10001,12 +10251,15 @@ static void test_bug4026()
rc= mysql_stmt_fetch(stmt);
DIE_UNLESS(rc == 0);
- printf("%d:%d:%d.%lu\n", time_out.hour, time_out.minute, time_out.second,
- time_out.second_part);
- printf("%d-%d-%d %d:%d:%d.%lu\n", datetime_out.year, datetime_out.month,
- datetime_out.day, datetime_out.hour,
- datetime_out.minute, datetime_out.second,
- datetime_out.second_part);
+ if (!opt_silent)
+ {
+ printf("%d:%d:%d.%lu\n", time_out.hour, time_out.minute, time_out.second,
+ time_out.second_part);
+ printf("%d-%d-%d %d:%d:%d.%lu\n", datetime_out.year, datetime_out.month,
+ datetime_out.day, datetime_out.hour,
+ datetime_out.minute, datetime_out.second,
+ datetime_out.second_part);
+ }
DIE_UNLESS(memcmp(&time_in, &time_out, sizeof(time_in)) == 0);
DIE_UNLESS(memcmp(&datetime_in, &datetime_out, sizeof(datetime_in)) == 0);
mysql_stmt_close(stmt);
@@ -10049,8 +10302,9 @@ static void test_bug4079()
rc= mysql_stmt_fetch(stmt);
DIE_UNLESS(rc != 0 && rc != MYSQL_NO_DATA);
- printf("Got error from mysql_stmt_fetch (as expected):\n%s\n",
- mysql_stmt_error(stmt));
+ if (!opt_silent)
+ printf("Got error from mysql_stmt_fetch (as expected):\n%s\n",
+ mysql_stmt_error(stmt));
/* buggy version of libmysql hanged up here */
mysql_stmt_close(stmt);
}
@@ -10144,13 +10398,16 @@ static void test_bug4030()
rc= mysql_stmt_fetch(stmt);
DIE_UNLESS(rc == 0);
- printf("%d:%d:%d.%lu\n", time_out.hour, time_out.minute, time_out.second,
- time_out.second_part);
- printf("%d-%d-%d\n", date_out.year, date_out.month, date_out.day);
- printf("%d-%d-%d %d:%d:%d.%lu\n", datetime_out.year, datetime_out.month,
- datetime_out.day, datetime_out.hour,
- datetime_out.minute, datetime_out.second,
- datetime_out.second_part);
+ if (!opt_silent)
+ {
+ printf("%d:%d:%d.%lu\n", time_out.hour, time_out.minute, time_out.second,
+ time_out.second_part);
+ printf("%d-%d-%d\n", date_out.year, date_out.month, date_out.day);
+ printf("%d-%d-%d %d:%d:%d.%lu\n", datetime_out.year, datetime_out.month,
+ datetime_out.day, datetime_out.hour,
+ datetime_out.minute, datetime_out.second,
+ datetime_out.second_part);
+ }
DIE_UNLESS(memcmp(&time_canonical, &time_out, sizeof(time_out)) == 0);
DIE_UNLESS(memcmp(&date_canonical, &date_out, sizeof(date_out)) == 0);
DIE_UNLESS(memcmp(&datetime_canonical, &datetime_out, sizeof(datetime_out)) == 0);
@@ -10200,7 +10457,8 @@ static void test_bug5126()
rc= mysql_stmt_fetch(stmt);
DIE_UNLESS(rc == 0);
DIE_UNLESS(c1 == 8386608 && c2 == 1);
- printf("%ld, %ld\n", (long) c1, (long) c2);
+ if (!opt_silent)
+ printf("%ld, %ld\n", (long) c1, (long) c2);
mysql_stmt_close(stmt);
}
@@ -10306,7 +10564,8 @@ static void test_bug5399()
check_execute(*stmt, rc);
mysql_stmt_bind_result(*stmt, bind);
}
- printf("%d statements prepared.\n", NUM_OF_USED_STMT);
+ if (!opt_silent)
+ printf("%d statements prepared.\n", NUM_OF_USED_STMT);
for (stmt= stmt_list; stmt != stmt_list + NUM_OF_USED_STMT; ++stmt)
{
@@ -10478,15 +10737,17 @@ static void test_bug5194()
rc= mysql_stmt_prepare(stmt, query, query_ptr - query);
if (rc && nrows * COLUMN_COUNT > uint16_max)
{
- printf("Failed to prepare a statement with %d placeholders "
- "(as expected).\n", nrows * COLUMN_COUNT);
+ if (!opt_silent)
+ printf("Failed to prepare a statement with %d placeholders "
+ "(as expected).\n", nrows * COLUMN_COUNT);
break;
}
else
check_execute(stmt, rc);
- printf("Insert: query length= %d, row count= %d, param count= %lu\n",
- strlen(query), nrows, mysql_stmt_param_count(stmt));
+ if (!opt_silent)
+ printf("Insert: query length= %d, row count= %d, param count= %lu\n",
+ strlen(query), nrows, mysql_stmt_param_count(stmt));
/* bind the parameter array and execute the query */
rc= mysql_stmt_bind_param(stmt, bind);
@@ -10522,7 +10783,10 @@ static void test_bug5315()
rc= mysql_stmt_execute(stmt);
DIE_UNLESS(rc != 0);
if (rc)
- printf("Got error (as expected):\n%s", mysql_stmt_error(stmt));
+ {
+ if (!opt_silent)
+ printf("Got error (as expected):\n%s", mysql_stmt_error(stmt));
+ }
/* check that connection is OK */
mysql_stmt_close(stmt);
stmt= mysql_stmt_init(mysql);
@@ -10570,8 +10834,11 @@ static void test_bug6049()
rc= mysql_stmt_fetch(stmt);
DIE_UNLESS(rc == 0);
- printf("Result from query: %s\n", row[0]);
- printf("Result from prepared statement: %s\n", (char*) buffer);
+ if (!opt_silent)
+ {
+ printf("Result from query: %s\n", row[0]);
+ printf("Result from prepared statement: %s\n", (char*) buffer);
+ }
DIE_UNLESS(strcmp(row[0], (char*) buffer) == 0);
@@ -10616,8 +10883,11 @@ static void test_bug6058()
rc= mysql_stmt_fetch(stmt);
DIE_UNLESS(rc == 0);
- printf("Result from query: %s\n", row[0]);
- printf("Result from prepared statement: %s\n", buffer);
+ if (!opt_silent)
+ {
+ printf("Result from query: %s\n", row[0]);
+ printf("Result from prepared statement: %s\n", buffer);
+ }
DIE_UNLESS(strcmp(row[0], buffer) == 0);
@@ -10656,17 +10926,17 @@ static void test_bug6046()
stmt_text= "DROP TABLE IF EXISTS t1";
rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
myquery(rc);
- stmt_text= "CREATE TABLE a1 (a int, b int)";
+ stmt_text= "CREATE TABLE t1 (a int, b int)";
rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
myquery(rc);
- stmt_text= "INSERT INTO a1 VALUES (1,1),(2,2),(3,1),(4,2)";
+ stmt_text= "INSERT INTO t1 VALUES (1,1),(2,2),(3,1),(4,2)";
rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
myquery(rc);
stmt= mysql_stmt_init(mysql);
- stmt_text= "SELECT a1.a FROM a1 NATURAL JOIN a1 as X1 "
- "WHERE a1.b > ? ORDER BY a1.a";
+ stmt_text= "SELECT t1.a FROM t1 NATURAL JOIN t1 as X1 "
+ "WHERE t1.b > ? ORDER BY t1.a";
rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
check_execute(stmt, rc);
@@ -10772,22 +11042,25 @@ static void test_bug6096()
/* Print out and check the metadata */
- printf(" ---------------------------------------------------------------\n");
- printf(" | Metadata \n");
- printf(" ---------------------------------------------------------------\n");
- printf(" | Query | Prepared statement \n");
- printf(" ---------------------------------------------------------------\n");
- printf(" field name | length | max_length | length | max_length \n");
- printf(" ---------------------------------------------------------------\n");
-
- for (i= 0; i < query_field_count; ++i)
+ if (!opt_silent)
{
- MYSQL_FIELD *f1= &query_field_list[i], *f2= &stmt_field_list[i];
- printf(" %-11s | %9lu | %10lu | %9lu | %10lu \n",
- f1->name, f1->length, f1->max_length, f2->length, f2->max_length);
- DIE_UNLESS(f1->length == f2->length);
+ printf(" ------------------------------------------------------------\n");
+ printf(" | Metadata \n");
+ printf(" ------------------------------------------------------------\n");
+ printf(" | Query | Prepared statement \n");
+ printf(" ------------------------------------------------------------\n");
+ printf(" field name | length | max_length | length | max_length\n");
+ printf(" ------------------------------------------------------------\n");
+
+ for (i= 0; i < query_field_count; ++i)
+ {
+ MYSQL_FIELD *f1= &query_field_list[i], *f2= &stmt_field_list[i];
+ printf(" %-11s | %9lu | %10lu | %9lu | %10lu \n",
+ f1->name, f1->length, f1->max_length, f2->length, f2->max_length);
+ DIE_UNLESS(f1->length == f2->length);
+ }
+ printf(" ---------------------------------------------------------------\n");
}
- printf(" ---------------------------------------------------------------\n");
/* Bind and fetch the data */
@@ -10842,6 +11115,8 @@ static struct my_option client_test_long_options[] =
#endif
{"port", 'P', "Port number to use for connection", (char **) &opt_port,
(char **) &opt_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"silent", 's', "Be more silent", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0,
+ 0},
{"socket", 'S', "Socket file to use for connection", (char **) &opt_unix_socket,
(char **) &opt_unix_socket, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"testcase", 'c', "May disable some code when runs as mysql-test-run testcase.",
@@ -10851,36 +11126,25 @@ static struct my_option client_test_long_options[] =
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
-static void client_test_print_version(void)
-{
- fprintf(stdout, "%s Distrib %s, for %s (%s)\n\n",
- my_progname, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE);
-}
-
static void usage(void)
{
- /*
- * show the usage string when the user asks for this
- */
+ /* show the usage string when the user asks for this */
putc('\n', stdout);
- puts("***********************************************************************\n");
- puts(" Test for client-server protocol 4.1");
- puts(" By Monty & Venu \n");
- puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software, ");
- puts("and you are welcome to modify and redistribute it under the GPL license\n");
- puts(" Copyright (C) 1995-2003 MySQL AB ");
- puts("-----------------------------------------------------------------------\n");
- client_test_print_version();
- fprintf(stdout, "Usage: %s [OPTIONS]\n\n", my_progname);
-
+ printf("%s Ver %s Distrib %s, for %s (%s)\n",
+ my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE);
+ puts("By Monty, Venu, Kent and others\n");
+ printf("\
+Copyright (C) 2002-2004 MySQL AB\n\
+This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\
+and you are welcome to modify and redistribute it under the GPL license\n");
+ printf("Usage: %s [OPTIONS]\n", my_progname);
my_print_help(client_test_long_options);
print_defaults("my", client_test_load_default_groups);
my_print_variables(client_test_long_options);
-
- puts("***********************************************************************\n");
}
+
static my_bool
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
char *argument)
@@ -10905,6 +11169,12 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
else
tty_password= 1;
break;
+ case 's':
+ if (argument == disabled_my_option)
+ opt_silent= 0;
+ else
+ opt_silent++;
+ break;
case '?':
case 'I': /* Info */
usage();
@@ -10933,14 +11203,17 @@ static void get_options(int argc, char **argv)
static void print_test_output()
{
- fprintf(stdout, "\n\n");
- fprintf(stdout, "All '%d' tests were successful (in '%d' iterations)",
- test_count-1, opt_count);
- fprintf(stdout, "\n Total execution time: %g SECS", total_time);
- if (opt_count > 1)
- fprintf(stdout, " (Avg: %g SECS)", total_time/opt_count);
+ if (opt_silent < 3)
+ {
+ fprintf(stdout, "\n\n");
+ fprintf(stdout, "All '%d' tests were successful (in '%d' iterations)",
+ test_count-1, opt_count);
+ fprintf(stdout, "\n Total execution time: %g SECS", total_time);
+ if (opt_count > 1)
+ fprintf(stdout, " (Avg: %g SECS)", total_time/opt_count);
- fprintf(stdout, "\n\n!!! SUCCESS !!!\n");
+ fprintf(stdout, "\n\n!!! SUCCESS !!!\n");
+ }
}
From ded5595cb2d21ffbb886b03767084f1d4a81a231 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Tue, 2 Nov 2004 19:40:10 +0000
Subject: [PATCH 49/59] add compile flad -DSNPRINTF_RETURN_TRUNC on hp ux
11 remove compiler warning patch for my_vsnprintf not dully
implemented patch for platfroms that return -1 on snprintf overflow
compile fix for hpux
---
configure.in | 4 ++--
ndb/src/common/editline/sysunix.c | 2 +-
ndb/src/common/util/basestring_vsnprintf.c | 8 ++++++--
ndb/src/kernel/vm/Emulator.hpp | 1 +
ndb/src/mgmsrv/Services.cpp | 22 ++++++++--------------
ndb/src/ndbapi/NdbDictionaryImpl.cpp | 6 ++----
6 files changed, 20 insertions(+), 23 deletions(-)
diff --git a/configure.in b/configure.in
index d63859720a3..71adaa747f5 100644
--- a/configure.in
+++ b/configure.in
@@ -1039,8 +1039,8 @@ case $SYSTEM_TYPE in
;;
*hpux11.*)
echo "Enabling workarounds for hpux 11"
- CFLAGS="$CFLAGS -DHPUX11 -DHAVE_BROKEN_PREAD -DDONT_USE_FINITE -DHAVE_BROKEN_GETPASS -DNO_FCNTL_NONBLOCK -DDO_NOT_REMOVE_THREAD_WRAPPERS -DHAVE_BROKEN_PTHREAD_COND_TIMEDWAIT"
- CXXFLAGS="$CXXFLAGS -DHPUX11 -DHAVE_BROKEN_PREAD -DDONT_USE_FINITE -D_INCLUDE_LONGLONG -DNO_FCNTL_NONBLOCK -DDO_NOT_REMOVE_THREAD_WRAPPERS -DHAVE_BROKEN_PTHREAD_COND_TIMEDWAIT"
+ CFLAGS="$CFLAGS -DHPUX11 -DSNPRINTF_RETURN_TRUNC -DHAVE_BROKEN_PREAD -DDONT_USE_FINITE -DHAVE_BROKEN_GETPASS -DNO_FCNTL_NONBLOCK -DDO_NOT_REMOVE_THREAD_WRAPPERS -DHAVE_BROKEN_PTHREAD_COND_TIMEDWAIT"
+ CXXFLAGS="$CXXFLAGS -DHPUX11 -DSNPRINTF_RETURN_TRUNC -DHAVE_BROKEN_PREAD -DDONT_USE_FINITE -D_INCLUDE_LONGLONG -DNO_FCNTL_NONBLOCK -DDO_NOT_REMOVE_THREAD_WRAPPERS -DHAVE_BROKEN_PTHREAD_COND_TIMEDWAIT"
if test "$with_named_thread" = "no"
then
echo "Using --with-named-thread=-lpthread"
diff --git a/ndb/src/common/editline/sysunix.c b/ndb/src/common/editline/sysunix.c
index 1339e5769e2..d7437f6a9c7 100644
--- a/ndb/src/common/editline/sysunix.c
+++ b/ndb/src/common/editline/sysunix.c
@@ -139,7 +139,7 @@ rl_add_slash(char *path, char *p, size_t p_len)
struct stat Sb;
if (stat(path, &Sb) >= 0) {
- int len= strlen(p);
+ size_t len= strlen(p);
if (len+1 < p_len) {
p[len]= S_ISDIR(Sb.st_mode) ? '/' : ' ';
p[len+1]= 0;
diff --git a/ndb/src/common/util/basestring_vsnprintf.c b/ndb/src/common/util/basestring_vsnprintf.c
index c96d1a300e1..7307279f345 100644
--- a/ndb/src/common/util/basestring_vsnprintf.c
+++ b/ndb/src/common/util/basestring_vsnprintf.c
@@ -35,7 +35,11 @@ basestring_snprintf(char *str, size_t size, const char *format, ...)
#define BASESTRING_VSNPRINTF_FUNC(a,b,c,d) vsnprintf(a,b,c,d)
#else
#define SNPRINTF_RETURN_TRUNC
- #define BASESTRING_VSNPRINTF_FUNC(a,b,c,d) my_vsnprintf(a,b,c,d)
+ /* #define BASESTRING_VSNPRINTF_FUNC(a,b,c,d) my_vsnprintf(a,b,c,d)
+ * we would like to use my_vsnprintf but it does not have enough features
+ * Let's hope vsnprintf works anyways
+ */
+ #define BASESTRING_VSNPRINTF_FUNC(a,b,c,d) vsnprintf(a,b,c,d)
extern int my_vsnprintf(char *str, size_t size, const char *format, va_list ap);
#endif
#ifdef SNPRINTF_RETURN_TRUNC
@@ -46,7 +50,7 @@ basestring_vsnprintf(char *str, size_t size, const char *format, va_list ap)
{
int ret= BASESTRING_VSNPRINTF_FUNC(str, size, format, ap);
#ifdef SNPRINTF_RETURN_TRUNC
- if (ret == size-1) {
+ if (ret == size-1 || ret == -1) {
ret= BASESTRING_VSNPRINTF_FUNC(basestring_vsnprintf_buf,
sizeof(basestring_vsnprintf_buf),
format, ap);
diff --git a/ndb/src/kernel/vm/Emulator.hpp b/ndb/src/kernel/vm/Emulator.hpp
index bd240f8679b..b3c64830802 100644
--- a/ndb/src/kernel/vm/Emulator.hpp
+++ b/ndb/src/kernel/vm/Emulator.hpp
@@ -25,6 +25,7 @@
//
//===========================================================================
#include
+#include
extern class JobTable globalJobTable;
extern class TimeQueue globalTimeQueue;
diff --git a/ndb/src/mgmsrv/Services.cpp b/ndb/src/mgmsrv/Services.cpp
index 5b552836955..2672d8c9d4b 100644
--- a/ndb/src/mgmsrv/Services.cpp
+++ b/ndb/src/mgmsrv/Services.cpp
@@ -773,8 +773,10 @@ MgmApiSession::setClusterLogLevel(Parser::Context &,
/* XXX should use constants for this value */
if(level > 15) {
- errorString.assign("Invalied loglevel");
- goto error;
+ m_output->println("set cluster loglevel reply");
+ m_output->println("result: Invalid loglevel");
+ m_output->println("");
+ return;
}
EventSubscribeReq req;
@@ -786,11 +788,6 @@ MgmApiSession::setClusterLogLevel(Parser::Context &,
m_output->println("set cluster loglevel reply");
m_output->println("result: Ok");
m_output->println("");
- return;
-error:
- m_output->println("set cluster loglevel reply");
- m_output->println("result: %s", errorString.c_str());
- m_output->println("");
}
void
@@ -807,8 +804,10 @@ MgmApiSession::setLogLevel(Parser::Context &,
/* XXX should use constants for this value */
if(level > 15) {
- errorString.assign("Invalied loglevel");
- goto error;
+ m_output->println("set loglevel reply");
+ m_output->println("result: Invalid loglevel", errorString.c_str());
+ m_output->println("");
+ return;
}
EventSubscribeReq req;
@@ -820,11 +819,6 @@ MgmApiSession::setLogLevel(Parser::Context &,
m_output->println("set loglevel reply");
m_output->println("result: Ok");
m_output->println("");
- return;
- error:
- m_output->println("set loglevel reply");
- m_output->println("result: %s", errorString.c_str());
- m_output->println("");
}
void
diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/ndb/src/ndbapi/NdbDictionaryImpl.cpp
index 76854cabcd7..304d1b904d4 100644
--- a/ndb/src/ndbapi/NdbDictionaryImpl.cpp
+++ b/ndb/src/ndbapi/NdbDictionaryImpl.cpp
@@ -47,15 +47,13 @@
* Column
*/
NdbColumnImpl::NdbColumnImpl()
- : NdbDictionary::Column(* this), m_facade(this),
- m_attrId(-1)
+ : NdbDictionary::Column(* this), m_attrId(-1), m_facade(this)
{
init();
}
NdbColumnImpl::NdbColumnImpl(NdbDictionary::Column & f)
- : NdbDictionary::Column(* this), m_facade(&f),
- m_attrId(-1)
+ : NdbDictionary::Column(* this), m_attrId(-1), m_facade(&f)
{
init();
}
From dd5486a5999d27c204e128aaafb3cb3f9076372b Mon Sep 17 00:00:00 2001
From: "serg@serg.mylan" <>
Date: Tue, 2 Nov 2004 22:46:55 +0100
Subject: [PATCH 50/59] one more name clash in public includes fixed
http://lists.mysql.com/internals/18149
---
include/my_list.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/my_list.h b/include/my_list.h
index 789bbb50f97..f786621e311 100644
--- a/include/my_list.h
+++ b/include/my_list.h
@@ -33,8 +33,8 @@ extern LIST *list_delete(LIST *root,LIST *element);
extern LIST *list_cons(void *data,LIST *root);
extern LIST *list_reverse(LIST *root);
extern void list_free(LIST *root,unsigned int free_data);
-extern unsigned int list_length(LIST *list);
-extern int list_walk(LIST *list,list_walk_action action,gptr argument);
+extern unsigned int list_length(LIST *);
+extern int list_walk(LIST *,list_walk_action action,gptr argument);
#define rest(a) ((a)->next)
#define list_push(a,b) (a)=list_cons((b),(a))
From 4650f0acab425e08b5f3f7f7bee9612f81387b6e Mon Sep 17 00:00:00 2001
From: "serg@serg.mylan" <>
Date: Tue, 2 Nov 2004 23:34:40 +0100
Subject: [PATCH 51/59] bad automerge (?) fixed
---
tests/client_test.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/tests/client_test.c b/tests/client_test.c
index 70e1b26aeaa..227f7e29ef2 100644
--- a/tests/client_test.c
+++ b/tests/client_test.c
@@ -815,7 +815,6 @@ end:
static void test_debug_example()
{
- DBUG_ENTER("fill_tables");
int rc;
MYSQL_RES *result;
From 45451568bfabaaf42d5f55c05c57a716ceb42798 Mon Sep 17 00:00:00 2001
From: "bar@mysql.com" <>
Date: Wed, 3 Nov 2004 15:22:33 +0400
Subject: [PATCH 52/59] opt_range.cc, range.result, range.test: Bug #6045:
Binary Comparison regression in MySQL 4.1 Binary searches didn't use a case
insensitive index, now they do.
---
mysql-test/r/range.result | 16 ++++++++++++++++
mysql-test/t/range.test | 14 ++++++++++++++
sql/opt_range.cc | 15 ++++++++++++---
3 files changed, 42 insertions(+), 3 deletions(-)
diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result
index 4ca96316800..17ed9513653 100644
--- a/mysql-test/r/range.result
+++ b/mysql-test/r/range.result
@@ -561,3 +561,19 @@ select count(*) from t1 where x = 18446744073709551601;
count(*)
1
drop table t1;
+set names latin1;
+create table t1 (a char(10), b text, key (a)) character set latin1;
+INSERT INTO t1 (a) VALUES
+('111'),('222'),('222'),('222'),('222'),('444'),('aaa'),('AAA'),('bbb');
+explain select * from t1 where a='aaa';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref a a 11 const 2 Using where
+explain select * from t1 where a=binary 'aaa';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 11 NULL 2 Using where
+explain select * from t1 where a='aaa' collate latin1_bin;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 11 NULL 2 Using where
+explain select * from t1 where a='aaa' collate latin1_german1_ci;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL a NULL NULL NULL 9 Using where
diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test
index cd6620f7126..44f55da5722 100644
--- a/mysql-test/t/range.test
+++ b/mysql-test/t/range.test
@@ -431,3 +431,17 @@ select count(*) from t1 where x = 18446744073709551601;
drop table t1;
+#
+# Bug #6045: Binary Comparison regression in MySQL 4.1
+# Binary searches didn't use a case insensitive index.
+#
+set names latin1;
+create table t1 (a char(10), b text, key (a)) character set latin1;
+INSERT INTO t1 (a) VALUES
+('111'),('222'),('222'),('222'),('222'),('444'),('aaa'),('AAA'),('bbb');
+# all these three can be optimized
+explain select * from t1 where a='aaa';
+explain select * from t1 where a=binary 'aaa';
+explain select * from t1 where a='aaa' collate latin1_bin;
+# this one cannot:
+explain select * from t1 where a='aaa' collate latin1_german1_ci;
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 541acc69ec7..c9528af7d98 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -1013,13 +1013,22 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
}
/*
- We can't use an index when comparing strings of
- different collations
+ 1. Usually we can't use an index if the column collation
+ differ from the operation collation.
+
+ 2. However, we can reuse a case insensitive index for
+ the binary searches:
+
+ WHERE latin1_swedish_ci_column = 'a' COLLATE lati1_bin;
+
+ WHERE latin1_swedish_ci_colimn = BINARY 'a '
+
*/
if (field->result_type() == STRING_RESULT &&
value->result_type() == STRING_RESULT &&
key_part->image_type == Field::itRAW &&
- ((Field_str*)field)->charset() != conf_func->compare_collation())
+ ((Field_str*)field)->charset() != conf_func->compare_collation() &&
+ !(conf_func->compare_collation()->state & MY_CS_BINSORT))
DBUG_RETURN(0);
if (type == Item_func::LIKE_FUNC)
From 2356c9f9959d2487dbf615d4a064df4f6c77b792 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Wed, 3 Nov 2004 11:43:46 +0000
Subject: [PATCH 53/59] mysql-master-run does not need to start second mysqld
with innodb, add --skip-innodb
---
mysql-test/mysql-test-run.sh | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh
index 6b40fb3e974..65be9bf9c8e 100644
--- a/mysql-test/mysql-test-run.sh
+++ b/mysql-test/mysql-test-run.sh
@@ -994,9 +994,11 @@ start_master()
if [ -n "$1" ] ; then
id=`$EXPR $1 + 101`;
this_master_myport=`$EXPR $MASTER_MYPORT + $1`
+ NOT_FIRST_MASTER_EXTRA_OPTS="--skip-innodb"
else
id=1;
this_master_myport=$MASTER_MYPORT
+ NOT_FIRST_MASTER_EXTRA_OPTS=""
fi
if [ -z "$DO_BENCH" ]
then
@@ -1020,7 +1022,8 @@ start_master()
--open-files-limit=1024 \
$MASTER_40_ARGS \
$SMALL_SERVER \
- $EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT"
+ $EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT \
+ $NOT_FIRST_MASTER_EXTRA_OPTS"
else
master_args="--no-defaults --log-bin=$MYSQL_TEST_DIR/var/log/master-bin$1 \
--server-id=$id --rpl-recovery-rank=1 \
@@ -1039,7 +1042,8 @@ start_master()
--innodb_data_file_path=ibdata1:50M \
$MASTER_40_ARGS \
$SMALL_SERVER \
- $EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT"
+ $EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT \
+ $NOT_FIRST_MASTER_EXTRA_OPTS"
fi
CUR_MYERR=$MASTER_MYERR
From 0fd9d08c0189592edd8fb1651f15ceb48f3c08d6 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Wed, 3 Nov 2004 14:34:21 +0000
Subject: [PATCH 54/59] changed to use the future-proof option to ndb_mgmd
there was a clash in using -c, added -f as the future proof switch
---
mysql-test/ndb/ndbcluster.sh | 2 +-
ndb/src/mgmsrv/main.cpp | 27 +++++++++++++++++++++++++--
2 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/mysql-test/ndb/ndbcluster.sh b/mysql-test/ndb/ndbcluster.sh
index 294d32ac4be..9d83a291f3d 100644
--- a/mysql-test/ndb/ndbcluster.sh
+++ b/mysql-test/ndb/ndbcluster.sh
@@ -146,7 +146,7 @@ fi
rm -f "$cfgfile" 2>&1 | cat > /dev/null
rm -f "$fs_ndb/$cfgfile" 2>&1 | cat > /dev/null
-if ( cd "$fs_ndb" ; $exec_mgmtsrvr -c config.ini ) ; then :; else
+if ( cd "$fs_ndb" ; $exec_mgmtsrvr -f config.ini ) ; then :; else
echo "Unable to start $exec_mgmtsrvr from `pwd`"
exit 1
fi
diff --git a/ndb/src/mgmsrv/main.cpp b/ndb/src/mgmsrv/main.cpp
index c1876f68ea2..15767e4766d 100644
--- a/ndb/src/mgmsrv/main.cpp
+++ b/ndb/src/mgmsrv/main.cpp
@@ -101,8 +101,23 @@ static char *opt_connect_str= 0;
static struct my_option my_long_options[] =
{
- NDB_STD_OPTS("ndb_mgmd"),
- { "config-file", 'c', "Specify cluster configuration file",
+#ifndef DBUG_OFF
+ { "debug", '#', "Output debug log. Often this is 'd:t:o,filename'.",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0 },
+#endif
+ { "usage", '?', "Display this help and exit.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 },
+ { "help", '?', "Display this help and exit.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 },
+ { "version", 'V', "Output version information and exit.", 0, 0, 0,
+ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 },
+ { "connect-string", 1023,
+ "Set connect string for connecting to ndb_mgmd. "
+ "=\"host=[;nodeid=]\". "
+ "Overides specifying entries in NDB_CONNECTSTRING and config file",
+ (gptr*) &opt_connect_str, (gptr*) &opt_connect_str, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+ { "config-file", 'f', "Specify cluster configuration file",
(gptr*) &glob.config_filename, (gptr*) &glob.config_filename, 0,
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
{ "daemon", 'd', "Run ndb_mgmd in daemon mode (default)",
@@ -120,6 +135,11 @@ static struct my_option my_long_options[] =
{ "nodaemon", 258, "Don't run as daemon, but don't read from stdin",
(gptr*) &glob.non_interactive, (gptr*) &glob.non_interactive, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
+ { "config-file", 'c',
+ "-c provided for backwards compatability, will be removed in 5.0."
+ " Use -f instead",
+ (gptr*) &glob.config_filename, (gptr*) &glob.config_filename, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
static void short_usage_sub(void)
@@ -148,6 +168,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
case 'V':
print_version();
exit(0);
+ case 'c':
+ printf("Warning: -c will be removed in 5.0, use -f instead\n");
+ break;
case '?':
usage();
exit(0);
From 485de9cbb7585b5eb1ac97ca92248e1fa1704825 Mon Sep 17 00:00:00 2001
From: "lars@mysql.com" <>
Date: Wed, 3 Nov 2004 18:23:58 +0100
Subject: [PATCH 55/59] Fix for bug#5551 (Version 4). The idea of the fix is
that the administrative statements OPTIMIZE TABLE, REPAIR TABLE and ANALYZE
TABLE should not generate binlog errors if there is no errors on the master.
---
BitKeeper/etc/logging_ok | 1 +
mysql-test/r/rpl_failed_optimize.result | 15 +++++++++++++++
mysql-test/t/rpl_failed_optimize-master.opt | 1 +
mysql-test/t/rpl_failed_optimize.test | 18 ++++++++++++++++++
sql/sql_parse.cc | 3 +++
sql/sql_table.cc | 6 ++++++
6 files changed, 44 insertions(+)
create mode 100644 mysql-test/r/rpl_failed_optimize.result
create mode 100644 mysql-test/t/rpl_failed_optimize-master.opt
create mode 100644 mysql-test/t/rpl_failed_optimize.test
diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok
index 953ddf7b564..ac02fa84bbc 100644
--- a/BitKeeper/etc/logging_ok
+++ b/BitKeeper/etc/logging_ok
@@ -95,6 +95,7 @@ kaj@work.mysql.com
kent@mysql.com
konstantin@mysql.com
kostja@oak.local
+lars@mysql.com
lenz@kallisto.mysql.com
lenz@mysql.com
magnus@neptunus.(none)
diff --git a/mysql-test/r/rpl_failed_optimize.result b/mysql-test/r/rpl_failed_optimize.result
new file mode 100644
index 00000000000..1576ec60500
--- /dev/null
+++ b/mysql-test/r/rpl_failed_optimize.result
@@ -0,0 +1,15 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+CREATE TABLE t1 ( a int ) ENGINE=InnoDB;
+BEGIN;
+INSERT INTO t1 VALUES (1);
+OPTIMIZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 optimize status Operation failed
+OPTIMIZE TABLE non_existing;
+Table Op Msg_type Msg_text
+test.non_existing optimize error Table 'test.non_existing' doesn't exist
diff --git a/mysql-test/t/rpl_failed_optimize-master.opt b/mysql-test/t/rpl_failed_optimize-master.opt
new file mode 100644
index 00000000000..a6ef074a120
--- /dev/null
+++ b/mysql-test/t/rpl_failed_optimize-master.opt
@@ -0,0 +1 @@
+--innodb-lock-wait-timeout=1
diff --git a/mysql-test/t/rpl_failed_optimize.test b/mysql-test/t/rpl_failed_optimize.test
new file mode 100644
index 00000000000..d245d1bacbb
--- /dev/null
+++ b/mysql-test/t/rpl_failed_optimize.test
@@ -0,0 +1,18 @@
+source include/have_innodb.inc;
+source include/master-slave.inc;
+
+#
+# BUG#5551 "Failed OPTIMIZE TABLE is logged to binary log"
+# Replication should work when OPTIMIZE TABLE timeouts, and
+# when OPTIMIZE TABLE is executed on a non-existing table
+#
+
+CREATE TABLE t1 ( a int ) ENGINE=InnoDB;
+BEGIN;
+INSERT INTO t1 VALUES (1);
+
+connection master1;
+OPTIMIZE TABLE t1;
+
+OPTIMIZE TABLE non_existing;
+sync_slave_with_master;
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index dce32720184..f5b9bc0638f 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -2610,6 +2610,7 @@ unsent_create_error:
mysql_update_log.write(thd, thd->query, thd->query_length);
if (mysql_bin_log.is_open())
{
+ thd->clear_error(); // No binlog error generated
Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
mysql_bin_log.write(&qinfo);
}
@@ -2638,6 +2639,7 @@ unsent_create_error:
mysql_update_log.write(thd, thd->query, thd->query_length);
if (mysql_bin_log.is_open())
{
+ thd->clear_error(); // No binlog error generated
Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
mysql_bin_log.write(&qinfo);
}
@@ -2660,6 +2662,7 @@ unsent_create_error:
mysql_update_log.write(thd, thd->query, thd->query_length);
if (mysql_bin_log.is_open())
{
+ thd->clear_error(); // No binlog error generated
Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
mysql_bin_log.write(&qinfo);
}
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 2f7a5f32d01..c69235a5647 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1734,6 +1734,12 @@ end:
}
+/*
+ RETURN VALUES
+ 0 Message sent to net (admin operation went ok)
+ -1 Message should be sent by caller
+ (admin operation or network communication failed)
+*/
static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
HA_CHECK_OPT* check_opt,
const char *operator_name,
From b9ec6803ae39367dad8d3b716c59c1c741b2c91b Mon Sep 17 00:00:00 2001
From: "pekka@mysql.com" <>
Date: Wed, 3 Nov 2004 20:21:56 +0100
Subject: [PATCH 56/59] NDB blobs - try to handle insert-update-delete under
autocommit=0
---
mysql-test/r/ndb_blob.result | 9 ++++++++-
mysql-test/t/ndb_blob.test | 8 +++++++-
ndb/src/ndbapi/NdbBlob.cpp | 12 ++++++++++++
ndb/src/ndbapi/NdbConnection.cpp | 5 +++++
ndb/src/ndbapi/NdbOperationExec.cpp | 2 +-
ndb/src/ndbapi/ndberror.c | 2 +-
ndb/test/ndbapi/testBlobs.cpp | 16 ++++++++++++++++
7 files changed, 50 insertions(+), 4 deletions(-)
diff --git a/mysql-test/r/ndb_blob.result b/mysql-test/r/ndb_blob.result
index 1f2cf33f57d..156c2d570a4 100644
--- a/mysql-test/r/ndb_blob.result
+++ b/mysql-test/r/ndb_blob.result
@@ -414,6 +414,7 @@ a b c d
9 b9 999 dd9
drop table t1;
drop database test2;
+set autocommit=0;
create table t1 (
a int not null primary key,
b tinytext
@@ -422,9 +423,13 @@ insert into t1 values(1, 'x');
update t1 set b = 'y';
select * from t1;
a b
-1 x
+1 y
delete from t1;
+select * from t1;
+a b
+commit;
drop table t1;
+set autocommit=0;
create table t1 (
a int not null primary key,
b text not null
@@ -433,6 +438,7 @@ insert into t1 values(1, '');
select * from t1;
a b
1
+commit;
drop table t1;
set autocommit=1;
use test;
@@ -454,6 +460,7 @@ select * from t1 order by a;
a b
1 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
2 BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
+set autocommit=1;
alter table t1 engine=myisam;
select * from t1 order by a;
a b
diff --git a/mysql-test/t/ndb_blob.test b/mysql-test/t/ndb_blob.test
index ba5f089b17b..06ecbc66d97 100644
--- a/mysql-test/t/ndb_blob.test
+++ b/mysql-test/t/ndb_blob.test
@@ -337,8 +337,9 @@ select * from t1 order by a;
drop table t1;
drop database test2;
-# -- bug-5252 tinytext crashes --
+# -- bug-5252 tinytext crashes plus no-commit result --
+set autocommit=0;
create table t1 (
a int not null primary key,
b tinytext
@@ -348,10 +349,13 @@ insert into t1 values(1, 'x');
update t1 set b = 'y';
select * from t1;
delete from t1;
+select * from t1;
+commit;
drop table t1;
# -- bug-5013 insert empty string to text --
+set autocommit=0;
create table t1 (
a int not null primary key,
b text not null
@@ -359,6 +363,7 @@ create table t1 (
insert into t1 values(1, '');
select * from t1;
+commit;
drop table t1;
# -- bug #5349 --
@@ -380,6 +385,7 @@ alter table t1 engine=ndb;
select * from t1 order by a;
# -- bug #5872 --
+set autocommit=1;
alter table t1 engine=myisam;
select * from t1 order by a;
drop table t1;
diff --git a/ndb/src/ndbapi/NdbBlob.cpp b/ndb/src/ndbapi/NdbBlob.cpp
index 9d21304939a..53c0a0e07f9 100644
--- a/ndb/src/ndbapi/NdbBlob.cpp
+++ b/ndb/src/ndbapi/NdbBlob.cpp
@@ -1428,6 +1428,18 @@ NdbBlob::postExecute(ExecType anExecType)
if (invokeActiveHook() == -1)
return -1;
}
+ if (anExecType == NoCommit && theHeadInlineUpdateFlag) {
+ NdbOperation* tOp = theNdbCon->getNdbOperation(theTable);
+ if (tOp == NULL ||
+ tOp->updateTuple() == -1 ||
+ setTableKeyValue(tOp) == -1 ||
+ setHeadInlineValue(tOp) == -1) {
+ setErrorCode(ErrAbort);
+ return -1;
+ }
+ tOp->m_abortOption = AbortOnError;
+ DBG("added op to update head+inline");
+ }
DBG("postExecute [out]");
return 0;
}
diff --git a/ndb/src/ndbapi/NdbConnection.cpp b/ndb/src/ndbapi/NdbConnection.cpp
index c21a85fd24d..4f6468eb4ae 100644
--- a/ndb/src/ndbapi/NdbConnection.cpp
+++ b/ndb/src/ndbapi/NdbConnection.cpp
@@ -340,7 +340,12 @@ NdbConnection::execute(ExecType aTypeOfExec,
if (executeNoBlobs(tExecType, abortOption, forceSend) == -1)
ret = -1;
+#ifndef VM_TRACE
+ // can happen in complex abort cases
+ theFirstOpInList = theLastOpInList = NULL;
+#else
assert(theFirstOpInList == NULL && theLastOpInList == NULL);
+#endif
{
NdbOperation* tOp = theCompletedFirstOp;
diff --git a/ndb/src/ndbapi/NdbOperationExec.cpp b/ndb/src/ndbapi/NdbOperationExec.cpp
index 6d7a3817e04..13664794dcd 100644
--- a/ndb/src/ndbapi/NdbOperationExec.cpp
+++ b/ndb/src/ndbapi/NdbOperationExec.cpp
@@ -552,7 +552,7 @@ NdbOperation::receiveTCKEYREF( NdbApiSignal* aSignal)
theNdbCon->theReturnStatus = NdbConnection::ReturnFailure;
theError.code = aSignal->readData(4);
- theNdbCon->setOperationErrorCodeAbort(aSignal->readData(4), ao);
+ theNdbCon->setOperationErrorCodeAbort(aSignal->readData(4), m_abortOption);
if(theOperationType != ReadRequest || !theSimpleIndicator) // not simple read
return theNdbCon->OpCompleteFailure(ao, m_abortOption != IgnoreError);
diff --git a/ndb/src/ndbapi/ndberror.c b/ndb/src/ndbapi/ndberror.c
index 20661b89517..17a80082023 100644
--- a/ndb/src/ndbapi/ndberror.c
+++ b/ndb/src/ndbapi/ndberror.c
@@ -150,7 +150,7 @@ ErrorBundle ErrorCodes[] = {
{ 623, IS, "623" },
{ 624, IS, "624" },
{ 625, IS, "Out of memory in Ndb Kernel, index part" },
- { 826, IS, "826" },
+ { 826, IS, "Too many tables and attributes (increase MaxNoOfAttributes)" },
{ 827, IS, "Out of memory in Ndb Kernel, data part" },
{ 832, IS, "832" },
diff --git a/ndb/test/ndbapi/testBlobs.cpp b/ndb/test/ndbapi/testBlobs.cpp
index 08bf8a2fd4b..efa0811aa39 100644
--- a/ndb/test/ndbapi/testBlobs.cpp
+++ b/ndb/test/ndbapi/testBlobs.cpp
@@ -42,6 +42,7 @@ struct Opt {
bool m_core;
bool m_dbg;
bool m_dbgall;
+ const char* m_dbug;
bool m_full;
unsigned m_loop;
unsigned m_parts;
@@ -66,6 +67,7 @@ struct Opt {
m_core(false),
m_dbg(false),
m_dbgall(false),
+ m_dbug(0),
m_full(false),
m_loop(1),
m_parts(10),
@@ -100,6 +102,7 @@ printusage()
<< " -core dump core on error" << endl
<< " -dbg print debug" << endl
<< " -dbgall print also NDB API debug (if compiled in)" << endl
+ << " -dbug opt dbug options" << endl
<< " -full read/write only full blob values" << endl
<< " -loop N loop N times 0=forever [" << d.m_loop << "]" << endl
<< " -parts N max parts in blob value [" << d.m_parts << "]" << endl
@@ -1046,8 +1049,12 @@ writeIdx(int style)
if (style == 0) {
CHK(setBlobValue(tup) == 0);
} else if (style == 1) {
+ // non-nullable must be set
+ CHK(g_bh1->setValue("", 0) == 0);
CHK(setBlobWriteHook(tup) == 0);
} else {
+ // non-nullable must be set
+ CHK(g_bh1->setValue("", 0) == 0);
CHK(g_con->execute(NoCommit) == 0);
CHK(writeBlobData(tup) == 0);
}
@@ -1463,6 +1470,12 @@ NDB_COMMAND(testOdbcDriver, "testBlobs", "testBlobs", "testBlobs", 65535)
putenv(strdup("NDB_BLOB_DEBUG=1"));
continue;
}
+ if (strcmp(arg, "-dbug") == 0) {
+ if (++argv, --argc > 0) {
+ g_opt.m_dbug = strdup(argv[0]);
+ continue;
+ }
+ }
if (strcmp(arg, "-full") == 0) {
g_opt.m_full = true;
continue;
@@ -1533,6 +1546,9 @@ NDB_COMMAND(testOdbcDriver, "testBlobs", "testBlobs", "testBlobs", 65535)
printusage();
return NDBT_ProgramExit(NDBT_WRONGARGS);
}
+ if (g_opt.m_dbug != 0) {
+ DBUG_PUSH(g_opt.m_dbug);
+ }
if (g_opt.m_pk2len == 0) {
char b[100];
b[0] = 0;
From 13a60a76312d3035005d90a94fd2442456ce0f77 Mon Sep 17 00:00:00 2001
From: "heikki@hundin.mysql.fi" <>
Date: Thu, 4 Nov 2004 00:10:00 +0200
Subject: [PATCH 57/59] ibuf0ibuf.c: Do not print to .err log about
discarding ibuf entries in DISCARD TABLESPACE; removed compiler warning about
unused variable
---
innobase/ibuf/ibuf0ibuf.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/innobase/ibuf/ibuf0ibuf.c b/innobase/ibuf/ibuf0ibuf.c
index b3c8ade2414..2191cdc0ee6 100644
--- a/innobase/ibuf/ibuf0ibuf.c
+++ b/innobase/ibuf/ibuf0ibuf.c
@@ -2866,6 +2866,8 @@ ibuf_delete_rec(
#ifdef UNIV_IBUF_DEBUG
ibuf_count_set(space, page_no, ibuf_count_get(space, page_no) - 1);
+#else
+ UT_NOT_USED(space);
#endif
ibuf_data_sizes_update(ibuf_data, root, mtr);
@@ -3267,11 +3269,11 @@ leave_loop:
ibuf_data->n_merged_recs += n_inserts;
mutex_exit(&ibuf_mutex);
-
+ /*
fprintf(stderr,
"InnoDB: Discarded %lu ibuf entries for space %lu\n",
(ulong) n_inserts, (ulong) space);
-
+ */
ibuf_exit();
mem_heap_free(heap);
From f979603cf2c292b80fae7cc47f75ea34769f146f Mon Sep 17 00:00:00 2001
From: "bar@mysql.com" <>
Date: Thu, 4 Nov 2004 08:50:07 +0400
Subject: [PATCH 58/59] field.cc, sql_mode.result, sql_mode.test: "SHOW
CREATE TABLE" mysql-4.0 and mysql-3.23 compatibiliry mode change: Check
that a binary collation adds 'binary' suffix into a char() column
definition in mysql40 and mysql2323 modes. This allows not to lose the
column's case sensitivity when loading the dump in pre-4.1 servers.
---
mysql-test/r/sql_mode.result | 30 ++++++++++++++++++++++++++++++
mysql-test/t/sql_mode.test | 31 +++++++++++++++++++++++++++++++
sql/field.cc | 4 ++++
3 files changed, 65 insertions(+)
diff --git a/mysql-test/r/sql_mode.result b/mysql-test/r/sql_mode.result
index e54dd217f8c..c18be2df403 100644
--- a/mysql-test/r/sql_mode.result
+++ b/mysql-test/r/sql_mode.result
@@ -85,6 +85,36 @@ t1 CREATE TABLE "t1" (
UNIQUE KEY "email" ("email")
)
drop table t1;
+CREATE TABLE t1 (
+a char(10),
+b char(10) collate latin1_bin,
+c binary(10)
+) character set latin1;
+set @@sql_mode="";
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(10) default NULL,
+ `b` char(10) character set latin1 collate latin1_bin default NULL,
+ `c` binary(10) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+set @@sql_mode="mysql323";
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(10) default NULL,
+ `b` char(10) binary default NULL,
+ `c` binary(10) default NULL
+) TYPE=MyISAM
+set @@sql_mode="mysql40";
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(10) default NULL,
+ `b` char(10) binary default NULL,
+ `c` binary(10) default NULL
+) TYPE=MyISAM
+drop table t1;
set session sql_mode = '';
create table t1 ( min_num dec(6,6) default .000001);
show create table t1;
diff --git a/mysql-test/t/sql_mode.test b/mysql-test/t/sql_mode.test
index 63a5d6d3671..f841d36e837 100644
--- a/mysql-test/t/sql_mode.test
+++ b/mysql-test/t/sql_mode.test
@@ -29,6 +29,37 @@ select @@sql_mode;
show create table t1;
drop table t1;
+#
+# Check that a binary collation adds 'binary'
+# suffix into a char() column definition in
+# mysql40 and mysql2323 modes. This allows
+# not to lose the column's case sensitivity
+# when loading the dump in pre-4.1 servers.
+#
+# Thus, in 4.0 and 3.23 modes we dump:
+#
+# 'char(10) collate xxx_bin' as 'char(10) binary'
+# 'binary(10)' as 'binary(10)'
+#
+# In mysql-4.1 these types are different, and they will
+# be recreated differently.
+#
+# In mysqld-4.0 the the above two types were the same,
+# so it will create a 'char(10) binary' column for both definitions.
+#
+CREATE TABLE t1 (
+ a char(10),
+ b char(10) collate latin1_bin,
+ c binary(10)
+) character set latin1;
+set @@sql_mode="";
+show create table t1;
+set @@sql_mode="mysql323";
+show create table t1;
+set @@sql_mode="mysql40";
+show create table t1;
+drop table t1;
+
#
# BUG#5318 - failure: 'IGNORE_SPACE' affects numeric values after DEFAULT
#
diff --git a/sql/field.cc b/sql/field.cc
index 4b833874221..24bd0c48c92 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -4417,6 +4417,7 @@ void Field_string::sort_string(char *to,uint length)
void Field_string::sql_type(String &res) const
{
+ THD *thd= table->in_use;
CHARSET_INFO *cs=res.charset();
ulong length= cs->cset->snprintf(cs,(char*) res.ptr(),
res.alloced_length(), "%s(%d)",
@@ -4427,6 +4428,9 @@ void Field_string::sql_type(String &res) const
(has_charset() ? "char" : "binary")),
(int) field_length / charset()->mbmaxlen);
res.length(length);
+ if ((thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40)) &&
+ has_charset() && (charset()->state & MY_CS_BINSORT))
+ res.append(" binary");
}
char *Field_string::pack(char *to, const char *from, uint max_length)
From f5e5dfb2f779cbb5468d63d94d659fa3d6a17e8a Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Thu, 4 Nov 2004 13:06:22 +0000
Subject: [PATCH 59/59] just do kill instead ok kill -9
---
mysql-test/ndb/ndbcluster.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/mysql-test/ndb/ndbcluster.sh b/mysql-test/ndb/ndbcluster.sh
index 9d83a291f3d..d7b115d71b6 100644
--- a/mysql-test/ndb/ndbcluster.sh
+++ b/mysql-test/ndb/ndbcluster.sh
@@ -212,8 +212,8 @@ if [ -f "$fs_ndb/$pidfile" ] ; then
attempt=`expr $attempt + 1`
done
if [ "$kill_pids" != "" ] ; then
- echo "Failed to shutdown ndbcluster, executing kill -9 "$kill_pids
- kill -9 $kill_pids
+ echo "Failed to shutdown ndbcluster, executing kill "$kill_pids
+ kill $kill_pids
fi
rm "$fs_ndb/$pidfile"
fi
|