$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 618428d2e84fe6a68a1ce4d420a94809635d88b4 Mon Sep 17 00:00:00 2001
From: "wax@kishkin.ru" <>
Date: Thu, 4 Nov 2004 19:45:31 +0500
Subject: [PATCH 007/145] BUG#6056 fixed MySQL can't clean shutdown with
--shared-memory
---
sql/mysqld.cc | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index af6f25c1400..89b0a035e6c 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -468,6 +468,7 @@ Query_cache query_cache;
#ifdef HAVE_SMEM
char *shared_memory_base_name= default_shared_memory_base_name;
bool opt_enable_shared_memory;
+HANDLE event_connect_request= 0;
#endif
#include "sslopt-vars.h"
@@ -743,6 +744,15 @@ void kill_mysql(void)
CloseHandle(hEvent);
*/
}
+#ifdef HAVE_SMEM
+ /*
+ Send event to event_connect_request for aborting
+ */
+ if (!SetEvent(event_connect_request))
+ {
+ DBUG_PRINT("error",("Got error: %ld from SetEvent of event_connect_request",GetLastError()));
+ }
+#endif
#endif
#elif defined(OS2)
pthread_cond_signal( &eventShutdown); // post semaphore
@@ -3707,7 +3717,6 @@ pthread_handler_decl(handle_connections_shared_memory,arg)
/* file-mapping object, use for create shared memory */
HANDLE handle_connect_file_map= 0;
char *handle_connect_map= 0; // pointer on shared memory
- HANDLE event_connect_request= 0; // for start connection actions
HANDLE event_connect_answer= 0;
ulong smem_buffer_length= shared_memory_buffer_length + 4;
ulong connect_number= 1;
@@ -3761,6 +3770,12 @@ pthread_handler_decl(handle_connections_shared_memory,arg)
/* Wait a request from client */
WaitForSingleObject(event_connect_request,INFINITE);
+ /*
+ it can be after shutdown command
+ */
+ if (abort_loop)
+ goto error;
+
HANDLE handle_client_file_map= 0;
char *handle_client_map= 0;
HANDLE event_client_wrote= 0;
From 167c9489fa9dbee781085b000e818990df96ee20 Mon Sep 17 00:00:00 2001
From: "ram@gw.mysql.r18.ru" <>
Date: Sat, 6 Nov 2004 09:37:30 +0400
Subject: [PATCH 008/145] A fix (bug #6441: Aggregate UDF in multi-table query
crashes MySQL when returning multiple rows).
---
sql/item_func.cc | 19 +++++++++++--------
sql/item_sum.h | 2 +-
sql/sql_udf.h | 3 ++-
3 files changed, 14 insertions(+), 10 deletions(-)
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 09d7e50eaa3..32708ecb4ca 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -1602,18 +1602,21 @@ longlong Item_func_bit_count::val_int()
udf_handler::~udf_handler()
{
- if (initialized)
+ if (!not_original)
{
- if (u_d->func_deinit != NULL)
+ if (initialized)
{
- void (*deinit)(UDF_INIT *) = (void (*)(UDF_INIT*))
- u_d->func_deinit;
- (*deinit)(&initid);
+ if (u_d->func_deinit != NULL)
+ {
+ void (*deinit)(UDF_INIT *) = (void (*)(UDF_INIT*))
+ u_d->func_deinit;
+ (*deinit)(&initid);
+ }
+ free_udf(u_d);
}
- free_udf(u_d);
+ if (buffers) // Because of bug in ecc
+ delete [] buffers;
}
- if (buffers) // Because of bug in ecc
- delete [] buffers;
}
diff --git a/sql/item_sum.h b/sql/item_sum.h
index 5aa0d37190b..74c28765f8d 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -532,7 +532,7 @@ public:
:Item_sum( list ), udf(udf_arg)
{ quick_group=0;}
Item_udf_sum(THD *thd, Item_udf_sum *item)
- :Item_sum(thd, item), udf(item->udf) {}
+ :Item_sum(thd, item), udf(item->udf) { udf.not_original= TRUE; }
const char *func_name() const { return udf.name(); }
bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
{
diff --git a/sql/sql_udf.h b/sql/sql_udf.h
index 7b10b80f148..d1f99a6d232 100644
--- a/sql/sql_udf.h
+++ b/sql/sql_udf.h
@@ -56,8 +56,9 @@ class udf_handler :public Sql_alloc
public:
table_map used_tables_cache;
bool const_item_cache;
+ bool not_original;
udf_handler(udf_func *udf_arg) :u_d(udf_arg), buffers(0), error(0),
- is_null(0), initialized(0)
+ is_null(0), initialized(0), not_original(0)
{}
~udf_handler();
const char *name() const { return u_d ? u_d->name.str : "?"; }
From 3d67df4cff0b27865e49f6dab2ff44f416d1edfc Mon Sep 17 00:00:00 2001
From: "serg@serg.mylan" <>
Date: Fri, 12 Nov 2004 22:55:00 +0100
Subject: [PATCH 009/145] wrong constant fixed - boolean fulltext searches like
"+something +smth*" were stopping at docid 0xffffffff
---
myisam/ft_boolean_search.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/myisam/ft_boolean_search.c b/myisam/ft_boolean_search.c
index 13f46849210..97dfb18e5f9 100644
--- a/myisam/ft_boolean_search.c
+++ b/myisam/ft_boolean_search.c
@@ -161,7 +161,7 @@ static void _ftb_parse_query(FTB *ftb, byte **start, byte *end,
if (param.trunc) ftbw->flags|=FTB_FLAG_TRUNC;
ftbw->weight=weight;
ftbw->up=up;
- ftbw->docid[0]=ftbw->docid[1]=HA_POS_ERROR;
+ ftbw->docid[0]=ftbw->docid[1]=HA_OFFSET_ERROR;
ftbw->ndepth= (param.yesno<0) + depth;
memcpy(ftbw->word+1, w.pos, w.len);
ftbw->word[0]=w.len;
@@ -177,7 +177,7 @@ static void _ftb_parse_query(FTB *ftb, byte **start, byte *end,
ftbe->weight=weight;
ftbe->up=up;
ftbe->ythresh=ftbe->yweaks=0;
- ftbe->docid[0]=ftbe->docid[1]=HA_POS_ERROR;
+ ftbe->docid[0]=ftbe->docid[1]=HA_OFFSET_ERROR;
if ((ftbe->quot=param.quot)) ftb->with_scan|=2;
if (param.yesno > 0) up->ythresh++;
_ftb_parse_query(ftb, start, end, ftbe, depth+1);
@@ -245,7 +245,7 @@ static void _ftb_init_index_search(FT_INFO *ftb)
ftbe->up->ythresh - ftbe->up->yweaks >1) /* 1 */
{
FTB_EXPR *top_ftbe=ftbe->up->up;
- ftbw->docid[0]=HA_POS_ERROR;
+ ftbw->docid[0]=HA_OFFSET_ERROR;
for (ftbe=ftbw->up; ftbe != top_ftbe; ftbe=ftbe->up)
if (ftbe->flags & FTB_FLAG_YES)
ftbe->yweaks++;
@@ -319,7 +319,7 @@ FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, byte *query,
default_charset_info :
info->s->keyinfo[keynr].seg->charset);
ftb->with_scan=0;
- ftb->lastpos=HA_POS_ERROR;
+ ftb->lastpos=HA_OFFSET_ERROR;
bzero(& ftb->no_dupes, sizeof(TREE));
init_alloc_root(&ftb->mem_root, 1024, 1024);
@@ -342,7 +342,7 @@ FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, byte *query,
ftbe->quot=0;
ftbe->up=0;
ftbe->ythresh=ftbe->yweaks=0;
- ftbe->docid[0]=ftbe->docid[1]=HA_POS_ERROR;
+ ftbe->docid[0]=ftbe->docid[1]=HA_OFFSET_ERROR;
ftb->root=ftbe;
_ftb_parse_query(ftb, &query, query+query_len, ftbe, 0);
ftb->list=(FTB_WORD **)alloc_root(&ftb->mem_root,
@@ -496,7 +496,7 @@ int ft_boolean_read_next(FT_INFO *ftb, char *record)
while (ftb->state == INDEX_SEARCH &&
(curdoc=((FTB_WORD *)queue_top(& ftb->queue))->docid[0]) !=
- HA_POS_ERROR)
+ HA_OFFSET_ERROR)
{
while (curdoc==(ftbw=(FTB_WORD *)queue_top(& ftb->queue))->docid[0])
{
@@ -521,7 +521,7 @@ int ft_boolean_read_next(FT_INFO *ftb, char *record)
}
if (r) /* not found */
{
- ftbw->docid[0]=HA_POS_ERROR;
+ ftbw->docid[0]=HA_OFFSET_ERROR;
if (ftbw->flags&FTB_FLAG_YES && ftbw->up->up==0)
{
/*
@@ -580,7 +580,7 @@ float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length)
const byte *end;
my_off_t docid=ftb->info->lastpos;
- if (docid == HA_POS_ERROR)
+ if (docid == HA_OFFSET_ERROR)
return -2.0;
if (!ftb->queue.elements)
return 0;
@@ -592,9 +592,9 @@ float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length)
for (i=0; i < ftb->queue.elements; i++)
{
- ftb->list[i]->docid[1]=HA_POS_ERROR;
+ ftb->list[i]->docid[1]=HA_OFFSET_ERROR;
for (x=ftb->list[i]->up; x; x=x->up)
- x->docid[1]=HA_POS_ERROR;
+ x->docid[1]=HA_OFFSET_ERROR;
}
}
From 52e05dadac6f72a7bac2e88fd5acabed7644f6a7 Mon Sep 17 00:00:00 2001
From: "pekka@mysql.com" <>
Date: Sat, 13 Nov 2004 17:34:34 +0100
Subject: [PATCH 010/145] ndb: fix bug-4644 Err Out of fragment operations
---
ndb/include/kernel/signaldata/TupFrag.hpp | 6 +-
ndb/src/kernel/blocks/ERROR_codes.txt | 10 +-
ndb/src/kernel/blocks/dblqh/Dblqh.hpp | 2 +-
ndb/src/kernel/blocks/dblqh/DblqhMain.cpp | 105 ++++++++++++++++++++-
ndb/src/kernel/blocks/dbtup/Dbtup.hpp | 2 +
ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp | 54 +++++++++--
ndb/src/kernel/blocks/dbtux/Dbtux.hpp | 2 +
ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp | 13 +++
ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp | 9 +-
ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp | 88 ++++++++++++++---
ndb/test/ndbapi/testDict.cpp | 67 +++++++++++++
sql/ha_ndbcluster.cc | 11 +--
12 files changed, 328 insertions(+), 41 deletions(-)
diff --git a/ndb/include/kernel/signaldata/TupFrag.hpp b/ndb/include/kernel/signaldata/TupFrag.hpp
index c1e861c5dff..c132b19c50a 100644
--- a/ndb/include/kernel/signaldata/TupFrag.hpp
+++ b/ndb/include/kernel/signaldata/TupFrag.hpp
@@ -132,9 +132,10 @@ class TupAddAttrConf {
friend class Dblqh;
friend class Dbtup;
public:
- STATIC_CONST( SignalLength = 1 );
+ STATIC_CONST( SignalLength = 2 );
private:
Uint32 userPtr;
+ Uint32 lastAttr; // bool: got last attr and closed frag op
};
class TupAddAttrRef {
@@ -171,9 +172,10 @@ class TuxAddAttrConf {
friend class Dblqh;
friend class Dbtux;
public:
- STATIC_CONST( SignalLength = 1 );
+ STATIC_CONST( SignalLength = 2 );
private:
Uint32 userPtr;
+ Uint32 lastAttr; // bool: got last attr and closed frag op
};
class TuxAddAttrRef {
diff --git a/ndb/src/kernel/blocks/ERROR_codes.txt b/ndb/src/kernel/blocks/ERROR_codes.txt
index 70f11c33cd7..7ff03684cff 100644
--- a/ndb/src/kernel/blocks/ERROR_codes.txt
+++ b/ndb/src/kernel/blocks/ERROR_codes.txt
@@ -2,7 +2,7 @@ Next QMGR 1
Next NDBCNTR 1000
Next NDBFS 2000
Next DBACC 3001
-Next DBTUP 4007
+Next DBTUP 4013
Next DBLQH 5042
Next DBDICT 6006
Next DBDIH 7174
@@ -10,7 +10,7 @@ Next DBTC 8035
Next CMVMI 9000
Next BACKUP 10022
Next DBUTIL 11002
-Next DBTUX 12001
+Next DBTUX 12007
Next SUMA 13001
TESTING NODE FAILURE, ARBITRATION
@@ -393,6 +393,12 @@ Failed Create Table:
--------------------
7173: Create table failed due to not sufficient number of fragment or
replica records.
+4007 12001: Fail create 1st fragment
+4008 12002: Fail create 2nd fragment
+4009 12003: Fail create 1st attribute in 1st fragment
+4010 12004: Fail create last attribute in 1st fragment
+4011 12005: Fail create 1st attribute in 2nd fragment
+4012 12006: Fail create last attribute in 2nd fragment
Drop Table/Index:
-----------------
diff --git a/ndb/src/kernel/blocks/dblqh/Dblqh.hpp b/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
index d6987f3e478..739c3c741fb 100644
--- a/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
+++ b/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
@@ -2474,7 +2474,7 @@ private:
void sendExecFragRefLab(Signal* signal);
void fragrefLab(Signal* signal, BlockReference retRef,
Uint32 retPtr, Uint32 errorCode);
- void accFragRefLab(Signal* signal);
+ void abortAddFragOps(Signal* signal);
void rwConcludedLab(Signal* signal);
void sendsttorryLab(Signal* signal);
void initialiseRecordsLab(Signal* signal, Uint32 data, Uint32, Uint32);
diff --git a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
index af1131e5e55..5622706a96c 100644
--- a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
+++ b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
@@ -912,6 +912,10 @@ void Dblqh::execREAD_CONFIG_REQ(Signal* signal)
/* *********************************************************> */
/* LQHFRAGREQ: Create new fragments for a table. Sender DICT */
/* *********************************************************> */
+
+// this unbelievable mess could be replaced by one signal to LQH
+// and execute direct to local DICT to get everything at once
+
void Dblqh::execLQHFRAGREQ(Signal* signal)
{
jamEntry();
@@ -1049,6 +1053,11 @@ void Dblqh::execLQHFRAGREQ(Signal* signal)
addfragptr.p->lh3DistrBits = tlhstar;
addfragptr.p->tableType = tableType;
addfragptr.p->primaryTableId = primaryTableId;
+ //
+ addfragptr.p->tup1Connectptr = RNIL;
+ addfragptr.p->tup2Connectptr = RNIL;
+ addfragptr.p->tux1Connectptr = RNIL;
+ addfragptr.p->tux2Connectptr = RNIL;
if (DictTabInfo::isTable(tableType) ||
DictTabInfo::isHashIndex(tableType)) {
@@ -1329,15 +1338,21 @@ void Dblqh::execTUP_ADD_ATTCONF(Signal* signal)
{
jamEntry();
addfragptr.i = signal->theData[0];
+ // implies that operation was released on the other side
+ const bool lastAttr = signal->theData[1];
ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord);
switch (addfragptr.p->addfragStatus) {
case AddFragRecord::TUP_ATTR_WAIT1:
jam();
+ if (lastAttr)
+ addfragptr.p->tup1Connectptr = RNIL;
addfragptr.p->addfragStatus = AddFragRecord::TUP_ATTR_WAIT2;
sendAddAttrReq(signal);
break;
case AddFragRecord::TUP_ATTR_WAIT2:
jam();
+ if (lastAttr)
+ addfragptr.p->tup2Connectptr = RNIL;
if (DictTabInfo::isOrderedIndex(addfragptr.p->tableType)) {
addfragptr.p->addfragStatus = AddFragRecord::TUX_ATTR_WAIT1;
sendAddAttrReq(signal);
@@ -1347,11 +1362,15 @@ void Dblqh::execTUP_ADD_ATTCONF(Signal* signal)
break;
case AddFragRecord::TUX_ATTR_WAIT1:
jam();
+ if (lastAttr)
+ addfragptr.p->tux1Connectptr = RNIL;
addfragptr.p->addfragStatus = AddFragRecord::TUX_ATTR_WAIT2;
sendAddAttrReq(signal);
break;
case AddFragRecord::TUX_ATTR_WAIT2:
jam();
+ if (lastAttr)
+ addfragptr.p->tux2Connectptr = RNIL;
goto done_with_attr;
break;
done_with_attr:
@@ -1455,6 +1474,7 @@ Dblqh::sendAddAttrReq(Signal* signal)
jam();
TupAddAttrConf* tupconf = (TupAddAttrConf*)signal->getDataPtrSend();
tupconf->userPtr = addfragptr.i;
+ tupconf->lastAttr = false;
sendSignal(reference(), GSN_TUP_ADD_ATTCONF,
signal, TupAddAttrConf::SignalLength, JBB);
return;
@@ -1485,6 +1505,7 @@ Dblqh::sendAddAttrReq(Signal* signal)
jam();
TuxAddAttrConf* tuxconf = (TuxAddAttrConf*)signal->getDataPtrSend();
tuxconf->userPtr = addfragptr.i;
+ tuxconf->lastAttr = false;
sendSignal(reference(), GSN_TUX_ADD_ATTRCONF,
signal, TuxAddAttrConf::SignalLength, JBB);
return;
@@ -1549,6 +1570,40 @@ void Dblqh::fragrefLab(Signal* signal,
return;
}//Dblqh::fragrefLab()
+/*
+ * Abort on-going ops.
+ */
+void Dblqh::abortAddFragOps(Signal* signal)
+{
+ fragptr.i = addfragptr.p->fragmentPtr;
+ ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
+ signal->theData[0] = (Uint32)-1;
+ if (addfragptr.p->tup1Connectptr != RNIL) {
+ jam();
+ signal->theData[1] = addfragptr.p->tup1Connectptr;
+ sendSignal(fragptr.p->tupBlockref, GSN_TUPFRAGREQ, signal, 2, JBB);
+ addfragptr.p->tup1Connectptr = RNIL;
+ }
+ if (addfragptr.p->tup2Connectptr != RNIL) {
+ jam();
+ signal->theData[1] = addfragptr.p->tup2Connectptr;
+ sendSignal(fragptr.p->tupBlockref, GSN_TUPFRAGREQ, signal, 2, JBB);
+ addfragptr.p->tup2Connectptr = RNIL;
+ }
+ if (addfragptr.p->tux1Connectptr != RNIL) {
+ jam();
+ signal->theData[1] = addfragptr.p->tux1Connectptr;
+ sendSignal(fragptr.p->tuxBlockref, GSN_TUXFRAGREQ, signal, 2, JBB);
+ addfragptr.p->tux1Connectptr = RNIL;
+ }
+ if (addfragptr.p->tux2Connectptr != RNIL) {
+ jam();
+ signal->theData[1] = addfragptr.p->tux2Connectptr;
+ sendSignal(fragptr.p->tuxBlockref, GSN_TUXFRAGREQ, signal, 2, JBB);
+ addfragptr.p->tux2Connectptr = RNIL;
+ }
+}
+
/* ************>> */
/* ACCFRAGREF > */
/* ************>> */
@@ -1582,6 +1637,27 @@ void Dblqh::execTUPFRAGREF(Signal* signal)
fragptr.i = addfragptr.p->fragmentPtr;
ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
addfragptr.p->addfragErrorCode = terrorCode;
+
+ // no operation to release, just add some jams
+ switch (addfragptr.p->addfragStatus) {
+ case AddFragRecord::WAIT_TWO_TUP:
+ jam();
+ break;
+ case AddFragRecord::WAIT_ONE_TUP:
+ jam();
+ break;
+ case AddFragRecord::WAIT_TWO_TUX:
+ jam();
+ break;
+ case AddFragRecord::WAIT_ONE_TUX:
+ jam();
+ break;
+ default:
+ ndbrequire(false);
+ break;
+ }
+ abortAddFragOps(signal);
+
const Uint32 ref = addfragptr.p->dictBlockref;
const Uint32 senderData = addfragptr.p->dictConnectptr;
const Uint32 errorCode = addfragptr.p->addfragErrorCode;
@@ -1605,11 +1681,38 @@ void Dblqh::execTUXFRAGREF(Signal* signal)
void Dblqh::execTUP_ADD_ATTRREF(Signal* signal)
{
jamEntry();
-
addfragptr.i = signal->theData[0];
ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord);
terrorCode = signal->theData[1];
addfragptr.p->addfragErrorCode = terrorCode;
+
+ // operation was released on the other side
+ switch (addfragptr.p->addfragStatus) {
+ case AddFragRecord::TUP_ATTR_WAIT1:
+ jam();
+ ndbrequire(addfragptr.p->tup1Connectptr != RNIL);
+ addfragptr.p->tup1Connectptr = RNIL;
+ break;
+ case AddFragRecord::TUP_ATTR_WAIT2:
+ jam();
+ ndbrequire(addfragptr.p->tup2Connectptr != RNIL);
+ addfragptr.p->tup2Connectptr = RNIL;
+ break;
+ case AddFragRecord::TUX_ATTR_WAIT1:
+ jam();
+ ndbrequire(addfragptr.p->tux1Connectptr != RNIL);
+ addfragptr.p->tux1Connectptr = RNIL;
+ break;
+ case AddFragRecord::TUX_ATTR_WAIT2:
+ jam();
+ ndbrequire(addfragptr.p->tux2Connectptr != RNIL);
+ addfragptr.p->tux2Connectptr = RNIL;
+ break;
+ default:
+ ndbrequire(false);
+ break;
+ }
+ abortAddFragOps(signal);
const Uint32 Ref = addfragptr.p->dictBlockref;
const Uint32 senderData = addfragptr.p->dictConnectptr;
diff --git a/ndb/src/kernel/blocks/dbtup/Dbtup.hpp b/ndb/src/kernel/blocks/dbtup/Dbtup.hpp
index 55ad1d0910a..b48546576f9 100644
--- a/ndb/src/kernel/blocks/dbtup/Dbtup.hpp
+++ b/ndb/src/kernel/blocks/dbtup/Dbtup.hpp
@@ -504,6 +504,7 @@ struct Fragoperrec {
Uint32 noOfNewAttrCount;
Uint32 charsetIndex;
BlockReference lqhBlockrefFrag;
+ bool inUse;
};
typedef Ptr FragoperrecPtr;
@@ -1936,6 +1937,7 @@ private:
void setUpKeyArray(Tablerec* const regTabPtr);
bool addfragtotab(Tablerec* const regTabPtr, Uint32 fragId, Uint32 fragIndex);
void deleteFragTab(Tablerec* const regTabPtr, Uint32 fragId);
+ void abortAddFragOp(Signal* signal);
void releaseTabDescr(Tablerec* const regTabPtr);
void getFragmentrec(FragrecordPtr& regFragPtr, Uint32 fragId, Tablerec* const regTabPtr);
diff --git a/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp b/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp
index efea312b865..914dba00674 100644
--- a/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp
+++ b/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp
@@ -39,11 +39,18 @@
/* ---------------------------------------------------------------- */
void Dbtup::execTUPFRAGREQ(Signal* signal)
{
+ ljamEntry();
+
+ if (signal->theData[0] == (Uint32)-1) {
+ ljam();
+ abortAddFragOp(signal);
+ return;
+ }
+
FragoperrecPtr fragOperPtr;
FragrecordPtr regFragPtr;
TablerecPtr regTabPtr;
- ljamEntry();
Uint32 userptr = signal->theData[0];
Uint32 userblockref = signal->theData[1];
Uint32 reqinfo = signal->theData[2];
@@ -132,6 +139,15 @@ void Dbtup::execTUPFRAGREQ(Signal* signal)
return;
}//if
+ if (ERROR_INSERTED(4007) && regTabPtr.p->fragid[0] == fragId ||
+ ERROR_INSERTED(4008) && regTabPtr.p->fragid[1] == fragId) {
+ ljam();
+ terrorCode = 1;
+ fragrefuse4Lab(signal, fragOperPtr, regFragPtr, regTabPtr.p, fragId);
+ CLEAR_ERROR_INSERT_VALUE;
+ return;
+ }
+
if (regTabPtr.p->tableStatus == NOT_DEFINED) {
ljam();
//-------------------------------------------------------------------------------------
@@ -243,6 +259,7 @@ void Dbtup::seizeFragoperrec(FragoperrecPtr& fragOperPtr)
ptrCheckGuard(fragOperPtr, cnoOfFragoprec, fragoperrec);
cfirstfreeFragopr = fragOperPtr.p->nextFragoprec;
fragOperPtr.p->nextFragoprec = RNIL;
+ fragOperPtr.p->inUse = true;
}//Dbtup::seizeFragoperrec()
/* **************************************************************** */
@@ -273,6 +290,7 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* signal)
ndbrequire(fragOperPtr.p->attributeCount > 0);
fragOperPtr.p->attributeCount--;
+ const bool lastAttr = (fragOperPtr.p->attributeCount == 0);
if ((regTabPtr.p->tableStatus == DEFINING) &&
(fragOperPtr.p->definingFragment)) {
@@ -346,20 +364,30 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* signal)
addattrrefuseLab(signal, regFragPtr, fragOperPtr, regTabPtr.p, fragId);
return;
}//if
- if ((fragOperPtr.p->attributeCount == 0) &&
- (fragOperPtr.p->freeNullBit != 0)) {
+ if (lastAttr && (fragOperPtr.p->freeNullBit != 0)) {
ljam();
terrorCode = ZINCONSISTENT_NULL_ATTRIBUTE_COUNT;
addattrrefuseLab(signal, regFragPtr, fragOperPtr, regTabPtr.p, fragId);
return;
}//if
}//if
+ if (ERROR_INSERTED(4009) && regTabPtr.p->fragid[0] == fragId && attrId == 0 ||
+ ERROR_INSERTED(4010) && regTabPtr.p->fragid[0] == fragId && lastAttr ||
+ ERROR_INSERTED(4011) && regTabPtr.p->fragid[1] == fragId && attrId == 0 ||
+ ERROR_INSERTED(4012) && regTabPtr.p->fragid[1] == fragId && lastAttr) {
+ ljam();
+ terrorCode = 1;
+ addattrrefuseLab(signal, regFragPtr, fragOperPtr, regTabPtr.p, fragId);
+ CLEAR_ERROR_INSERT_VALUE;
+ return;
+ }
/* **************************************************************** */
/* ************** TUP_ADD_ATTCONF ****************** */
/* **************************************************************** */
signal->theData[0] = fragOperPtr.p->lqhPtrFrag;
- sendSignal(fragOperPtr.p->lqhBlockrefFrag, GSN_TUP_ADD_ATTCONF, signal, 1, JBB);
- if (fragOperPtr.p->attributeCount > 0) {
+ signal->theData[1] = lastAttr;
+ sendSignal(fragOperPtr.p->lqhBlockrefFrag, GSN_TUP_ADD_ATTCONF, signal, 2, JBB);
+ if (! lastAttr) {
ljam();
return; /* EXIT AND WAIT FOR MORE */
}//if
@@ -491,11 +519,11 @@ void Dbtup::fragrefuseLab(Signal* signal, FragoperrecPtr fragOperPtr)
void Dbtup::releaseFragoperrec(FragoperrecPtr fragOperPtr)
{
+ fragOperPtr.p->inUse = false;
fragOperPtr.p->nextFragoprec = cfirstfreeFragopr;
cfirstfreeFragopr = fragOperPtr.i;
}//Dbtup::releaseFragoperrec()
-
void Dbtup::deleteFragTab(Tablerec* const regTabPtr, Uint32 fragId)
{
for (Uint32 i = 0; i < (2 * MAX_FRAG_PER_NODE); i++) {
@@ -510,6 +538,20 @@ void Dbtup::deleteFragTab(Tablerec* const regTabPtr, Uint32 fragId)
ndbrequire(false);
}//Dbtup::deleteFragTab()
+/*
+ * LQH aborts on-going create table operation. The table is later
+ * dropped by DICT.
+ */
+void Dbtup::abortAddFragOp(Signal* signal)
+{
+ FragoperrecPtr fragOperPtr;
+
+ fragOperPtr.i = signal->theData[1];
+ ptrCheckGuard(fragOperPtr, cnoOfFragoprec, fragoperrec);
+ ndbrequire(fragOperPtr.p->inUse);
+ releaseFragoperrec(fragOperPtr);
+}
+
void
Dbtup::execDROP_TAB_REQ(Signal* signal)
{
diff --git a/ndb/src/kernel/blocks/dbtux/Dbtux.hpp b/ndb/src/kernel/blocks/dbtux/Dbtux.hpp
index 8896324f793..8f49b7fa6d6 100644
--- a/ndb/src/kernel/blocks/dbtux/Dbtux.hpp
+++ b/ndb/src/kernel/blocks/dbtux/Dbtux.hpp
@@ -575,6 +575,7 @@ private:
void execDROP_TAB_REQ(Signal* signal);
bool allocDescEnt(IndexPtr indexPtr);
void freeDescEnt(IndexPtr indexPtr);
+ void abortAddFragOp(Signal* signal);
void dropIndex(Signal* signal, IndexPtr indexPtr, Uint32 senderRef, Uint32 senderData);
/*
@@ -684,6 +685,7 @@ private:
friend class NdbOut& operator<<(NdbOut&, const ScanOp&);
friend class NdbOut& operator<<(NdbOut&, const Index&);
friend class NdbOut& operator<<(NdbOut&, const Frag&);
+ friend class NdbOut& operator<<(NdbOut&, const FragOp&);
friend class NdbOut& operator<<(NdbOut&, const NodeHandle&);
FILE* debugFile;
NdbOut debugOut;
diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp
index c5c22264460..1e1b0d1d5b6 100644
--- a/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp
+++ b/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp
@@ -403,6 +403,19 @@ operator<<(NdbOut& out, const Dbtux::Frag& frag)
return out;
}
+NdbOut&
+operator<<(NdbOut& out, const Dbtux::FragOp& fragOp)
+{
+ out << "[FragOp " << hex << &fragOp;
+ out << " [userPtr " << dec << fragOp.m_userPtr << "]";
+ out << " [indexId " << dec << fragOp.m_indexId << "]";
+ out << " [fragId " << dec << fragOp.m_fragId << "]";
+ out << " [fragNo " << dec << fragOp.m_fragNo << "]";
+ out << " numAttrsRecvd " << dec << fragOp.m_numAttrsRecvd << "]";
+ out << "]";
+ return out;
+}
+
NdbOut&
operator<<(NdbOut& out, const Dbtux::NodeHandle& node)
{
diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp
index ded02696a89..18aa914de05 100644
--- a/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp
+++ b/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp
@@ -24,12 +24,7 @@ Dbtux::Dbtux(const Configuration& conf) :
#ifdef VM_TRACE
debugFile(0),
debugOut(*new NullOutputStream()),
- // until ndb_mgm supports dump
-#ifdef DBTUX_DEBUG_TREE
- debugFlags(DebugTree),
-#else
debugFlags(0),
-#endif
#endif
c_internalStartPhase(0),
c_typeOfStart(NodeState::ST_ILLEGAL_TYPE),
@@ -86,7 +81,7 @@ Dbtux::execCONTINUEB(Signal* signal)
jamEntry();
const Uint32* data = signal->getDataPtr();
switch (data[0]) {
- case TuxContinueB::DropIndex:
+ case TuxContinueB::DropIndex: // currently unused
{
IndexPtr indexPtr;
c_indexPool.getPtr(indexPtr, data[1]);
@@ -174,7 +169,7 @@ Dbtux::execREAD_CONFIG_REQ(Signal* signal)
ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUX_ATTRIBUTE, &nAttribute));
ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUX_SCAN_OP, &nScanOp));
- const Uint32 nDescPage = (nIndex + nAttribute + DescPageSize - 1) / DescPageSize;
+ const Uint32 nDescPage = (nIndex * DescHeadSize + nAttribute * DescAttrSize + DescPageSize - 1) / DescPageSize;
const Uint32 nScanBoundWords = nScanOp * ScanBoundSegmentSize * 4;
c_indexPool.setSize(nIndex);
diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp
index 1577c5045e0..b7526593a08 100644
--- a/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp
+++ b/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp
@@ -29,6 +29,11 @@ void
Dbtux::execTUXFRAGREQ(Signal* signal)
{
jamEntry();
+ if (signal->theData[0] == (Uint32)-1) {
+ jam();
+ abortAddFragOp(signal);
+ return;
+ }
const TuxFragReq reqCopy = *(const TuxFragReq*)signal->getDataPtr();
const TuxFragReq* const req = &reqCopy;
IndexPtr indexPtr;
@@ -61,6 +66,11 @@ Dbtux::execTUXFRAGREQ(Signal* signal)
fragOpPtr.p->m_fragId = req->fragId;
fragOpPtr.p->m_fragNo = indexPtr.p->m_numFrags;
fragOpPtr.p->m_numAttrsRecvd = 0;
+#ifdef VM_TRACE
+ if (debugFlags & DebugMeta) {
+ debugOut << "Seize frag op " << fragOpPtr.i << " " << *fragOpPtr.p << endl;
+ }
+#endif
// check if index has place for more fragments
ndbrequire(indexPtr.p->m_numFrags < MaxIndexFragments);
// seize new fragment record
@@ -129,6 +139,14 @@ Dbtux::execTUXFRAGREQ(Signal* signal)
debugOut << "Add frag " << fragPtr.i << " " << *fragPtr.p << endl;
}
#endif
+ // error inserts
+ if (ERROR_INSERTED(12001) && fragOpPtr.p->m_fragNo == 0 ||
+ ERROR_INSERTED(12002) && fragOpPtr.p->m_fragNo == 1) {
+ jam();
+ errorCode = (TuxFragRef::ErrorCode)1;
+ CLEAR_ERROR_INSERT_VALUE;
+ break;
+ }
// success
TuxFragConf* const conf = (TuxFragConf*)signal->getDataPtrSend();
conf->userPtr = req->userPtr;
@@ -145,10 +163,18 @@ Dbtux::execTUXFRAGREQ(Signal* signal)
ref->errorCode = errorCode;
sendSignal(req->userRef, GSN_TUXFRAGREF,
signal, TuxFragRef::SignalLength, JBB);
- if (fragOpPtr.i != RNIL)
+ if (fragOpPtr.i != RNIL) {
+#ifdef VM_TRACE
+ if (debugFlags & DebugMeta) {
+ debugOut << "Release on frag error frag op " << fragOpPtr.i << " " << *fragOpPtr.p << endl;
+ }
+#endif
c_fragOpPool.release(fragOpPtr);
- if (indexPtr.i != RNIL)
- dropIndex(signal, indexPtr, 0, 0);
+ }
+ if (indexPtr.i != RNIL) {
+ jam();
+ // let DICT drop the unfinished index
+ }
}
void
@@ -203,7 +229,16 @@ Dbtux::execTUX_ADD_ATTRREQ(Signal* signal)
}
}
#endif
- if (indexPtr.p->m_numAttrs == fragOpPtr.p->m_numAttrsRecvd) {
+ const bool lastAttr = (indexPtr.p->m_numAttrs == fragOpPtr.p->m_numAttrsRecvd);
+ if (ERROR_INSERTED(12003) && fragOpPtr.p->m_fragNo == 0 && attrId == 0 ||
+ ERROR_INSERTED(12004) && fragOpPtr.p->m_fragNo == 0 && lastAttr ||
+ ERROR_INSERTED(12005) && fragOpPtr.p->m_fragNo == 1 && attrId == 0 ||
+ ERROR_INSERTED(12006) && fragOpPtr.p->m_fragNo == 1 && lastAttr) {
+ errorCode = (TuxAddAttrRef::ErrorCode)1;
+ CLEAR_ERROR_INSERT_VALUE;
+ break;
+ }
+ if (lastAttr) {
jam();
// initialize tree header
TreeHead& tree = fragPtr.p->m_tree;
@@ -246,11 +281,17 @@ Dbtux::execTUX_ADD_ATTRREQ(Signal* signal)
}
#endif
// fragment is defined
+#ifdef VM_TRACE
+ if (debugFlags & DebugMeta) {
+ debugOut << "Release frag op " << fragOpPtr.i << " " << *fragOpPtr.p << endl;
+ }
+#endif
c_fragOpPool.release(fragOpPtr);
}
// success
TuxAddAttrConf* conf = (TuxAddAttrConf*)signal->getDataPtrSend();
conf->userPtr = fragOpPtr.p->m_userPtr;
+ conf->lastAttr = lastAttr;
sendSignal(fragOpPtr.p->m_userRef, GSN_TUX_ADD_ATTRCONF,
signal, TuxAddAttrConf::SignalLength, JBB);
return;
@@ -261,8 +302,32 @@ Dbtux::execTUX_ADD_ATTRREQ(Signal* signal)
ref->errorCode = errorCode;
sendSignal(fragOpPtr.p->m_userRef, GSN_TUX_ADD_ATTRREF,
signal, TuxAddAttrRef::SignalLength, JBB);
+#ifdef VM_TRACE
+ if (debugFlags & DebugMeta) {
+ debugOut << "Release on attr error frag op " << fragOpPtr.i << " " << *fragOpPtr.p << endl;
+ }
+#endif
c_fragOpPool.release(fragOpPtr);
- dropIndex(signal, indexPtr, 0, 0);
+ // let DICT drop the unfinished index
+}
+
+/*
+ * LQH aborts on-going create index operation.
+ */
+void
+Dbtux::abortAddFragOp(Signal* signal)
+{
+ FragOpPtr fragOpPtr;
+ IndexPtr indexPtr;
+ c_fragOpPool.getPtr(fragOpPtr, signal->theData[1]);
+ c_indexPool.getPtr(indexPtr, fragOpPtr.p->m_indexId);
+#ifdef VM_TRACE
+ if (debugFlags & DebugMeta) {
+ debugOut << "Release on abort frag op " << fragOpPtr.i << " " << *fragOpPtr.p << endl;
+ }
+#endif
+ c_fragOpPool.release(fragOpPtr);
+ // let DICT drop the unfinished index
}
/*
@@ -341,20 +406,13 @@ Dbtux::dropIndex(Signal* signal, IndexPtr indexPtr, Uint32 senderRef, Uint32 sen
{
jam();
indexPtr.p->m_state = Index::Dropping;
- // drop one fragment at a time
- if (indexPtr.p->m_numFrags > 0) {
+ // drop fragments
+ while (indexPtr.p->m_numFrags > 0) {
jam();
- unsigned i = --indexPtr.p->m_numFrags;
+ Uint32 i = --indexPtr.p->m_numFrags;
FragPtr fragPtr;
c_fragPool.getPtr(fragPtr, indexPtr.p->m_fragPtrI[i]);
c_fragPool.release(fragPtr);
- // the real time break is not used for anything currently
- signal->theData[0] = TuxContinueB::DropIndex;
- signal->theData[1] = indexPtr.i;
- signal->theData[2] = senderRef;
- signal->theData[3] = senderData;
- sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB);
- return;
}
// drop attributes
if (indexPtr.p->m_descPage != RNIL) {
diff --git a/ndb/test/ndbapi/testDict.cpp b/ndb/test/ndbapi/testDict.cpp
index 9552e321f00..b832cb7039b 100644
--- a/ndb/test/ndbapi/testDict.cpp
+++ b/ndb/test/ndbapi/testDict.cpp
@@ -1479,6 +1479,69 @@ runTestDictionaryPerf(NDBT_Context* ctx, NDBT_Step* step){
return NDBT_OK;
}
+int runFailAddFragment(NDBT_Context* ctx, NDBT_Step* step){
+ static int tuplst[] = { 4007, 4008, 4009, 4010, 4011, 4012 };
+ static int tuxlst[] = { 12001, 12002, 12003, 12004, 12005, 12006 };
+ static unsigned tupcnt = sizeof(tuplst)/sizeof(tuplst[0]);
+ static unsigned tuxcnt = sizeof(tuxlst)/sizeof(tuxlst[0]);
+
+ NdbRestarter restarter;
+ int nodeId = restarter.getMasterNodeId();
+ Ndb* pNdb = GETNDB(step);
+ NdbDictionary::Dictionary* pDic = pNdb->getDictionary();
+ NdbDictionary::Table tab(*ctx->getTab());
+ tab.setFragmentType(NdbDictionary::Object::FragAllLarge);
+
+ // ordered index on first few columns
+ NdbDictionary::Index idx("X");
+ idx.setTable(tab.getName());
+ idx.setType(NdbDictionary::Index::OrderedIndex);
+ idx.setLogging(false);
+ for (int i_hate_broken_compilers = 0;
+ i_hate_broken_compilers < 3 &&
+ i_hate_broken_compilers < tab.getNoOfColumns();
+ i_hate_broken_compilers++) {
+ idx.addColumn(*tab.getColumn(i_hate_broken_compilers));
+ }
+
+ const int loops = ctx->getNumLoops();
+ int result = NDBT_OK;
+ (void)pDic->dropTable(tab.getName());
+
+ for (int l = 0; l < loops; l++) {
+ for (unsigned i = 0; i < tupcnt; i++) {
+ unsigned j = (l == 0 ? i : myRandom48(tupcnt));
+ int errval = tuplst[j];
+ g_info << "insert error node=" << nodeId << " value=" << errval << endl;
+ CHECK2(restarter.insertErrorInNode(nodeId, errval) == 0,
+ "failed to set error insert");
+ CHECK2(pDic->createTable(tab) != 0,
+ "failed to fail after error insert " << errval);
+ CHECK2(pDic->createTable(tab) == 0,
+ pDic->getNdbError());
+ CHECK2(pDic->dropTable(tab.getName()) == 0,
+ pDic->getNdbError());
+ }
+ for (unsigned i = 0; i < tuxcnt; i++) {
+ unsigned j = (l == 0 ? i : myRandom48(tuxcnt));
+ int errval = tuxlst[j];
+ g_info << "insert error node=" << nodeId << " value=" << errval << endl;
+ CHECK2(restarter.insertErrorInNode(nodeId, errval) == 0,
+ "failed to set error insert");
+ CHECK2(pDic->createTable(tab) == 0,
+ pDic->getNdbError());
+ CHECK2(pDic->createIndex(idx) != 0,
+ "failed to fail after error insert " << errval);
+ CHECK2(pDic->createIndex(idx) == 0,
+ pDic->getNdbError());
+ CHECK2(pDic->dropTable(tab.getName()) == 0,
+ pDic->getNdbError());
+ }
+ }
+end:
+ return result;
+}
+
NDBT_TESTSUITE(testDict);
TESTCASE("CreateAndDrop",
"Try to create and drop the table loop number of times\n"){
@@ -1574,6 +1637,10 @@ TESTCASE("DictionaryPerf",
""){
INITIALIZER(runTestDictionaryPerf);
}
+TESTCASE("FailAddFragment",
+ "Fail add fragment or attribute in TUP or TUX\n"){
+ INITIALIZER(runFailAddFragment);
+}
NDBT_TESTSUITE_END(testDict);
int main(int argc, const char** argv){
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index d9545d5cbb8..6c4870817e3 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -2144,22 +2144,19 @@ void ha_ndbcluster::print_results()
}
case NdbDictionary::Column::Decimal: {
char *value= field->ptr;
-
fprintf(DBUG_FILE, "Decimal\t'%-*s'", field->pack_length(), value);
break;
}
case NdbDictionary::Column::Char:{
- char buf[field->pack_length()+1];
- char *value= (char *) field->ptr;
- snprintf(buf, field->pack_length(), "%s", value);
- fprintf(DBUG_FILE, "Char\t'%s'", buf);
+ const char *value= (char *) field->ptr;
+ fprintf(DBUG_FILE, "Char\t'%.*s'", field->pack_length(), value);
break;
}
case NdbDictionary::Column::Varchar:
case NdbDictionary::Column::Binary:
case NdbDictionary::Column::Varbinary: {
- char *value= (char *) field->ptr;
- fprintf(DBUG_FILE, "'%s'", value);
+ const char *value= (char *) field->ptr;
+ fprintf(DBUG_FILE, "Var\t'%.*s'", field->pack_length(), value);
break;
}
case NdbDictionary::Column::Datetime: {
From 63e29532ea051d84474443aee3d4f7e437e965e6 Mon Sep 17 00:00:00 2001
From: "pekka@mysql.com" <>
Date: Sat, 13 Nov 2004 17:49:20 +0100
Subject: [PATCH 011/145] ndb: minor
---
ndb/test/ndbapi/testDict.cpp | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/ndb/test/ndbapi/testDict.cpp b/ndb/test/ndbapi/testDict.cpp
index b832cb7039b..712ab2e4d25 100644
--- a/ndb/test/ndbapi/testDict.cpp
+++ b/ndb/test/ndbapi/testDict.cpp
@@ -1509,8 +1509,8 @@ int runFailAddFragment(NDBT_Context* ctx, NDBT_Step* step){
(void)pDic->dropTable(tab.getName());
for (int l = 0; l < loops; l++) {
- for (unsigned i = 0; i < tupcnt; i++) {
- unsigned j = (l == 0 ? i : myRandom48(tupcnt));
+ for (unsigned i1 = 0; i1 < tupcnt; i1++) {
+ unsigned j = (l == 0 ? i1 : myRandom48(tupcnt));
int errval = tuplst[j];
g_info << "insert error node=" << nodeId << " value=" << errval << endl;
CHECK2(restarter.insertErrorInNode(nodeId, errval) == 0,
@@ -1522,8 +1522,8 @@ int runFailAddFragment(NDBT_Context* ctx, NDBT_Step* step){
CHECK2(pDic->dropTable(tab.getName()) == 0,
pDic->getNdbError());
}
- for (unsigned i = 0; i < tuxcnt; i++) {
- unsigned j = (l == 0 ? i : myRandom48(tuxcnt));
+ for (unsigned i2 = 0; i2 < tuxcnt; i2++) {
+ unsigned j = (l == 0 ? i2 : myRandom48(tuxcnt));
int errval = tuxlst[j];
g_info << "insert error node=" << nodeId << " value=" << errval << endl;
CHECK2(restarter.insertErrorInNode(nodeId, errval) == 0,
From b02f5aa6926ecf80748066ca9da82d90ea95f746 Mon Sep 17 00:00:00 2001
From: "dlenev@brandersnatch.localdomain" <>
Date: Mon, 15 Nov 2004 15:44:29 +0300
Subject: [PATCH 012/145] Fix for bug #6266 "Invalid DATETIME value is not
handled properly".
In server we assume that datetime values stored in MYSQL_TIME struct
are normalized (and year is not greater than 9999), so we should
perform range checks in all places then we convert something to
MYSQL_TIME.
---
include/my_time.h | 5 +-
include/mysql_time.h | 12 +++
libmysql/libmysql.c | 13 +--
mysql-test/r/type_datetime.result | 11 ++-
mysql-test/t/type_datetime.test | 7 +-
sql-common/my_time.c | 7 +-
sql/field.cc | 4 +
sql/item.cc | 26 ++++++
sql/sql_prepare.cc | 23 +----
tests/client_test.c | 135 ++++++++++++++++++++++++++++++
10 files changed, 209 insertions(+), 34 deletions(-)
diff --git a/include/my_time.h b/include/my_time.h
index dab17904b2d..94701e159c4 100644
--- a/include/my_time.h
+++ b/include/my_time.h
@@ -58,14 +58,15 @@ void init_time(void);
my_time_t
my_system_gmt_sec(const MYSQL_TIME *t, long *my_timezone, bool *in_dst_time_gap);
-void set_zero_time(MYSQL_TIME *tm);
+void set_zero_time(MYSQL_TIME *tm, enum enum_mysql_timestamp_type time_type);
/*
Required buffer length for my_time_to_str, my_date_to_str,
my_datetime_to_str and TIME_to_string functions. Note, that the
caller is still responsible to check that given TIME structure
has values in valid ranges, otherwise size of the buffer could
- be not enough.
+ be not enough. We also rely on the fact that even wrong values
+ sent using binary protocol fit in this buffer.
*/
#define MAX_DATE_STRING_REP_LENGTH 30
diff --git a/include/mysql_time.h b/include/mysql_time.h
index ec67d60dea5..5f4fc12c005 100644
--- a/include/mysql_time.h
+++ b/include/mysql_time.h
@@ -33,6 +33,18 @@ enum enum_mysql_timestamp_type
};
+/*
+ Structure which is used to represent datetime values inside MySQL.
+
+ We assume that values in this structure are normalized, i.e. year <= 9999,
+ month <= 12, day <= 31, hour <= 23, hour <= 59, hour <= 59. Many functions
+ in server such as my_system_gmt_sec() or make_time() family of functions
+ rely on this (actually now usage of make_*() family relies on a bit weaker
+ restriction). Also functions that produce MYSQL_TIME as result ensure this.
+ There is one exception to this rule though if this structure holds time
+ value (time_type == MYSQL_TIMESTAMP_TIME) days and hour member can hold
+ bigger values.
+*/
typedef struct st_mysql_time
{
unsigned int year, month, day, hour, minute, second;
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index 88f46ce19e7..bfbfd9670ca 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -3256,11 +3256,12 @@ static void read_binary_time(MYSQL_TIME *tm, uchar **pos)
tm->hour+= tm->day*24;
tm->day= 0;
}
+ tm->time_type= MYSQL_TIMESTAMP_TIME;
+
*pos+= length;
}
else
- set_zero_time(tm);
- tm->time_type= MYSQL_TIMESTAMP_TIME;
+ set_zero_time(tm, MYSQL_TIMESTAMP_TIME);
}
static void read_binary_datetime(MYSQL_TIME *tm, uchar **pos)
@@ -3285,12 +3286,12 @@ static void read_binary_datetime(MYSQL_TIME *tm, uchar **pos)
else
tm->hour= tm->minute= tm->second= 0;
tm->second_part= (length > 7) ? (ulong) sint4korr(to+7) : 0;
+ tm->time_type= MYSQL_TIMESTAMP_DATETIME;
*pos+= length;
}
else
- set_zero_time(tm);
- tm->time_type= MYSQL_TIMESTAMP_DATETIME;
+ set_zero_time(tm, MYSQL_TIMESTAMP_DATETIME);
}
static void read_binary_date(MYSQL_TIME *tm, uchar **pos)
@@ -3307,12 +3308,12 @@ static void read_binary_date(MYSQL_TIME *tm, uchar **pos)
tm->hour= tm->minute= tm->second= 0;
tm->second_part= 0;
tm->neg= 0;
+ tm->time_type= MYSQL_TIMESTAMP_DATE;
*pos+= length;
}
else
- set_zero_time(tm);
- tm->time_type= MYSQL_TIMESTAMP_DATE;
+ set_zero_time(tm, MYSQL_TIMESTAMP_DATE);
}
diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result
index 524bc9c50d4..127a54e087b 100644
--- a/mysql-test/r/type_datetime.result
+++ b/mysql-test/r/type_datetime.result
@@ -97,13 +97,15 @@ select * from t1 where a is null or b is null;
a b
drop table t1;
create table t1 (t datetime);
-insert into t1 values (20030102030460),(20030102036301),(20030102240401),(20030132030401),(20031302030460);
+insert into t1 values (20030102030460),(20030102036301),(20030102240401),
+(20030132030401),(20031302030401),(100001202030401);
Warnings:
Warning 1265 Data truncated for column 't' at row 1
Warning 1265 Data truncated for column 't' at row 2
Warning 1265 Data truncated for column 't' at row 3
Warning 1265 Data truncated for column 't' at row 4
Warning 1265 Data truncated for column 't' at row 5
+Warning 1265 Data truncated for column 't' at row 6
select * from t1;
t
0000-00-00 00:00:00
@@ -111,14 +113,18 @@ t
0000-00-00 00:00:00
0000-00-00 00:00:00
0000-00-00 00:00:00
+0000-00-00 00:00:00
delete from t1;
-insert into t1 values ("20030102030460"),("20030102036301"),("20030102240401"),("20030132030401"),("20031302030460");
+insert into t1 values
+("2003-01-02 03:04:60"),("2003-01-02 03:63:01"),("2003-01-02 24:04:01"),
+("2003-01-32 03:04:01"),("2003-13-02 03:04:01"), ("10000-12-02 03:04:00");
Warnings:
Warning 1264 Data truncated; out of range for column 't' at row 1
Warning 1264 Data truncated; out of range for column 't' at row 2
Warning 1264 Data truncated; out of range for column 't' at row 3
Warning 1264 Data truncated; out of range for column 't' at row 4
Warning 1264 Data truncated; out of range for column 't' at row 5
+Warning 1264 Data truncated; out of range for column 't' at row 6
select * from t1;
t
0000-00-00 00:00:00
@@ -126,6 +132,7 @@ t
0000-00-00 00:00:00
0000-00-00 00:00:00
0000-00-00 00:00:00
+0000-00-00 00:00:00
delete from t1;
insert into t1 values ("0000-00-00 00:00:00 some trailer"),("2003-01-01 00:00:00 some trailer");
Warnings:
diff --git a/mysql-test/t/type_datetime.test b/mysql-test/t/type_datetime.test
index 47866058524..04e4a73554a 100644
--- a/mysql-test/t/type_datetime.test
+++ b/mysql-test/t/type_datetime.test
@@ -77,10 +77,13 @@ drop table t1;
# warnings (for both strings and numbers)
#
create table t1 (t datetime);
-insert into t1 values (20030102030460),(20030102036301),(20030102240401),(20030132030401),(20031302030460);
+insert into t1 values (20030102030460),(20030102036301),(20030102240401),
+ (20030132030401),(20031302030401),(100001202030401);
select * from t1;
delete from t1;
-insert into t1 values ("20030102030460"),("20030102036301"),("20030102240401"),("20030132030401"),("20031302030460");
+insert into t1 values
+ ("2003-01-02 03:04:60"),("2003-01-02 03:63:01"),("2003-01-02 24:04:01"),
+ ("2003-01-32 03:04:01"),("2003-13-02 03:04:01"), ("10000-12-02 03:04:00");
select * from t1;
delete from t1;
insert into t1 values ("0000-00-00 00:00:00 some trailer"),("2003-01-01 00:00:00 some trailer");
diff --git a/sql-common/my_time.c b/sql-common/my_time.c
index 6c020466e1e..6b305944154 100644
--- a/sql-common/my_time.c
+++ b/sql-common/my_time.c
@@ -343,7 +343,8 @@ str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
(l_time->month || l_time->day))
l_time->year+= (l_time->year < YY_PART_YEAR ? 2000 : 1900);
- if (number_of_fields < 3 || l_time->month > 12 ||
+ if (number_of_fields < 3 ||
+ l_time->year > 9999 || l_time->month > 12 ||
l_time->day > 31 || l_time->hour > 23 ||
l_time->minute > 59 || l_time->second > 59 ||
(!(flags & TIME_FUZZY_DATE) && (l_time->month == 0 || l_time->day == 0)))
@@ -720,10 +721,10 @@ my_system_gmt_sec(const MYSQL_TIME *t, long *my_timezone, bool *in_dst_time_gap)
/* Set MYSQL_TIME structure to 0000-00-00 00:00:00.000000 */
-void set_zero_time(MYSQL_TIME *tm)
+void set_zero_time(MYSQL_TIME *tm, enum enum_mysql_timestamp_type time_type)
{
bzero((void*) tm, sizeof(*tm));
- tm->time_type= MYSQL_TIMESTAMP_NONE;
+ tm->time_type= time_type;
}
diff --git a/sql/field.cc b/sql/field.cc
index 24bd0c48c92..7d1627ef521 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -4086,6 +4086,10 @@ int Field_datetime::store(longlong nr)
void Field_datetime::store_time(TIME *ltime,timestamp_type type)
{
longlong tmp;
+ /*
+ We don't perform range checking here since values stored in TIME
+ structure always fit into DATETIME range.
+ */
if (type == MYSQL_TIMESTAMP_DATE || type == MYSQL_TIMESTAMP_DATETIME)
tmp=((ltime->year*10000L+ltime->month*100+ltime->day)*LL(1000000)+
(ltime->hour*10000L+ltime->minute*100+ltime->second));
diff --git a/sql/item.cc b/sql/item.cc
index 7dc7e9e542c..382b85f9dc1 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -837,6 +837,21 @@ void Item_param::set_double(double d)
}
+/*
+ Set parameter value from TIME value.
+
+ SYNOPSIS
+ set_time()
+ tm - datetime value to set (time_type is ignored)
+ type - type of datetime value
+ max_length_arg - max length of datetime value as string
+
+ NOTE
+ If we value to be stored is not normalized, zero value will be stored
+ instead and proper warning will be produced. This function relies on
+ the fact that even wrong value sent over binary protocol fits into
+ MAX_DATE_STRING_REP_LENGTH buffer.
+*/
void Item_param::set_time(TIME *tm, timestamp_type type, uint32 max_length_arg)
{
DBUG_ENTER("Item_param::set_time");
@@ -844,6 +859,17 @@ void Item_param::set_time(TIME *tm, timestamp_type type, uint32 max_length_arg)
value.time= *tm;
value.time.time_type= type;
+ if (value.time.year > 9999 || value.time.month > 12 ||
+ value.time.day > 31 ||
+ type != MYSQL_TIMESTAMP_TIME && value.time.hour > 23 ||
+ value.time.minute > 59 || value.time.second > 59)
+ {
+ char buff[MAX_DATE_STRING_REP_LENGTH];
+ uint length= my_TIME_to_str(&value.time, buff);
+ make_truncated_value_warning(current_thd, buff, length, type);
+ set_zero_time(&value.time, MYSQL_TIMESTAMP_ERROR);
+ }
+
state= TIME_VALUE;
maybe_null= 0;
max_length= max_length_arg;
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 4ae69e40342..089853456e4 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -349,12 +349,6 @@ static void set_param_time(Item_param *param, uchar **pos, ulong len)
tm.neg= (bool) to[0];
day= (uint) sint4korr(to+1);
- /*
- Note, that though ranges of hour, minute and second are not checked
- here we rely on them being < 256: otherwise
- we'll get buffer overflow in make_{date,time} functions,
- which are called when time value is converted to string.
- */
tm.hour= (uint) to[5] + day * 24;
tm.minute= (uint) to[6];
tm.second= (uint) to[7];
@@ -369,7 +363,7 @@ static void set_param_time(Item_param *param, uchar **pos, ulong len)
tm.day= tm.year= tm.month= 0;
}
else
- set_zero_time(&tm);
+ set_zero_time(&tm, MYSQL_TIMESTAMP_TIME);
param->set_time(&tm, MYSQL_TIMESTAMP_TIME,
MAX_TIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN);
*pos+= length;
@@ -388,11 +382,6 @@ static void set_param_datetime(Item_param *param, uchar **pos, ulong len)
tm.year= (uint) sint2korr(to);
tm.month= (uint) to[2];
tm.day= (uint) to[3];
- /*
- Note, that though ranges of hour, minute and second are not checked
- here we rely on them being < 256: otherwise
- we'll get buffer overflow in make_{date,time} functions.
- */
if (length > 4)
{
tm.hour= (uint) to[4];
@@ -405,7 +394,7 @@ static void set_param_datetime(Item_param *param, uchar **pos, ulong len)
tm.second_part= (length > 7) ? (ulong) sint4korr(to+7) : 0;
}
else
- set_zero_time(&tm);
+ set_zero_time(&tm, MYSQL_TIMESTAMP_DATETIME);
param->set_time(&tm, MYSQL_TIMESTAMP_DATETIME,
MAX_DATETIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN);
*pos+= length;
@@ -419,11 +408,7 @@ static void set_param_date(Item_param *param, uchar **pos, ulong len)
if (length >= 4)
{
uchar *to= *pos;
- /*
- Note, that though ranges of hour, minute and second are not checked
- here we rely on them being < 256: otherwise
- we'll get buffer overflow in make_{date,time} functions.
- */
+
tm.year= (uint) sint2korr(to);
tm.month= (uint) to[2];
tm.day= (uint) to[3];
@@ -433,7 +418,7 @@ static void set_param_date(Item_param *param, uchar **pos, ulong len)
tm.neg= 0;
}
else
- set_zero_time(&tm);
+ set_zero_time(&tm, MYSQL_TIMESTAMP_DATE);
param->set_time(&tm, MYSQL_TIMESTAMP_DATE,
MAX_DATE_WIDTH * MY_CHARSET_BIN_MB_MAXLEN);
*pos+= length;
diff --git a/tests/client_test.c b/tests/client_test.c
index 227f7e29ef2..bf0b69f9354 100644
--- a/tests/client_test.c
+++ b/tests/client_test.c
@@ -11088,6 +11088,139 @@ static void test_bug6096()
}
+/*
+ Test of basic checks that are performed in server for components
+ of MYSQL_TIME parameters.
+ */
+static void test_datetime_ranges()
+{
+ const char *stmt_text;
+ int rc, i;
+ MYSQL_STMT *stmt;
+ MYSQL_BIND bind[6];
+ MYSQL_TIME tm[6];
+
+ myheader("test_datetime_ranges");
+
+ stmt_text= "drop table if exists t1";
+ rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
+ myquery(rc);
+
+ stmt_text= "create table t1 (year datetime, month datetime, day datetime, "
+ "hour datetime, min datetime, sec datetime)";
+ rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
+ myquery(rc);
+
+ stmt= mysql_simple_prepare(mysql,
+ "INSERT INTO t1 VALUES (?, ?, ?, ?, ?, ?)");
+ check_stmt(stmt);
+ verify_param_count(stmt, 6);
+
+ bzero(bind, sizeof(bind));
+ for (i= 0; i < 6; i++)
+ {
+ bind[i].buffer_type= MYSQL_TYPE_DATETIME;
+ bind[i].buffer= &tm[i];
+ }
+ rc= mysql_stmt_bind_param(stmt, bind);
+ check_execute(stmt, rc);
+
+ tm[0].year= 2004; tm[0].month= 11; tm[0].day= 10;
+ tm[0].hour= 12; tm[0].minute= 30; tm[0].second= 30;
+ tm[0].second_part= 0; tm[0].neg= 0;
+
+ tm[5]= tm[4]= tm[3]= tm[2]= tm[1]= tm[0];
+ tm[0].year= 10000; tm[1].month= 13; tm[2].day= 32;
+ tm[3].hour= 24; tm[4].minute= 60; tm[5].second= 60;
+
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+ DIE_UNLESS(mysql_warning_count(mysql) != 6);
+
+ verify_col_data("t1", "year", "0000-00-00 00:00:00");
+ verify_col_data("t1", "month", "0000-00-00 00:00:00");
+ verify_col_data("t1", "day", "0000-00-00 00:00:00");
+ verify_col_data("t1", "hour", "0000-00-00 00:00:00");
+ verify_col_data("t1", "min", "0000-00-00 00:00:00");
+ verify_col_data("t1", "sec", "0000-00-00 00:00:00");
+
+ mysql_stmt_close(stmt);
+
+ stmt_text= "delete from t1";
+ rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
+ myquery(rc);
+
+ stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 (year, month, day) "
+ "VALUES (?, ?, ?)");
+ check_stmt(stmt);
+ verify_param_count(stmt, 3);
+
+ /*
+ We reuse contents of bind and tm arrays left from previous part of test.
+ */
+ for (i= 0; i < 3; i++)
+ bind[i].buffer_type= MYSQL_TYPE_DATE;
+
+ rc= mysql_stmt_bind_param(stmt, bind);
+ check_execute(stmt, rc);
+
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+ DIE_UNLESS(mysql_warning_count(mysql) != 3);
+
+ verify_col_data("t1", "year", "0000-00-00 00:00:00");
+ verify_col_data("t1", "month", "0000-00-00 00:00:00");
+ verify_col_data("t1", "day", "0000-00-00 00:00:00");
+
+ mysql_stmt_close(stmt);
+
+ stmt_text= "drop table t1";
+ rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
+ myquery(rc);
+
+ stmt_text= "create table t1 (day_ovfl time, day time, hour time, min time, sec time)";
+ rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
+ myquery(rc);
+
+ stmt= mysql_simple_prepare(mysql,
+ "INSERT INTO t1 VALUES (?, ?, ?, ?, ?)");
+ check_stmt(stmt);
+ verify_param_count(stmt, 5);
+
+ /*
+ Again we reuse what we can from previous part of test.
+ */
+ for (i= 0; i < 5; i++)
+ bind[i].buffer_type= MYSQL_TYPE_TIME;
+
+ rc= mysql_stmt_bind_param(stmt, bind);
+ check_execute(stmt, rc);
+
+ tm[0].year= 0; tm[0].month= 0; tm[0].day= 10;
+ tm[0].hour= 12; tm[0].minute= 30; tm[0].second= 30;
+ tm[0].second_part= 0; tm[0].neg= 0;
+
+ tm[4]= tm[3]= tm[2]= tm[1]= tm[0];
+ tm[0].day= 35; tm[1].day= 34; tm[2].hour= 30; tm[3].minute= 60; tm[4].second= 60;
+
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+ DIE_UNLESS(mysql_warning_count(mysql) != 2);
+
+ verify_col_data("t1", "day_ovfl", "838:59:59");
+ verify_col_data("t1", "day", "828:30:30");
+ verify_col_data("t1", "hour", "270:30:30");
+ verify_col_data("t1", "min", "00:00:00");
+ verify_col_data("t1", "sec", "00:00:00");
+
+ mysql_stmt_close(stmt);
+
+ stmt_text= "drop table t1";
+ rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
+ myquery(rc);
+}
+
+
/*
Read and parse arguments and MySQL options from my.cnf
*/
@@ -11404,6 +11537,8 @@ int main(int argc, char **argv)
test_bug6046(); /* NATURAL JOIN transformation works in PS */
test_bug6081(); /* test of mysql_create_db()/mysql_rm_db() */
test_bug6096(); /* max_length for numeric columns */
+ test_datetime_ranges(); /* Test if basic checks are performed for
+ components of MYSQL_TIME parameters */
/*
XXX: PLEASE RUN THIS PROGRAM UNDER VALGRIND AND VERIFY THAT YOUR TEST
DOESN'T CONTAIN WARNINGS/ERRORS BEFORE YOU PUSH.
From 5ddc564d892928e42f75adfa01bee3d50b416770 Mon Sep 17 00:00:00 2001
From: "dlenev@mysql.com" <>
Date: Mon, 15 Nov 2004 16:11:13 +0300
Subject: [PATCH 013/145] Proposed fix for bug #6439 "from_unixtime() function
returns wrong datetime values for too big argument".
Added range checking for from_unixtime() argument, cleaned up code
a bit.
---
mysql-test/r/func_time.result | 6 ++++
mysql-test/t/func_time.test | 7 +++++
sql/item_timefunc.cc | 57 ++++++++++++++---------------------
3 files changed, 36 insertions(+), 34 deletions(-)
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result
index 877ca0e2d51..32034bf289d 100644
--- a/mysql-test/r/func_time.result
+++ b/mysql-test/r/func_time.result
@@ -470,3 +470,9 @@ unix_timestamp(@a)
select unix_timestamp('1969-12-01 19:00:01');
unix_timestamp('1969-12-01 19:00:01')
0
+select from_unixtime(0);
+from_unixtime(0)
+NULL
+select from_unixtime(2145916800);
+from_unixtime(2145916800)
+NULL
diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test
index fffda12c14e..da18269cf6a 100644
--- a/mysql-test/t/func_time.test
+++ b/mysql-test/t/func_time.test
@@ -225,3 +225,10 @@ drop table t1,t2,t3;
select @a:=FROM_UNIXTIME(1);
select unix_timestamp(@a);
select unix_timestamp('1969-12-01 19:00:01');
+
+#
+# Test for bug #6439 "unix_timestamp() function returns wrong datetime
+# values for too big argument". It should return error instead.
+#
+select from_unixtime(0);
+select from_unixtime(2145916800);
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index ed950a33166..d188310be24 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -919,21 +919,14 @@ String *Item_func_date_format::val_str(String *str)
String *Item_func_from_unixtime::val_str(String *str)
{
- struct tm tm_tmp,*start;
- time_t tmp=(time_t) args[0]->val_int();
- if ((null_value=args[0]->null_value))
+ TIME ltime;
+ if (get_date(<ime, 0))
return 0;
- localtime_r(&tmp,&tm_tmp);
- start=&tm_tmp;
if (str->alloc(20))
return str; /* purecov: inspected */
sprintf((char*) str->ptr(),"%04d-%02d-%02d %02d:%02d:%02d",
- (int) start->tm_year+1900,
- (int) start->tm_mon+1,
- (int) start->tm_mday,
- (int) start->tm_hour,
- (int) start->tm_min,
- (int) start->tm_sec);
+ (int) ltime.year, (int) ltime.month, (int) ltime.day,
+ (int) ltime.hour, (int) ltime.minute, (int) ltime.second);
str->length(19);
return str;
}
@@ -941,37 +934,33 @@ String *Item_func_from_unixtime::val_str(String *str)
longlong Item_func_from_unixtime::val_int()
{
- time_t tmp=(time_t) (ulong) args[0]->val_int();
- if ((null_value=args[0]->null_value))
+ TIME ltime;
+ if (get_date(<ime, 0))
return 0;
- struct tm tm_tmp,*start;
- localtime_r(&tmp,&tm_tmp);
- start= &tm_tmp;
- return ((longlong) ((ulong) ((uint) start->tm_year+1900)*10000L+
- (((uint) start->tm_mon+1)*100+
- (uint) start->tm_mday))*LL(1000000)+
- (longlong) ((ulong) ((uint) start->tm_hour)*10000L+
- (ulong) (((uint) start->tm_min)*100L+
- (uint) start->tm_sec)));
+ return ((longlong)(ltime.year*10000L+ltime.month*100+ltime.day)*LL(1000000)+
+ (longlong)(ltime.hour*10000L+ltime.minute*100+ltime.second));
}
bool Item_func_from_unixtime::get_date(TIME *ltime,
bool fuzzy_date __attribute__((unused)))
{
- time_t tmp=(time_t) (ulong) args[0]->val_int();
- if ((null_value=args[0]->null_value))
+ struct tm tm_tmp;
+ time_t tmp;
+ longlong arg= args[0]->val_int();
+ if ((null_value= (args[0]->null_value ||
+ arg < TIMESTAMP_MIN_VALUE ||
+ arg > TIMESTAMP_MAX_VALUE)))
return 1;
- struct tm tm_tmp,*start;
+ tmp= arg;
localtime_r(&tmp,&tm_tmp);
- start= &tm_tmp;
- ltime->year= start->tm_year+1900;
- ltime->month= start->tm_mon+1;
- ltime->day= start->tm_mday;
- ltime->hour= start->tm_hour;
- ltime->minute=start->tm_min;
- ltime->second=start->tm_sec;
- ltime->second_part=0;
- ltime->neg=0;
+ ltime->year= tm_tmp.tm_year+1900;
+ ltime->month= tm_tmp.tm_mon+1;
+ ltime->day= tm_tmp.tm_mday;
+ ltime->hour= tm_tmp.tm_hour;
+ ltime->minute= tm_tmp.tm_min;
+ ltime->second= tm_tmp.tm_sec;
+ ltime->second_part= 0;
+ ltime->neg= 0;
return 0;
}
From dd64377dc2eb6478e862929c9b47965f82a18b93 Mon Sep 17 00:00:00 2001
From: "heikki@hundin.mysql.fi" <>
Date: Tue, 16 Nov 2004 20:37:42 +0200
Subject: [PATCH 014/145] ha_innodb.cc: Fix InnoDB bug #6287: if one uses
INSERT IGNORE to insert several rows at a time, and the first inserts are
ignored because of a duplicate key collision, then InnoDB in a replication
slave assigns AUTO_INCREMENT values 1 bigger than in the master
---
sql/ha_innodb.cc | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index d57a9f73c91..91f92c8cadb 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -2172,8 +2172,9 @@ ha_innobase::write_row(
same SQL statement! */
if (auto_inc == 0 && user_thd->next_insert_id != 0) {
- auto_inc = user_thd->next_insert_id;
- auto_inc_counter_for_this_stat = auto_inc;
+
+ auto_inc_counter_for_this_stat
+ = user_thd->next_insert_id;
}
if (auto_inc == 0 && auto_inc_counter_for_this_stat) {
@@ -2181,14 +2182,14 @@ ha_innobase::write_row(
this SQL statement with SET INSERT_ID. We must
assign sequential values from the counter. */
- auto_inc_counter_for_this_stat++;
- incremented_auto_inc_for_stat = TRUE;
-
auto_inc = auto_inc_counter_for_this_stat;
/* We give MySQL a new value to place in the
auto-inc column */
user_thd->next_insert_id = auto_inc;
+
+ auto_inc_counter_for_this_stat++;
+ incremented_auto_inc_for_stat = TRUE;
}
if (auto_inc != 0) {
From 0acc6f83b2d0fae4bf3306e73c1de607f05feadd Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Wed, 17 Nov 2004 08:10:26 +0000
Subject: [PATCH 015/145] enabled having system tables in ndb
---
sql/sql_acl.cc | 37 +++++++++++++++++++++++++++----------
1 file changed, 27 insertions(+), 10 deletions(-)
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 98af43e17a7..d6f52fed1d2 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -1384,8 +1384,10 @@ static bool update_user_table(THD *thd, const char *host, const char *user,
table->field[0]->store(host,(uint) strlen(host), &my_charset_latin1);
table->field[1]->store(user,(uint) strlen(user), &my_charset_latin1);
+ table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS);
if (table->file->index_read_idx(table->record[0],0,
- (byte*) table->field[0]->ptr,0,
+ (byte*) table->field[0]->ptr,
+ table->key_info[0].key_length,
HA_READ_KEY_EXACT))
{
my_error(ER_PASSWORD_NO_MATCH,MYF(0)); /* purecov: deadcode */
@@ -1463,9 +1465,11 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
table->field[0]->store(combo.host.str,combo.host.length, &my_charset_latin1);
table->field[1]->store(combo.user.str,combo.user.length, &my_charset_latin1);
+ table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS);
if (table->file->index_read_idx(table->record[0], 0,
- (byte*) table->field[0]->ptr,0,
- HA_READ_KEY_EXACT))
+ (byte*) table->field[0]->ptr,
+ table->key_info[0].key_length,
+ HA_READ_KEY_EXACT))
{
if (!create_user)
{
@@ -1568,6 +1572,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
We should NEVER delete from the user table, as a uses can still
use mysqld even if he doesn't have any privileges in the user table!
*/
+ table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS);
if (cmp_record(table,record[1]) &&
(error=table->file->update_row(table->record[1],table->record[0])))
{ // This should never happen
@@ -1645,8 +1650,11 @@ static int replace_db_table(TABLE *table, const char *db,
table->field[0]->store(combo.host.str,combo.host.length, &my_charset_latin1);
table->field[1]->store(db,(uint) strlen(db), &my_charset_latin1);
table->field[2]->store(combo.user.str,combo.user.length, &my_charset_latin1);
- if (table->file->index_read_idx(table->record[0],0,(byte*) table->field[0]->ptr,0,
- HA_READ_KEY_EXACT))
+ table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS);
+ if (table->file->index_read_idx(table->record[0],0,
+ (byte*) table->field[0]->ptr,
+ table->key_info[0].key_length,
+ HA_READ_KEY_EXACT))
{
if (what == 'N')
{ // no row, no revoke
@@ -1679,6 +1687,7 @@ static int replace_db_table(TABLE *table, const char *db,
/* update old existing row */
if (rights)
{
+ table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS);
if ((error=table->file->update_row(table->record[1],table->record[0])))
goto table_error; /* purecov: deadcode */
}
@@ -1953,8 +1962,10 @@ static int replace_column_table(GRANT_TABLE *g_t,
table->field[4]->store(xx->column.ptr(),xx->column.length(),
&my_charset_latin1);
+ table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS);
if (table->file->index_read(table->record[0],(byte*) table->field[0]->ptr,
- 0, HA_READ_KEY_EXACT))
+ table->key_info[0].key_length,
+ HA_READ_KEY_EXACT))
{
if (revoke_grant)
{
@@ -2022,8 +2033,10 @@ static int replace_column_table(GRANT_TABLE *g_t,
if (revoke_grant)
{
+ table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS);
if (table->file->index_read(table->record[0], (byte*) table->field[0]->ptr,
- key_length, HA_READ_KEY_EXACT))
+ table->key_info[0].key_length,
+ HA_READ_KEY_EXACT))
goto end;
/* Scan through all rows with the same host,db,user and table */
@@ -2112,9 +2125,10 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
table->field[2]->store(combo.user.str,combo.user.length, &my_charset_latin1);
table->field[3]->store(table_name,(uint) strlen(table_name), &my_charset_latin1);
store_record(table,record[1]); // store at pos 1
-
+ table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS);
if (table->file->index_read_idx(table->record[0],0,
- (byte*) table->field[0]->ptr,0,
+ (byte*) table->field[0]->ptr,
+ table->key_info[0].key_length,
HA_READ_KEY_EXACT))
{
/*
@@ -3571,9 +3585,12 @@ int mysql_drop_user(THD *thd, List &list)
tables[0].table->field[1]->store(user_name->user.str,(uint)
user_name->user.length,
system_charset_info);
+ tables[0].table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS);
if (!tables[0].table->file->index_read_idx(tables[0].table->record[0],0,
(byte*) tables[0].table->
- field[0]->ptr,0,
+ field[0]->ptr,
+ tables[0].table->
+ key_info[0].key_length,
HA_READ_KEY_EXACT))
{
int error;
From 1700bf3844b5504fbde8c575968f867c30a76a8e Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Wed, 17 Nov 2004 08:15:53 +0000
Subject: [PATCH 016/145] Enabled usage of new system variables for ndb -
ndb_use_exact_count - ndb_autoincrement_prefetch_sz -
ndb_use_transactions - ndb_force_send moved "inlined" functions to .cc file
since they are virtual anyways enabled printout od ndb errors in warnings
even if mapping existst to mysql error code
---
sql/ha_ndbcluster.cc | 194 +++++++++++++++++++++++++++++++------------
sql/ha_ndbcluster.h | 46 ++++------
sql/mysqld.cc | 34 +++++++-
sql/set_var.cc | 32 ++++++-
sql/sql_class.h | 6 ++
5 files changed, 223 insertions(+), 89 deletions(-)
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index bc1c887bfab..8ef24ad5af1 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -39,9 +39,6 @@ static const int parallelism= 240;
// createable against NDB from this handler
static const int max_transactions= 256;
-// Default value for prefetch of autoincrement values
-static const ha_rows autoincrement_prefetch= 32;
-
// connectstring to cluster if given by mysqld
const char *ndbcluster_connectstring= 0;
@@ -103,58 +100,52 @@ struct err_code_mapping
{
int ndb_err;
int my_err;
+ int show_warning;
};
static const err_code_mapping err_map[]=
{
- { 626, HA_ERR_KEY_NOT_FOUND },
- { 630, HA_ERR_FOUND_DUPP_KEY },
- { 893, HA_ERR_FOUND_DUPP_UNIQUE },
- { 721, HA_ERR_TABLE_EXIST },
- { 4244, HA_ERR_TABLE_EXIST },
+ { 626, HA_ERR_KEY_NOT_FOUND, 0 },
+ { 630, HA_ERR_FOUND_DUPP_KEY, 0 },
+ { 893, HA_ERR_FOUND_DUPP_UNIQUE, 0 },
+ { 721, HA_ERR_TABLE_EXIST, 1 },
+ { 4244, HA_ERR_TABLE_EXIST, 1 },
- { 709, HA_ERR_NO_SUCH_TABLE },
- { 284, HA_ERR_NO_SUCH_TABLE },
+ { 709, HA_ERR_NO_SUCH_TABLE, 1 },
+ { 284, HA_ERR_NO_SUCH_TABLE, 1 },
- { 266, HA_ERR_LOCK_WAIT_TIMEOUT },
- { 274, HA_ERR_LOCK_WAIT_TIMEOUT },
- { 296, HA_ERR_LOCK_WAIT_TIMEOUT },
- { 297, HA_ERR_LOCK_WAIT_TIMEOUT },
- { 237, HA_ERR_LOCK_WAIT_TIMEOUT },
+ { 266, HA_ERR_LOCK_WAIT_TIMEOUT, 1 },
+ { 274, HA_ERR_LOCK_WAIT_TIMEOUT, 1 },
+ { 296, HA_ERR_LOCK_WAIT_TIMEOUT, 1 },
+ { 297, HA_ERR_LOCK_WAIT_TIMEOUT, 1 },
+ { 237, HA_ERR_LOCK_WAIT_TIMEOUT, 1 },
- { 623, HA_ERR_RECORD_FILE_FULL },
- { 624, HA_ERR_RECORD_FILE_FULL },
- { 625, HA_ERR_RECORD_FILE_FULL },
- { 826, HA_ERR_RECORD_FILE_FULL },
- { 827, HA_ERR_RECORD_FILE_FULL },
- { 832, HA_ERR_RECORD_FILE_FULL },
+ { 623, HA_ERR_RECORD_FILE_FULL, 1 },
+ { 624, HA_ERR_RECORD_FILE_FULL, 1 },
+ { 625, HA_ERR_RECORD_FILE_FULL, 1 },
+ { 826, HA_ERR_RECORD_FILE_FULL, 1 },
+ { 827, HA_ERR_RECORD_FILE_FULL, 1 },
+ { 832, HA_ERR_RECORD_FILE_FULL, 1 },
- { 0, 1 },
+ { 0, 1, 0 },
- { -1, -1 }
+ { -1, -1, 1 }
};
static int ndb_to_mysql_error(const NdbError *err)
{
uint i;
- for (i=0 ; err_map[i].ndb_err != err->code ; i++)
+ for (i=0; err_map[i].ndb_err != err->code && err_map[i].my_err != -1; i++);
+ if (err_map[i].show_warning)
{
- if (err_map[i].my_err == -1){
- // Push the NDB error message as warning
- push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
- ER_GET_ERRMSG, ER(ER_GET_ERRMSG),
- err->code, err->message, "NDB");
- return err->code;
- }
+ // Push the NDB error message as warning
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ ER_GET_ERRMSG, ER(ER_GET_ERRMSG),
+ err->code, err->message, "NDB");
}
- // Push the NDB error message as warning
- // this since e.g. HA_ERR_RECORD_FILE_FULL maps to
- // several error codes in NDB, and the uses needs
- // to know which one it is
- push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
- ER_GET_ERRMSG, ER(ER_GET_ERRMSG),
- err->code, err->message, "NDB");
+ if (err_map[i].my_err == -1)
+ return err->code;
return err_map[i].my_err;
}
@@ -168,7 +159,7 @@ int execute_no_commit(ha_ndbcluster *h, NdbConnection *trans)
if (m_batch_execute)
return 0;
#endif
- return trans->execute(NoCommit,AbortOnError,1);
+ return trans->execute(NoCommit,AbortOnError,h->m_force_send);
}
inline
@@ -179,7 +170,18 @@ int execute_commit(ha_ndbcluster *h, NdbConnection *trans)
if (m_batch_execute)
return 0;
#endif
- return trans->execute(Commit,AbortOnError,1);
+ return trans->execute(Commit,AbortOnError,h->m_force_send);
+}
+
+inline
+int execute_commit(THD *thd, NdbConnection *trans)
+{
+ int m_batch_execute= 0;
+#ifdef NOT_USED
+ if (m_batch_execute)
+ return 0;
+#endif
+ return trans->execute(Commit,AbortOnError,thd->variables.ndb_force_send);
}
inline
@@ -190,7 +192,7 @@ int execute_no_commit_ie(ha_ndbcluster *h, NdbConnection *trans)
if (m_batch_execute)
return 0;
#endif
- return trans->execute(NoCommit,IgnoreError,1);
+ return trans->execute(NoCommit,IgnoreError,h->m_force_send);
}
/*
@@ -233,6 +235,8 @@ void ha_ndbcluster::set_rec_per_key()
void ha_ndbcluster::records_update()
{
+ if (m_ha_not_exact_count)
+ return;
DBUG_ENTER("ha_ndbcluster::records_update");
struct Ndb_table_local_info *info= (struct Ndb_table_local_info *)m_table_info;
DBUG_PRINT("info", ("id=%d, no_uncommitted_rows_count=%d",
@@ -256,6 +260,8 @@ void ha_ndbcluster::records_update()
void ha_ndbcluster::no_uncommitted_rows_execute_failure()
{
+ if (m_ha_not_exact_count)
+ return;
DBUG_ENTER("ha_ndbcluster::no_uncommitted_rows_execute_failure");
THD *thd= current_thd;
((Thd_ndb*)(thd->transaction.thd_ndb))->error= 1;
@@ -264,6 +270,8 @@ void ha_ndbcluster::no_uncommitted_rows_execute_failure()
void ha_ndbcluster::no_uncommitted_rows_init(THD *thd)
{
+ if (m_ha_not_exact_count)
+ return;
DBUG_ENTER("ha_ndbcluster::no_uncommitted_rows_init");
struct Ndb_table_local_info *info= (struct Ndb_table_local_info *)m_table_info;
Thd_ndb *thd_ndb= (Thd_ndb *)thd->transaction.thd_ndb;
@@ -281,6 +289,8 @@ void ha_ndbcluster::no_uncommitted_rows_init(THD *thd)
void ha_ndbcluster::no_uncommitted_rows_update(int c)
{
+ if (m_ha_not_exact_count)
+ return;
DBUG_ENTER("ha_ndbcluster::no_uncommitted_rows_update");
struct Ndb_table_local_info *info=
(struct Ndb_table_local_info *)m_table_info;
@@ -293,6 +303,8 @@ void ha_ndbcluster::no_uncommitted_rows_update(int c)
void ha_ndbcluster::no_uncommitted_rows_reset(THD *thd)
{
+ if (m_ha_not_exact_count)
+ return;
DBUG_ENTER("ha_ndbcluster::no_uncommitted_rows_reset");
((Thd_ndb*)(thd->transaction.thd_ndb))->count++;
((Thd_ndb*)(thd->transaction.thd_ndb))->error= 0;
@@ -1229,7 +1241,8 @@ inline int ha_ndbcluster::next_result(byte *buf)
DBUG_PRINT("info", ("ops_pending: %d", m_ops_pending));
if (m_ops_pending)
{
- if (current_thd->transaction.on)
+ // if (current_thd->transaction.on)
+ if (m_transaction_on)
{
if (execute_no_commit(this,trans) != 0)
DBUG_RETURN(ndb_err(trans));
@@ -1715,7 +1728,8 @@ int ha_ndbcluster::write_row(byte *record)
(int)m_rows_inserted, (int)m_bulk_insert_rows));
m_bulk_insert_not_flushed= FALSE;
- if (thd->transaction.on)
+ // if (thd->transaction.on)
+ if (m_transaction_on)
{
if (execute_no_commit(this,trans) != 0)
{
@@ -1888,7 +1902,7 @@ int ha_ndbcluster::update_row(const byte *old_data, byte *new_data)
for (i= 0; i < table->fields; i++)
{
Field *field= table->field[i];
- if ((thd->query_id == field->query_id) &&
+ if (((thd->query_id == field->query_id) || m_retrieve_all_fields) &&
(!(field->flags & PRI_KEY_FLAG)) &&
set_ndb_value(op, field, i))
ERR_RETURN(op->getNdbError());
@@ -2547,14 +2561,17 @@ void ha_ndbcluster::info(uint flag)
DBUG_PRINT("info", ("HA_STATUS_VARIABLE"));
if (m_table_info)
{
- records_update();
+ if (m_ha_not_exact_count)
+ records= 100;
+ else
+ records_update();
}
else
{
- Uint64 rows;
- if(ndb_get_table_statistics(m_ndb, m_tabname, &rows, 0) == 0){
- records= rows;
- }
+ Uint64 rows= 100;
+ if (current_thd->variables.ndb_use_exact_count)
+ ndb_get_table_statistics(m_ndb, m_tabname, &rows, 0);
+ records= rows;
}
}
if (flag & HA_STATUS_CONST)
@@ -2943,6 +2960,15 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
pointer to point to the NDB transaction.
*/
+ // store thread specific data first to set the right context
+ m_force_send= thd->variables.ndb_force_send;
+ m_ha_not_exact_count= !thd->variables.ndb_use_exact_count;
+ m_autoincrement_prefetch= thd->variables.ndb_autoincrement_prefetch_sz;
+ if (!thd->transaction.on)
+ m_transaction_on= FALSE;
+ else
+ m_transaction_on= thd->variables.ndb_use_transactions;
+
m_active_trans= thd->transaction.all.ndb_tid ?
(NdbConnection*)thd->transaction.all.ndb_tid:
(NdbConnection*)thd->transaction.stmt.ndb_tid;
@@ -3063,7 +3089,7 @@ int ndbcluster_commit(THD *thd, void *ndb_transaction)
"stmt" : "all"));
DBUG_ASSERT(ndb && trans);
- if (execute_commit(0,trans) != 0)
+ if (execute_commit(thd,trans) != 0)
{
const NdbError err= trans->getNdbError();
const NdbOperation *error_op= trans->getNdbErrorOperation();
@@ -3617,11 +3643,11 @@ longlong ha_ndbcluster::get_auto_increment()
DBUG_ENTER("get_auto_increment");
DBUG_PRINT("enter", ("m_tabname: %s", m_tabname));
int cache_size=
- (m_rows_to_insert - m_rows_inserted < autoincrement_prefetch) ?
+ (m_rows_to_insert - m_rows_inserted < m_autoincrement_prefetch) ?
m_rows_to_insert - m_rows_inserted
- : (m_rows_to_insert > autoincrement_prefetch) ?
+ : (m_rows_to_insert > m_autoincrement_prefetch) ?
m_rows_to_insert
- : autoincrement_prefetch;
+ : m_autoincrement_prefetch;
Uint64 auto_value=
(m_skip_auto_increment) ?
m_ndb->readAutoIncrementValue((const NDBTAB *) m_table)
@@ -3659,7 +3685,11 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg):
m_blobs_pending(0),
m_blobs_buffer(0),
m_blobs_buffer_size(0),
- m_dupkey((uint) -1)
+ m_dupkey((uint) -1),
+ m_ha_not_exact_count(FALSE),
+ m_force_send(TRUE),
+ m_autoincrement_prefetch(32),
+ m_transaction_on(TRUE)
{
int i;
@@ -4309,6 +4339,62 @@ ha_ndbcluster::records_in_range(uint inx, key_range *min_key,
DBUG_RETURN(10); /* Good guess when you don't know anything */
}
+ulong ha_ndbcluster::table_flags(void) const
+{
+ if (m_ha_not_exact_count)
+ return m_table_flags | HA_NOT_EXACT_COUNT;
+ else
+ return m_table_flags;
+}
+const char * ha_ndbcluster::table_type() const
+{
+ return("ndbcluster");
+}
+uint ha_ndbcluster::max_supported_record_length() const
+{
+ return NDB_MAX_TUPLE_SIZE;
+}
+uint ha_ndbcluster::max_supported_keys() const
+{
+ return MAX_KEY;
+}
+uint ha_ndbcluster::max_supported_key_parts() const
+{
+ return NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY;
+}
+uint ha_ndbcluster::max_supported_key_length() const
+{
+ return NDB_MAX_KEY_SIZE;
+}
+bool ha_ndbcluster::low_byte_first() const
+{
+#ifdef WORDS_BIGENDIAN
+ return FALSE;
+#else
+ return TRUE;
+#endif
+}
+bool ha_ndbcluster::has_transactions()
+{
+ return TRUE;
+}
+const char* ha_ndbcluster::index_type(uint key_number)
+{
+ switch (get_index_type(key_number)) {
+ case ORDERED_INDEX:
+ case UNIQUE_ORDERED_INDEX:
+ case PRIMARY_KEY_ORDERED_INDEX:
+ return "BTREE";
+ case UNIQUE_INDEX:
+ case PRIMARY_KEY_INDEX:
+ default:
+ return "HASH";
+ }
+}
+uint8 ha_ndbcluster::table_cache_type()
+{
+ return HA_CACHE_TBL_NOCACHE;
+}
/*
Handling the shared NDB_SHARE structure that is needed to
diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h
index 2121228a869..6c51d1f0af7 100644
--- a/sql/ha_ndbcluster.h
+++ b/sql/ha_ndbcluster.h
@@ -118,15 +118,14 @@ class ha_ndbcluster: public handler
int reset();
int external_lock(THD *thd, int lock_type);
int start_stmt(THD *thd);
- const char * table_type() const { return("ndbcluster");}
+ const char * table_type() const;
const char ** bas_ext() const;
- ulong table_flags(void) const { return m_table_flags; }
+ ulong table_flags(void) const;
ulong index_flags(uint idx, uint part, bool all_parts) const;
- uint max_supported_record_length() const { return NDB_MAX_TUPLE_SIZE; };
- uint max_supported_keys() const { return MAX_KEY; }
- uint max_supported_key_parts() const
- { return NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY; };
- uint max_supported_key_length() const { return NDB_MAX_KEY_SIZE;};
+ uint max_supported_record_length() const;
+ uint max_supported_keys() const;
+ uint max_supported_key_parts() const;
+ uint max_supported_key_length() const;
int rename_table(const char *from, const char *to);
int delete_table(const char *name);
@@ -135,28 +134,9 @@ class ha_ndbcluster: public handler
THR_LOCK_DATA **to,
enum thr_lock_type lock_type);
- bool low_byte_first() const
- {
-#ifdef WORDS_BIGENDIAN
- return FALSE;
-#else
- return TRUE;
-#endif
- }
- bool has_transactions() { return TRUE; }
-
- const char* index_type(uint key_number) {
- switch (get_index_type(key_number)) {
- case ORDERED_INDEX:
- case UNIQUE_ORDERED_INDEX:
- case PRIMARY_KEY_ORDERED_INDEX:
- return "BTREE";
- case UNIQUE_INDEX:
- case PRIMARY_KEY_INDEX:
- default:
- return "HASH";
- }
- }
+ bool low_byte_first() const;
+ bool has_transactions();
+ const char* index_type(uint key_number);
double scan_time();
ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key);
@@ -165,7 +145,7 @@ class ha_ndbcluster: public handler
static Thd_ndb* seize_thd_ndb();
static void release_thd_ndb(Thd_ndb* thd_ndb);
- uint8 table_cache_type() { return HA_CACHE_TBL_NOCACHE; }
+ uint8 table_cache_type();
private:
int alter_table_name(const char *from, const char *to);
@@ -256,6 +236,10 @@ class ha_ndbcluster: public handler
char *m_blobs_buffer;
uint32 m_blobs_buffer_size;
uint m_dupkey;
+ bool m_ha_not_exact_count;
+ bool m_force_send;
+ ha_rows m_autoincrement_prefetch;
+ bool m_transaction_on;
void set_rec_per_key();
void records_update();
@@ -265,6 +249,8 @@ class ha_ndbcluster: public handler
void no_uncommitted_rows_reset(THD *);
friend int execute_no_commit(ha_ndbcluster*, NdbConnection*);
+ friend int execute_commit(ha_ndbcluster*, NdbConnection*);
+ friend int execute_no_commit_ie(ha_ndbcluster*, NdbConnection*);
};
bool ndbcluster_init(void);
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 1da5359bae0..5ee52326276 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -3947,7 +3947,11 @@ enum options_mysqld
OPT_INNODB_FILE_PER_TABLE, OPT_CRASH_BINLOG_INNODB,
OPT_INNODB_LOCKS_UNSAFE_FOR_BINLOG,
OPT_SAFE_SHOW_DB, OPT_INNODB_SAFE_BINLOG,
- OPT_INNODB, OPT_ISAM, OPT_NDBCLUSTER, OPT_NDB_CONNECTSTRING, OPT_SKIP_SAFEMALLOC,
+ OPT_INNODB, OPT_ISAM,
+ OPT_NDBCLUSTER, OPT_NDB_CONNECTSTRING, OPT_NDB_USE_EXACT_COUNT,
+ OPT_NDB_FORCE_SEND, OPT_NDB_AUTOINCREMENT_PREFETCH_SZ,
+ OPT_NDB_USE_TRANSACTIONS,
+ OPT_SKIP_SAFEMALLOC,
OPT_TEMP_POOL, OPT_TX_ISOLATION,
OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS,
OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL,
@@ -4386,9 +4390,31 @@ Disable with --skip-ndbcluster (will save memory).",
(gptr*) &opt_ndbcluster, (gptr*) &opt_ndbcluster, 0, GET_BOOL, NO_ARG, 1, 0, 0,
0, 0, 0},
#ifdef HAVE_NDBCLUSTER_DB
- {"ndb-connectstring", OPT_NDB_CONNECTSTRING, "Connect string for ndbcluster.",
- (gptr*) &ndbcluster_connectstring, (gptr*) &ndbcluster_connectstring, 0, GET_STR,
- REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"ndb-connectstring", OPT_NDB_CONNECTSTRING,
+ "Connect string for ndbcluster.",
+ (gptr*) &ndbcluster_connectstring, (gptr*) &ndbcluster_connectstring,
+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"ndb_autoincrement_prefetch_sz", OPT_NDB_AUTOINCREMENT_PREFETCH_SZ,
+ "Specify number of autoincrement values that are prefetched",
+ (gptr*) &global_system_variables.ndb_autoincrement_prefetch_sz,
+ (gptr*) &global_system_variables.ndb_autoincrement_prefetch_sz,
+ 0, GET_INT, REQUIRED_ARG, 32, 1, 256, 0, 0, 0},
+ {"ndb_force_send", OPT_NDB_FORCE_SEND,
+ "Force send of buffers to ndb immediately without waiting for other threads",
+ (gptr*) &global_system_variables.ndb_force_send,
+ (gptr*) &global_system_variables.ndb_force_send,
+ 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
+ {"ndb_use_exact_count", OPT_NDB_USE_EXACT_COUNT,
+ "Use exact records count during query planning and for "
+ "fast select count(*)",
+ (gptr*) &global_system_variables.ndb_use_exact_count,
+ (gptr*) &global_system_variables.ndb_use_exact_count,
+ 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
+ {"ndb_use_transactions", OPT_NDB_USE_TRANSACTIONS,
+ "Use transactions in ndb",
+ (gptr*) &global_system_variables.ndb_use_transactions,
+ (gptr*) &global_system_variables.ndb_use_transactions,
+ 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
#endif
{"new", 'n', "Use very new possible 'unsafe' functions.",
(gptr*) &global_system_variables.new_mode,
diff --git a/sql/set_var.cc b/sql/set_var.cc
index a97506ad07c..f1973b53e49 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -359,6 +359,23 @@ sys_var_thd_bool sys_innodb_table_locks("innodb_table_locks",
sys_var_long_ptr sys_innodb_autoextend_increment("innodb_autoextend_increment",
&srv_auto_extend_increment);
#endif
+#ifdef HAVE_NDBCLUSTER_DB
+// ndb thread specific variable settings
+sys_var_thd_ulong
+sys_ndb_autoincrement_prefetch_sz("ndb_autoincrement_prefetch_sz",
+ &SV::ndb_autoincrement_prefetch_sz);
+sys_var_thd_bool
+sys_ndb_force_send("ndb_force_send",
+ &SV::ndb_force_send);
+sys_var_thd_bool
+sys_ndb_use_exact_count("ndb_use_exact_count",
+ &SV::ndb_use_exact_count);
+sys_var_thd_bool
+sys_ndb_use_transactions("ndb_use_transactions",
+ &SV::ndb_use_transactions);
+// ndb server global variable settings
+// none
+#endif
/* Time/date/datetime formats */
@@ -612,7 +629,13 @@ sys_var *sys_variables[]=
&sys_innodb_table_locks,
&sys_innodb_max_purge_lag,
&sys_innodb_autoextend_increment,
-#endif
+#endif
+#ifdef HAVE_NDBCLUSTER_DB
+ &sys_ndb_autoincrement_prefetch_sz,
+ &sys_ndb_force_send,
+ &sys_ndb_use_exact_count,
+ &sys_ndb_use_transactions,
+#endif
&sys_unique_checks,
&sys_warning_count
};
@@ -772,6 +795,13 @@ struct show_var_st init_vars[]= {
{sys_myisam_sort_buffer_size.name, (char*) &sys_myisam_sort_buffer_size, SHOW_SYS},
#ifdef __NT__
{"named_pipe", (char*) &opt_enable_named_pipe, SHOW_MY_BOOL},
+#endif
+#ifdef HAVE_NDBCLUSTER_DB
+ {sys_ndb_autoincrement_prefetch_sz.name,
+ (char*) &sys_ndb_autoincrement_prefetch_sz, SHOW_SYS},
+ {sys_ndb_force_send.name, (char*) &sys_ndb_force_send, SHOW_SYS},
+ {sys_ndb_use_exact_count.name,(char*) &sys_ndb_use_exact_count, SHOW_SYS},
+ {sys_ndb_use_transactions.name,(char*) &sys_ndb_use_transactions, SHOW_SYS},
#endif
{sys_net_buffer_length.name,(char*) &sys_net_buffer_length, SHOW_SYS},
{sys_net_read_timeout.name, (char*) &sys_net_read_timeout, SHOW_SYS},
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 312d9de9794..d0d9afc7746 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -399,6 +399,12 @@ struct system_variables
#ifdef HAVE_INNOBASE_DB
my_bool innodb_table_locks;
#endif /* HAVE_INNOBASE_DB */
+#ifdef HAVE_NDBCLUSTER_DB
+ ulong ndb_autoincrement_prefetch_sz;
+ my_bool ndb_force_send;
+ my_bool ndb_use_exact_count;
+ my_bool ndb_use_transactions;
+#endif /* HAVE_NDBCLUSTER_DB */
my_bool old_passwords;
/* Only charset part of these variables is sensible */
From 2d8c21f700ceed83e5c7ef3ac20cccb434da48fb Mon Sep 17 00:00:00 2001
From: "serg@serg.mylan" <>
Date: Wed, 17 Nov 2004 13:38:35 +0100
Subject: [PATCH 017/145] test for bug#5528
---
mysql-test/r/fulltext.result | 9 +++++++++
mysql-test/t/fulltext.test | 10 ++++++++++
2 files changed, 19 insertions(+)
diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result
index 19bd355f537..31be1881897 100644
--- a/mysql-test/r/fulltext.result
+++ b/mysql-test/r/fulltext.result
@@ -298,3 +298,12 @@ 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 (h text, FULLTEXT (h));
+INSERT INTO t1 VALUES ('Jesses Hasse Ling and his syncopators of Swing');
+REPAIR TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 repair status OK
+select count(*) from t1;
+count(*)
+1
+drop table t1;
diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test
index bd887bc63ee..e46399bb876 100644
--- a/mysql-test/t/fulltext.test
+++ b/mysql-test/t/fulltext.test
@@ -240,3 +240,13 @@ select * from t2 where match name against ('a* b* c* d* e* f*' in boolean mode);
drop table t1,t2;
+#
+# icc -ip bug (ip = interprocedural optimization)
+# bug#5528
+#
+CREATE TABLE t1 (h text, FULLTEXT (h));
+INSERT INTO t1 VALUES ('Jesses Hasse Ling and his syncopators of Swing');
+REPAIR TABLE t1;
+select count(*) from t1;
+drop table t1;
+
From d34421c12732951b69d47c4f49486918f5c7823e Mon Sep 17 00:00:00 2001
From: "guilhem@mysql.com" <>
Date: Wed, 17 Nov 2004 16:41:30 +0100
Subject: [PATCH 018/145] Fixes for compilation errors in Windows (casts from
uint32* to uint*) in repl and charset code. Moving the part of user_var.test
using UCS2 to ctype_ucs.test
---
mysql-test/r/ctype_ucs.result | 14 ++++++++++++++
mysql-test/r/user_var.result | 13 +------------
mysql-test/t/ctype_ucs.test | 15 +++++++++++++++
mysql-test/t/user_var.test | 5 +----
sql/slave.cc | 4 ++--
sql/slave.h | 2 +-
sql/sql_parse.cc | 8 ++++----
7 files changed, 38 insertions(+), 23 deletions(-)
diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result
index 0e36b00a670..56830153fd0 100644
--- a/mysql-test/r/ctype_ucs.result
+++ b/mysql-test/r/ctype_ucs.result
@@ -487,3 +487,17 @@ prepare stmt1 from @str2;
execute stmt1 using @ivar;
?
1234
+create table t2 (c char(30)) charset=ucs2;
+set @v=convert('abc' using ucs2);
+reset master;
+insert into t2 values (@v);
+show binlog events from 79;
+Log_name Pos Event_type Server_id Orig_log_pos Info
+master-bin.000001 79 User var 1 79 @`v`=_ucs2 0x006100620063 COLLATE ucs2_general_ci
+master-bin.000001 119 Query 1 119 use `test`; insert into t2 values (@v)
+/*!40019 SET @@session.max_insert_delayed_threads=0*/;
+SET @`v`:=_ucs2 0x006100620063 COLLATE ucs2_general_ci;
+use test;
+SET TIMESTAMP=1100684975;
+insert into t2 values (@v);
+drop table t2;
diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result
index 659c392e153..4f521143d97 100644
--- a/mysql-test/r/user_var.result
+++ b/mysql-test/r/user_var.result
@@ -169,18 +169,12 @@ SET @`a b`='hello';
INSERT INTO t1 VALUES(@`a b`);
set @var1= "';aaa";
insert into t1 values (@var1);
-create table t2 (c char(30)) charset=ucs2;
-set @v=convert('abc' using ucs2);
-insert into t2 values (@v);
show binlog events from 79;
Log_name Pos Event_type Server_id Orig_log_pos Info
master-bin.000001 79 User var 1 79 @`a b`=_latin1 0x68656C6C6F COLLATE latin1_swedish_ci
master-bin.000001 120 Query 1 120 use `test`; INSERT INTO t1 VALUES(@`a b`)
master-bin.000001 184 User var 1 184 @`var1`=_latin1 0x273B616161 COLLATE latin1_swedish_ci
master-bin.000001 226 Query 1 226 use `test`; insert into t1 values (@var1)
-master-bin.000001 290 Query 1 290 use `test`; create table t2 (c char(30)) charset=ucs2
-master-bin.000001 366 User var 1 366 @`v`=_ucs2 0x006100620063 COLLATE ucs2_general_ci
-master-bin.000001 406 Query 1 406 use `test`; insert into t2 values (@v)
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
SET @`a b`:=_latin1 0x68656C6C6F COLLATE latin1_swedish_ci;
use test;
@@ -189,12 +183,7 @@ INSERT INTO t1 VALUES(@`a b`);
SET @`var1`:=_latin1 0x273B616161 COLLATE latin1_swedish_ci;
SET TIMESTAMP=10000;
insert into t1 values (@var1);
-SET TIMESTAMP=10000;
-create table t2 (c char(30)) charset=ucs2;
-SET @`v`:=_ucs2 0x006100620063 COLLATE ucs2_general_ci;
-SET TIMESTAMP=10000;
-insert into t2 values (@v);
-drop table t1, t2;
+drop table t1;
set @var= NULL ;
select FIELD( @var,'1it','Hit') as my_column;
my_column
diff --git a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test
index 4c6d1bbebef..909638042c2 100644
--- a/mysql-test/t/ctype_ucs.test
+++ b/mysql-test/t/ctype_ucs.test
@@ -323,3 +323,18 @@ set @str1 = 'select ?';
set @str2 = convert(@str1 using ucs2);
prepare stmt1 from @str2;
execute stmt1 using @ivar;
+
+#
+# Check correct binlogging of UCS2 user variables (BUG#3875)
+#
+create table t2 (c char(30)) charset=ucs2;
+set @v=convert('abc' using ucs2);
+reset master;
+insert into t2 values (@v);
+show binlog events from 79;
+# more important than SHOW BINLOG EVENTS, mysqlbinlog (where we
+# absolutely need variables names to be quoted and strings to be
+# escaped).
+--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
+--exec $MYSQL_BINLOG --short-form $MYSQL_TEST_DIR/var/log/master-bin.000001
+drop table t2;
diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test
index 3816af42c55..d985be05b94 100644
--- a/mysql-test/t/user_var.test
+++ b/mysql-test/t/user_var.test
@@ -108,16 +108,13 @@ SET @`a b`='hello';
INSERT INTO t1 VALUES(@`a b`);
set @var1= "';aaa";
insert into t1 values (@var1);
-create table t2 (c char(30)) charset=ucs2;
-set @v=convert('abc' using ucs2);
-insert into t2 values (@v);
show binlog events from 79;
# more important than SHOW BINLOG EVENTS, mysqlbinlog (where we
# absolutely need variables names to be quoted and strings to be
# escaped).
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
--exec $MYSQL_BINLOG --short-form $MYSQL_TEST_DIR/var/log/master-bin.000001
-drop table t1, t2;
+drop table t1;
#
diff --git a/sql/slave.cc b/sql/slave.cc
index b6ad35573ff..6bc977e8d41 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -1032,7 +1032,7 @@ bool net_request_file(NET* net, const char* fname)
}
-const char *rewrite_db(const char* db, uint *new_len)
+const char *rewrite_db(const char* db, uint32 *new_len)
{
if (replicate_rewrite_db.is_empty() || !db)
return db;
@@ -1043,7 +1043,7 @@ const char *rewrite_db(const char* db, uint *new_len)
{
if (!strcmp(tmp->key, db))
{
- *new_len= strlen(tmp->val);
+ *new_len= (uint32)strlen(tmp->val);
return tmp->val;
}
}
diff --git a/sql/slave.h b/sql/slave.h
index 97f197fb50a..c6cb81699a2 100644
--- a/sql/slave.h
+++ b/sql/slave.h
@@ -510,7 +510,7 @@ int add_table_rule(HASH* h, const char* table_spec);
int add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec);
void init_table_rule_hash(HASH* h, bool* h_inited);
void init_table_rule_array(DYNAMIC_ARRAY* a, bool* a_inited);
-const char *rewrite_db(const char* db, uint *new_db_len);
+const char *rewrite_db(const char* db, uint32 *new_db_len);
const char *print_slave_db_safe(const char *db);
int check_expected_error(THD* thd, RELAY_LOG_INFO* rli, int error_code);
void skip_load_data_infile(NET* net);
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 7420f9de100..e066e447345 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -4123,7 +4123,7 @@ bool mysql_test_parse_for_slave(THD *thd, char *inBuf, uint length)
- SET uses tot_length.
*/
void calculate_interval_lengths(THD *thd, TYPELIB *interval,
- uint *max_length, uint *tot_length)
+ uint32 *max_length, uint32 *tot_length)
{
const char **pos;
uint *len;
@@ -4135,7 +4135,7 @@ void calculate_interval_lengths(THD *thd, TYPELIB *interval,
*len= (uint) strip_sp((char*) *pos);
uint length= cs->cset->numchars(cs, *pos, *pos + *len);
*tot_length+= length;
- set_if_bigger(*max_length, length);
+ set_if_bigger(*max_length, (uint32)length);
}
}
@@ -4454,7 +4454,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
if (new_field->pack_length > 4)
new_field->pack_length=8;
new_field->interval=interval;
- uint dummy_max_length;
+ uint32 dummy_max_length;
calculate_interval_lengths(thd, interval,
&dummy_max_length, &new_field->length);
new_field->length+= (interval->count - 1);
@@ -4484,7 +4484,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
new_field->interval=interval;
new_field->pack_length=interval->count < 256 ? 1 : 2; // Should be safe
- uint dummy_tot_length;
+ uint32 dummy_tot_length;
calculate_interval_lengths(thd, interval,
&new_field->length, &dummy_tot_length);
set_if_smaller(new_field->length,MAX_FIELD_WIDTH-1);
From f04832b52d698afd2fa5f6829a9dce52be1fd64e Mon Sep 17 00:00:00 2001
From: "guilhem@mysql.com" <>
Date: Wed, 17 Nov 2004 17:06:24 +0100
Subject: [PATCH 019/145] time independent test
---
mysql-test/r/ctype_ucs.result | 3 ++-
mysql-test/t/ctype_ucs.test | 1 +
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result
index 56830153fd0..6394bc28c6e 100644
--- a/mysql-test/r/ctype_ucs.result
+++ b/mysql-test/r/ctype_ucs.result
@@ -487,6 +487,7 @@ prepare stmt1 from @str2;
execute stmt1 using @ivar;
?
1234
+SET TIMESTAMP=10000;
create table t2 (c char(30)) charset=ucs2;
set @v=convert('abc' using ucs2);
reset master;
@@ -498,6 +499,6 @@ master-bin.000001 119 Query 1 119 use `test`; insert into t2 values (@v)
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
SET @`v`:=_ucs2 0x006100620063 COLLATE ucs2_general_ci;
use test;
-SET TIMESTAMP=1100684975;
+SET TIMESTAMP=10000;
insert into t2 values (@v);
drop table t2;
diff --git a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test
index 909638042c2..0b8678ef59b 100644
--- a/mysql-test/t/ctype_ucs.test
+++ b/mysql-test/t/ctype_ucs.test
@@ -327,6 +327,7 @@ execute stmt1 using @ivar;
#
# Check correct binlogging of UCS2 user variables (BUG#3875)
#
+SET TIMESTAMP=10000;
create table t2 (c char(30)) charset=ucs2;
set @v=convert('abc' using ucs2);
reset master;
From f2110823d51288eb5e34533752b58019f352da77 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Thu, 18 Nov 2004 08:42:26 +0000
Subject: [PATCH 020/145] ifdef'd unused table reorg code
---
ndb/src/kernel/blocks/dbdict/Dbdict.cpp | 12 ++++++++++--
ndb/src/kernel/blocks/dbdict/Dbdict.hpp | 4 ++--
2 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
index 882557daae1..2b9072ab042 100644
--- a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
+++ b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
@@ -239,7 +239,11 @@ Dbdict::packTableIntoPagesImpl(SimpleProperties::Writer & w,
w.add(DictTabInfo::TableName, tablePtr.p->tableName);
w.add(DictTabInfo::TableId, tablePtr.i);
+#ifdef HAVE_TABLE_REORG
w.add(DictTabInfo::SecondTableId, tablePtr.p->secondTable);
+#else
+ w.add(DictTabInfo::SecondTableId, (Uint32)0);
+#endif
w.add(DictTabInfo::TableVersion, tablePtr.p->tableVersion);
w.add(DictTabInfo::NoOfKeyAttr, tablePtr.p->noOfPrimkey);
w.add(DictTabInfo::NoOfAttributes, tablePtr.p->noOfAttributes);
@@ -1436,6 +1440,7 @@ Uint32 Dbdict::getFreeTableRecord(Uint32 primaryTableId)
jam();
return RNIL;
}//if
+#ifdef HAVE_TABLE_REORG
bool secondFound = false;
for (tablePtr.i = firstTablePtr.i + 1; tablePtr.i < tabSize ; tablePtr.i++) {
jam();
@@ -1455,6 +1460,7 @@ Uint32 Dbdict::getFreeTableRecord(Uint32 primaryTableId)
firstTablePtr.p->tabState = TableRecord::NOT_DEFINED;
return RNIL;
}//if
+#endif
return firstTablePtr.i;
}//Dbdict::getFreeTableRecord()
@@ -4623,7 +4629,7 @@ void Dbdict::handleTabInfoInit(SimpleProperties::Reader & it,
jam();
tablePtr.p->tabState = TableRecord::DEFINING;
}//if
-
+#ifdef HAVE_TABLE_REORG
/* ---------------------------------------------------------------- */
// Get id of second table id and check that table doesn't already exist
// and set up links between first and second table.
@@ -4637,7 +4643,7 @@ void Dbdict::handleTabInfoInit(SimpleProperties::Reader & it,
secondTablePtr.p->tabState = TableRecord::REORG_TABLE_PREPARED;
secondTablePtr.p->secondTable = tablePtr.i;
tablePtr.p->secondTable = secondTablePtr.i;
-
+#endif
/* ---------------------------------------------------------------- */
// Set table version
/* ---------------------------------------------------------------- */
@@ -5535,10 +5541,12 @@ void Dbdict::releaseTableObject(Uint32 tableId, bool removeFromHash)
nextAttrRecord = attrPtr.p->nextAttrInTable;
c_attributeRecordPool.release(attrPtr);
}//if
+#ifdef HAVE_TABLE_REORG
Uint32 secondTableId = tablePtr.p->secondTable;
initialiseTableRecord(tablePtr);
c_tableRecordPool.getPtr(tablePtr, secondTableId);
initialiseTableRecord(tablePtr);
+#endif
return;
}//releaseTableObject()
diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.hpp b/ndb/src/kernel/blocks/dbdict/Dbdict.hpp
index 19c03a86e22..af80bcf5f94 100644
--- a/ndb/src/kernel/blocks/dbdict/Dbdict.hpp
+++ b/ndb/src/kernel/blocks/dbdict/Dbdict.hpp
@@ -151,10 +151,10 @@ public:
/* Temporary record used during add/drop table */
Uint32 myConnect;
-
+#ifdef HAVE_TABLE_REORG
/* Second table used by this table (for table reorg) */
Uint32 secondTable;
-
+#endif
/* Next record in Pool */
Uint32 nextPool;
From b2b7bf0eaa784447a8db797cc67ac6d2c1b52d6e Mon Sep 17 00:00:00 2001
From: "pekka@mysql.com" <>
Date: Thu, 18 Nov 2004 11:48:21 +0100
Subject: [PATCH 021/145] ndb: charset fix from Bar (strxfrm_multiply can be 0)
---
ndb/src/common/util/NdbSqlUtil.cpp | 6 +++---
ndb/src/ndbapi/NdbIndexOperation.cpp | 2 +-
ndb/src/ndbapi/NdbOperationSearch.cpp | 2 +-
ndb/src/ndbapi/NdbScanOperation.cpp | 2 +-
4 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/ndb/src/common/util/NdbSqlUtil.cpp b/ndb/src/common/util/NdbSqlUtil.cpp
index 6e4e5919e43..5b2381df50a 100644
--- a/ndb/src/common/util/NdbSqlUtil.cpp
+++ b/ndb/src/common/util/NdbSqlUtil.cpp
@@ -582,7 +582,7 @@ NdbSqlUtil::usable_in_pk(Uint32 typeId, const void* info)
cs->cset != 0 &&
cs->coll != 0 &&
cs->coll->strnxfrm != 0 &&
- cs->strxfrm_multiply == 1; // current limitation
+ cs->strxfrm_multiply <= 1; // current limitation
}
break;
case Type::Varchar:
@@ -618,7 +618,7 @@ NdbSqlUtil::usable_in_ordered_index(Uint32 typeId, const void* info)
cs->coll != 0 &&
cs->coll->strnxfrm != 0 &&
cs->coll->strnncollsp != 0 &&
- cs->strxfrm_multiply == 1; // current limitation
+ cs->strxfrm_multiply <= 1; // current limitation
}
break;
case Type::Varchar:
@@ -633,7 +633,7 @@ NdbSqlUtil::usable_in_ordered_index(Uint32 typeId, const void* info)
cs->coll != 0 &&
cs->coll->strnxfrm != 0 &&
cs->coll->strnncollsp != 0 &&
- cs->strxfrm_multiply == 1; // current limitation
+ cs->strxfrm_multiply <= 1; // current limitation
}
break;
default:
diff --git a/ndb/src/ndbapi/NdbIndexOperation.cpp b/ndb/src/ndbapi/NdbIndexOperation.cpp
index 3f174a61b64..23af646c4c7 100644
--- a/ndb/src/ndbapi/NdbIndexOperation.cpp
+++ b/ndb/src/ndbapi/NdbIndexOperation.cpp
@@ -272,7 +272,7 @@ int NdbIndexOperation::equal_impl(const NdbColumnImpl* tAttrInfo,
CHARSET_INFO* cs = tAttrInfo->m_cs;
if (cs != 0) {
// current limitation: strxfrm does not increase length
- assert(cs->strxfrm_multiply == 1);
+ assert(cs->strxfrm_multiply <= 1);
unsigned n =
(*cs->coll->strnxfrm)(cs,
(uchar*)xfrmData, sizeof(xfrmData),
diff --git a/ndb/src/ndbapi/NdbOperationSearch.cpp b/ndb/src/ndbapi/NdbOperationSearch.cpp
index 69b4e803acd..28a70abcb9b 100644
--- a/ndb/src/ndbapi/NdbOperationSearch.cpp
+++ b/ndb/src/ndbapi/NdbOperationSearch.cpp
@@ -142,7 +142,7 @@ NdbOperation::equal_impl(const NdbColumnImpl* tAttrInfo,
CHARSET_INFO* cs = tAttrInfo->m_cs;
if (cs != 0) {
// current limitation: strxfrm does not increase length
- assert(cs->strxfrm_multiply == 1);
+ assert(cs->strxfrm_multiply <= 1);
unsigned n =
(*cs->coll->strnxfrm)(cs,
(uchar*)xfrmData, sizeof(xfrmData),
diff --git a/ndb/src/ndbapi/NdbScanOperation.cpp b/ndb/src/ndbapi/NdbScanOperation.cpp
index 373fec1a2b0..4b10ebb10cd 100644
--- a/ndb/src/ndbapi/NdbScanOperation.cpp
+++ b/ndb/src/ndbapi/NdbScanOperation.cpp
@@ -1091,7 +1091,7 @@ NdbIndexScanOperation::setBound(const NdbColumnImpl* tAttrInfo,
Uint32 xfrmData[2000];
if (cs != NULL && aValue != NULL) {
// current limitation: strxfrm does not increase length
- assert(cs->strxfrm_multiply == 1);
+ assert(cs->strxfrm_multiply <= 1);
unsigned n =
(*cs->coll->strnxfrm)(cs,
(uchar*)xfrmData, sizeof(xfrmData),
From a4d061a5d996bd245c6cd70bdbecdf51b386007e Mon Sep 17 00:00:00 2001
From: "mskold@mysql.com" <>
Date: Thu, 18 Nov 2004 12:11:56 +0100
Subject: [PATCH 022/145] Fix for bug#4312 ndb table, wrong behaviour on insert
.. on duplicate key ..
---
mysql-test/r/ndb_charset.result | 4 +-
mysql-test/r/ndb_index_unique.result | 8 ++--
mysql-test/r/ndb_insert.result | 45 +++++++++++++------
mysql-test/t/ndb_charset.test | 4 +-
mysql-test/t/ndb_index_unique.test | 8 ++--
mysql-test/t/ndb_insert.test | 36 ++++++++++-----
sql/ha_ndbcluster.cc | 66 ++++++++++++++++++++++------
sql/ha_ndbcluster.h | 4 +-
sql/sql_insert.cc | 7 ++-
9 files changed, 130 insertions(+), 52 deletions(-)
diff --git a/mysql-test/r/ndb_charset.result b/mysql-test/r/ndb_charset.result
index 93429a1fcb0..501bec99ea3 100644
--- a/mysql-test/r/ndb_charset.result
+++ b/mysql-test/r/ndb_charset.result
@@ -78,9 +78,9 @@ unique key(a)
) engine=ndb;
insert into t1 values(1, 'aAa');
insert into t1 values(2, 'aaa');
-ERROR 23000: Can't write, because of unique constraint, to table 't1'
+ERROR 23000: Duplicate entry '2' for key 1
insert into t1 values(3, 'AAA');
-ERROR 23000: Can't write, because of unique constraint, to table 't1'
+ERROR 23000: Duplicate entry '3' for key 1
select * from t1 order by p;
p a
1 aAa
diff --git a/mysql-test/r/ndb_index_unique.result b/mysql-test/r/ndb_index_unique.result
index f1407dfe78d..af9b84022ed 100644
--- a/mysql-test/r/ndb_index_unique.result
+++ b/mysql-test/r/ndb_index_unique.result
@@ -22,7 +22,7 @@ select * from t1 where b = 4 order by a;
a b c
3 4 6
insert into t1 values(8, 2, 3);
-ERROR 23000: Can't write, because of unique constraint, to table 't1'
+ERROR 23000: Duplicate entry '8' for key 1
select * from t1 order by a;
a b c
1 2 3
@@ -65,7 +65,7 @@ select * from t2 where b = 4 order by a;
a b c
3 4 6
insert into t2 values(8, 2, 3);
-ERROR 23000: Can't write, because of unique constraint, to table 't2'
+ERROR 23000: Duplicate entry '8' for key 1
select * from t2 order by a;
a b c
1 2 3
@@ -123,7 +123,7 @@ pk a
3 NULL
4 4
insert into t1 values (5,0);
-ERROR 23000: Can't write, because of unique constraint, to table 't1'
+ERROR 23000: Duplicate entry '5' for key 1
select * from t1 order by pk;
pk a
-1 NULL
@@ -156,7 +156,7 @@ pk a b c
0 NULL 18 NULL
1 3 19 abc
insert into t2 values(2,3,19,'abc');
-ERROR 23000: Can't write, because of unique constraint, to table 't2'
+ERROR 23000: Duplicate entry '2' for key 1
select * from t2 order by pk;
pk a b c
-1 1 17 NULL
diff --git a/mysql-test/r/ndb_insert.result b/mysql-test/r/ndb_insert.result
index 16c76f39680..7503010a66b 100644
--- a/mysql-test/r/ndb_insert.result
+++ b/mysql-test/r/ndb_insert.result
@@ -535,27 +535,46 @@ count(*)
2000
insert into t1 select * from t1 where b < 10 order by pk1;
ERROR 23000: Duplicate entry '9' for key 1
+DELETE FROM t1 WHERE pk1=2;
begin;
-INSERT IGNORE INTO t1 VALUES(1,2,3);
-ERROR HY000: Table storage engine for 't1' doesn't have this option
-commit;
-select * from t1 where pk1=1;
+INSERT IGNORE INTO t1 VALUES(1,2,3),(2,3,4);
+select * from t1 where pk1 < 3 order by pk1;
pk1 b c
+0 0 0
1 1 1
-INSERT IGNORE INTO t1 VALUES(1,2,3);
-ERROR HY000: Table storage engine for 't1' doesn't have this option
-select * from t1 where pk1=1;
+2 3 4
+rollback;
+INSERT IGNORE INTO t1 VALUES(1,2,3),(2,3,4);
+select * from t1 where pk1 < 3 order by pk1;
pk1 b c
+0 0 0
1 1 1
-REPLACE INTO t1 values(1, 2, 3);
+2 3 4
+REPLACE INTO t1 values(1, 78, 3);
select * from t1 where pk1=1;
pk1 b c
-1 2 3
-INSERT INTO t1 VALUES(1,1,1) ON DUPLICATE KEY UPDATE b=79;
-ERROR HY000: Table storage engine for 't1' doesn't have this option
-select * from t1 where pk1=1;
+1 78 3
+INSERT INTO t1 VALUES(1,1,1),(3,4,5) ON DUPLICATE KEY UPDATE b=79;
+select * from t1 where pk1 < 4 order by pk1;
pk1 b c
-1 2 3
+0 0 0
+1 79 3
+2 3 4
+3 79 3
+INSERT INTO t1 VALUES(1,1,1),(3,4,5) ON DUPLICATE KEY UPDATE b=pk1+c;
+select * from t1 where pk1 < 4 order by pk1;
+pk1 b c
+0 0 0
+1 4 3
+2 3 4
+3 6 3
+DELETE FROM t1 WHERE pk1 = 2 OR pk1 = 4 OR pk1 = 6;
+INSERT INTO t1 VALUES(1,1,1),(2,2,17),(3,4,5) ON DUPLICATE KEY UPDATE pk1=b;
+select * from t1 where pk1 = b and b != c order by pk1;
+pk1 b c
+2 2 17
+4 4 3
+6 6 3
DROP TABLE t1;
CREATE TABLE t1(a INT) ENGINE=ndb;
INSERT IGNORE INTO t1 VALUES (1);
diff --git a/mysql-test/t/ndb_charset.test b/mysql-test/t/ndb_charset.test
index b9f28ed0faf..f1ec0485e12 100644
--- a/mysql-test/t/ndb_charset.test
+++ b/mysql-test/t/ndb_charset.test
@@ -86,9 +86,9 @@ create table t1 (
# ok
insert into t1 values(1, 'aAa');
# fail
---error 1169
+--error 1062
insert into t1 values(2, 'aaa');
---error 1169
+--error 1062
insert into t1 values(3, 'AAA');
# 1
select * from t1 order by p;
diff --git a/mysql-test/t/ndb_index_unique.test b/mysql-test/t/ndb_index_unique.test
index 4a0c689bafb..bdb23949763 100644
--- a/mysql-test/t/ndb_index_unique.test
+++ b/mysql-test/t/ndb_index_unique.test
@@ -21,7 +21,7 @@ select * from t1 where b = 4 order by b;
insert into t1 values(7,8,3);
select * from t1 where b = 4 order by a;
--- error 1169
+-- error 1062
insert into t1 values(8, 2, 3);
select * from t1 order by a;
delete from t1 where a = 1;
@@ -49,7 +49,7 @@ select * from t2 where c = 6;
insert into t2 values(7,8,3);
select * from t2 where b = 4 order by a;
--- error 1169
+-- error 1062
insert into t2 values(8, 2, 3);
select * from t2 order by a;
delete from t2 where a = 1;
@@ -92,7 +92,7 @@ insert into t1 values (-1,NULL), (0,0), (1,NULL),(2,2),(3,NULL),(4,4);
select * from t1 order by pk;
---error 1169
+--error 1062
insert into t1 values (5,0);
select * from t1 order by pk;
delete from t1 where a = 0;
@@ -111,7 +111,7 @@ insert into t2 values (-1,1,17,NULL),(0,NULL,18,NULL),(1,3,19,'abc');
select * from t2 order by pk;
---error 1169
+--error 1062
insert into t2 values(2,3,19,'abc');
select * from t2 order by pk;
delete from t2 where c IS NOT NULL;
diff --git a/mysql-test/t/ndb_insert.test b/mysql-test/t/ndb_insert.test
index c3da4641014..611df3d84e9 100644
--- a/mysql-test/t/ndb_insert.test
+++ b/mysql-test/t/ndb_insert.test
@@ -564,23 +564,37 @@ select count(*) from t1;
--error 1062
insert into t1 select * from t1 where b < 10 order by pk1;
+DELETE FROM t1 WHERE pk1=2;
begin;
---error 1031
-INSERT IGNORE INTO t1 VALUES(1,2,3);
-commit;
+INSERT IGNORE INTO t1 VALUES(1,2,3),(2,3,4);
+select * from t1 where pk1 < 3 order by pk1;
+rollback;
+
+INSERT IGNORE INTO t1 VALUES(1,2,3),(2,3,4);
+select * from t1 where pk1 < 3 order by pk1;
+
+REPLACE INTO t1 values(1, 78, 3);
select * from t1 where pk1=1;
---error 1031
-INSERT IGNORE INTO t1 VALUES(1,2,3);
-select * from t1 where pk1=1;
+INSERT INTO t1 VALUES(1,1,1),(3,4,5) ON DUPLICATE KEY UPDATE b=79;
+select * from t1 where pk1 < 4 order by pk1;
-REPLACE INTO t1 values(1, 2, 3);
-select * from t1 where pk1=1;
+INSERT INTO t1 VALUES(1,1,1),(3,4,5) ON DUPLICATE KEY UPDATE b=pk1+c;
+select * from t1 where pk1 < 4 order by pk1;
---error 1031
-INSERT INTO t1 VALUES(1,1,1) ON DUPLICATE KEY UPDATE b=79;
-select * from t1 where pk1=1;
+DELETE FROM t1 WHERE pk1 = 2 OR pk1 = 4 OR pk1 = 6;
+INSERT INTO t1 VALUES(1,1,1),(2,2,17),(3,4,5) ON DUPLICATE KEY UPDATE pk1=b;
+select * from t1 where pk1 = b and b != c order by pk1;
+
+# The following test case currently does not work
+#DELETE FROM t1;
+#CREATE UNIQUE INDEX bi ON t1(b);
+#INSERT INTO t1 VALUES
+#(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),
+#(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10);
+#INSERT INTO t1 VALUES(0,1,0),(21,21,21) ON DUPLICATE KEY UPDATE pk1=b+10,c=b+10;
+#select * from t1 order by pk1;
DROP TABLE t1;
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index cdbf2eb3d6a..84d1b2468d5 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -109,7 +109,7 @@ static const err_code_mapping err_map[]=
{
{ 626, HA_ERR_KEY_NOT_FOUND },
{ 630, HA_ERR_FOUND_DUPP_KEY },
- { 893, HA_ERR_FOUND_DUPP_UNIQUE },
+ { 893, HA_ERR_FOUND_DUPP_KEY }, // Unique constraint
{ 721, HA_ERR_TABLE_EXIST },
{ 4244, HA_ERR_TABLE_EXIST },
@@ -144,7 +144,7 @@ static int ndb_to_mysql_error(const NdbError *err)
// Push the NDB error message as warning
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
ER_GET_ERRMSG, ER(ER_GET_ERRMSG),
- err->code, err->message, "NDB");
+ err->code, err->message, "NDB");
return err->code;
}
}
@@ -1018,7 +1018,8 @@ int ha_ndbcluster::pk_read(const byte *key, uint key_len, byte *buf)
{
Field *field= table->field[i];
if ((thd->query_id == field->query_id) ||
- m_retrieve_all_fields)
+ m_retrieve_all_fields ||
+ (field->flags & PRI_KEY_FLAG) && m_retrieve_primary_key)
{
if (get_ndb_value(op, field, i, buf))
ERR_RETURN(trans->getNdbError());
@@ -1029,7 +1030,6 @@ int ha_ndbcluster::pk_read(const byte *key, uint key_len, byte *buf)
m_value[i].ptr= NULL;
}
}
-
if (execute_no_commit_ie(this,trans) != 0)
{
table->status= STATUS_NOT_FOUND;
@@ -1093,6 +1093,34 @@ int ha_ndbcluster::complemented_pk_read(const byte *old_data, byte *new_data)
DBUG_RETURN(0);
}
+/*
+ Peek to check if a particular row already exists
+*/
+
+int ha_ndbcluster::peek_row()
+{
+ NdbConnection *trans= m_active_trans;
+ NdbOperation *op;
+ THD *thd= current_thd;
+ DBUG_ENTER("peek_row");
+
+ NdbOperation::LockMode lm=
+ (NdbOperation::LockMode)get_ndb_lock_type(m_lock.type);
+ if (!(op= trans->getNdbOperation((const NDBTAB *) m_table)) ||
+ op->readTuple(lm) != 0)
+ ERR_RETURN(trans->getNdbError());
+
+ int res;
+ if ((res= set_primary_key(op)))
+ ERR_RETURN(trans->getNdbError());
+
+ if (execute_no_commit_ie(this,trans) != 0)
+ {
+ table->status= STATUS_NOT_FOUND;
+ DBUG_RETURN(ndb_err(trans));
+ }
+ DBUG_RETURN(0);
+}
/*
Read one record from NDB using unique secondary index
@@ -1138,7 +1166,7 @@ int ha_ndbcluster::unique_index_read(const byte *key,
{
Field *field= table->field[i];
if ((thd->query_id == field->query_id) ||
- (field->flags & PRI_KEY_FLAG))
+ (field->flags & PRI_KEY_FLAG)) // && m_retrieve_primary_key ??
{
if (get_ndb_value(op, field, i, buf))
ERR_RETURN(op->getNdbError());
@@ -1566,7 +1594,7 @@ int ha_ndbcluster::filtered_scan(const byte *key, uint key_len,
Field* field= key_part->field;
uint ndb_fieldnr= key_part->fieldnr-1;
DBUG_PRINT("key_part", ("fieldnr: %d", ndb_fieldnr));
- // const NDBCOL *col= tab->getColumn(ndb_fieldnr);
+ //const NDBCOL *col= ((const NDBTAB *) m_table)->getColumn(ndb_fieldnr);
uint32 field_len= field->pack_length();
DBUG_DUMP("key", (char*)key, field_len);
@@ -1635,9 +1663,17 @@ int ha_ndbcluster::write_row(byte *record)
int res;
DBUG_ENTER("write_row");
- if(m_ignore_dup_key_not_supported)
+ if(m_ignore_dup_key && table->primary_key != MAX_KEY)
{
- DBUG_RETURN(HA_ERR_WRONG_COMMAND);
+ int peek_res= peek_row();
+
+ if (!peek_res)
+ {
+ m_dupkey= table->primary_key;
+ DBUG_RETURN(HA_ERR_FOUND_DUPP_KEY);
+ }
+ if (peek_res != HA_ERR_KEY_NOT_FOUND)
+ DBUG_RETURN(peek_res);
}
statistic_increment(ha_write_count,&LOCK_status);
@@ -1791,7 +1827,7 @@ int ha_ndbcluster::update_row(const byte *old_data, byte *new_data)
NdbOperation *op;
uint i;
DBUG_ENTER("update_row");
-
+
statistic_increment(ha_update_count,&LOCK_status);
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
table->timestamp_field->set_time();
@@ -2653,15 +2689,15 @@ int ha_ndbcluster::extra(enum ha_extra_function operation)
m_use_write= TRUE;
} else
{
- if (table->keys)
- m_ignore_dup_key_not_supported= TRUE;
+ DBUG_PRINT("info", ("Ignoring duplicate key"));
+ m_ignore_dup_key= TRUE;
}
break;
case HA_EXTRA_NO_IGNORE_DUP_KEY:
DBUG_PRINT("info", ("HA_EXTRA_NO_IGNORE_DUP_KEY"));
DBUG_PRINT("info", ("Turning OFF use of write instead of insert"));
m_use_write= FALSE;
- m_ignore_dup_key_not_supported= FALSE;
+ m_ignore_dup_key= FALSE;
break;
case HA_EXTRA_RETRIEVE_ALL_COLS: /* Retrieve all columns, not just those
where field->query_id is the same as
@@ -2680,6 +2716,7 @@ int ha_ndbcluster::extra(enum ha_extra_function operation)
break;
case HA_EXTRA_RETRIEVE_PRIMARY_KEY:
DBUG_PRINT("info", ("HA_EXTRA_RETRIEVE_PRIMARY_KEY"));
+ m_retrieve_primary_key= TRUE;
break;
case HA_EXTRA_CHANGE_KEY_TO_UNIQUE:
DBUG_PRINT("info", ("HA_EXTRA_CHANGE_KEY_TO_UNIQUE"));
@@ -2942,6 +2979,7 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
DBUG_ASSERT(m_active_trans);
// Start of transaction
m_retrieve_all_fields= FALSE;
+ m_retrieve_primary_key= FALSE;
m_ops_pending= 0;
{
NDBDICT *dict= m_ndb->getDictionary();
@@ -3034,6 +3072,7 @@ int ha_ndbcluster::start_stmt(THD *thd)
// Start of statement
m_retrieve_all_fields= FALSE;
+ m_retrieve_primary_key= FALSE;
m_ops_pending= 0;
DBUG_RETURN(error);
@@ -3640,9 +3679,10 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg):
HA_NO_PREFIX_CHAR_KEYS),
m_share(0),
m_use_write(FALSE),
- m_ignore_dup_key_not_supported(FALSE),
+ m_ignore_dup_key(FALSE),
m_primary_key_update(FALSE),
m_retrieve_all_fields(FALSE),
+ m_retrieve_primary_key(FALSE),
m_rows_to_insert(1),
m_rows_inserted(0),
m_bulk_insert_rows(1024),
diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h
index 2121228a869..c6c233c013c 100644
--- a/sql/ha_ndbcluster.h
+++ b/sql/ha_ndbcluster.h
@@ -183,6 +183,7 @@ class ha_ndbcluster: public handler
int pk_read(const byte *key, uint key_len, byte *buf);
int complemented_pk_read(const byte *old_data, byte *new_data);
+ int peek_row();
int unique_index_read(const byte *key, uint key_len,
byte *buf);
int ordered_index_scan(const key_range *start_key,
@@ -242,9 +243,10 @@ class ha_ndbcluster: public handler
typedef union { NdbRecAttr *rec; NdbBlob *blob; void *ptr; } NdbValue;
NdbValue m_value[NDB_MAX_ATTRIBUTES_IN_TABLE];
bool m_use_write;
- bool m_ignore_dup_key_not_supported;
+ bool m_ignore_dup_key;
bool m_primary_key_update;
bool m_retrieve_all_fields;
+ bool m_retrieve_primary_key;
ha_rows m_rows_to_insert;
ha_rows m_rows_inserted;
ha_rows m_bulk_insert_rows;
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 822ce622b1b..d590d3b5093 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -453,8 +453,8 @@ int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
setup_tables(insert_table_list) ||
setup_fields(thd, 0, insert_table_list, *values, 0, 0, 0) ||
(duplic == DUP_UPDATE &&
- (setup_fields(thd, 0, insert_table_list, update_fields, 0, 0, 0) ||
- setup_fields(thd, 0, insert_table_list, update_values, 0, 0, 0))))
+ (setup_fields(thd, 0, insert_table_list, update_fields, 1, 0, 0) ||
+ setup_fields(thd, 0, insert_table_list, update_values, 1, 0, 0))))
DBUG_RETURN(-1);
if (find_real_table_in_list(table_list->next,
table_list->db, table_list->real_name))
@@ -462,6 +462,9 @@ int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->real_name);
DBUG_RETURN(-1);
}
+ if (duplic == DUP_UPDATE || duplic == DUP_REPLACE)
+ table->file->extra(HA_EXTRA_RETRIEVE_PRIMARY_KEY);
+
DBUG_RETURN(0);
}
From fe3b359b747105a664065ebb3fc30b3b4891c472 Mon Sep 17 00:00:00 2001
From: "bar@mysql.com" <>
Date: Thu, 18 Nov 2004 16:15:48 +0400
Subject: [PATCH 023/145] Check that the third UNION part with COLLATE clause
resolves collation conflict for the first and the second parts pair.
---
mysql-test/r/union.result | 10 ++++++++++
mysql-test/t/union.test | 6 ++++++
2 files changed, 16 insertions(+)
diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result
index 7820cd1d6ff..49a2907f571 100644
--- a/mysql-test/r/union.result
+++ b/mysql-test/r/union.result
@@ -1110,4 +1110,14 @@ t1 CREATE TABLE `t1` (
`a` char(1) character set latin1 collate latin1_german1_ci default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
+create table t1 as
+(select a from t2) union
+(select b from t2) union
+(select 'c' collate latin1_german1_ci from t2);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(1) character set latin1 collate latin1_german1_ci default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
drop table t2;
diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test
index 36027e8c4cb..468a88b83db 100644
--- a/mysql-test/t/union.test
+++ b/mysql-test/t/union.test
@@ -652,5 +652,11 @@ create table t1 as
(select b collate latin1_german1_ci from t2);
show create table t1;
drop table t1;
+create table t1 as
+(select a from t2) union
+(select b from t2) union
+(select 'c' collate latin1_german1_ci from t2);
+show create table t1;
+drop table t1;
drop table t2;
From 5d1f920ba7e3619a66c40228d275ad8ed8f41e61 Mon Sep 17 00:00:00 2001
From: "timour@mysql.com" <>
Date: Thu, 18 Nov 2004 16:52:45 +0200
Subject: [PATCH 024/145] correct name of function in synopsis
---
BitKeeper/etc/logging_ok | 1 +
mysys/mf_keycaches.c | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok
index 1f1918027e2..1c1a3efc542 100644
--- a/BitKeeper/etc/logging_ok
+++ b/BitKeeper/etc/logging_ok
@@ -199,6 +199,7 @@ tim@siva.hindu.god
tim@threads.polyesthetic.msg
tim@white.box
tim@work.mysql.com
+timour@mysql.com
tom@basil-firewall.home.com
tomas@mc05.(none)
tomas@poseidon.(none)
diff --git a/mysys/mf_keycaches.c b/mysys/mf_keycaches.c
index 20465f3d23b..8bf203e249f 100644
--- a/mysys/mf_keycaches.c
+++ b/mysys/mf_keycaches.c
@@ -309,7 +309,7 @@ void multi_keycache_free(void)
Get a key cache to be used for a specific table.
SYNOPSIS
- multi_key_cache_get()
+ multi_key_cache_search()
key key to find (usually table path)
uint length Length of key.
From 766adf172bcc4c42e9d580a5b7ab2a739a6aa85e Mon Sep 17 00:00:00 2001
From: "marko@hundin.mysql.fi" <>
Date: Thu, 18 Nov 2004 17:01:33 +0200
Subject: [PATCH 025/145] row0ins.c: row_ins_scan_sec_index_for_duplicate(),
row_ins_duplicate_error_in_clust(): remove unused variables "ptr"
---
innobase/row/row0ins.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c
index c45818ddd26..6d1482b6720 100644
--- a/innobase/row/row0ins.c
+++ b/innobase/row/row0ins.c
@@ -1509,7 +1509,6 @@ row_ins_scan_sec_index_for_duplicate(
ibool moved;
mtr_t mtr;
trx_t* trx;
- const char* ptr;
n_unique = dict_index_get_n_unique(index);
@@ -1630,7 +1629,6 @@ row_ins_duplicate_error_in_clust(
page_t* page;
ulint n_unique;
trx_t* trx = thr_get_trx(thr);
- const char* ptr;
UT_NOT_USED(mtr);
From c273fda5ed7989bc2a845e4cd6e2d77e33c4709d Mon Sep 17 00:00:00 2001
From: "pekka@mysql.com" <>
Date: Thu, 18 Nov 2004 16:44:50 +0100
Subject: [PATCH 026/145] ndb: new arbitrator behaviour for >=3-way: < 1/2
nodes can survive
---
.../kernel/signaldata/ArbitSignalData.hpp | 15 +++++-----
ndb/src/common/debugger/EventLogger.cpp | 5 ++++
ndb/src/kernel/blocks/qmgr/QmgrMain.cpp | 29 +++++++++++++------
3 files changed, 33 insertions(+), 16 deletions(-)
diff --git a/ndb/include/kernel/signaldata/ArbitSignalData.hpp b/ndb/include/kernel/signaldata/ArbitSignalData.hpp
index f255b8dcbbe..34b73644a13 100644
--- a/ndb/include/kernel/signaldata/ArbitSignalData.hpp
+++ b/ndb/include/kernel/signaldata/ArbitSignalData.hpp
@@ -94,13 +94,14 @@ public:
// arbitration result
LoseNodes = 41, // lose on ndb node count
- WinGroups = 42, // we win, no need for arbitration
- LoseGroups = 43, // we lose, missing node group
- Partitioning = 44, // possible network partitioning
- WinChoose = 45, // positive reply
- LoseChoose = 46, // negative reply
- LoseNorun = 47, // arbitrator required but not running
- LoseNocfg = 48, // arbitrator required but none configured
+ WinNodes = 42, // win on ndb node count
+ WinGroups = 43, // we win, no need for arbitration
+ LoseGroups = 44, // we lose, missing node group
+ Partitioning = 45, // possible network partitioning
+ WinChoose = 46, // positive reply
+ LoseChoose = 47, // negative reply
+ LoseNorun = 48, // arbitrator required but not running
+ LoseNocfg = 49, // arbitrator required but none configured
// general error codes
ErrTicket = 91, // invalid arbitrator-ticket
diff --git a/ndb/src/common/debugger/EventLogger.cpp b/ndb/src/common/debugger/EventLogger.cpp
index 8a09be9a0a7..59be0affcb4 100644
--- a/ndb/src/common/debugger/EventLogger.cpp
+++ b/ndb/src/common/debugger/EventLogger.cpp
@@ -421,6 +421,11 @@ EventLogger::getText(char * m_text, size_t m_text_len,
"%sArbitration check lost - less than 1/2 nodes left",
theNodeId);
break;
+ case ArbitCode::WinNodes:
+ BaseString::snprintf(m_text, m_text_len,
+ "%sArbitration check won - all node groups and more than 1/2 nodes left",
+ theNodeId);
+ break;
case ArbitCode::WinGroups:
BaseString::snprintf(m_text, m_text_len,
"%sArbitration check won - node group majority",
diff --git a/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp b/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
index a433d72744e..da8596076ec 100644
--- a/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
+++ b/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
@@ -2946,6 +2946,12 @@ void Qmgr::sendPrepFailReq(Signal* signal, Uint16 aNode)
* the "handle" routines.
*/
+/**
+ * Should < 1/2 nodes die unconditionally. Affects only >= 3-way
+ * replication.
+ */
+static const bool g_ndb_arbit_one_half_rule = false;
+
/**
* Config signals are logically part of CM_INIT.
*/
@@ -3157,7 +3163,8 @@ Qmgr::handleArbitCheck(Signal* signal)
ndbrequire(cpresident == getOwnNodeId());
NodeBitmask ndbMask;
computeArbitNdbMask(ndbMask);
- if (2 * ndbMask.count() < cnoOfNodes) {
+ if (g_ndb_arbit_one_half_rule &&
+ 2 * ndbMask.count() < cnoOfNodes) {
jam();
arbitRec.code = ArbitCode::LoseNodes;
} else {
@@ -3181,6 +3188,11 @@ Qmgr::handleArbitCheck(Signal* signal)
case CheckNodeGroups::Partitioning:
jam();
arbitRec.code = ArbitCode::Partitioning;
+ if (g_ndb_arbit_one_half_rule &&
+ 2 * ndbMask.count() > cnoOfNodes) {
+ jam();
+ arbitRec.code = ArbitCode::WinNodes;
+ }
break;
default:
ndbrequire(false);
@@ -3190,8 +3202,12 @@ Qmgr::handleArbitCheck(Signal* signal)
switch (arbitRec.code) {
case ArbitCode::LoseNodes:
jam();
+ case ArbitCode::LoseGroups:
+ jam();
goto crashme;
- case ArbitCode::WinGroups:
+ case ArbitCode::WinNodes:
+ jam();
+ case ArbitCode::WinGroups:
jam();
if (arbitRec.state == ARBIT_RUN) {
jam();
@@ -3200,9 +3216,6 @@ Qmgr::handleArbitCheck(Signal* signal)
arbitRec.state = ARBIT_INIT;
arbitRec.newstate = true;
break;
- case ArbitCode::LoseGroups:
- jam();
- goto crashme;
case ArbitCode::Partitioning:
if (arbitRec.state == ARBIT_RUN) {
jam();
@@ -3762,8 +3775,7 @@ Qmgr::execARBIT_CHOOSEREF(Signal* signal)
}
/**
- * Handle CRASH state. We must crash immediately. But it
- * would be nice to wait until event reports have been sent.
+ * Handle CRASH state. We must crash immediately.
* XXX tell other nodes in our party to crash too.
*/
void
@@ -3773,12 +3785,11 @@ Qmgr::stateArbitCrash(Signal* signal)
if (arbitRec.newstate) {
jam();
CRASH_INSERTION((Uint32)910 + arbitRec.state);
-
arbitRec.setTimestamp();
arbitRec.code = 0;
arbitRec.newstate = false;
}
-#if 0
+#ifdef ndb_arbit_crash_wait_for_event_report_to_get_out
if (! (arbitRec.getTimediff() > getArbitTimeout()))
return;
#endif
From 7ec0239162dcd693541ae24a03f977cf371aa063 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Thu, 18 Nov 2004 18:38:38 +0000
Subject: [PATCH 027/145] changed mysqladmin.c to mysqladmin.cc no need
for dvlags to have DEFINE_CXA_PURE_VIRTUAL anymore aligned the parsing of
connectstring, retries for connect, allocation of nodeid for all cluster
nodes removed all dependencies of LocalConfig, except for mgmapi
internals enabled multiple management servrs to fetch data configurations
from eachother
---
client/Makefile.am | 1 +
client/{mysqladmin.c => mysqladmin.cc} | 3 -
configure.in | 1 -
ndb/include/mgmapi/mgmapi.h | 30 +++-
ndb/include/mgmcommon/ConfigRetriever.hpp | 26 +--
ndb/include/ndbapi/ndb_cluster_connection.hpp | 2 -
ndb/src/common/mgmcommon/ConfigRetriever.cpp | 163 ++++++++----------
ndb/src/kernel/main.cpp | 12 +-
ndb/src/kernel/vm/Configuration.cpp | 34 ++--
ndb/src/kernel/vm/Configuration.hpp | 3 +-
ndb/src/mgmapi/LocalConfig.cpp | 17 +-
ndb/{include => src}/mgmapi/LocalConfig.hpp | 1 +
ndb/src/mgmapi/mgmapi.cpp | 138 ++++++++++-----
ndb/src/mgmclient/CommandInterpreter.cpp | 30 +---
ndb/src/mgmclient/main.cpp | 3 +-
ndb/src/mgmclient/ndb_mgmclient.h | 2 +-
ndb/src/mgmclient/ndb_mgmclient.hpp | 2 +-
ndb/src/mgmsrv/MgmtSrvr.cpp | 109 +++++++-----
ndb/src/mgmsrv/MgmtSrvr.hpp | 13 +-
ndb/src/mgmsrv/MgmtSrvrConfig.cpp | 18 +-
ndb/src/mgmsrv/main.cpp | 54 +-----
ndb/src/ndbapi/ndb_cluster_connection.cpp | 30 ++--
ndb/tools/waiter.cpp | 46 ++---
23 files changed, 358 insertions(+), 380 deletions(-)
rename client/{mysqladmin.c => mysqladmin.cc} (99%)
rename ndb/{include => src}/mgmapi/LocalConfig.hpp (97%)
diff --git a/client/Makefile.am b/client/Makefile.am
index 1c552036f9b..07167d97df5 100644
--- a/client/Makefile.am
+++ b/client/Makefile.am
@@ -28,6 +28,7 @@ bin_PROGRAMS = mysql mysqladmin mysqlcheck mysqlshow \
noinst_HEADERS = sql_string.h completion_hash.h my_readline.h \
client_priv.h
mysql_SOURCES = mysql.cc readline.cc sql_string.cc completion_hash.cc
+mysqladmin_SOURCES = mysqladmin.cc
mysql_LDADD = @readline_link@ @TERMCAP_LIB@ $(LDADD) $(CXXLDFLAGS)
mysqlbinlog_LDADD = $(LDADD) $(CXXLDFLAGS)
mysql_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) $(DEPLIB)
diff --git a/client/mysqladmin.c b/client/mysqladmin.cc
similarity index 99%
rename from client/mysqladmin.c
rename to client/mysqladmin.cc
index a32dfa14d28..a9fc3f31d03 100644
--- a/client/mysqladmin.c
+++ b/client/mysqladmin.cc
@@ -1287,9 +1287,6 @@ static my_bool wait_pidfile(char *pidfile, time_t last_modified,
}
DBUG_RETURN(error);
}
-#ifdef HAVE_NDBCLUSTER_DB
-/* lib linked in contains c++ code */
#ifdef __GNUC__
FIX_GCC_LINKING_PROBLEM
#endif
-#endif
diff --git a/configure.in b/configure.in
index f360ee46453..1fcba6b8f5f 100644
--- a/configure.in
+++ b/configure.in
@@ -399,7 +399,6 @@ then
then
if $CXX -v 2>&1 | grep 'version 3' > /dev/null 2>&1
then
- CFLAGS="$CFLAGS -DDEFINE_CXA_PURE_VIRTUAL"
CXXFLAGS="$CXXFLAGS -DUSE_MYSYS_NEW -DDEFINE_CXA_PURE_VIRTUAL"
fi
fi
diff --git a/ndb/include/mgmapi/mgmapi.h b/ndb/include/mgmapi/mgmapi.h
index f1ef357421b..a4e1fc1d1a8 100644
--- a/ndb/include/mgmapi/mgmapi.h
+++ b/ndb/include/mgmapi/mgmapi.h
@@ -356,11 +356,28 @@ extern "C" {
/**
* Create a handle to a management server
*
- * @return A management handle
- * or NULL if no management handle could be created.
+ * @param connect_string Connect string to the management server,
+ *
+ * @return A management handle
+ * or NULL if no management handle could be created.
*/
NdbMgmHandle ndb_mgm_create_handle();
+ /**
+ * Set connecst string to management server
+ *
+ * @param handle Management handle
+ * @param connect_string Connect string to the management server,
+ *
+ * @return -1 on error.
+ */
+ int ndb_mgm_set_connectstring(NdbMgmHandle handle,
+ const char *connect_string);
+
+ int ndb_mgm_get_configuration_nodeid(NdbMgmHandle handle);
+ int ndb_mgm_get_connected_port(NdbMgmHandle handle);
+ const char *ndb_mgm_get_connected_host(NdbMgmHandle handle);
+
/**
* Destroy a management server handle
*
@@ -378,11 +395,10 @@ extern "C" {
* Connect to a management server
*
* @param handle Management handle.
- * @param mgmsrv Hostname and port of the management server,
- * "hostname:port".
* @return -1 on error.
*/
- int ndb_mgm_connect(NdbMgmHandle handle, const char * mgmsrv);
+ int ndb_mgm_connect(NdbMgmHandle handle, int no_retries,
+ int retry_delay_in_seconds, int verbose);
/**
* Disconnect from a management server
@@ -709,9 +725,7 @@ extern "C" {
void ndb_mgm_destroy_configuration(struct ndb_mgm_configuration *);
int ndb_mgm_alloc_nodeid(NdbMgmHandle handle,
- unsigned version,
- unsigned *pnodeid,
- int nodetype);
+ unsigned version, int nodetype);
/**
* Config iterator
*/
diff --git a/ndb/include/mgmcommon/ConfigRetriever.hpp b/ndb/include/mgmcommon/ConfigRetriever.hpp
index 6c32255e921..80449628867 100644
--- a/ndb/include/mgmcommon/ConfigRetriever.hpp
+++ b/ndb/include/mgmcommon/ConfigRetriever.hpp
@@ -20,7 +20,6 @@
#include
#include
#include
-#include
/**
* @class ConfigRetriever
@@ -28,10 +27,11 @@
*/
class ConfigRetriever {
public:
- ConfigRetriever(LocalConfig &local_config, Uint32 version, Uint32 nodeType);
+ ConfigRetriever(const char * _connect_string,
+ Uint32 version, Uint32 nodeType);
~ConfigRetriever();
- int do_connect(int exit_on_connect_failure= false);
+ int do_connect(int no_retries, int retry_delay_in_seconds, int verbose);
/**
* Get configuration for current node.
@@ -46,12 +46,14 @@ public:
*/
struct ndb_mgm_configuration * getConfig();
+ void resetError();
+ int hasError();
const char * getErrorString();
/**
* @return Node id of this node (as stated in local config or connectString)
*/
- Uint32 allocNodeId();
+ Uint32 allocNodeId(int no_retries, int retry_delay_in_seconds);
/**
* Get config using socket
@@ -68,22 +70,26 @@ public:
*/
bool verifyConfig(const struct ndb_mgm_configuration *, Uint32 nodeid);
- Uint32 get_mgmd_port() const {return m_mgmd_port;};
- const char *get_mgmd_host() const {return m_mgmd_host;};
+ Uint32 get_mgmd_port() const;
+ const char *get_mgmd_host() const;
+
+ Uint32 get_configuration_nodeid() const;
private:
BaseString errorString;
enum ErrorType {
- CR_ERROR = 0,
- CR_RETRY = 1
+ CR_NO_ERROR = 0,
+ CR_ERROR = 1,
+ CR_RETRY = 2
};
ErrorType latestErrorType;
void setError(ErrorType, const char * errorMsg);
- struct LocalConfig& _localConfig;
- Uint32 _ownNodeId;
+ Uint32 _ownNodeId;
+ /*
Uint32 m_mgmd_port;
const char *m_mgmd_host;
+ */
Uint32 m_version;
Uint32 m_node_type;
diff --git a/ndb/include/ndbapi/ndb_cluster_connection.hpp b/ndb/include/ndbapi/ndb_cluster_connection.hpp
index f8e6f25ce73..59d5a038844 100644
--- a/ndb/include/ndbapi/ndb_cluster_connection.hpp
+++ b/ndb/include/ndbapi/ndb_cluster_connection.hpp
@@ -19,7 +19,6 @@
#define CLUSTER_CONNECTION_HPP
class TransporterFacade;
-class LocalConfig;
class ConfigRetriever;
class NdbThread;
@@ -38,7 +37,6 @@ private:
void connect_thread();
char *m_connect_string;
TransporterFacade *m_facade;
- LocalConfig *m_local_config;
ConfigRetriever *m_config_retriever;
NdbThread *m_connect_thread;
int (*m_connect_callback)(void);
diff --git a/ndb/src/common/mgmcommon/ConfigRetriever.cpp b/ndb/src/common/mgmcommon/ConfigRetriever.cpp
index a1b979f62d8..0af5eb2f83c 100644
--- a/ndb/src/common/mgmcommon/ConfigRetriever.cpp
+++ b/ndb/src/common/mgmcommon/ConfigRetriever.cpp
@@ -20,7 +20,6 @@
#include
#include
-#include "LocalConfig.hpp"
#include
#include
@@ -45,90 +44,62 @@
//****************************************************************************
//****************************************************************************
-ConfigRetriever::ConfigRetriever(LocalConfig &local_config,
+ConfigRetriever::ConfigRetriever(const char * _connect_string,
Uint32 version, Uint32 node_type)
- : _localConfig(local_config)
{
- m_handle= 0;
m_version = version;
m_node_type = node_type;
- _ownNodeId = _localConfig._ownNodeId;
+ _ownNodeId= 0;
+
+ m_handle= ndb_mgm_create_handle();
+
+ if (m_handle == 0) {
+ setError(CR_ERROR, "Unable to allocate mgm handle");
+ return;
+ }
+
+ if (ndb_mgm_set_connectstring(m_handle, _connect_string))
+ {
+ setError(CR_ERROR, ndb_mgm_get_latest_error_desc(m_handle));
+ return;
+ }
+ resetError();
}
-ConfigRetriever::~ConfigRetriever(){
-
+ConfigRetriever::~ConfigRetriever()
+{
if (m_handle) {
ndb_mgm_disconnect(m_handle);
ndb_mgm_destroy_handle(&m_handle);
}
}
+Uint32
+ConfigRetriever::get_configuration_nodeid() const
+{
+ return ndb_mgm_get_configuration_nodeid(m_handle);
+}
+
+Uint32 ConfigRetriever::get_mgmd_port() const
+{
+ return ndb_mgm_get_connected_port(m_handle);
+}
+
+const char *ConfigRetriever::get_mgmd_host() const
+{
+ return ndb_mgm_get_connected_host(m_handle);
+}
//****************************************************************************
//****************************************************************************
int
-ConfigRetriever::do_connect(int exit_on_connect_failure){
-
- m_mgmd_port= 0;
- m_mgmd_host= 0;
-
- if(!m_handle)
- m_handle= ndb_mgm_create_handle();
-
- if (m_handle == 0) {
- setError(CR_ERROR, "Unable to allocate mgm handle");
- return -1;
- }
-
- int retry = 1;
- int retry_max = 12; // Max number of retry attempts
- int retry_interval= 5; // Seconds between each retry
- while(retry < retry_max){
- Uint32 type = CR_ERROR;
- BaseString tmp;
- for (unsigned int i = 0; i<_localConfig.ids.size(); i++){
- MgmtSrvrId * m = &_localConfig.ids[i];
- DBUG_PRINT("info",("trying %s:%d",
- m->name.c_str(),
- m->port));
- switch(m->type){
- case MgmId_TCP:
- tmp.assfmt("%s:%d", m->name.c_str(), m->port);
- if (ndb_mgm_connect(m_handle, tmp.c_str()) == 0) {
- m_mgmd_port= m->port;
- m_mgmd_host= m->name.c_str();
- DBUG_PRINT("info",("connected to ndb_mgmd at %s:%d",
- m_mgmd_host,
- m_mgmd_port));
- return 0;
- }
- setError(CR_RETRY, ndb_mgm_get_latest_error_desc(m_handle));
- case MgmId_File:
- break;
- }
- }
- if(latestErrorType == CR_RETRY){
- DBUG_PRINT("info",("CR_RETRY"));
- if (exit_on_connect_failure)
- return 1;
- REPORT_WARNING("Failed to retrieve cluster configuration");
- ndbout << "(Cause of failure: " << getErrorString() << ")" << endl;
- ndbout << "Attempt " << retry << " of " << retry_max << ". "
- << "Trying again in "<< retry_interval <<" seconds..."
- << endl << endl;
- NdbSleep_SecSleep(retry_interval);
- } else {
- break;
- }
- retry++;
- }
-
- ndb_mgm_destroy_handle(&m_handle);
- m_handle= 0;
- m_mgmd_port= 0;
- m_mgmd_host= 0;
- return -1;
+ConfigRetriever::do_connect(int no_retries,
+ int retry_delay_in_seconds, int verbose)
+{
+ return
+ (ndb_mgm_connect(m_handle,no_retries,retry_delay_in_seconds,verbose)==0) ?
+ 0 : -1;
}
//****************************************************************************
@@ -140,22 +111,9 @@ ConfigRetriever::getConfig() {
struct ndb_mgm_configuration * p = 0;
- if(m_handle != 0){
+ if(m_handle != 0)
p = getConfig(m_handle);
- } else {
- for (unsigned int i = 0; i<_localConfig.ids.size(); i++){
- MgmtSrvrId * m = &_localConfig.ids[i];
- switch(m->type){
- case MgmId_File:
- p = getConfig(m->name.c_str());
- break;
- case MgmId_TCP:
- break;
- }
- if(p)
- break;
- }
- }
+
if(p == 0)
return 0;
@@ -227,6 +185,16 @@ ConfigRetriever::setError(ErrorType et, const char * s){
latestErrorType = et;
}
+void
+ConfigRetriever::resetError(){
+ setError(CR_NO_ERROR,0);
+}
+
+int
+ConfigRetriever::hasError()
+{
+ return latestErrorType != CR_NO_ERROR;
+}
const char *
ConfigRetriever::getErrorString(){
@@ -341,16 +309,23 @@ ConfigRetriever::verifyConfig(const struct ndb_mgm_configuration * conf, Uint32
}
Uint32
-ConfigRetriever::allocNodeId(){
- unsigned nodeid= _ownNodeId;
-
- if(m_handle != 0){
- int res= ndb_mgm_alloc_nodeid(m_handle, m_version, &nodeid, m_node_type);
- if(res != 0) {
- setError(CR_ERROR, ndb_mgm_get_latest_error_desc(m_handle));
- return 0;
+ConfigRetriever::allocNodeId(int no_retries, int retry_delay_in_seconds)
+{
+ _ownNodeId= 0;
+ if(m_handle != 0)
+ {
+ while (1)
+ {
+ int res= ndb_mgm_alloc_nodeid(m_handle, m_version, m_node_type);
+ if(res >= 0)
+ return _ownNodeId= (Uint32)res;
+ if (no_retries == 0)
+ break;
+ no_retries--;
+ NdbSleep_SecSleep(retry_delay_in_seconds);
}
- }
-
- return _ownNodeId= nodeid;
+ setError(CR_ERROR, ndb_mgm_get_latest_error_desc(m_handle));
+ } else
+ setError(CR_ERROR, "management server handle not initialized");
+ return 0;
}
diff --git a/ndb/src/kernel/main.cpp b/ndb/src/kernel/main.cpp
index 926647838c9..f34e16318cd 100644
--- a/ndb/src/kernel/main.cpp
+++ b/ndb/src/kernel/main.cpp
@@ -19,7 +19,6 @@
#include
#include "Configuration.hpp"
-#include
#include
#include "vm/SimBlockList.hpp"
@@ -69,16 +68,9 @@ int main(int argc, char** argv)
return NRT_Default;
}
- LocalConfig local_config;
- if (!local_config.init(theConfig->getConnectString(),0)){
- local_config.printError();
- local_config.printUsage();
- return NRT_Default;
- }
-
{ // Do configuration
signal(SIGPIPE, SIG_IGN);
- theConfig->fetch_configuration(local_config);
+ theConfig->fetch_configuration();
}
chdir(NdbConfig_get_path(0));
@@ -141,7 +133,7 @@ int main(int argc, char** argv)
exit(0);
}
g_eventLogger.info("Ndb has terminated (pid %d) restarting", child);
- theConfig->fetch_configuration(local_config);
+ theConfig->fetch_configuration();
}
g_eventLogger.info("Angel pid: %d ndb pid: %d", getppid(), getpid());
diff --git a/ndb/src/kernel/vm/Configuration.cpp b/ndb/src/kernel/vm/Configuration.cpp
index b3a436275f7..9019782f4db 100644
--- a/ndb/src/kernel/vm/Configuration.cpp
+++ b/ndb/src/kernel/vm/Configuration.cpp
@@ -17,7 +17,6 @@
#include
#include
-#include
#include "Configuration.hpp"
#include
#include "GlobalData.hpp"
@@ -189,7 +188,7 @@ Configuration::closeConfiguration(){
}
void
-Configuration::fetch_configuration(LocalConfig &local_config){
+Configuration::fetch_configuration(){
/**
* Fetch configuration from management server
*/
@@ -199,8 +198,17 @@ Configuration::fetch_configuration(LocalConfig &local_config){
m_mgmd_port= 0;
m_mgmd_host= 0;
- m_config_retriever= new ConfigRetriever(local_config, NDB_VERSION, NODE_TYPE_DB);
- if(m_config_retriever->do_connect() == -1){
+ m_config_retriever= new ConfigRetriever(getConnectString(),
+ NDB_VERSION, NODE_TYPE_DB);
+
+ if (m_config_retriever->hasError())
+ {
+ ERROR_SET(fatal, ERR_INVALID_CONFIG,
+ "Could not connect initialize handle to management server",
+ m_config_retriever->getErrorString());
+ }
+
+ if(m_config_retriever->do_connect(12,5,1) == -1){
const char * s = m_config_retriever->getErrorString();
if(s == 0)
s = "No error given!";
@@ -215,13 +223,7 @@ Configuration::fetch_configuration(LocalConfig &local_config){
ConfigRetriever &cr= *m_config_retriever;
- if((globalData.ownId = cr.allocNodeId()) == 0){
- for(Uint32 i = 0; i<3; i++){
- NdbSleep_SecSleep(3);
- if((globalData.ownId = cr.allocNodeId()) != 0)
- break;
- }
- }
+ globalData.ownId = cr.allocNodeId(2 /*retry*/,3 /*delay*/);
if(globalData.ownId == 0){
ERROR_SET(fatal, ERR_INVALID_CONFIG,
@@ -599,7 +601,8 @@ Configuration::calcSizeAlt(ConfigValues * ownConfig){
Uint32 noOfTCScanRecords = noOfScanRecords;
{
- Uint32 noOfAccTables= noOfTables + noOfUniqueHashIndexes;
+ Uint32 noOfAccTables= noOfTables + noOfUniqueHashIndexes *
+ noOfOrderedIndexes /* should be removed */;
/**
* Acc Size Alt values
*/
@@ -758,13 +761,14 @@ Configuration::calcSizeAlt(ConfigValues * ownConfig){
* Tux Size Alt values
*/
cfg.put(CFG_TUX_INDEX,
- noOfOrderedIndexes);
+ noOfMetaTables /*noOfOrderedIndexes*/);
cfg.put(CFG_TUX_FRAGMENT,
- 2 * NO_OF_FRAG_PER_NODE * noOfOrderedIndexes * noOfReplicas);
+ 2 * NO_OF_FRAG_PER_NODE * noOfMetaTables /*noOfOrderedIndexes*/ *
+ noOfReplicas);
cfg.put(CFG_TUX_ATTRIBUTE,
- noOfOrderedIndexes * 4);
+ noOfMetaTables /*noOfOrderedIndexes*/ * 4);
cfg.put(CFG_TUX_SCAN_OP, noOfLocalScanRecords);
}
diff --git a/ndb/src/kernel/vm/Configuration.hpp b/ndb/src/kernel/vm/Configuration.hpp
index e4cd64f5ca8..acf0e163a84 100644
--- a/ndb/src/kernel/vm/Configuration.hpp
+++ b/ndb/src/kernel/vm/Configuration.hpp
@@ -21,7 +21,6 @@
#include
class ConfigRetriever;
-class LocalConfig;
class Configuration {
public:
@@ -33,7 +32,7 @@ public:
*/
bool init(int argc, char** argv);
- void fetch_configuration(LocalConfig &local_config);
+ void fetch_configuration();
void setupConfiguration();
void closeConfiguration();
diff --git a/ndb/src/mgmapi/LocalConfig.cpp b/ndb/src/mgmapi/LocalConfig.cpp
index d0ff97cdedf..8f1e2ee8100 100644
--- a/ndb/src/mgmapi/LocalConfig.cpp
+++ b/ndb/src/mgmapi/LocalConfig.cpp
@@ -14,7 +14,7 @@
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 "LocalConfig.hpp"
#include
#include
#include
@@ -294,4 +294,19 @@ LocalConfig::readConnectString(const char * connectString,
return return_value;
}
+char *
+LocalConfig::makeConnectString(char *buf, int sz)
+{
+ int p= BaseString::snprintf(buf,sz,"nodeid=%d", _ownNodeId);
+ for (int i = 0; (i < ids.size()) && (sz-p > 0); i++)
+ {
+ if (ids[i].type != MgmId_TCP)
+ continue;
+ p+=BaseString::snprintf(buf+p,sz-p,",%s:%d",
+ ids[i].name.c_str(), ids[i].port);
+ }
+ buf[sz-1]=0;
+ return buf;
+}
+
template class Vector;
diff --git a/ndb/include/mgmapi/LocalConfig.hpp b/ndb/src/mgmapi/LocalConfig.hpp
similarity index 97%
rename from ndb/include/mgmapi/LocalConfig.hpp
rename to ndb/src/mgmapi/LocalConfig.hpp
index 9ceeffdba36..c415ec1be91 100644
--- a/ndb/include/mgmapi/LocalConfig.hpp
+++ b/ndb/src/mgmapi/LocalConfig.hpp
@@ -61,6 +61,7 @@ struct LocalConfig {
bool parseHostName(const char *buf);
bool parseFileName(const char *buf);
bool parseString(const char *buf, BaseString &err);
+ char * makeConnectString(char *buf, int sz);
};
#endif // LocalConfig_H
diff --git a/ndb/src/mgmapi/mgmapi.cpp b/ndb/src/mgmapi/mgmapi.cpp
index 51f2d7cee01..ca3a2a2186d 100644
--- a/ndb/src/mgmapi/mgmapi.cpp
+++ b/ndb/src/mgmapi/mgmapi.cpp
@@ -20,6 +20,7 @@
#include
#include
+#include
#include
#include "mgmapi.h"
#include "mgmapi_debug.h"
@@ -83,8 +84,8 @@ typedef Parser Parser_t;
#define NDB_MGM_MAX_ERR_DESC_SIZE 256
struct ndb_mgm_handle {
- char * hostname;
- unsigned short port;
+ char * connectstring;
+ int cfg_i;
int connected;
int last_error;
@@ -95,7 +96,7 @@ struct ndb_mgm_handle {
NDB_SOCKET_TYPE socket;
- char cfg_ptr[sizeof(LocalConfig)];
+ LocalConfig cfg;
#ifdef MGMAPI_LOG
FILE* logfile;
@@ -148,14 +149,16 @@ ndb_mgm_create_handle()
h->connected = 0;
h->last_error = 0;
h->last_error_line = 0;
- h->hostname = 0;
h->socket = NDB_INVALID_SOCKET;
h->read_timeout = 50000;
h->write_timeout = 100;
-
- new (h->cfg_ptr) LocalConfig;
+ h->cfg_i = 0;
strncpy(h->last_error_desc, "No error", NDB_MGM_MAX_ERR_DESC_SIZE);
+
+ new (&(h->cfg)) LocalConfig;
+ h->cfg.init(0, 0);
+
#ifdef MGMAPI_LOG
h->logfile = 0;
#endif
@@ -163,6 +166,23 @@ ndb_mgm_create_handle()
return h;
}
+extern "C"
+int
+ndb_mgm_set_connectstring(NdbMgmHandle handle, const char * mgmsrv)
+{
+ new (&(handle->cfg)) LocalConfig;
+ if (!handle->cfg.init(mgmsrv, 0) ||
+ handle->cfg.ids.size() == 0)
+ {
+ new (&(handle->cfg)) LocalConfig;
+ handle->cfg.init(0, 0); /* reset the LocalCongig */
+ SET_ERROR(handle, NDB_MGM_ILLEGAL_CONNECT_STRING, "");
+ return -1;
+ }
+ handle->cfg_i= 0;
+ return 0;
+}
+
/**
* Destroy a handle
*/
@@ -175,14 +195,13 @@ ndb_mgm_destroy_handle(NdbMgmHandle * handle)
if((* handle)->connected){
ndb_mgm_disconnect(* handle);
}
- my_free((* handle)->hostname,MYF(MY_ALLOW_ZERO_PTR));
#ifdef MGMAPI_LOG
if ((* handle)->logfile != 0){
fclose((* handle)->logfile);
(* handle)->logfile = 0;
}
#endif
- ((LocalConfig*)((*handle)->cfg_ptr))->~LocalConfig();
+ (*handle)->cfg.~LocalConfig();
my_free((char*)* handle,MYF(MY_ALLOW_ZERO_PTR));
* handle = 0;
}
@@ -314,7 +333,8 @@ ndb_mgm_call(NdbMgmHandle handle, const ParserRow *command_reply,
*/
extern "C"
int
-ndb_mgm_connect(NdbMgmHandle handle, const char * mgmsrv)
+ndb_mgm_connect(NdbMgmHandle handle, int no_retries,
+ int retry_delay_in_seconds, int verbose)
{
SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_connect");
CHECK_HANDLE(handle, -1);
@@ -331,36 +351,48 @@ ndb_mgm_connect(NdbMgmHandle handle, const char * mgmsrv)
/**
* Do connect
*/
- LocalConfig *cfg= (LocalConfig*)(handle->cfg_ptr);
- new (cfg) LocalConfig;
- if (!cfg->init(mgmsrv, 0) ||
- cfg->ids.size() == 0)
- {
- SET_ERROR(handle, NDB_MGM_ILLEGAL_CONNECT_STRING, "");
- return -1;
- }
-
+ LocalConfig &cfg= handle->cfg;
NDB_SOCKET_TYPE sockfd= NDB_INVALID_SOCKET;
Uint32 i;
- for (i = 0; i < cfg->ids.size(); i++)
+ while (sockfd == NDB_INVALID_SOCKET)
{
- if (cfg->ids[i].type != MgmId_TCP)
- continue;
- SocketClient s(cfg->ids[i].name.c_str(), cfg->ids[i].port);
- sockfd = s.connect();
+ // do all the mgmt servers
+ for (i = 0; i < cfg.ids.size(); i++)
+ {
+ if (cfg.ids[i].type != MgmId_TCP)
+ continue;
+ SocketClient s(cfg.ids[i].name.c_str(), cfg.ids[i].port);
+ sockfd = s.connect();
+ if (sockfd != NDB_INVALID_SOCKET)
+ break;
+ }
if (sockfd != NDB_INVALID_SOCKET)
break;
- }
- if (sockfd == NDB_INVALID_SOCKET)
- {
- setError(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, __LINE__,
- "Unable to connect using connectstring %s", mgmsrv);
- return -1;
+ if (verbose > 0) {
+ char buf[1024];
+ ndbout_c("Unable to connect with connect string: %s",
+ cfg.makeConnectString(buf,sizeof(buf)));
+ verbose= -1;
+ }
+ if (no_retries == 0) {
+ char buf[1024];
+ setError(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, __LINE__,
+ "Unable to connect with connect string: %s",
+ cfg.makeConnectString(buf,sizeof(buf)));
+ return -1;
+ }
+ if (verbose == -1) {
+ ndbout << "retrying every " << retry_delay_in_seconds << " seconds:";
+ verbose= -2;
+ }
+ NdbSleep_SecSleep(retry_delay_in_seconds);
+ if (verbose == -2) {
+ ndbout << " " << no_retries;
+ }
+ no_retries--;
}
- my_free(handle->hostname,MYF(MY_ALLOW_ZERO_PTR));
- handle->hostname = my_strdup(cfg->ids[i].name.c_str(),MYF(MY_WME));
- handle->port = cfg->ids[i].port;
+ handle->cfg_i = i;
handle->socket = sockfd;
handle->connected = 1;
@@ -1068,7 +1100,9 @@ ndb_mgm_listen_event(NdbMgmHandle handle, int filter[])
};
CHECK_HANDLE(handle, -1);
- SocketClient s(handle->hostname, handle->port);
+ const char *hostname= ndb_mgm_get_connected_host(handle);
+ int port= ndb_mgm_get_connected_port(handle);
+ SocketClient s(hostname, port);
const NDB_SOCKET_TYPE sockfd = s.connect();
if (sockfd < 0) {
setError(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, __LINE__,
@@ -1613,16 +1647,37 @@ ndb_mgm_destroy_configuration(struct ndb_mgm_configuration *cfg)
extern "C"
int
-ndb_mgm_alloc_nodeid(NdbMgmHandle handle, unsigned int version, unsigned *pnodeid, int nodetype)
+ndb_mgm_get_configuration_nodeid(NdbMgmHandle handle)
{
+ CHECK_HANDLE(handle, 0);
+ return handle->cfg._ownNodeId;
+}
+extern "C"
+int ndb_mgm_get_connected_port(NdbMgmHandle handle)
+{
+ return handle->cfg.ids[handle->cfg_i].port;
+}
+
+extern "C"
+const char *ndb_mgm_get_connected_host(NdbMgmHandle handle)
+{
+ return handle->cfg.ids[handle->cfg_i].name.c_str();
+}
+
+extern "C"
+int
+ndb_mgm_alloc_nodeid(NdbMgmHandle handle, unsigned int version, int nodetype)
+{
CHECK_HANDLE(handle, 0);
CHECK_CONNECTED(handle, 0);
+ int nodeid= handle->cfg._ownNodeId;
+
Properties args;
args.put("version", version);
args.put("nodetype", nodetype);
- args.put("nodeid", *pnodeid);
+ args.put("nodeid", nodeid);
args.put("user", "mysqld");
args.put("password", "mysqld");
args.put("public key", "a public key");
@@ -1638,26 +1693,29 @@ ndb_mgm_alloc_nodeid(NdbMgmHandle handle, unsigned int version, unsigned *pnodei
prop= ndb_mgm_call(handle, reply, "get nodeid", &args);
CHECK_REPLY(prop, -1);
- int res= -1;
+ nodeid= -1;
do {
const char * buf;
if(!prop->get("result", &buf) || strcmp(buf, "Ok") != 0){
+ const char *hostname= ndb_mgm_get_connected_host(handle);
+ unsigned port= ndb_mgm_get_connected_port(handle);
BaseString err;
err.assfmt("Could not alloc node id at %s port %d: %s",
- handle->hostname, handle->port, buf);
+ hostname, port, buf);
setError(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, __LINE__,
err.c_str());
break;
}
- if(!prop->get("nodeid", pnodeid) != 0){
+ Uint32 _nodeid;
+ if(!prop->get("nodeid", &_nodeid) != 0){
ndbout_c("ERROR Message: \n");
break;
}
- res= 0;
+ nodeid= _nodeid;
}while(0);
delete prop;
- return res;
+ return nodeid;
}
/*****************************************************************************
diff --git a/ndb/src/mgmclient/CommandInterpreter.cpp b/ndb/src/mgmclient/CommandInterpreter.cpp
index d940f6e165a..00e0a8c1919 100644
--- a/ndb/src/mgmclient/CommandInterpreter.cpp
+++ b/ndb/src/mgmclient/CommandInterpreter.cpp
@@ -153,7 +153,6 @@ private:
NdbMgmHandle m_mgmsrv;
bool connected;
- const char *host;
int try_reconnect;
#ifdef HAVE_GLOBAL_REPLICATION
NdbRepHandle m_repserver;
@@ -193,7 +192,7 @@ extern "C" {
{
return (Ndb_mgmclient_handle) new Ndb_mgmclient(connect_string);
}
- int ndb_mgmclient_execute(Ndb_mgmclient_handle h, int argc, const char** argv)
+ int ndb_mgmclient_execute(Ndb_mgmclient_handle h, int argc, char** argv)
{
return ((Ndb_mgmclient*)h)->execute(argc, argv, 1);
}
@@ -226,7 +225,7 @@ extern "C" {
#include
#include
-int Ndb_mgmclient::execute(int argc, const char** argv, int _try_reconnect)
+int Ndb_mgmclient::execute(int argc, char** argv, int _try_reconnect)
{
if (argc <= 0)
return 0;
@@ -379,15 +378,16 @@ CommandInterpreter::CommandInterpreter(const char *_host)
m_mgmsrv = ndb_mgm_create_handle();
if(m_mgmsrv == NULL) {
ndbout_c("Cannot create handle to management server.");
+ exit(-1);
+ }
+ if (ndb_mgm_set_connectstring(m_mgmsrv, _host))
+ {
printError();
+ exit(-1);
}
connected = false;
try_reconnect = 0;
- if (_host)
- host= my_strdup(_host,MYF(MY_WME));
- else
- host= 0;
#ifdef HAVE_GLOBAL_REPLICATION
rep_host = NULL;
m_repserver = NULL;
@@ -402,8 +402,6 @@ CommandInterpreter::~CommandInterpreter()
{
connected = false;
ndb_mgm_destroy_handle(&m_mgmsrv);
- my_free((char *)host,MYF(MY_ALLOW_ZERO_PTR));
- host = NULL;
}
static bool
@@ -438,18 +436,8 @@ bool
CommandInterpreter::connect()
{
if(!connected) {
- int tries = try_reconnect; // tries == 0 => infinite
- while(!connected) {
- if(ndb_mgm_connect(m_mgmsrv, host) == -1) {
- ndbout << "Cannot connect to management server (" << host << ").";
- tries--;
- if (tries == 0)
- break;
- ndbout << "Retrying in 5 seconds." << endl;
- NdbSleep_SecSleep(5);
- } else
- connected = true;
- }
+ if(!ndb_mgm_connect(m_mgmsrv, try_reconnect-1, 5, 1))
+ connected = true;
}
return connected;
}
diff --git a/ndb/src/mgmclient/main.cpp b/ndb/src/mgmclient/main.cpp
index 401a9198f30..e2de4b277a9 100644
--- a/ndb/src/mgmclient/main.cpp
+++ b/ndb/src/mgmclient/main.cpp
@@ -30,9 +30,10 @@ extern "C" int add_history(const char *command); /* From readline directory */
#include
#include
+#include
+#include
#include
#include
-#include
#include "ndb_mgmclient.hpp"
diff --git a/ndb/src/mgmclient/ndb_mgmclient.h b/ndb/src/mgmclient/ndb_mgmclient.h
index 265e6bc67ec..b62a33999a3 100644
--- a/ndb/src/mgmclient/ndb_mgmclient.h
+++ b/ndb/src/mgmclient/ndb_mgmclient.h
@@ -23,7 +23,7 @@ extern "C" {
typedef void* Ndb_mgmclient_handle;
Ndb_mgmclient_handle ndb_mgmclient_handle_create(const char *connect_string);
-int ndb_mgmclient_execute(Ndb_mgmclient_handle, int argc, const char** argv);
+int ndb_mgmclient_execute(Ndb_mgmclient_handle, int argc, char** argv);
int ndb_mgmclient_handle_destroy(Ndb_mgmclient_handle);
#ifdef __cplusplus
diff --git a/ndb/src/mgmclient/ndb_mgmclient.hpp b/ndb/src/mgmclient/ndb_mgmclient.hpp
index 933d1bab5ce..f6bcebc3896 100644
--- a/ndb/src/mgmclient/ndb_mgmclient.hpp
+++ b/ndb/src/mgmclient/ndb_mgmclient.hpp
@@ -24,7 +24,7 @@ public:
Ndb_mgmclient(const char*);
~Ndb_mgmclient();
int execute(const char *_line, int _try_reconnect=-1);
- int execute(int argc, const char** argv, int _try_reconnect=-1);
+ int execute(int argc, char** argv, int _try_reconnect=-1);
int disconnect();
private:
CommandInterpreter *m_cmd;
diff --git a/ndb/src/mgmsrv/MgmtSrvr.cpp b/ndb/src/mgmsrv/MgmtSrvr.cpp
index a49b29af275..81b5eb9dfb3 100644
--- a/ndb/src/mgmsrv/MgmtSrvr.cpp
+++ b/ndb/src/mgmsrv/MgmtSrvr.cpp
@@ -399,16 +399,20 @@ MgmtSrvr::getPort() const {
}
/* Constructor */
-MgmtSrvr::MgmtSrvr(NodeId nodeId,
- SocketServer *socket_server,
- const BaseString &configFilename,
- LocalConfig &local_config,
- Config * config):
+int MgmtSrvr::init()
+{
+ if ( _ownNodeId > 0)
+ return 0;
+ return -1;
+}
+
+MgmtSrvr::MgmtSrvr(SocketServer *socket_server,
+ const char *config_filename,
+ const char *connect_string) :
_blockNumber(1), // Hard coded block number since it makes it easy to send
// signals to other management servers.
m_socket_server(socket_server),
_ownReference(0),
- m_local_config(local_config),
theSignalIdleList(NULL),
theWaitState(WAIT_SUBSCRIBE_CONF),
m_statisticsListner(this)
@@ -416,6 +420,8 @@ MgmtSrvr::MgmtSrvr(NodeId nodeId,
DBUG_ENTER("MgmtSrvr::MgmtSrvr");
+ _ownNodeId= 0;
+
_config = NULL;
_isStopThread = false;
@@ -426,12 +432,43 @@ MgmtSrvr::MgmtSrvr(NodeId nodeId,
theFacade = 0;
m_newConfig = NULL;
- m_configFilename = configFilename;
+ m_configFilename.assign(config_filename);
m_nextConfigGenerationNumber = 0;
- _config = (config == 0 ? readConfig() : config);
-
+ m_config_retriever= new ConfigRetriever(connect_string,
+ NDB_VERSION, NDB_MGM_NODE_TYPE_MGM);
+
+ // first try to allocate nodeid from another management server
+ if(m_config_retriever->do_connect(0,0,0) == 0)
+ {
+ int tmp_nodeid= 0;
+ tmp_nodeid= m_config_retriever->allocNodeId(0 /*retry*/,0 /*delay*/);
+ if (tmp_nodeid == 0)
+ {
+ ndbout_c(m_config_retriever->getErrorString());
+ exit(-1);
+ }
+ // read config from other managent server
+ _config= fetchConfig();
+ if (_config == 0)
+ {
+ ndbout << m_config_retriever->getErrorString() << endl;
+ exit(-1);
+ }
+ _ownNodeId= tmp_nodeid;
+ }
+
+ if (_ownNodeId == 0)
+ {
+ // read config locally
+ _config= readConfig();
+ if (_config == 0) {
+ ndbout << "Unable to read config file" << endl;
+ exit(-1);
+ }
+ }
+
theMgmtWaitForResponseCondPtr = NdbCondition_Create();
m_configMutex = NdbMutex_Create();
@@ -443,9 +480,11 @@ MgmtSrvr::MgmtSrvr(NodeId nodeId,
nodeTypes[i] = (enum ndb_mgm_node_type)-1;
m_connect_address[i].s_addr= 0;
}
+
{
- ndb_mgm_configuration_iterator * iter = ndb_mgm_create_configuration_iterator
- (config->m_configValues, CFG_SECTION_NODE);
+ ndb_mgm_configuration_iterator
+ *iter = ndb_mgm_create_configuration_iterator(_config->m_configValues,
+ CFG_SECTION_NODE);
for(ndb_mgm_first(iter); ndb_mgm_valid(iter); ndb_mgm_next(iter)){
unsigned type, id;
if(ndb_mgm_get_int_parameter(iter, CFG_TYPE_OF_SECTION, &type) != 0)
@@ -478,8 +517,6 @@ MgmtSrvr::MgmtSrvr(NodeId nodeId,
}
_props = NULL;
- _ownNodeId= 0;
- NodeId tmp= nodeId;
BaseString error_string;
if ((m_node_id_mutex = NdbMutex_Create()) == 0)
@@ -488,43 +525,25 @@ MgmtSrvr::MgmtSrvr(NodeId nodeId,
exit(-1);
}
-#if 0
- char my_hostname[256];
- struct sockaddr_in tmp_addr;
- SOCKET_SIZE_TYPE addrlen= sizeof(tmp_addr);
- if (!g_no_nodeid_checks) {
- if (gethostname(my_hostname, sizeof(my_hostname))) {
- ndbout << "error: gethostname() - " << strerror(errno) << endl;
- exit(-1);
- }
- if (Ndb_getInAddr(&(((sockaddr_in*)&tmp_addr)->sin_addr),my_hostname)) {
- ndbout << "error: Ndb_getInAddr(" << my_hostname << ") - "
- << strerror(errno) << endl;
+ if (_ownNodeId == 0) // we did not get node id from other server
+ {
+ NodeId tmp= m_config_retriever->get_configuration_nodeid();
+
+ if (!alloc_node_id(&tmp, NDB_MGM_NODE_TYPE_MGM,
+ 0, 0, error_string)){
+ ndbout << "Unable to obtain requested nodeid: "
+ << error_string.c_str() << endl;
exit(-1);
}
+ _ownNodeId = tmp;
}
- if (!alloc_node_id(&tmp, NDB_MGM_NODE_TYPE_MGM,
- (struct sockaddr *)&tmp_addr,
- &addrlen, error_string)){
- ndbout << "Unable to obtain requested nodeid: "
- << error_string.c_str() << endl;
- exit(-1);
- }
-#else
- if (!alloc_node_id(&tmp, NDB_MGM_NODE_TYPE_MGM,
- 0, 0, error_string)){
- ndbout << "Unable to obtain requested nodeid: "
- << error_string.c_str() << endl;
- exit(-1);
- }
-#endif
- _ownNodeId = tmp;
{
DBUG_PRINT("info", ("verifyConfig"));
- ConfigRetriever cr(m_local_config, NDB_VERSION, NDB_MGM_NODE_TYPE_MGM);
- if (!cr.verifyConfig(config->m_configValues, _ownNodeId)) {
- ndbout << cr.getErrorString() << endl;
+ if (!m_config_retriever->verifyConfig(_config->m_configValues,
+ _ownNodeId))
+ {
+ ndbout << m_config_retriever->getErrorString() << endl;
exit(-1);
}
}
@@ -657,6 +676,8 @@ MgmtSrvr::~MgmtSrvr()
NdbThread_WaitFor(m_signalRecvThread, &res);
NdbThread_Destroy(&m_signalRecvThread);
}
+ if (m_config_retriever)
+ delete m_config_retriever;
}
//****************************************************************************
diff --git a/ndb/src/mgmsrv/MgmtSrvr.hpp b/ndb/src/mgmsrv/MgmtSrvr.hpp
index b3257491123..2ab11250d81 100644
--- a/ndb/src/mgmsrv/MgmtSrvr.hpp
+++ b/ndb/src/mgmsrv/MgmtSrvr.hpp
@@ -175,11 +175,10 @@ public:
/* Constructor */
- MgmtSrvr(NodeId nodeId, /* Local nodeid */
- SocketServer *socket_server,
- const BaseString &config_filename, /* Where to save config */
- LocalConfig &local_config, /* Ndb.cfg filename */
- Config * config);
+ MgmtSrvr(SocketServer *socket_server,
+ const char *config_filename, /* Where to save config */
+ const char *connect_string);
+ int init();
NodeId getOwnNodeId() const {return _ownNodeId;};
/**
@@ -538,7 +537,6 @@ private:
NdbMutex *m_configMutex;
const Config * _config;
Config * m_newConfig;
- LocalConfig &m_local_config;
BaseString m_configFilename;
Uint32 m_nextConfigGenerationNumber;
@@ -755,6 +753,9 @@ private:
Config *_props;
int send(class NdbApiSignal* signal, Uint32 node, Uint32 node_type);
+
+ ConfigRetriever *m_config_retriever;
+
public:
/**
* This method does not exist
diff --git a/ndb/src/mgmsrv/MgmtSrvrConfig.cpp b/ndb/src/mgmsrv/MgmtSrvrConfig.cpp
index 1d51061e909..6c4b4e9ae3c 100644
--- a/ndb/src/mgmsrv/MgmtSrvrConfig.cpp
+++ b/ndb/src/mgmsrv/MgmtSrvrConfig.cpp
@@ -272,30 +272,20 @@ MgmtSrvr::saveConfig(const Config *conf) {
Config *
MgmtSrvr::readConfig() {
- Config *conf = NULL;
- if(m_configFilename.length() != 0) {
- /* Use config file */
- InitConfigFileParser parser;
- conf = parser.parseConfig(m_configFilename.c_str());
-
- if(conf == NULL) {
- /* Try to get configuration from other MGM server */
- return fetchConfig();
- }
- }
+ Config *conf;
+ InitConfigFileParser parser;
+ conf = parser.parseConfig(m_configFilename.c_str());
return conf;
}
Config *
MgmtSrvr::fetchConfig() {
- ConfigRetriever cr(m_local_config, NDB_VERSION, NODE_TYPE_MGM);
- struct ndb_mgm_configuration * tmp = cr.getConfig();
+ struct ndb_mgm_configuration * tmp = m_config_retriever->getConfig();
if(tmp != 0){
Config * conf = new Config();
conf->m_configValues = tmp;
return conf;
}
-
return 0;
}
diff --git a/ndb/src/mgmsrv/main.cpp b/ndb/src/mgmsrv/main.cpp
index 76f0679b069..625a303f7c0 100644
--- a/ndb/src/mgmsrv/main.cpp
+++ b/ndb/src/mgmsrv/main.cpp
@@ -62,7 +62,6 @@ struct MgmGlobals {
int non_interactive;
int interactive;
const char * config_filename;
- const char * local_config_filename;
/** Stuff found in environment or in local config */
NodeId localNodeId;
@@ -70,9 +69,6 @@ struct MgmGlobals {
char * interface_name;
int port;
- /** The configuration of the cluster */
- Config * cluster_config;
-
/** The Mgmt Server */
MgmtSrvr * mgmObject;
@@ -86,9 +82,6 @@ static MgmGlobals glob;
/******************************************************************************
* Function prototypes
******************************************************************************/
-static bool readLocalConfig();
-static bool readGlobalConfig();
-
/**
* Global variables
*/
@@ -122,9 +115,6 @@ static struct my_option my_long_options[] =
{ "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 },
@@ -212,29 +202,16 @@ int main(int argc, char** argv)
MgmApiService * mapi = new MgmApiService();
- /****************************
- * Read configuration files *
- ****************************/
- LocalConfig local_config;
- if(!local_config.init(opt_connect_str,glob.local_config_filename)){
- local_config.printError();
- goto error_end;
- }
- glob.localNodeId = local_config._ownNodeId;
+ glob.mgmObject = new MgmtSrvr(glob.socketServer,
+ glob.config_filename,
+ opt_connect_str);
- if (!readGlobalConfig())
+ if (glob.mgmObject->init())
goto error_end;
- glob.mgmObject = new MgmtSrvr(glob.localNodeId, glob.socketServer,
- BaseString(glob.config_filename),
- local_config,
- glob.cluster_config);
-
chdir(NdbConfig_get_path(0));
- glob.cluster_config = 0;
glob.localNodeId= glob.mgmObject->getOwnNodeId();
-
if (glob.localNodeId == 0) {
goto error_end;
}
@@ -345,9 +322,7 @@ MgmGlobals::MgmGlobals(){
// Default values
port = 0;
config_filename = NULL;
- local_config_filename = NULL;
interface_name = 0;
- cluster_config = 0;
daemon = 1;
non_interactive = 0;
interactive = 0;
@@ -360,27 +335,6 @@ MgmGlobals::~MgmGlobals(){
delete socketServer;
if (mgmObject)
delete mgmObject;
- if (cluster_config)
- delete cluster_config;
if (interface_name)
free(interface_name);
}
-
-/**
- * @fn readGlobalConfig
- * @param glob : Global variables
- * @return true if success, false otherwise.
- */
-static bool
-readGlobalConfig() {
- if(glob.config_filename == NULL)
- return false;
-
- /* Use config file */
- InitConfigFileParser parser;
- glob.cluster_config = parser.parseConfig(glob.config_filename);
- if(glob.cluster_config == 0){
- return false;
- }
- return true;
-}
diff --git a/ndb/src/ndbapi/ndb_cluster_connection.cpp b/ndb/src/ndbapi/ndb_cluster_connection.cpp
index 4c42fe1aeef..b2043b2c2c1 100644
--- a/ndb/src/ndbapi/ndb_cluster_connection.cpp
+++ b/ndb/src/ndbapi/ndb_cluster_connection.cpp
@@ -45,7 +45,6 @@ Ndb_cluster_connection::Ndb_cluster_connection(const char *connect_string)
else
m_connect_string= 0;
m_config_retriever= 0;
- m_local_config= 0;
m_connect_thread= 0;
m_connect_callback= 0;
@@ -125,38 +124,31 @@ int Ndb_cluster_connection::connect(int reconnect)
do {
if (m_config_retriever == 0)
{
- if (m_local_config == 0) {
- m_local_config= new LocalConfig();
- if (!m_local_config->init(m_connect_string,0)) {
- ndbout_c("Configuration error: Unable to retrieve local config");
- m_local_config->printError();
- m_local_config->printUsage();
- DBUG_RETURN(-1);
- }
- }
m_config_retriever=
- new ConfigRetriever(*m_local_config, NDB_VERSION, NODE_TYPE_API);
+ new ConfigRetriever(m_connect_string, NDB_VERSION, NODE_TYPE_API);
+ if (m_config_retriever->hasError())
+ {
+ printf("Could not connect initialize handle to management server",
+ m_config_retriever->getErrorString());
+ DBUG_RETURN(-1);
+ }
}
else
if (reconnect == 0)
DBUG_RETURN(0);
if (reconnect)
{
- int r= m_config_retriever->do_connect(1);
+ int r= m_config_retriever->do_connect(0,0,0);
if (r == 1)
DBUG_RETURN(1); // mgmt server not up yet
if (r == -1)
break;
}
else
- if(m_config_retriever->do_connect() == -1)
+ if(m_config_retriever->do_connect(12,5,1) == -1)
break;
- Uint32 nodeId = m_config_retriever->allocNodeId();
- for(Uint32 i = 0; nodeId == 0 && i<5; i++){
- NdbSleep_SecSleep(3);
- nodeId = m_config_retriever->allocNodeId();
- }
+ Uint32 nodeId = m_config_retriever->allocNodeId(4/*retries*/,3/*delay*/);
if(nodeId == 0)
break;
ndb_mgm_configuration * props = m_config_retriever->getConfig();
@@ -200,8 +192,6 @@ Ndb_cluster_connection::~Ndb_cluster_connection()
my_free(m_connect_string,MYF(MY_ALLOW_ZERO_PTR));
if (m_config_retriever)
delete m_config_retriever;
- if (m_local_config)
- delete m_local_config;
DBUG_VOID_RETURN;
}
diff --git a/ndb/tools/waiter.cpp b/ndb/tools/waiter.cpp
index e24164ea807..cb694ae5877 100644
--- a/ndb/tools/waiter.cpp
+++ b/ndb/tools/waiter.cpp
@@ -23,7 +23,6 @@
#include
#include
#include
-#include
#include
@@ -85,39 +84,8 @@ int main(int argc, char** argv){
char buf[255];
_hostName = argv[0];
- if (_hostName == NULL){
- LocalConfig lcfg;
- if(!lcfg.init(opt_connect_str, 0))
- {
- lcfg.printError();
- lcfg.printUsage();
- g_err << "Error parsing local config file" << endl;
- return NDBT_ProgramExit(NDBT_FAILED);
- }
-
- for (unsigned i = 0; itype){
- case MgmId_TCP:
- snprintf(buf, 255, "%s:%d", m->name.c_str(), m->port);
- _hostName = buf;
- break;
- case MgmId_File:
- break;
- default:
- break;
- }
- if (_hostName != NULL)
- break;
- }
- if (_hostName == NULL)
- {
- g_err << "No management servers configured in local config file" << endl;
- return NDBT_ProgramExit(NDBT_FAILED);
- }
- }
+ if (_hostName == 0)
+ _hostName= opt_connect_str;
if (_no_contact) {
if (waitClusterStatus(_hostName, NDB_MGM_NODE_STATUS_NO_CONTACT, _timeout) != 0)
@@ -210,13 +178,19 @@ waitClusterStatus(const char* _addr,
int _nodes[MAX_NDB_NODES];
int _num_nodes = 0;
- handle = ndb_mgm_create_handle();
+ handle = ndb_mgm_create_handle();
if (handle == NULL){
g_err << "handle == NULL" << endl;
return -1;
}
g_info << "Connecting to mgmsrv at " << _addr << endl;
- if (ndb_mgm_connect(handle, _addr) == -1) {
+ if (ndb_mgm_set_connectstring(handle, _addr))
+ {
+ MGMERR(handle);
+ g_err << "Connectstring " << _addr << " invalid" << endl;
+ return -1;
+ }
+ if (ndb_mgm_connect(handle,0,0,1)) {
MGMERR(handle);
g_err << "Connection to " << _addr << " failed" << endl;
return -1;
From b444c28e2aa25a6bfe63b0ffa738205ddd1c9e41 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Thu, 18 Nov 2004 19:07:14 +0000
Subject: [PATCH 028/145] bug#6684, error messages id wrong settings
---
ndb/tools/restore/main.cpp | 27 +++++++++++++++++++--------
1 file changed, 19 insertions(+), 8 deletions(-)
diff --git a/ndb/tools/restore/main.cpp b/ndb/tools/restore/main.cpp
index 482212911cb..064fbad43a3 100644
--- a/ndb/tools/restore/main.cpp
+++ b/ndb/tools/restore/main.cpp
@@ -74,7 +74,7 @@ static struct my_option my_long_options[] =
"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 },
+ GET_INT, REQUIRED_ARG, 128, 1, 1024, 0, 1, 0 },
{ "print", 256, "Print data and log to stdout",
(gptr*) &_print, (gptr*) &_print, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
@@ -120,6 +120,18 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
case 'V':
print_version();
exit(0);
+ case 'n':
+ if (ga_nodeId == 0)
+ {
+ printf("Error in --nodeid|-n setting, see --help\n");
+ exit(1);
+ }
+ case 'b':
+ if (ga_backupId == 0)
+ {
+ printf("Error in --backupid|-b setting, see --help\n");
+ exit(1);
+ }
case '?':
usage();
exit(0);
@@ -131,11 +143,8 @@ 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) {
+ if (handle_options(pargc, pargv, my_long_options, get_one_option))
+ {
exit(1);
}
@@ -343,7 +352,8 @@ main(int argc, char** argv)
if (res < 0)
{
- err << "Restore: An error occured while restoring data. Exiting... res=" << res << endl;
+ err << "Restore: An error occured while restoring data. Exiting... "
+ << "res=" << res << endl;
return -1;
}
@@ -369,7 +379,8 @@ main(int argc, char** argv)
}
if (res < 0)
{
- err << "Restore: An restoring the data log. Exiting... res=" << res << endl;
+ err << "Restore: An restoring the data log. Exiting... res="
+ << res << endl;
return -1;
}
logIter.validateFooter(); //not implemented
From 5e0d7711c2979729f54c54077d88593a4c0904eb Mon Sep 17 00:00:00 2001
From: "joreland@mysql.com" <>
Date: Thu, 18 Nov 2004 20:54:35 +0100
Subject: [PATCH 029/145] wl2077 moved inline to .hpp file
---
ndb/src/kernel/blocks/dblqh/Dblqh.hpp | 19 +++
ndb/src/kernel/blocks/dblqh/DblqhMain.cpp | 54 +++----
ndb/src/kernel/blocks/dbtc/Dbtc.hpp | 11 +-
ndb/src/kernel/blocks/dbtc/DbtcMain.cpp | 80 ++++++----
ndb/src/kernel/blocks/suma/Suma.cpp | 2 +-
ndb/src/ndbapi/NdbConnection.cpp | 6 -
ndb/src/ndbapi/NdbConnectionScan.cpp | 24 +--
ndb/src/ndbapi/NdbScanOperation.cpp | 135 ++++++++++++-----
ndb/test/include/HugoTransactions.hpp | 16 +-
ndb/test/include/UtilTransactions.hpp | 4 +-
ndb/test/ndbapi/testScan.cpp | 9 +-
ndb/test/src/HugoTransactions.cpp | 170 ++++++++++++++++++++--
ndb/test/src/UtilTransactions.cpp | 23 +--
ndb/test/tools/create_index.cpp | 2 +-
ndb/test/tools/hugoScanRead.cpp | 50 ++++++-
ndb/tools/select_all.cpp | 7 +-
16 files changed, 439 insertions(+), 173 deletions(-)
diff --git a/ndb/src/kernel/blocks/dblqh/Dblqh.hpp b/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
index d6987f3e478..983fda9b7be 100644
--- a/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
+++ b/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
@@ -2925,4 +2925,23 @@ Dblqh::ScanRecord::check_scan_batch_completed() const
(max_bytes > 0 && (m_curr_batch_size_bytes >= max_bytes));
}
+inline
+void
+Dblqh::i_get_acc_ptr(ScanRecord* scanP, Uint32* &acc_ptr, Uint32 index)
+{
+ if (index == 0) {
+ acc_ptr= (Uint32*)&scanP->scan_acc_op_ptr[0];
+ } else {
+ Uint32 attr_buf_index, attr_buf_rec;
+
+ AttrbufPtr regAttrPtr;
+ jam();
+ attr_buf_rec= (index + 31) / 32;
+ attr_buf_index= (index - 1) & 31;
+ regAttrPtr.i= scanP->scan_acc_op_ptr[attr_buf_rec];
+ ptrCheckGuard(regAttrPtr, cattrinbufFileSize, attrbuf);
+ acc_ptr= (Uint32*)®AttrPtr.p->attrbuf[attr_buf_index];
+ }
+}
+
#endif
diff --git a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
index cd15ad0c3b2..e9e81d55488 100644
--- a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
+++ b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
@@ -7058,10 +7058,7 @@ void Dblqh::continueScanNextReqLab(Signal* signal)
// Update timer on tcConnectRecord
tcConnectptr.p->tcTimer = cLqhTimeOutCount;
-
init_acc_ptr_list(scanptr.p);
- scanptr.p->m_curr_batch_size_rows = 0;
- scanptr.p->m_curr_batch_size_bytes= 0;
scanptr.p->scanFlag = NextScanReq::ZSCAN_NEXT;
scanNextLoopLab(signal);
}//Dblqh::continueScanNextReqLab()
@@ -7260,22 +7257,32 @@ void Dblqh::scanLockReleasedLab(Signal* signal)
tcConnectptr.i = scanptr.p->scanTcrec;
ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
releaseActiveFrag(signal);
+
if (scanptr.p->scanReleaseCounter == scanptr.p->m_curr_batch_size_rows) {
if ((scanptr.p->scanErrorCounter > 0) ||
(scanptr.p->scanCompletedStatus == ZTRUE)) {
jam();
+ scanptr.p->m_curr_batch_size_rows = 0;
+ scanptr.p->m_curr_batch_size_bytes = 0;
closeScanLab(signal);
} else if (scanptr.p->check_scan_batch_completed() &&
scanptr.p->scanLockHold != ZTRUE) {
jam();
scanptr.p->scanState = ScanRecord::WAIT_SCAN_NEXTREQ;
sendScanFragConf(signal, ZFALSE);
+ } else if (scanptr.p->m_last_row && !scanptr.p->scanLockHold) {
+ jam();
+ closeScanLab(signal);
+ return;
} else {
jam();
/*
- We came here after releasing locks after receiving SCAN_NEXTREQ from TC. We only
- come here when scanHoldLock == ZTRUE
- */
+ * We came here after releasing locks after
+ * receiving SCAN_NEXTREQ from TC. We only come here
+ * when scanHoldLock == ZTRUE
+ */
+ scanptr.p->m_curr_batch_size_rows = 0;
+ scanptr.p->m_curr_batch_size_bytes = 0;
continueScanNextReqLab(signal);
}//if
} else if (scanptr.p->scanReleaseCounter < scanptr.p->m_curr_batch_size_rows) {
@@ -7362,25 +7369,6 @@ Dblqh::init_acc_ptr_list(ScanRecord* scanP)
scanP->scan_acc_index = 0;
}
-inline
-void
-Dblqh::i_get_acc_ptr(ScanRecord* scanP, Uint32* &acc_ptr, Uint32 index)
-{
- if (index == 0) {
- acc_ptr= (Uint32*)&scanP->scan_acc_op_ptr[0];
- } else {
- Uint32 attr_buf_index, attr_buf_rec;
-
- AttrbufPtr regAttrPtr;
- jam();
- attr_buf_rec= (index + 31) / 32;
- attr_buf_index= (index - 1) & 31;
- regAttrPtr.i= scanP->scan_acc_op_ptr[attr_buf_rec];
- ptrCheckGuard(regAttrPtr, cattrinbufFileSize, attrbuf);
- acc_ptr= (Uint32*)®AttrPtr.p->attrbuf[attr_buf_index];
- }
-}
-
Uint32
Dblqh::get_acc_ptr_from_scan_record(ScanRecord* scanP,
Uint32 index,
@@ -7904,6 +7892,13 @@ void Dblqh::nextScanConfScanLab(Signal* signal)
/*************************************************************
* STOP THE SCAN PROCESS IF THIS HAS BEEN REQUESTED.
************************************************************ */
+ if (!scanptr.p->scanLockHold)
+ {
+ jam();
+ closeScanLab(signal);
+ return;
+ }
+
if (scanptr.p->scanCompletedStatus == ZTRUE) {
if ((scanptr.p->scanLockHold == ZTRUE) &&
(scanptr.p->m_curr_batch_size_rows > 0)) {
@@ -8404,8 +8399,6 @@ void Dblqh::tupScanCloseConfLab(Signal* signal)
ScanFragRef::SignalLength, JBB);
} else {
jam();
- scanptr.p->m_curr_batch_size_rows = 0;
- scanptr.p->m_curr_batch_size_bytes= 0;
sendScanFragConf(signal, ZSCAN_FRAG_CLOSED);
}//if
finishScanrec(signal);
@@ -8809,6 +8802,13 @@ void Dblqh::sendScanFragConf(Signal* signal, Uint32 scanCompleted)
conf->total_len= total_len;
sendSignal(tcConnectptr.p->clientBlockref, GSN_SCAN_FRAGCONF,
signal, ScanFragConf::SignalLength, JBB);
+
+ if(!scanptr.p->scanLockHold)
+ {
+ jam();
+ scanptr.p->m_curr_batch_size_rows = 0;
+ scanptr.p->m_curr_batch_size_bytes= 0;
+ }
}//Dblqh::sendScanFragConf()
/* ######################################################################### */
diff --git a/ndb/src/kernel/blocks/dbtc/Dbtc.hpp b/ndb/src/kernel/blocks/dbtc/Dbtc.hpp
index a209df24c44..fb90ccc8c90 100644
--- a/ndb/src/kernel/blocks/dbtc/Dbtc.hpp
+++ b/ndb/src/kernel/blocks/dbtc/Dbtc.hpp
@@ -1054,9 +1054,8 @@ public:
// Id of the ScanRecord this fragment scan belongs to
Uint32 scanRec;
- // The maximum number of operations that can be scanned before
- // returning to TC
- Uint16 scanFragConcurrency;
+ // The value of fragmentCompleted in the last received SCAN_FRAGCONF
+ Uint8 m_scan_frag_conf_status;
inline void startFragTimer(Uint32 timeVal){
scanFragTimer = timeVal;
@@ -1193,8 +1192,10 @@ public:
// Number of operation records per scanned fragment
// Number of operations in first batch
// Max number of bytes per batch
- Uint16 noOprecPerFrag;
- Uint16 first_batch_size;
+ union {
+ Uint16 first_batch_size_rows;
+ Uint16 batch_size_rows;
+ };
Uint32 batch_byte_size;
Uint32 scanRequestInfo; // ScanFrag format
diff --git a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
index d8b3ee10532..c7f467484bd 100644
--- a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
+++ b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
@@ -8646,9 +8646,9 @@ void Dbtc::initScanrec(ScanRecordPtr scanptr,
scanptr.p->scanTableref = tabptr.i;
scanptr.p->scanSchemaVersion = scanTabReq->tableSchemaVersion;
scanptr.p->scanParallel = scanParallel;
- scanptr.p->noOprecPerFrag = noOprecPerFrag;
- scanptr.p->first_batch_size= scanTabReq->first_batch_size;
- scanptr.p->batch_byte_size= scanTabReq->batch_byte_size;
+ scanptr.p->first_batch_size_rows = scanTabReq->first_batch_size;
+ scanptr.p->batch_byte_size = scanTabReq->batch_byte_size;
+ scanptr.p->batch_size_rows = noOprecPerFrag;
Uint32 tmp = 0;
const UintR ri = scanTabReq->requestInfo;
@@ -8672,7 +8672,6 @@ void Dbtc::initScanrec(ScanRecordPtr scanptr,
ndbrequire(list.seize(ptr));
ptr.p->scanRec = scanptr.i;
ptr.p->scanFragId = 0;
- ptr.p->scanFragConcurrency = noOprecPerFrag;
ptr.p->m_apiPtr = cdata[i];
}//for
@@ -9141,6 +9140,7 @@ void Dbtc::execSCAN_FRAGCONF(Signal* signal)
const ScanFragConf * const conf = (ScanFragConf*)&signal->theData[0];
const Uint32 noCompletedOps = conf->completedOps;
+ const Uint32 status = conf->fragmentCompleted;
scanFragptr.i = conf->senderData;
c_scan_frag_pool.getPtr(scanFragptr);
@@ -9163,11 +9163,9 @@ void Dbtc::execSCAN_FRAGCONF(Signal* signal)
ndbrequire(scanFragptr.p->scanFragState == ScanFragRec::LQH_ACTIVE);
- const Uint32 status = conf->fragmentCompleted;
-
if(scanptr.p->scanState == ScanRecord::CLOSING_SCAN){
jam();
- if(status == ZFALSE){
+ if(status == 0){
/**
* We have started closing = we sent a close -> ignore this
*/
@@ -9184,11 +9182,11 @@ void Dbtc::execSCAN_FRAGCONF(Signal* signal)
return;
}
- if(status == ZCLOSED && scanptr.p->scanNextFragId < scanptr.p->scanNoFrag){
+ if(noCompletedOps == 0 && status != 0 &&
+ scanptr.p->scanNextFragId < scanptr.p->scanNoFrag){
/**
* Start on next fragment
*/
- ndbrequire(noCompletedOps == 0);
scanFragptr.p->scanFragState = ScanFragRec::WAIT_GET_PRIMCONF;
scanFragptr.p->startFragTimer(ctcTimer);
@@ -9218,6 +9216,7 @@ void Dbtc::execSCAN_FRAGCONF(Signal* signal)
scanptr.p->m_queued_count++;
}
+ scanFragptr.p->m_scan_frag_conf_status = status;
scanFragptr.p->m_ops = noCompletedOps;
scanFragptr.p->m_totalLen = total_len;
scanFragptr.p->scanFragState = ScanFragRec::QUEUED_FOR_DELIVERY;
@@ -9330,11 +9329,12 @@ void Dbtc::execSCAN_NEXTREQ(Signal* signal)
// Copy op ptrs so I dont overwrite them when sending...
memcpy(signal->getDataPtrSend()+25, signal->getDataPtr()+4, 4 * len);
- ScanFragNextReq * nextReq = (ScanFragNextReq*)&signal->theData[0];
- nextReq->closeFlag = ZFALSE;
- nextReq->transId1 = apiConnectptr.p->transid[0];
- nextReq->transId2 = apiConnectptr.p->transid[1];
- nextReq->batch_size_bytes= scanP->batch_byte_size;
+ ScanFragNextReq tmp;
+ tmp.closeFlag = ZFALSE;
+ tmp.transId1 = apiConnectptr.p->transid[0];
+ tmp.transId2 = apiConnectptr.p->transid[1];
+ tmp.batch_size_rows = scanP->batch_size_rows;
+ tmp.batch_size_bytes = scanP->batch_byte_size;
ScanFragList running(c_scan_frag_pool, scanP->m_running_scan_frags);
ScanFragList delivered(c_scan_frag_pool, scanP->m_delivered_scan_frags);
@@ -9344,15 +9344,37 @@ void Dbtc::execSCAN_NEXTREQ(Signal* signal)
c_scan_frag_pool.getPtr(scanFragptr);
ndbrequire(scanFragptr.p->scanFragState == ScanFragRec::DELIVERED);
- scanFragptr.p->scanFragState = ScanFragRec::LQH_ACTIVE;
scanFragptr.p->startFragTimer(ctcTimer);
-
scanFragptr.p->m_ops = 0;
- nextReq->senderData = scanFragptr.i;
- nextReq->batch_size_rows= scanFragptr.p->scanFragConcurrency;
- sendSignal(scanFragptr.p->lqhBlockref, GSN_SCAN_NEXTREQ, signal,
- ScanFragNextReq::SignalLength, JBB);
+ if(scanFragptr.p->m_scan_frag_conf_status)
+ {
+ /**
+ * last scan was complete
+ */
+ jam();
+ ndbrequire(scanptr.p->scanNextFragId < scanptr.p->scanNoFrag);
+ scanFragptr.p->scanFragState = ScanFragRec::WAIT_GET_PRIMCONF;
+
+ tcConnectptr.i = scanptr.p->scanTcrec;
+ ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
+ scanFragptr.p->scanFragId = scanptr.p->scanNextFragId++;
+ signal->theData[0] = tcConnectptr.p->dihConnectptr;
+ signal->theData[1] = scanFragptr.i;
+ signal->theData[2] = scanptr.p->scanTableref;
+ signal->theData[3] = scanFragptr.p->scanFragId;
+ sendSignal(cdihblockref, GSN_DIGETPRIMREQ, signal, 4, JBB);
+ }
+ else
+ {
+ jam();
+ scanFragptr.p->scanFragState = ScanFragRec::LQH_ACTIVE;
+ ScanFragNextReq * req = (ScanFragNextReq*)signal->getDataPtrSend();
+ * req = tmp;
+ req->senderData = scanFragptr.i;
+ sendSignal(scanFragptr.p->lqhBlockref, GSN_SCAN_NEXTREQ, signal,
+ ScanFragNextReq::SignalLength, JBB);
+ }
delivered.remove(scanFragptr);
running.add(scanFragptr);
}//for
@@ -9551,7 +9573,7 @@ void Dbtc::sendScanFragReq(Signal* signal,
req->transId1 = apiConnectptr.p->transid[0];
req->transId2 = apiConnectptr.p->transid[1];
req->clientOpPtr = scanFragP->m_apiPtr;
- req->batch_size_rows= scanFragP->scanFragConcurrency;
+ req->batch_size_rows= scanP->batch_size_rows;
req->batch_size_bytes= scanP->batch_byte_size;
sendSignal(scanFragP->lqhBlockref, GSN_SCAN_FRAGREQ, signal,
ScanFragReq::SignalLength, JBB);
@@ -9573,6 +9595,8 @@ void Dbtc::sendScanTabConf(Signal* signal, ScanRecordPtr scanPtr) {
jam();
ops += 21;
}
+
+ Uint32 left = scanPtr.p->scanNoFrag - scanPtr.p->scanNextFragId;
ScanTabConf * conf = (ScanTabConf*)&signal->theData[0];
conf->apiConnectPtr = apiConnectptr.p->ndbapiConnect;
@@ -9588,24 +9612,25 @@ void Dbtc::sendScanTabConf(Signal* signal, ScanRecordPtr scanPtr) {
ScanFragRecPtr curr = ptr; // Remove while iterating...
queued.next(ptr);
+ bool done = curr.p->m_scan_frag_conf_status && --left;
+
* ops++ = curr.p->m_apiPtr;
- * ops++ = curr.i;
+ * ops++ = done ? RNIL : curr.i;
* ops++ = (curr.p->m_totalLen << 10) + curr.p->m_ops;
queued.remove(curr);
- if(curr.p->m_ops > 0){
+ if(!done){
delivered.add(curr);
curr.p->scanFragState = ScanFragRec::DELIVERED;
curr.p->stopFragTimer();
} else {
- (* --ops) = ScanTabConf::EndOfData; ops++;
c_scan_frag_pool.release(curr);
curr.p->scanFragState = ScanFragRec::COMPLETED;
curr.p->stopFragTimer();
}
}
}
-
+
if(scanPtr.p->m_delivered_scan_frags.isEmpty() &&
scanPtr.p->m_running_scan_frags.isEmpty()){
conf->requestInfo = op_count | ScanTabConf::EndOfData;
@@ -10424,9 +10449,8 @@ Dbtc::execDUMP_STATE_ORD(Signal* signal)
sfp.i,
sfp.p->scanFragState,
sfp.p->scanFragId);
- infoEvent(" nodeid=%d, concurr=%d, timer=%d",
+ infoEvent(" nodeid=%d, timer=%d",
refToNode(sfp.p->lqhBlockref),
- sfp.p->scanFragConcurrency,
sfp.p->scanFragTimer);
}
@@ -10504,7 +10528,7 @@ Dbtc::execDUMP_STATE_ORD(Signal* signal)
sp.p->scanAiLength,
sp.p->scanParallel,
sp.p->scanReceivedOperations,
- sp.p->noOprecPerFrag);
+ sp.p->batch_size_rows);
infoEvent(" schv=%d, tab=%d, sproc=%d",
sp.p->scanSchemaVersion,
sp.p->scanTableref,
diff --git a/ndb/src/kernel/blocks/suma/Suma.cpp b/ndb/src/kernel/blocks/suma/Suma.cpp
index d11d5f7176a..f6d9a0ac35a 100644
--- a/ndb/src/kernel/blocks/suma/Suma.cpp
+++ b/ndb/src/kernel/blocks/suma/Suma.cpp
@@ -1888,7 +1888,7 @@ SumaParticipant::SyncRecord::nextScan(Signal* signal){
req->requestInfo = 0;
req->savePointId = 0;
ScanFragReq::setLockMode(req->requestInfo, 0);
- ScanFragReq::setHoldLockFlag(req->requestInfo, 0);
+ ScanFragReq::setHoldLockFlag(req->requestInfo, 1);
ScanFragReq::setKeyinfoFlag(req->requestInfo, 0);
ScanFragReq::setAttrLen(req->requestInfo, attrLen);
req->fragmentNoKeyLen = fd.m_fragDesc.m_fragmentNo;
diff --git a/ndb/src/ndbapi/NdbConnection.cpp b/ndb/src/ndbapi/NdbConnection.cpp
index c21a85fd24d..aecc7124d15 100644
--- a/ndb/src/ndbapi/NdbConnection.cpp
+++ b/ndb/src/ndbapi/NdbConnection.cpp
@@ -1577,9 +1577,6 @@ from other transactions.
/**
* There's always a TCKEYCONF when using IgnoreError
*/
-#ifdef VM_TRACE
- ndbout_c("Not completing transaction 2");
-#endif
return -1;
}
/**********************************************************************/
@@ -1831,9 +1828,6 @@ NdbConnection::OpCompleteFailure(Uint8 abortOption, bool setFailure)
/**
* There's always a TCKEYCONF when using IgnoreError
*/
-#ifdef VM_TRACE
- ndbout_c("Not completing transaction");
-#endif
return -1;
}
diff --git a/ndb/src/ndbapi/NdbConnectionScan.cpp b/ndb/src/ndbapi/NdbConnectionScan.cpp
index 3fe8993a42b..a7a8f1350b1 100644
--- a/ndb/src/ndbapi/NdbConnectionScan.cpp
+++ b/ndb/src/ndbapi/NdbConnectionScan.cpp
@@ -97,7 +97,7 @@ NdbConnection::receiveSCAN_TABCONF(NdbApiSignal* aSignal,
theScanningOp->execCLOSE_SCAN_REP();
return 0;
}
-
+
for(Uint32 i = 0; iint2void(ptrI);
assert(tPtr); // For now
NdbReceiver* tOp = theNdb->void2rec(tPtr);
- if (tOp && tOp->checkMagicNumber()){
- if(tOp->execSCANOPCONF(tcPtrI, totalLen, opCount)){
- /**
- *
- */
- theScanningOp->receiver_delivered(tOp);
- } else if(info == ScanTabConf::EndOfData){
+ if (tOp && tOp->checkMagicNumber())
+ {
+ if (tcPtrI == RNIL && opCount == 0)
theScanningOp->receiver_completed(tOp);
- }
- }
- }
- if (conf->requestInfo & ScanTabConf::EndOfData) {
- if(theScanningOp->m_ordered)
- theScanningOp->m_api_receivers_count = 0;
- if(theScanningOp->m_api_receivers_count +
- theScanningOp->m_conf_receivers_count +
- theScanningOp->m_sent_receivers_count){
- abort();
+ else if (tOp->execSCANOPCONF(tcPtrI, totalLen, opCount))
+ theScanningOp->receiver_delivered(tOp);
}
}
return 0;
diff --git a/ndb/src/ndbapi/NdbScanOperation.cpp b/ndb/src/ndbapi/NdbScanOperation.cpp
index 373fec1a2b0..30b596d7098 100644
--- a/ndb/src/ndbapi/NdbScanOperation.cpp
+++ b/ndb/src/ndbapi/NdbScanOperation.cpp
@@ -35,6 +35,8 @@
#include
#include
+#define DEBUG_NEXT_RESULT 0
+
NdbScanOperation::NdbScanOperation(Ndb* aNdb) :
NdbOperation(aNdb),
m_resultSet(0),
@@ -275,6 +277,9 @@ NdbScanOperation::fix_receivers(Uint32 parallel){
void
NdbScanOperation::receiver_delivered(NdbReceiver* tRec){
if(theError.code == 0){
+ if(DEBUG_NEXT_RESULT)
+ ndbout_c("receiver_delivered");
+
Uint32 idx = tRec->m_list_index;
Uint32 last = m_sent_receivers_count - 1;
if(idx != last){
@@ -298,6 +303,9 @@ NdbScanOperation::receiver_delivered(NdbReceiver* tRec){
void
NdbScanOperation::receiver_completed(NdbReceiver* tRec){
if(theError.code == 0){
+ if(DEBUG_NEXT_RESULT)
+ ndbout_c("receiver_completed");
+
Uint32 idx = tRec->m_list_index;
Uint32 last = m_sent_receivers_count - 1;
if(idx != last){
@@ -445,8 +453,6 @@ NdbScanOperation::executeCursor(int nodeId){
return -1;
}
-#define DEBUG_NEXT_RESULT 0
-
int NdbScanOperation::nextResult(bool fetchAllowed)
{
if(m_ordered)
@@ -579,7 +585,8 @@ int NdbScanOperation::nextResult(bool fetchAllowed)
int
NdbScanOperation::send_next_scan(Uint32 cnt, bool stopScanFlag){
- if(cnt > 0 || stopScanFlag){
+ if(cnt > 0)
+ {
NdbApiSignal tSignal(theNdb->theMyRef);
tSignal.setSignal(GSN_SCAN_NEXTREQ);
@@ -595,33 +602,40 @@ NdbScanOperation::send_next_scan(Uint32 cnt, bool stopScanFlag){
*/
Uint32 last = m_sent_receivers_count;
Uint32 * prep_array = (cnt > 21 ? m_prepared_receivers : theData + 4);
+ Uint32 sent = 0;
for(Uint32 i = 0; im_list_index = last+i;
- prep_array[i] = tRec->m_tcPtrI;
- tRec->prepareSend();
+ if((prep_array[sent] = tRec->m_tcPtrI) != RNIL)
+ {
+ m_sent_receivers[last+sent] = tRec;
+ tRec->m_list_index = last+sent;
+ tRec->prepareSend();
+ sent++;
+ }
}
memcpy(&m_api_receivers[0], &m_api_receivers[cnt], cnt * sizeof(char*));
- Uint32 nodeId = theNdbCon->theDBnode;
- TransporterFacade * tp = TransporterFacade::instance();
- int ret;
- if(cnt > 21){
- tSignal.setLength(4);
- LinearSectionPtr ptr[3];
- ptr[0].p = prep_array;
- ptr[0].sz = cnt;
- ret = tp->sendSignal(&tSignal, nodeId, ptr, 1);
- } else {
- tSignal.setLength(4+cnt);
- ret = tp->sendSignal(&tSignal, nodeId);
+ int ret = 0;
+ if(sent)
+ {
+ Uint32 nodeId = theNdbCon->theDBnode;
+ TransporterFacade * tp = TransporterFacade::instance();
+ if(cnt > 21 && !stopScanFlag){
+ tSignal.setLength(4);
+ LinearSectionPtr ptr[3];
+ ptr[0].p = prep_array;
+ ptr[0].sz = sent;
+ ret = tp->sendSignal(&tSignal, nodeId, ptr, 1);
+ } else {
+ tSignal.setLength(4+(stopScanFlag ? 0 : sent));
+ ret = tp->sendSignal(&tSignal, nodeId);
+ }
}
-
- m_sent_receivers_count = last + cnt + stopScanFlag;
+
+ m_sent_receivers_count = last + sent;
m_api_receivers_count -= cnt;
m_current_api_receiver = 0;
-
+
return ret;
}
return 0;
@@ -1412,10 +1426,22 @@ NdbIndexScanOperation::send_next_scan_ordered(Uint32 idx){
if(idx == theParallelism)
return 0;
+ NdbReceiver* tRec = m_api_receivers[idx];
NdbApiSignal tSignal(theNdb->theMyRef);
tSignal.setSignal(GSN_SCAN_NEXTREQ);
+ Uint32 last = m_sent_receivers_count;
Uint32* theData = tSignal.getDataPtrSend();
+ Uint32* prep_array = theData + 4;
+
+ m_current_api_receiver = idx + 1;
+ if((prep_array[0] = tRec->m_tcPtrI) == RNIL)
+ {
+ if(DEBUG_NEXT_RESULT)
+ ndbout_c("receiver completed, don't send");
+ return 0;
+ }
+
theData[0] = theNdbCon->theTCConPtr;
theData[1] = 0;
Uint64 transId = theNdbCon->theTransactionId;
@@ -1425,17 +1451,10 @@ NdbIndexScanOperation::send_next_scan_ordered(Uint32 idx){
/**
* Prepare ops
*/
- Uint32 last = m_sent_receivers_count;
- Uint32 * prep_array = theData + 4;
-
- NdbReceiver * tRec = m_api_receivers[idx];
m_sent_receivers[last] = tRec;
tRec->m_list_index = last;
- prep_array[0] = tRec->m_tcPtrI;
tRec->prepareSend();
-
m_sent_receivers_count = last + 1;
- m_current_api_receiver = idx + 1;
Uint32 nodeId = theNdbCon->theDBnode;
TransporterFacade * tp = TransporterFacade::instance();
@@ -1448,12 +1467,17 @@ NdbScanOperation::close_impl(TransporterFacade* tp){
Uint32 seq = theNdbCon->theNodeSequence;
Uint32 nodeId = theNdbCon->theDBnode;
- if(seq != tp->getNodeSequence(nodeId)){
+ if(seq != tp->getNodeSequence(nodeId))
+ {
theNdbCon->theReleaseOnClose = true;
return -1;
}
- while(theError.code == 0 && m_sent_receivers_count){
+ /**
+ * Wait for outstanding
+ */
+ while(theError.code == 0 && m_sent_receivers_count)
+ {
theNdb->theWaiter.m_node = nodeId;
theNdb->theWaiter.m_state = WAIT_SCAN;
int return_code = theNdb->receiveResponse(WAITFOR_SCAN_TIMEOUT);
@@ -1471,18 +1495,52 @@ NdbScanOperation::close_impl(TransporterFacade* tp){
}
}
- if(m_api_receivers_count+m_conf_receivers_count){
- // Send close scan
- if(send_next_scan(0, true) == -1){ // Close scan
- theNdbCon->theReleaseOnClose = true;
- return -1;
- }
+ /**
+ * move all conf'ed into api
+ * so that send_next_scan can check if they needs to be closed
+ */
+ Uint32 api = m_api_receivers_count;
+ Uint32 conf = m_conf_receivers_count;
+
+ if(m_ordered)
+ {
+ /**
+ * Ordered scan, keep the m_api_receivers "to the right"
+ */
+ memmove(m_api_receivers, m_api_receivers+m_current_api_receiver,
+ (theParallelism - m_current_api_receiver) * sizeof(char*));
+ api = (theParallelism - m_current_api_receiver);
+ m_api_receivers_count = api;
+ }
+
+ if(DEBUG_NEXT_RESULT)
+ ndbout_c("close_impl: [order api conf sent curr parr] %d %d %d %d %d %d",
+ m_ordered, api, conf,
+ m_sent_receivers_count, m_current_api_receiver, theParallelism);
+
+ if(api+conf)
+ {
+ /**
+ * There's something to close
+ * setup m_api_receivers (for send_next_scan)
+ */
+ memcpy(m_api_receivers+api, m_conf_receivers, conf * sizeof(char*));
+ m_api_receivers_count = api + conf;
+ m_conf_receivers_count = 0;
+ }
+
+ // Send close scan
+ if(send_next_scan(api+conf, true) == -1)
+ {
+ theNdbCon->theReleaseOnClose = true;
+ return -1;
}
/**
* wait for close scan conf
*/
- while(m_sent_receivers_count+m_api_receivers_count+m_conf_receivers_count){
+ while(m_sent_receivers_count+m_api_receivers_count+m_conf_receivers_count)
+ {
theNdb->theWaiter.m_node = nodeId;
theNdb->theWaiter.m_state = WAIT_SCAN;
int return_code = theNdb->receiveResponse(WAITFOR_SCAN_TIMEOUT);
@@ -1499,6 +1557,7 @@ NdbScanOperation::close_impl(TransporterFacade* tp){
return -1;
}
}
+
return 0;
}
diff --git a/ndb/test/include/HugoTransactions.hpp b/ndb/test/include/HugoTransactions.hpp
index 19e4cb43336..b833f2ac629 100644
--- a/ndb/test/include/HugoTransactions.hpp
+++ b/ndb/test/include/HugoTransactions.hpp
@@ -36,15 +36,21 @@ public:
bool allowConstraintViolation = true,
int doSleep = 0,
bool oneTrans = false);
+
int scanReadRecords(Ndb*,
int records,
int abort = 0,
int parallelism = 0,
- bool committed = false);
- int scanReadCommittedRecords(Ndb*,
- int records,
- int abort = 0,
- int parallelism = 0);
+ NdbOperation::LockMode = NdbOperation::LM_Read);
+
+ int scanReadRecords(Ndb*,
+ const NdbDictionary::Index*,
+ int records,
+ int abort = 0,
+ int parallelism = 0,
+ NdbOperation::LockMode = NdbOperation::LM_Read,
+ bool sorted = false);
+
int pkReadRecords(Ndb*,
int records,
int batchsize = 1,
diff --git a/ndb/test/include/UtilTransactions.hpp b/ndb/test/include/UtilTransactions.hpp
index 37cd99550a5..23902f3b317 100644
--- a/ndb/test/include/UtilTransactions.hpp
+++ b/ndb/test/include/UtilTransactions.hpp
@@ -53,11 +53,11 @@ public:
int selectCount(Ndb*,
int parallelism = 0,
int* count_rows = NULL,
- ScanLock lock = SL_Read,
+ NdbOperation::LockMode lm = NdbOperation::LM_CommittedRead,
NdbConnection* pTrans = NULL);
int scanReadRecords(Ndb*,
int parallelism,
- bool exclusive,
+ NdbOperation::LockMode lm,
int records,
int noAttribs,
int* attrib_list,
diff --git a/ndb/test/ndbapi/testScan.cpp b/ndb/test/ndbapi/testScan.cpp
index 0cd30dfefde..51913e8fbf9 100644
--- a/ndb/test/ndbapi/testScan.cpp
+++ b/ndb/test/ndbapi/testScan.cpp
@@ -242,8 +242,9 @@ int runScanReadCommitted(NDBT_Context* ctx, NDBT_Step* step){
HugoTransactions hugoTrans(*ctx->getTab());
while (iisTestStopped()) {
g_info << i << ": ";
- if (hugoTrans.scanReadCommittedRecords(GETNDB(step), records,
- abort, parallelism) != 0){
+ if (hugoTrans.scanReadRecords(GETNDB(step), records,
+ abort, parallelism,
+ NdbOperation::LM_CommittedRead) != 0){
return NDBT_FAILED;
}
i++;
@@ -639,7 +640,7 @@ int runCheckGetValue(NDBT_Context* ctx, NDBT_Step* step){
g_info << (unsigned)i << endl;
if(utilTrans.scanReadRecords(GETNDB(step),
parallelism,
- false,
+ NdbOperation::LM_Read,
records,
alist.attriblist[i]->numAttribs,
alist.attriblist[i]->attribs) != 0){
@@ -647,7 +648,7 @@ int runCheckGetValue(NDBT_Context* ctx, NDBT_Step* step){
}
if(utilTrans.scanReadRecords(GETNDB(step),
parallelism,
- true,
+ NdbOperation::LM_Read,
records,
alist.attriblist[i]->numAttribs,
alist.attriblist[i]->attribs) != 0){
diff --git a/ndb/test/src/HugoTransactions.cpp b/ndb/test/src/HugoTransactions.cpp
index 456bfffbb77..096f5406bbf 100644
--- a/ndb/test/src/HugoTransactions.cpp
+++ b/ndb/test/src/HugoTransactions.cpp
@@ -29,20 +29,13 @@ HugoTransactions::~HugoTransactions(){
deallocRows();
}
-
-int HugoTransactions::scanReadCommittedRecords(Ndb* pNdb,
- int records,
- int abortPercent,
- int parallelism){
- return scanReadRecords(pNdb, records, abortPercent, parallelism, true);
-}
-
int
HugoTransactions::scanReadRecords(Ndb* pNdb,
int records,
int abortPercent,
int parallelism,
- bool committed){
+ NdbOperation::LockMode lm)
+{
int retryAttempt = 0;
const int retryMax = 100;
@@ -80,8 +73,163 @@ HugoTransactions::scanReadRecords(Ndb* pNdb,
}
NdbResultSet * rs;
- rs = pOp ->readTuples(committed ? NdbScanOperation::LM_CommittedRead :
- NdbScanOperation::LM_Read);
+ rs = pOp ->readTuples(lm);
+
+ if( rs == 0 ) {
+ ERR(pTrans->getNdbError());
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+ check = pOp->interpret_exit_ok();
+ if( check == -1 ) {
+ ERR(pTrans->getNdbError());
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+ for(a = 0; agetValue(tab.getColumn(a)->getName())) == 0) {
+ ERR(pTrans->getNdbError());
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+ }
+
+ check = pTrans->execute(NoCommit);
+ if( check == -1 ) {
+ const NdbError err = pTrans->getNdbError();
+ if (err.status == NdbError::TemporaryError){
+ ERR(err);
+ pNdb->closeTransaction(pTrans);
+ NdbSleep_MilliSleep(50);
+ retryAttempt++;
+ continue;
+ }
+ ERR(err);
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+ // Abort after 1-100 or 1-records rows
+ int ranVal = rand();
+ int abortCount = ranVal % (records == 0 ? 100 : records);
+ bool abortTrans = false;
+ if (abort > 0){
+ // Abort if abortCount is less then abortPercent
+ if (abortCount < abortPercent)
+ abortTrans = true;
+ }
+
+ int eof;
+ int rows = 0;
+ while((eof = rs->nextResult(true)) == 0){
+ rows++;
+ if (calc.verifyRowValues(&row) != 0){
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+ if (abortCount == rows && abortTrans == true){
+ ndbout << "Scan is aborted" << endl;
+ g_info << "Scan is aborted" << endl;
+ rs->close();
+ if( check == -1 ) {
+ ERR(pTrans->getNdbError());
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+ pNdb->closeTransaction(pTrans);
+ return NDBT_OK;
+ }
+ }
+ if (eof == -1) {
+ const NdbError err = pTrans->getNdbError();
+
+ if (err.status == NdbError::TemporaryError){
+ ERR_INFO(err);
+ pNdb->closeTransaction(pTrans);
+ NdbSleep_MilliSleep(50);
+ switch (err.code){
+ case 488:
+ case 245:
+ case 490:
+ // Too many active scans, no limit on number of retry attempts
+ break;
+ default:
+ retryAttempt++;
+ }
+ continue;
+ }
+ ERR(err);
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+ pNdb->closeTransaction(pTrans);
+
+ g_info << rows << " rows have been read" << endl;
+ if (records != 0 && rows != records){
+ g_err << "Check expected number of records failed" << endl
+ << " expected=" << records <<", " << endl
+ << " read=" << rows << endl;
+ return NDBT_FAILED;
+ }
+
+ return NDBT_OK;
+ }
+ return NDBT_FAILED;
+}
+
+int
+HugoTransactions::scanReadRecords(Ndb* pNdb,
+ const NdbDictionary::Index * pIdx,
+ int records,
+ int abortPercent,
+ int parallelism,
+ NdbOperation::LockMode lm,
+ bool sorted)
+{
+
+ int retryAttempt = 0;
+ const int retryMax = 100;
+ int check, a;
+ NdbConnection *pTrans;
+ NdbIndexScanOperation *pOp;
+
+ while (true){
+
+ if (retryAttempt >= retryMax){
+ g_err << "ERROR: has retried this operation " << retryAttempt
+ << " times, failing!" << endl;
+ return NDBT_FAILED;
+ }
+
+ pTrans = pNdb->startTransaction();
+ if (pTrans == NULL) {
+ const NdbError err = pNdb->getNdbError();
+
+ if (err.status == NdbError::TemporaryError){
+ ERR(err);
+ NdbSleep_MilliSleep(50);
+ retryAttempt++;
+ continue;
+ }
+ ERR(err);
+ return NDBT_FAILED;
+ }
+
+ pOp = pTrans->getNdbIndexScanOperation(pIdx->getName(), tab.getName());
+ if (pOp == NULL) {
+ ERR(pTrans->getNdbError());
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+ NdbResultSet * rs;
+ rs = pOp ->readTuples(lm, 0, parallelism, sorted);
if( rs == 0 ) {
ERR(pTrans->getNdbError());
diff --git a/ndb/test/src/UtilTransactions.cpp b/ndb/test/src/UtilTransactions.cpp
index c0e6effd244..869f7fc76cb 100644
--- a/ndb/test/src/UtilTransactions.cpp
+++ b/ndb/test/src/UtilTransactions.cpp
@@ -619,7 +619,7 @@ UtilTransactions::addRowToInsert(Ndb* pNdb,
int
UtilTransactions::scanReadRecords(Ndb* pNdb,
int parallelism,
- bool exclusive,
+ NdbOperation::LockMode lm,
int records,
int noAttribs,
int *attrib_list,
@@ -669,10 +669,7 @@ UtilTransactions::scanReadRecords(Ndb* pNdb,
return NDBT_FAILED;
}
- NdbResultSet * rs = pOp->readTuples(exclusive ?
- NdbScanOperation::LM_Exclusive :
- NdbScanOperation::LM_Read,
- 0, parallelism);
+ NdbResultSet * rs = pOp->readTuples(lm, 0, parallelism);
if( rs == 0 ) {
ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans);
@@ -761,7 +758,7 @@ int
UtilTransactions::selectCount(Ndb* pNdb,
int parallelism,
int* count_rows,
- ScanLock lock,
+ NdbOperation::LockMode lm,
NdbConnection* pTrans){
int retryAttempt = 0;
@@ -785,19 +782,7 @@ UtilTransactions::selectCount(Ndb* pNdb,
return NDBT_FAILED;
}
- NdbResultSet * rs;
- switch(lock){
- case SL_ReadHold:
- rs = pOp->readTuples(NdbScanOperation::LM_Read);
- break;
- case SL_Exclusive:
- rs = pOp->readTuples(NdbScanOperation::LM_Exclusive);
- break;
- case SL_Read:
- default:
- rs = pOp->readTuples(NdbScanOperation::LM_CommittedRead);
- }
-
+ NdbResultSet * rs = pOp->readTuples(lm);
if( rs == 0) {
ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans);
diff --git a/ndb/test/tools/create_index.cpp b/ndb/test/tools/create_index.cpp
index 75a657522f6..6e4c5377f4a 100644
--- a/ndb/test/tools/create_index.cpp
+++ b/ndb/test/tools/create_index.cpp
@@ -30,7 +30,7 @@ main(int argc, const char** argv){
const char* _dbname = "TEST_DB";
int _help = 0;
- int _ordered, _pk;
+ int _ordered = 0, _pk = 1;
struct getargs args[] = {
{ "database", 'd', arg_string, &_dbname, "dbname",
diff --git a/ndb/test/tools/hugoScanRead.cpp b/ndb/test/tools/hugoScanRead.cpp
index cdfdcea4654..42180207a8a 100644
--- a/ndb/test/tools/hugoScanRead.cpp
+++ b/ndb/test/tools/hugoScanRead.cpp
@@ -35,13 +35,17 @@ int main(int argc, const char** argv){
int _parallelism = 1;
const char* _tabname = NULL;
int _help = 0;
-
+ int lock = NdbOperation::LM_Read;
+ int sorted = 0;
+
struct getargs args[] = {
{ "aborts", 'a', arg_integer, &_abort, "percent of transactions that are aborted", "abort%" },
{ "loops", 'l', arg_integer, &_loops, "number of times to run this program(0=infinite loop)", "loops" },
{ "parallelism", 'p', arg_integer, &_parallelism, "parallelism(1-240)", "para" },
{ "records", 'r', arg_integer, &_records, "Number of records", "recs" },
- { "usage", '?', arg_flag, &_help, "Print help", "" }
+ { "usage", '?', arg_flag, &_help, "Print help", "" },
+ { "lock", 'm', arg_integer, &lock, "lock mode", "" },
+ { "sorted", 's', arg_flag, &sorted, "sorted", "" }
};
int num_args = sizeof(args) / sizeof(args[0]);
int optind = 0;
@@ -73,16 +77,48 @@ int main(int argc, const char** argv){
ndbout << " Table " << _tabname << " does not exist!" << endl;
return NDBT_ProgramExit(NDBT_WRONGARGS);
}
+
+ const NdbDictionary::Index * pIdx = 0;
+ if(optind+1 < argc)
+ {
+ pIdx = MyNdb.getDictionary()->getIndex(argv[optind+1], _tabname);
+ if(!pIdx)
+ ndbout << " Index " << argv[optind+1] << " not found" << endl;
+ else
+ if(pIdx->getType() != NdbDictionary::Index::UniqueOrderedIndex &&
+ pIdx->getType() != NdbDictionary::Index::OrderedIndex)
+ {
+ ndbout << " Index " << argv[optind+1] << " is not scannable" << endl;
+ pIdx = 0;
+ }
+ }
HugoTransactions hugoTrans(*pTab);
int i = 0;
while (i<_loops || _loops==0) {
ndbout << i << ": ";
- if(hugoTrans.scanReadRecords(&MyNdb,
- 0,
- _abort,
- _parallelism) != 0){
- return NDBT_ProgramExit(NDBT_FAILED);
+ if(!pIdx)
+ {
+ if(hugoTrans.scanReadRecords(&MyNdb,
+ 0,
+ _abort,
+ _parallelism,
+ (NdbOperation::LockMode)lock) != 0)
+ {
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+ }
+ else
+ {
+ if(hugoTrans.scanReadRecords(&MyNdb, pIdx,
+ 0,
+ _abort,
+ _parallelism,
+ (NdbOperation::LockMode)lock,
+ sorted) != 0)
+ {
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
}
i++;
}
diff --git a/ndb/tools/select_all.cpp b/ndb/tools/select_all.cpp
index 758c1e48c88..9c944c8c93e 100644
--- a/ndb/tools/select_all.cpp
+++ b/ndb/tools/select_all.cpp
@@ -133,13 +133,18 @@ int main(int argc, char** argv){
const NdbDictionary::Table* pTab = NDBT_Table::discoverTableFromDb(&MyNdb, _tabname);
const NdbDictionary::Index * pIdx = 0;
if(argc > 1){
- pIdx = MyNdb.getDictionary()->getIndex(argv[0], _tabname);
+ pIdx = MyNdb.getDictionary()->getIndex(argv[1], _tabname);
}
if(pTab == NULL){
ndbout << " Table " << _tabname << " does not exist!" << endl;
return NDBT_ProgramExit(NDBT_WRONGARGS);
}
+
+ if(argc > 1 && pIdx == 0)
+ {
+ ndbout << " Index " << argv[1] << " does not exists" << endl;
+ }
if(_order && pIdx == NULL){
ndbout << " Order flag given without an index" << endl;
From 3f369106390a7a57d6c07e438f85fa804db7248f Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Thu, 18 Nov 2004 20:28:36 +0000
Subject: [PATCH 030/145] fix for mysqladmin link problem .c -> .cc
fix source dist problem for ndb fix type check problem for mysqladmin
---
client/Makefile.am | 1 +
client/{mysqladmin.c => mysqladmin.cc} | 3 ---
configure.in | 1 -
ndb/include/Makefile.am | 1 +
ndb/src/mgmclient/CommandInterpreter.cpp | 4 ++--
ndb/src/mgmclient/ndb_mgmclient.h | 2 +-
ndb/src/mgmclient/ndb_mgmclient.hpp | 2 +-
7 files changed, 6 insertions(+), 8 deletions(-)
rename client/{mysqladmin.c => mysqladmin.cc} (99%)
diff --git a/client/Makefile.am b/client/Makefile.am
index 1c552036f9b..5034dd5bf51 100644
--- a/client/Makefile.am
+++ b/client/Makefile.am
@@ -27,6 +27,7 @@ bin_PROGRAMS = mysql mysqladmin mysqlcheck mysqlshow \
mysqldump mysqlimport mysqltest mysqlbinlog mysqlmanagerc mysqlmanager-pwgen
noinst_HEADERS = sql_string.h completion_hash.h my_readline.h \
client_priv.h
+mysqladmin_SOURCES = mysqladmin.cc
mysql_SOURCES = mysql.cc readline.cc sql_string.cc completion_hash.cc
mysql_LDADD = @readline_link@ @TERMCAP_LIB@ $(LDADD) $(CXXLDFLAGS)
mysqlbinlog_LDADD = $(LDADD) $(CXXLDFLAGS)
diff --git a/client/mysqladmin.c b/client/mysqladmin.cc
similarity index 99%
rename from client/mysqladmin.c
rename to client/mysqladmin.cc
index a32dfa14d28..a9fc3f31d03 100644
--- a/client/mysqladmin.c
+++ b/client/mysqladmin.cc
@@ -1287,9 +1287,6 @@ static my_bool wait_pidfile(char *pidfile, time_t last_modified,
}
DBUG_RETURN(error);
}
-#ifdef HAVE_NDBCLUSTER_DB
-/* lib linked in contains c++ code */
#ifdef __GNUC__
FIX_GCC_LINKING_PROBLEM
#endif
-#endif
diff --git a/configure.in b/configure.in
index f360ee46453..1fcba6b8f5f 100644
--- a/configure.in
+++ b/configure.in
@@ -399,7 +399,6 @@ then
then
if $CXX -v 2>&1 | grep 'version 3' > /dev/null 2>&1
then
- CFLAGS="$CFLAGS -DDEFINE_CXA_PURE_VIRTUAL"
CXXFLAGS="$CXXFLAGS -DUSE_MYSYS_NEW -DDEFINE_CXA_PURE_VIRTUAL"
fi
fi
diff --git a/ndb/include/Makefile.am b/ndb/include/Makefile.am
index 7b3f80b5560..ca2e8152352 100644
--- a/ndb/include/Makefile.am
+++ b/ndb/include/Makefile.am
@@ -28,6 +28,7 @@ ndbapi/NdbIndexScanOperation.hpp \
ndbapi/ndberror.h
mgmapiinclude_HEADERS = \
+mgmapi/LocalConfig.hpp \
mgmapi/mgmapi.h \
mgmapi/mgmapi_debug.h
diff --git a/ndb/src/mgmclient/CommandInterpreter.cpp b/ndb/src/mgmclient/CommandInterpreter.cpp
index d940f6e165a..a36263395ec 100644
--- a/ndb/src/mgmclient/CommandInterpreter.cpp
+++ b/ndb/src/mgmclient/CommandInterpreter.cpp
@@ -193,7 +193,7 @@ extern "C" {
{
return (Ndb_mgmclient_handle) new Ndb_mgmclient(connect_string);
}
- int ndb_mgmclient_execute(Ndb_mgmclient_handle h, int argc, const char** argv)
+ int ndb_mgmclient_execute(Ndb_mgmclient_handle h, int argc, char** argv)
{
return ((Ndb_mgmclient*)h)->execute(argc, argv, 1);
}
@@ -226,7 +226,7 @@ extern "C" {
#include
#include
-int Ndb_mgmclient::execute(int argc, const char** argv, int _try_reconnect)
+int Ndb_mgmclient::execute(int argc, char** argv, int _try_reconnect)
{
if (argc <= 0)
return 0;
diff --git a/ndb/src/mgmclient/ndb_mgmclient.h b/ndb/src/mgmclient/ndb_mgmclient.h
index 265e6bc67ec..b62a33999a3 100644
--- a/ndb/src/mgmclient/ndb_mgmclient.h
+++ b/ndb/src/mgmclient/ndb_mgmclient.h
@@ -23,7 +23,7 @@ extern "C" {
typedef void* Ndb_mgmclient_handle;
Ndb_mgmclient_handle ndb_mgmclient_handle_create(const char *connect_string);
-int ndb_mgmclient_execute(Ndb_mgmclient_handle, int argc, const char** argv);
+int ndb_mgmclient_execute(Ndb_mgmclient_handle, int argc, char** argv);
int ndb_mgmclient_handle_destroy(Ndb_mgmclient_handle);
#ifdef __cplusplus
diff --git a/ndb/src/mgmclient/ndb_mgmclient.hpp b/ndb/src/mgmclient/ndb_mgmclient.hpp
index 933d1bab5ce..f6bcebc3896 100644
--- a/ndb/src/mgmclient/ndb_mgmclient.hpp
+++ b/ndb/src/mgmclient/ndb_mgmclient.hpp
@@ -24,7 +24,7 @@ public:
Ndb_mgmclient(const char*);
~Ndb_mgmclient();
int execute(const char *_line, int _try_reconnect=-1);
- int execute(int argc, const char** argv, int _try_reconnect=-1);
+ int execute(int argc, char** argv, int _try_reconnect=-1);
int disconnect();
private:
CommandInterpreter *m_cmd;
From acc0317bb7504103af8d39b51dbda18e0c4d91d4 Mon Sep 17 00:00:00 2001
From: "heikki@hundin.mysql.fi" <>
Date: Thu, 18 Nov 2004 22:28:37 +0200
Subject: [PATCH 031/145] fil0fil.h, fil0fil.c: Fix bug introduced in 4.1.1:
InnoDB no longer respected the data file max size given in :autoextend:max:
---
innobase/fil/fil0fil.c | 19 ++++++++++++++++---
innobase/include/fil0fil.h | 2 +-
2 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/innobase/fil/fil0fil.c b/innobase/fil/fil0fil.c
index 7d57468f632..de528355182 100644
--- a/innobase/fil/fil0fil.c
+++ b/innobase/fil/fil0fil.c
@@ -106,7 +106,7 @@ struct fil_node_struct {
device or a raw disk partition */
ulint size; /* size of the file in database pages, 0 if
not known yet; the possible last incomplete
- megabyte is ignored if space == 0 */
+ megabyte may be ignored if space == 0 */
ulint n_pending;
/* count of pending i/o's on this file;
closing of the file is not allowed if
@@ -160,7 +160,9 @@ struct fil_space_struct {
UT_LIST_BASE_NODE_T(fil_node_t) chain;
/* base node for the file chain */
ulint size; /* space size in pages; 0 if a single-table
- tablespace whose size we do not know yet */
+ tablespace whose size we do not know yet;
+ last incomplete megabytes in data files may be
+ ignored if space == 0 */
ulint n_reserved_extents;
/* number of reserved free extents for
ongoing operations like B-tree page split */
@@ -3255,7 +3257,7 @@ fil_extend_space_to_desired_size(
ulint* actual_size, /* out: size of the space after extension;
if we ran out of disk space this may be lower
than the desired size */
- ulint space_id, /* in: space id, must be != 0 */
+ ulint space_id, /* in: space id */
ulint size_after_extend)/* in: desired size in pages after the
extension; if the current space size is bigger
than this already, the function does nothing */
@@ -3352,6 +3354,17 @@ fil_extend_space_to_desired_size(
fil_node_complete_io(node, system, OS_FILE_WRITE);
*actual_size = space->size;
+
+ if (space_id == 0) {
+ ulint pages_per_mb = (1024 * 1024) / UNIV_PAGE_SIZE;
+
+ /* Keep the last data file size info up to date, rounded to
+ full megabytes */
+
+ srv_data_file_sizes[srv_n_data_files - 1] =
+ (node->size / pages_per_mb) * pages_per_mb;
+ }
+
/*
printf("Extended %s to %lu, actual size %lu pages\n", space->name,
size_after_extend, *actual_size); */
diff --git a/innobase/include/fil0fil.h b/innobase/include/fil0fil.h
index 5a5db77073a..43327aab9d2 100644
--- a/innobase/include/fil0fil.h
+++ b/innobase/include/fil0fil.h
@@ -478,7 +478,7 @@ fil_extend_space_to_desired_size(
ulint* actual_size, /* out: size of the space after extension;
if we ran out of disk space this may be lower
than the desired size */
- ulint space_id, /* in: space id, must be != 0 */
+ ulint space_id, /* in: space id */
ulint size_after_extend);/* in: desired size in pages after the
extension; if the current space size is bigger
than this already, the function does nothing */
From f30ce1ecafb8bfecb6e3b0921e16fe9fbe48e0d5 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Thu, 18 Nov 2004 20:35:19 +0000
Subject: [PATCH 032/145] adopted testprograms to changes in mgmapi
---
ndb/test/run-test/main.cpp | 22 ++++++++++--------
ndb/test/src/NdbBackup.cpp | 10 ++++----
ndb/test/src/NdbRestarter.cpp | 43 ++++++++---------------------------
3 files changed, 27 insertions(+), 48 deletions(-)
diff --git a/ndb/test/run-test/main.cpp b/ndb/test/run-test/main.cpp
index e5f73bc6a5c..ac7710d9546 100644
--- a/ndb/test/run-test/main.cpp
+++ b/ndb/test/run-test/main.cpp
@@ -538,15 +538,19 @@ connect_ndb_mgm(atrt_process & proc){
}
BaseString tmp = proc.m_hostname;
tmp.appfmt(":%d", proc.m_ndb_mgm_port);
- time_t start = time(0);
- const time_t max_connect_time = 30;
- do {
- if(ndb_mgm_connect(handle, tmp.c_str()) != -1){
- proc.m_ndb_mgm_handle = handle;
- return true;
- }
- sleep(1);
- } while(time(0) < (start + max_connect_time));
+
+ if (ndb_mgm_set_connectstring(handle,tmp.c_str()))
+ {
+ g_logger.critical("Unable to create parse connectstring");
+ return false;
+ }
+
+ if(ndb_mgm_connect(handle, 30, 1, 0) != -1)
+ {
+ proc.m_ndb_mgm_handle = handle;
+ return true;
+ }
+
g_logger.critical("Unable to connect to ndb mgm %s", tmp.c_str());
return false;
}
diff --git a/ndb/test/src/NdbBackup.cpp b/ndb/test/src/NdbBackup.cpp
index 1ce48d495a5..398a7c32fc4 100644
--- a/ndb/test/src/NdbBackup.cpp
+++ b/ndb/test/src/NdbBackup.cpp
@@ -69,16 +69,14 @@ NdbBackup::getBackupDataDirForNode(int _node_id){
/**
* Fetch configuration from management server
*/
- LocalConfig lc;
- if (!lc.init(0,0)) {
- abort();
- }
- ConfigRetriever cr(lc, 0, NODE_TYPE_API);
+ ConfigRetriever cr(0, 0, NODE_TYPE_API);
ndb_mgm_configuration * p = 0;
BaseString tmp; tmp.assfmt("%s:%d", host.c_str(), port);
NdbMgmHandle handle = ndb_mgm_create_handle();
- if(handle == 0 || ndb_mgm_connect(handle, tmp.c_str()) != 0 ||
+ if(handle == 0 ||
+ ndb_mgm_set_connectstring(handle,tmp.c_str()) != 0 ||
+ ndb_mgm_connect(handle,0,0,0) != 0 ||
(p = ndb_mgm_get_configuration(handle, 0)) == 0){
const char * s = 0;
diff --git a/ndb/test/src/NdbRestarter.cpp b/ndb/test/src/NdbRestarter.cpp
index 4d6d3ddc001..e1802f36e82 100644
--- a/ndb/test/src/NdbRestarter.cpp
+++ b/ndb/test/src/NdbRestarter.cpp
@@ -18,7 +18,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -38,37 +37,7 @@ NdbRestarter::NdbRestarter(const char* _addr):
m_config(0)
{
if (_addr == NULL){
- LocalConfig lcfg;
- if(!lcfg.init()){
- lcfg.printError();
- lcfg.printUsage();
- g_err << "NdbRestarter - Error parsing local config file" << endl;
- return;
- }
-
- if (lcfg.ids.size() == 0){
- g_err << "NdbRestarter - No management servers configured in local config file" << endl;
- return;
- }
-
- for (int i = 0; itype){
- case MgmId_TCP:
- char buf[255];
- snprintf(buf, 255, "%s:%d", m->name.c_str(), m->port);
- addr.assign(buf);
- host.assign(m->name.c_str());
- port = m->port;
- return;
- break;
- case MgmId_File:
- break;
- default:
- break;
- }
- }
+ addr.assign("");
} else {
addr.assign(_addr);
}
@@ -397,7 +366,15 @@ NdbRestarter::connect(){
return -1;
}
g_info << "Connecting to mgmsrv at " << addr.c_str() << endl;
- if (ndb_mgm_connect(handle, addr.c_str()) == -1) {
+ if (ndb_mgm_set_connectstring(handle,addr.c_str()))
+ {
+ MGMERR(handle);
+ g_err << "Connection to " << addr.c_str() << " failed" << endl;
+ return -1;
+ }
+
+ if (ndb_mgm_connect(handle, 0, 0, 0) == -1)
+ {
MGMERR(handle);
g_err << "Connection to " << addr.c_str() << " failed" << endl;
return -1;
From fec630622bb286928d044d4abd4598f9c859ff75 Mon Sep 17 00:00:00 2001
From: "konstantin@mysql.com" <>
Date: Thu, 18 Nov 2004 23:35:45 +0300
Subject: [PATCH 033/145] Some comments regarding Bug#6275 ""client_test" fail
in 4.1.7 make test"
---
tests/client_test.c | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/tests/client_test.c b/tests/client_test.c
index 2f28da6d00d..0ada98d44b0 100644
--- a/tests/client_test.c
+++ b/tests/client_test.c
@@ -635,12 +635,15 @@ static void verify_prepare_field(MYSQL_RES *result,
unsigned long length, const char *def)
{
MYSQL_FIELD *field;
+ CHARSET_INFO *cs;
if (!(field= mysql_fetch_field_direct(result, no)))
{
fprintf(stdout, "\n *** ERROR: FAILED TO GET THE RESULT ***");
exit(1);
}
+ cs= get_charset(field->charsetnr, 0);
+ DIE_UNLESS(cs);
if (!opt_silent)
{
fprintf(stdout, "\n field[%d]:", no);
@@ -654,7 +657,7 @@ static void verify_prepare_field(MYSQL_RES *result,
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);
+ field->length, length * cs->mbmaxlen);
fprintf(stdout, "\n maxlength:`%ld`", field->max_length);
fprintf(stdout, "\n charsetnr:`%d`", field->charsetnr);
fprintf(stdout, "\n default :`%s`\t(expected: `%s`)",
@@ -663,11 +666,24 @@ static void verify_prepare_field(MYSQL_RES *result,
}
DIE_UNLESS(strcmp(field->name, name) == 0);
DIE_UNLESS(strcmp(field->org_name, org_name) == 0);
- DIE_UNLESS(field->type == type);
+ /*
+ XXX: silent column specification change works based on number of
+ bytes a column occupies. So CHAR -> VARCHAR upgrade is possible even
+ for CHAR(2) column if its character set is multibyte.
+ VARCHAR -> CHAR downgrade won't work for VARCHAR(3) as one would
+ expect.
+ */
+ if (cs->mbmaxlen == 1)
+ DIE_UNLESS(field->type == type);
DIE_UNLESS(strcmp(field->table, table) == 0);
DIE_UNLESS(strcmp(field->org_table, org_table) == 0);
DIE_UNLESS(strcmp(field->db, db) == 0);
- DIE_UNLESS(field->length == length);
+ /*
+ Character set should be taken into account for multibyte encodings, such
+ as utf8. Field length is calculated as number of characters * maximum
+ number of bytes a character can occupy.
+ */
+ DIE_UNLESS(field->length == length * cs->mbmaxlen);
if (def)
DIE_UNLESS(strcmp(field->def, def) == 0);
}
From 21e8a090561af2ccabfc69f58bd92a363ff41777 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Thu, 18 Nov 2004 21:15:18 +0000
Subject: [PATCH 034/145] bug#6677 bug#6684
---
ndb/src/mgmclient/CommandInterpreter.cpp | 7 +++++-
ndb/tools/restore/main.cpp | 27 +++++++++++++++++-------
2 files changed, 25 insertions(+), 9 deletions(-)
diff --git a/ndb/src/mgmclient/CommandInterpreter.cpp b/ndb/src/mgmclient/CommandInterpreter.cpp
index a36263395ec..bdeb885ed8b 100644
--- a/ndb/src/mgmclient/CommandInterpreter.cpp
+++ b/ndb/src/mgmclient/CommandInterpreter.cpp
@@ -1386,7 +1386,7 @@ void
CommandInterpreter::executeDumpState(int processId, const char* parameters,
bool all)
{
- if(parameters == 0 || strlen(parameters) == 0){
+ if(emptyString(parameters)){
ndbout << "Expected argument" << endl;
return;
}
@@ -1806,6 +1806,10 @@ CommandInterpreter::executeEventReporting(int processId,
const char* parameters,
bool all)
{
+ if (emptyString(parameters)) {
+ ndbout << "Expected argument" << endl;
+ return;
+ }
connect();
BaseString tmp(parameters);
@@ -1906,6 +1910,7 @@ void
CommandInterpreter::executeAbortBackup(char* parameters)
{
connect();
+
strtok(parameters, " ");
struct ndb_mgm_reply reply;
char* id = strtok(NULL, "\0");
diff --git a/ndb/tools/restore/main.cpp b/ndb/tools/restore/main.cpp
index 482212911cb..064fbad43a3 100644
--- a/ndb/tools/restore/main.cpp
+++ b/ndb/tools/restore/main.cpp
@@ -74,7 +74,7 @@ static struct my_option my_long_options[] =
"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 },
+ GET_INT, REQUIRED_ARG, 128, 1, 1024, 0, 1, 0 },
{ "print", 256, "Print data and log to stdout",
(gptr*) &_print, (gptr*) &_print, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
@@ -120,6 +120,18 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
case 'V':
print_version();
exit(0);
+ case 'n':
+ if (ga_nodeId == 0)
+ {
+ printf("Error in --nodeid|-n setting, see --help\n");
+ exit(1);
+ }
+ case 'b':
+ if (ga_backupId == 0)
+ {
+ printf("Error in --backupid|-b setting, see --help\n");
+ exit(1);
+ }
case '?':
usage();
exit(0);
@@ -131,11 +143,8 @@ 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) {
+ if (handle_options(pargc, pargv, my_long_options, get_one_option))
+ {
exit(1);
}
@@ -343,7 +352,8 @@ main(int argc, char** argv)
if (res < 0)
{
- err << "Restore: An error occured while restoring data. Exiting... res=" << res << endl;
+ err << "Restore: An error occured while restoring data. Exiting... "
+ << "res=" << res << endl;
return -1;
}
@@ -369,7 +379,8 @@ main(int argc, char** argv)
}
if (res < 0)
{
- err << "Restore: An restoring the data log. Exiting... res=" << res << endl;
+ err << "Restore: An restoring the data log. Exiting... res="
+ << res << endl;
return -1;
}
logIter.validateFooter(); //not implemented
From 64382cdcf31f020969d69e20d0ed10283e33904a Mon Sep 17 00:00:00 2001
From: "joreland@mysql.com" <>
Date: Thu, 18 Nov 2004 22:41:31 +0100
Subject: [PATCH 035/145] wl2077 - ndb scan optimizations
---
ndb/test/ndbapi/testScanPerf.cpp | 78 ++++++++++++++++++++++----------
1 file changed, 54 insertions(+), 24 deletions(-)
diff --git a/ndb/test/ndbapi/testScanPerf.cpp b/ndb/test/ndbapi/testScanPerf.cpp
index c1334125978..fca67c6abcb 100644
--- a/ndb/test/ndbapi/testScanPerf.cpp
+++ b/ndb/test/ndbapi/testScanPerf.cpp
@@ -39,8 +39,9 @@ struct Parameter {
#define P_LOOPS 8
#define P_CREATE 9
#define P_LOAD 10
+#define P_RESET 11
-#define P_MAX 11
+#define P_MAX 12
static
Parameter
@@ -55,7 +56,8 @@ g_paramters[] = {
{ "size", 1000000, 1, ~0 },
{ "iterations", 3, 1, ~0 },
{ "create_drop", 1, 0, 1 },
- { "data", 1, 0, 1 }
+ { "data", 1, 0, 1 },
+ { "q-reset bounds", 0, 1, 0 }
};
static Ndb* g_ndb = 0;
@@ -218,21 +220,29 @@ run_scan(){
NDB_TICKS start1, stop;
int sum_time= 0;
+ int sample_rows = 0;
+ NDB_TICKS sample_start = NdbTick_CurrentMillisecond();
+
Uint32 tot = g_paramters[P_ROWS].value;
+ if(g_paramters[P_BOUND].value == 2 || g_paramters[P_FILT].value == 2)
+ iter *= g_paramters[P_ROWS].value;
+
+ NdbScanOperation * pOp = 0;
+ NdbIndexScanOperation * pIOp = 0;
+ NdbConnection * pTrans = 0;
+ NdbResultSet * rs = 0;
+ int check = 0;
+
for(int i = 0; istartTransaction();
+ pTrans = pTrans ? pTrans : g_ndb->startTransaction();
if(!pTrans){
g_err << "Failed to start transaction" << endl;
err(g_ndb->getNdbError());
return -1;
}
- NdbScanOperation * pOp;
- NdbIndexScanOperation * pIOp;
-
- NdbResultSet * rs;
int par = g_paramters[P_PARRA].value;
int bat = g_paramters[P_BATCH].value;
NdbScanOperation::LockMode lm;
@@ -255,9 +265,17 @@ run_scan(){
assert(pOp);
rs = pOp->readTuples(lm, bat, par);
} else {
- pOp = pIOp = pTrans->getNdbIndexScanOperation(g_indexname, g_tablename);
- bool ord = g_paramters[P_ACCESS].value == 2;
- rs = pIOp->readTuples(lm, bat, par, ord);
+ if(g_paramters[P_RESET].value == 0 || pIOp == 0)
+ {
+ pOp= pIOp= pTrans->getNdbIndexScanOperation(g_indexname, g_tablename);
+ bool ord = g_paramters[P_ACCESS].value == 2;
+ rs = pIOp->readTuples(lm, bat, par, ord);
+ }
+ else
+ {
+ pIOp->reset_bounds();
+ }
+
switch(g_paramters[P_BOUND].value){
case 0: // All
break;
@@ -267,20 +285,22 @@ run_scan(){
case 2: { // 1 row
default:
assert(g_table->getNoOfPrimaryKeys() == 1); // only impl. so far
- abort();
-#if 0
int tot = g_paramters[P_ROWS].value;
int row = rand() % tot;
+#if 0
fix_eq_bound(pIOp, row);
+#else
+ pIOp->setBound((Uint32)0, NdbIndexScanOperation::BoundEQ, &row);
#endif
break;
}
}
+ if(g_paramters[P_RESET].value == 1)
+ goto execute;
}
assert(pOp);
assert(rs);
- int check = 0;
switch(g_paramters[P_FILT].value){
case 0: // All
check = pOp->interpret_exit_ok();
@@ -312,7 +332,7 @@ run_scan(){
for(int i = 0; igetNoOfColumns(); i++){
pOp->getValue(i);
}
-
+execute:
int rows = 0;
check = pTrans->execute(NoCommit);
assert(check == 0);
@@ -333,19 +353,29 @@ run_scan(){
return -1;
}
assert(check == 1);
- g_info << "Found " << rows << " rows" << endl;
-
- pTrans->close();
-
+ if(g_paramters[P_RESET].value == 0)
+ {
+ pTrans->close();
+ pTrans = 0;
+ }
stop = NdbTick_CurrentMillisecond();
+
int time_passed= (int)(stop - start1);
- g_err.println("Time: %d ms = %u rows/sec", time_passed,
- (1000*tot)/time_passed);
+ sample_rows += rows;
sum_time+= time_passed;
+
+ if(sample_rows >= tot)
+ {
+ int sample_time = (int)(stop - sample_start);
+ g_info << "Found " << sample_rows << " rows" << endl;
+ g_err.println("Time: %d ms = %u rows/sec", sample_time,
+ (1000*sample_rows)/sample_time);
+ sample_rows = 0;
+ sample_start = stop;
+ }
}
- sum_time= sum_time / iter;
-
- g_err.println("Avg time: %d ms = %u rows/sec", sum_time,
- (1000*tot)/sum_time);
+
+ g_err.println("Avg time: %d ms = %u rows/sec", sum_time/iter,
+ (1000*tot*iter)/sum_time);
return 0;
}
From 554ae2336e7c2937b92d1bf3a4ec0ec2c8cd2c44 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Thu, 18 Nov 2004 21:42:25 +0000
Subject: [PATCH 036/145] change file name to avoid conflict corrected
mistake in previous patch
---
ndb/tools/Makefile.am | 2 +-
ndb/tools/restore/{main.cpp => restore_main.cpp} | 6 ++++--
2 files changed, 5 insertions(+), 3 deletions(-)
rename ndb/tools/restore/{main.cpp => restore_main.cpp} (98%)
diff --git a/ndb/tools/Makefile.am b/ndb/tools/Makefile.am
index 9c086d665c1..7a61a9b1be5 100644
--- a/ndb/tools/Makefile.am
+++ b/ndb/tools/Makefile.am
@@ -26,7 +26,7 @@ ndb_select_all_SOURCES = select_all.cpp \
../test/src/NDBT_ResultRow.cpp \
$(tools_common_sources)
ndb_select_count_SOURCES = select_count.cpp $(tools_common_sources)
-ndb_restore_SOURCES = restore/main.cpp \
+ndb_restore_SOURCES = restore/restore_main.cpp \
restore/consumer.cpp \
restore/consumer_restore.cpp \
restore/consumer_printer.cpp \
diff --git a/ndb/tools/restore/main.cpp b/ndb/tools/restore/restore_main.cpp
similarity index 98%
rename from ndb/tools/restore/main.cpp
rename to ndb/tools/restore/restore_main.cpp
index 064fbad43a3..c43791c6723 100644
--- a/ndb/tools/restore/main.cpp
+++ b/ndb/tools/restore/restore_main.cpp
@@ -123,15 +123,17 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
case 'n':
if (ga_nodeId == 0)
{
- printf("Error in --nodeid|-n setting, see --help\n");
+ printf("Error in --nodeid,-n setting, see --help\n");
exit(1);
}
+ break;
case 'b':
if (ga_backupId == 0)
{
- printf("Error in --backupid|-b setting, see --help\n");
+ printf("Error in --backupid,-b setting, see --help\n");
exit(1);
}
+ break;
case '?':
usage();
exit(0);
From 7743dbbb56821c4ff45d892243d5acf0ee54e7a5 Mon Sep 17 00:00:00 2001
From: "guilhem@mysql.com" <>
Date: Thu, 18 Nov 2004 22:59:17 +0100
Subject: [PATCH 037/145] When mysqlbinlog prints LOAD DATA INFILE, let it
print the thread id. Some customer would have benefited much from this in his
recovery. All this change does is adding one commented (#) line before the
LOAD DATA command, so it is quite innocuous.
---
sql/log_event.cc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sql/log_event.cc b/sql/log_event.cc
index f707eabebd5..007bb6e7b85 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -1612,7 +1612,7 @@ void Create_file_log_event::print(FILE* file, bool short_form,
if (enable_local)
{
- Load_log_event::print(file, 1, last_db, !check_fname_outside_temp_buf());
+ Load_log_event::print(file, short_form, last_db, !check_fname_outside_temp_buf());
/*
That one is for "file_id: etc" below: in mysqlbinlog we want the #, in
SHOW BINLOG EVENTS we don't.
From 3a8a6d4457f88b636cb7ea3f07e4dd4be04477d8 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Thu, 18 Nov 2004 22:44:34 +0000
Subject: [PATCH 038/145] merge error
---
ndb/include/Makefile.am | 1 -
1 file changed, 1 deletion(-)
diff --git a/ndb/include/Makefile.am b/ndb/include/Makefile.am
index ca2e8152352..7b3f80b5560 100644
--- a/ndb/include/Makefile.am
+++ b/ndb/include/Makefile.am
@@ -28,7 +28,6 @@ ndbapi/NdbIndexScanOperation.hpp \
ndbapi/ndberror.h
mgmapiinclude_HEADERS = \
-mgmapi/LocalConfig.hpp \
mgmapi/mgmapi.h \
mgmapi/mgmapi_debug.h
From eb11d34403100f1b839b0dcef670bc80abd91621 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Thu, 18 Nov 2004 22:45:48 +0000
Subject: [PATCH 039/145] moved ndb_use_transactions out of opts and to be set
default true in THD::init
---
sql/mysqld.cc | 6 ------
sql/sql_class.cc | 3 +++
2 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 5ee52326276..5033c42ac69 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -3950,7 +3950,6 @@ enum options_mysqld
OPT_INNODB, OPT_ISAM,
OPT_NDBCLUSTER, OPT_NDB_CONNECTSTRING, OPT_NDB_USE_EXACT_COUNT,
OPT_NDB_FORCE_SEND, OPT_NDB_AUTOINCREMENT_PREFETCH_SZ,
- OPT_NDB_USE_TRANSACTIONS,
OPT_SKIP_SAFEMALLOC,
OPT_TEMP_POOL, OPT_TX_ISOLATION,
OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS,
@@ -4410,11 +4409,6 @@ Disable with --skip-ndbcluster (will save memory).",
(gptr*) &global_system_variables.ndb_use_exact_count,
(gptr*) &global_system_variables.ndb_use_exact_count,
0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
- {"ndb_use_transactions", OPT_NDB_USE_TRANSACTIONS,
- "Use transactions in ndb",
- (gptr*) &global_system_variables.ndb_use_transactions,
- (gptr*) &global_system_variables.ndb_use_transactions,
- 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
#endif
{"new", 'n', "Use very new possible 'unsafe' functions.",
(gptr*) &global_system_variables.new_mode,
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index eda60b5cfdb..bab81d785c3 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -280,6 +280,9 @@ void THD::init(void)
variables.date_format);
variables.datetime_format= date_time_format_copy((THD*) 0,
variables.datetime_format);
+#ifdef HAVE_NDBCLUSTER_DB
+ variables.ndb_use_transactions= 1;
+#endif
pthread_mutex_unlock(&LOCK_global_system_variables);
server_status= SERVER_STATUS_AUTOCOMMIT;
options= thd_startup_options;
From 6c438ba9a45a8a528bf20b150b0f22a8f38eac3a Mon Sep 17 00:00:00 2001
From: "guilhem@mysql.com" <>
Date: Fri, 19 Nov 2004 00:57:26 +0100
Subject: [PATCH 040/145] log_event.cc: post-conflict-merge fix (duplicate
comment)
---
sql/log_event.cc | 1 -
1 file changed, 1 deletion(-)
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 31b02a5a29a..2fdc89504d7 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -1,4 +1,3 @@
-/* Copyright (C) 2000-2004 MySQL AB
/* Copyright (C) 2000-2004 MySQL AB
This program is free software; you can redistribute it and/or modify
From 287fe9e31362973660f9e06898641080ef1d4d7b Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Fri, 19 Nov 2004 09:17:36 +0000
Subject: [PATCH 041/145] ndb_grant.result, ndb_grant.test: new file
---
mysql-test/r/ndb_grant.result | 416 ++++++++++++++++++++++++++++++++++
mysql-test/t/ndb_grant.test | 374 ++++++++++++++++++++++++++++++
2 files changed, 790 insertions(+)
create mode 100644 mysql-test/r/ndb_grant.result
create mode 100644 mysql-test/t/ndb_grant.test
diff --git a/mysql-test/r/ndb_grant.result b/mysql-test/r/ndb_grant.result
new file mode 100644
index 00000000000..6583065a0c4
--- /dev/null
+++ b/mysql-test/r/ndb_grant.result
@@ -0,0 +1,416 @@
+drop table if exists t1;
+SET NAMES binary;
+use mysql;
+alter table columns_priv engine=ndb;
+alter table db engine=ndb;
+alter table func engine=ndb;
+alter table help_category engine=ndb;
+alter table help_keyword engine=ndb;
+alter table help_relation engine=ndb;
+alter table help_topic engine=ndb;
+alter table host engine=ndb;
+alter table tables_priv engine=ndb;
+alter table time_zone engine=ndb;
+alter table time_zone_leap_second engine=ndb;
+alter table time_zone_name engine=ndb;
+alter table time_zone_transition engine=ndb;
+alter table time_zone_transition_type engine=ndb;
+alter table user engine=ndb;
+use test;
+delete from mysql.user where user='mysqltest_1';
+delete from mysql.db where user='mysqltest_1';
+flush privileges;
+begin;
+grant select on mysqltest.* to mysqltest_1@localhost require cipher "EDH-RSA-DES-CBC3-SHA";
+commit;
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA'
+GRANT SELECT ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
+begin;
+grant delete on mysqltest.* to mysqltest_1@localhost;
+commit;
+select * from mysql.user where user="mysqltest_1";
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections
+localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N SPECIFIED EDH-RSA-DES-CBC3-SHA 0 0 0
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA'
+GRANT SELECT, DELETE ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
+begin;
+revoke delete on mysqltest.* from mysqltest_1@localhost;
+commit;
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA'
+GRANT SELECT ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
+begin;
+grant select on mysqltest.* to mysqltest_1@localhost require NONE;
+commit;
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
+GRANT SELECT ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
+begin;
+grant USAGE on mysqltest.* to mysqltest_1@localhost require cipher "EDH-RSA-DES-CBC3-SHA" AND SUBJECT "testsubject" ISSUER "MySQL AB";
+commit;
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE ISSUER 'MySQL AB' SUBJECT 'testsubject' CIPHER 'EDH-RSA-DES-CBC3-SHA'
+GRANT SELECT ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
+begin;
+revoke all privileges on mysqltest.* from mysqltest_1@localhost;
+commit;
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE ISSUER 'MySQL AB' SUBJECT 'testsubject' CIPHER 'EDH-RSA-DES-CBC3-SHA'
+delete from mysql.user where user='mysqltest_1';
+flush privileges;
+begin;
+grant CREATE TEMPORARY TABLES, LOCK TABLES on mysqltest.* to mysqltest_1@localhost;
+commit;
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
+GRANT CREATE TEMPORARY TABLES, LOCK TABLES ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
+flush privileges;
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
+GRANT CREATE TEMPORARY TABLES, LOCK TABLES ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
+begin;
+revoke CREATE TEMPORARY TABLES on mysqltest.* from mysqltest_1@localhost;
+commit;
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
+GRANT LOCK TABLES ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
+begin;
+grant ALL PRIVILEGES on mysqltest.* to mysqltest_1@localhost with GRANT OPTION;
+commit;
+flush privileges;
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
+GRANT ALL PRIVILEGES ON `mysqltest`.* TO 'mysqltest_1'@'localhost' WITH GRANT OPTION
+begin;
+revoke LOCK TABLES, ALTER on mysqltest.* from mysqltest_1@localhost;
+commit;
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
+GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, CREATE TEMPORARY TABLES ON `mysqltest`.* TO 'mysqltest_1'@'localhost' WITH GRANT OPTION
+begin;
+revoke all privileges on mysqltest.* from mysqltest_1@localhost;
+commit;
+delete from mysql.user where user='mysqltest_1';
+flush privileges;
+begin;
+grant usage on test.* to mysqltest_1@localhost with grant option;
+commit;
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
+GRANT USAGE ON `mysqltest`.* TO 'mysqltest_1'@'localhost' WITH GRANT OPTION
+GRANT USAGE ON `test`.* TO 'mysqltest_1'@'localhost' WITH GRANT OPTION
+delete from mysql.user where user='mysqltest_1';
+delete from mysql.db where user='mysqltest_1';
+delete from mysql.tables_priv where user='mysqltest_1';
+delete from mysql.columns_priv where user='mysqltest_1';
+flush privileges;
+show grants for mysqltest_1@localhost;
+ERROR 42000: There is no such grant defined for user 'mysqltest_1' on host 'localhost'
+create table t1 (a int);
+begin;
+GRANT select,update,insert on t1 to mysqltest_1@localhost;
+GRANT select (a), update (a),insert(a), references(a) on t1 to mysqltest_1@localhost;
+commit;
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
+GRANT SELECT, SELECT (a), INSERT, INSERT (a), UPDATE, UPDATE (a), REFERENCES (a) ON `test`.`t1` TO 'mysqltest_1'@'localhost'
+select table_priv,column_priv from mysql.tables_priv where user="mysqltest_1";
+table_priv column_priv
+Select,Insert,Update Select,Insert,Update,References
+begin;
+REVOKE select (a), update on t1 from mysqltest_1@localhost;
+commit;
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
+GRANT SELECT, INSERT, INSERT (a), REFERENCES (a) ON `test`.`t1` TO 'mysqltest_1'@'localhost'
+begin;
+REVOKE select,update,insert,insert (a) on t1 from mysqltest_1@localhost;
+commit;
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
+GRANT REFERENCES (a) ON `test`.`t1` TO 'mysqltest_1'@'localhost'
+begin;
+GRANT select,references on t1 to mysqltest_1@localhost;
+commit;
+select table_priv,column_priv from mysql.tables_priv where user="mysqltest_1";
+table_priv column_priv
+Select,References References
+begin;
+grant all on test.* to mysqltest_3@localhost with grant option;
+revoke all on test.* from mysqltest_3@localhost;
+commit;
+show grants for mysqltest_3@localhost;
+Grants for mysqltest_3@localhost
+GRANT USAGE ON *.* TO 'mysqltest_3'@'localhost'
+GRANT USAGE ON `test`.* TO 'mysqltest_3'@'localhost' WITH GRANT OPTION
+begin;
+revoke grant option on test.* from mysqltest_3@localhost;
+commit;
+show grants for mysqltest_3@localhost;
+Grants for mysqltest_3@localhost
+GRANT USAGE ON *.* TO 'mysqltest_3'@'localhost'
+begin;
+grant all on test.t1 to mysqltest_2@localhost with grant option;
+revoke all on test.t1 from mysqltest_2@localhost;
+commit;
+show grants for mysqltest_2@localhost;
+Grants for mysqltest_2@localhost
+GRANT USAGE ON *.* TO 'mysqltest_2'@'localhost'
+GRANT USAGE ON `test`.`t1` TO 'mysqltest_2'@'localhost' WITH GRANT OPTION
+begin;
+revoke grant option on test.t1 from mysqltest_2@localhost;
+commit;
+show grants for mysqltest_2@localhost;
+Grants for mysqltest_2@localhost
+GRANT USAGE ON *.* TO 'mysqltest_2'@'localhost'
+delete from mysql.user where user='mysqltest_1' or user="mysqltest_2" or user="mysqltest_3";
+delete from mysql.db where user='mysqltest_1' or user="mysqltest_2" or user="mysqltest_3";
+delete from mysql.tables_priv where user='mysqltest_1' or user="mysqltest_2" or user="mysqltest_3";
+delete from mysql.columns_priv where user='mysqltest_1' or user="mysqltest_2" or user="mysqltest_3";
+flush privileges;
+drop table t1;
+begin;
+GRANT FILE on mysqltest.* to mysqltest_1@localhost;
+ERROR HY000: Incorrect usage of DB GRANT and GLOBAL PRIVILEGES
+commit;
+select 1;
+1
+1
+create database mysqltest1;
+begin;
+grant usage on mysqltest1.* to test6123 identified by 'magic123';
+commit;
+select host,db,user,select_priv,insert_priv from mysql.db where db="mysqltest1";
+host db user select_priv insert_priv
+delete from mysql.user where user='test6123';
+drop database mysqltest1;
+create table t1 (a int);
+begin;
+grant ALL PRIVILEGES on *.* to drop_user2@localhost with GRANT OPTION;
+commit;
+show grants for drop_user2@localhost;
+Grants for drop_user2@localhost
+GRANT ALL PRIVILEGES ON *.* TO 'drop_user2'@'localhost' WITH GRANT OPTION
+begin;
+revoke all privileges, grant option from drop_user2@localhost;
+commit;
+drop user drop_user2@localhost;
+begin;
+grant ALL PRIVILEGES on *.* to drop_user@localhost with GRANT OPTION;
+grant ALL PRIVILEGES on test.* to drop_user@localhost with GRANT OPTION;
+grant select(a) on test.t1 to drop_user@localhost;
+commit;
+show grants for drop_user@localhost;
+Grants for drop_user@localhost
+GRANT ALL PRIVILEGES ON *.* TO 'drop_user'@'localhost' WITH GRANT OPTION
+GRANT ALL PRIVILEGES ON `test`.* TO 'drop_user'@'localhost' WITH GRANT OPTION
+GRANT SELECT (a) ON `test`.`t1` TO 'drop_user'@'localhost'
+set sql_mode=ansi_quotes;
+show grants for drop_user@localhost;
+Grants for drop_user@localhost
+GRANT ALL PRIVILEGES ON *.* TO 'drop_user'@'localhost' WITH GRANT OPTION
+GRANT ALL PRIVILEGES ON "test".* TO 'drop_user'@'localhost' WITH GRANT OPTION
+GRANT SELECT (a) ON "test"."t1" TO 'drop_user'@'localhost'
+set sql_mode=default;
+set sql_quote_show_create=0;
+show grants for drop_user@localhost;
+Grants for drop_user@localhost
+GRANT ALL PRIVILEGES ON *.* TO 'drop_user'@'localhost' WITH GRANT OPTION
+GRANT ALL PRIVILEGES ON test.* TO 'drop_user'@'localhost' WITH GRANT OPTION
+GRANT SELECT (a) ON test.t1 TO 'drop_user'@'localhost'
+set sql_mode="ansi_quotes";
+show grants for drop_user@localhost;
+Grants for drop_user@localhost
+GRANT ALL PRIVILEGES ON *.* TO 'drop_user'@'localhost' WITH GRANT OPTION
+GRANT ALL PRIVILEGES ON test.* TO 'drop_user'@'localhost' WITH GRANT OPTION
+GRANT SELECT (a) ON test.t1 TO 'drop_user'@'localhost'
+set sql_quote_show_create=1;
+show grants for drop_user@localhost;
+Grants for drop_user@localhost
+GRANT ALL PRIVILEGES ON *.* TO 'drop_user'@'localhost' WITH GRANT OPTION
+GRANT ALL PRIVILEGES ON "test".* TO 'drop_user'@'localhost' WITH GRANT OPTION
+GRANT SELECT (a) ON "test"."t1" TO 'drop_user'@'localhost'
+set sql_mode="";
+show grants for drop_user@localhost;
+Grants for drop_user@localhost
+GRANT ALL PRIVILEGES ON *.* TO 'drop_user'@'localhost' WITH GRANT OPTION
+GRANT ALL PRIVILEGES ON `test`.* TO 'drop_user'@'localhost' WITH GRANT OPTION
+GRANT SELECT (a) ON `test`.`t1` TO 'drop_user'@'localhost'
+revoke all privileges, grant option from drop_user@localhost;
+show grants for drop_user@localhost;
+Grants for drop_user@localhost
+GRANT USAGE ON *.* TO 'drop_user'@'localhost'
+drop user drop_user@localhost;
+begin;
+revoke all privileges, grant option from drop_user@localhost;
+ERROR HY000: Can't revoke all privileges, grant for one or more of the requested users
+commit;
+begin;
+grant select(a) on test.t1 to drop_user1@localhost;
+commit;
+flush privileges;
+begin;
+grant select on test.t1 to drop_user2@localhost;
+grant select on test.* to drop_user3@localhost;
+grant select on *.* to drop_user4@localhost;
+commit;
+drop user drop_user1@localhost, drop_user2@localhost, drop_user3@localhost,
+drop_user4@localhost;
+ERROR HY000: Can't drop one or more of the requested users
+begin;
+revoke all privileges, grant option from drop_user1@localhost, drop_user2@localhost,
+drop_user3@localhost, drop_user4@localhost;
+commit;
+drop user drop_user1@localhost, drop_user2@localhost, drop_user3@localhost,
+drop_user4@localhost;
+drop table t1;
+begin;
+grant usage on *.* to mysqltest_1@localhost identified by "password";
+grant select, update, insert on test.* to mysqltest@localhost;
+commit;
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' IDENTIFIED BY PASSWORD '*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19'
+drop user mysqltest_1@localhost;
+SET NAMES koi8r;
+CREATE DATABASE ÂÄ;
+USE ÂÄ;
+CREATE TABLE ÔÁÂ (ËÏÌ int);
+begin;
+GRANT SELECT ON ÂÄ.* TO ÀÚÅÒ@localhost;
+commit;
+SHOW GRANTS FOR ÀÚÅÒ@localhost;
+Grants for ÀÚÅÒ@localhost
+GRANT USAGE ON *.* TO 'ÀÚÅÒ'@'localhost'
+GRANT SELECT ON `ÂÄ`.* TO 'ÀÚÅÒ'@'localhost'
+begin;
+REVOKE SELECT ON ÂÄ.* FROM ÀÚÅÒ@localhost;
+commit;
+begin;
+GRANT SELECT ON ÂÄ.ÔÁÂ TO ÀÚÅÒ@localhost;
+commit;
+SHOW GRANTS FOR ÀÚÅÒ@localhost;
+Grants for ÀÚÅÒ@localhost
+GRANT USAGE ON *.* TO 'ÀÚÅÒ'@'localhost'
+GRANT SELECT ON `ÂÄ`.`ÔÁÂ` TO 'ÀÚÅÒ'@'localhost'
+begin;
+REVOKE SELECT ON ÂÄ.ÔÁÂ FROM ÀÚÅÒ@localhost;
+commit;
+begin;
+GRANT SELECT (ËÏÌ) ON ÂÄ.ÔÁÂ TO ÀÚÅÒ@localhost;
+commit;
+SHOW GRANTS FOR ÀÚÅÒ@localhost;
+Grants for ÀÚÅÒ@localhost
+GRANT USAGE ON *.* TO 'ÀÚÅÒ'@'localhost'
+GRANT SELECT (ËÏÌ) ON `ÂÄ`.`ÔÁÂ` TO 'ÀÚÅÒ'@'localhost'
+begin;
+REVOKE SELECT (ËÏÌ) ON ÂÄ.ÔÁÂ FROM ÀÚÅÒ@localhost;
+commit;
+DROP DATABASE ÂÄ;
+SET NAMES latin1;
+USE test;
+CREATE TABLE t1 (a int );
+CREATE TABLE t2 LIKE t1;
+CREATE TABLE t3 LIKE t1;
+CREATE TABLE t4 LIKE t1;
+CREATE TABLE t5 LIKE t1;
+CREATE TABLE t6 LIKE t1;
+CREATE TABLE t7 LIKE t1;
+CREATE TABLE t8 LIKE t1;
+CREATE TABLE t9 LIKE t1;
+CREATE TABLE t10 LIKE t1;
+CREATE DATABASE testdb1;
+CREATE DATABASE testdb2;
+CREATE DATABASE testdb3;
+CREATE DATABASE testdb4;
+CREATE DATABASE testdb5;
+CREATE DATABASE testdb6;
+CREATE DATABASE testdb7;
+CREATE DATABASE testdb8;
+CREATE DATABASE testdb9;
+CREATE DATABASE testdb10;
+begin;
+GRANT ALL ON testdb1.* TO testuser@localhost;
+GRANT ALL ON testdb2.* TO testuser@localhost;
+GRANT ALL ON testdb3.* TO testuser@localhost;
+GRANT ALL ON testdb4.* TO testuser@localhost;
+GRANT ALL ON testdb5.* TO testuser@localhost;
+GRANT ALL ON testdb6.* TO testuser@localhost;
+GRANT ALL ON testdb7.* TO testuser@localhost;
+GRANT ALL ON testdb8.* TO testuser@localhost;
+GRANT ALL ON testdb9.* TO testuser@localhost;
+GRANT ALL ON testdb10.* TO testuser@localhost;
+GRANT SELECT ON test.t1 TO testuser@localhost;
+GRANT SELECT ON test.t2 TO testuser@localhost;
+GRANT SELECT ON test.t3 TO testuser@localhost;
+GRANT SELECT ON test.t4 TO testuser@localhost;
+GRANT SELECT ON test.t5 TO testuser@localhost;
+GRANT SELECT ON test.t6 TO testuser@localhost;
+GRANT SELECT ON test.t7 TO testuser@localhost;
+GRANT SELECT ON test.t8 TO testuser@localhost;
+GRANT SELECT ON test.t9 TO testuser@localhost;
+GRANT SELECT ON test.t10 TO testuser@localhost;
+GRANT SELECT (a) ON test.t1 TO testuser@localhost;
+GRANT SELECT (a) ON test.t2 TO testuser@localhost;
+GRANT SELECT (a) ON test.t3 TO testuser@localhost;
+GRANT SELECT (a) ON test.t4 TO testuser@localhost;
+GRANT SELECT (a) ON test.t5 TO testuser@localhost;
+GRANT SELECT (a) ON test.t6 TO testuser@localhost;
+GRANT SELECT (a) ON test.t7 TO testuser@localhost;
+GRANT SELECT (a) ON test.t8 TO testuser@localhost;
+GRANT SELECT (a) ON test.t9 TO testuser@localhost;
+GRANT SELECT (a) ON test.t10 TO testuser@localhost;
+commit;
+begin;
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM testuser@localhost;
+commit;
+SHOW GRANTS FOR testuser@localhost;
+Grants for testuser@localhost
+GRANT USAGE ON *.* TO 'testuser'@'localhost'
+DROP USER testuser@localhost;
+DROP TABLE t1,t2,t3,t4,t5,t6,t7,t8,t9,t10;
+DROP DATABASE testdb1;
+DROP DATABASE testdb2;
+DROP DATABASE testdb3;
+DROP DATABASE testdb4;
+DROP DATABASE testdb5;
+DROP DATABASE testdb6;
+DROP DATABASE testdb7;
+DROP DATABASE testdb8;
+DROP DATABASE testdb9;
+DROP DATABASE testdb10;
+use mysql;
+alter table columns_priv engine=myisam;
+alter table db engine=myisam;
+alter table func engine=myisam;
+alter table help_category engine=myisam;
+alter table help_keyword engine=myisam;
+alter table help_relation engine=myisam;
+alter table help_topic engine=myisam;
+alter table host engine=myisam;
+alter table tables_priv engine=myisam;
+alter table time_zone engine=myisam;
+alter table time_zone_leap_second engine=myisam;
+alter table time_zone_name engine=myisam;
+alter table time_zone_transition engine=myisam;
+alter table time_zone_transition_type engine=myisam;
+alter table user engine=myisam;
+use test;
+flush privileges;
diff --git a/mysql-test/t/ndb_grant.test b/mysql-test/t/ndb_grant.test
new file mode 100644
index 00000000000..d3899d9972f
--- /dev/null
+++ b/mysql-test/t/ndb_grant.test
@@ -0,0 +1,374 @@
+-- source include/have_ndb.inc
+# Test of GRANT commands
+
+# Cleanup
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+SET NAMES binary;
+
+#
+# Alter mysql system tables to ndb
+# make sure you alter all back in the end
+#
+use mysql;
+alter table columns_priv engine=ndb;
+alter table db engine=ndb;
+alter table func engine=ndb;
+alter table help_category engine=ndb;
+alter table help_keyword engine=ndb;
+alter table help_relation engine=ndb;
+alter table help_topic engine=ndb;
+alter table host engine=ndb;
+alter table tables_priv engine=ndb;
+alter table time_zone engine=ndb;
+alter table time_zone_leap_second engine=ndb;
+alter table time_zone_name engine=ndb;
+alter table time_zone_transition engine=ndb;
+alter table time_zone_transition_type engine=ndb;
+alter table user engine=ndb;
+use test;
+
+#
+# Test that SSL options works properly
+#
+delete from mysql.user where user='mysqltest_1';
+delete from mysql.db where user='mysqltest_1';
+flush privileges;
+begin;
+grant select on mysqltest.* to mysqltest_1@localhost require cipher "EDH-RSA-DES-CBC3-SHA";
+commit;
+show grants for mysqltest_1@localhost;
+begin;
+grant delete on mysqltest.* to mysqltest_1@localhost;
+commit;
+select * from mysql.user where user="mysqltest_1";
+show grants for mysqltest_1@localhost;
+begin;
+revoke delete on mysqltest.* from mysqltest_1@localhost;
+commit;
+show grants for mysqltest_1@localhost;
+begin;
+grant select on mysqltest.* to mysqltest_1@localhost require NONE;
+commit;
+show grants for mysqltest_1@localhost;
+begin;
+grant USAGE on mysqltest.* to mysqltest_1@localhost require cipher "EDH-RSA-DES-CBC3-SHA" AND SUBJECT "testsubject" ISSUER "MySQL AB";
+commit;
+show grants for mysqltest_1@localhost;
+begin;
+revoke all privileges on mysqltest.* from mysqltest_1@localhost;
+commit;
+show grants for mysqltest_1@localhost;
+delete from mysql.user where user='mysqltest_1';
+flush privileges;
+
+#
+# Test that the new db privileges are stored/retrieved correctly
+#
+
+begin;
+grant CREATE TEMPORARY TABLES, LOCK TABLES on mysqltest.* to mysqltest_1@localhost;
+commit;
+show grants for mysqltest_1@localhost;
+flush privileges;
+show grants for mysqltest_1@localhost;
+begin;
+revoke CREATE TEMPORARY TABLES on mysqltest.* from mysqltest_1@localhost;
+commit;
+show grants for mysqltest_1@localhost;
+begin;
+grant ALL PRIVILEGES on mysqltest.* to mysqltest_1@localhost with GRANT OPTION;
+commit;
+flush privileges;
+show grants for mysqltest_1@localhost;
+begin;
+revoke LOCK TABLES, ALTER on mysqltest.* from mysqltest_1@localhost;
+commit;
+show grants for mysqltest_1@localhost;
+begin;
+revoke all privileges on mysqltest.* from mysqltest_1@localhost;
+commit;
+delete from mysql.user where user='mysqltest_1';
+flush privileges;
+begin;
+grant usage on test.* to mysqltest_1@localhost with grant option;
+commit;
+show grants for mysqltest_1@localhost;
+delete from mysql.user where user='mysqltest_1';
+delete from mysql.db where user='mysqltest_1';
+delete from mysql.tables_priv where user='mysqltest_1';
+delete from mysql.columns_priv where user='mysqltest_1';
+flush privileges;
+--error 1141
+show grants for mysqltest_1@localhost;
+
+#
+# Test what happens when you have same table and colum level grants
+#
+
+create table t1 (a int);
+begin;
+GRANT select,update,insert on t1 to mysqltest_1@localhost;
+GRANT select (a), update (a),insert(a), references(a) on t1 to mysqltest_1@localhost;
+commit;
+show grants for mysqltest_1@localhost;
+select table_priv,column_priv from mysql.tables_priv where user="mysqltest_1";
+begin;
+REVOKE select (a), update on t1 from mysqltest_1@localhost;
+commit;
+show grants for mysqltest_1@localhost;
+begin;
+REVOKE select,update,insert,insert (a) on t1 from mysqltest_1@localhost;
+commit;
+show grants for mysqltest_1@localhost;
+begin;
+GRANT select,references on t1 to mysqltest_1@localhost;
+commit;
+select table_priv,column_priv from mysql.tables_priv where user="mysqltest_1";
+begin;
+grant all on test.* to mysqltest_3@localhost with grant option;
+revoke all on test.* from mysqltest_3@localhost;
+commit;
+show grants for mysqltest_3@localhost;
+begin;
+revoke grant option on test.* from mysqltest_3@localhost;
+commit;
+show grants for mysqltest_3@localhost;
+begin;
+grant all on test.t1 to mysqltest_2@localhost with grant option;
+revoke all on test.t1 from mysqltest_2@localhost;
+commit;
+show grants for mysqltest_2@localhost;
+begin;
+revoke grant option on test.t1 from mysqltest_2@localhost;
+commit;
+show grants for mysqltest_2@localhost;
+delete from mysql.user where user='mysqltest_1' or user="mysqltest_2" or user="mysqltest_3";
+delete from mysql.db where user='mysqltest_1' or user="mysqltest_2" or user="mysqltest_3";
+delete from mysql.tables_priv where user='mysqltest_1' or user="mysqltest_2" or user="mysqltest_3";
+delete from mysql.columns_priv where user='mysqltest_1' or user="mysqltest_2" or user="mysqltest_3";
+flush privileges;
+drop table t1;
+
+#
+# Test some error conditions
+#
+begin;
+--error 1221
+GRANT FILE on mysqltest.* to mysqltest_1@localhost;
+commit;
+select 1; -- To test that the previous command didn't cause problems
+
+#
+# Bug#6123: GRANT USAGE inserts useless Db row
+#
+create database mysqltest1;
+begin;
+grant usage on mysqltest1.* to test6123 identified by 'magic123';
+commit;
+select host,db,user,select_priv,insert_priv from mysql.db where db="mysqltest1";
+delete from mysql.user where user='test6123';
+drop database mysqltest1;
+
+#
+# Test for 'drop user', 'revoke privileges, grant'
+#
+
+create table t1 (a int);
+begin;
+grant ALL PRIVILEGES on *.* to drop_user2@localhost with GRANT OPTION;
+commit;
+show grants for drop_user2@localhost;
+begin;
+revoke all privileges, grant option from drop_user2@localhost;
+commit;
+drop user drop_user2@localhost;
+
+begin;
+grant ALL PRIVILEGES on *.* to drop_user@localhost with GRANT OPTION;
+grant ALL PRIVILEGES on test.* to drop_user@localhost with GRANT OPTION;
+grant select(a) on test.t1 to drop_user@localhost;
+commit;
+show grants for drop_user@localhost;
+
+#
+# Bug3086
+#
+set sql_mode=ansi_quotes;
+show grants for drop_user@localhost;
+set sql_mode=default;
+
+set sql_quote_show_create=0;
+show grants for drop_user@localhost;
+set sql_mode="ansi_quotes";
+show grants for drop_user@localhost;
+set sql_quote_show_create=1;
+show grants for drop_user@localhost;
+set sql_mode="";
+show grants for drop_user@localhost;
+
+revoke all privileges, grant option from drop_user@localhost;
+show grants for drop_user@localhost;
+drop user drop_user@localhost;
+begin;
+--error 1269
+revoke all privileges, grant option from drop_user@localhost;
+commit;
+
+begin;
+grant select(a) on test.t1 to drop_user1@localhost;
+commit;
+flush privileges;
+begin;
+grant select on test.t1 to drop_user2@localhost;
+grant select on test.* to drop_user3@localhost;
+grant select on *.* to drop_user4@localhost;
+commit;
+--error 1268
+drop user drop_user1@localhost, drop_user2@localhost, drop_user3@localhost,
+drop_user4@localhost;
+begin;
+revoke all privileges, grant option from drop_user1@localhost, drop_user2@localhost,
+drop_user3@localhost, drop_user4@localhost;
+commit;
+drop user drop_user1@localhost, drop_user2@localhost, drop_user3@localhost,
+drop_user4@localhost;
+drop table t1;
+begin;
+grant usage on *.* to mysqltest_1@localhost identified by "password";
+grant select, update, insert on test.* to mysqltest@localhost;
+commit;
+show grants for mysqltest_1@localhost;
+drop user mysqltest_1@localhost;
+
+#
+# Bug #3403 Wrong encodin in SHOW GRANTS output
+#
+SET NAMES koi8r;
+CREATE DATABASE ÂÄ;
+USE ÂÄ;
+CREATE TABLE ÔÁÂ (ËÏÌ int);
+
+begin;
+GRANT SELECT ON ÂÄ.* TO ÀÚÅÒ@localhost;
+commit;
+SHOW GRANTS FOR ÀÚÅÒ@localhost;
+begin;
+REVOKE SELECT ON ÂÄ.* FROM ÀÚÅÒ@localhost;
+commit;
+
+begin;
+GRANT SELECT ON ÂÄ.ÔÁÂ TO ÀÚÅÒ@localhost;
+commit;
+SHOW GRANTS FOR ÀÚÅÒ@localhost;
+begin;
+REVOKE SELECT ON ÂÄ.ÔÁÂ FROM ÀÚÅÒ@localhost;
+commit;
+
+begin;
+GRANT SELECT (ËÏÌ) ON ÂÄ.ÔÁÂ TO ÀÚÅÒ@localhost;
+commit;
+SHOW GRANTS FOR ÀÚÅÒ@localhost;
+begin;
+REVOKE SELECT (ËÏÌ) ON ÂÄ.ÔÁÂ FROM ÀÚÅÒ@localhost;
+commit;
+
+DROP DATABASE ÂÄ;
+SET NAMES latin1;
+
+#
+# Bug #5831: REVOKE ALL PRIVILEGES, GRANT OPTION does not revoke everything
+#
+USE test;
+CREATE TABLE t1 (a int );
+CREATE TABLE t2 LIKE t1;
+CREATE TABLE t3 LIKE t1;
+CREATE TABLE t4 LIKE t1;
+CREATE TABLE t5 LIKE t1;
+CREATE TABLE t6 LIKE t1;
+CREATE TABLE t7 LIKE t1;
+CREATE TABLE t8 LIKE t1;
+CREATE TABLE t9 LIKE t1;
+CREATE TABLE t10 LIKE t1;
+CREATE DATABASE testdb1;
+CREATE DATABASE testdb2;
+CREATE DATABASE testdb3;
+CREATE DATABASE testdb4;
+CREATE DATABASE testdb5;
+CREATE DATABASE testdb6;
+CREATE DATABASE testdb7;
+CREATE DATABASE testdb8;
+CREATE DATABASE testdb9;
+CREATE DATABASE testdb10;
+begin;
+GRANT ALL ON testdb1.* TO testuser@localhost;
+GRANT ALL ON testdb2.* TO testuser@localhost;
+GRANT ALL ON testdb3.* TO testuser@localhost;
+GRANT ALL ON testdb4.* TO testuser@localhost;
+GRANT ALL ON testdb5.* TO testuser@localhost;
+GRANT ALL ON testdb6.* TO testuser@localhost;
+GRANT ALL ON testdb7.* TO testuser@localhost;
+GRANT ALL ON testdb8.* TO testuser@localhost;
+GRANT ALL ON testdb9.* TO testuser@localhost;
+GRANT ALL ON testdb10.* TO testuser@localhost;
+GRANT SELECT ON test.t1 TO testuser@localhost;
+GRANT SELECT ON test.t2 TO testuser@localhost;
+GRANT SELECT ON test.t3 TO testuser@localhost;
+GRANT SELECT ON test.t4 TO testuser@localhost;
+GRANT SELECT ON test.t5 TO testuser@localhost;
+GRANT SELECT ON test.t6 TO testuser@localhost;
+GRANT SELECT ON test.t7 TO testuser@localhost;
+GRANT SELECT ON test.t8 TO testuser@localhost;
+GRANT SELECT ON test.t9 TO testuser@localhost;
+GRANT SELECT ON test.t10 TO testuser@localhost;
+GRANT SELECT (a) ON test.t1 TO testuser@localhost;
+GRANT SELECT (a) ON test.t2 TO testuser@localhost;
+GRANT SELECT (a) ON test.t3 TO testuser@localhost;
+GRANT SELECT (a) ON test.t4 TO testuser@localhost;
+GRANT SELECT (a) ON test.t5 TO testuser@localhost;
+GRANT SELECT (a) ON test.t6 TO testuser@localhost;
+GRANT SELECT (a) ON test.t7 TO testuser@localhost;
+GRANT SELECT (a) ON test.t8 TO testuser@localhost;
+GRANT SELECT (a) ON test.t9 TO testuser@localhost;
+GRANT SELECT (a) ON test.t10 TO testuser@localhost;
+commit;
+begin;
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM testuser@localhost;
+commit;
+SHOW GRANTS FOR testuser@localhost;
+DROP USER testuser@localhost;
+DROP TABLE t1,t2,t3,t4,t5,t6,t7,t8,t9,t10;
+DROP DATABASE testdb1;
+DROP DATABASE testdb2;
+DROP DATABASE testdb3;
+DROP DATABASE testdb4;
+DROP DATABASE testdb5;
+DROP DATABASE testdb6;
+DROP DATABASE testdb7;
+DROP DATABASE testdb8;
+DROP DATABASE testdb9;
+DROP DATABASE testdb10;
+
+#
+# Alter mysql system tables back to myisam
+#
+use mysql;
+alter table columns_priv engine=myisam;
+alter table db engine=myisam;
+alter table func engine=myisam;
+alter table help_category engine=myisam;
+alter table help_keyword engine=myisam;
+alter table help_relation engine=myisam;
+alter table help_topic engine=myisam;
+alter table host engine=myisam;
+alter table tables_priv engine=myisam;
+alter table time_zone engine=myisam;
+alter table time_zone_leap_second engine=myisam;
+alter table time_zone_name engine=myisam;
+alter table time_zone_transition engine=myisam;
+alter table time_zone_transition_type engine=myisam;
+alter table user engine=myisam;
+use test;
+flush privileges;
From fdfc731155188402153eb342326d5ab5dfa02544 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Fri, 19 Nov 2004 09:27:16 +0000
Subject: [PATCH 042/145] ha_ndbcluster.cc: merge error
---
sql/ha_ndbcluster.cc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index fd8660b29d2..bec4dfd9401 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -107,7 +107,7 @@ static const err_code_mapping err_map[]=
{
{ 626, HA_ERR_KEY_NOT_FOUND, 0 },
{ 630, HA_ERR_FOUND_DUPP_KEY, 0 },
- { 893, HA_ERR_FOUND_DUPP_UNIQUE, 0 },
+ { 893, HA_ERR_FOUND_DUPP_KEY, 0 },
{ 721, HA_ERR_TABLE_EXIST, 1 },
{ 4244, HA_ERR_TABLE_EXIST, 1 },
From 73f098836f9b09365b70a07e3bb635be833df80a Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Fri, 19 Nov 2004 09:35:12 +0000
Subject: [PATCH 043/145] added to ignore list
---
.bzrignore | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/.bzrignore b/.bzrignore
index e794d7d51cc..f98e9f7e6b6 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -924,3 +924,18 @@ Docs/Images/mydsn.txt
Docs/Images/myflowchart.txt
mysql-test/mysql_test_run_new
ndb/tools/ndb_test_platform
+help
+ndbcluster-1186
+ndbcluster-1186/SCCS
+ndbcluster-1186/config.ini
+ndbcluster-1186/ndb_1.pid
+ndbcluster-1186/ndb_1_out.log
+ndbcluster-1186/ndb_1_signal.log
+ndbcluster-1186/ndb_2.pid
+ndbcluster-1186/ndb_2_out.log
+ndbcluster-1186/ndb_2_signal.log
+ndbcluster-1186/ndb_3.pid
+ndbcluster-1186/ndb_3_cluster.log
+ndbcluster-1186/ndb_3_out.log
+ndbcluster-1186/ndbcluster.pid
+../ndb/tools/ndb_restore
From b67491ee41c89f4636844b15666c90185cb41e78 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Fri, 19 Nov 2004 09:38:41 +0000
Subject: [PATCH 044/145] ignore fix
---
.bzrignore | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.bzrignore b/.bzrignore
index f98e9f7e6b6..670d46db613 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -938,4 +938,4 @@ ndbcluster-1186/ndb_3.pid
ndbcluster-1186/ndb_3_cluster.log
ndbcluster-1186/ndb_3_out.log
ndbcluster-1186/ndbcluster.pid
-../ndb/tools/ndb_restore
+ndb/tools/ndb_restore
From f9d1a5a1c6505509d54edb46b5f2e6af20d14ff6 Mon Sep 17 00:00:00 2001
From: "bar@mysql.com" <>
Date: Fri, 19 Nov 2004 14:25:25 +0400
Subject: [PATCH 045/145] Incorrect response with partial utf8 index
---
mysql-test/include/ctype_common.inc | 56 +++++++++++++++++++++
mysql-test/r/ctype_uca.result | 57 ++++++++++++++++++++++
mysql-test/t/ctype_uca.test | 4 ++
strings/ctype-mb.c | 75 +++++++++++++++++------------
strings/ctype-uca.c | 32 ++++++------
5 files changed, 178 insertions(+), 46 deletions(-)
create mode 100644 mysql-test/include/ctype_common.inc
diff --git a/mysql-test/include/ctype_common.inc b/mysql-test/include/ctype_common.inc
new file mode 100644
index 00000000000..77937bdb854
--- /dev/null
+++ b/mysql-test/include/ctype_common.inc
@@ -0,0 +1,56 @@
+#
+# Common tests for all character sets and collations.
+# Include this file from a test with @test_characrer_set
+# and @test_collation set to desired values.
+#
+# Please don't use SHOW CREATE TABLE in this file,
+# we want it to be HANDLER independent. You can
+# use SHOW FULL COLUMNS instead.
+#
+# Please surround all CREATE TABLE with --disable_warnings
+# and --enable_warnings to be able to set storage_engine
+# without having to check if the hanlder exists.
+
+SET @safe_character_set_server= @@character_set_server;
+SET @safe_collation_server= @@collation_server;
+SET character_set_server= @test_character_set;
+SET collation_server= @test_collation;
+CREATE DATABASE d1;
+USE d1;
+
+#
+# Bug 1883: LIKE did not work in some cases with a key.
+#
+--disable_warnings
+CREATE TABLE t1 (c CHAR(10), KEY(c));
+--enable_warnings
+# check the column was created with the expected charset/collation
+SHOW FULL COLUMNS FROM t1;
+INSERT INTO t1 VALUES ('aaa'),('aaaa'),('aaaaa');
+SELECT c as want3results FROM t1 WHERE c LIKE 'aaa%';
+DROP TABLE t1;
+
+#
+# Bug 6643 incorrect response with partial utf8 index
+#
+--disable_warnings
+CREATE TABLE t1 (c1 varchar(15), KEY c1 (c1(2)));
+--enable_warnings
+# check the column was created with the expected charset/collation
+SHOW FULL COLUMNS FROM t1;
+INSERT INTO t1 VALUES ('location'),('loberge'),('lotre'),('boabab');
+SELECT c1 as want3results from t1 where c1 like 'l%';
+SELECT c1 as want3results from t1 where c1 like 'lo%';
+SELECT c1 as want1result from t1 where c1 like 'loc%';
+SELECT c1 as want1result from t1 where c1 like 'loca%';
+SELECT c1 as want1result from t1 where c1 like 'locat%';
+SELECT c1 as want1result from t1 where c1 like 'locati%';
+SELECT c1 as want1result from t1 where c1 like 'locatio%';
+SELECT c1 as want1result from t1 where c1 like 'location%';
+DROP TABLE t1;
+
+DROP DATABASE d1;
+# Restore settings
+USE test;
+SET character_set_server= @safe_character_set_server;
+SET collation_server= @safe_collation_server;
diff --git a/mysql-test/r/ctype_uca.result b/mysql-test/r/ctype_uca.result
index 90681795513..7620b18eea6 100644
--- a/mysql-test/r/ctype_uca.result
+++ b/mysql-test/r/ctype_uca.result
@@ -2315,3 +2315,60 @@ HEX(CONVERT(col1 USING ucs2))
064A06A9062F064A06AF0631
064A06A9064A
DROP TABLE t1;
+SET @test_character_set= 'utf8';
+SET @test_collation= 'utf8_swedish_ci';
+SET @safe_character_set_server= @@character_set_server;
+SET @safe_collation_server= @@collation_server;
+SET character_set_server= @test_character_set;
+SET collation_server= @test_collation;
+CREATE DATABASE d1;
+USE d1;
+CREATE TABLE t1 (c CHAR(10), KEY(c));
+SHOW FULL COLUMNS FROM t1;
+Field Type Collation Null Key Default Extra Privileges Comment
+c char(10) utf8_swedish_ci YES MUL NULL select,insert,update,references
+INSERT INTO t1 VALUES ('aaa'),('aaaa'),('aaaaa');
+SELECT c as want3results FROM t1 WHERE c LIKE 'aaa%';
+want3results
+aaa
+aaaa
+aaaaa
+DROP TABLE t1;
+CREATE TABLE t1 (c1 varchar(15), KEY c1 (c1(2)));
+SHOW FULL COLUMNS FROM t1;
+Field Type Collation Null Key Default Extra Privileges Comment
+c1 varchar(15) utf8_swedish_ci YES MUL NULL select,insert,update,references
+INSERT INTO t1 VALUES ('location'),('loberge'),('lotre'),('boabab');
+SELECT c1 as want3results from t1 where c1 like 'l%';
+want3results
+location
+loberge
+lotre
+SELECT c1 as want3results from t1 where c1 like 'lo%';
+want3results
+location
+loberge
+lotre
+SELECT c1 as want1result from t1 where c1 like 'loc%';
+want1result
+location
+SELECT c1 as want1result from t1 where c1 like 'loca%';
+want1result
+location
+SELECT c1 as want1result from t1 where c1 like 'locat%';
+want1result
+location
+SELECT c1 as want1result from t1 where c1 like 'locati%';
+want1result
+location
+SELECT c1 as want1result from t1 where c1 like 'locatio%';
+want1result
+location
+SELECT c1 as want1result from t1 where c1 like 'location%';
+want1result
+location
+DROP TABLE t1;
+DROP DATABASE d1;
+USE test;
+SET character_set_server= @safe_character_set_server;
+SET collation_server= @safe_collation_server;
diff --git a/mysql-test/t/ctype_uca.test b/mysql-test/t/ctype_uca.test
index 708a31d637e..e640e6b53dc 100644
--- a/mysql-test/t/ctype_uca.test
+++ b/mysql-test/t/ctype_uca.test
@@ -435,3 +435,7 @@ INSERT INTO t1 VALUES (CONVERT(_ucs2 0x06280648062F0646062F USING utf8));
INSERT INTO t1 VALUES (CONVERT(_ucs2 0x06450647064506270646 USING utf8));
SELECT HEX(CONVERT(col1 USING ucs2)) FROM t1 ORDER BY col1 COLLATE utf8_persian_ci, col1 COLLATE utf8_bin;
DROP TABLE t1;
+
+SET @test_character_set= 'utf8';
+SET @test_collation= 'utf8_swedish_ci';
+-- source include/ctype_common.inc
diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c
index 7d81766c4cb..3cdf7f460cd 100644
--- a/strings/ctype-mb.c
+++ b/strings/ctype-mb.c
@@ -443,6 +443,37 @@ static void my_hash_sort_mb_bin(CHARSET_INFO *cs __attribute__((unused)),
}
}
+
+/*
+ Write max key: create a buffer with multibyte
+ representation of the max_sort_char character,
+ and copy it into max_str in a loop.
+*/
+static void pad_max_char(CHARSET_INFO *cs, char *str, char *end)
+{
+ char buf[10];
+ char buflen= cs->cset->wc_mb(cs, cs->max_sort_char, (uchar*) buf,
+ (uchar*) buf + sizeof(buf));
+ DBUG_ASSERT(buflen > 0);
+ do
+ {
+ if ((str + buflen) < end)
+ {
+ /* Enough space for the characer */
+ memcpy(str, buf, buflen);
+ str+= buflen;
+ }
+ else
+ {
+ /*
+ There is no space for whole multibyte
+ character, then add trailing spaces.
+ */
+ *str++= ' ';
+ }
+ } while (str < end);
+}
+
/*
** Calculate min_str and max_str that ranges a LIKE string.
** Arguments:
@@ -467,10 +498,15 @@ my_bool my_like_range_mb(CHARSET_INFO *cs,
char *min_str,char *max_str,
uint *min_length,uint *max_length)
{
- const char *end=ptr+ptr_length;
- char *min_org=min_str;
- char *min_end=min_str+res_length;
- char *max_end=max_str+res_length;
+ const char *end;
+ char *min_org= min_str;
+ char *min_end= min_str + res_length;
+ char *max_end= max_str + res_length;
+ uint charlen= my_charpos(cs, ptr, ptr+ptr_length, res_length/cs->mbmaxlen);
+
+ if (charlen < ptr_length)
+ ptr_length= charlen;
+ end= ptr + ptr_length;
for (; ptr != end && min_str != min_end ; ptr++)
{
@@ -482,16 +518,14 @@ my_bool my_like_range_mb(CHARSET_INFO *cs,
}
if (*ptr == w_one || *ptr == w_many) /* '_' and '%' in SQL */
{
- char buf[10];
- uint buflen;
- uint charlen= my_charpos(cs, min_org, min_str, res_length/cs->mbmaxlen);
+ charlen= my_charpos(cs, min_org, min_str, res_length/cs->mbmaxlen);
if (charlen < (uint) (min_str - min_org))
min_str= min_org + charlen;
/* Write min key */
*min_length= (uint) (min_str - min_org);
- *max_length=res_length;
+ *max_length= res_length;
do
{
*min_str++= (char) cs->min_sort_char;
@@ -502,27 +536,7 @@ my_bool my_like_range_mb(CHARSET_INFO *cs,
representation of the max_sort_char character,
and copy it into max_str in a loop.
*/
- buflen= cs->cset->wc_mb(cs, cs->max_sort_char, (uchar*) buf,
- (uchar*) buf + sizeof(buf));
- DBUG_ASSERT(buflen > 0);
- do
- {
- if ((max_str + buflen) <= max_end)
- {
- /* Enough space for max characer */
- memcpy(max_str, buf, buflen);
- max_str+= buflen;
- }
- else
- {
- /*
- There is no space for whole multibyte
- character, then add trailing spaces.
- */
-
- *max_str++= ' ';
- }
- } while (max_str != max_end);
+ pad_max_char(cs, max_str, max_end);
return 0;
}
*min_str++= *max_str++ = *ptr;
@@ -530,7 +544,8 @@ my_bool my_like_range_mb(CHARSET_INFO *cs,
*min_length= *max_length = (uint) (min_str - min_org);
while (min_str != min_end)
- *min_str++ = *max_str++ = ' '; /* Because if key compression */
+ *min_str++= ' '; /* Because if key compression */
+ pad_max_char(cs, max_str, max_end);
return 0;
}
diff --git a/strings/ctype-uca.c b/strings/ctype-uca.c
index 91af7af0c54..8df5b3277c1 100644
--- a/strings/ctype-uca.c
+++ b/strings/ctype-uca.c
@@ -8567,7 +8567,7 @@ CHARSET_INFO my_charset_utf8_icelandic_uca_ci=
NULL, /* ident_map */
8, /* strxfrm_multiply */
1, /* mbminlen */
- 2, /* mbmaxlen */
+ 3, /* mbmaxlen */
9, /* min_sort_char */
0xFFFF, /* max_sort_char */
&my_charset_utf8_handler,
@@ -8594,7 +8594,7 @@ CHARSET_INFO my_charset_utf8_latvian_uca_ci=
NULL, /* ident_map */
8, /* strxfrm_multiply */
1, /* mbminlen */
- 2, /* mbmaxlen */
+ 3, /* mbmaxlen */
9, /* min_sort_char */
0xFFFF, /* max_sort_char */
&my_charset_utf8_handler,
@@ -8621,7 +8621,7 @@ CHARSET_INFO my_charset_utf8_romanian_uca_ci=
NULL, /* ident_map */
8, /* strxfrm_multiply */
1, /* mbminlen */
- 2, /* mbmaxlen */
+ 3, /* mbmaxlen */
9, /* min_sort_char */
0xFFFF, /* max_sort_char */
&my_charset_utf8_handler,
@@ -8648,7 +8648,7 @@ CHARSET_INFO my_charset_utf8_slovenian_uca_ci=
NULL, /* ident_map */
8, /* strxfrm_multiply */
1, /* mbminlen */
- 2, /* mbmaxlen */
+ 3, /* mbmaxlen */
9, /* min_sort_char */
0xFFFF, /* max_sort_char */
&my_charset_utf8_handler,
@@ -8675,7 +8675,7 @@ CHARSET_INFO my_charset_utf8_polish_uca_ci=
NULL, /* ident_map */
8, /* strxfrm_multiply */
1, /* mbminlen */
- 2, /* mbmaxlen */
+ 3, /* mbmaxlen */
9, /* min_sort_char */
0xFFFF, /* max_sort_char */
&my_charset_utf8_handler,
@@ -8702,7 +8702,7 @@ CHARSET_INFO my_charset_utf8_estonian_uca_ci=
NULL, /* ident_map */
8, /* strxfrm_multiply */
1, /* mbminlen */
- 2, /* mbmaxlen */
+ 3, /* mbmaxlen */
9, /* min_sort_char */
0xFFFF, /* max_sort_char */
&my_charset_utf8_handler,
@@ -8729,7 +8729,7 @@ CHARSET_INFO my_charset_utf8_spanish_uca_ci=
NULL, /* ident_map */
8, /* strxfrm_multiply */
1, /* mbminlen */
- 2, /* mbmaxlen */
+ 3, /* mbmaxlen */
9, /* min_sort_char */
0xFFFF, /* max_sort_char */
&my_charset_utf8_handler,
@@ -8756,7 +8756,7 @@ CHARSET_INFO my_charset_utf8_swedish_uca_ci=
NULL, /* ident_map */
8, /* strxfrm_multiply */
1, /* mbminlen */
- 2, /* mbmaxlen */
+ 3, /* mbmaxlen */
9, /* min_sort_char */
0xFFFF, /* max_sort_char */
&my_charset_utf8_handler,
@@ -8783,7 +8783,7 @@ CHARSET_INFO my_charset_utf8_turkish_uca_ci=
NULL, /* ident_map */
8, /* strxfrm_multiply */
1, /* mbminlen */
- 2, /* mbmaxlen */
+ 3, /* mbmaxlen */
9, /* min_sort_char */
0xFFFF, /* max_sort_char */
&my_charset_utf8_handler,
@@ -8810,7 +8810,7 @@ CHARSET_INFO my_charset_utf8_czech_uca_ci=
NULL, /* ident_map */
8, /* strxfrm_multiply */
1, /* mbminlen */
- 2, /* mbmaxlen */
+ 3, /* mbmaxlen */
9, /* min_sort_char */
0xFFFF, /* max_sort_char */
&my_charset_utf8_handler,
@@ -8838,7 +8838,7 @@ CHARSET_INFO my_charset_utf8_danish_uca_ci=
NULL, /* ident_map */
8, /* strxfrm_multiply */
1, /* mbminlen */
- 2, /* mbmaxlen */
+ 3, /* mbmaxlen */
9, /* min_sort_char */
0xFFFF, /* max_sort_char */
&my_charset_utf8_handler,
@@ -8865,7 +8865,7 @@ CHARSET_INFO my_charset_utf8_lithuanian_uca_ci=
NULL, /* ident_map */
8, /* strxfrm_multiply */
1, /* mbminlen */
- 2, /* mbmaxlen */
+ 3, /* mbmaxlen */
9, /* min_sort_char */
0xFFFF, /* max_sort_char */
&my_charset_utf8_handler,
@@ -8892,7 +8892,7 @@ CHARSET_INFO my_charset_utf8_slovak_uca_ci=
NULL, /* ident_map */
8, /* strxfrm_multiply */
1, /* mbminlen */
- 2, /* mbmaxlen */
+ 3, /* mbmaxlen */
9, /* min_sort_char */
0xFFFF, /* max_sort_char */
&my_charset_utf8_handler,
@@ -8919,7 +8919,7 @@ CHARSET_INFO my_charset_utf8_spanish2_uca_ci=
NULL, /* ident_map */
8, /* strxfrm_multiply */
1, /* mbminlen */
- 2, /* mbmaxlen */
+ 3, /* mbmaxlen */
9, /* min_sort_char */
0xFFFF, /* max_sort_char */
&my_charset_utf8_handler,
@@ -8946,7 +8946,7 @@ CHARSET_INFO my_charset_utf8_roman_uca_ci=
NULL, /* ident_map */
8, /* strxfrm_multiply */
1, /* mbminlen */
- 2, /* mbmaxlen */
+ 3, /* mbmaxlen */
9, /* min_sort_char */
0xFFFF, /* max_sort_char */
&my_charset_utf8_handler,
@@ -8973,7 +8973,7 @@ CHARSET_INFO my_charset_utf8_persian_uca_ci=
NULL, /* ident_map */
8, /* strxfrm_multiply */
1, /* mbminlen */
- 2, /* mbmaxlen */
+ 3, /* mbmaxlen */
9, /* min_sort_char */
0xFFFF, /* max_sort_char */
&my_charset_utf8_handler,
From 9e924a490264b747b6ab324997c5006f725dc673 Mon Sep 17 00:00:00 2001
From: "joreland@mysql.com" <>
Date: Fri, 19 Nov 2004 11:31:20 +0100
Subject: [PATCH 046/145] wl2077 - ndb scan optimizations
---
ndb/src/kernel/blocks/dbdih/Dbdih.hpp | 1 -
ndb/src/kernel/blocks/dbdih/DbdihMain.cpp | 20 +++++++++-----------
ndb/src/kernel/blocks/dbtc/DbtcMain.cpp | 14 ++++++++++++++
ndb/test/ndbapi/testReadPerf.cpp | 11 +++++++++--
4 files changed, 32 insertions(+), 14 deletions(-)
diff --git a/ndb/src/kernel/blocks/dbdih/Dbdih.hpp b/ndb/src/kernel/blocks/dbdih/Dbdih.hpp
index 14fa262f871..0a2d50cb876 100644
--- a/ndb/src/kernel/blocks/dbdih/Dbdih.hpp
+++ b/ndb/src/kernel/blocks/dbdih/Dbdih.hpp
@@ -147,7 +147,6 @@ public:
Uint32 nfConnect;
Uint32 table;
Uint32 userpointer;
- Uint32 nodeCount;
BlockReference userblockref;
};
typedef Ptr ConnectRecordPtr;
diff --git a/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp b/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
index 76aa745c3e0..4592b121c7e 100644
--- a/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
+++ b/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
@@ -7080,24 +7080,22 @@ void Dbdih::execDIGETPRIMREQ(Signal* signal)
ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_ACTIVE);
connectPtr.i = signal->theData[0];
- if(connectPtr.i != RNIL){
+ if(connectPtr.i != RNIL)
+ {
jam();
ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
- ndbrequire(connectPtr.p->connectState == ConnectRecord::INUSE);
- getFragstore(tabPtr.p, fragId, fragPtr);
- connectPtr.p->nodeCount = extractNodeInfo(fragPtr.p, connectPtr.p->nodes);
signal->theData[0] = connectPtr.p->userpointer;
- signal->theData[1] = passThrough;
- signal->theData[2] = connectPtr.p->nodes[0];
- sendSignal(connectPtr.p->userblockref, GSN_DIGETPRIMCONF, signal, 3, JBB);
- return;
- }//if
- //connectPtr.i == RNIL -> question without connect record
+ }
+ else
+ {
+ jam();
+ signal->theData[0] = RNIL;
+ }
+
Uint32 nodes[MAX_REPLICAS];
getFragstore(tabPtr.p, fragId, fragPtr);
Uint32 count = extractNodeInfo(fragPtr.p, nodes);
- signal->theData[0] = RNIL;
signal->theData[1] = passThrough;
signal->theData[2] = nodes[0];
signal->theData[3] = nodes[1];
diff --git a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
index c7f467484bd..8c663b42cbe 100644
--- a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
+++ b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
@@ -8944,6 +8944,20 @@ void Dbtc::execDIGETPRIMCONF(Signal* signal)
scanptr.i = scanFragptr.p->scanRec;
ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord);
+ if(ScanFragReq::getReadCommittedFlag(scanptr.p->scanRequestInfo))
+ {
+ jam();
+ Uint32 max = 3+signal->theData[6];
+ Uint32 nodeid = getOwnNodeId();
+ for(Uint32 i = 3; itheData[i] == nodeid)
+ {
+ jam();
+ tnodeid = nodeid;
+ break;
+ }
+ }
+
{
/**
* Check table
diff --git a/ndb/test/ndbapi/testReadPerf.cpp b/ndb/test/ndbapi/testReadPerf.cpp
index 380a809ad00..3adcb5a2d9b 100644
--- a/ndb/test/ndbapi/testReadPerf.cpp
+++ b/ndb/test/ndbapi/testReadPerf.cpp
@@ -391,8 +391,15 @@ run_read(){
void
print_result(){
+ int tmp = 1;
+ tmp *= g_paramters[P_RANGE].value;
+ tmp *= g_paramters[P_LOOPS].value;
+
+ int t, t2;
for(int i = 0; i
Date: Fri, 19 Nov 2004 14:33:55 +0400
Subject: [PATCH 047/145] Reuse ctype_common.inc instead of retyping the same
queries.
---
mysql-test/r/ctype_big5.result | 56 +++++++++++++++++++++++++++++++---
mysql-test/t/ctype_big5.test | 12 ++------
2 files changed, 55 insertions(+), 13 deletions(-)
diff --git a/mysql-test/r/ctype_big5.result b/mysql-test/r/ctype_big5.result
index 44fad0cd96a..789b6e586ad 100644
--- a/mysql-test/r/ctype_big5.result
+++ b/mysql-test/r/ctype_big5.result
@@ -1,10 +1,58 @@
drop table if exists t1;
-SET NAMES big5;
-CREATE TABLE t1 (c CHAR(10) CHARACTER SET big5, KEY(c));
+SET @test_character_set= 'big5';
+SET @test_collation= 'big5_chinese_ci';
+SET @safe_character_set_server= @@character_set_server;
+SET @safe_collation_server= @@collation_server;
+SET character_set_server= @test_character_set;
+SET collation_server= @test_collation;
+CREATE DATABASE d1;
+USE d1;
+CREATE TABLE t1 (c CHAR(10), KEY(c));
+SHOW FULL COLUMNS FROM t1;
+Field Type Collation Null Key Default Extra Privileges Comment
+c char(10) big5_chinese_ci YES MUL NULL select,insert,update,references
INSERT INTO t1 VALUES ('aaa'),('aaaa'),('aaaaa');
-SELECT * FROM t1 WHERE c LIKE 'aaa%';
-c
+SELECT c as want3results FROM t1 WHERE c LIKE 'aaa%';
+want3results
aaa
aaaa
aaaaa
DROP TABLE t1;
+CREATE TABLE t1 (c1 varchar(15), KEY c1 (c1(2)));
+SHOW FULL COLUMNS FROM t1;
+Field Type Collation Null Key Default Extra Privileges Comment
+c1 varchar(15) big5_chinese_ci YES MUL NULL select,insert,update,references
+INSERT INTO t1 VALUES ('location'),('loberge'),('lotre'),('boabab');
+SELECT c1 as want3results from t1 where c1 like 'l%';
+want3results
+location
+loberge
+lotre
+SELECT c1 as want3results from t1 where c1 like 'lo%';
+want3results
+location
+loberge
+lotre
+SELECT c1 as want1result from t1 where c1 like 'loc%';
+want1result
+location
+SELECT c1 as want1result from t1 where c1 like 'loca%';
+want1result
+location
+SELECT c1 as want1result from t1 where c1 like 'locat%';
+want1result
+location
+SELECT c1 as want1result from t1 where c1 like 'locati%';
+want1result
+location
+SELECT c1 as want1result from t1 where c1 like 'locatio%';
+want1result
+location
+SELECT c1 as want1result from t1 where c1 like 'location%';
+want1result
+location
+DROP TABLE t1;
+DROP DATABASE d1;
+USE test;
+SET character_set_server= @safe_character_set_server;
+SET collation_server= @safe_collation_server;
diff --git a/mysql-test/t/ctype_big5.test b/mysql-test/t/ctype_big5.test
index 9bf1808636e..b1d71a6af15 100644
--- a/mysql-test/t/ctype_big5.test
+++ b/mysql-test/t/ctype_big5.test
@@ -7,12 +7,6 @@
drop table if exists t1;
--enable_warnings
-SET NAMES big5;
-
-#
-# Bug 1883: LIKE did not work in some cases with a key.
-#
-CREATE TABLE t1 (c CHAR(10) CHARACTER SET big5, KEY(c));
-INSERT INTO t1 VALUES ('aaa'),('aaaa'),('aaaaa');
-SELECT * FROM t1 WHERE c LIKE 'aaa%';
-DROP TABLE t1;
+SET @test_character_set= 'big5';
+SET @test_collation= 'big5_chinese_ci';
+-- source include/ctype_common.inc
From b254e69a385b583096ddc19b7b8d067221d1036e Mon Sep 17 00:00:00 2001
From: "joreland@mysql.com" <>
Date: Fri, 19 Nov 2004 11:37:16 +0100
Subject: [PATCH 048/145] wl2077 - scan optimizations (recommit in clean clone)
---
ndb/docs/wl2077.txt | 35 +++++++++++++++++++++++
ndb/src/kernel/blocks/dbdih/Dbdih.hpp | 1 -
ndb/src/kernel/blocks/dbdih/DbdihMain.cpp | 20 ++++++-------
ndb/src/kernel/blocks/dbtc/DbtcMain.cpp | 14 +++++++++
ndb/test/ndbapi/testReadPerf.cpp | 11 +++++--
5 files changed, 67 insertions(+), 14 deletions(-)
create mode 100644 ndb/docs/wl2077.txt
diff --git a/ndb/docs/wl2077.txt b/ndb/docs/wl2077.txt
new file mode 100644
index 00000000000..5a77c18aa2a
--- /dev/null
+++ b/ndb/docs/wl2077.txt
@@ -0,0 +1,35 @@
+
+100' * (select 1 from T1 (1M rows) where key = rand());
+1 host, 1 ndbd, api co-hosted
+results in 1000 rows / sec
+
+ wo/reset bounds w/ rb
+4.1-read committed a) 4.9 b) 7.4
+4.1-read hold lock c) 4.7 d) 6.7
+
+wl2077-read committed 6.4 (+30%) 10.8 (+45%)
+wl2077-read hold lock 4.6 (-1%) 6.7 (+ 0%)
+
+-- Comparision e)
+serial pk: 10.9'
+batched (1000): 59'
+serial uniq index: 8.4'
+batched (1000): 33'
+index range (1000): 186'
+
+----
+
+load) testScanPerf -c 1 -d 1 T1
+a) testScanPerf -s 100000 -c 0 -d 0 -a 1 -l 0 -r 2 -q 0 T1
+b) testScanPerf -s 100000 -c 0 -d 0 -a 1 -l 0 -r 2 -q 1 T1
+c) testScanPerf -s 100000 -c 0 -d 0 -a 1 -l 1 -r 2 -q 0 T1
+d) testScanPerf -s 100000 -c 0 -d 0 -a 1 -l 1 -r 2 -q 1 T1
+e) testReadPerf -i 25 -c 0 -d 0 T1
+
+--- music join 1db-co 2db-co
+
+4.1 13s 14s
+4.1 wo/ blobs 1.7s 3.2s
+
+wl2077 12s 14s
+wl2077 wo/ blobs 1.2s (-30%) 2.5s (-22%)
diff --git a/ndb/src/kernel/blocks/dbdih/Dbdih.hpp b/ndb/src/kernel/blocks/dbdih/Dbdih.hpp
index 14fa262f871..0a2d50cb876 100644
--- a/ndb/src/kernel/blocks/dbdih/Dbdih.hpp
+++ b/ndb/src/kernel/blocks/dbdih/Dbdih.hpp
@@ -147,7 +147,6 @@ public:
Uint32 nfConnect;
Uint32 table;
Uint32 userpointer;
- Uint32 nodeCount;
BlockReference userblockref;
};
typedef Ptr ConnectRecordPtr;
diff --git a/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp b/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
index 76aa745c3e0..4592b121c7e 100644
--- a/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
+++ b/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
@@ -7080,24 +7080,22 @@ void Dbdih::execDIGETPRIMREQ(Signal* signal)
ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_ACTIVE);
connectPtr.i = signal->theData[0];
- if(connectPtr.i != RNIL){
+ if(connectPtr.i != RNIL)
+ {
jam();
ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
- ndbrequire(connectPtr.p->connectState == ConnectRecord::INUSE);
- getFragstore(tabPtr.p, fragId, fragPtr);
- connectPtr.p->nodeCount = extractNodeInfo(fragPtr.p, connectPtr.p->nodes);
signal->theData[0] = connectPtr.p->userpointer;
- signal->theData[1] = passThrough;
- signal->theData[2] = connectPtr.p->nodes[0];
- sendSignal(connectPtr.p->userblockref, GSN_DIGETPRIMCONF, signal, 3, JBB);
- return;
- }//if
- //connectPtr.i == RNIL -> question without connect record
+ }
+ else
+ {
+ jam();
+ signal->theData[0] = RNIL;
+ }
+
Uint32 nodes[MAX_REPLICAS];
getFragstore(tabPtr.p, fragId, fragPtr);
Uint32 count = extractNodeInfo(fragPtr.p, nodes);
- signal->theData[0] = RNIL;
signal->theData[1] = passThrough;
signal->theData[2] = nodes[0];
signal->theData[3] = nodes[1];
diff --git a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
index c7f467484bd..8c663b42cbe 100644
--- a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
+++ b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
@@ -8944,6 +8944,20 @@ void Dbtc::execDIGETPRIMCONF(Signal* signal)
scanptr.i = scanFragptr.p->scanRec;
ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord);
+ if(ScanFragReq::getReadCommittedFlag(scanptr.p->scanRequestInfo))
+ {
+ jam();
+ Uint32 max = 3+signal->theData[6];
+ Uint32 nodeid = getOwnNodeId();
+ for(Uint32 i = 3; itheData[i] == nodeid)
+ {
+ jam();
+ tnodeid = nodeid;
+ break;
+ }
+ }
+
{
/**
* Check table
diff --git a/ndb/test/ndbapi/testReadPerf.cpp b/ndb/test/ndbapi/testReadPerf.cpp
index 8d0d78cbe8c..f8ecc6192dc 100644
--- a/ndb/test/ndbapi/testReadPerf.cpp
+++ b/ndb/test/ndbapi/testReadPerf.cpp
@@ -390,8 +390,15 @@ run_read(){
void
print_result(){
+ int tmp = 1;
+ tmp *= g_paramters[P_RANGE].value;
+ tmp *= g_paramters[P_LOOPS].value;
+
+ int t, t2;
for(int i = 0; i
Date: Fri, 19 Nov 2004 11:19:27 +0000
Subject: [PATCH 049/145] fixed error messages for some error codes
---
ndb/src/ndbapi/ndberror.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/ndb/src/ndbapi/ndberror.c b/ndb/src/ndbapi/ndberror.c
index 1a0d8132d71..e08b80f2433 100644
--- a/ndb/src/ndbapi/ndberror.c
+++ b/ndb/src/ndbapi/ndberror.c
@@ -53,6 +53,9 @@ typedef struct ErrorBundle {
#define NI ndberror_cl_function_not_implemented
#define UE ndberror_cl_unknown_error_code
+static const char REDO_BUFFER_MSG[]=
+"REDO log buffers overloaded, consult online manual (increase RedoBuffer, and|or decrease TimeBetweenLocalCheckpoints, and|or increase NoOfFragmentLogFiles)";
+
static const char* empty_string = "";
static
@@ -137,9 +140,8 @@ ErrorBundle ErrorCodes[] = {
{ 805, TR, "Out of attrinfo records in tuple manager" },
{ 830, TR, "Out of add fragment operation records" },
{ 873, TR, "Out of attrinfo records for scan in tuple manager" },
- { 1217, TR, "1217" },
- { 1219, TR, "Out of operation records in local data manager (increase MaxNoOfLocalOperations)" },
- { 1220, TR, "1220" },
+ { 1217, TR, "Out of operation records in local data manager (increase MaxNoOfLocalOperations)" },
+ { 1220, TR, REDO_BUFFER_MSG },
{ 1222, TR, "Out of transaction markers in LQH" },
{ 4021, TR, "Out of Send Buffer space in NDB API" },
{ 4022, TR, "Out of Send Buffer space in NDB API" },
@@ -165,14 +167,13 @@ ErrorBundle ErrorCodes[] = {
{ 297, TO, "Time-out in NDB, probably caused by deadlock" }, /* Scan trans timeout, temporary!! */
{ 237, TO, "Transaction had timed out when trying to commit it" },
-
/**
* OverloadError
*/
- { 410, OL, "Out of log file space temporarily" },
+ { 410, OL, REDO_BUFFER_MSG },
{ 677, OL, "Index UNDO buffers overloaded (increase UndoIndexBuffer)" },
{ 891, OL, "Data UNDO buffers overloaded (increase UndoDataBuffer)" },
- { 1221, OL, "REDO log buffers overloaded (increase RedoBuffer)" },
+ { 1221, OL, REDO_BUFFER_MSG },
{ 4006, OL, "Connect failure - out of connection objects (increase MaxNoOfConcurrentTransactions)" },
From 56a59cf301dc5ee8790d72d1ff2c606a0921d558 Mon Sep 17 00:00:00 2001
From: "joreland@mysql.com" <>
Date: Fri, 19 Nov 2004 13:52:01 +0100
Subject: [PATCH 050/145] wl2077: ndb, disable scanning of backup fragments
(temporary)
---
ndb/src/kernel/blocks/dbtc/DbtcMain.cpp | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
index 8c663b42cbe..9af770db5b7 100644
--- a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
+++ b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
@@ -8944,7 +8944,12 @@ void Dbtc::execDIGETPRIMCONF(Signal* signal)
scanptr.i = scanFragptr.p->scanRec;
ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord);
- if(ScanFragReq::getReadCommittedFlag(scanptr.p->scanRequestInfo))
+ /**
+ * This must be false as select count(*) otherwise
+ * can "pass" committing on backup fragments and
+ * get incorrect row count
+ */
+ if(false && ScanFragReq::getReadCommittedFlag(scanptr.p->scanRequestInfo))
{
jam();
Uint32 max = 3+signal->theData[6];
From da7c9e26a008586fd961668557104ac50074df0f Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Fri, 19 Nov 2004 13:52:21 +0000
Subject: [PATCH 051/145] set sizes array sizes correctly in ndb blocks
configuration
---
ndb/src/kernel/vm/Configuration.cpp | 36 ++++++++++++++++-------------
1 file changed, 20 insertions(+), 16 deletions(-)
diff --git a/ndb/src/kernel/vm/Configuration.cpp b/ndb/src/kernel/vm/Configuration.cpp
index b3a436275f7..c2f47adff29 100644
--- a/ndb/src/kernel/vm/Configuration.cpp
+++ b/ndb/src/kernel/vm/Configuration.cpp
@@ -590,6 +590,23 @@ Configuration::calcSizeAlt(ConfigValues * ownConfig){
*/
ConfigValuesFactory cfg(ownConfig);
+ Uint32 noOfMetaTables= noOfTables + noOfOrderedIndexes +
+ noOfUniqueHashIndexes;
+ if (noOfMetaTables > MAX_TABLES)
+ noOfMetaTables= MAX_TABLES;
+
+ {
+ /**
+ * Dict Size Alt values
+ */
+ cfg.put(CFG_DICT_ATTRIBUTE,
+ noOfAttributes);
+
+ cfg.put(CFG_DICT_TABLE,
+ noOfMetaTables);
+ }
+
+
if (noOfLocalScanRecords == 0) {
noOfLocalScanRecords = (noOfDBNodes * noOfScanRecords) + 1;
}
@@ -599,7 +616,7 @@ Configuration::calcSizeAlt(ConfigValues * ownConfig){
Uint32 noOfTCScanRecords = noOfScanRecords;
{
- Uint32 noOfAccTables= noOfTables + noOfUniqueHashIndexes;
+ Uint32 noOfAccTables= noOfMetaTables/*noOfTables+noOfUniqueHashIndexes*/;
/**
* Acc Size Alt values
*/
@@ -641,19 +658,6 @@ Configuration::calcSizeAlt(ConfigValues * ownConfig){
cfg.put(CFG_ACC_SCAN, noOfLocalScanRecords);
}
- Uint32 noOfMetaTables= noOfTables + noOfOrderedIndexes +
- noOfUniqueHashIndexes;
- {
- /**
- * Dict Size Alt values
- */
- cfg.put(CFG_DICT_ATTRIBUTE,
- noOfAttributes);
-
- cfg.put(CFG_DICT_TABLE,
- noOfMetaTables);
- }
-
{
/**
* Dih Size Alt values
@@ -758,9 +762,9 @@ Configuration::calcSizeAlt(ConfigValues * ownConfig){
* Tux Size Alt values
*/
cfg.put(CFG_TUX_INDEX,
- noOfOrderedIndexes);
+ noOfMetaTables /*noOfOrderedIndexes*/);
- cfg.put(CFG_TUX_FRAGMENT,
+ cfg.put(CFG_TUX_FRAGMENT,
2 * NO_OF_FRAG_PER_NODE * noOfOrderedIndexes * noOfReplicas);
cfg.put(CFG_TUX_ATTRIBUTE,
From 03c28bf12f107d901a35d8342ce6e8c244d07247 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Fri, 19 Nov 2004 15:35:35 +0000
Subject: [PATCH 052/145] correct some linking problem
---
acinclude.m4 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/acinclude.m4 b/acinclude.m4
index 81917372206..58e24dcbc5e 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -1687,7 +1687,7 @@ AC_DEFUN([MYSQL_CHECK_NDBCLUSTER], [
ndbcluster_includes="-I../ndb/include -I../ndb/include/ndbapi"
ndbcluster_libs="\$(top_builddir)/ndb/src/.libs/libndbclient.a"
ndbcluster_system_libs=""
- ndb_mgmclient_libs="\$(top_builddir)/ndb/src/mgmclient/libndbmgmclient.la"
+ ndb_mgmclient_libs="\$(top_builddir)/ndb/src/mgmclient/libndbmgmclient.la \$(top_builddir)/mysys/libmysys.a"
MYSQL_CHECK_NDB_OPTIONS
;;
* )
From 770c9be8c22d138c27cd7c399f968925f26753ec Mon Sep 17 00:00:00 2001
From: "bar@mysql.com" <>
Date: Fri, 19 Nov 2004 19:35:36 +0400
Subject: [PATCH 053/145] Bug #6658 MAX(column) returns incorrect coercibility
Also, Item_sum_hybrid->charset was removed as redundant, and switched to use
collation.collation instead.
---
mysql-test/r/func_group.result | 16 +++++++++++++++-
mysql-test/r/func_str.result | 14 ++++++++++++++
mysql-test/t/func_group.test | 11 +++++++++++
sql/item_func.cc | 1 +
sql/item_sum.cc | 9 +++------
sql/item_sum.h | 9 ++++-----
6 files changed, 48 insertions(+), 12 deletions(-)
diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result
index c25f89d4df3..4bb79a1cb41 100644
--- a/mysql-test/r/func_group.result
+++ b/mysql-test/r/func_group.result
@@ -637,8 +637,22 @@ create table t1 (a char(10));
insert into t1 values ('a'),('b'),('c');
select coercibility(max(a)) from t1;
coercibility(max(a))
-3
+2
drop table t1;
+create table t1 (a char character set latin2);
+insert into t1 values ('a'),('b');
+select charset(max(a)), coercibility(max(a)),
+charset(min(a)), coercibility(min(a)) from t1;
+charset(max(a)) coercibility(max(a)) charset(min(a)) coercibility(min(a))
+latin2 2 latin2 2
+create table t2 select max(a),min(a) from t1;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `max(a)` char(1) character set latin2 default NULL,
+ `min(a)` char(1) character set latin2 default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t2,t1;
create table t1 (a int);
insert into t1 values (1);
select max(a) as b from t1 having b=1;
diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result
index 8d49d55be39..083f85ee6fa 100644
--- a/mysql-test/r/func_str.result
+++ b/mysql-test/r/func_str.result
@@ -614,6 +614,20 @@ t1 CREATE TABLE `t1` (
`encode('abcd','ab')` binary(4) NOT NULL default ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
+create table t1 (a char character set latin2);
+insert into t1 values ('a'),('b');
+select charset(max(a)), coercibility(max(a)),
+charset(min(a)), coercibility(min(a)) from t1;
+charset(max(a)) coercibility(max(a)) charset(min(a)) coercibility(min(a))
+latin2 2 latin2 2
+create table t2 select max(a),min(a) from t1;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `max(a)` char(1) character set latin2 default NULL,
+ `min(a)` char(1) character set latin2 default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t2,t1;
select SUBSTR('abcdefg',3,2);
SUBSTR('abcdefg',3,2)
cd
diff --git a/mysql-test/t/func_group.test b/mysql-test/t/func_group.test
index 8d8779e9d1b..79d6112e6de 100644
--- a/mysql-test/t/func_group.test
+++ b/mysql-test/t/func_group.test
@@ -383,6 +383,17 @@ insert into t1 values ('a'),('b'),('c');
select coercibility(max(a)) from t1;
drop table t1;
+#
+# Bug #6658 MAX(column) returns incorrect coercibility
+#
+create table t1 (a char character set latin2);
+insert into t1 values ('a'),('b');
+select charset(max(a)), coercibility(max(a)),
+ charset(min(a)), coercibility(min(a)) from t1;
+create table t2 select max(a),min(a) from t1;
+show create table t2;
+drop table t2,t1;
+
#
# aggregate functions on static tables
#
diff --git a/sql/item_func.cc b/sql/item_func.cc
index c07e9f23ea2..3fb5bcd01c6 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -350,6 +350,7 @@ void Item_func::split_sum_func(THD *thd, Item **ref_pointer_array,
{
uint el= fields.elements;
Item *new_item= new Item_ref(ref_pointer_array + el, 0, item->name);
+ new_item->collation.set(item->collation);
fields.push_front(item);
ref_pointer_array[el]= item;
thd->change_item_tree(arg, new_item);
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 3b3a6083725..c43a7d87f8f 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -218,16 +218,13 @@ Item_sum_hybrid::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
hybrid_type= item->result_type();
if (hybrid_type == INT_RESULT)
{
- cmp_charset= &my_charset_bin;
max_length=20;
}
else if (hybrid_type == REAL_RESULT)
{
- cmp_charset= &my_charset_bin;
max_length=float_length(decimals);
}else
{
- cmp_charset= item->collation.collation;
max_length=item->max_length;
}
decimals=item->decimals;
@@ -557,7 +554,7 @@ bool Item_sum_min::add()
{
String *result=args[0]->val_str(&tmp_value);
if (!args[0]->null_value &&
- (null_value || sortcmp(&value,result,cmp_charset) > 0))
+ (null_value || sortcmp(&value,result,collation.collation) > 0))
{
value.copy(*result);
null_value=0;
@@ -610,7 +607,7 @@ bool Item_sum_max::add()
{
String *result=args[0]->val_str(&tmp_value);
if (!args[0]->null_value &&
- (null_value || sortcmp(&value,result,cmp_charset) < 0))
+ (null_value || sortcmp(&value,result,collation.collation) < 0))
{
value.copy(*result);
null_value=0;
@@ -921,7 +918,7 @@ Item_sum_hybrid::min_max_update_str_field()
result_field->val_str(&tmp_value);
if (result_field->is_null() ||
- (cmp_sign * sortcmp(res_str,&tmp_value,cmp_charset)) < 0)
+ (cmp_sign * sortcmp(res_str,&tmp_value,collation.collation)) < 0)
result_field->store(res_str->ptr(),res_str->length(),res_str->charset());
result_field->set_notnull();
}
diff --git a/sql/item_sum.h b/sql/item_sum.h
index 5aa0d37190b..f9c48304795 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -402,20 +402,19 @@ class Item_sum_hybrid :public Item_sum
enum_field_types hybrid_field_type;
int cmp_sign;
table_map used_table_cache;
- CHARSET_INFO *cmp_charset;
public:
Item_sum_hybrid(Item *item_par,int sign)
:Item_sum(item_par), sum(0.0), sum_int(0),
hybrid_type(INT_RESULT), hybrid_field_type(FIELD_TYPE_LONGLONG),
- cmp_sign(sign), used_table_cache(~(table_map) 0),
- cmp_charset(&my_charset_bin)
- {}
+ cmp_sign(sign), used_table_cache(~(table_map) 0)
+ { collation.set(&my_charset_bin); }
Item_sum_hybrid(THD *thd, Item_sum_hybrid *item):
Item_sum(thd, item), value(item->value),
sum(item->sum), sum_int(item->sum_int), hybrid_type(item->hybrid_type),
hybrid_field_type(item->hybrid_field_type),cmp_sign(item->cmp_sign),
- used_table_cache(item->used_table_cache), cmp_charset(item->cmp_charset) {}
+ used_table_cache(item->used_table_cache)
+ { collation.set(item->collation); }
bool fix_fields(THD *, TABLE_LIST *, Item **);
table_map used_tables() const { return used_table_cache; }
bool const_item() const { return !used_table_cache; }
From edc868e3977f922eecd05ec3f2caeb399caff360 Mon Sep 17 00:00:00 2001
From: "petr@mysql.com" <>
Date: Fri, 19 Nov 2004 18:35:36 +0300
Subject: [PATCH 054/145] Added --disable-log-bin option to the mysqlbinlog
(WL1787)
---
BitKeeper/etc/logging_ok | 1 +
client/mysqlbinlog.cc | 17 ++++++++++++++++-
2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok
index 1c1a3efc542..8fcec769a0c 100644
--- a/BitKeeper/etc/logging_ok
+++ b/BitKeeper/etc/logging_ok
@@ -163,6 +163,7 @@ pem@mysql.com
peter@linux.local
peter@mysql.com
peterg@mysql.com
+petr@mysql.com
pgulutzan@linux.local
ram@deer.(none)
ram@gw.mysql.r18.ru
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index 8015871428e..de53831c43d 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -44,7 +44,7 @@ static const char *load_default_groups[]= { "mysqlbinlog","client",0 };
void sql_print_error(const char *format, ...);
-static bool one_database=0, to_last_remote_log= 0;
+static bool one_database=0, to_last_remote_log= 0, disable_log_bin= 0;
static const char* database= 0;
static my_bool force_opt= 0, short_form= 0, remote_opt= 0;
static ulonglong offset = 0;
@@ -438,6 +438,13 @@ static struct my_option my_long_options[] =
{"database", 'd', "List entries for just this database (local log only).",
(gptr*) &database, (gptr*) &database, 0, GET_STR_ALLOC, REQUIRED_ARG,
0, 0, 0, 0, 0, 0},
+ {"disable-log-bin", 'D', "Disable binary log. This is useful, if you "
+ "enabled --to-last-log and are sending the output to the same MySQL server. "
+ "This way you could avoid an endless loop. You would also like to use it "
+ "when restoring after a crash to avoid duplication of the statements you "
+ "already have. NOTE: you will need a SUPER privilege to use this option.",
+ (gptr*) &disable_log_bin, (gptr*) &disable_log_bin, 0, GET_BOOL,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
{"force-read", 'f', "Force reading unknown binlog events.",
(gptr*) &force_opt, (gptr*) &force_opt, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
0, 0},
@@ -1068,6 +1075,11 @@ int main(int argc, char** argv)
fprintf(result_file,
"/*!40019 SET @@session.max_insert_delayed_threads=0*/;\n");
+
+ if (disable_log_bin)
+ fprintf(result_file,
+ "/*!32316 SET @OLD_SQL_LOG_BIN=@@SQL_LOG_BIN, SQL_LOG_BIN=0*/;\n");
+
for (save_stop_position= stop_position, stop_position= ~(my_off_t)0 ;
(--argc >= 0) && !stop_passed ; )
{
@@ -1082,6 +1094,9 @@ int main(int argc, char** argv)
start_position= BIN_LOG_HEADER_SIZE;
}
+ if (disable_log_bin)
+ fprintf(result_file, "/*!32316 SET SQL_LOG_BIN=@OLD_SQL_LOG_BIN*/;\n");
+
if (tmpdir.list)
free_tmpdir(&tmpdir);
if (result_file != stdout)
From 3b0fd7fe9622b7db7585d07a50844c61ad986d0d Mon Sep 17 00:00:00 2001
From: "bar@mysql.com" <>
Date: Fri, 19 Nov 2004 19:35:37 +0400
Subject: [PATCH 055/145] func_str.result: This test was moved into
func_group.
---
mysql-test/r/func_str.result | 14 --------------
1 file changed, 14 deletions(-)
diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result
index 083f85ee6fa..8d49d55be39 100644
--- a/mysql-test/r/func_str.result
+++ b/mysql-test/r/func_str.result
@@ -614,20 +614,6 @@ t1 CREATE TABLE `t1` (
`encode('abcd','ab')` binary(4) NOT NULL default ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
-create table t1 (a char character set latin2);
-insert into t1 values ('a'),('b');
-select charset(max(a)), coercibility(max(a)),
-charset(min(a)), coercibility(min(a)) from t1;
-charset(max(a)) coercibility(max(a)) charset(min(a)) coercibility(min(a))
-latin2 2 latin2 2
-create table t2 select max(a),min(a) from t1;
-show create table t2;
-Table Create Table
-t2 CREATE TABLE `t2` (
- `max(a)` char(1) character set latin2 default NULL,
- `min(a)` char(1) character set latin2 default NULL
-) ENGINE=MyISAM DEFAULT CHARSET=latin1
-drop table t2,t1;
select SUBSTR('abcdefg',3,2);
SUBSTR('abcdefg',3,2)
cd
From ad8dad86a845897c2da726b3ca0092ca32d5993f Mon Sep 17 00:00:00 2001
From: "pekka@mysql.com" <>
Date: Fri, 19 Nov 2004 16:49:17 +0100
Subject: [PATCH 056/145] ndb: do not crash on config mismatch if release
compiled
---
ndb/src/kernel/blocks/ERROR_codes.txt | 3 ++-
ndb/src/kernel/blocks/dbacc/DbaccMain.cpp | 14 ++++++++++++++
ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp | 11 +++++++++++
ndb/test/ndbapi/testDict.cpp | 19 ++++++++++++++++---
4 files changed, 43 insertions(+), 4 deletions(-)
diff --git a/ndb/src/kernel/blocks/ERROR_codes.txt b/ndb/src/kernel/blocks/ERROR_codes.txt
index 7ff03684cff..5193d3eae9d 100644
--- a/ndb/src/kernel/blocks/ERROR_codes.txt
+++ b/ndb/src/kernel/blocks/ERROR_codes.txt
@@ -1,7 +1,7 @@
Next QMGR 1
Next NDBCNTR 1000
Next NDBFS 2000
-Next DBACC 3001
+Next DBACC 3002
Next DBTUP 4013
Next DBLQH 5042
Next DBDICT 6006
@@ -393,6 +393,7 @@ Failed Create Table:
--------------------
7173: Create table failed due to not sufficient number of fragment or
replica records.
+3001: Fail create 1st fragment
4007 12001: Fail create 1st fragment
4008 12002: Fail create 2nd fragment
4009 12003: Fail create 1st attribute in 1st fragment
diff --git a/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp b/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp
index c275e5382f7..5c7cc597672 100644
--- a/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp
+++ b/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp
@@ -1062,7 +1062,21 @@ void Dbacc::execACCFRAGREQ(Signal* signal)
{
const AccFragReq * const req = (AccFragReq*)&signal->theData[0];
jamEntry();
+ if (ERROR_INSERTED(3001)) {
+ jam();
+ addFragRefuse(signal, 1);
+ CLEAR_ERROR_INSERT_VALUE;
+ return;
+ }
tabptr.i = req->tableId;
+#ifndef VM_TRACE
+ // config mismatch - do not crash if release compiled
+ if (tabptr.i >= ctablesize) {
+ jam();
+ addFragRefuse(signal, 800);
+ return;
+ }
+#endif
ptrCheckGuard(tabptr, ctablesize, tabrec);
ndbrequire((req->reqInfo & 0xF) == ZADDFRAG);
ndbrequire(!getrootfragmentrec(signal, rootfragrecptr, req->fragId));
diff --git a/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp b/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp
index 914dba00674..405f790954e 100644
--- a/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp
+++ b/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp
@@ -69,6 +69,17 @@ void Dbtup::execTUPFRAGREQ(Signal* signal)
Uint32 noOfAttributeGroups = signal->theData[12];
Uint32 globalCheckpointIdIndicator = signal->theData[13];
+#ifndef VM_TRACE
+ // config mismatch - do not crash if release compiled
+ if (regTabPtr.i >= cnoOfTablerec) {
+ ljam();
+ signal->theData[0] = userptr;
+ signal->theData[1] = 800;
+ sendSignal(userblockref, GSN_TUPFRAGREF, signal, 2, JBB);
+ return;
+ }
+#endif
+
ptrCheckGuard(regTabPtr, cnoOfTablerec, tablerec);
if (cfirstfreeFragopr == RNIL) {
ljam();
diff --git a/ndb/test/ndbapi/testDict.cpp b/ndb/test/ndbapi/testDict.cpp
index 712ab2e4d25..0a43bb02fff 100644
--- a/ndb/test/ndbapi/testDict.cpp
+++ b/ndb/test/ndbapi/testDict.cpp
@@ -1480,8 +1480,10 @@ runTestDictionaryPerf(NDBT_Context* ctx, NDBT_Step* step){
}
int runFailAddFragment(NDBT_Context* ctx, NDBT_Step* step){
+ static int acclst[] = { 3001 };
static int tuplst[] = { 4007, 4008, 4009, 4010, 4011, 4012 };
static int tuxlst[] = { 12001, 12002, 12003, 12004, 12005, 12006 };
+ static unsigned acccnt = sizeof(acclst)/sizeof(acclst[0]);
static unsigned tupcnt = sizeof(tuplst)/sizeof(tuplst[0]);
static unsigned tuxcnt = sizeof(tuxlst)/sizeof(tuxlst[0]);
@@ -1509,6 +1511,19 @@ int runFailAddFragment(NDBT_Context* ctx, NDBT_Step* step){
(void)pDic->dropTable(tab.getName());
for (int l = 0; l < loops; l++) {
+ for (unsigned i0 = 0; i0 < acccnt; i0++) {
+ unsigned j = (l == 0 ? i0 : myRandom48(acccnt));
+ int errval = acclst[j];
+ g_info << "insert error node=" << nodeId << " value=" << errval << endl;
+ CHECK2(restarter.insertErrorInNode(nodeId, errval) == 0,
+ "failed to set error insert");
+ CHECK2(pDic->createTable(tab) != 0,
+ "failed to fail after error insert " << errval);
+ CHECK2(pDic->createTable(tab) == 0,
+ pDic->getNdbError());
+ CHECK2(pDic->dropTable(tab.getName()) == 0,
+ pDic->getNdbError());
+ }
for (unsigned i1 = 0; i1 < tupcnt; i1++) {
unsigned j = (l == 0 ? i1 : myRandom48(tupcnt));
int errval = tuplst[j];
@@ -1638,7 +1653,7 @@ TESTCASE("DictionaryPerf",
INITIALIZER(runTestDictionaryPerf);
}
TESTCASE("FailAddFragment",
- "Fail add fragment or attribute in TUP or TUX\n"){
+ "Fail add fragment or attribute in ACC or TUP or TUX\n"){
INITIALIZER(runFailAddFragment);
}
NDBT_TESTSUITE_END(testDict);
@@ -1650,5 +1665,3 @@ int main(int argc, const char** argv){
myRandom48Init(NdbTick_CurrentMillisecond());
return testDict.execute(argc, argv);
}
-
-
From 12744adc4bd363223b8266e475a3eba4e3ca454b Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Fri, 19 Nov 2004 16:58:02 +0000
Subject: [PATCH 057/145] corrected some erroneous size calculations in tup
fixed erroneous error message - set auto increment was done even if
create table failed so real error message got lost behind "table not found"
and simplified code a bit
---
ndb/src/kernel/vm/Configuration.cpp | 4 +--
ndb/src/ndbapi/NdbDictionaryImpl.cpp | 42 +++++++++++++++-------------
2 files changed, 25 insertions(+), 21 deletions(-)
diff --git a/ndb/src/kernel/vm/Configuration.cpp b/ndb/src/kernel/vm/Configuration.cpp
index c2f47adff29..aac035fe1b7 100644
--- a/ndb/src/kernel/vm/Configuration.cpp
+++ b/ndb/src/kernel/vm/Configuration.cpp
@@ -750,8 +750,8 @@ Configuration::calcSizeAlt(ConfigValues * ownConfig){
noOfMetaTables);
cfg.put(CFG_TUP_TABLE_DESC,
- 4 * NO_OF_FRAG_PER_NODE * noOfAttributes* noOfReplicas +
- 12 * NO_OF_FRAG_PER_NODE * noOfMetaTables* noOfReplicas );
+ 2 * 6 * NO_OF_FRAG_PER_NODE * noOfAttributes * noOfReplicas +
+ 2 * 10 * NO_OF_FRAG_PER_NODE * noOfMetaTables * noOfReplicas );
cfg.put(CFG_TUP_STORED_PROC,
noOfLocalScanRecords);
diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/ndb/src/ndbapi/NdbDictionaryImpl.cpp
index 304d1b904d4..345f2caac89 100644
--- a/ndb/src/ndbapi/NdbDictionaryImpl.cpp
+++ b/ndb/src/ndbapi/NdbDictionaryImpl.cpp
@@ -1571,7 +1571,13 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb,
NdbApiSignal tSignal(m_reference);
tSignal.theReceiversBlockNumber = DBDICT;
- if (alter) {
+
+ LinearSectionPtr ptr[3];
+ ptr[0].p = (Uint32*)m_buffer.get_data();
+ ptr[0].sz = m_buffer.length() / 4;
+ int ret;
+ if (alter)
+ {
AlterTableReq * const req =
CAST_PTR(AlterTableReq, tSignal.getDataPtrSend());
@@ -1582,8 +1588,10 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb,
req->tableVersion = impl.m_version;;
tSignal.theVerId_signalNumber = GSN_ALTER_TABLE_REQ;
tSignal.theLength = AlterTableReq::SignalLength;
+ ret= alterTable(&tSignal, ptr);
}
- else {
+ else
+ {
CreateTableReq * const req =
CAST_PTR(CreateTableReq, tSignal.getDataPtrSend());
@@ -1591,25 +1599,21 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb,
req->senderData = 0;
tSignal.theVerId_signalNumber = GSN_CREATE_TABLE_REQ;
tSignal.theLength = CreateTableReq::SignalLength;
- }
-
- LinearSectionPtr ptr[3];
- ptr[0].p = (Uint32*)m_buffer.get_data();
- ptr[0].sz = m_buffer.length() / 4;
+ ret= createTable(&tSignal, ptr);
- int ret = (alter) ?
- alterTable(&tSignal, ptr)
- : createTable(&tSignal, ptr);
+ if (ret)
+ return ret;
- if (!alter && haveAutoIncrement) {
- if (!ndb.setAutoIncrementValue(impl.m_externalName.c_str(),
- autoIncrementValue)) {
- if (ndb.theError.code == 0) {
- m_error.code = 4336;
- ndb.theError = m_error;
- } else
- m_error= ndb.theError;
- ret = -1; // errorcode set in initialize_autoincrement
+ if (haveAutoIncrement) {
+ if (!ndb.setAutoIncrementValue(impl.m_externalName.c_str(),
+ autoIncrementValue)) {
+ if (ndb.theError.code == 0) {
+ m_error.code = 4336;
+ ndb.theError = m_error;
+ } else
+ m_error= ndb.theError;
+ ret = -1; // errorcode set in initialize_autoincrement
+ }
}
}
return ret;
From fcb57426965cf7b1f2bf84265393a9eb40a32f82 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Fri, 19 Nov 2004 17:18:46 +0000
Subject: [PATCH 058/145] acinclude.m4: reverting my last fix
---
acinclude.m4 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/acinclude.m4 b/acinclude.m4
index 58e24dcbc5e..81917372206 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -1687,7 +1687,7 @@ AC_DEFUN([MYSQL_CHECK_NDBCLUSTER], [
ndbcluster_includes="-I../ndb/include -I../ndb/include/ndbapi"
ndbcluster_libs="\$(top_builddir)/ndb/src/.libs/libndbclient.a"
ndbcluster_system_libs=""
- ndb_mgmclient_libs="\$(top_builddir)/ndb/src/mgmclient/libndbmgmclient.la \$(top_builddir)/mysys/libmysys.a"
+ ndb_mgmclient_libs="\$(top_builddir)/ndb/src/mgmclient/libndbmgmclient.la"
MYSQL_CHECK_NDB_OPTIONS
;;
* )
From 65d31b3e92f92284cb095c71fad7ba2d5e04de5d Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Fri, 19 Nov 2004 17:21:27 +0000
Subject: [PATCH 059/145] Makefile.am, mysqladmin.cc: reverting linking
ndbclisnt to mysqladmin.cc
---
client/Makefile.am | 3 +--
client/mysqladmin.cc | 12 ++++++------
2 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/client/Makefile.am b/client/Makefile.am
index 5034dd5bf51..514ed7fdf51 100644
--- a/client/Makefile.am
+++ b/client/Makefile.am
@@ -20,8 +20,7 @@
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/regex \
$(openssl_includes)
LIBS = @CLIENT_LIBS@
-DEPLIB= @ndb_mgmclient_libs@ \
- ../libmysql/libmysqlclient.la
+DEPLIB= ../libmysql/libmysqlclient.la
LDADD = @CLIENT_EXTRA_LDFLAGS@ $(DEPLIB)
bin_PROGRAMS = mysql mysqladmin mysqlcheck mysqlshow \
mysqldump mysqlimport mysqltest mysqlbinlog mysqlmanagerc mysqlmanager-pwgen
diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc
index a9fc3f31d03..eec0dcb90fe 100644
--- a/client/mysqladmin.cc
+++ b/client/mysqladmin.cc
@@ -24,7 +24,7 @@
#include
#include
-#ifdef HAVE_NDBCLUSTER_DB
+#ifdef LATER_HAVE_NDBCLUSTER_DB
#include "../ndb/src/mgmclient/ndb_mgmclient.h"
#endif
@@ -45,7 +45,7 @@ static uint tcp_port = 0, option_wait = 0, option_silent=0, nr_iterations,
opt_count_iterations= 0;
static ulong opt_connect_timeout, opt_shutdown_timeout;
static my_string unix_port=0;
-#ifdef HAVE_NDBCLUSTER_DB
+#ifdef LATER_HAVE_NDBCLUSTER_DB
static my_bool opt_ndbcluster=0;
static char *opt_ndb_connectstring=0;
#endif
@@ -101,7 +101,7 @@ enum commands {
ADMIN_PING, ADMIN_EXTENDED_STATUS, ADMIN_FLUSH_STATUS,
ADMIN_FLUSH_PRIVILEGES, ADMIN_START_SLAVE, ADMIN_STOP_SLAVE,
ADMIN_FLUSH_THREADS, ADMIN_OLD_PASSWORD
-#ifdef HAVE_NDBCLUSTER_DB
+#ifdef LATER_HAVE_NDBCLUSTER_DB
,ADMIN_NDB_MGM
#endif
};
@@ -114,7 +114,7 @@ static const char *command_names[]= {
"ping", "extended-status", "flush-status",
"flush-privileges", "start-slave", "stop-slave",
"flush-threads","old-password",
-#ifdef HAVE_NDBCLUSTER_DB
+#ifdef LATER_HAVE_NDBCLUSTER_DB
"ndb-mgm",
#endif
NullS
@@ -197,7 +197,7 @@ static struct my_option my_long_options[] =
{"shutdown_timeout", OPT_SHUTDOWN_TIMEOUT, "", (gptr*) &opt_shutdown_timeout,
(gptr*) &opt_shutdown_timeout, 0, GET_ULONG, REQUIRED_ARG,
SHUTDOWN_DEF_TIMEOUT, 0, 3600*12, 0, 1, 0},
-#ifdef HAVE_NDBCLUSTER_DB
+#ifdef LATER_HAVE_NDBCLUSTER_DB
{"ndbcluster", OPT_NDBCLUSTER, ""
"", (gptr*) &opt_ndbcluster,
(gptr*) &opt_ndbcluster, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
@@ -903,7 +903,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
}
mysql->reconnect=1; /* Automatic reconnect is default */
break;
-#ifdef HAVE_NDBCLUSTER_DB
+#ifdef LATER_HAVE_NDBCLUSTER_DB
case ADMIN_NDB_MGM:
{
if (argc < 2)
From 59c0102e230c5ad1fe79040e19339b5ccf58b470 Mon Sep 17 00:00:00 2001
From: "paul@kite-hub.kitebird.com" <>
Date: Fri, 19 Nov 2004 14:53:40 -0600
Subject: [PATCH 060/145] mysql.cc: Tweak some help text.
---
client/mysql.cc | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/client/mysql.cc b/client/mysql.cc
index 358b13e652b..8e9dd84c8f0 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -1609,7 +1609,7 @@ static void print_help_item(MYSQL_ROW *cur, int num_name, int num_cat, char *las
char ccat= (*cur)[num_cat][0];
if (*last_char != ccat)
{
- put_info(ccat == 'Y' ? "categories :" : "topics :", INFO_INFO);
+ put_info(ccat == 'Y' ? "categories:" : "topics:", INFO_INFO);
*last_char= ccat;
}
tee_fprintf(PAGER, " %s\n", (*cur)[num_name]);
@@ -1676,8 +1676,8 @@ static int com_server_help(String *buffer __attribute__((unused)),
if (num_fields == 2)
{
- put_info("Many help items for your request exist", INFO_INFO);
- put_info("To make a more specific request, please type 'help - ',\nwhere item is one of next", INFO_INFO);
+ put_info("Many help items for your request exist.", INFO_INFO);
+ put_info("To make a more specific request, please type 'help
- ',\nwhere item is one of the following", INFO_INFO);
num_name= 0;
num_cat= 1;
last_char= '_';
From 6337ea8a406738f3b8134fcb840027311ca36d99 Mon Sep 17 00:00:00 2001
From: "konstantin@mysql.com" <>
Date: Sun, 21 Nov 2004 12:04:27 +0300
Subject: [PATCH 061/145] A fix and test case for Bug#6297 "prepared statement,
wrong handling of IS NULL": we must not only set
Item::null_value in Item_param, but implement Item_param::is_null() to work
well with IS NULL/IS NOT NULL clauses.
---
mysql-test/r/ps.result | 21 +++++++++++++++++++++
mysql-test/t/ps.test | 14 ++++++++++++++
sql/item.h | 10 ++++++++++
3 files changed, 45 insertions(+)
diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result
index 6d9cfabb5a7..4a4c8fe22e4 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -450,3 +450,24 @@ PREPARE stmt FROM 'UPDATE t1 AS P1 INNER JOIN (SELECT N FROM t1 GROUP BY N HAVIN
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
DROP TABLE t1;
+prepare stmt from "select ? is null, ? is not null, ?";
+select @no_such_var is null, @no_such_var is not null, @no_such_var;
+@no_such_var is null @no_such_var is not null @no_such_var
+1 0 NULL
+execute stmt using @no_such_var, @no_such_var, @no_such_var;
+? is null ? is not null ?
+1 0 NULL
+set @var='abc';
+select @var is null, @var is not null, @var;
+@var is null @var is not null @var
+0 1 abc
+execute stmt using @var, @var, @var;
+? is null ? is not null ?
+0 1 abc
+set @var=null;
+select @var is null, @var is not null, @var;
+@var is null @var is not null @var
+1 0 NULL
+execute stmt using @var, @var, @var;
+? is null ? is not null ?
+1 0 NULL
diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test
index 2b3e961fc28..7fe88ad0ddc 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -458,3 +458,17 @@ EXECUTE stmt;
DEALLOCATE PREPARE stmt;
DROP TABLE t1;
+#
+# Bug#6297 "prepared statement, wrong handling of IS NULL"
+# Test that placeholders work with IS NULL/IS NOT NULL clauses.
+#
+prepare stmt from "select ? is null, ? is not null, ?";
+select @no_such_var is null, @no_such_var is not null, @no_such_var;
+execute stmt using @no_such_var, @no_such_var, @no_such_var;
+set @var='abc';
+select @var is null, @var is not null, @var;
+execute stmt using @var, @var, @var;
+set @var=null;
+select @var is null, @var is not null, @var;
+execute stmt using @var, @var, @var;
+
diff --git a/sql/item.h b/sql/item.h
index 547577a7ee0..ccb0fda1c49 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -266,6 +266,14 @@ public:
virtual bool get_time(TIME *ltime);
virtual bool get_date_result(TIME *ltime,uint fuzzydate)
{ return get_date(ltime,fuzzydate); }
+ /*
+ This function is used only in Item_func_isnull/Item_func_isnotnull
+ (implementations of IS NULL/IS NOT NULL clauses). Item_func_is{not}null
+ calls this method instead of one of val/result*() methods, which
+ normally will set null_value. This allows to determine nullness of
+ a complex expression without fully evaluating it.
+ Any new item which can be NULL must implement this call.
+ */
virtual bool is_null() { return 0; }
/*
it is "top level" item of WHERE clause and we do not need correct NULL
@@ -573,6 +581,8 @@ public:
void print(String *str) { str->append('?'); }
/* parameter never equal to other parameter of other item */
bool eq(const Item *item, bool binary_cmp) const { return 0; }
+ bool is_null()
+ { DBUG_ASSERT(state != NO_VALUE); return state == NULL_VALUE; }
};
class Item_int :public Item_num
From 7f5661ae44b6c6d73569e30dd201a484c8ad0c45 Mon Sep 17 00:00:00 2001
From: "heikki@hundin.mysql.fi" <>
Date: Sun, 21 Nov 2004 17:38:15 +0200
Subject: [PATCH 062/145] trx0undo.c, trx0purge.c: Print a warning to the
.err log if the InnoDB history list length is > 20 000 even though purge
reaches the list head; this is to track corruption reported on the MySQL
mailing list Nov 9, 2004 lock0lock.c: Let SHOW INNODB STATUS print the
history list length
---
innobase/lock/lock0lock.c | 3 +++
innobase/trx/trx0purge.c | 23 ++++++++++++++++++++++-
innobase/trx/trx0undo.c | 2 +-
3 files changed, 26 insertions(+), 2 deletions(-)
diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c
index 6f2d58b72c3..78a78c9dd95 100644
--- a/innobase/lock/lock0lock.c
+++ b/innobase/lock/lock0lock.c
@@ -4063,6 +4063,9 @@ lock_print_info(
(ulong) ut_dulint_get_high(purge_sys->purge_undo_no),
(ulong) ut_dulint_get_low(purge_sys->purge_undo_no));
+ fprintf(file,
+ "History list length %lu\n", (ulong) trx_sys->rseg_history_len);
+
fprintf(file,
"Total number of lock structs in row lock hash table %lu\n",
(ulong) lock_get_n_rec_locks());
diff --git a/innobase/trx/trx0purge.c b/innobase/trx/trx0purge.c
index 5c62640e011..3df34111281 100644
--- a/innobase/trx/trx0purge.c
+++ b/innobase/trx/trx0purge.c
@@ -289,7 +289,7 @@ trx_purge_add_update_undo_to_history(
flst_get_len(seg_header + TRX_UNDO_PAGE_LIST, mtr));
mlog_write_ulint(rseg_header + TRX_RSEG_HISTORY_SIZE,
- hist_size + undo->size, MLOG_4BYTES, mtr);
+ hist_size + undo->size, MLOG_4BYTES, mtr);
}
/* Add the log as the first in the history list */
@@ -646,6 +646,27 @@ trx_purge_rseg_get_next_history_log(
mutex_exit(&(rseg->mutex));
mtr_commit(&mtr);
+ mutex_enter(&kernel_mutex);
+
+ /* Add debug code to track history list corruption reported
+ on the MySQL mailing list on Nov 9, 2004. The fut0lst.c
+ file-based list was corrupt. The prev node pointer was
+ FIL_NULL, even though the list length was over 8 million nodes!
+ We assume that purge truncates the history list in moderate
+ size pieces, and if we here reach the head of the list, the
+ list cannot be longer than 20 000 undo logs now. */
+
+ if (trx_sys->rseg_history_len > 20000) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+" InnoDB: Warning: purge reached the head of the history list,\n"
+"InnoDB: but its length is still reported as %lu! Make a detailed bug\n"
+"InnoDB: report, and post it to bugs.mysql.com\n",
+ (ulong)trx_sys->rseg_history_len);
+ }
+
+ mutex_exit(&kernel_mutex);
+
return;
}
diff --git a/innobase/trx/trx0undo.c b/innobase/trx/trx0undo.c
index c1edc223cbc..8d1518753dd 100644
--- a/innobase/trx/trx0undo.c
+++ b/innobase/trx/trx0undo.c
@@ -1241,7 +1241,7 @@ trx_undo_lists_init(
if (page_no != FIL_NULL
&& srv_force_recovery < SRV_FORCE_NO_UNDO_LOG_SCAN) {
-
+
undo = trx_undo_mem_create_at_db_start(rseg, i,
page_no, &mtr);
size += undo->size;
From 4d43c10f3bcb0e40b15f79d6cc15dc5817de420f Mon Sep 17 00:00:00 2001
From: "joreland@mysql.com" <>
Date: Sun, 21 Nov 2004 22:15:44 +0100
Subject: [PATCH 063/145] wl2077 - ndb close scan - fix introduced bugs wrt
premature close of scan
---
ndb/src/common/debugger/signaldata/ScanTab.cpp | 5 +++--
ndb/src/kernel/blocks/dbtc/DbtcMain.cpp | 3 +--
ndb/src/ndbapi/NdbConnectionScan.cpp | 10 ++++++++--
ndb/src/ndbapi/NdbScanOperation.cpp | 8 +++++---
ndb/test/src/NDBT_Test.cpp | 4 +---
ndb/tools/select_all.cpp | 2 +-
6 files changed, 19 insertions(+), 13 deletions(-)
diff --git a/ndb/src/common/debugger/signaldata/ScanTab.cpp b/ndb/src/common/debugger/signaldata/ScanTab.cpp
index 72a4d9f94b9..0755ee0a856 100644
--- a/ndb/src/common/debugger/signaldata/ScanTab.cpp
+++ b/ndb/src/common/debugger/signaldata/ScanTab.cpp
@@ -30,13 +30,14 @@ printSCANTABREQ(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiv
fprintf(output, " apiConnectPtr: H\'%.8x",
sig->apiConnectPtr);
fprintf(output, " requestInfo: H\'%.8x:\n", requestInfo);
- fprintf(output, " Parallellism: %u, Batch: %u LockMode: %u, Keyinfo: %u Holdlock: %u, RangeScan: %u\n",
+ fprintf(output, " Parallellism: %u, Batch: %u LockMode: %u, Keyinfo: %u Holdlock: %u, RangeScan: %u ReadCommitted: %u\n",
sig->getParallelism(requestInfo),
sig->getScanBatch(requestInfo),
sig->getLockMode(requestInfo),
+ sig->getKeyinfoFlag(requestInfo),
sig->getHoldLockFlag(requestInfo),
sig->getRangeScanFlag(requestInfo),
- sig->getKeyinfoFlag(requestInfo));
+ sig->getReadCommittedFlag(requestInfo));
Uint32 keyLen = (sig->attrLenKeyLen >> 16);
Uint32 attrLen = (sig->attrLenKeyLen & 0xFFFF);
diff --git a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
index 9af770db5b7..07dbb370ec6 100644
--- a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
+++ b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
@@ -9329,7 +9329,6 @@ void Dbtc::execSCAN_NEXTREQ(Signal* signal)
/*********************************************************************
* APPLICATION IS CLOSING THE SCAN.
**********************************************************************/
- ndbrequire(len == 0);
close_scan_req(signal, scanptr, true);
return;
}//if
@@ -9457,7 +9456,7 @@ Dbtc::close_scan_req(Signal* signal, ScanRecordPtr scanPtr, bool req_received){
ndbrequire(curr.p->scanFragState == ScanFragRec::DELIVERED);
delivered.remove(curr);
- if(curr.p->m_ops > 0){
+ if(curr.p->m_ops > 0 && curr.p->m_scan_frag_conf_status == 0){
jam();
running.add(curr);
curr.p->scanFragState = ScanFragRec::LQH_ACTIVE;
diff --git a/ndb/src/ndbapi/NdbConnectionScan.cpp b/ndb/src/ndbapi/NdbConnectionScan.cpp
index a7a8f1350b1..a1a220caacf 100644
--- a/ndb/src/ndbapi/NdbConnectionScan.cpp
+++ b/ndb/src/ndbapi/NdbConnectionScan.cpp
@@ -57,12 +57,18 @@ NdbConnection::receiveSCAN_TABREF(NdbApiSignal* aSignal){
if(checkState_TransId(&ref->transId1)){
theScanningOp->theError.code = ref->errorCode;
+ theScanningOp->execCLOSE_SCAN_REP();
if(!ref->closeNeeded){
- theScanningOp->execCLOSE_SCAN_REP();
return 0;
}
- assert(theScanningOp->m_sent_receivers_count);
+
+ /**
+ * Setup so that close_impl will actually perform a close
+ * and not "close scan"-optimze it away
+ */
theScanningOp->m_conf_receivers_count++;
+ theScanningOp->m_conf_receivers[0] = theScanningOp->m_receivers[0];
+ theScanningOp->m_conf_receivers[0]->m_tcPtrI = ~0;
return 0;
} else {
#ifdef NDB_NO_DROPPED_SIGNAL
diff --git a/ndb/src/ndbapi/NdbScanOperation.cpp b/ndb/src/ndbapi/NdbScanOperation.cpp
index 30b596d7098..0fe68c5bab8 100644
--- a/ndb/src/ndbapi/NdbScanOperation.cpp
+++ b/ndb/src/ndbapi/NdbScanOperation.cpp
@@ -613,21 +613,22 @@ NdbScanOperation::send_next_scan(Uint32 cnt, bool stopScanFlag){
sent++;
}
}
- memcpy(&m_api_receivers[0], &m_api_receivers[cnt], cnt * sizeof(char*));
+ memmove(m_api_receivers, m_api_receivers+cnt,
+ (theParallelism-cnt) * sizeof(char*));
int ret = 0;
if(sent)
{
Uint32 nodeId = theNdbCon->theDBnode;
TransporterFacade * tp = TransporterFacade::instance();
- if(cnt > 21 && !stopScanFlag){
+ if(cnt > 21){
tSignal.setLength(4);
LinearSectionPtr ptr[3];
ptr[0].p = prep_array;
ptr[0].sz = sent;
ret = tp->sendSignal(&tSignal, nodeId, ptr, 1);
} else {
- tSignal.setLength(4+(stopScanFlag ? 0 : sent));
+ tSignal.setLength(4+sent);
ret = tp->sendSignal(&tSignal, nodeId);
}
}
@@ -687,6 +688,7 @@ NdbScanOperation::execCLOSE_SCAN_REP(){
m_api_receivers_count = 0;
m_conf_receivers_count = 0;
m_sent_receivers_count = 0;
+ m_current_api_receiver = theParallelism;
}
void NdbScanOperation::release()
diff --git a/ndb/test/src/NDBT_Test.cpp b/ndb/test/src/NDBT_Test.cpp
index 367223f8c98..10233cb5859 100644
--- a/ndb/test/src/NDBT_Test.cpp
+++ b/ndb/test/src/NDBT_Test.cpp
@@ -839,9 +839,7 @@ void NDBT_TestSuite::execute(Ndb* ndb, const NdbDictionary::Table* pTab,
continue;
}
pTab2 = pDict->getTable(pTab->getName());
- } else {
- pTab2 = pTab;
- }
+ }
ctx = new NDBT_Context();
ctx->setTab(pTab2);
diff --git a/ndb/tools/select_all.cpp b/ndb/tools/select_all.cpp
index 9c944c8c93e..a670a2ed49a 100644
--- a/ndb/tools/select_all.cpp
+++ b/ndb/tools/select_all.cpp
@@ -50,7 +50,7 @@ static struct my_option my_long_options[] =
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 },
+ GET_INT, REQUIRED_ARG, 0, 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 },
From 3d845ad7e8b612e2a085cb5d7dc994f3cd3c54b4 Mon Sep 17 00:00:00 2001
From: "joreland@mysql.com" <>
Date: Mon, 22 Nov 2004 07:22:08 +0100
Subject: [PATCH 064/145] wl2077 - ndb, fix testDict
---
ndb/test/src/NDBT_Test.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/ndb/test/src/NDBT_Test.cpp b/ndb/test/src/NDBT_Test.cpp
index 10233cb5859..1434617c988 100644
--- a/ndb/test/src/NDBT_Test.cpp
+++ b/ndb/test/src/NDBT_Test.cpp
@@ -839,6 +839,8 @@ void NDBT_TestSuite::execute(Ndb* ndb, const NdbDictionary::Table* pTab,
continue;
}
pTab2 = pDict->getTable(pTab->getName());
+ } else if(!pTab2) {
+ pTab2 = pTab;
}
ctx = new NDBT_Context();
From e3b94d4ef5965ce9e64246751d249cfd0e7e774f Mon Sep 17 00:00:00 2001
From: "bar@mysql.com" <>
Date: Mon, 22 Nov 2004 11:58:40 +0400
Subject: [PATCH 065/145] Bug #6737: REGEXP gives wrong result with case
sensitive collation: - A new flag MY_CS_CSSORT was introduced for case
sensitivity. - Item_func_regexp doesn't substiture ICASE not only for
binary collations but for case sensitive collations as well.
---
include/m_ctype.h | 2 +-
mysql-test/r/ctype_latin1.result | 9 +++++++++
mysql-test/t/ctype_latin1.test | 7 +++++++
mysys/charset.c | 11 +++++++++++
sql/item_cmpfunc.cc | 20 +++++++++++---------
strings/ctype-czech.c | 12 ++++++------
strings/ctype-win1250ch.c | 12 ++++++------
7 files changed, 51 insertions(+), 22 deletions(-)
diff --git a/include/m_ctype.h b/include/m_ctype.h
index ddc21070547..26e285b9683 100644
--- a/include/m_ctype.h
+++ b/include/m_ctype.h
@@ -63,7 +63,7 @@ typedef struct unicase_info_st
#define MY_CS_UNICODE 128 /* is a charset is full unicode */
#define MY_CS_READY 256 /* if a charset is initialized */
#define MY_CS_AVAILABLE 512 /* If either compiled-in or loaded*/
-
+#define MY_CS_CSSORT 1024 /* if case sensitive sort order */
#define MY_CHARSET_UNDEFINED 0
diff --git a/mysql-test/r/ctype_latin1.result b/mysql-test/r/ctype_latin1.result
index a8182438ac4..355f53b63a5 100644
--- a/mysql-test/r/ctype_latin1.result
+++ b/mysql-test/r/ctype_latin1.result
@@ -296,3 +296,12 @@ FD C3BD FD 1
FE C3BE FE 1
FF C3BF FF 1
DROP TABLE t1;
+select 'a' regexp 'A' collate latin1_general_ci;
+'a' regexp 'A' collate latin1_general_ci
+1
+select 'a' regexp 'A' collate latin1_general_cs;
+'a' regexp 'A' collate latin1_general_cs
+0
+select 'a' regexp 'A' collate latin1_bin;
+'a' regexp 'A' collate latin1_bin
+0
diff --git a/mysql-test/t/ctype_latin1.test b/mysql-test/t/ctype_latin1.test
index 14062437428..677acd9faa9 100644
--- a/mysql-test/t/ctype_latin1.test
+++ b/mysql-test/t/ctype_latin1.test
@@ -53,3 +53,10 @@ SELECT
hex(@l:=convert(@u using latin1)),
a=@l FROM t1;
DROP TABLE t1;
+
+#
+# Bug #6737: REGEXP gives wrong result with case sensitive collation
+#
+select 'a' regexp 'A' collate latin1_general_ci;
+select 'a' regexp 'A' collate latin1_general_cs;
+select 'a' regexp 'A' collate latin1_bin;
diff --git a/mysys/charset.c b/mysys/charset.c
index 1388fc40c6d..cb2379f8723 100644
--- a/mysys/charset.c
+++ b/mysys/charset.c
@@ -228,6 +228,7 @@ static int add_collation(CHARSET_INFO *cs)
}
else
{
+ uchar *sort_order= all_charsets[cs->number]->sort_order;
simple_cs_init_functions(all_charsets[cs->number]);
new->mbminlen= 1;
new->mbmaxlen= 1;
@@ -236,6 +237,16 @@ static int add_collation(CHARSET_INFO *cs)
all_charsets[cs->number]->state |= MY_CS_LOADED;
}
all_charsets[cs->number]->state|= MY_CS_AVAILABLE;
+
+ /*
+ Check if case sensitive sort order: A < a < B.
+ We need MY_CS_FLAG for regex library, and for
+ case sensitivity flag for 5.0 client protocol,
+ to support isCaseSensitive() method in JDBC driver
+ */
+ if (sort_order && sort_order['A'] < sort_order['a'] &&
+ sort_order['a'] < sort_order['B'])
+ all_charsets[cs->number]->state|= MY_CS_CSSORT;
}
}
else
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index c36f2d191c7..4970517de87 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -2364,11 +2364,12 @@ Item_func_regex::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
return 0;
}
int error;
- if ((error=regcomp(&preg,res->c_ptr(),
- (cmp_collation.collation->state & MY_CS_BINSORT) ?
- REG_EXTENDED | REG_NOSUB :
- REG_EXTENDED | REG_NOSUB | REG_ICASE,
- cmp_collation.collation)))
+ if ((error= regcomp(&preg,res->c_ptr(),
+ ((cmp_collation.collation->state & MY_CS_BINSORT) ||
+ (cmp_collation.collation->state & MY_CS_CSSORT)) ?
+ REG_EXTENDED | REG_NOSUB :
+ REG_EXTENDED | REG_NOSUB | REG_ICASE,
+ cmp_collation.collation)))
{
(void) regerror(error,&preg,buff,sizeof(buff));
my_printf_error(ER_REGEXP_ERROR,ER(ER_REGEXP_ERROR),MYF(0),buff);
@@ -2416,10 +2417,11 @@ longlong Item_func_regex::val_int()
regex_compiled=0;
}
if (regcomp(&preg,res2->c_ptr(),
- (cmp_collation.collation->state & MY_CS_BINSORT) ?
- REG_EXTENDED | REG_NOSUB :
- REG_EXTENDED | REG_NOSUB | REG_ICASE,
- cmp_collation.collation))
+ ((cmp_collation.collation->state & MY_CS_BINSORT) ||
+ (cmp_collation.collation->state & MY_CS_CSSORT)) ?
+ REG_EXTENDED | REG_NOSUB :
+ REG_EXTENDED | REG_NOSUB | REG_ICASE,
+ cmp_collation.collation))
{
null_value=1;
return 0;
diff --git a/strings/ctype-czech.c b/strings/ctype-czech.c
index 6f9e9f74d35..2177a18504e 100644
--- a/strings/ctype-czech.c
+++ b/strings/ctype-czech.c
@@ -589,12 +589,12 @@ static MY_COLLATION_HANDLER my_collation_latin2_czech_ci_handler =
CHARSET_INFO my_charset_latin2_czech_ci =
{
- 2,0,0, /* number */
- MY_CS_COMPILED|MY_CS_STRNXFRM, /* state */
- "latin2", /* cs name */
- "latin2_czech_cs", /* name */
- "", /* comment */
- NULL, /* tailoring */
+ 2,0,0, /* number */
+ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_CSSORT, /* state */
+ "latin2", /* cs name */
+ "latin2_czech_cs", /* name */
+ "", /* comment */
+ NULL, /* tailoring */
ctype_czech,
to_lower_czech,
to_upper_czech,
diff --git a/strings/ctype-win1250ch.c b/strings/ctype-win1250ch.c
index b4dbda3e8ed..4ada3d47bf5 100644
--- a/strings/ctype-win1250ch.c
+++ b/strings/ctype-win1250ch.c
@@ -624,12 +624,12 @@ static MY_COLLATION_HANDLER my_collation_czech_ci_handler =
CHARSET_INFO my_charset_cp1250_czech_ci =
{
- 34,0,0, /* number */
- MY_CS_COMPILED|MY_CS_STRNXFRM, /* state */
- "cp1250", /* cs name */
- "cp1250_czech_cs", /* name */
- "", /* comment */
- NULL, /* tailoring */
+ 34,0,0, /* number */
+ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_CSSORT, /* state */
+ "cp1250", /* cs name */
+ "cp1250_czech_cs", /* name */
+ "", /* comment */
+ NULL, /* tailoring */
ctype_win1250ch,
to_lower_win1250ch,
to_upper_win1250ch,
From c23b521e2f8ba73e101ed5b67d0f5899130ee0b7 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Mon, 22 Nov 2004 08:06:39 +0000
Subject: [PATCH 066/145] aligned connect string option on all cluster
executables, --ndb-connectstring is now supported by all enabled new section
in my.cnf [mysql_cluster], which is read by all executables, where connect
string can be put for all cluster executables
---
ndb/include/util/ndb_opts.h | 18 ++++++++++++------
ndb/src/kernel/vm/Configuration.cpp | 2 +-
ndb/src/mgmclient/main.cpp | 2 +-
ndb/src/mgmsrv/main.cpp | 12 ++++++++----
ndb/tools/delete_all.cpp | 2 +-
ndb/tools/desc.cpp | 2 +-
ndb/tools/drop_index.cpp | 2 +-
ndb/tools/drop_tab.cpp | 2 +-
ndb/tools/listTables.cpp | 2 +-
ndb/tools/restore/restore_main.cpp | 2 +-
ndb/tools/select_all.cpp | 2 +-
ndb/tools/select_count.cpp | 2 +-
ndb/tools/waiter.cpp | 2 +-
13 files changed, 31 insertions(+), 21 deletions(-)
diff --git a/ndb/include/util/ndb_opts.h b/ndb/include/util/ndb_opts.h
index 6cba9c04449..f7ae3b5489e 100644
--- a/ndb/include/util/ndb_opts.h
+++ b/ndb/include/util/ndb_opts.h
@@ -32,10 +32,13 @@
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', \
+ { "ndb-connectstring", 'c', \
"Set connect string for connecting to ndb_mgmd. " \
- "=\"host=[;nodeid=]\". " \
- "Overides specifying entries in NDB_CONNECTSTRING and config file", \
+ "Syntax: \"[nodeid=;][host=][:]\". " \
+ "Overides specifying entries in NDB_CONNECTSTRING and Ndb.cfg", \
+ (gptr*) &opt_connect_str, (gptr*) &opt_connect_str, 0, \
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },\
+ { "connect-string", 'c', "same as --ndb-connectstring",\
(gptr*) &opt_connect_str, (gptr*) &opt_connect_str, 0, \
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }
#else
@@ -46,11 +49,14 @@
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', \
+ { "ndb-connectstring", 'c', \
"Set connect string for connecting to ndb_mgmd. " \
- "=\"host=[;nodeid=]\". " \
- "Overides specifying entries in NDB_CONNECTSTRING and config file", \
+ "Syntax: \"[nodeid=;][host=][:]\". " \
+ "Overides specifying entries in NDB_CONNECTSTRING and Ndb.cfg", \
(gptr*) &opt_connect_str, (gptr*) &opt_connect_str, 0, \
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },\
+ { "connect-string", 'c', "same as --ndb-connectstring",\
+ (gptr*) &opt_connect_str, (gptr*) &opt_connect_str, 0,\
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }
#endif
diff --git a/ndb/src/kernel/vm/Configuration.cpp b/ndb/src/kernel/vm/Configuration.cpp
index aac035fe1b7..61615c85337 100644
--- a/ndb/src/kernel/vm/Configuration.cpp
+++ b/ndb/src/kernel/vm/Configuration.cpp
@@ -108,7 +108,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
bool
Configuration::init(int argc, char** argv)
{
- const char *load_default_groups[]= { "ndbd",0 };
+ const char *load_default_groups[]= { "mysql_cluster","ndbd",0 };
load_defaults("my",load_default_groups,&argc,&argv);
int ho_error;
diff --git a/ndb/src/mgmclient/main.cpp b/ndb/src/mgmclient/main.cpp
index 401a9198f30..8cdba854fc4 100644
--- a/ndb/src/mgmclient/main.cpp
+++ b/ndb/src/mgmclient/main.cpp
@@ -138,7 +138,7 @@ int main(int argc, char** argv){
NDB_INIT(argv[0]);
const char *_host = 0;
int _port = 0;
- const char *load_default_groups[]= { "ndb_mgm",0 };
+ const char *load_default_groups[]= { "mysql_cluster","ndb_mgm",0 };
load_defaults("my",load_default_groups,&argc,&argv);
int ho_error;
diff --git a/ndb/src/mgmsrv/main.cpp b/ndb/src/mgmsrv/main.cpp
index 76f0679b069..85bcb849d0e 100644
--- a/ndb/src/mgmsrv/main.cpp
+++ b/ndb/src/mgmsrv/main.cpp
@@ -110,10 +110,14 @@ static struct my_option my_long_options[] =
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,
+ { "ndb-connectstring", 1023,
"Set connect string for connecting to ndb_mgmd. "
- "=\"host=[;nodeid=]\". "
- "Overides specifying entries in NDB_CONNECTSTRING and config file",
+ "Syntax: \"[nodeid=;][host=][:]\". "
+ "Overides specifying entries in NDB_CONNECTSTRING and Ndb.cfg",
+ (gptr*) &opt_connect_str, (gptr*) &opt_connect_str, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+ { "connect-string", 1023,
+ "same as --ndb-connectstring.",
(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",
@@ -196,7 +200,7 @@ int main(int argc, char** argv)
global_mgmt_server_check = 1;
glob.config_filename= "config.ini";
- const char *load_default_groups[]= { "ndb_mgmd",0 };
+ const char *load_default_groups[]= { "mysql_cluster","ndb_mgmd",0 };
load_defaults("my",load_default_groups,&argc,&argv);
int ho_error;
diff --git a/ndb/tools/delete_all.cpp b/ndb/tools/delete_all.cpp
index a4fd73a5128..046ac8005d2 100644
--- a/ndb/tools/delete_all.cpp
+++ b/ndb/tools/delete_all.cpp
@@ -67,7 +67,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
int main(int argc, char** argv){
NDB_INIT(argv[0]);
- const char *load_default_groups[]= { "ndb_tools",0 };
+ const char *load_default_groups[]= { "mysql_cluster",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)))
diff --git a/ndb/tools/desc.cpp b/ndb/tools/desc.cpp
index 8f7a2031ef0..c5e9efdfa8a 100644
--- a/ndb/tools/desc.cpp
+++ b/ndb/tools/desc.cpp
@@ -67,7 +67,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
int main(int argc, char** argv){
NDB_INIT(argv[0]);
- const char *load_default_groups[]= { "ndb_tools",0 };
+ const char *load_default_groups[]= { "mysql_cluster",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)))
diff --git a/ndb/tools/drop_index.cpp b/ndb/tools/drop_index.cpp
index 1d4b454682f..6600811e0c4 100644
--- a/ndb/tools/drop_index.cpp
+++ b/ndb/tools/drop_index.cpp
@@ -64,7 +64,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
int main(int argc, char** argv){
NDB_INIT(argv[0]);
- const char *load_default_groups[]= { "ndb_tools",0 };
+ const char *load_default_groups[]= { "mysql_cluster",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)))
diff --git a/ndb/tools/drop_tab.cpp b/ndb/tools/drop_tab.cpp
index 3362c7de47b..0661a8c599b 100644
--- a/ndb/tools/drop_tab.cpp
+++ b/ndb/tools/drop_tab.cpp
@@ -64,7 +64,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
int main(int argc, char** argv){
NDB_INIT(argv[0]);
- const char *load_default_groups[]= { "ndb_tools",0 };
+ const char *load_default_groups[]= { "mysql_cluster",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)))
diff --git a/ndb/tools/listTables.cpp b/ndb/tools/listTables.cpp
index 05e864a35c4..b923207a4fe 100644
--- a/ndb/tools/listTables.cpp
+++ b/ndb/tools/listTables.cpp
@@ -220,7 +220,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
int main(int argc, char** argv){
NDB_INIT(argv[0]);
const char* _tabname;
- const char *load_default_groups[]= { "ndb_tools",0 };
+ const char *load_default_groups[]= { "mysql_cluster",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)))
diff --git a/ndb/tools/restore/restore_main.cpp b/ndb/tools/restore/restore_main.cpp
index c43791c6723..409ebd54764 100644
--- a/ndb/tools/restore/restore_main.cpp
+++ b/ndb/tools/restore/restore_main.cpp
@@ -143,7 +143,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
bool
readArguments(int *pargc, char*** pargv)
{
- const char *load_default_groups[]= { "ndb_tools","ndb_restore",0 };
+ const char *load_default_groups[]= { "mysql_cluster","ndb_restore",0 };
load_defaults("my",load_default_groups,pargc,pargv);
if (handle_options(pargc, pargv, my_long_options, get_one_option))
{
diff --git a/ndb/tools/select_all.cpp b/ndb/tools/select_all.cpp
index 758c1e48c88..77e5e14548e 100644
--- a/ndb/tools/select_all.cpp
+++ b/ndb/tools/select_all.cpp
@@ -105,7 +105,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
int main(int argc, char** argv){
NDB_INIT(argv[0]);
- const char *load_default_groups[]= { "ndb_tools",0 };
+ const char *load_default_groups[]= { "mysql_cluster",0 };
load_defaults("my",load_default_groups,&argc,&argv);
const char* _tabname;
int ho_error;
diff --git a/ndb/tools/select_count.cpp b/ndb/tools/select_count.cpp
index 6ee49ddbff0..c3491f842d8 100644
--- a/ndb/tools/select_count.cpp
+++ b/ndb/tools/select_count.cpp
@@ -83,7 +83,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
int main(int argc, char** argv){
NDB_INIT(argv[0]);
- const char *load_default_groups[]= { "ndb_tools",0 };
+ const char *load_default_groups[]= { "mysql_cluster",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)))
diff --git a/ndb/tools/waiter.cpp b/ndb/tools/waiter.cpp
index e24164ea807..753e56cabde 100644
--- a/ndb/tools/waiter.cpp
+++ b/ndb/tools/waiter.cpp
@@ -75,7 +75,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
int main(int argc, char** argv){
NDB_INIT(argv[0]);
- const char *load_default_groups[]= { "ndb_tools",0 };
+ const char *load_default_groups[]= { "mysql_cluster",0 };
load_defaults("my",load_default_groups,&argc,&argv);
const char* _hostName = NULL;
int ho_error;
From d12c3540539b872cef92d03077c1e1f6bb04d847 Mon Sep 17 00:00:00 2001
From: "jan@hundin.mysql.fi" <>
Date: Mon, 22 Nov 2004 10:34:29 +0200
Subject: [PATCH 067/145] Fixed BUG #6747: innodb_locks_unsafe_for_binlog still
uses next-key locking.
---
innobase/row/row0sel.c | 128 ++++++++++++++++++++++-------------------
1 file changed, 69 insertions(+), 59 deletions(-)
diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c
index 740241fa210..5b7d068d0c1 100644
--- a/innobase/row/row0sel.c
+++ b/innobase/row/row0sel.c
@@ -638,23 +638,24 @@ row_sel_get_clust_rec(
if (!node->read_view) {
/* Try to place a lock on the index record */
- /* If innodb_locks_unsafe_for_binlog option is used,
- we lock only the record, i.e. next-key locking is
- not used.
- */
- if ( srv_locks_unsafe_for_binlog )
- {
- err = lock_clust_rec_read_check_and_lock(0, clust_rec,
- index,node->row_lock_mode, LOCK_REC_NOT_GAP, thr);
- }
- else
- {
- err = lock_clust_rec_read_check_and_lock(0, clust_rec, index,
- node->row_lock_mode, LOCK_ORDINARY, thr);
+ /* If innodb_locks_unsafe_for_binlog option is used,
+ we lock only the record, i.e. next-key locking is
+ not used.
+ */
- }
+ if (srv_locks_unsafe_for_binlog) {
+ err = lock_clust_rec_read_check_and_lock(0,
+ clust_rec,
+ index, node->row_lock_mode,
+ LOCK_REC_NOT_GAP, thr);
+ } else {
+ err = lock_clust_rec_read_check_and_lock(0,
+ clust_rec,
+ index, node->row_lock_mode,
+ LOCK_ORDINARY, thr);
+ }
- if (err != DB_SUCCESS) {
+ if (err != DB_SUCCESS) {
return(err);
}
@@ -1205,22 +1206,24 @@ rec_loop:
if (!consistent_read) {
- /* If innodb_locks_unsafe_for_binlog option is used,
- we lock only the record, i.e. next-key locking is
- not used.
- */
+ /* If innodb_locks_unsafe_for_binlog option is used,
+ we lock only the record, i.e. next-key locking is
+ not used.
+ */
- if ( srv_locks_unsafe_for_binlog )
- {
- err = sel_set_rec_lock(page_rec_get_next(rec), index,
- node->row_lock_mode, LOCK_REC_NOT_GAP, thr);
- }
- else
- {
- err = sel_set_rec_lock(page_rec_get_next(rec), index,
- node->row_lock_mode, LOCK_ORDINARY, thr);
- }
- if (err != DB_SUCCESS) {
+ if (srv_locks_unsafe_for_binlog) {
+ err = sel_set_rec_lock(page_rec_get_next(rec),
+ index,
+ node->row_lock_mode,
+ LOCK_REC_NOT_GAP, thr);
+ } else {
+ err = sel_set_rec_lock(page_rec_get_next(rec),
+ index,
+ node->row_lock_mode,
+ LOCK_ORDINARY, thr);
+ }
+
+ if (err != DB_SUCCESS) {
/* Note that in this case we will store in pcur
the PREDECESSOR of the record we are waiting
the lock for */
@@ -1245,21 +1248,18 @@ rec_loop:
if (!consistent_read) {
/* Try to place a lock on the index record */
- /* If innodb_locks_unsafe_for_binlog option is used,
- we lock only the record, i.e. next-key locking is
- not used.
- */
+ /* If innodb_locks_unsafe_for_binlog option is used,
+ we lock only the record, i.e. next-key locking is
+ not used.
+ */
- if ( srv_locks_unsafe_for_binlog )
- {
- err = sel_set_rec_lock(rec, index, node->row_lock_mode,
+ if (srv_locks_unsafe_for_binlog) {
+ err = sel_set_rec_lock(rec, index, node->row_lock_mode,
LOCK_REC_NOT_GAP, thr);
- }
- else
- {
- err = sel_set_rec_lock(rec, index, node->row_lock_mode,
+ } else {
+ err = sel_set_rec_lock(rec, index, node->row_lock_mode,
LOCK_ORDINARY, thr);
- }
+ }
if (err != DB_SUCCESS) {
@@ -3209,8 +3209,7 @@ rec_loop:
we do not lock gaps. Supremum record is really
a gap and therefore we do not set locks there. */
- if ( srv_locks_unsafe_for_binlog == FALSE )
- {
+ if (srv_locks_unsafe_for_binlog == FALSE) {
err = sel_set_rec_lock(rec, index,
prebuilt->select_lock_type,
LOCK_ORDINARY, thr);
@@ -3312,11 +3311,18 @@ rec_loop:
if (prebuilt->select_lock_type != LOCK_NONE
&& set_also_gap_locks) {
- /* Try to place a lock on the index record */
- err = sel_set_rec_lock(rec, index,
+ /* Try to place a gap lock on the index
+ record only if innodb_locks_unsafe_for_binlog
+ option is not set */
+
+ if (srv_locks_unsafe_for_binlog == FALSE) {
+
+ err = sel_set_rec_lock(rec, index,
prebuilt->select_lock_type,
LOCK_GAP, thr);
+ }
+
if (err != DB_SUCCESS) {
goto lock_wait_or_error;
@@ -3338,11 +3344,18 @@ rec_loop:
if (prebuilt->select_lock_type != LOCK_NONE
&& set_also_gap_locks) {
- /* Try to place a lock on the index record */
- err = sel_set_rec_lock(rec, index,
+ /* Try to place a gap lock on the index
+ record only if innodb_locks_unsafe_for_binlog
+ option is not set */
+
+ if (srv_locks_unsafe_for_binlog == FALSE) {
+
+ err = sel_set_rec_lock(rec, index,
prebuilt->select_lock_type,
LOCK_GAP, thr);
+ }
+
if (err != DB_SUCCESS) {
goto lock_wait_or_error;
@@ -3376,19 +3389,16 @@ rec_loop:
prebuilt->select_lock_type,
LOCK_REC_NOT_GAP, thr);
} else {
- /* If innodb_locks_unsafe_for_binlog option is used,
- we lock only the record, i.e. next-key locking is
- not used.
- */
- if ( srv_locks_unsafe_for_binlog )
- {
- err = sel_set_rec_lock(rec, index,
+ /* If innodb_locks_unsafe_for_binlog option is used,
+ we lock only the record, i.e. next-key locking is
+ not used. */
+
+ if (srv_locks_unsafe_for_binlog) {
+ err = sel_set_rec_lock(rec, index,
prebuilt->select_lock_type,
LOCK_REC_NOT_GAP, thr);
- }
- else
- {
- err = sel_set_rec_lock(rec, index,
+ } else {
+ err = sel_set_rec_lock(rec, index,
prebuilt->select_lock_type,
LOCK_ORDINARY, thr);
}
From 3082312fa80408b9b8baaece27bfa162a40e09ba Mon Sep 17 00:00:00 2001
From: "bar@mysql.com" <>
Date: Mon, 22 Nov 2004 13:02:27 +0400
Subject: [PATCH 068/145] uca-dump.c: Mofidications to dump secondary and
tertiary weigthts And some minor improvements
---
strings/uca-dump.c | 80 ++++++++++++++++++++++++++++++++--------------
1 file changed, 56 insertions(+), 24 deletions(-)
diff --git a/strings/uca-dump.c b/strings/uca-dump.c
index 6836c321526..c9642598c3c 100644
--- a/strings/uca-dump.c
+++ b/strings/uca-dump.c
@@ -23,13 +23,14 @@ struct uca_item_st
#define MY_UCA_PSHIFT 8
#endif
+static char *pname[]= {"", "2", "3"};
+
int main(int ac, char **av)
{
char str[256];
char *weights[64];
struct uca_item_st uca[64*1024];
- size_t code, page, w;
- int pagemaxlen[MY_UCA_NPAGES];
+ size_t code, w;
int pageloaded[MY_UCA_NPAGES];
bzero(uca, sizeof(uca));
@@ -155,14 +156,20 @@ int main(int ac, char **av)
printf("#define MY_UCA_CMASK %d\n",MY_UCA_CMASK);
printf("#define MY_UCA_PSHIFT %d\n",MY_UCA_PSHIFT);
- for (w=0; w<1; w++)
+ for (w=0; w<3; w++)
{
+ size_t page;
+ int pagemaxlen[MY_UCA_NPAGES];
+
for (page=0; page < MY_UCA_NPAGES; page++)
{
size_t offs;
size_t maxnum= 0;
size_t nchars= 0;
size_t mchars;
+ size_t ndefs= 0;
+
+ pagemaxlen[page]= 0;
/*
Skip this page if no weights were loaded
@@ -183,15 +190,37 @@ int main(int ac, char **av)
code= page*MY_UCA_NCHARS+offs;
/* Calculate only non-zero weights */
- num=0;
- for (i=0; i < uca[code].num; i++)
+ for (num=0, i=0; i < uca[code].num; i++)
if (uca[code].weight[w][i])
num++;
maxnum= maxnum < num ? num : maxnum;
+
+ /* Check if default weight */
+ if (w == 1 && num == 1)
+ {
+ /* 0020 0000 ... */
+ if (uca[code].weight[w][0] == 0x0020)
+ ndefs++;
+ }
+ else if (w == 2 && num == 1)
+ {
+ /* 0002 0000 ... */
+ if (uca[code].weight[w][0] == 0x0002)
+ ndefs++;
+ }
}
maxnum++;
+ /*
+ If the page have only default weights
+ then no needs to dump it, skip.
+ */
+ if (ndefs == MY_UCA_NCHARS)
+ {
+ printf("/* Don't dump w=%d pg=%3X: ndefs=%d */\n",w, page, ndefs);
+ continue;
+ }
switch (maxnum)
{
case 0: mchars= 8; break;
@@ -210,8 +239,8 @@ int main(int ac, char **av)
*/
- printf("uint16 page%03Xdata[]= { /* %04X (%d weights per char) */\n",
- page, page*MY_UCA_NCHARS, maxnum);
+ printf("uint16 page%03Xdata%s[]= { /* %04X (%d weights per char) */\n",
+ page, pname[w], page*MY_UCA_NCHARS, maxnum);
for (offs=0; offs < MY_UCA_NCHARS; offs++)
{
@@ -251,25 +280,28 @@ int main(int ac, char **av)
}
printf("};\n\n");
}
+
+ printf("uchar ucal%s[%d]={\n", pname[w], MY_UCA_NPAGES);
+ for (page=0; page < MY_UCA_NPAGES; page++)
+ {
+ printf("%d%s%s",pagemaxlen[page],page
Date: Mon, 22 Nov 2004 10:35:03 +0100
Subject: [PATCH 069/145] Added checks for NOT NULL for all fields in UNIQUE
INDEX (USING HASH)
---
mysql-test/r/ndb_index_unique.result | 7 +++++++
mysql-test/t/ndb_index_unique.test | 8 ++++++++
sql/ha_ndbcluster.cc | 23 ++++++++++++++++++++++-
sql/ha_ndbcluster.h | 3 ++-
4 files changed, 39 insertions(+), 2 deletions(-)
diff --git a/mysql-test/r/ndb_index_unique.result b/mysql-test/r/ndb_index_unique.result
index af9b84022ed..9754be84b17 100644
--- a/mysql-test/r/ndb_index_unique.result
+++ b/mysql-test/r/ndb_index_unique.result
@@ -87,6 +87,13 @@ a b c
7 8 3
8 2 3
drop table t2;
+CREATE TABLE t2 (
+a int unsigned NOT NULL PRIMARY KEY,
+b int unsigned not null,
+c int unsigned,
+UNIQUE USING HASH (b, c)
+) engine=ndbcluster;
+ERROR 42000: Column 'c' is used with UNIQUE or INDEX but is not defined as NOT NULL
CREATE TABLE t3 (
a int unsigned NOT NULL,
b int unsigned not null,
diff --git a/mysql-test/t/ndb_index_unique.test b/mysql-test/t/ndb_index_unique.test
index bdb23949763..3b7cecf6a69 100644
--- a/mysql-test/t/ndb_index_unique.test
+++ b/mysql-test/t/ndb_index_unique.test
@@ -58,6 +58,14 @@ select * from t2 order by a;
drop table t2;
+-- error 1121
+CREATE TABLE t2 (
+ a int unsigned NOT NULL PRIMARY KEY,
+ b int unsigned not null,
+ c int unsigned,
+ UNIQUE USING HASH (b, c)
+) engine=ndbcluster;
+
#
# Show use of PRIMARY KEY USING HASH indexes
#
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index bec4dfd9401..77cc7ce5bc4 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -796,7 +796,8 @@ int ha_ndbcluster::build_index_list(TABLE *tab, enum ILBP phase)
error= create_unique_index(unique_index_name, key_info);
break;
case UNIQUE_INDEX:
- error= create_unique_index(unique_index_name, key_info);
+ if (!(error= check_index_fields_not_null(i)))
+ error= create_unique_index(unique_index_name, key_info);
break;
case ORDERED_INDEX:
error= create_ordered_index(index_name, key_info);
@@ -848,6 +849,26 @@ NDB_INDEX_TYPE ha_ndbcluster::get_index_type_from_table(uint inx) const
ORDERED_INDEX);
}
+int ha_ndbcluster::check_index_fields_not_null(uint inx)
+{
+ KEY* key_info= table->key_info + inx;
+ KEY_PART_INFO* key_part= key_info->key_part;
+ KEY_PART_INFO* end= key_part+key_info->key_parts;
+ DBUG_ENTER("check_index_fields_not_null");
+
+ for (; key_part != end; key_part++)
+ {
+ Field* field= key_part->field;
+ if (field->maybe_null())
+ {
+ my_printf_error(ER_NULL_COLUMN_IN_INDEX,ER(ER_NULL_COLUMN_IN_INDEX),
+ MYF(0),field->field_name);
+ DBUG_RETURN(ER_NULL_COLUMN_IN_INDEX);
+ }
+ }
+
+ DBUG_RETURN(0);
+}
void ha_ndbcluster::release_metadata()
{
diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h
index 9d7cba459cb..1b49aca81e6 100644
--- a/sql/ha_ndbcluster.h
+++ b/sql/ha_ndbcluster.h
@@ -160,7 +160,8 @@ class ha_ndbcluster: public handler
void release_metadata();
NDB_INDEX_TYPE get_index_type(uint idx_no) const;
NDB_INDEX_TYPE get_index_type_from_table(uint index_no) const;
-
+ int check_index_fields_not_null(uint index_no);
+
int pk_read(const byte *key, uint key_len, byte *buf);
int complemented_pk_read(const byte *old_data, byte *new_data);
int peek_row();
From c37977c87d1d26a81ea44275d853e636532e2a16 Mon Sep 17 00:00:00 2001
From: "dlenev@brandersnatch.localdomain" <>
Date: Mon, 22 Nov 2004 13:05:10 +0300
Subject: [PATCH 070/145] Fix for bug #6462 "Same request on same data returns
different results." a.k.a. "Proper cleanup of subqueries is missing for SET
and DO statements". (Version #2 with after-review fixes).
To perform proper cleanup for statements that can contain subqueries
but don't have main select we must call free_undelaid_joins().
---
mysql-test/r/subselect.result | 15 +++++++++++++++
mysql-test/t/subselect.test | 19 +++++++++++++++++++
sql/set_var.cc | 17 +++++++++++------
sql/sql_do.cc | 1 +
4 files changed, 46 insertions(+), 6 deletions(-)
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index 32d482f5a32..53b92fe50f1 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -1990,3 +1990,18 @@ ac
700
NULL
drop tables t1,t2;
+create table t1 (a int not null, b int not null, c int, primary key (a,b));
+insert into t1 values (1,1,1), (2,2,2), (3,3,3);
+set @b:= 0;
+explain select sum(a) from t1 where b > @b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL PRIMARY 8 NULL 3 Using where; Using index
+set @a:= (select sum(a) from t1 where b > @b);
+explain select a from t1 where c=2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where
+do @a:= (select sum(a) from t1 where b > @b);
+explain select a from t1 where c=2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where
+drop table t1;
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index e0f6fcbf515..19bfaa6194a 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -1282,3 +1282,22 @@ INSERT INTO `t2` VALUES (6,5,12,7,'a'),(12,0,0,7,'a'),(12,1,0,7,'a'),(12,5,5,7,'
SELECT b.sc FROM (SELECT (SELECT a.access FROM t1 a WHERE a.map = op.map AND a.slave = op.pid AND a.master = 1) ac FROM t2 op WHERE op.id = 12 AND op.map = 0) b;
SELECT b.ac FROM (SELECT (SELECT a.access FROM t1 a WHERE a.map = op.map AND a.slave = op.pid AND a.master = 1) ac FROM t2 op WHERE op.id = 12 AND op.map = 0) b;
drop tables t1,t2;
+
+#
+# Test for bug #6462. "Same request on same data returns different
+# results." a.k.a. "Proper cleanup of subqueries is missing for
+# SET and DO statements".
+#
+create table t1 (a int not null, b int not null, c int, primary key (a,b));
+insert into t1 values (1,1,1), (2,2,2), (3,3,3);
+set @b:= 0;
+# Let us check that subquery will use covering index
+explain select sum(a) from t1 where b > @b;
+# This should not crash -debug server due to failing assertion
+set @a:= (select sum(a) from t1 where b > @b);
+# And this should not falsely report index usage
+explain select a from t1 where c=2;
+# Same for DO statement
+do @a:= (select sum(a) from t1 where b > @b);
+explain select a from t1 where c=2;
+drop table t1;
diff --git a/sql/set_var.cc b/sql/set_var.cc
index a97506ad07c..bc0f2c2a02c 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -2703,13 +2703,18 @@ int sql_set_variables(THD *thd, List *var_list)
while ((var=it++))
{
if ((error=var->check(thd)))
- DBUG_RETURN(error);
+ goto err;
}
- if (thd->net.report_error)
- DBUG_RETURN(1);
- it.rewind();
- while ((var=it++))
- error|= var->update(thd); // Returns 0, -1 or 1
+ if (!thd->net.report_error)
+ {
+ it.rewind();
+ while ((var= it++))
+ error|= var->update(thd); // Returns 0, -1 or 1
+ }
+ else
+ error= 1;
+err:
+ free_underlaid_joins(thd, &thd->lex->select_lex);
DBUG_RETURN(error);
}
diff --git a/sql/sql_do.cc b/sql/sql_do.cc
index 25a8359f3d2..0d4529fb29e 100644
--- a/sql/sql_do.cc
+++ b/sql/sql_do.cc
@@ -29,6 +29,7 @@ int mysql_do(THD *thd, List
- &values)
DBUG_RETURN(-1);
while ((value = li++))
value->val_int();
+ free_underlaid_joins(thd, &thd->lex->select_lex);
thd->clear_error(); // DO always is OK
send_ok(thd);
DBUG_RETURN(0);
From e38512b378ed29cfd3c697b1372819de74d9f6e8 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Mon, 22 Nov 2004 10:47:59 +0000
Subject: [PATCH 071/145] removed unused variables assigned "localhost"
as default connectstring added a disconnect() first in connect()
removed double implementation of connect code, use connect() in NdbRestarter
removed extra "host=" in connectstring
---
ndb/include/mgmapi/mgmapi.h | 2 --
ndb/test/include/NdbRestarter.hpp | 2 --
ndb/test/src/NdbBackup.cpp | 31 ++++++++++++-------------------
ndb/test/src/NdbRestarter.cpp | 4 ++--
4 files changed, 14 insertions(+), 25 deletions(-)
diff --git a/ndb/include/mgmapi/mgmapi.h b/ndb/include/mgmapi/mgmapi.h
index a4e1fc1d1a8..a23417f153a 100644
--- a/ndb/include/mgmapi/mgmapi.h
+++ b/ndb/include/mgmapi/mgmapi.h
@@ -356,8 +356,6 @@ extern "C" {
/**
* Create a handle to a management server
*
- * @param connect_string Connect string to the management server,
- *
* @return A management handle
* or NULL if no management handle could be created.
*/
diff --git a/ndb/test/include/NdbRestarter.hpp b/ndb/test/include/NdbRestarter.hpp
index 114726f6a2b..19a88b4f8ad 100644
--- a/ndb/test/include/NdbRestarter.hpp
+++ b/ndb/test/include/NdbRestarter.hpp
@@ -87,8 +87,6 @@ protected:
bool connected;
BaseString addr;
- BaseString host;
- int port;
NdbMgmHandle handle;
ndb_mgm_configuration * m_config;
protected:
diff --git a/ndb/test/src/NdbBackup.cpp b/ndb/test/src/NdbBackup.cpp
index 398a7c32fc4..655fdda7c95 100644
--- a/ndb/test/src/NdbBackup.cpp
+++ b/ndb/test/src/NdbBackup.cpp
@@ -69,26 +69,19 @@ NdbBackup::getBackupDataDirForNode(int _node_id){
/**
* Fetch configuration from management server
*/
- ConfigRetriever cr(0, 0, NODE_TYPE_API);
- ndb_mgm_configuration * p = 0;
+ ndb_mgm_configuration *p;
+ if (connect())
+ return NULL;
- BaseString tmp; tmp.assfmt("%s:%d", host.c_str(), port);
- NdbMgmHandle handle = ndb_mgm_create_handle();
- if(handle == 0 ||
- ndb_mgm_set_connectstring(handle,tmp.c_str()) != 0 ||
- ndb_mgm_connect(handle,0,0,0) != 0 ||
- (p = ndb_mgm_get_configuration(handle, 0)) == 0){
-
- const char * s = 0;
- if(p == 0 && handle != 0){
- s = ndb_mgm_get_latest_error_msg(handle);
- if(s == 0)
- s = "No error given!";
+ if ((p = ndb_mgm_get_configuration(handle, 0)) == 0)
+ {
+ const char * s= ndb_mgm_get_latest_error_msg(handle);
+ if(s == 0)
+ s = "No error given!";
- ndbout << "Could not fetch configuration" << endl;
- ndbout << s << endl;
- return NULL;
- }
+ ndbout << "Could not fetch configuration" << endl;
+ ndbout << s << endl;
+ return NULL;
}
/**
@@ -153,7 +146,7 @@ NdbBackup::execRestore(bool _restore_data,
ndbout << "scp res: " << res << endl;
- BaseString::snprintf(buf, 255, "%sndb_restore -c \"host=%s\" -n %d -b %d %s %s .",
+ BaseString::snprintf(buf, 255, "%sndb_restore -c \"%s\" -n %d -b %d %s %s .",
#if 1
"",
#else
diff --git a/ndb/test/src/NdbRestarter.cpp b/ndb/test/src/NdbRestarter.cpp
index e1802f36e82..1c5fbbabb42 100644
--- a/ndb/test/src/NdbRestarter.cpp
+++ b/ndb/test/src/NdbRestarter.cpp
@@ -32,12 +32,11 @@
NdbRestarter::NdbRestarter(const char* _addr):
connected(false),
- port(-1),
handle(NULL),
m_config(0)
{
if (_addr == NULL){
- addr.assign("");
+ addr.assign("localhost");
} else {
addr.assign(_addr);
}
@@ -360,6 +359,7 @@ NdbRestarter::isConnected(){
int
NdbRestarter::connect(){
+ disconnect();
handle = ndb_mgm_create_handle();
if (handle == NULL){
g_err << "handle == NULL" << endl;
From 30f0c495b7d36bf1017bee5cd22dbfc7a06ed298 Mon Sep 17 00:00:00 2001
From: "dlenev@brandersnatch.localdomain" <>
Date: Mon, 22 Nov 2004 14:17:04 +0300
Subject: [PATCH 072/145] Backport of fix making myisam test results repeatable
---
mysql-test/r/myisam.result | 1 +
mysql-test/t/myisam.test | 3 ++-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result
index 31b14f9b822..d155a14bb60 100644
--- a/mysql-test/r/myisam.result
+++ b/mysql-test/r/myisam.result
@@ -529,6 +529,7 @@ show keys from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 1 a 1 a A NULL NULL NULL YES BTREE disabled
create table t2 (a int);
+set @@rand_seed1=31415926,@@rand_seed2=2718281828;
insert t1 select * from t2;
show keys from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test
index f9081e8769b..c8ed7910b76 100644
--- a/mysql-test/t/myisam.test
+++ b/mysql-test/t/myisam.test
@@ -498,11 +498,12 @@ alter table t1 disable keys;
show keys from t1;
create table t2 (a int);
let $i=1000;
+set @@rand_seed1=31415926,@@rand_seed2=2718281828;
--disable_query_log
while ($i)
{
dec $i;
- eval insert t2 values (rand()*100000);
+ insert t2 values (rand()*100000);
}
--enable_query_log
insert t1 select * from t2;
From 6cdf1fc96fdc0d4e4f00346305f939088d94e54e Mon Sep 17 00:00:00 2001
From: "mskold@mysql.com" <>
Date: Mon, 22 Nov 2004 13:58:11 +0100
Subject: [PATCH 073/145] Added NULL value tests for UNIQUE index
---
mysql-test/r/ndb_index_unique.result | 45 ++++++++++++++++++++++++++++
mysql-test/t/ndb_index_unique.test | 26 ++++++++++++++++
2 files changed, 71 insertions(+)
diff --git a/mysql-test/r/ndb_index_unique.result b/mysql-test/r/ndb_index_unique.result
index 9754be84b17..31b258c0a6f 100644
--- a/mysql-test/r/ndb_index_unique.result
+++ b/mysql-test/r/ndb_index_unique.result
@@ -44,6 +44,51 @@ a b c
7 8 3
8 2 3
drop table t1;
+CREATE TABLE t1 (
+a int unsigned NOT NULL PRIMARY KEY,
+b int unsigned,
+c int unsigned,
+UNIQUE bc(b,c)
+) engine = ndb;
+insert into t1 values(1,1,1),(2,NULL,2),(3,NULL,NULL),(4,4,NULL);
+select * from t1 use index (bc) where b IS NULL order by a;
+a b c
+2 NULL 2
+3 NULL NULL
+select * from t1 use index (bc)order by a;
+a b c
+1 1 1
+2 NULL 2
+3 NULL NULL
+4 4 NULL
+select * from t1 use index (bc) order by a;
+a b c
+1 1 1
+2 NULL 2
+3 NULL NULL
+4 4 NULL
+select * from t1 use index (PRIMARY) where b IS NULL order by a;
+a b c
+2 NULL 2
+3 NULL NULL
+select * from t1 use index (bc) where b IS NULL order by a;
+a b c
+2 NULL 2
+3 NULL NULL
+select * from t1 use index (bc) where b IS NULL and c IS NULL order by a;
+a b c
+select * from t1 use index (bc) where b IS NULL and c = 2 order by a;
+a b c
+select * from t1 use index (bc) where b < 4 order by a;
+a b c
+1 1 1
+select * from t1 use index (bc) where b IS NOT NULL order by a;
+a b c
+1 1 1
+4 4 NULL
+insert into t1 values(5,1,1);
+ERROR 23000: Duplicate entry '5' for key 1
+drop table t1;
CREATE TABLE t2 (
a int unsigned NOT NULL PRIMARY KEY,
b int unsigned not null,
diff --git a/mysql-test/t/ndb_index_unique.test b/mysql-test/t/ndb_index_unique.test
index 3b7cecf6a69..397a2c45a9f 100644
--- a/mysql-test/t/ndb_index_unique.test
+++ b/mysql-test/t/ndb_index_unique.test
@@ -30,6 +30,32 @@ select * from t1 order by a;
drop table t1;
+#
+# Indexing NULL values
+#
+
+CREATE TABLE t1 (
+ a int unsigned NOT NULL PRIMARY KEY,
+ b int unsigned,
+ c int unsigned,
+ UNIQUE bc(b,c)
+) engine = ndb;
+
+insert into t1 values(1,1,1),(2,NULL,2),(3,NULL,NULL),(4,4,NULL);
+select * from t1 use index (bc) where b IS NULL order by a;
+
+select * from t1 use index (bc)order by a;
+select * from t1 use index (bc) order by a;
+select * from t1 use index (PRIMARY) where b IS NULL order by a;
+select * from t1 use index (bc) where b IS NULL order by a;
+select * from t1 use index (bc) where b IS NULL and c IS NULL order by a;
+select * from t1 use index (bc) where b IS NULL and c = 2 order by a;
+select * from t1 use index (bc) where b < 4 order by a;
+select * from t1 use index (bc) where b IS NOT NULL order by a;
+-- error 1062
+insert into t1 values(5,1,1);
+drop table t1;
+
#
# Show use of UNIQUE USING HASH indexes
From 1d981111e01bf45e02da8604ebd39de8b7cd3a58 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Mon, 22 Nov 2004 13:41:46 +0000
Subject: [PATCH 074/145] added force send interface to scan prepared for using
query cache in ndb
---
ndb/include/ndbapi/NdbIndexScanOperation.hpp | 6 +--
ndb/include/ndbapi/NdbResultSet.hpp | 6 +--
ndb/include/ndbapi/NdbScanOperation.hpp | 11 +++--
ndb/src/ndbapi/NdbResultSet.cpp | 12 ++---
ndb/src/ndbapi/NdbScanOperation.cpp | 50 +++++++++++++-------
sql/ha_ndbcluster.cc | 33 ++++++++-----
sql/ha_ndbcluster.h | 2 +
7 files changed, 74 insertions(+), 46 deletions(-)
diff --git a/ndb/include/ndbapi/NdbIndexScanOperation.hpp b/ndb/include/ndbapi/NdbIndexScanOperation.hpp
index 66b3fc9d43b..a3388f62f58 100644
--- a/ndb/include/ndbapi/NdbIndexScanOperation.hpp
+++ b/ndb/include/ndbapi/NdbIndexScanOperation.hpp
@@ -113,7 +113,7 @@ public:
* Reset bounds and put operation in list that will be
* sent on next execute
*/
- int reset_bounds();
+ int reset_bounds(bool forceSend = false);
bool getSorted() const { return m_ordered; }
private:
@@ -127,8 +127,8 @@ private:
virtual NdbRecAttr* getValue_impl(const NdbColumnImpl*, char*);
void fix_get_values();
- int next_result_ordered(bool fetchAllowed);
- int send_next_scan_ordered(Uint32 idx);
+ int next_result_ordered(bool fetchAllowed, bool forceSend = false);
+ int send_next_scan_ordered(Uint32 idx, bool forceSend = false);
int compare(Uint32 key, Uint32 cols, const NdbReceiver*, const NdbReceiver*);
Uint32 m_sort_columns;
diff --git a/ndb/include/ndbapi/NdbResultSet.hpp b/ndb/include/ndbapi/NdbResultSet.hpp
index 478daf8aad2..dc0288a380c 100644
--- a/ndb/include/ndbapi/NdbResultSet.hpp
+++ b/ndb/include/ndbapi/NdbResultSet.hpp
@@ -89,17 +89,17 @@ public:
* - 1: if there are no more tuples to scan.
* - 2: if there are no more cached records in NdbApi
*/
- int nextResult(bool fetchAllowed = true);
+ int nextResult(bool fetchAllowed = true, bool forceSend = false);
/**
* Close result set (scan)
*/
- void close();
+ void close(bool forceSend = false);
/**
* Restart
*/
- int restart();
+ int restart(bool forceSend = false);
/**
* Transfer scan operation to an updating transaction. Use this function
diff --git a/ndb/include/ndbapi/NdbScanOperation.hpp b/ndb/include/ndbapi/NdbScanOperation.hpp
index 2e4d173ac75..3c95c79e776 100644
--- a/ndb/include/ndbapi/NdbScanOperation.hpp
+++ b/ndb/include/ndbapi/NdbScanOperation.hpp
@@ -90,11 +90,11 @@ protected:
NdbScanOperation(Ndb* aNdb);
virtual ~NdbScanOperation();
- int nextResult(bool fetchAllowed = true);
+ int nextResult(bool fetchAllowed = true, bool forceSend = false);
virtual void release();
- void closeScan();
- int close_impl(class TransporterFacade*);
+ void closeScan(bool forceSend = false);
+ int close_impl(class TransporterFacade*, bool forceSend = false);
// Overloaded methods from NdbCursorOperation
int executeCursor(int ProcessorId);
@@ -103,6 +103,7 @@ protected:
int init(const NdbTableImpl* tab, NdbConnection* myConnection);
int prepareSend(Uint32 TC_ConnectPtr, Uint64 TransactionId);
int doSend(int ProcessorId);
+ void checkForceSend(bool forceSend);
virtual void setErrorCode(int aErrorCode);
virtual void setErrorCodeAbort(int aErrorCode);
@@ -138,7 +139,7 @@ protected:
Uint32 m_sent_receivers_count; // NOTE needs mutex to access
NdbReceiver** m_sent_receivers; // receive thread puts them here
- int send_next_scan(Uint32 cnt, bool close);
+ int send_next_scan(Uint32 cnt, bool close, bool forceSend = false);
void receiver_delivered(NdbReceiver*);
void receiver_completed(NdbReceiver*);
void execCLOSE_SCAN_REP();
@@ -148,7 +149,7 @@ protected:
Uint32 m_ordered;
- int restart();
+ int restart(bool forceSend = false);
};
inline
diff --git a/ndb/src/ndbapi/NdbResultSet.cpp b/ndb/src/ndbapi/NdbResultSet.cpp
index f270584d227..d9d71464026 100644
--- a/ndb/src/ndbapi/NdbResultSet.cpp
+++ b/ndb/src/ndbapi/NdbResultSet.cpp
@@ -44,10 +44,10 @@ void NdbResultSet::init()
{
}
-int NdbResultSet::nextResult(bool fetchAllowed)
+int NdbResultSet::nextResult(bool fetchAllowed, bool forceSend)
{
int res;
- if ((res = m_operation->nextResult(fetchAllowed)) == 0) {
+ if ((res = m_operation->nextResult(fetchAllowed, forceSend)) == 0) {
// handle blobs
NdbBlob* tBlob = m_operation->theBlobList;
while (tBlob != 0) {
@@ -67,9 +67,9 @@ int NdbResultSet::nextResult(bool fetchAllowed)
return res;
}
-void NdbResultSet::close()
+void NdbResultSet::close(bool forceSend)
{
- m_operation->closeScan();
+ m_operation->closeScan(forceSend);
}
NdbOperation*
@@ -98,6 +98,6 @@ NdbResultSet::deleteTuple(NdbConnection * takeOverTrans){
}
int
-NdbResultSet::restart(){
- return m_operation->restart();
+NdbResultSet::restart(bool forceSend){
+ return m_operation->restart(forceSend);
}
diff --git a/ndb/src/ndbapi/NdbScanOperation.cpp b/ndb/src/ndbapi/NdbScanOperation.cpp
index 4b10ebb10cd..33fa826e470 100644
--- a/ndb/src/ndbapi/NdbScanOperation.cpp
+++ b/ndb/src/ndbapi/NdbScanOperation.cpp
@@ -447,10 +447,11 @@ NdbScanOperation::executeCursor(int nodeId){
#define DEBUG_NEXT_RESULT 0
-int NdbScanOperation::nextResult(bool fetchAllowed)
+int NdbScanOperation::nextResult(bool fetchAllowed, bool forceSend)
{
if(m_ordered)
- return ((NdbIndexScanOperation*)this)->next_result_ordered(fetchAllowed);
+ return ((NdbIndexScanOperation*)this)->next_result_ordered(fetchAllowed,
+ forceSend);
/**
* Check current receiver
@@ -487,7 +488,8 @@ int NdbScanOperation::nextResult(bool fetchAllowed)
TransporterFacade* tp = TransporterFacade::instance();
Guard guard(tp->theMutexPtr);
Uint32 seq = theNdbCon->theNodeSequence;
- if(seq == tp->getNodeSequence(nodeId) && send_next_scan(idx, false) == 0){
+ if(seq == tp->getNodeSequence(nodeId) && send_next_scan(idx, false,
+ forceSend) == 0){
idx = m_current_api_receiver;
last = m_api_receivers_count;
@@ -578,7 +580,8 @@ int NdbScanOperation::nextResult(bool fetchAllowed)
}
int
-NdbScanOperation::send_next_scan(Uint32 cnt, bool stopScanFlag){
+NdbScanOperation::send_next_scan(Uint32 cnt, bool stopScanFlag,
+ bool forceSend){
if(cnt > 0 || stopScanFlag){
NdbApiSignal tSignal(theNdb->theMyRef);
tSignal.setSignal(GSN_SCAN_NEXTREQ);
@@ -618,6 +621,8 @@ NdbScanOperation::send_next_scan(Uint32 cnt, bool stopScanFlag){
ret = tp->sendSignal(&tSignal, nodeId);
}
+ if (!ret) checkForceSend(forceSend);
+
m_sent_receivers_count = last + cnt + stopScanFlag;
m_api_receivers_count -= cnt;
m_current_api_receiver = 0;
@@ -627,6 +632,15 @@ NdbScanOperation::send_next_scan(Uint32 cnt, bool stopScanFlag){
return 0;
}
+void NdbScanOperation::checkForceSend(bool forceSend)
+{
+ if (forceSend) {
+ TransporterFacade::instance()->forceSend(theNdb->theNdbBlockNumber);
+ } else {
+ TransporterFacade::instance()->checkForceSend(theNdb->theNdbBlockNumber);
+ }//if
+}
+
int
NdbScanOperation::prepareSend(Uint32 TC_ConnectPtr, Uint64 TransactionId)
{
@@ -642,7 +656,7 @@ NdbScanOperation::doSend(int ProcessorId)
return 0;
}
-void NdbScanOperation::closeScan()
+void NdbScanOperation::closeScan(bool forceSend)
{
if(m_transConnection){
if(DEBUG_NEXT_RESULT)
@@ -657,7 +671,7 @@ void NdbScanOperation::closeScan()
TransporterFacade* tp = TransporterFacade::instance();
Guard guard(tp->theMutexPtr);
- close_impl(tp);
+ close_impl(tp, forceSend);
} while(0);
@@ -1293,7 +1307,8 @@ NdbIndexScanOperation::compare(Uint32 skip, Uint32 cols,
}
int
-NdbIndexScanOperation::next_result_ordered(bool fetchAllowed){
+NdbIndexScanOperation::next_result_ordered(bool fetchAllowed,
+ bool forceSend){
Uint32 u_idx = 0, u_last = 0;
Uint32 s_idx = m_current_api_receiver; // first sorted
@@ -1319,7 +1334,8 @@ NdbIndexScanOperation::next_result_ordered(bool fetchAllowed){
Guard guard(tp->theMutexPtr);
Uint32 seq = theNdbCon->theNodeSequence;
Uint32 nodeId = theNdbCon->theDBnode;
- if(seq == tp->getNodeSequence(nodeId) && !send_next_scan_ordered(s_idx)){
+ if(seq == tp->getNodeSequence(nodeId) &&
+ !send_next_scan_ordered(s_idx, forceSend)){
Uint32 tmp = m_sent_receivers_count;
s_idx = m_current_api_receiver;
while(m_sent_receivers_count > 0 && !theError.code){
@@ -1408,7 +1424,7 @@ NdbIndexScanOperation::next_result_ordered(bool fetchAllowed){
}
int
-NdbIndexScanOperation::send_next_scan_ordered(Uint32 idx){
+NdbIndexScanOperation::send_next_scan_ordered(Uint32 idx, bool forceSend){
if(idx == theParallelism)
return 0;
@@ -1440,11 +1456,13 @@ NdbIndexScanOperation::send_next_scan_ordered(Uint32 idx){
Uint32 nodeId = theNdbCon->theDBnode;
TransporterFacade * tp = TransporterFacade::instance();
tSignal.setLength(4+1);
- return tp->sendSignal(&tSignal, nodeId);
+ int ret= tp->sendSignal(&tSignal, nodeId);
+ if (!ret) checkForceSend(forceSend);
+ return ret;
}
int
-NdbScanOperation::close_impl(TransporterFacade* tp){
+NdbScanOperation::close_impl(TransporterFacade* tp, bool forceSend){
Uint32 seq = theNdbCon->theNodeSequence;
Uint32 nodeId = theNdbCon->theDBnode;
@@ -1473,7 +1491,7 @@ NdbScanOperation::close_impl(TransporterFacade* tp){
if(m_api_receivers_count+m_conf_receivers_count){
// Send close scan
- if(send_next_scan(0, true) == -1){ // Close scan
+ if(send_next_scan(0, true, forceSend) == -1){ // Close scan
theNdbCon->theReleaseOnClose = true;
return -1;
}
@@ -1520,7 +1538,7 @@ NdbScanOperation::reset_receivers(Uint32 parallell, Uint32 ordered){
}
int
-NdbScanOperation::restart()
+NdbScanOperation::restart(bool forceSend)
{
TransporterFacade* tp = TransporterFacade::instance();
@@ -1529,7 +1547,7 @@ NdbScanOperation::restart()
{
int res;
- if((res= close_impl(tp)))
+ if((res= close_impl(tp, forceSend)))
{
return res;
}
@@ -1548,13 +1566,13 @@ NdbScanOperation::restart()
}
int
-NdbIndexScanOperation::reset_bounds(){
+NdbIndexScanOperation::reset_bounds(bool forceSend){
int res;
{
TransporterFacade* tp = TransporterFacade::instance();
Guard guard(tp->theMutexPtr);
- res= close_impl(tp);
+ res= close_impl(tp, forceSend);
}
if(!res)
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index bec4dfd9401..6f7940caf75 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -1247,7 +1247,7 @@ inline int ha_ndbcluster::next_result(byte *buf)
m_ops_pending= 0;
m_blobs_pending= FALSE;
}
- check= cursor->nextResult(contact_ndb);
+ check= cursor->nextResult(contact_ndb, m_force_send);
if (check == 0)
{
// One more record found
@@ -1540,7 +1540,7 @@ int ha_ndbcluster::ordered_index_scan(const key_range *start_key,
DBUG_ASSERT(op->getSorted() == sorted);
DBUG_ASSERT(op->getLockMode() ==
(NdbOperation::LockMode)get_ndb_lock_type(m_lock.type));
- if(op->reset_bounds())
+ if(op->reset_bounds(m_force_send))
DBUG_RETURN(ndb_err(m_active_trans));
}
@@ -2367,7 +2367,7 @@ int ha_ndbcluster::index_last(byte *buf)
int res;
if((res= ordered_index_scan(0, 0, TRUE, buf)) == 0){
NdbResultSet *cursor= m_active_cursor;
- while((res= cursor->nextResult(TRUE)) == 0);
+ while((res= cursor->nextResult(TRUE, m_force_send)) == 0);
if(res == 1){
unpack_record(buf);
table->status= 0;
@@ -2453,7 +2453,7 @@ int ha_ndbcluster::rnd_init(bool scan)
{
if (!scan)
DBUG_RETURN(1);
- int res= cursor->restart();
+ int res= cursor->restart(m_force_send);
DBUG_ASSERT(res == 0);
}
index_init(table->primary_key);
@@ -2484,7 +2484,7 @@ int ha_ndbcluster::close_scan()
m_ops_pending= 0;
}
- cursor->close();
+ cursor->close(m_force_send);
m_active_cursor= NULL;
DBUG_RETURN(0);
}
@@ -3004,6 +3004,7 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
m_transaction_on= FALSE;
else
m_transaction_on= thd->variables.ndb_use_transactions;
+ // m_use_local_query_cache= thd->variables.ndb_use_local_query_cache;
m_active_trans= thd->transaction.all.ndb_tid ?
(NdbConnection*)thd->transaction.all.ndb_tid:
@@ -3728,7 +3729,8 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg):
m_ha_not_exact_count(FALSE),
m_force_send(TRUE),
m_autoincrement_prefetch(32),
- m_transaction_on(TRUE)
+ m_transaction_on(TRUE),
+ m_use_local_query_cache(FALSE)
{
int i;
@@ -4415,7 +4417,7 @@ bool ha_ndbcluster::low_byte_first() const
}
bool ha_ndbcluster::has_transactions()
{
- return TRUE;
+ return m_transaction_on;
}
const char* ha_ndbcluster::index_type(uint key_number)
{
@@ -4432,7 +4434,10 @@ const char* ha_ndbcluster::index_type(uint key_number)
}
uint8 ha_ndbcluster::table_cache_type()
{
- return HA_CACHE_TBL_NOCACHE;
+ if (m_use_local_query_cache)
+ return HA_CACHE_TBL_TRANSACT;
+ else
+ return HA_CACHE_TBL_NOCACHE;
}
/*
@@ -4600,13 +4605,12 @@ ndb_get_table_statistics(Ndb* ndb, const char * table,
{
DBUG_ENTER("ndb_get_table_statistics");
DBUG_PRINT("enter", ("table: %s", table));
-
+ NdbConnection* pTrans= ndb->startTransaction();
do
{
- NdbConnection* pTrans= ndb->startTransaction();
if (pTrans == NULL)
break;
-
+
NdbScanOperation* pOp= pTrans->getNdbScanOperation(table);
if (pOp == NULL)
break;
@@ -4623,13 +4627,13 @@ ndb_get_table_statistics(Ndb* ndb, const char * table,
pOp->getValue(NdbDictionary::Column::ROW_COUNT, (char*)&rows);
pOp->getValue(NdbDictionary::Column::COMMIT_COUNT, (char*)&commits);
- check= pTrans->execute(NoCommit);
+ check= pTrans->execute(NoCommit, AbortOnError, TRUE);
if (check == -1)
break;
Uint64 sum_rows= 0;
Uint64 sum_commits= 0;
- while((check= rs->nextResult(TRUE)) == 0)
+ while((check= rs->nextResult(TRUE, TRUE)) == 0)
{
sum_rows+= rows;
sum_commits+= commits;
@@ -4638,6 +4642,8 @@ ndb_get_table_statistics(Ndb* ndb, const char * table,
if (check == -1)
break;
+ rs->close(TRUE);
+
ndb->closeTransaction(pTrans);
if(row_count)
* row_count= sum_rows;
@@ -4647,6 +4653,7 @@ ndb_get_table_statistics(Ndb* ndb, const char * table,
DBUG_RETURN(0);
} while(0);
+ ndb->closeTransaction(pTrans);
DBUG_PRINT("exit", ("failed"));
DBUG_RETURN(-1);
}
diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h
index 9d7cba459cb..6b878681c05 100644
--- a/sql/ha_ndbcluster.h
+++ b/sql/ha_ndbcluster.h
@@ -238,10 +238,12 @@ class ha_ndbcluster: public handler
char *m_blobs_buffer;
uint32 m_blobs_buffer_size;
uint m_dupkey;
+ // set from thread variables at external lock
bool m_ha_not_exact_count;
bool m_force_send;
ha_rows m_autoincrement_prefetch;
bool m_transaction_on;
+ bool m_use_local_query_cache;
void set_rec_per_key();
void records_update();
From 41c33c29a3bbdd6a32ad3103545abe726f84dbb9 Mon Sep 17 00:00:00 2001
From: "serg@serg.mylan" <>
Date: Mon, 22 Nov 2004 14:53:18 +0100
Subject: [PATCH 075/145] Bug #6748 heap_rfirst() doesn't work (and never did!)
range for BETWEEN typo fixed
---
extra/perror.c | 2 +-
heap/hp_rfirst.c | 1 +
mysql-test/r/heap.result | 7 +++++++
mysql-test/r/range.result | 4 ++--
mysql-test/t/heap.test | 11 +++++++++++
sql/handler.cc | 4 +++-
sql/sql_select.cc | 2 +-
7 files changed, 26 insertions(+), 5 deletions(-)
diff --git a/extra/perror.c b/extra/perror.c
index a28626fd873..1bd4b203120 100644
--- a/extra/perror.c
+++ b/extra/perror.c
@@ -69,7 +69,7 @@ static HA_ERRORS ha_errlist[]=
{
{ 120,"Didn't find key on read or update" },
{ 121,"Duplicate key on write or update" },
- { 123,"Someone has changed the row since it was read; Update with is recoverable" },
+ { 123,"Someone has changed the row since it was read (while the table was locked to prevent it)" },
{ 124,"Wrong index given to function" },
{ 126,"Index file is crashed" },
{ 127,"Record-file is crashed" },
diff --git a/heap/hp_rfirst.c b/heap/hp_rfirst.c
index 1668376ed1c..85548fea212 100644
--- a/heap/hp_rfirst.c
+++ b/heap/hp_rfirst.c
@@ -52,6 +52,7 @@ int heap_rfirst(HP_INFO *info, byte *record, int inx)
my_errno=HA_ERR_END_OF_FILE;
DBUG_RETURN(my_errno);
}
+ DBUG_ASSERT(0); /* TODO fix it */
info->current_record=0;
info->current_hash_ptr=0;
info->update=HA_STATE_PREV_FOUND;
diff --git a/mysql-test/r/heap.result b/mysql-test/r/heap.result
index 4950799137a..1f994b100e2 100644
--- a/mysql-test/r/heap.result
+++ b/mysql-test/r/heap.result
@@ -233,3 +233,10 @@ SELECT * FROM t1 WHERE B is not null;
a B
1 1
DROP TABLE t1;
+CREATE TABLE t1 (pseudo char(35) PRIMARY KEY, date int(10) unsigned NOT NULL) ENGINE=HEAP;
+INSERT INTO t1 VALUES ('massecot',1101106491),('altec',1101106492),('stitch+',1101106304),('Seb Corgan',1101106305),('beerfilou',1101106263),('flaker',1101106529),('joce8',5),('M4vrick',1101106418),('gabay008',1101106525),('Vamp irX',1101106291),('ZoomZip',1101106546),('rip666',1101106502),('CBP ',1101106397),('guezpard',1101106496);
+DELETE FROM t1 WHERE date<1101106546;
+SELECT * FROM t1;
+pseudo date
+ZoomZip 1101106546
+DROP TABLE t1;
diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result
index 17ed9513653..fc2b4a78469 100644
--- a/mysql-test/r/range.result
+++ b/mysql-test/r/range.result
@@ -221,7 +221,7 @@ update t1 set y=x;
explain select * from t1, t1 t2 where t1.y = 2 and t2.x between 7 and t1.y+0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref y y 5 const 1 Using where
-1 SIMPLE t2 range x x 5 NULL 4 Using where
+1 SIMPLE t2 range x x 5 NULL 4 Range checked for each record (index map: 0x1)
explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= 7 and t2.x <= t1.y+0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref y y 5 const 1 Using where
@@ -237,7 +237,7 @@ id select_type table type possible_keys key key_len ref rows Extra
explain select * from t1, t1 t2 where t1.y = 2 and t2.x between 0 and t1.y;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref y y 5 const 1 Using where
-1 SIMPLE t2 ALL x NULL NULL NULL 9 Using where
+1 SIMPLE t2 ALL x NULL NULL NULL 9 Range checked for each record (index map: 0x1)
explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= 0 and t2.x <= t1.y;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref y y 5 const 1 Using where
diff --git a/mysql-test/t/heap.test b/mysql-test/t/heap.test
index e1776245d9e..2eff36f3317 100644
--- a/mysql-test/t/heap.test
+++ b/mysql-test/t/heap.test
@@ -174,3 +174,14 @@ CREATE TABLE t1 (a INT NOT NULL, B INT, KEY(B)) ENGINE=HEAP;
INSERT INTO t1 VALUES(1,1), (1,NULL);
SELECT * FROM t1 WHERE B is not null;
DROP TABLE t1;
+
+#
+# Bug #6748
+# heap_rfirst() doesn't work (and never did!)
+#
+CREATE TABLE t1 (pseudo char(35) PRIMARY KEY, date int(10) unsigned NOT NULL) ENGINE=HEAP;
+INSERT INTO t1 VALUES ('massecot',1101106491),('altec',1101106492),('stitch+',1101106304),('Seb Corgan',1101106305),('beerfilou',1101106263),('flaker',1101106529),('joce8',5),('M4vrick',1101106418),('gabay008',1101106525),('Vamp irX',1101106291),('ZoomZip',1101106546),('rip666',1101106502),('CBP ',1101106397),('guezpard',1101106496);
+DELETE FROM t1 WHERE date<1101106546;
+SELECT * FROM t1;
+DROP TABLE t1;
+
diff --git a/sql/handler.cc b/sql/handler.cc
index 5dae7950390..7ddd7b80a34 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -953,8 +953,10 @@ int handler::read_first_row(byte * buf, uint primary_key)
/*
If there is very few deleted rows in the table, find the first row by
scanning the table.
+ TODO remove the test for HA_READ_ORDER
*/
- if (deleted < 10 || primary_key >= MAX_KEY)
+ if (deleted < 10 || primary_key >= MAX_KEY ||
+ !(index_flags(primary_key, 0, 0) & HA_READ_ORDER))
{
(void) ha_rnd_init(1);
while ((error= rnd_next(buf)) == HA_ERR_RECORD_DELETED) ;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 9162cd30d63..40dae434c5e 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -2154,7 +2154,7 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, COND *cond,
bool is_const=1;
for (uint i=0; iconst_item();
+ is_const&= value[i]->const_item();
if (is_const)
stat[0].const_keys.merge(possible_keys);
/*
From 9f6d5a02ca2c64600e6644957ca2d6f934bce26b Mon Sep 17 00:00:00 2001
From: "bar@mysql.com" <>
Date: Mon, 22 Nov 2004 18:17:41 +0400
Subject: [PATCH 076/145] uca-dump.c: Better variable names in dump. Dump
tertiary weight in reverse order, to sort upper letters before their lower
counterparts.
---
strings/uca-dump.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/strings/uca-dump.c b/strings/uca-dump.c
index c9642598c3c..db5cb7e999a 100644
--- a/strings/uca-dump.c
+++ b/strings/uca-dump.c
@@ -218,7 +218,6 @@ int main(int ac, char **av)
*/
if (ndefs == MY_UCA_NCHARS)
{
- printf("/* Don't dump w=%d pg=%3X: ndefs=%d */\n",w, page, ndefs);
continue;
}
switch (maxnum)
@@ -263,7 +262,17 @@ int main(int ac, char **av)
for (i=0; i < maxnum; i++)
{
- printf("0x%04X",(int)weight[i]);
+ /*
+ Invert weights for secondary level to
+ sort upper case letters before their
+ lower case counter part.
+ */
+ int tmp= weight[i];
+ if (w == 2 && tmp)
+ tmp= (int)(0x100 - weight[i]);
+
+
+ printf("0x%04X", tmp);
if ((offs+1 != MY_UCA_NCHARS) || (i+1!=maxnum))
printf(",");
nchars++;
@@ -281,7 +290,7 @@ int main(int ac, char **av)
printf("};\n\n");
}
- printf("uchar ucal%s[%d]={\n", pname[w], MY_UCA_NPAGES);
+ printf("uchar uca_length%s[%d]={\n", pname[w], MY_UCA_NPAGES);
for (page=0; page < MY_UCA_NPAGES; page++)
{
printf("%d%s%s",pagemaxlen[page],page
Date: Mon, 22 Nov 2004 15:27:28 +0100
Subject: [PATCH 077/145] wl2077 - bug fix for SCAN_TABREF
---
ndb/src/ndbapi/NdbScanOperation.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ndb/src/ndbapi/NdbScanOperation.cpp b/ndb/src/ndbapi/NdbScanOperation.cpp
index c037fe732fc..282b831f8fd 100644
--- a/ndb/src/ndbapi/NdbScanOperation.cpp
+++ b/ndb/src/ndbapi/NdbScanOperation.cpp
@@ -688,7 +688,7 @@ NdbScanOperation::execCLOSE_SCAN_REP(){
m_api_receivers_count = 0;
m_conf_receivers_count = 0;
m_sent_receivers_count = 0;
- m_current_api_receiver = theParallelism;
+ m_current_api_receiver = m_ordered ? theParallelism : 0;
}
void NdbScanOperation::release()
From a487b87928c03e3914fe49b87b1dfb5f23b44bb3 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Mon, 22 Nov 2004 15:05:51 +0000
Subject: [PATCH 078/145] added --no-defaults to ndb_drop_table in autodiscover
test
---
mysql-test/t/ndb_autodiscover.test | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/mysql-test/t/ndb_autodiscover.test b/mysql-test/t/ndb_autodiscover.test
index fd7fe0e60d8..6551732adba 100644
--- a/mysql-test/t/ndb_autodiscover.test
+++ b/mysql-test/t/ndb_autodiscover.test
@@ -199,7 +199,7 @@ insert into t4 values (1, "Automatic");
select * from t4;
# Remove the table from NDB
-system exec $NDB_TOOLS_DIR/ndb_drop_table -d test t4 > /dev/null ;
+system exec $NDB_TOOLS_DIR/ndb_drop_table --no-defaults -d test t4 > /dev/null ;
#
# Test that correct error is returned
@@ -230,7 +230,7 @@ select * from t4;
flush tables;
# Remove the table from NDB
-system exec $NDB_TOOLS_DIR/ndb_drop_table -d test t4 > /dev/null ;
+system exec $NDB_TOOLS_DIR/ndb_drop_table --no-defaults -d test t4 > /dev/null ;
SHOW TABLES;
@@ -264,8 +264,8 @@ insert into t8 values (8, "myisam table 8");
insert into t9 values (9);
# Remove t3, t5 from NDB
-system exec $NDB_TOOLS_DIR/ndb_drop_table -d test t3 > /dev/null ;
-system exec $NDB_TOOLS_DIR/ndb_drop_table -d test t5 > /dev/null ;
+system exec $NDB_TOOLS_DIR/ndb_drop_table --no-defaults -d test t3 > /dev/null ;
+system exec $NDB_TOOLS_DIR/ndb_drop_table --no-defaults -d test t5 > /dev/null ;
# Remove t6, t7 from disk
system rm var/master-data/test/t6.frm > /dev/null ;
system rm var/master-data/test/t7.frm > /dev/null ;
@@ -306,8 +306,8 @@ insert into t8 values (8, "myisam table 8");
insert into t9 values (9);
# Remove t3, t5 from NDB
-system exec $NDB_TOOLS_DIR/ndb_drop_table -d test t3 > /dev/null ;
-system exec $NDB_TOOLS_DIR/ndb_drop_table -d test t5 > /dev/null ;
+system exec $NDB_TOOLS_DIR/ndb_drop_table --no-defaults -d test t3 > /dev/null ;
+system exec $NDB_TOOLS_DIR/ndb_drop_table --no-defaults -d test t5 > /dev/null ;
# Remove t6, t7 from disk
system rm var/master-data/test/t6.frm > /dev/null ;
system rm var/master-data/test/t7.frm > /dev/null ;
@@ -479,4 +479,4 @@ create table t10 (
insert into t10 values (1, 'kalle');
---exec $NDB_TOOLS_DIR/ndb_drop_table -d test `$NDB_TOOLS_DIR/ndb_show_tables | grep BLOB` > /dev/null 2>&1 || true
+--exec $NDB_TOOLS_DIR/ndb_drop_table --no-defaults -d test `$NDB_TOOLS_DIR/ndb_show_tables --no-defaults | grep BLOB` > /dev/null 2>&1 || true
From 51e18c217a4b2b31d44930892d664229fbf3f9c3 Mon Sep 17 00:00:00 2001
From: "lenz@mysql.com" <>
Date: Mon, 22 Nov 2004 17:08:06 +0100
Subject: [PATCH 079/145] - renamed mysqladmin.c -> mysqladmin.cpp to fix the
Windows builds
---
.bzrignore | 1 +
VC++Files/client/mysqladmin.dsp | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/.bzrignore b/.bzrignore
index 670d46db613..10388d79013 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -939,3 +939,4 @@ ndbcluster-1186/ndb_3_cluster.log
ndbcluster-1186/ndb_3_out.log
ndbcluster-1186/ndbcluster.pid
ndb/tools/ndb_restore
+ac_available_languages_fragment
diff --git a/VC++Files/client/mysqladmin.dsp b/VC++Files/client/mysqladmin.dsp
index a7e4404e253..7a0b3bec1a7 100644
--- a/VC++Files/client/mysqladmin.dsp
+++ b/VC++Files/client/mysqladmin.dsp
@@ -115,7 +115,7 @@ LINK32=xilink6.exe
# Name "mysqladmin - Win32 classic"
# Begin Source File
-SOURCE=.\mysqladmin.c
+SOURCE=.\mysqladmin.cpp
# End Source File
# End Target
# End Project
From dca2182fdc8d2eedeaebfd2fbec8cd07b8be3fb5 Mon Sep 17 00:00:00 2001
From: "serg@serg.mylan" <>
Date: Mon, 22 Nov 2004 18:37:30 +0100
Subject: [PATCH 080/145] ft_boolean_search.c: bug#6705 - (+trunc1* +trunc2*)
fulltext.test, fulltext.result: bug#6705
---
myisam/ft_boolean_search.c | 4 ++--
mysql-test/r/fulltext.result | 8 ++++++++
mysql-test/t/fulltext.test | 2 ++
3 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/myisam/ft_boolean_search.c b/myisam/ft_boolean_search.c
index 97dfb18e5f9..1958619c2dd 100644
--- a/myisam/ft_boolean_search.c
+++ b/myisam/ft_boolean_search.c
@@ -247,7 +247,7 @@ static void _ftb_init_index_search(FT_INFO *ftb)
FTB_EXPR *top_ftbe=ftbe->up->up;
ftbw->docid[0]=HA_OFFSET_ERROR;
for (ftbe=ftbw->up; ftbe != top_ftbe; ftbe=ftbe->up)
- if (ftbe->flags & FTB_FLAG_YES)
+ if (!(ftbe->flags & FTB_FLAG_NO))
ftbe->yweaks++;
ftbe=0;
break;
@@ -255,7 +255,7 @@ static void _ftb_init_index_search(FT_INFO *ftb)
}
if (!ftbe)
continue;
- /* 3 */
+ /* 4 */
if (!is_tree_inited(& ftb->no_dupes))
init_tree(& ftb->no_dupes,0,0,sizeof(my_off_t),
_ftb_no_dupes_cmp,0,0,0);
diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result
index 31be1881897..50f0a1dc120 100644
--- a/mysql-test/r/fulltext.result
+++ b/mysql-test/r/fulltext.result
@@ -162,6 +162,14 @@ a
select * from t1 where match a against ("+aaa10 +(bbb*)" in boolean mode);
a
aaa10 bbb20
+select * from t1 where match a against ("+(+aaa* +bbb1*)" in boolean mode);
+a
+aaa20 bbb15
+aaa30 bbb10
+select * from t1 where match a against ("(+aaa* +bbb1*)" in boolean mode);
+a
+aaa20 bbb15
+aaa30 bbb10
drop table t1;
CREATE TABLE t1 (
id int(11),
diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test
index e46399bb876..b44854860f9 100644
--- a/mysql-test/t/fulltext.test
+++ b/mysql-test/t/fulltext.test
@@ -87,6 +87,8 @@ select * from t1 where match a against ("+aaa* +bbb*" in boolean mode);
select * from t1 where match a against ("+aaa* +bbb1*" in boolean mode);
select * from t1 where match a against ("+aaa* +ccc*" in boolean mode);
select * from t1 where match a against ("+aaa10 +(bbb*)" in boolean mode);
+select * from t1 where match a against ("+(+aaa* +bbb1*)" in boolean mode);
+select * from t1 where match a against ("(+aaa* +bbb1*)" in boolean mode);
drop table t1;
#
From 37f0ff9bc07abf4e41a53bd2285fe25bf1fdd8c4 Mon Sep 17 00:00:00 2001
From: "pekka@mysql.com" <>
Date: Mon, 22 Nov 2004 18:54:06 +0100
Subject: [PATCH 081/145] ndb: fix blob performance in long transactions
---
ndb/include/ndbapi/NdbConnection.hpp | 4 +-
ndb/src/ndbapi/NdbConnection.cpp | 36 ++++
ndb/test/ndbapi/testBlobs.cpp | 303 ++++++++++++++++++++++++++-
3 files changed, 340 insertions(+), 3 deletions(-)
diff --git a/ndb/include/ndbapi/NdbConnection.hpp b/ndb/include/ndbapi/NdbConnection.hpp
index 7af5d27b922..256199dced7 100644
--- a/ndb/include/ndbapi/NdbConnection.hpp
+++ b/ndb/include/ndbapi/NdbConnection.hpp
@@ -607,8 +607,8 @@ private:
NdbOperation* theLastExecOpInList; // Last executing operation in list.
- NdbOperation* theCompletedFirstOp; // First operation in completed
- // operation list.
+ NdbOperation* theCompletedFirstOp; // First & last operation in completed
+ NdbOperation* theCompletedLastOp; // operation list.
Uint32 theNoOfOpSent; // How many operations have been sent
Uint32 theNoOfOpCompleted; // How many operations have completed
diff --git a/ndb/src/ndbapi/NdbConnection.cpp b/ndb/src/ndbapi/NdbConnection.cpp
index 4f6468eb4ae..719c5bef49e 100644
--- a/ndb/src/ndbapi/NdbConnection.cpp
+++ b/ndb/src/ndbapi/NdbConnection.cpp
@@ -55,6 +55,7 @@ NdbConnection::NdbConnection( Ndb* aNdb ) :
theFirstExecOpInList(NULL),
theLastExecOpInList(NULL),
theCompletedFirstOp(NULL),
+ theCompletedLastOp(NULL),
theNoOfOpSent(0),
theNoOfOpCompleted(0),
theNoOfOpFetched(0),
@@ -124,6 +125,7 @@ NdbConnection::init()
theLastExecOpInList = NULL;
theCompletedFirstOp = NULL;
+ theCompletedLastOp = NULL;
theGlobalCheckpointId = 0;
theCommitStatus = Started;
@@ -256,6 +258,8 @@ NdbConnection::handleExecuteCompletion()
if (tLastExecOp != NULL) {
tLastExecOp->next(theCompletedFirstOp);
theCompletedFirstOp = tFirstExecOp;
+ if (theCompletedLastOp == NULL)
+ theCompletedLastOp = tLastExecOp;
theFirstExecOpInList = NULL;
theLastExecOpInList = NULL;
}//if
@@ -292,6 +296,8 @@ NdbConnection::execute(ExecType aTypeOfExec,
ExecType tExecType;
NdbOperation* tPrepOp;
+ NdbOperation* tCompletedFirstOp = NULL;
+ NdbOperation* tCompletedLastOp = NULL;
int ret = 0;
do {
@@ -314,6 +320,7 @@ NdbConnection::execute(ExecType aTypeOfExec,
}
tPrepOp = tPrepOp->next();
}
+
// save rest of prepared ops if batch
NdbOperation* tRestOp= 0;
NdbOperation* tLastOp= 0;
@@ -323,6 +330,7 @@ NdbConnection::execute(ExecType aTypeOfExec,
tLastOp = theLastOpInList;
theLastOpInList = tPrepOp;
}
+
if (tExecType == Commit) {
NdbOperation* tOp = theCompletedFirstOp;
while (tOp != NULL) {
@@ -338,6 +346,19 @@ NdbConnection::execute(ExecType aTypeOfExec,
}
}
+ // completed ops are in unspecified order
+ if (theCompletedFirstOp != NULL) {
+ if (tCompletedFirstOp == NULL) {
+ tCompletedFirstOp = theCompletedFirstOp;
+ tCompletedLastOp = theCompletedLastOp;
+ } else {
+ tCompletedLastOp->next(theCompletedFirstOp);
+ tCompletedLastOp = theCompletedLastOp;
+ }
+ theCompletedFirstOp = NULL;
+ theCompletedLastOp = NULL;
+ }
+
if (executeNoBlobs(tExecType, abortOption, forceSend) == -1)
ret = -1;
#ifndef VM_TRACE
@@ -362,6 +383,7 @@ NdbConnection::execute(ExecType aTypeOfExec,
tOp = tOp->next();
}
}
+
// add saved prepared ops if batch
if (tPrepOp != NULL && tRestOp != NULL) {
if (theFirstOpInList == NULL)
@@ -373,6 +395,18 @@ NdbConnection::execute(ExecType aTypeOfExec,
assert(theFirstOpInList == NULL || tExecType == NoCommit);
} while (theFirstOpInList != NULL || tExecType != aTypeOfExec);
+ if (tCompletedFirstOp != NULL) {
+ tCompletedLastOp->next(theCompletedFirstOp);
+ theCompletedFirstOp = tCompletedFirstOp;
+ if (theCompletedLastOp == NULL)
+ theCompletedLastOp = tCompletedLastOp;
+ }
+#if ndb_api_count_completed_ops_after_blob_execute
+ { NdbOperation* tOp; unsigned n = 0;
+ for (tOp = theCompletedFirstOp; tOp != NULL; tOp = tOp->next()) n++;
+ ndbout << "completed ops: " << n << endl;
+ }
+#endif
DBUG_RETURN(ret);
}
@@ -894,6 +928,7 @@ NdbConnection::releaseOperations()
releaseOps(theFirstExecOpInList);
theCompletedFirstOp = NULL;
+ theCompletedLastOp = NULL;
theFirstOpInList = NULL;
theFirstExecOpInList = NULL;
theLastOpInList = NULL;
@@ -909,6 +944,7 @@ NdbConnection::releaseCompletedOperations()
{
releaseOps(theCompletedFirstOp);
theCompletedFirstOp = NULL;
+ theCompletedLastOp = NULL;
}//NdbConnection::releaseOperations()
/******************************************************************************
diff --git a/ndb/test/ndbapi/testBlobs.cpp b/ndb/test/ndbapi/testBlobs.cpp
index efa0811aa39..4b532856709 100644
--- a/ndb/test/ndbapi/testBlobs.cpp
+++ b/ndb/test/ndbapi/testBlobs.cpp
@@ -22,6 +22,7 @@
#include
#include
#include
+#include
struct Bcol {
bool m_nullable;
@@ -59,6 +60,9 @@ struct Opt {
bool m_oneblob;
Bcol m_blob1;
Bcol m_blob2;
+ // perf
+ const char* m_tnameperf;
+ unsigned m_rowsperf;
// bugs
int m_bug;
int (*m_bugtest)();
@@ -84,6 +88,9 @@ struct Opt {
m_oneblob(false),
m_blob1(false, 7, 1137, 10),
m_blob2(true, 99, 55, 1),
+ // perf
+ m_tnameperf("TBLOB2"),
+ m_rowsperf(10000),
// bugs
m_bug(0),
m_bugtest(0) {
@@ -107,6 +114,7 @@ printusage()
<< " -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
+ << " -rowsperf N rows for performace test [" << d.m_rowsperf << "]" << endl
<< " -seed N random seed 0=loop number [" << d.m_seed << "]" << endl
<< " -skip xxx skip given tests (see list) [no tests]" << endl
<< " -test xxx only given tests (see list) [all tests]" << endl
@@ -118,6 +126,7 @@ printusage()
<< " i hash index ops" << endl
<< " s table scans" << endl
<< " r ordered index scans" << endl
+ << " p performance test" << endl
<< "additional flags for test/skip" << endl
<< " u update existing blob value" << endl
<< " n normal insert and update" << endl
@@ -1381,6 +1390,292 @@ testmain()
return 0;
}
+// separate performance test
+
+struct Tmr { // stolen from testOIBasic
+ Tmr() {
+ clr();
+ }
+ void clr() {
+ m_on = m_ms = m_cnt = m_time[0] = m_text[0] = 0;
+ }
+ void on() {
+ assert(m_on == 0);
+ m_on = NdbTick_CurrentMillisecond();
+ }
+ void off(unsigned cnt = 0) {
+ NDB_TICKS off = NdbTick_CurrentMillisecond();
+ assert(m_on != 0 && off >= m_on);
+ m_ms += off - m_on;
+ m_cnt += cnt;
+ m_on = 0;
+ }
+ const char* time() {
+ if (m_cnt == 0)
+ sprintf(m_time, "%u ms", m_ms);
+ else
+ sprintf(m_time, "%u ms per %u ( %u ms per 1000 )", m_ms, m_cnt, (1000 * m_ms) / m_cnt);
+ return m_time;
+ }
+ const char* pct (const Tmr& t1) {
+ if (0 < t1.m_ms)
+ sprintf(m_text, "%u pct", (100 * m_ms) / t1.m_ms);
+ else
+ sprintf(m_text, "[cannot measure]");
+ return m_text;
+ }
+ const char* over(const Tmr& t1) {
+ if (0 < t1.m_ms) {
+ if (t1.m_ms <= m_ms)
+ sprintf(m_text, "%u pct", (100 * (m_ms - t1.m_ms)) / t1.m_ms);
+ else
+ sprintf(m_text, "-%u pct", (100 * (t1.m_ms - m_ms)) / t1.m_ms);
+ } else
+ sprintf(m_text, "[cannot measure]");
+ return m_text;
+ }
+ NDB_TICKS m_on;
+ unsigned m_ms;
+ unsigned m_cnt;
+ char m_time[100];
+ char m_text[100];
+};
+
+static int
+testperf()
+{
+ if (! testcase('p'))
+ return 0;
+ DBG("=== perf test ===");
+ g_ndb = new Ndb("TEST_DB");
+ CHK(g_ndb->init() == 0);
+ CHK(g_ndb->waitUntilReady() == 0);
+ g_dic = g_ndb->getDictionary();
+ NdbDictionary::Table tab(g_opt.m_tnameperf);
+ if (g_dic->getTable(tab.getName()) != 0)
+ CHK(g_dic->dropTable(tab) == 0);
+ // col A - pk
+ { NdbDictionary::Column col("A");
+ col.setType(NdbDictionary::Column::Unsigned);
+ col.setPrimaryKey(true);
+ tab.addColumn(col);
+ }
+ // col B - char 20
+ { NdbDictionary::Column col("B");
+ col.setType(NdbDictionary::Column::Char);
+ col.setLength(20);
+ col.setNullable(true);
+ tab.addColumn(col);
+ }
+ // col C - text
+ { NdbDictionary::Column col("C");
+ col.setType(NdbDictionary::Column::Text);
+ col.setInlineSize(20);
+ col.setPartSize(512);
+ col.setStripeSize(1);
+ col.setNullable(true);
+ tab.addColumn(col);
+ }
+ // create
+ CHK(g_dic->createTable(tab) == 0);
+ Uint32 cA = 0, cB = 1, cC = 2;
+ // timers
+ Tmr t1;
+ Tmr t2;
+ // insert char (one trans)
+ {
+ DBG("--- insert char ---");
+ t1.on();
+ CHK((g_con = g_ndb->startTransaction()) != 0);
+ for (Uint32 k = 0; k < g_opt.m_rowsperf; k++) {
+ CHK((g_opr = g_con->getNdbOperation(tab.getName())) != 0);
+ CHK(g_opr->insertTuple() == 0);
+ CHK(g_opr->equal(cA, (char*)&k) == 0);
+ CHK(g_opr->setValue(cB, "b") == 0);
+ CHK(g_con->execute(NoCommit) == 0);
+ }
+ t1.off(g_opt.m_rowsperf);
+ CHK(g_con->execute(Rollback) == 0);
+ DBG(t1.time());
+ g_opr = 0;
+ g_con = 0;
+ }
+ // insert text (one trans)
+ {
+ DBG("--- insert text ---");
+ t2.on();
+ CHK((g_con = g_ndb->startTransaction()) != 0);
+ for (Uint32 k = 0; k < g_opt.m_rowsperf; k++) {
+ CHK((g_opr = g_con->getNdbOperation(tab.getName())) != 0);
+ CHK(g_opr->insertTuple() == 0);
+ CHK(g_opr->equal(cA, (char*)&k) == 0);
+ CHK((g_bh1 = g_opr->getBlobHandle(cC)) != 0);
+ CHK((g_bh1->setValue("c", 1) == 0));
+ CHK(g_con->execute(NoCommit) == 0);
+ }
+ t2.off(g_opt.m_rowsperf);
+ CHK(g_con->execute(Rollback) == 0);
+ DBG(t2.time());
+ g_bh1 = 0;
+ g_opr = 0;
+ g_con = 0;
+ }
+ // insert overhead
+ DBG("insert overhead: " << t2.over(t1));
+ t1.clr();
+ t2.clr();
+ // insert
+ {
+ DBG("--- insert for read test ---");
+ unsigned n = 0;
+ CHK((g_con = g_ndb->startTransaction()) != 0);
+ for (Uint32 k = 0; k < g_opt.m_rowsperf; k++) {
+ CHK((g_opr = g_con->getNdbOperation(tab.getName())) != 0);
+ CHK(g_opr->insertTuple() == 0);
+ CHK(g_opr->equal(cA, (char*)&k) == 0);
+ CHK(g_opr->setValue(cB, "b") == 0);
+ CHK((g_bh1 = g_opr->getBlobHandle(cC)) != 0);
+ CHK((g_bh1->setValue("c", 1) == 0));
+ if (++n == g_opt.m_batch) {
+ CHK(g_con->execute(Commit) == 0);
+ g_ndb->closeTransaction(g_con);
+ CHK((g_con = g_ndb->startTransaction()) != 0);
+ n = 0;
+ }
+ }
+ if (n != 0) {
+ CHK(g_con->execute(Commit) == 0);
+ n = 0;
+ }
+ g_bh1 = 0;
+ g_opr = 0;
+ g_con = 0;
+ }
+ // pk read char (one trans)
+ {
+ DBG("--- pk read char ---");
+ CHK((g_con = g_ndb->startTransaction()) != 0);
+ Uint32 a;
+ char b[20];
+ t1.on();
+ for (Uint32 k = 0; k < g_opt.m_rowsperf; k++) {
+ CHK((g_opr = g_con->getNdbOperation(tab.getName())) != 0);
+ CHK(g_opr->readTuple() == 0);
+ CHK(g_opr->equal(cA, (char*)&k) == 0);
+ CHK(g_opr->getValue(cA, (char*)&a) != 0);
+ CHK(g_opr->getValue(cB, b) != 0);
+ a = (Uint32)-1;
+ b[0] = 0;
+ CHK(g_con->execute(NoCommit) == 0);
+ CHK(a == k && strcmp(b, "b") == 0);
+ }
+ CHK(g_con->execute(Commit) == 0);
+ t1.off(g_opt.m_rowsperf);
+ DBG(t1.time());
+ g_opr = 0;
+ g_con = 0;
+ }
+ // pk read text (one trans)
+ {
+ DBG("--- pk read text ---");
+ CHK((g_con = g_ndb->startTransaction()) != 0);
+ Uint32 a;
+ char c[20];
+ t2.on();
+ for (Uint32 k = 0; k < g_opt.m_rowsperf; k++) {
+ CHK((g_opr = g_con->getNdbOperation(tab.getName())) != 0);
+ CHK(g_opr->readTuple() == 0);
+ CHK(g_opr->equal(cA, (char*)&k) == 0);
+ CHK(g_opr->getValue(cA, (char*)&a) != 0);
+ CHK((g_bh1 = g_opr->getBlobHandle(cC)) != 0);
+ a = (Uint32)-1;
+ c[0] = 0;
+ CHK(g_con->execute(NoCommit) == 0);
+ Uint32 m = 20;
+ CHK(g_bh1->readData(c, m) == 0);
+ CHK(a == k && m == 1 && strcmp(c, "c") == 0);
+ }
+ CHK(g_con->execute(Commit) == 0);
+ t2.off(g_opt.m_rowsperf);
+ DBG(t2.time());
+ g_opr = 0;
+ g_con = 0;
+ }
+ // pk read overhead
+ DBG("pk read overhead: " << t2.over(t1));
+ t1.clr();
+ t2.clr();
+ // scan read char
+ {
+ DBG("--- scan read char ---");
+ NdbResultSet* rs;
+ Uint32 a;
+ char b[20];
+ CHK((g_con = g_ndb->startTransaction()) != 0);
+ CHK((g_ops = g_con->getNdbScanOperation(tab.getName())) != 0);
+ CHK((rs = g_ops->readTuples(NdbScanOperation::LM_Read)) != 0);
+ CHK(g_ops->getValue(cA, (char*)&a) != 0);
+ CHK(g_ops->getValue(cB, b) != 0);
+ CHK(g_con->execute(NoCommit) == 0);
+ unsigned n = 0;
+ t1.on();
+ while (1) {
+ a = (Uint32)-1;
+ b[0] = 0;
+ int ret;
+ CHK((ret = rs->nextResult(true)) == 0 || ret == 1);
+ if (ret == 1)
+ break;
+ CHK(a < g_opt.m_rowsperf && strcmp(b, "b") == 0);
+ n++;
+ }
+ CHK(n == g_opt.m_rowsperf);
+ t1.off(g_opt.m_rowsperf);
+ DBG(t1.time());
+ g_ops = 0;
+ g_con = 0;
+ }
+ // scan read text
+ {
+ DBG("--- read text ---");
+ NdbResultSet* rs;
+ Uint32 a;
+ char c[20];
+ CHK((g_con = g_ndb->startTransaction()) != 0);
+ CHK((g_ops = g_con->getNdbScanOperation(tab.getName())) != 0);
+ CHK((rs = g_ops->readTuples(NdbScanOperation::LM_Read)) != 0);
+ CHK(g_ops->getValue(cA, (char*)&a) != 0);
+ CHK((g_bh1 = g_ops->getBlobHandle(cC)) != 0);
+ CHK(g_con->execute(NoCommit) == 0);
+ unsigned n = 0;
+ t2.on();
+ while (1) {
+ a = (Uint32)-1;
+ c[0] = 0;
+ int ret;
+ CHK((ret = rs->nextResult(true)) == 0 || ret == 1);
+ if (ret == 1)
+ break;
+ Uint32 m = 20;
+ CHK(g_bh1->readData(c, m) == 0);
+ CHK(a < g_opt.m_rowsperf && m == 1 && strcmp(c, "c") == 0);
+ n++;
+ }
+ CHK(n == g_opt.m_rowsperf);
+ t2.off(g_opt.m_rowsperf);
+ DBG(t2.time());
+ g_bh1 = 0;
+ g_ops = 0;
+ g_con = 0;
+ }
+ // scan read overhead
+ DBG("scan read overhead: " << t2.over(t1));
+ t1.clr();
+ t2.clr();
+ delete g_ndb;
+ return 0;
+}
+
// bug tests
static int
@@ -1498,6 +1793,12 @@ NDB_COMMAND(testOdbcDriver, "testBlobs", "testBlobs", "testBlobs", 65535)
continue;
}
}
+ if (strcmp(arg, "-rowsperf") == 0) {
+ if (++argv, --argc > 0) {
+ g_opt.m_rowsperf = atoi(argv[0]);
+ continue;
+ }
+ }
if (strcmp(arg, "-seed") == 0) {
if (++argv, --argc > 0) {
g_opt.m_seed = atoi(argv[0]);
@@ -1558,7 +1859,7 @@ NDB_COMMAND(testOdbcDriver, "testBlobs", "testBlobs", "testBlobs", 65535)
strcat(b, "r");
g_opt.m_skip = strdup(b);
}
- if (testmain() == -1) {
+ if (testmain() == -1 || testperf() == -1) {
ndbout << "line " << __LINE__ << " FAIL loop=" << g_loop << endl;
return NDBT_ProgramExit(NDBT_FAILED);
}
From 076f27147fcb8624b03e167063b424c7b512721f Mon Sep 17 00:00:00 2001
From: "antony@ltantony.rdg.cyberkinetica.homeunix.net" <>
Date: Mon, 22 Nov 2004 18:07:04 +0000
Subject: [PATCH 082/145] Bug#6252 - Duplicate columns in keys should fail
Added check for duplicate column in key Added tests and fixed tests which
exploit bug
---
mysql-test/r/delete.result | 30 ++++++++++++++++++++++++++----
mysql-test/r/innodb.result | 18 ++++++++++++++++++
mysql-test/r/key.result | 18 ++++++++++++++++++
mysql-test/r/type_blob.result | 4 ++--
mysql-test/t/delete.test | 30 ++++++++++++++++++++++++++----
mysql-test/t/innodb.test | 22 ++++++++++++++++++++++
mysql-test/t/key.test | 23 +++++++++++++++++++++++
mysql-test/t/type_blob.test | 4 ++--
sql/sql_table.cc | 15 ++++++++++++++-
9 files changed, 151 insertions(+), 13 deletions(-)
diff --git a/mysql-test/r/delete.result b/mysql-test/r/delete.result
index 5575ee1bf98..f1fba87c70b 100644
--- a/mysql-test/r/delete.result
+++ b/mysql-test/r/delete.result
@@ -16,12 +16,34 @@ SET AUTOCOMMIT=0;
DELETE from t1;
SET AUTOCOMMIT=1;
drop table t1;
-create table t1 (a bigint not null, primary key (a,a,a,a,a,a,a,a,a,a));
-insert into t1 values (2),(4),(6),(8),(10),(12),(14),(16),(18),(20),(22),(24),(26),(23);
+create table t1 (
+a bigint not null,
+b bigint not null default 0,
+c bigint not null default 0,
+d bigint not null default 0,
+e bigint not null default 0,
+f bigint not null default 0,
+g bigint not null default 0,
+h bigint not null default 0,
+i bigint not null default 0,
+j bigint not null default 0,
+primary key (a,b,c,d,e,f,g,h,i,j));
+insert into t1 (a) values (2),(4),(6),(8),(10),(12),(14),(16),(18),(20),(22),(24),(26),(23);
delete from t1 where a=26;
drop table t1;
-create table t1 (a bigint not null, primary key (a,a,a,a,a,a,a,a,a,a));
-insert into t1 values (2),(4),(6),(8),(10),(12),(14),(16),(18),(20),(22),(24),(26),(23),(27);
+create table t1 (
+a bigint not null,
+b bigint not null default 0,
+c bigint not null default 0,
+d bigint not null default 0,
+e bigint not null default 0,
+f bigint not null default 0,
+g bigint not null default 0,
+h bigint not null default 0,
+i bigint not null default 0,
+j bigint not null default 0,
+primary key (a,b,c,d,e,f,g,h,i,j));
+insert into t1 (a) values (2),(4),(6),(8),(10),(12),(14),(16),(18),(20),(22),(24),(26),(23),(27);
delete from t1 where a=27;
drop table t1;
CREATE TABLE `t1` (
diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result
index 9d830367745..009432ec3ab 100644
--- a/mysql-test/r/innodb.result
+++ b/mysql-test/r/innodb.result
@@ -1630,3 +1630,21 @@ show status like "binlog_cache_disk_use";
Variable_name Value
Binlog_cache_disk_use 1
drop table t1;
+create table t1 (c char(10), index (c,c)) engine=innodb;
+ERROR 42S21: Duplicate column name 'c'
+create table t1 (c1 char(10), c2 char(10), index (c1,c2,c1)) engine=innodb;
+ERROR 42S21: Duplicate column name 'c1'
+create table t1 (c1 char(10), c2 char(10), index (c1,c1,c2)) engine=innodb;
+ERROR 42S21: Duplicate column name 'c1'
+create table t1 (c1 char(10), c2 char(10), index (c2,c1,c1)) engine=innodb;
+ERROR 42S21: Duplicate column name 'c1'
+create table t1 (c1 char(10), c2 char(10)) engine=innodb;
+alter table t1 add key (c1,c1);
+ERROR 42S21: Duplicate column name 'c1'
+alter table t1 add key (c2,c1,c1);
+ERROR 42S21: Duplicate column name 'c1'
+alter table t1 add key (c1,c2,c1);
+ERROR 42S21: Duplicate column name 'c1'
+alter table t1 add key (c1,c1,c2);
+ERROR 42S21: Duplicate column name 'c1'
+drop table t1;
diff --git a/mysql-test/r/key.result b/mysql-test/r/key.result
index e74bda23da9..cceaf393a60 100644
--- a/mysql-test/r/key.result
+++ b/mysql-test/r/key.result
@@ -307,3 +307,21 @@ test.t1 check status OK
drop table t1;
create table t1 (c char(10), index (c(0)));
ERROR HY000: Key part 'c' length cannot be 0
+create table t1 (c char(10), index (c,c));
+ERROR 42S21: Duplicate column name 'c'
+create table t1 (c1 char(10), c2 char(10), index (c1,c2,c1));
+ERROR 42S21: Duplicate column name 'c1'
+create table t1 (c1 char(10), c2 char(10), index (c1,c1,c2));
+ERROR 42S21: Duplicate column name 'c1'
+create table t1 (c1 char(10), c2 char(10), index (c2,c1,c1));
+ERROR 42S21: Duplicate column name 'c1'
+create table t1 (c1 char(10), c2 char(10));
+alter table t1 add key (c1,c1);
+ERROR 42S21: Duplicate column name 'c1'
+alter table t1 add key (c2,c1,c1);
+ERROR 42S21: Duplicate column name 'c1'
+alter table t1 add key (c1,c2,c1);
+ERROR 42S21: Duplicate column name 'c1'
+alter table t1 add key (c1,c1,c2);
+ERROR 42S21: Duplicate column name 'c1'
+drop table t1;
diff --git a/mysql-test/r/type_blob.result b/mysql-test/r/type_blob.result
index 95bba1d4ec7..8a0c74b3ae5 100644
--- a/mysql-test/r/type_blob.result
+++ b/mysql-test/r/type_blob.result
@@ -682,8 +682,8 @@ id txt
3 NULL
1 Chevy
drop table t1;
-CREATE TABLE t1 ( i int(11) NOT NULL default '0', c text NOT NULL, PRIMARY KEY (i), KEY (c(1),c(1)));
-INSERT t1 VALUES (1,''),(2,''),(3,'asdfh'),(4,'');
+CREATE TABLE t1 ( i int(11) NOT NULL default '0', c text NOT NULL, d varchar(1) NOT NULL DEFAULT ' ', PRIMARY KEY (i), KEY (c(1),d));
+INSERT t1 (i, c) VALUES (1,''),(2,''),(3,'asdfh'),(4,'');
select max(i) from t1 where c = '';
max(i)
4
diff --git a/mysql-test/t/delete.test b/mysql-test/t/delete.test
index 5f60445d765..0bf7187865d 100644
--- a/mysql-test/t/delete.test
+++ b/mysql-test/t/delete.test
@@ -29,12 +29,34 @@ drop table t1;
# (This assumes a block size of 1024)
#
-create table t1 (a bigint not null, primary key (a,a,a,a,a,a,a,a,a,a));
-insert into t1 values (2),(4),(6),(8),(10),(12),(14),(16),(18),(20),(22),(24),(26),(23);
+create table t1 (
+ a bigint not null,
+ b bigint not null default 0,
+ c bigint not null default 0,
+ d bigint not null default 0,
+ e bigint not null default 0,
+ f bigint not null default 0,
+ g bigint not null default 0,
+ h bigint not null default 0,
+ i bigint not null default 0,
+ j bigint not null default 0,
+ primary key (a,b,c,d,e,f,g,h,i,j));
+insert into t1 (a) values (2),(4),(6),(8),(10),(12),(14),(16),(18),(20),(22),(24),(26),(23);
delete from t1 where a=26;
drop table t1;
-create table t1 (a bigint not null, primary key (a,a,a,a,a,a,a,a,a,a));
-insert into t1 values (2),(4),(6),(8),(10),(12),(14),(16),(18),(20),(22),(24),(26),(23),(27);
+create table t1 (
+ a bigint not null,
+ b bigint not null default 0,
+ c bigint not null default 0,
+ d bigint not null default 0,
+ e bigint not null default 0,
+ f bigint not null default 0,
+ g bigint not null default 0,
+ h bigint not null default 0,
+ i bigint not null default 0,
+ j bigint not null default 0,
+ primary key (a,b,c,d,e,f,g,h,i,j));
+insert into t1 (a) values (2),(4),(6),(8),(10),(12),(14),(16),(18),(20),(22),(24),(26),(23),(27);
delete from t1 where a=27;
drop table t1;
diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test
index a452f79f949..cf7be4f882c 100644
--- a/mysql-test/t/innodb.test
+++ b/mysql-test/t/innodb.test
@@ -1158,3 +1158,25 @@ show status like "binlog_cache_use";
show status like "binlog_cache_disk_use";
drop table t1;
+
+#
+# Bug #6126: Duplicate columns in keys gives misleading error message
+#
+--error 1060
+create table t1 (c char(10), index (c,c)) engine=innodb;
+--error 1060
+create table t1 (c1 char(10), c2 char(10), index (c1,c2,c1)) engine=innodb;
+--error 1060
+create table t1 (c1 char(10), c2 char(10), index (c1,c1,c2)) engine=innodb;
+--error 1060
+create table t1 (c1 char(10), c2 char(10), index (c2,c1,c1)) engine=innodb;
+create table t1 (c1 char(10), c2 char(10)) engine=innodb;
+--error 1060
+alter table t1 add key (c1,c1);
+--error 1060
+alter table t1 add key (c2,c1,c1);
+--error 1060
+alter table t1 add key (c1,c2,c1);
+--error 1060
+alter table t1 add key (c1,c1,c2);
+drop table t1;
diff --git a/mysql-test/t/key.test b/mysql-test/t/key.test
index 5ee2f68ab83..a0a291fdf3c 100644
--- a/mysql-test/t/key.test
+++ b/mysql-test/t/key.test
@@ -297,3 +297,26 @@ drop table t1;
--error 1105
create table t1 (c char(10), index (c(0)));
+
+#
+# Bug #6126: Duplicate columns in keys should fail
+# Bug #6252: (dup)
+#
+--error 1060
+create table t1 (c char(10), index (c,c));
+--error 1060
+create table t1 (c1 char(10), c2 char(10), index (c1,c2,c1));
+--error 1060
+create table t1 (c1 char(10), c2 char(10), index (c1,c1,c2));
+--error 1060
+create table t1 (c1 char(10), c2 char(10), index (c2,c1,c1));
+create table t1 (c1 char(10), c2 char(10));
+--error 1060
+alter table t1 add key (c1,c1);
+--error 1060
+alter table t1 add key (c2,c1,c1);
+--error 1060
+alter table t1 add key (c1,c2,c1);
+--error 1060
+alter table t1 add key (c1,c1,c2);
+drop table t1;
diff --git a/mysql-test/t/type_blob.test b/mysql-test/t/type_blob.test
index b67fa7a552d..f70193ddbe0 100644
--- a/mysql-test/t/type_blob.test
+++ b/mysql-test/t/type_blob.test
@@ -369,8 +369,8 @@ explain select * from t1 where txt='Chevy' or txt is NULL order by txt;
select * from t1 where txt='Chevy' or txt is NULL order by txt;
drop table t1;
-CREATE TABLE t1 ( i int(11) NOT NULL default '0', c text NOT NULL, PRIMARY KEY (i), KEY (c(1),c(1)));
-INSERT t1 VALUES (1,''),(2,''),(3,'asdfh'),(4,'');
+CREATE TABLE t1 ( i int(11) NOT NULL default '0', c text NOT NULL, d varchar(1) NOT NULL DEFAULT ' ', PRIMARY KEY (i), KEY (c(1),d));
+INSERT t1 (i, c) VALUES (1,''),(2,''),(3,'asdfh'),(4,'');
select max(i) from t1 where c = '';
drop table t1;
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 3a242dc6547..eedd9388877 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -835,7 +835,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
#endif
}
- List_iterator cols(key->columns);
+ List_iterator cols(key->columns), cols2(key->columns);
CHARSET_INFO *ft_key_charset=0; // for FULLTEXT
for (uint column_nr=0 ; (column=cols++) ; column_nr++)
{
@@ -853,6 +853,19 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
column->field_name);
DBUG_RETURN(-1);
}
+ for (uint dup_nr= 0; dup_nr < column_nr; dup_nr++)
+ {
+ key_part_spec *dup_column= cols2++;
+ if (!my_strcasecmp(system_charset_info,
+ column->field_name, dup_column->field_name))
+ {
+ my_printf_error(ER_DUP_FIELDNAME,
+ ER(ER_DUP_FIELDNAME),MYF(0),
+ column->field_name);
+ DBUG_RETURN(-1);
+ }
+ }
+ cols2.rewind();
/* for fulltext keys keyseg length is 1 for blobs (it's ignored in
ft code anyway, and 0 (set to column width later) for char's.
it has to be correct col width for char's, as char data are not
From b7aa981578e03317128868d5011db33a08d0f74d Mon Sep 17 00:00:00 2001
From: "serg@serg.mylan" <>
Date: Mon, 22 Nov 2004 19:18:35 +0100
Subject: [PATCH 083/145] "Table file %s was created in MySQL 4.1+" is an
error, not a warning
---
myisam/mi_open.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/myisam/mi_open.c b/myisam/mi_open.c
index 944a8af01e9..339ce2de291 100644
--- a/myisam/mi_open.c
+++ b/myisam/mi_open.c
@@ -188,7 +188,11 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
share->state_diff_length=len-MI_STATE_INFO_SIZE;
if (share->state.header.fulltext_keys)
+ {
fprintf(stderr, "Warning: table file %s was created in MySQL 4.1+, use REPAIR TABLE ... USE_FRM to recreate it as a valid MySQL 4.0 table\n", name_buff);
+ my_errno=HA_ERR_UNSUPPORTED;
+ goto err;
+ }
mi_state_info_read(disk_cache, &share->state);
len= mi_uint2korr(share->state.header.base_info_length);
From cb7563b05cd2074341c9f8434a42289922426f5f Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Tue, 23 Nov 2004 09:12:56 +0000
Subject: [PATCH 084/145] small bug fix for ndb restarter
---
ndb/test/src/NdbBackup.cpp | 5 +++--
ndb/test/src/NdbRestarter.cpp | 2 +-
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/ndb/test/src/NdbBackup.cpp b/ndb/test/src/NdbBackup.cpp
index 655fdda7c95..09f52bf0bed 100644
--- a/ndb/test/src/NdbBackup.cpp
+++ b/ndb/test/src/NdbBackup.cpp
@@ -146,13 +146,14 @@ NdbBackup::execRestore(bool _restore_data,
ndbout << "scp res: " << res << endl;
- BaseString::snprintf(buf, 255, "%sndb_restore -c \"%s\" -n %d -b %d %s %s .",
+ BaseString::snprintf(buf, 255, "%sndb_restore -c \"%s:%d\" -n %d -b %d %s %s .",
#if 1
"",
#else
"valgrind --leak-check=yes -v "
#endif
- addr.c_str(),
+ ndb_mgm_get_connected_host(handle),
+ ndb_mgm_get_connected_port(handle),
_node_id,
_backup_id,
_restore_data?"-r":"",
diff --git a/ndb/test/src/NdbRestarter.cpp b/ndb/test/src/NdbRestarter.cpp
index 1c5fbbabb42..91c0963feae 100644
--- a/ndb/test/src/NdbRestarter.cpp
+++ b/ndb/test/src/NdbRestarter.cpp
@@ -36,7 +36,7 @@ NdbRestarter::NdbRestarter(const char* _addr):
m_config(0)
{
if (_addr == NULL){
- addr.assign("localhost");
+ addr.assign("");
} else {
addr.assign(_addr);
}
From cfb82e9ef7c3c6654291bc27f42338f30af7af54 Mon Sep 17 00:00:00 2001
From: "wax@kishkin.ru" <>
Date: Tue, 23 Nov 2004 17:55:07 +0500
Subject: [PATCH 085/145] rename event_connect_request to
smem_event_connect_request
---
sql/mysqld.cc | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 89b0a035e6c..ea4d52359f1 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -468,7 +468,7 @@ Query_cache query_cache;
#ifdef HAVE_SMEM
char *shared_memory_base_name= default_shared_memory_base_name;
bool opt_enable_shared_memory;
-HANDLE event_connect_request= 0;
+HANDLE smem_event_connect_request= 0;
#endif
#include "sslopt-vars.h"
@@ -746,11 +746,11 @@ void kill_mysql(void)
}
#ifdef HAVE_SMEM
/*
- Send event to event_connect_request for aborting
+ Send event to smem_event_connect_request for aborting
*/
- if (!SetEvent(event_connect_request))
+ if (!SetEvent(smem_event_connect_request))
{
- DBUG_PRINT("error",("Got error: %ld from SetEvent of event_connect_request",GetLastError()));
+ DBUG_PRINT("error",("Got error: %ld from SetEvent of smem_event_connect_request",GetLastError()));
}
#endif
#endif
@@ -3737,7 +3737,7 @@ pthread_handler_decl(handle_connections_shared_memory,arg)
*/
suffix_pos= strxmov(tmp,shared_memory_base_name,"_",NullS);
strmov(suffix_pos, "CONNECT_REQUEST");
- if ((event_connect_request= CreateEvent(0,FALSE,FALSE,tmp)) == 0)
+ if ((smem_event_connect_request= CreateEvent(0,FALSE,FALSE,tmp)) == 0)
{
errmsg= "Could not create request event";
goto error;
@@ -3768,7 +3768,7 @@ pthread_handler_decl(handle_connections_shared_memory,arg)
while (!abort_loop)
{
/* Wait a request from client */
- WaitForSingleObject(event_connect_request,INFINITE);
+ WaitForSingleObject(smem_event_connect_request,INFINITE);
/*
it can be after shutdown command
@@ -3899,7 +3899,7 @@ error:
if (handle_connect_map) UnmapViewOfFile(handle_connect_map);
if (handle_connect_file_map) CloseHandle(handle_connect_file_map);
if (event_connect_answer) CloseHandle(event_connect_answer);
- if (event_connect_request) CloseHandle(event_connect_request);
+ if (smem_event_connect_request) CloseHandle(smem_event_connect_request);
decrement_handler_count();
DBUG_RETURN(0);
From f88cf926576440dfa5c0f70d56a3aa7eb5f8bdf4 Mon Sep 17 00:00:00 2001
From: "wax@kishkin.ru" <>
Date: Tue, 23 Nov 2004 18:05:13 +0500
Subject: [PATCH 086/145] Delete: mysql-test/mysql_test_run.c
---
mysql-test/mysql_test_run.c | 1728 -----------------------------------
1 file changed, 1728 deletions(-)
delete mode 100644 mysql-test/mysql_test_run.c
diff --git a/mysql-test/mysql_test_run.c b/mysql-test/mysql_test_run.c
deleted file mode 100644
index 6f388fc4a45..00000000000
--- a/mysql-test/mysql_test_run.c
+++ /dev/null
@@ -1,1728 +0,0 @@
-/*
- Copyright (c) 2002, 2003 Novell, Inc. All Rights Reserved.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include
-#include
-#include
-#ifndef __WIN__
-#include
-#endif
-#include
-#ifdef __NETWARE__
-#include
-#include
-#endif
-#include
-#include
-#ifndef __WIN__
-#include
-#endif
-#include
-#ifdef __NETWARE__
-#include
-#endif
-#ifdef __WIN__
-#include
-#include
-#endif
-
-#include "my_manage.h"
-
-/******************************************************************************
-
- macros
-
-******************************************************************************/
-
-#define HEADER "TEST RESULT \n"
-#define DASH "-------------------------------------------------------\n"
-
-#define NW_TEST_SUFFIX ".nw-test"
-#define NW_RESULT_SUFFIX ".nw-result"
-#define TEST_SUFFIX ".test"
-#define RESULT_SUFFIX ".result"
-#define REJECT_SUFFIX ".reject"
-#define OUT_SUFFIX ".out"
-#define ERR_SUFFIX ".err"
-
-const char *TEST_PASS = "[ pass ]";
-const char *TEST_SKIP = "[ skip ]";
-const char *TEST_FAIL = "[ fail ]";
-const char *TEST_BAD = "[ bad ]";
-const char *TEST_IGNORE = "[ignore]";
-
-/******************************************************************************
-
- global variables
-
-******************************************************************************/
-#ifdef __NETWARE__
-static char base_dir[PATH_MAX] = "sys:/mysql";
-#else
-static char base_dir[PATH_MAX] = "..";
-#endif
-static char db[PATH_MAX] = "test";
-static char user[PATH_MAX] = "root";
-static char password[PATH_MAX] = "";
-
-int master_port = 9306;
-int slave_port = 9307;
-
-#if !defined(__NETWARE__) && !defined(__WIN__)
-static char master_socket[PATH_MAX] = "./var/tmp/master.sock";
-static char slave_socket[PATH_MAX] = "./var/tmp/slave.sock";
-#endif
-
-// comma delimited list of tests to skip or empty string
-#ifndef __WIN__
-static char skip_test[PATH_MAX] = " lowercase_table3 , system_mysql_db_fix ";
-#else
-/*
- The most ignore testes contain the calls of system command
-*/
-#define MAX_COUNT_TESTES 1024
-/*
- lowercase_table3 is disabled by Gerg
- system_mysql_db_fix is disabled by Gerg
- sp contains a command system
- rpl_EE_error contains a command system
- rpl_loaddatalocal contains a command system
- ndb_autodiscover contains a command system
- rpl_rotate_logs contains a command system
- repair contains a command system
- rpl_trunc_binlog contains a command system
- mysqldump contains a command system
- rpl000001 makes non-exit loop...temporary skiped
-*/
-static char skip_test[PATH_MAX] = " lowercase_table3 , system_mysql_db_fix , sp , rpl_EE_error , rpl_loaddatalocal , ndb_autodiscover , rpl_rotate_logs , repair , rpl_trunc_binlog , mysqldump , rpl000001 ";
-#endif
-static char ignore_test[PATH_MAX] = "";
-
-static char bin_dir[PATH_MAX];
-static char mysql_test_dir[PATH_MAX];
-static char test_dir[PATH_MAX];
-static char mysql_tmp_dir[PATH_MAX];
-static char result_dir[PATH_MAX];
-static char master_dir[PATH_MAX];
-static char slave_dir[PATH_MAX];
-static char lang_dir[PATH_MAX];
-static char char_dir[PATH_MAX];
-
-static char mysqladmin_file[PATH_MAX];
-static char mysqld_file[PATH_MAX];
-static char mysqltest_file[PATH_MAX];
-#ifndef __WIN__
-static char master_pid[PATH_MAX];
-static char slave_pid[PATH_MAX];
-static char sh_file[PATH_MAX] = "/bin/sh";
-#else
-static HANDLE master_pid;
-static HANDLE slave_pid;
-#endif
-
-static char master_opt[PATH_MAX] = "";
-static char slave_opt[PATH_MAX] = "";
-
-static char slave_master_info[PATH_MAX] = "";
-
-static char master_init_script[PATH_MAX] = "";
-static char slave_init_script[PATH_MAX] = "";
-
-// OpenSSL
-static char ca_cert[PATH_MAX];
-static char server_cert[PATH_MAX];
-static char server_key[PATH_MAX];
-static char client_cert[PATH_MAX];
-static char client_key[PATH_MAX];
-
-int total_skip = 0;
-int total_pass = 0;
-int total_fail = 0;
-int total_test = 0;
-
-int total_ignore = 0;
-
-int use_openssl = FALSE;
-int master_running = FALSE;
-int slave_running = FALSE;
-int skip_slave = TRUE;
-int single_test = TRUE;
-
-int restarts = 0;
-
-FILE *log_fd = NULL;
-
-/******************************************************************************
-
- functions
-
-******************************************************************************/
-
-/******************************************************************************
-
- prototypes
-
-******************************************************************************/
-
-void report_stats();
-void install_db(char *);
-void mysql_install_db();
-void start_master();
-void start_slave();
-void mysql_start();
-void stop_slave();
-void stop_master();
-void mysql_stop();
-void mysql_restart();
-int read_option(char *, char *);
-void run_test(char *);
-void setup(char *);
-void vlog(const char *, va_list);
-void mlog(const char *, ...);
-void log_info(const char *, ...);
-void log_error(const char *, ...);
-void log_errno(const char *, ...);
-void die(const char *);
-char *str_tok(char *string, const char *delim);
-#ifndef __WIN__
-void run_init_script(const char *script_name);
-#endif
-/******************************************************************************
-
- report_stats()
-
- Report the gathered statistics.
-
-******************************************************************************/
-void report_stats()
-{
- if (total_fail == 0)
- {
- mlog("\nAll %d test(s) were successful.\n", total_test);
- }
- else
- {
- double percent = ((double)total_pass / total_test) * 100;
-
- mlog("\nFailed %u/%u test(s), %.02f%% successful.\n",
- total_fail, total_test, percent);
- mlog("\nThe .out and .err files in %s may give you some\n", result_dir);
- mlog("hint of what when wrong.\n");
- mlog("\nIf you want to report this error, please first read the documentation\n");
- mlog("at: http://www.mysql.com/doc/M/y/MySQL_test_suite.html\n");
- }
-}
-
-/******************************************************************************
-
- install_db()
-
- Install the a database.
-
-******************************************************************************/
-void install_db(char *datadir)
-{
- arg_list_t al;
- int err;
- char input[PATH_MAX];
- char output[PATH_MAX];
- char error[PATH_MAX];
-
- // input file
-#ifdef __NETWARE__
- snprintf(input, PATH_MAX, "%s/bin/init_db.sql", base_dir);
-#else
- snprintf(input, PATH_MAX, "%s/mysql-test/init_db.sql", base_dir);
-#endif
- snprintf(output, PATH_MAX, "%s/install.out", datadir);
- snprintf(error, PATH_MAX, "%s/install.err", datadir);
-
- // args
- init_args(&al);
- add_arg(&al, mysqld_file);
- add_arg(&al, "--no-defaults");
- add_arg(&al, "--bootstrap");
- add_arg(&al, "--skip-grant-tables");
- add_arg(&al, "--basedir=%s", base_dir);
- add_arg(&al, "--datadir=%s", datadir);
- add_arg(&al, "--skip-innodb");
- add_arg(&al, "--skip-bdb");
-#ifndef __NETWARE__
- add_arg(&al, "--character-sets-dir=%s", char_dir);
- add_arg(&al, "--language=%s", lang_dir);
-#endif
-
- // spawn
- if ((err = spawn(mysqld_file, &al, TRUE, input, output, error, NULL)) != 0)
- {
- die("Unable to create database.");
- }
-
- // free args
- free_args(&al);
-}
-
-/******************************************************************************
-
- mysql_install_db()
-
- Install the test databases.
-
-******************************************************************************/
-void mysql_install_db()
-{
- char temp[PATH_MAX];
-
- // var directory
- snprintf(temp, PATH_MAX, "%s/var", mysql_test_dir);
-
- // clean up old direcotry
- del_tree(temp);
-
- // create var directory
-#ifndef __WIN__
- mkdir(temp, S_IRWXU);
- // create subdirectories
- mlog("Creating test-suite folders...\n");
- snprintf(temp, PATH_MAX, "%s/var/run", mysql_test_dir);
- mkdir(temp, S_IRWXU);
- snprintf(temp, PATH_MAX, "%s/var/tmp", mysql_test_dir);
- mkdir(temp, S_IRWXU);
- snprintf(temp, PATH_MAX, "%s/var/master-data", mysql_test_dir);
- mkdir(temp, S_IRWXU);
- snprintf(temp, PATH_MAX, "%s/var/master-data/mysql", mysql_test_dir);
- mkdir(temp, S_IRWXU);
- snprintf(temp, PATH_MAX, "%s/var/master-data/test", mysql_test_dir);
- mkdir(temp, S_IRWXU);
- snprintf(temp, PATH_MAX, "%s/var/slave-data", mysql_test_dir);
- mkdir(temp, S_IRWXU);
- snprintf(temp, PATH_MAX, "%s/var/slave-data/mysql", mysql_test_dir);
- mkdir(temp, S_IRWXU);
- snprintf(temp, PATH_MAX, "%s/var/slave-data/test", mysql_test_dir);
- mkdir(temp, S_IRWXU);
-#else
- mkdir(temp);
- // create subdirectories
- mlog("Creating test-suite folders...\n");
- snprintf(temp, PATH_MAX, "%s/var/run", mysql_test_dir);
- mkdir(temp);
- snprintf(temp, PATH_MAX, "%s/var/tmp", mysql_test_dir);
- mkdir(temp);
- snprintf(temp, PATH_MAX, "%s/var/master-data", mysql_test_dir);
- mkdir(temp);
- snprintf(temp, PATH_MAX, "%s/var/master-data/mysql", mysql_test_dir);
- mkdir(temp);
- snprintf(temp, PATH_MAX, "%s/var/master-data/test", mysql_test_dir);
- mkdir(temp);
- snprintf(temp, PATH_MAX, "%s/var/slave-data", mysql_test_dir);
- mkdir(temp);
- snprintf(temp, PATH_MAX, "%s/var/slave-data/mysql", mysql_test_dir);
- mkdir(temp);
- snprintf(temp, PATH_MAX, "%s/var/slave-data/test", mysql_test_dir);
- mkdir(temp);
-#endif
-
- // install databases
- mlog("Creating test databases for master... \n");
- install_db(master_dir);
- mlog("Creating test databases for slave... \n");
- install_db(slave_dir);
-}
-
-/******************************************************************************
-
- start_master()
-
- Start the master server.
-
-******************************************************************************/
-void start_master()
-{
- arg_list_t al;
- int err;
- char master_out[PATH_MAX];
- char master_err[PATH_MAX];
-// char temp[PATH_MAX];
- char temp2[PATH_MAX];
-
- // remove old berkeley db log files that can confuse the server
- removef("%s/log.*", master_dir);
-
- // remove stale binary logs
- removef("%s/var/log/*-bin.*", mysql_test_dir);
-
- // remove stale binary logs
- removef("%s/var/log/*.index", mysql_test_dir);
-
- // remove master.info file
- removef("%s/master.info", master_dir);
-
- // remove relay files
- removef("%s/var/log/*relay*", mysql_test_dir);
-
- // remove relay-log.info file
- removef("%s/relay-log.info", master_dir);
-
- // init script
- if (master_init_script[0] != 0)
- {
-#ifdef __NETWARE__
- // TODO: use the scripts
- if (strinstr(master_init_script, "repair_part2-master.sh") != 0)
- {
- FILE *fp;
-
- // create an empty index file
- snprintf(temp, PATH_MAX, "%s/test/t1.MYI", master_dir);
- fp = fopen(temp, "wb+");
-
- fputs("1", fp);
-
- fclose(fp);
- }
-#elif !defined(__WIN__)
- run_init_script(master_init_script);
-#endif
- }
-
- // redirection files
- snprintf(master_out, PATH_MAX, "%s/var/run/master%u.out",
- mysql_test_dir, restarts);
- snprintf(master_err, PATH_MAX, "%s/var/run/master%u.err",
- mysql_test_dir, restarts);
-#ifndef __WIN__
- snprintf(temp2,PATH_MAX,"%s/var",mysql_test_dir);
- mkdir(temp2,S_IRWXU);
- snprintf(temp2,PATH_MAX,"%s/var/log",mysql_test_dir);
- mkdir(temp2,S_IRWXU);
-#else
- snprintf(temp2,PATH_MAX,"%s/var",mysql_test_dir);
- mkdir(temp2);
- snprintf(temp2,PATH_MAX,"%s/var/log",mysql_test_dir);
- mkdir(temp2);
-#endif
- // args
- init_args(&al);
- add_arg(&al, "%s", mysqld_file);
- add_arg(&al, "--no-defaults");
- add_arg(&al, "--log-bin=%s/var/log/master-bin",mysql_test_dir);
- add_arg(&al, "--server-id=1");
- add_arg(&al, "--basedir=%s", base_dir);
- add_arg(&al, "--port=%u", master_port);
-#if !defined(__NETWARE__) && !defined(__WIN__)
- add_arg(&al, "--socket=%s",master_socket);
-#endif
- add_arg(&al, "--local-infile");
- add_arg(&al, "--core");
- add_arg(&al, "--datadir=%s", master_dir);
-#ifndef __WIN__
- add_arg(&al, "--pid-file=%s", master_pid);
-#endif
- add_arg(&al, "--character-sets-dir=%s", char_dir);
- add_arg(&al, "--tmpdir=%s", mysql_tmp_dir);
- add_arg(&al, "--language=%s", lang_dir);
-#ifdef DEBUG //only for debug builds
- add_arg(&al, "--debug");
-#endif
-
- if (use_openssl)
- {
- add_arg(&al, "--ssl-ca=%s", ca_cert);
- add_arg(&al, "--ssl-cert=%s", server_cert);
- add_arg(&al, "--ssl-key=%s", server_key);
- }
-
- // $MASTER_40_ARGS
- add_arg(&al, "--rpl-recovery-rank=1");
- add_arg(&al, "--init-rpl-role=master");
-
- // $SMALL_SERVER
- add_arg(&al, "-O");
- add_arg(&al, "key_buffer_size=1M");
- add_arg(&al, "-O");
- add_arg(&al, "sort_buffer=256K");
- add_arg(&al, "-O");
- add_arg(&al, "max_heap_table_size=1M");
-
- // $EXTRA_MASTER_OPT
- if (master_opt[0] != 0)
- {
- char *p;
-
- p = (char *)str_tok(master_opt, " \t");
- if (!strstr(master_opt, "timezone"))
- {
- while (p)
- {
- add_arg(&al, "%s", p);
- p = (char *)str_tok(NULL, " \t");
- }
- }
- }
-
- // remove the pid file if it exists
-#ifndef __WIN__
- remove(master_pid);
-#endif
-
- // spawn
-#ifdef __WIN__
- if ((err= spawn(mysqld_file, &al, FALSE, NULL, master_out, master_err, &master_pid)) == 0)
-#else
- if ((err= spawn(mysqld_file, &al, FALSE, NULL, master_out, master_err, master_pid)) == 0)
-#endif
- {
- sleep_until_file_exists(master_pid);
-
- if ((err = wait_for_server_start(bin_dir, mysqladmin_file, user, password, master_port,
- mysql_tmp_dir)) == 0)
- {
- master_running = TRUE;
- }
- else
- {
- log_error("The master server went down early.");
- }
- }
- else
- {
- log_error("Unable to start master server.");
- }
-
- // free_args
- free_args(&al);
-}
-
-/******************************************************************************
-
- start_slave()
-
- Start the slave server.
-
-******************************************************************************/
-void start_slave()
-{
- arg_list_t al;
- int err;
- char slave_out[PATH_MAX];
- char slave_err[PATH_MAX];
-
- // skip?
- if (skip_slave) return;
-
- // remove stale binary logs
- removef("%s/*-bin.*", slave_dir);
-
- // remove stale binary logs
- removef("%s/*.index", slave_dir);
-
- // remove master.info file
- removef("%s/master.info", slave_dir);
-
- // remove relay files
- removef("%s/var/log/*relay*", mysql_test_dir);
-
- // remove relay-log.info file
- removef("%s/relay-log.info", slave_dir);
-
- // init script
- if (slave_init_script[0] != 0)
- {
-#ifdef __NETWARE__
- // TODO: use the scripts
- if (strinstr(slave_init_script, "rpl000016-slave.sh") != 0)
- {
- // create empty master.info file
- snprintf(temp, PATH_MAX, "%s/master.info", slave_dir);
- close(open(temp, O_WRONLY | O_CREAT,S_IRWXU|S_IRWXG|S_IRWXO));
- }
- else if (strinstr(slave_init_script, "rpl000017-slave.sh") != 0)
- {
- FILE *fp;
-
- // create a master.info file
- snprintf(temp, PATH_MAX, "%s/master.info", slave_dir);
- fp = fopen(temp, "wb+");
-
- fputs("master-bin.000001\n", fp);
- fputs("4\n", fp);
- fputs("127.0.0.1\n", fp);
- fputs("replicate\n", fp);
- fputs("aaaaaaaaaaaaaaab\n", fp);
- fputs("9306\n", fp);
- fputs("1\n", fp);
- fputs("0\n", fp);
-
- fclose(fp);
- }
- else if (strinstr(slave_init_script, "rpl_rotate_logs-slave.sh") != 0)
- {
- // create empty master.info file
- snprintf(temp, PATH_MAX, "%s/master.info", slave_dir);
- close(open(temp, O_WRONLY | O_CREAT,S_IRWXU|S_IRWXG|S_IRWXO));
- }
-#elif !defined(__WIN__)
- run_init_script(slave_init_script);
-#endif
- }
-
- // redirection files
- snprintf(slave_out, PATH_MAX, "%s/var/run/slave%u.out",
- mysql_test_dir, restarts);
- snprintf(slave_err, PATH_MAX, "%s/var/run/slave%u.err",
- mysql_test_dir, restarts);
-
- // args
- init_args(&al);
- add_arg(&al, "%s", mysqld_file);
- add_arg(&al, "--no-defaults");
- add_arg(&al, "--log-bin=slave-bin");
- add_arg(&al, "--relay_log=slave-relay-bin");
- add_arg(&al, "--basedir=%s", base_dir);
- add_arg(&al, "--port=%u", slave_port);
-#if !defined(__NETWARE__) && !defined(__WIN__)
- add_arg(&al, "--socket=%s",slave_socket);
-#endif
- add_arg(&al, "--datadir=%s", slave_dir);
-#ifndef __WIN__
- add_arg(&al, "--pid-file=%s", slave_pid);
-#endif
- add_arg(&al, "--character-sets-dir=%s", char_dir);
- add_arg(&al, "--core");
- add_arg(&al, "--tmpdir=%s", mysql_tmp_dir);
- add_arg(&al, "--language=%s", lang_dir);
-
- add_arg(&al, "--exit-info=256");
- add_arg(&al, "--log-slave-updates");
- add_arg(&al, "--init-rpl-role=slave");
- add_arg(&al, "--skip-innodb");
- add_arg(&al, "--skip-slave-start");
- add_arg(&al, "--slave-load-tmpdir=../../var/tmp");
-
- add_arg(&al, "--report-user=%s", user);
- add_arg(&al, "--report-host=127.0.0.1");
- add_arg(&al, "--report-port=%u", slave_port);
-
- add_arg(&al, "--master-retry-count=10");
- add_arg(&al, "-O");
- add_arg(&al, "slave_net_timeout=10");
-#ifdef DEBUG //only for debug builds
- add_arg(&al, "--debug");
-#endif
-
- if (use_openssl)
- {
- add_arg(&al, "--ssl-ca=%s", ca_cert);
- add_arg(&al, "--ssl-cert=%s", server_cert);
- add_arg(&al, "--ssl-key=%s", server_key);
- }
-
- // slave master info
- if (slave_master_info[0] != 0)
- {
- char *p;
-
- p = (char *)str_tok(slave_master_info, " \t");
-
- while(p)
- {
- add_arg(&al, "%s", p);
-
- p = (char *)str_tok(NULL, " \t");
- }
- }
- else
- {
- add_arg(&al, "--master-user=%s", user);
- add_arg(&al, "--master-password=%s", password);
- add_arg(&al, "--master-host=127.0.0.1");
- add_arg(&al, "--master-port=%u", master_port);
- add_arg(&al, "--master-connect-retry=1");
- add_arg(&al, "--server-id=2");
- add_arg(&al, "--rpl-recovery-rank=2");
- }
-
- // small server
- add_arg(&al, "-O");
- add_arg(&al, "key_buffer_size=1M");
- add_arg(&al, "-O");
- add_arg(&al, "sort_buffer=256K");
- add_arg(&al, "-O");
- add_arg(&al, "max_heap_table_size=1M");
-
-
- // opt args
- if (slave_opt[0] != 0)
- {
- char *p;
-
- p = (char *)str_tok(slave_opt, " \t");
-
- while(p)
- {
- add_arg(&al, "%s", p);
-
- p = (char *)str_tok(NULL, " \t");
- }
- }
-
- // remove the pid file if it exists
-#ifndef __WIN__
- remove(slave_pid);
-#endif
- // spawn
-#ifdef __WIN__
- if ((err = spawn(mysqld_file, &al, FALSE, NULL, slave_out, slave_err, &slave_pid)) == 0)
-#else
- if ((err = spawn(mysqld_file, &al, FALSE, NULL, slave_out, slave_err, slave_pid)) == 0)
-#endif
- {
- sleep_until_file_exists(slave_pid);
-
- if ((err = wait_for_server_start(bin_dir, mysqladmin_file, user, password, slave_port,
- mysql_tmp_dir)) == 0)
- {
- slave_running = TRUE;
- }
- else
- {
- log_error("The slave server went down early.");
- }
- }
- else
- {
- log_error("Unable to start slave server.");
- }
-
- // free args
- free_args(&al);
-}
-
-/******************************************************************************
-
- mysql_start()
-
- Start the mysql servers.
-
-******************************************************************************/
-void mysql_start()
-{
-// log_info("Starting the MySQL server(s): %u", ++restarts);
- start_master();
-
- start_slave();
-
- // activate the test screen
-#ifdef __NETWARE__
- ActivateScreen(getscreenhandle());
-#endif
-}
-
-/******************************************************************************
-
- stop_slave()
-
- Stop the slave server.
-
-******************************************************************************/
-void stop_slave()
-{
- int err;
-
- // running?
- if (!slave_running) return;
-
- // stop
- if ((err = stop_server(bin_dir, mysqladmin_file, user, password, slave_port, slave_pid,
- mysql_tmp_dir)) == 0)
- {
- slave_running = FALSE;
- }
- else
- {
- log_error("Unable to stop slave server.");
- }
-}
-
-/******************************************************************************
-
- stop_master()
-
- Stop the master server.
-
-******************************************************************************/
-void stop_master()
-{
- int err;
-
- // running?
- if (!master_running) return;
-
- if ((err = stop_server(bin_dir, mysqladmin_file, user, password, master_port, master_pid,
- mysql_tmp_dir)) == 0)
- {
- master_running = FALSE;
- }
- else
- {
- log_error("Unable to stop master server.");
- }
-}
-
-/******************************************************************************
-
- mysql_stop()
-
- Stop the mysql servers.
-
-******************************************************************************/
-void mysql_stop()
-{
-
- stop_master();
-
- stop_slave();
-
- // activate the test screen
-#ifdef __NETWARE__
- ActivateScreen(getscreenhandle());
-#endif
-}
-
-/******************************************************************************
-
- mysql_restart()
-
- Restart the mysql servers.
-
-******************************************************************************/
-void mysql_restart()
-{
-// log_info("Restarting the MySQL server(s): %u", ++restarts);
-
- mysql_stop();
-
- mlog(DASH);
-
- mysql_start();
-}
-
-/******************************************************************************
-
- read_option()
-
- Read the option file.
-
-******************************************************************************/
-int read_option(char *opt_file, char *opt)
-{
- int fd, err;
- char *p;
- char buf[PATH_MAX];
-
- // copy current option
- strncpy(buf, opt, PATH_MAX);
-
- // open options file
- fd = open(opt_file, O_RDONLY);
-
- err = read(fd, opt, PATH_MAX);
-
- close(fd);
-
- if (err > 0)
- {
- // terminate string
- if ((p = strchr(opt, '\n')) != NULL)
- {
- *p = 0;
-
- // check for a '\r'
- if ((p = strchr(opt, '\r')) != NULL)
- {
- *p = 0;
- }
- }
- else
- {
- opt[err] = 0;
- }
-
- // check for $MYSQL_TEST_DIR
- if ((p = strstr(opt, "$MYSQL_TEST_DIR")) != NULL)
- {
- char temp[PATH_MAX];
-
- *p = 0;
-
- strcpy(temp, p + strlen("$MYSQL_TEST_DIR"));
-
- strcat(opt, mysql_test_dir);
-
- strcat(opt, temp);
- }
- // Check for double backslash and replace it with single bakslash
- if ((p = strstr(opt, "\\\\")) != NULL)
- {
- /* bmove is guranteed to work byte by byte */
- bmove(p, p+1, strlen(p+1));
- }
- }
- else
- {
- // clear option
- *opt = 0;
- }
-
- // compare current option with previous
- return strcmp(opt, buf);
-}
-
-/******************************************************************************
-
- run_test()
-
- Run the given test case.
-
-******************************************************************************/
-void run_test(char *test)
-{
- char temp[PATH_MAX];
- const char *rstr;
- int skip = FALSE, ignore=FALSE;
- int restart = FALSE;
- int flag = FALSE;
- struct stat info;
-
- // skip tests in the skip list
- snprintf(temp, PATH_MAX, " %s ", test);
- skip = (strinstr(skip_test, temp) != 0);
- if (skip == FALSE)
- ignore = (strinstr(ignore_test, temp) != 0);
-
- snprintf(master_init_script, PATH_MAX, "%s/%s-master.sh", test_dir, test);
- snprintf(slave_init_script, PATH_MAX, "%s/%s-slave.sh", test_dir, test);
-#ifdef __WIN__
- if (! stat(master_init_script, &info))
- skip = TRUE;
- if (!stat(slave_init_script, &info))
- skip = TRUE;
-#endif
- if (ignore)
- {
- // show test
- mlog("%-46s ", test);
-
- // ignore
- rstr = TEST_IGNORE;
- ++total_ignore;
- }
- else if (!skip) // skip test?
- {
- char test_file[PATH_MAX];
- char master_opt_file[PATH_MAX];
- char slave_opt_file[PATH_MAX];
- char slave_master_info_file[PATH_MAX];
- char result_file[PATH_MAX];
- char reject_file[PATH_MAX];
- char out_file[PATH_MAX];
- char err_file[PATH_MAX];
- int err;
- arg_list_t al;
-#ifdef __WIN__
- /*
- Clean test database
- */
- removef("%s/test/*.*", master_dir);
- removef("%s/test/*.*", slave_dir);
- removef("%s/mysqltest/*.*", master_dir);
- removef("%s/mysqltest/*.*", slave_dir);
-
-#endif
- // skip slave?
- flag = skip_slave;
- skip_slave = (strncmp(test, "rpl", 3) != 0);
- if (flag != skip_slave) restart = TRUE;
-
- // create files
- snprintf(master_opt_file, PATH_MAX, "%s/%s-master.opt", test_dir, test);
- snprintf(slave_opt_file, PATH_MAX, "%s/%s-slave.opt", test_dir, test);
- snprintf(slave_master_info_file, PATH_MAX, "%s/%s.slave-mi", test_dir, test);
- snprintf(reject_file, PATH_MAX, "%s/%s%s", result_dir, test, REJECT_SUFFIX);
- snprintf(out_file, PATH_MAX, "%s/%s%s", result_dir, test, OUT_SUFFIX);
- snprintf(err_file, PATH_MAX, "%s/%s%s", result_dir, test, ERR_SUFFIX);
-
- // netware specific files
- snprintf(test_file, PATH_MAX, "%s/%s%s", test_dir, test, NW_TEST_SUFFIX);
- if (stat(test_file, &info))
- {
- snprintf(test_file, PATH_MAX, "%s/%s%s", test_dir, test, TEST_SUFFIX);
- if (access(test_file,0))
- {
- printf("Invalid test name %s, %s file not found\n",test,test_file);
- return;
- }
- }
-
- snprintf(result_file, PATH_MAX, "%s/%s%s", result_dir, test, NW_RESULT_SUFFIX);
- if (stat(result_file, &info))
- {
- snprintf(result_file, PATH_MAX, "%s/%s%s", result_dir, test, RESULT_SUFFIX);
- }
-
- // init scripts
- if (stat(master_init_script, &info))
- master_init_script[0] = 0;
- else
- restart = TRUE;
-
- if (stat(slave_init_script, &info))
- slave_init_script[0] = 0;
- else
- restart = TRUE;
-
- // read options
- if (read_option(master_opt_file, master_opt)) restart = TRUE;
- if (read_option(slave_opt_file, slave_opt)) restart = TRUE;
- if (read_option(slave_master_info_file, slave_master_info)) restart = TRUE;
-
- // cleanup previous run
- remove(reject_file);
- remove(out_file);
- remove(err_file);
-
- // start or restart?
- if (!master_running) mysql_start();
- else if (restart) mysql_restart();
-
- // let the system stabalize
- sleep(1);
-
- // show test
- mlog("%-46s ", test);
-
-
- // args
- init_args(&al);
- add_arg(&al, "%s", mysqltest_file);
- add_arg(&al, "--no-defaults");
- add_arg(&al, "--port=%u", master_port);
-#if !defined(__NETWARE__) && !defined(__WIN__)
- add_arg(&al, "--socket=%s", master_socket);
- add_arg(&al, "--tmpdir=%s", mysql_tmp_dir);
-#endif
- add_arg(&al, "--database=%s", db);
- add_arg(&al, "--user=%s", user);
- add_arg(&al, "--password=%s", password);
- add_arg(&al, "--silent");
- add_arg(&al, "--basedir=%s/", mysql_test_dir);
- add_arg(&al, "--host=127.0.0.1");
- add_arg(&al, "-v");
- add_arg(&al, "-R");
- add_arg(&al, "%s", result_file);
-
- if (use_openssl)
- {
- add_arg(&al, "--ssl-ca=%s", ca_cert);
- add_arg(&al, "--ssl-cert=%s", client_cert);
- add_arg(&al, "--ssl-key=%s", client_key);
- }
-
- // spawn
- err = spawn(mysqltest_file, &al, TRUE, test_file, out_file, err_file, NULL);
-
- // free args
- free_args(&al);
-
- remove_empty_file(out_file);
- remove_empty_file(err_file);
-
- if (err == 0)
- {
- // pass
- rstr = TEST_PASS;
- ++total_pass;
-
- // increment total
- ++total_test;
- }
- else if (err == 2)
- {
- // skip
- rstr = TEST_SKIP;
- ++total_skip;
- }
- else if (err == 1)
- {
- // fail
- rstr = TEST_FAIL;
- ++total_fail;
-
- // increment total
- ++total_test;
- }
- else
- {
- rstr = TEST_BAD;
- }
- }
- else // early skips
- {
- // show test
- mlog("%-46s ", test);
-
- // skip
- rstr = TEST_SKIP;
- ++total_skip;
- }
-
- // result
- mlog("%-14s\n", rstr);
-}
-
-/******************************************************************************
-
- vlog()
-
- Log the message.
-
-******************************************************************************/
-void vlog(const char *format, va_list ap)
-{
- vfprintf(stdout, format, ap);
- fflush(stdout);
-
- if (log_fd)
- {
- vfprintf(log_fd, format, ap);
- fflush(log_fd);
- }
-}
-
-/******************************************************************************
-
- log()
-
- Log the message.
-
-******************************************************************************/
-void mlog(const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
-
- vlog(format, ap);
-
- va_end(ap);
-}
-
-/******************************************************************************
-
- log_info()
-
- Log the given information.
-
-******************************************************************************/
-void log_info(const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
-
- mlog("-- INFO : ");
- vlog(format, ap);
- mlog("\n");
-
- va_end(ap);
-}
-
-/******************************************************************************
-
- log_error()
-
- Log the given error.
-
-******************************************************************************/
-void log_error(const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
-
- mlog("-- ERROR: ");
- vlog(format, ap);
- mlog("\n");
-
- va_end(ap);
-}
-
-/******************************************************************************
-
- log_errno()
-
- Log the given error and errno.
-
-******************************************************************************/
-void log_errno(const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
-
- mlog("-- ERROR: (%003u) ", errno);
- vlog(format, ap);
- mlog("\n");
-
- va_end(ap);
-}
-
-/******************************************************************************
-
- die()
-
- Exit the application.
-
-******************************************************************************/
-void die(const char *msg)
-{
- log_error(msg);
-#ifdef __NETWARE__
- pressanykey();
-#endif
- exit(-1);
-}
-
-/******************************************************************************
-
- setup()
-
- Setup the mysql test enviornment.
-
-******************************************************************************/
-void setup(char *file)
-{
- char temp[PATH_MAX];
- char file_path[PATH_MAX*2];
- char *p;
- int position;
-
- // set the timezone for the timestamp test
-#ifdef __WIN__
- _putenv( "TZ=GMT-3" );
-#else
- setenv("TZ", "GMT-3", TRUE);
-#endif
- // find base dir
-#ifdef __NETWARE__
- strcpy(temp, strlwr(file));
- while((p = strchr(temp, '\\')) != NULL) *p = '/';
-#else
- getcwd(temp, PATH_MAX);
- position = strlen(temp);
- temp[position] = '/';
- temp[position+1] = 0;
-#ifdef __WIN__
- while((p = strchr(temp, '\\')) != NULL) *p = '/';
-#endif
-#endif
-
- if ((position = strinstr(temp, "/mysql-test/")) != 0)
- {
- p = temp + position - 1;
- *p = 0;
- strcpy(base_dir, temp);
- }
-
- log_info("Currect directory: %s",base_dir);
-
-#ifdef __NETWARE__
- // setup paths
- snprintf(bin_dir, PATH_MAX, "%s/bin", base_dir);
- snprintf(mysql_test_dir, PATH_MAX, "%s/mysql-test", base_dir);
- snprintf(test_dir, PATH_MAX, "%s/t", mysql_test_dir);
- snprintf(mysql_tmp_dir, PATH_MAX, "%s/var/tmp", mysql_test_dir);
- snprintf(result_dir, PATH_MAX, "%s/r", mysql_test_dir);
- snprintf(master_dir, PATH_MAX, "%s/var/master-data", mysql_test_dir);
- snprintf(slave_dir, PATH_MAX, "%s/var/slave-data", mysql_test_dir);
- snprintf(lang_dir, PATH_MAX, "%s/share/english", base_dir);
- snprintf(char_dir, PATH_MAX, "%s/share/charsets", base_dir);
-
-#ifdef HAVE_OPENSSL
- use_openssl = TRUE;
-#endif // HAVE_OPENSSL
-
- // OpenSSL paths
- snprintf(ca_cert, PATH_MAX, "%s/SSL/cacert.pem", base_dir);
- snprintf(server_cert, PATH_MAX, "%s/SSL/server-cert.pem", base_dir);
- snprintf(server_key, PATH_MAX, "%s/SSL/server-key.pem", base_dir);
- snprintf(client_cert, PATH_MAX, "%s/SSL/client-cert.pem", base_dir);
- snprintf(client_key, PATH_MAX, "%s/SSL/client-key.pem", base_dir);
-
- // setup files
- snprintf(mysqld_file, PATH_MAX, "%s/mysqld", bin_dir);
- snprintf(mysqltest_file, PATH_MAX, "%s/mysqltest", bin_dir);
- snprintf(mysqladmin_file, PATH_MAX, "%s/mysqladmin", bin_dir);
- snprintf(master_pid, PATH_MAX, "%s/var/run/master.pid", mysql_test_dir);
- snprintf(slave_pid, PATH_MAX, "%s/var/run/slave.pid", mysql_test_dir);
-#elif __WIN__
- // setup paths
-#ifdef _DEBUG
- snprintf(bin_dir, PATH_MAX, "%s/client_debug", base_dir);
-#else
- snprintf(bin_dir, PATH_MAX, "%s/client_release", base_dir);
-#endif
- snprintf(mysql_test_dir, PATH_MAX, "%s/mysql-test", base_dir);
- snprintf(test_dir, PATH_MAX, "%s/t", mysql_test_dir);
- snprintf(mysql_tmp_dir, PATH_MAX, "%s/var/tmp", mysql_test_dir);
- snprintf(result_dir, PATH_MAX, "%s/r", mysql_test_dir);
- snprintf(master_dir, PATH_MAX, "%s/var/master-data", mysql_test_dir);
- snprintf(slave_dir, PATH_MAX, "%s/var/slave-data", mysql_test_dir);
- snprintf(lang_dir, PATH_MAX, "%s/share/english", base_dir);
- snprintf(char_dir, PATH_MAX, "%s/share/charsets", base_dir);
-
-#ifdef HAVE_OPENSSL
- use_openssl = TRUE;
-#endif // HAVE_OPENSSL
-
- // OpenSSL paths
- snprintf(ca_cert, PATH_MAX, "%s/SSL/cacert.pem", base_dir);
- snprintf(server_cert, PATH_MAX, "%s/SSL/server-cert.pem", base_dir);
- snprintf(server_key, PATH_MAX, "%s/SSL/server-key.pem", base_dir);
- snprintf(client_cert, PATH_MAX, "%s/SSL/client-cert.pem", base_dir);
- snprintf(client_key, PATH_MAX, "%s/SSL/client-key.pem", base_dir);
-
- // setup files
- snprintf(mysqld_file, PATH_MAX, "%s/mysqld.exe", bin_dir);
- snprintf(mysqltest_file, PATH_MAX, "%s/mysqltest.exe", bin_dir);
- snprintf(mysqladmin_file, PATH_MAX, "%s/mysqladmin.exe", bin_dir);
-#else
- // setup paths
- snprintf(bin_dir, PATH_MAX, "%s/client", base_dir);
- snprintf(mysql_test_dir, PATH_MAX, "%s/mysql-test", base_dir);
- snprintf(test_dir, PATH_MAX, "%s/t", mysql_test_dir);
- snprintf(mysql_tmp_dir, PATH_MAX, "%s/var/tmp", mysql_test_dir);
- snprintf(result_dir, PATH_MAX, "%s/r", mysql_test_dir);
- snprintf(master_dir, PATH_MAX, "%s/var/master-data", mysql_test_dir);
- snprintf(slave_dir, PATH_MAX, "%s/var/slave-data", mysql_test_dir);
- snprintf(lang_dir, PATH_MAX, "%s/sql/share/english", base_dir);
- snprintf(char_dir, PATH_MAX, "%s/sql/share/charsets", base_dir);
-
-#ifdef HAVE_OPENSSL
- use_openssl = TRUE;
-#endif // HAVE_OPENSSL
-
- // OpenSSL paths
- snprintf(ca_cert, PATH_MAX, "%s/SSL/cacert.pem", base_dir);
- snprintf(server_cert, PATH_MAX, "%s/SSL/server-cert.pem", base_dir);
- snprintf(server_key, PATH_MAX, "%s/SSL/server-key.pem", base_dir);
- snprintf(client_cert, PATH_MAX, "%s/SSL/client-cert.pem", base_dir);
- snprintf(client_key, PATH_MAX, "%s/SSL/client-key.pem", base_dir);
-
- // setup files
- snprintf(mysqld_file, PATH_MAX, "%s/sql/mysqld", base_dir);
- snprintf(mysqltest_file, PATH_MAX, "%s/mysqltest", bin_dir);
- snprintf(mysqladmin_file, PATH_MAX, "%s/mysqladmin", bin_dir);
- snprintf(master_pid, PATH_MAX, "%s/var/run/master.pid", mysql_test_dir);
- snprintf(slave_pid, PATH_MAX, "%s/var/run/slave.pid", mysql_test_dir);
-
- snprintf(master_socket,PATH_MAX, "%s/var/tmp/master.sock", mysql_test_dir);
- snprintf(slave_socket,PATH_MAX, "%s/var/tmp/slave.sock", mysql_test_dir);
-
-#endif
- // create log file
- snprintf(temp, PATH_MAX, "%s/mysql-test-run.log", mysql_test_dir);
- if ((log_fd = fopen(temp, "w+")) == NULL)
- {
- log_errno("Unable to create log file.");
- }
-
- // prepare skip test list
- while((p = strchr(skip_test, ',')) != NULL) *p = ' ';
- strcpy(temp, strlwr(skip_test));
- snprintf(skip_test, PATH_MAX, " %s ", temp);
-
- // environment
-#ifdef __NETWARE__
- setenv("MYSQL_TEST_DIR", mysql_test_dir, 1);
- snprintf(file_path, PATH_MAX*2, "%s/client/mysqldump --no-defaults -u root --port=%u", bin_dir, master_port);
- setenv("MYSQL_DUMP", file_path, 1);
- snprintf(file_path, PATH_MAX*2, "%s/client/mysqlbinlog --no-defaults --local-load=%s", bin_dir, mysql_tmp_dir);
- setenv("MYSQL_BINLOG", file_path, 1);
-#elif __WIN__
- snprintf(file_path,MAX_PATH,"MYSQL_TEST_DIR=%s",mysql_test_dir);
- _putenv(file_path);
- snprintf(file_path, PATH_MAX*2, "MYSQL_DUMP=%s/mysqldump.exe --no-defaults -u root --port=%u", bin_dir, master_port);
- _putenv(file_path);
- snprintf(file_path, PATH_MAX*2, "MYSQL_BINLOG=%s/mysqlbinlog.exe --no-defaults --local-load=%s", bin_dir, mysql_tmp_dir);
- _putenv(file_path);
-#else
- setenv("MYSQL_TEST_DIR", mysql_test_dir, 1);
- snprintf(file_path, PATH_MAX*2, "%s/mysqldump --no-defaults -u root --port=%u --socket=%s", bin_dir, master_port, master_socket);
- setenv("MYSQL_DUMP", file_path, 1);
- snprintf(file_path, PATH_MAX*2, "%s/mysqlbinlog --no-defaults --local-load=%s", bin_dir, mysql_tmp_dir);
- setenv("MYSQL_BINLOG", file_path, 1);
-#endif
-
-#ifndef __WIN__
- setenv("MASTER_MYPORT", "9306", 1);
- setenv("SLAVE_MYPORT", "9307", 1);
- setenv("MYSQL_TCP_PORT", "3306", 1);
-#else
- _putenv("MASTER_MYPORT=9306");
- _putenv("SLAVE_MYPORT=9307");
- _putenv("MYSQL_TCP_PORT=3306");
-#endif
-
-}
-
-/******************************************************************************
-
- main()
-
-******************************************************************************/
-int main(int argc, char **argv)
-{
- int is_ignore_list = 0;
- // setup
- setup(argv[0]);
-
- /* The --ignore option is comma saperated list of test cases to skip and
- should be very first command line option to the test suite.
-
- The usage is now:
- mysql_test_run --ignore=test1,test2 test3 test4
- where test1 and test2 are test cases to ignore
- and test3 and test4 are test cases to run.
- */
- if (argc >= 2 && !strnicmp(argv[1], "--ignore=", sizeof("--ignore=")-1))
- {
- char *temp, *token;
- temp= strdup(strchr(argv[1],'=') + 1);
- for (token=str_tok(temp, ","); token != NULL; token=str_tok(NULL, ","))
- {
- if (strlen(ignore_test) + strlen(token) + 2 <= PATH_MAX-1)
- sprintf(ignore_test+strlen(ignore_test), " %s ", token);
- else
- {
- free(temp);
- die("ignore list too long.");
- }
- }
- free(temp);
- is_ignore_list = 1;
- }
- // header
-#ifndef __WIN__
- mlog("MySQL Server %s, for %s (%s)\n\n", VERSION, SYSTEM_TYPE, MACHINE_TYPE);
-#else
- mlog("MySQL Server ---, for %s (%s)\n\n", SYSTEM_TYPE, MACHINE_TYPE);
-#endif
-
- mlog("Initializing Tests...\n");
-
- // install test databases
- mysql_install_db();
-
- mlog("Starting Tests...\n");
-
- mlog("\n");
- mlog(HEADER);
- mlog(DASH);
-
- if ( argc > 1 + is_ignore_list )
- {
- int i;
-
- // single test
- single_test = TRUE;
-
- for (i = 1 + is_ignore_list; i < argc; i++)
- {
- // run given test
- run_test(argv[i]);
- }
- }
- else
- {
- // run all tests
-#ifndef __WIN__
- struct dirent **namelist;
- int i,n;
- char test[NAME_MAX];
- char *p;
- int position;
-
- n = scandir(test_dir, &namelist, 0, alphasort);
- if (n < 0)
- die("Unable to open tests directory.");
- else
- {
- for (i = 0; i < n; i++)
- {
- strcpy(test, strlwr(namelist[i]->d_name));
- // find the test suffix
- if ((position = strinstr(test, TEST_SUFFIX)) != 0)
- {
- p = test + position - 1;
- // null terminate at the suffix
- *p = 0;
- // run test
- run_test(test);
- }
- free(namelist[n]);
- }
- free(namelist);
- }
-#else
- struct _finddata_t dir;
- intptr_t handle;
- char test[NAME_MAX];
- char mask[PATH_MAX];
- char *p;
- int position;
- char **names = 0;
- char **testes = 0;
- int name_index;
- int index;
-
- // single test
- single_test = FALSE;
-
- snprintf(mask,MAX_PATH,"%s/*.test",test_dir);
-
- if ((handle=_findfirst(mask,&dir)) == -1L)
- {
- die("Unable to open tests directory.");
- }
-
- names = malloc(MAX_COUNT_TESTES*4);
- testes = names;
- name_index = 0;
-
- do
- {
- if (!(dir.attrib & _A_SUBDIR))
- {
- strcpy(test, strlwr(dir.name));
-
- // find the test suffix
- if ((position = strinstr(test, TEST_SUFFIX)) != 0)
- {
- p = test + position - 1;
- // null terminate at the suffix
- *p = 0;
-
- // insert test
- *names = malloc(PATH_MAX);
- strcpy(*names,test);
- names++;
- name_index++;
- }
- }
- }while (_findnext(handle,&dir) == 0);
-
- _findclose(handle);
-
- qsort( (void *)testes, name_index, sizeof( char * ), compare );
-
- for (index = 0; index <= name_index; index++)
- {
- run_test(testes[index]);
- free(testes[index]);
- }
-
- free(testes);
-#endif
- }
-
- // stop server
- mysql_stop();
-
- mlog(DASH);
- mlog("\n");
-
- mlog("Ending Tests...\n");
-
- // report stats
- report_stats();
-
- // close log
- if (log_fd) fclose(log_fd);
-
- // keep results up
-#ifdef __NETWARE__
- pressanykey();
-#endif
- return 0;
-}
-
-
-/*
- Synopsis:
- This function breaks the string into a sequence of tokens. The difference
- between this function and strtok is that it respects the quoted string i.e.
- it skips any delimiter character within the quoted part of the string.
- It return tokens by eliminating quote character. It modifies the input string
- passed. It will work with whitespace delimeter but may not work properly with
- other delimeter. If the delimeter will contain any quote character, then
- function will not tokenize and will return null string.
- e.g. if input string is
- --init-slave="set global max_connections=500" --skip-external-locking
- then the output will two string i.e.
- --init-slave=set global max_connections=500
- --skip-external-locking
-
-Arguments:
- string: input string
- delim: set of delimiter character
-Output:
- return the null terminated token of NULL.
-*/
-
-
-char *str_tok(char *string, const char *delim)
-{
- char *token; /* current token received from strtok */
- char *qt_token; /* token delimeted by the matching pair of quote */
- /*
- if there are any quote chars found in the token then this variable
- will hold the concatenated string to return to the caller
- */
- char *ptr_token=NULL;
- /* pointer to the quote character in the token from strtok */
- char *ptr_quote=NULL;
-
- /* See if the delimeter contains any quote character */
- if (strchr(delim,'\'') || strchr(delim,'\"'))
- return NULL;
-
- /* repeate till we are getting some token from strtok */
- while ((token = (char*)strtok(string, delim) ) != NULL)
- {
- /*
- make the input string NULL so that next time onward strtok can
- be called with NULL input string.
- */
- string = NULL;
- /*
- We don't need to remove any quote character for Windows version
- */
-#ifndef __WIN__
- /* check if the current token contain double quote character*/
- if ((ptr_quote = (char*)strchr(token,'\"')) != NULL)
- {
- /*
- get the matching the matching double quote in the remaining
- input string
- */
- qt_token = (char*)strtok(NULL,"\"");
- }
- /* check if the current token contain single quote character*/
- else if ((ptr_quote = (char*)strchr(token,'\'')) != NULL)
- {
- /*
- get the matching the matching single quote in the remaining
- input string
- */
- qt_token = (char*)strtok(NULL,"\'");
- }
-#endif
- /*
- if the current token does not contains any quote character then
- return to the caller.
- */
- if (ptr_quote == NULL)
- {
- /*
- if there is any earlier token i.e. ptr_token then append the
- current token in it and return it else return the current
- token directly
- */
- return ptr_token ? strcat(ptr_token,token) : token;
- }
-
- /*
- remove the quote character i.e. make NULL so that the token will
- be devided in two part and later both part can be concatenated
- and hence quote will be removed
- */
- *ptr_quote= 0;
-
- /* check if ptr_token has been initialized or not */
- if (ptr_token == NULL)
- {
- /* initialize the ptr_token with current token */
- ptr_token= token;
- /* copy entire string between matching pair of quote*/
- sprintf(ptr_token+strlen(ptr_token),"%s %s", ptr_quote+1, qt_token);
- }
- else
- {
- /*
- copy the current token and entire string between matching pair
- of quote
- */
- if (qt_token == NULL)
- {
- sprintf(ptr_token+strlen(ptr_token),"%s%s", token, ptr_quote+1);
- }
- else
- {
- sprintf(ptr_token+strlen(ptr_token),"%s%s %s", token, ptr_quote+1,
- qt_token );
- }
- }
- }
-
- /* return the concatenated token */
- return ptr_token;
-}
-
-#ifndef __WIN__
-
-/*
- Synopsis:
- This function run scripts files on Linux and Netware
-
-Arguments:
- script_name: name of script file
-
-Output:
- nothing
-*/
-void run_init_script(const char *script_name)
-{
- arg_list_t al;
- int err;
-
- // args
- init_args(&al);
- add_arg(&al, sh_file);
- add_arg(&al, script_name);
-
- // spawn
- if ((err = spawn(sh_file, &al, TRUE, NULL, NULL, NULL, NULL)) != 0)
- {
- die("Unable to run script.");
- }
-
- // free args
- free_args(&al);
-}
-#endif
From 48e7c9abc66bcedc6b2d77bebafe1a83b4f1ed98 Mon Sep 17 00:00:00 2001
From: "serg@serg.mylan" <>
Date: Tue, 23 Nov 2004 15:03:16 +0100
Subject: [PATCH 087/145] use FT_MAX_WORD_LEN_FOR_SORT instead of
HA_FT_MAXBYTELEN when calculating preferred key block length for ft index
---
myisam/mi_create.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/myisam/mi_create.c b/myisam/mi_create.c
index 7fc7cc4edf1..f99a2c655d2 100644
--- a/myisam/mi_create.c
+++ b/myisam/mi_create.c
@@ -16,7 +16,7 @@
/* Create a MyISAM table */
-#include "fulltext.h"
+#include "ftdefs.h"
#include "sp_defs.h"
#if defined(MSDOS) || defined(__WIN__)
@@ -41,7 +41,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
File dfile,file;
int errpos,save_errno;
myf create_flag;
- uint fields,length,max_key_length,packed,pointer,
+ uint fields,length,max_key_length,packed,pointer,real_length_diff,
key_length,info_length,key_segs,options,min_key_length_skip,
base_pos,varchar_count,long_varchar_count,varchar_length,
max_key_block_length,unique_key_parts,fulltext_keys,offset;
@@ -238,7 +238,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
{
share.state.key_root[i]= HA_OFFSET_ERROR;
- min_key_length_skip=length=0;
+ min_key_length_skip=length=real_length_diff=0;
key_length=pointer;
if (keydef->flag & HA_SPATIAL)
{
@@ -297,6 +297,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
key_length+= HA_FT_MAXBYTELEN+HA_FT_WLEN;
length++; /* At least one length byte */
min_key_length_skip+=HA_FT_MAXBYTELEN;
+ real_length_diff=HA_FT_MAXBYTELEN-FT_MAX_WORD_LEN_FOR_SORT;
}
else
{
@@ -397,7 +398,8 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
key_segs)
share.state.rec_per_key_part[key_segs-1]=1L;
length+=key_length;
- keydef->block_length= MI_BLOCK_SIZE(length,pointer,MI_MAX_KEYPTR_SIZE);
+ keydef->block_length= MI_BLOCK_SIZE(length-real_length_diff,
+ pointer,MI_MAX_KEYPTR_SIZE);
if (keydef->block_length > MI_MAX_KEY_BLOCK_LENGTH ||
length >= MI_MAX_KEY_BUFF)
{
From 134aa0b97b0aabc646916b70847048c11dbbe85b Mon Sep 17 00:00:00 2001
From: "joerg@mysql.com" <>
Date: Tue, 23 Nov 2004 17:18:41 +0100
Subject: [PATCH 088/145] Change "Do-compile" to make automatic build log
analysis easier and to run the standard tests with "--force" (default, can be
switched off).
---
Build-tools/Do-compile | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/Build-tools/Do-compile b/Build-tools/Do-compile
index f92af463a0a..af03f3209aa 100755
--- a/Build-tools/Do-compile
+++ b/Build-tools/Do-compile
@@ -10,7 +10,7 @@ use Sys::Hostname;
$opt_distribution=$opt_user=$opt_config_env=$opt_config_extra_env="";
$opt_dbd_options=$opt_perl_options=$opt_config_options=$opt_make_options=$opt_suffix="";
$opt_tmp=$opt_version_suffix="";
-$opt_help=$opt_delete=$opt_debug=$opt_stage=$opt_no_test=$opt_no_perl=$opt_with_low_memory=$opt_fast_benchmark=$opt_static_client=$opt_static_server=$opt_static_perl=$opt_sur=$opt_with_small_disk=$opt_local_perl=$opt_tcpip=$opt_build_thread=$opt_use_old_distribution=$opt_enable_shared=$opt_no_crash_me=$opt_no_strip=$opt_with_debug=$opt_no_benchmark=$opt_no_mysqltest=$opt_without_embedded=0;
+$opt_help=$opt_delete=$opt_debug=$opt_stage=$opt_no_test=$opt_no_perl=$opt_one_error=$opt_with_low_memory=$opt_fast_benchmark=$opt_static_client=$opt_static_server=$opt_static_perl=$opt_sur=$opt_with_small_disk=$opt_local_perl=$opt_tcpip=$opt_build_thread=$opt_use_old_distribution=$opt_enable_shared=$opt_no_crash_me=$opt_no_strip=$opt_with_debug=$opt_no_benchmark=$opt_no_mysqltest=$opt_without_embedded=0;
$opt_innodb=$opt_bdb=$opt_raid=$opt_libwrap=$opt_clearlogs=$opt_without_ndbcluster=0;
GetOptions(
@@ -36,6 +36,7 @@ GetOptions(
"no-test",
"no-mysqltest",
"no-benchmark",
+ "one-error",
"perl-files=s",
"perl-options=s",
"raid",
@@ -298,6 +299,7 @@ if ($opt_stage <= 2)
$command=$make;
$command.= " $opt_make_options" if (defined($opt_make_options) && $opt_make_options ne "");
safe_system($command);
+ print LOG "Do-compile: Build successful\n";
}
#
@@ -358,10 +360,16 @@ $ENV{"LD_LIBRARY_PATH"}= ("$test_dir/lib" .
#
if ($opt_stage <= 5 && !$opt_no_test && !$opt_no_mysqltest)
{
+ my $force= "";
+ if (!$opt_one_error)
+ {
+ $force= "--force"; # default
+ }
log_timestamp();
system("mkdir $bench_tmpdir") if (! -d $bench_tmpdir);
safe_cd("${test_dir}/mysql-test");
- check_system("./mysql-test-run --tmpdir=$bench_tmpdir --master_port=$mysql_tcp_port --slave_port=$slave_port --manager-port=$manager_port --no-manager --sleep=10", "tests were successful");
+ check_system("./mysql-test-run $force --tmpdir=$bench_tmpdir --master_port=$mysql_tcp_port --slave_port=$slave_port --manager-port=$manager_port --no-manager --sleep=10", "tests were successful");
+ # 'mysql-test-run' writes its own final message for log evaluation.
}
#
@@ -535,7 +543,10 @@ Do not run any tests.
Do not run the benchmark test (written in perl)
--no-mysqltest
-Do not run the the mysql-test-run test (Same as 'make test')
+Do not run the mysql-test-run test (Same as 'make test')
+
+--one-error
+Terminate the mysql-test-run test after the first difference (default: use '--force')
--perl-files=list of files
Compile and install the given perl modules.
From 0978d3028dd904bdc5dc5414c8df0ba41f79d329 Mon Sep 17 00:00:00 2001
From: "joreland@mysql.com" <>
Date: Wed, 24 Nov 2004 09:36:49 +0100
Subject: [PATCH 089/145] ndb - debug printout
---
ndb/src/kernel/blocks/dblqh/DblqhMain.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
index 5622706a96c..a40c7842fcd 100644
--- a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
+++ b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
@@ -3084,6 +3084,7 @@ void Dblqh::execATTRINFO(Signal* signal)
return;
break;
default:
+ ndbout_c("%d", regTcPtr->transactionState);
ndbrequire(false);
break;
}//switch
From 97a2d6ebff80f3c592892abb0a50c12438104ce5 Mon Sep 17 00:00:00 2001
From: "joreland@mysql.com" <>
Date: Wed, 24 Nov 2004 09:39:05 +0100
Subject: [PATCH 090/145] ndb - Add testcase to autotest
---
ndb/src/kernel/blocks/dblqh/DblqhMain.cpp | 1 +
ndb/test/run-test/daily-basic-tests.txt | 4 ++++
2 files changed, 5 insertions(+)
diff --git a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
index fc0f39a4f5f..432bb1511aa 100644
--- a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
+++ b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
@@ -3084,6 +3084,7 @@ void Dblqh::execATTRINFO(Signal* signal)
return;
break;
default:
+ ndbout_c("%d", regTcPtr->transactionState);
ndbrequire(false);
break;
}//switch
diff --git a/ndb/test/run-test/daily-basic-tests.txt b/ndb/test/run-test/daily-basic-tests.txt
index 8d7e8a06c72..aa38fb4763c 100644
--- a/ndb/test/run-test/daily-basic-tests.txt
+++ b/ndb/test/run-test/daily-basic-tests.txt
@@ -222,6 +222,10 @@ max-time: 500
cmd: testScan
args: -n ScanRead488 -l 10 T6
+max-time: 500
+cmd: testScan
+args: -n ScanRead488Timeout -l 10 T6
+
max-time: 600
cmd: testScan
args: -n ScanRead40 -l 100 T2
From 16113e812a5b106db218ffbd5c80f54d8dd395e9 Mon Sep 17 00:00:00 2001
From: "bar@mysql.com" <>
Date: Wed, 24 Nov 2004 13:28:48 +0400
Subject: [PATCH 091/145] uca-dump.c: Use less wide spaces on the primary
level, to avoid big diff for ctype-uca.c.
---
strings/uca-dump.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/strings/uca-dump.c b/strings/uca-dump.c
index db5cb7e999a..dd3b74a55e8 100644
--- a/strings/uca-dump.c
+++ b/strings/uca-dump.c
@@ -269,7 +269,7 @@ int main(int ac, char **av)
*/
int tmp= weight[i];
if (w == 2 && tmp)
- tmp= (int)(0x100 - weight[i]);
+ tmp= (int)(0x20 - weight[i]);
printf("0x%04X", tmp);
@@ -304,7 +304,7 @@ int main(int ac, char **av)
const char *comma= page < MY_UCA_NPAGES-1 ? "," : "";
const char *nline= (page+1) % 4 ? "" : "\n";
if (!pagemaxlen[page])
- printf("NULL %s%s", comma , nline);
+ printf("NULL %s%s%s", w ? " ": "", comma , nline);
else
printf("page%03Xdata%s%s%s", page, pname[w], comma, nline);
}
From cd463b5202b2b7e93fc86ea9ef02efa9228b803e Mon Sep 17 00:00:00 2001
From: "serg@serg.mylan" <>
Date: Wed, 24 Nov 2004 11:01:54 +0100
Subject: [PATCH 092/145] harmless "buffer overflow" fixed
---
myisam/mi_test3.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/myisam/mi_test3.c b/myisam/mi_test3.c
index dca04a9a64b..27d23317b5c 100644
--- a/myisam/mi_test3.c
+++ b/myisam/mi_test3.c
@@ -40,7 +40,7 @@
#endif
-const char *filename= "test3.MSI";
+const char *filename= "test3";
uint tests=10,forks=10,key_cacheing=0,use_log=0;
static void get_options(int argc, char *argv[]);
@@ -363,7 +363,7 @@ int test_write(MI_INFO *file,int id,int lock_type)
}
sprintf(record.id,"%7d",getpid());
- strmov(record.text,"Testing...");
+ strnmov(record.text,"Testing...", sizeof(record.text));
tries=(uint) rnd(100)+10;
for (i=count=0 ; i < tries ; i++)
From 98c60c3932520aa65c364c96ba10da254442dad6 Mon Sep 17 00:00:00 2001
From: "joreland@mysql.com" <>
Date: Wed, 24 Nov 2004 11:03:54 +0100
Subject: [PATCH 093/145] ndb - 4.1.8 is not online software upgradable with
4.1.7 (due to close scan optimizations)
---
ndb/src/common/util/version.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/ndb/src/common/util/version.c b/ndb/src/common/util/version.c
index 82acd949c46..f2b3d5bd522 100644
--- a/ndb/src/common/util/version.c
+++ b/ndb/src/common/util/version.c
@@ -70,7 +70,6 @@ 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 }
};
From 5ac41f60e357958f5c6089d84efceba14a8cdf56 Mon Sep 17 00:00:00 2001
From: "joreland@mysql.com" <>
Date: Wed, 24 Nov 2004 12:33:09 +0100
Subject: [PATCH 094/145] merge error
---
client/Makefile.am | 1 -
1 file changed, 1 deletion(-)
diff --git a/client/Makefile.am b/client/Makefile.am
index 0b261b1b105..fa317367f71 100644
--- a/client/Makefile.am
+++ b/client/Makefile.am
@@ -26,7 +26,6 @@ bin_PROGRAMS = mysql mysqladmin mysqlcheck mysqlshow \
mysqldump mysqlimport mysqltest mysqlbinlog mysqlmanagerc mysqlmanager-pwgen
noinst_HEADERS = sql_string.h completion_hash.h my_readline.h \
client_priv.h
-mysqladmin_SOURCES = mysqladmin.cc
mysql_SOURCES = mysql.cc readline.cc sql_string.cc completion_hash.cc
mysqladmin_SOURCES = mysqladmin.cc
mysql_LDADD = @readline_link@ @TERMCAP_LIB@ $(LDADD) $(CXXLDFLAGS)
From 003b28d04fa605c4aff9400452b6c64949ea8389 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Wed, 24 Nov 2004 13:59:03 +0000
Subject: [PATCH 095/145] added mgmapi/mgmapi_config_parameters.h,
mgmapi/mgmapi_config_parameters_debug.h to distribution
---
ndb/include/Makefile.am | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/ndb/include/Makefile.am b/ndb/include/Makefile.am
index 7b3f80b5560..61f55cf9d61 100644
--- a/ndb/include/Makefile.am
+++ b/ndb/include/Makefile.am
@@ -29,13 +29,13 @@ ndbapi/ndberror.h
mgmapiinclude_HEADERS = \
mgmapi/mgmapi.h \
-mgmapi/mgmapi_debug.h
+mgmapi/mgmapi_debug.h \
+mgmapi/mgmapi_config_parameters.h \
+mgmapi/mgmapi_config_parameters_debug.h
noinst_HEADERS = \
ndb_global.h \
-ndb_net.h \
-mgmapi/mgmapi_config_parameters.h \
-mgmapi/mgmapi_config_parameters_debug.h
+ndb_net.h
EXTRA_DIST = debugger editline kernel logger mgmcommon \
portlib transporter util
From cf722bc3f5040d447f657477485e362b967d1f3e Mon Sep 17 00:00:00 2001
From: "joerg@mysql.com" <>
Date: Wed, 24 Nov 2004 15:24:23 +0100
Subject: [PATCH 096/145] Ensure consistent sources up to 5.0 where a C++
problem occurs.
---
client/mysqladmin.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/client/mysqladmin.c b/client/mysqladmin.c
index 153fcdde96d..978e0c7e88b 100644
--- a/client/mysqladmin.c
+++ b/client/mysqladmin.c
@@ -554,7 +554,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
{
char *pos,buff[40];
ulong sec;
- pos=strchr(status,' ');
+ pos= (char*) strchr(status,' ');
*pos++=0;
printf("%s\t\t\t",status); /* print label */
if ((status=str2int(pos,10,0,LONG_MAX,(long*) &sec)))
From dfe4e29a4c721dabaed404b33e97774b3f007104 Mon Sep 17 00:00:00 2001
From: "joreland@mysql.com" <>
Date: Wed, 24 Nov 2004 16:36:18 +0100
Subject: [PATCH 097/145] bug#6775 - ndb Queue scan on real fragment. Index
fragment for range scans Table fragment for table scans
---
ndb/src/kernel/blocks/dblqh/Dblqh.hpp | 5 +++
ndb/src/kernel/blocks/dblqh/DblqhMain.cpp | 41 ++++++++++++-----------
ndb/src/ndbapi/NdbConnection.cpp | 7 ++--
3 files changed, 31 insertions(+), 22 deletions(-)
diff --git a/ndb/src/kernel/blocks/dblqh/Dblqh.hpp b/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
index 6c8c2bb2dae..0c63cb5fe17 100644
--- a/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
+++ b/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
@@ -550,6 +550,11 @@ public:
UintR scanErrorCounter;
UintR scanLocalFragid;
UintR scanSchemaVersion;
+
+ /**
+ * This is _always_ main table, even in range scan
+ * in which case scanTcrec->fragmentptr is different
+ */
Uint32 fragPtrI;
UintR scanStoredProcId;
ScanState scanState;
diff --git a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
index 432bb1511aa..88e8f25b004 100644
--- a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
+++ b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
@@ -7703,6 +7703,9 @@ void Dblqh::abort_scan(Signal* signal, Uint32 scan_ptr_i, Uint32 errcode){
jam();
scanptr.i = scan_ptr_i;
c_scanRecordPool.getPtr(scanptr);
+
+ fragptr.i = tcConnectptr.p->fragmentptr;
+ ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
finishScanrec(signal);
releaseScanrec(signal);
tcConnectptr.p->transactionState = TcConnectionrec::IDLE;
@@ -8570,10 +8573,12 @@ Uint32 Dblqh::initScanrec(const ScanFragReq* scanFragReq)
/**
* Used for scan take over
*/
- FragrecordPtr tFragPtr;
- tFragPtr.i = fragptr.p->tableFragptr;
- ptrCheckGuard(tFragPtr, cfragrecFileSize, fragrecord);
- scanptr.p->fragPtrI = fragptr.p->tableFragptr;
+ {
+ FragrecordPtr tFragPtr;
+ tFragPtr.i = fragptr.p->tableFragptr;
+ ptrCheckGuard(tFragPtr, cfragrecFileSize, fragrecord);
+ scanptr.p->fragPtrI = fragptr.p->tableFragptr;
+ }
/**
* !idx uses 1 - (MAX_PARALLEL_SCANS_PER_FRAG - 1) = 1-11
@@ -8582,8 +8587,8 @@ Uint32 Dblqh::initScanrec(const ScanFragReq* scanFragReq)
Uint32 start = (idx ? MAX_PARALLEL_SCANS_PER_FRAG : 1 );
Uint32 stop = (idx ? MAX_PARALLEL_INDEX_SCANS_PER_FRAG : MAX_PARALLEL_SCANS_PER_FRAG - 1);
stop += start;
- Uint32 free = tFragPtr.p->m_scanNumberMask.find(start);
-
+ Uint32 free = fragptr.p->m_scanNumberMask.find(start);
+
if(free == Fragrecord::ScanNumberMask::NotFound || free >= stop){
jam();
@@ -8597,16 +8602,16 @@ Uint32 Dblqh::initScanrec(const ScanFragReq* scanFragReq)
*/
scanptr.p->scanState = ScanRecord::IN_QUEUE;
LocalDLFifoList queue(c_scanRecordPool,
- tFragPtr.p->m_queuedScans);
+ fragptr.p->m_queuedScans);
queue.add(scanptr);
return ZOK;
}
-
+
scanptr.p->scanNumber = free;
- tFragPtr.p->m_scanNumberMask.clear(free);// Update mask
+ fragptr.p->m_scanNumberMask.clear(free);// Update mask
- LocalDLList active(c_scanRecordPool, tFragPtr.p->m_activeScans);
+ LocalDLList active(c_scanRecordPool, fragptr.p->m_activeScans);
active.add(scanptr);
if(scanptr.p->scanKeyinfoFlag){
jam();
@@ -8666,12 +8671,8 @@ void Dblqh::finishScanrec(Signal* signal)
{
release_acc_ptr_list(scanptr.p);
- FragrecordPtr tFragPtr;
- tFragPtr.i = scanptr.p->fragPtrI;
- ptrCheckGuard(tFragPtr, cfragrecFileSize, fragrecord);
-
LocalDLFifoList queue(c_scanRecordPool,
- tFragPtr.p->m_queuedScans);
+ fragptr.p->m_queuedScans);
if(scanptr.p->scanState == ScanRecord::IN_QUEUE){
jam();
@@ -8689,11 +8690,11 @@ void Dblqh::finishScanrec(Signal* signal)
ndbrequire(tmp.p == scanptr.p);
}
- LocalDLList scans(c_scanRecordPool, tFragPtr.p->m_activeScans);
+ LocalDLList scans(c_scanRecordPool, fragptr.p->m_activeScans);
scans.release(scanptr);
const Uint32 scanNumber = scanptr.p->scanNumber;
- ndbrequire(!tFragPtr.p->m_scanNumberMask.get(scanNumber));
+ ndbrequire(!fragptr.p->m_scanNumberMask.get(scanNumber));
ScanRecordPtr restart;
/**
@@ -8701,13 +8702,13 @@ void Dblqh::finishScanrec(Signal* signal)
*/
if(scanNumber == NR_ScanNo || !queue.first(restart)){
jam();
- tFragPtr.p->m_scanNumberMask.set(scanNumber);
+ fragptr.p->m_scanNumberMask.set(scanNumber);
return;
}
if(ERROR_INSERTED(5034)){
jam();
- tFragPtr.p->m_scanNumberMask.set(scanNumber);
+ fragptr.p->m_scanNumberMask.set(scanNumber);
return;
}
@@ -8718,7 +8719,7 @@ void Dblqh::finishScanrec(Signal* signal)
ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
restart.p->scanNumber = scanNumber;
restart.p->scanState = ScanRecord::WAIT_ACC_SCAN;
-
+
queue.remove(restart);
scans.add(restart);
if(restart.p->scanKeyinfoFlag){
diff --git a/ndb/src/ndbapi/NdbConnection.cpp b/ndb/src/ndbapi/NdbConnection.cpp
index 6284ae8ce6e..f3ddc68245a 100644
--- a/ndb/src/ndbapi/NdbConnection.cpp
+++ b/ndb/src/ndbapi/NdbConnection.cpp
@@ -1086,8 +1086,11 @@ NdbConnection::getNdbIndexScanOperation(const NdbIndexImpl* index,
if (indexTable != 0){
NdbIndexScanOperation* tOp =
getNdbScanOperation((NdbTableImpl *) indexTable);
- tOp->m_currentTable = table;
- if(tOp) tOp->m_cursor_type = NdbScanOperation::IndexCursor;
+ if(tOp)
+ {
+ tOp->m_currentTable = table;
+ tOp->m_cursor_type = NdbScanOperation::IndexCursor;
+ }
return tOp;
} else {
setOperationErrorCodeAbort(theNdb->theError.code);
From ebc7c9cb999c7f81093d7f02511948e2309f9fd3 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Wed, 24 Nov 2004 15:51:59 +0000
Subject: [PATCH 098/145] calculation of noOfTriggers
---
ndb/src/kernel/vm/Configuration.cpp | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/ndb/src/kernel/vm/Configuration.cpp b/ndb/src/kernel/vm/Configuration.cpp
index 31853b7a3b7..92b09891a2f 100644
--- a/ndb/src/kernel/vm/Configuration.cpp
+++ b/ndb/src/kernel/vm/Configuration.cpp
@@ -34,6 +34,7 @@
#include
#include
+#include
#include "pc.hpp"
#include
#include
@@ -454,6 +455,7 @@ Configuration::calcSizeAlt(ConfigValues * ownConfig){
unsigned int noOfTables = 0;
unsigned int noOfUniqueHashIndexes = 0;
unsigned int noOfOrderedIndexes = 0;
+ unsigned int noOfTriggers = 0;
unsigned int noOfReplicas = 0;
unsigned int noOfDBNodes = 0;
unsigned int noOfAPINodes = 0;
@@ -478,6 +480,7 @@ Configuration::calcSizeAlt(ConfigValues * ownConfig){
{ CFG_DB_NO_TABLES, &noOfTables, false },
{ CFG_DB_NO_ORDERED_INDEXES, &noOfOrderedIndexes, false },
{ CFG_DB_NO_UNIQUE_HASH_INDEXES, &noOfUniqueHashIndexes, false },
+ { CFG_DB_NO_TRIGGERS, &noOfTriggers, true },
{ CFG_DB_NO_REPLICAS, &noOfReplicas, false },
{ CFG_DB_NO_ATTRIBUTES, &noOfAttributes, false },
{ CFG_DB_NO_OPS, &noOfOperations, false },
@@ -586,6 +589,16 @@ Configuration::calcSizeAlt(ConfigValues * ownConfig){
ConfigValues::Iterator it2(*ownConfig, db.m_config);
it2.set(CFG_DB_NO_TABLES, noOfTables);
it2.set(CFG_DB_NO_ATTRIBUTES, noOfAttributes);
+ {
+ Uint32 neededNoOfTriggers =
+ 3 * (noOfUniqueHashIndexes + NDB_MAX_ACTIVE_EVENTS)+
+ noOfOrderedIndexes;
+ if (noOfTriggers < neededNoOfTriggers)
+ {
+ noOfTriggers= neededNoOfTriggers;
+ it2.set(CFG_DB_NO_TRIGGERS, noOfTriggers);
+ }
+ }
/**
* Do size calculations
From 7b601bd984d190fca99ec3d4ba164b3243075ae6 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Wed, 24 Nov 2004 16:04:11 +0000
Subject: [PATCH 099/145] also backup needs triggers
---
ndb/src/kernel/vm/Configuration.cpp | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/ndb/src/kernel/vm/Configuration.cpp b/ndb/src/kernel/vm/Configuration.cpp
index 92b09891a2f..931b4da5a17 100644
--- a/ndb/src/kernel/vm/Configuration.cpp
+++ b/ndb/src/kernel/vm/Configuration.cpp
@@ -590,9 +590,11 @@ Configuration::calcSizeAlt(ConfigValues * ownConfig){
it2.set(CFG_DB_NO_TABLES, noOfTables);
it2.set(CFG_DB_NO_ATTRIBUTES, noOfAttributes);
{
- Uint32 neededNoOfTriggers =
- 3 * (noOfUniqueHashIndexes + NDB_MAX_ACTIVE_EVENTS)+
- noOfOrderedIndexes;
+ Uint32 neededNoOfTriggers = /* types: Insert/Update/Delete/Custom */
+ 3 * noOfUniqueHashIndexes + /* for unique hash indexes, I/U/D */
+ 3 * NDB_MAX_ACTIVE_EVENTS + /* for events in suma, I/U/D */
+ 3 * noOfTables + /* for backup, I/U/D */
+ noOfOrderedIndexes; /* for ordered indexes, C */
if (noOfTriggers < neededNoOfTriggers)
{
noOfTriggers= neededNoOfTriggers;
From 0f79f614806e45d2c314b5ba9095b523f2fd62a3 Mon Sep 17 00:00:00 2001
From: "bar@mysql.com" <>
Date: Wed, 24 Nov 2004 20:09:54 +0400
Subject: [PATCH 100/145] Bug#6787 LIKE not working properly with _ and utf8
data
---
mysql-test/r/ctype_uca.result | 3 +++
mysql-test/r/ctype_utf8.result | 3 +++
mysql-test/t/ctype_uca.test | 5 +++++
mysql-test/t/ctype_utf8.test | 6 ++++++
strings/ctype-uca.c | 4 +++-
strings/ctype-utf8.c | 26 ++++++++++++++------------
6 files changed, 34 insertions(+), 13 deletions(-)
diff --git a/mysql-test/r/ctype_uca.result b/mysql-test/r/ctype_uca.result
index 7620b18eea6..cb060ad7ee4 100644
--- a/mysql-test/r/ctype_uca.result
+++ b/mysql-test/r/ctype_uca.result
@@ -19,6 +19,9 @@ select 'a ' = 'a\t', 'a ' < 'a\t', 'a ' > 'a\t';
select 'a a' > 'a', 'a \t' < 'a';
'a a' > 'a' 'a \t' < 'a'
1 1
+select 'c' like '\_' as want0;
+want0
+0
CREATE TABLE t (
c char(20) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result
index 945ec8eae99..599d49208e7 100644
--- a/mysql-test/r/ctype_utf8.result
+++ b/mysql-test/r/ctype_utf8.result
@@ -814,3 +814,6 @@ t2 CREATE TABLE `t2` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t2;
drop table t1;
+select 'c' like '\_' as want0;
+want0
+0
diff --git a/mysql-test/t/ctype_uca.test b/mysql-test/t/ctype_uca.test
index e640e6b53dc..11833ba9bc7 100644
--- a/mysql-test/t/ctype_uca.test
+++ b/mysql-test/t/ctype_uca.test
@@ -24,6 +24,11 @@ select 'a ' = 'a\t', 'a ' < 'a\t', 'a ' > 'a\t';
select 'a a' > 'a', 'a \t' < 'a';
+#
+# Bug #6787 LIKE not working properly with _ and utf8 data
+#
+select 'c' like '\_' as want0;
+
#
# Bug #5679 utf8_unicode_ci LIKE--trailing % doesn't equal zero characters
#
diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test
index c75b1dee63c..42031be8f3c 100644
--- a/mysql-test/t/ctype_utf8.test
+++ b/mysql-test/t/ctype_utf8.test
@@ -660,3 +660,9 @@ create table t2 select concat(a,_utf8'') as a, concat(b,_utf8'')as b from t1;
show create table t2;
drop table t2;
drop table t1;
+
+#
+# Bug #6787 LIKE not working properly with _ and utf8 data
+#
+select 'c' like '\_' as want0;
+
diff --git a/strings/ctype-uca.c b/strings/ctype-uca.c
index 8df5b3277c1..89c876ad10c 100644
--- a/strings/ctype-uca.c
+++ b/strings/ctype-uca.c
@@ -7288,6 +7288,7 @@ int my_wildcmp_uca(CHARSET_INFO *cs,
{
while (1)
{
+ my_bool escaped= 0;
if ((scan= mb_wc(cs, &w_wc, (const uchar*)wildstr,
(const uchar*)wildend)) <= 0)
return 1;
@@ -7305,6 +7306,7 @@ int my_wildcmp_uca(CHARSET_INFO *cs,
(const uchar*)wildend)) <= 0)
return 1;
wildstr+= scan;
+ escaped= 1;
}
if ((scan= mb_wc(cs, &s_wc, (const uchar*)str,
@@ -7312,7 +7314,7 @@ int my_wildcmp_uca(CHARSET_INFO *cs,
return 1;
str+= scan;
- if (w_wc == (my_wc_t)w_one)
+ if (!escaped && w_wc == (my_wc_t)w_one)
{
result= 1; /* Found an anchor char */
}
diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c
index b3097649158..ce9346eb475 100644
--- a/strings/ctype-utf8.c
+++ b/strings/ctype-utf8.c
@@ -1545,31 +1545,33 @@ int my_wildcmp_unicode(CHARSET_INFO *cs,
{
while (1)
{
+ my_bool escaped= 0;
if ((scan= mb_wc(cs, &w_wc, (const uchar*)wildstr,
(const uchar*)wildend)) <= 0)
return 1;
-
- if (w_wc == (my_wc_t)escape)
- {
- wildstr+= scan;
- if ((scan= mb_wc(cs,&w_wc, (const uchar*)wildstr,
- (const uchar*)wildend)) <= 0)
- return 1;
- }
-
+
if (w_wc == (my_wc_t)w_many)
{
result= 1; /* Found an anchor char */
break;
}
-
+
wildstr+= scan;
+ if (w_wc == (my_wc_t)escape)
+ {
+ if ((scan= mb_wc(cs, &w_wc, (const uchar*)wildstr,
+ (const uchar*)wildend)) <= 0)
+ return 1;
+ wildstr+= scan;
+ escaped= 1;
+ }
+
if ((scan= mb_wc(cs, &s_wc, (const uchar*)str,
- (const uchar*)str_end)) <=0)
+ (const uchar*)str_end)) <= 0)
return 1;
str+= scan;
- if (w_wc == (my_wc_t)w_one)
+ if (!escaped && w_wc == (my_wc_t)w_one)
{
result= 1; /* Found an anchor char */
}
From 489b41164009d4fbd6c58f389514a54bc1dd3798 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Wed, 24 Nov 2004 17:40:40 +0000
Subject: [PATCH 101/145] added explanation of error code 4335
---
ndb/src/ndbapi/ndberror.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/ndb/src/ndbapi/ndberror.c b/ndb/src/ndbapi/ndberror.c
index e08b80f2433..bc49358cc63 100644
--- a/ndb/src/ndbapi/ndberror.c
+++ b/ndb/src/ndbapi/ndberror.c
@@ -426,7 +426,8 @@ ErrorBundle ErrorCodes[] = {
{ 4267, IE, "Corrupted blob value" },
{ 4268, IE, "Error in blob head update forced rollback of transaction" },
{ 4268, IE, "Unknown blob error" },
- { 4269, IE, "No connection to ndb management server" }
+ { 4269, IE, "No connection to ndb management server" },
+ { 4335, AE, "Only one autoincrement column allowed per table. Having a table without primary key uses an autoincremented hidden key, i.e. a table without a primary key can not have an autoincremented column" }
};
static
From bd6ccd46fc88d331cdbf244654a74666a3914a92 Mon Sep 17 00:00:00 2001
From: "heikki@hundin.mysql.fi" <>
Date: Wed, 24 Nov 2004 19:41:38 +0200
Subject: [PATCH 102/145] configure.in: Fix linking error in 5.0: the build
system for Linux/S390 does not have inlining working in the compiler; remove
inlining on that system
---
innobase/configure.in | 3 +++
1 file changed, 3 insertions(+)
diff --git a/innobase/configure.in b/innobase/configure.in
index 652291f1f38..d83da9fdc5c 100644
--- a/innobase/configure.in
+++ b/innobase/configure.in
@@ -110,6 +110,9 @@ esac
case "$target" in
i[[4567]]86-*-*)
CFLAGS="$CFLAGS -DUNIV_INTEL_X86";;
+ # The compiler on Linux/S390 does not seem to have inlining
+ s390-*-*)
+ CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE";;
esac
AC_OUTPUT(Makefile os/Makefile ut/Makefile btr/Makefile dnl
From e8203e437a991230bee1de60a8369eaf09357f2c Mon Sep 17 00:00:00 2001
From: "serg@serg.mylan" <>
Date: Wed, 24 Nov 2004 23:16:16 +0100
Subject: [PATCH 103/145] bug#6784 mi_flush_bulk_insert (on dup key error in
mi_write) was mangling info->dupp_key_pos
---
myisam/mi_write.c | 16 ++++++----------
mysql-test/r/fulltext.result | 6 ++++++
mysql-test/t/fulltext.test | 13 +++++++++++++
3 files changed, 25 insertions(+), 10 deletions(-)
diff --git a/myisam/mi_write.c b/myisam/mi_write.c
index e059bbb569f..303e924118f 100644
--- a/myisam/mi_write.c
+++ b/myisam/mi_write.c
@@ -165,12 +165,7 @@ err:
{
uint j;
for (j=0 ; j < share->base.keys ; j++)
- {
- if (is_tree_inited(&info->bulk_insert[j]))
- {
- reset_tree(&info->bulk_insert[j]);
- }
- }
+ mi_flush_bulk_insert(info, j);
}
info->errkey= (int) i;
while ( i-- > 0)
@@ -329,7 +324,7 @@ static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
uchar *temp_buff,*keypos;
uchar keybuff[MI_MAX_KEY_BUFF];
my_bool was_last_key;
- my_off_t next_page;
+ my_off_t next_page, dupp_key_pos;
DBUG_ENTER("w_search");
DBUG_PRINT("enter",("page: %ld",page));
@@ -349,9 +344,9 @@ static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
/* get position to record with duplicated key */
tmp_key_length=(*keyinfo->get_key)(keyinfo,nod_flag,&keypos,keybuff);
if (tmp_key_length)
- info->dupp_key_pos=_mi_dpos(info,0,keybuff+tmp_key_length);
+ dupp_key_pos=_mi_dpos(info,0,keybuff+tmp_key_length);
else
- info->dupp_key_pos= HA_OFFSET_ERROR;
+ dupp_key_pos= HA_OFFSET_ERROR;
if (keyinfo->flag & HA_FULLTEXT)
{
uint off;
@@ -370,7 +365,7 @@ static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
else
{
/* popular word. two-level tree. going down */
- my_off_t root=info->dupp_key_pos;
+ my_off_t root=dupp_key_pos;
keyinfo=&info->s->ft2_keyinfo;
get_key_full_length_rdonly(off, key);
key+=off;
@@ -389,6 +384,7 @@ static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
}
else /* not HA_FULLTEXT, normal HA_NOSAME key */
{
+ info->dupp_key_pos= dupp_key_pos;
my_afree((byte*) temp_buff);
my_errno=HA_ERR_FOUND_DUPP_KEY;
DBUG_RETURN(-1);
diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result
index cff43a821b3..7acc8a2d23f 100644
--- a/mysql-test/r/fulltext.result
+++ b/mysql-test/r/fulltext.result
@@ -399,3 +399,9 @@ select count(*) from t1;
count(*)
1
drop table t1;
+create table t1 (a int primary key, b text, fulltext(b));
+create table t2 (a int, b text);
+insert t1 values (1, "aaaa"), (2, "bbbb");
+insert t2 values (10, "aaaa"), (2, "cccc");
+replace t1 select * from t2;
+drop table t1, t2;
diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test
index 41fbf3f27ac..008e965297f 100644
--- a/mysql-test/t/fulltext.test
+++ b/mysql-test/t/fulltext.test
@@ -308,3 +308,16 @@ REPAIR TABLE t1;
select count(*) from t1;
drop table t1;
+#
+# bug#6784
+# mi_flush_bulk_insert (on dup key error in mi_write)
+# was mangling info->dupp_key_pos
+#
+
+create table t1 (a int primary key, b text, fulltext(b));
+create table t2 (a int, b text);
+insert t1 values (1, "aaaa"), (2, "bbbb");
+insert t2 values (10, "aaaa"), (2, "cccc");
+replace t1 select * from t2;
+drop table t1, t2;
+
From c06cae0f554e9e212c34ee419a3a5a4b292947af Mon Sep 17 00:00:00 2001
From: "mats@mysql.com" <>
Date: Thu, 25 Nov 2004 09:26:45 +0100
Subject: [PATCH 104/145] Fix for Bug#6148. Only rewind read position in
binary log when the slave SQL thread is started.
---
mysql-test/r/rpl_start_stop_slave.result | 12 +++++++++
mysql-test/t/rpl_start_stop_slave.test | 34 ++++++++++++++++++++++++
sql/repl_failsafe.cc | 3 ++-
sql/slave.cc | 14 +++++++---
sql/slave.h | 3 ++-
sql/sql_repl.cc | 6 +++--
6 files changed, 65 insertions(+), 7 deletions(-)
create mode 100644 mysql-test/r/rpl_start_stop_slave.result
create mode 100644 mysql-test/t/rpl_start_stop_slave.test
diff --git a/mysql-test/r/rpl_start_stop_slave.result b/mysql-test/r/rpl_start_stop_slave.result
new file mode 100644
index 00000000000..1b4d87124d1
--- /dev/null
+++ b/mysql-test/r/rpl_start_stop_slave.result
@@ -0,0 +1,12 @@
+slave stop;
+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;
+slave start;
+stop slave;
+create table t1(n int);
+start slave;
+stop slave io_thread;
+start slave io_thread;
+drop table t1;
diff --git a/mysql-test/t/rpl_start_stop_slave.test b/mysql-test/t/rpl_start_stop_slave.test
new file mode 100644
index 00000000000..903ff204194
--- /dev/null
+++ b/mysql-test/t/rpl_start_stop_slave.test
@@ -0,0 +1,34 @@
+source include/master-slave.inc;
+
+#
+# Bug#6148 ()
+#
+connection slave;
+stop slave;
+
+# Let the master do lots of insertions
+connection master;
+create table t1(n int);
+let $1=5000;
+disable_query_log;
+while ($1)
+{
+ eval insert into t1 values($1);
+ dec $1;
+}
+enable_query_log;
+save_master_pos;
+
+connection slave;
+start slave;
+sleep 1;
+stop slave io_thread;
+start slave io_thread;
+sync_with_master;
+
+connection master;
+drop table t1;
+save_master_pos;
+
+connection slave;
+sync_with_master;
diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc
index 9fa6ea843f1..84640fbc968 100644
--- a/sql/repl_failsafe.cc
+++ b/sql/repl_failsafe.cc
@@ -892,7 +892,8 @@ int load_master_data(THD* thd)
setting active_mi, because init_master_info() sets active_mi with
defaults.
*/
- if (init_master_info(active_mi, master_info_file, relay_log_info_file, 0))
+ if (init_master_info(active_mi, master_info_file, relay_log_info_file,
+ 0, (SLAVE_IO | SLAVE_SQL)))
send_error(&thd->net, ER_MASTER_INFO);
strmake(active_mi->master_log_name, row[0],
sizeof(active_mi->master_log_name));
diff --git a/sql/slave.cc b/sql/slave.cc
index 18e0ec5929f..7e544572755 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -137,7 +137,7 @@ int init_slave()
}
if (init_master_info(active_mi,master_info_file,relay_log_info_file,
- !master_host))
+ !master_host, (SLAVE_IO | SLAVE_SQL)))
{
sql_print_error("Failed to initialize the master info structure");
goto err;
@@ -1616,7 +1616,8 @@ void clear_last_slave_error(RELAY_LOG_INFO* rli)
int init_master_info(MASTER_INFO* mi, const char* master_info_fname,
const char* slave_info_fname,
- bool abort_if_no_master_info_file)
+ bool abort_if_no_master_info_file,
+ int thread_mask)
{
int fd,error;
char fname[FN_REFLEN+128];
@@ -1630,8 +1631,15 @@ int init_master_info(MASTER_INFO* mi, const char* master_info_fname,
last time. If this case pos_in_file would be set and we would
get a crash when trying to read the signature for the binary
relay log.
+
+ We only rewind the read position if we are starting the SQL
+ thread. The handle_slave_sql thread assumes that the read
+ position is at the beginning of the file, and will read the
+ "signature" and then fast-forward to the last position read.
*/
- my_b_seek(mi->rli.cur_log, (my_off_t) 0);
+ if (thread_mask & SLAVE_SQL) {
+ my_b_seek(mi->rli.cur_log, (my_off_t) 0);
+ }
DBUG_RETURN(0);
}
diff --git a/sql/slave.h b/sql/slave.h
index eb54e258a96..a01ff93b4af 100644
--- a/sql/slave.h
+++ b/sql/slave.h
@@ -411,7 +411,8 @@ void init_master_info_with_options(MASTER_INFO* mi);
void clear_last_slave_error(RELAY_LOG_INFO* rli);
int init_master_info(MASTER_INFO* mi, const char* master_info_fname,
const char* slave_info_fname,
- bool abort_if_no_master_info_file);
+ bool abort_if_no_master_info_file,
+ int thread_mask);
void end_master_info(MASTER_INFO* mi);
int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname);
void end_relay_log_info(RELAY_LOG_INFO* rli);
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 514fed226d2..9485031c144 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -662,7 +662,8 @@ int start_slave(THD* thd , MASTER_INFO* mi, bool net_report)
thread_mask &= thd->lex.slave_thd_opt;
if (thread_mask)
{
- if (init_master_info(mi,master_info_file,relay_log_info_file, 0))
+ if (init_master_info(mi,master_info_file,relay_log_info_file, 0,
+ thread_mask))
slave_errno=ER_MASTER_INFO;
else if (server_id_supplied && *mi->host)
slave_errno = start_slave_threads(0 /*no mutex */,
@@ -867,7 +868,8 @@ int change_master(THD* thd, MASTER_INFO* mi)
thd->proc_info = "Changing master";
LEX_MASTER_INFO* lex_mi = &thd->lex.mi;
// TODO: see if needs re-write
- if (init_master_info(mi, master_info_file, relay_log_info_file, 0))
+ if (init_master_info(mi, master_info_file, relay_log_info_file, 0,
+ thread_mask))
{
send_error(&thd->net, ER_MASTER_INFO);
unlock_slave_threads(mi);
From a9e5e7de88edad95e0f87432b8deaecb2ce87988 Mon Sep 17 00:00:00 2001
From: "joreland@mysql.com" <>
Date: Thu, 25 Nov 2004 10:38:46 +0100
Subject: [PATCH 105/145] bug#6775 - ndb - fix bug introduced by bug fix
---
ndb/src/kernel/blocks/dblqh/DblqhMain.cpp | 33 ++++++++++++-----------
1 file changed, 17 insertions(+), 16 deletions(-)
diff --git a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
index 88e8f25b004..c106a6ddfac 100644
--- a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
+++ b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
@@ -8573,13 +8573,11 @@ Uint32 Dblqh::initScanrec(const ScanFragReq* scanFragReq)
/**
* Used for scan take over
*/
- {
- FragrecordPtr tFragPtr;
- tFragPtr.i = fragptr.p->tableFragptr;
- ptrCheckGuard(tFragPtr, cfragrecFileSize, fragrecord);
- scanptr.p->fragPtrI = fragptr.p->tableFragptr;
- }
-
+ FragrecordPtr tFragPtr;
+ tFragPtr.i = fragptr.p->tableFragptr;
+ ptrCheckGuard(tFragPtr, cfragrecFileSize, fragrecord);
+ scanptr.p->fragPtrI = fragptr.p->tableFragptr;
+
/**
* !idx uses 1 - (MAX_PARALLEL_SCANS_PER_FRAG - 1) = 1-11
* idx uses from MAX_PARALLEL_SCANS_PER_FRAG - MAX = 12-42)
@@ -8587,11 +8585,11 @@ Uint32 Dblqh::initScanrec(const ScanFragReq* scanFragReq)
Uint32 start = (idx ? MAX_PARALLEL_SCANS_PER_FRAG : 1 );
Uint32 stop = (idx ? MAX_PARALLEL_INDEX_SCANS_PER_FRAG : MAX_PARALLEL_SCANS_PER_FRAG - 1);
stop += start;
- Uint32 free = fragptr.p->m_scanNumberMask.find(start);
-
+ Uint32 free = tFragPtr.p->m_scanNumberMask.find(start);
+
if(free == Fragrecord::ScanNumberMask::NotFound || free >= stop){
jam();
-
+
if(scanPrio == 0){
jam();
return ScanFragRef::ZTOO_MANY_ACTIVE_SCAN_ERROR;
@@ -8607,10 +8605,9 @@ Uint32 Dblqh::initScanrec(const ScanFragReq* scanFragReq)
return ZOK;
}
-
scanptr.p->scanNumber = free;
- fragptr.p->m_scanNumberMask.clear(free);// Update mask
-
+ tFragPtr.p->m_scanNumberMask.clear(free);// Update mask
+
LocalDLList active(c_scanRecordPool, fragptr.p->m_activeScans);
active.add(scanptr);
if(scanptr.p->scanKeyinfoFlag){
@@ -8693,8 +8690,12 @@ void Dblqh::finishScanrec(Signal* signal)
LocalDLList scans(c_scanRecordPool, fragptr.p->m_activeScans);
scans.release(scanptr);
+ FragrecordPtr tFragPtr;
+ tFragPtr.i = scanptr.p->fragPtrI;
+ ptrCheckGuard(tFragPtr, cfragrecFileSize, fragrecord);
+
const Uint32 scanNumber = scanptr.p->scanNumber;
- ndbrequire(!fragptr.p->m_scanNumberMask.get(scanNumber));
+ ndbrequire(!tFragPtr.p->m_scanNumberMask.get(scanNumber));
ScanRecordPtr restart;
/**
@@ -8702,13 +8703,13 @@ void Dblqh::finishScanrec(Signal* signal)
*/
if(scanNumber == NR_ScanNo || !queue.first(restart)){
jam();
- fragptr.p->m_scanNumberMask.set(scanNumber);
+ tFragPtr.p->m_scanNumberMask.set(scanNumber);
return;
}
if(ERROR_INSERTED(5034)){
jam();
- fragptr.p->m_scanNumberMask.set(scanNumber);
+ tFragPtr.p->m_scanNumberMask.set(scanNumber);
return;
}
From 5a09289bd15049fd6f7f09d2688e48bee9a0b321 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Thu, 25 Nov 2004 12:14:15 +0000
Subject: [PATCH 106/145] ndb/src/common/logger/LogHandler.cpp changed so
that error is returned if format is wrong in logger param parsing
ndb/src/common/logger/Logger.cpp some debuf printout added
ndb/src/mgmsrv/InitConfigFileParser.cpp rewrote parsing on
parseNameValuePair, was buggy
---
ndb/src/common/logger/LogHandler.cpp | 7 ++-
ndb/src/common/logger/Logger.cpp | 9 ++--
ndb/src/mgmsrv/InitConfigFileParser.cpp | 68 +++++++++----------------
3 files changed, 33 insertions(+), 51 deletions(-)
diff --git a/ndb/src/common/logger/LogHandler.cpp b/ndb/src/common/logger/LogHandler.cpp
index 4fab957fc50..a76cb622878 100644
--- a/ndb/src/common/logger/LogHandler.cpp
+++ b/ndb/src/common/logger/LogHandler.cpp
@@ -117,10 +117,9 @@ LogHandler::parseParams(const BaseString &_params) {
_params.split(v_args, ",");
for(size_t i=0; i < v_args.size(); i++) {
Vector v_param_value;
-
- v_args[i].split(v_param_value, "=", 2);
- if(v_param_value.size() == 2 &&
- !setParam(v_param_value[0], v_param_value[1]))
+ if(v_args[i].split(v_param_value, "=", 2) != 2)
+ ret = false;
+ else if (!setParam(v_param_value[0], v_param_value[1]))
ret = false;
}
diff --git a/ndb/src/common/logger/Logger.cpp b/ndb/src/common/logger/Logger.cpp
index 00a2fae67bc..1dc3bd43716 100644
--- a/ndb/src/common/logger/Logger.cpp
+++ b/ndb/src/common/logger/Logger.cpp
@@ -169,10 +169,13 @@ Logger::addHandler(const BaseString &logstring) {
size_t i;
Vector logdest;
Vectorloghandlers;
+ DBUG_ENTER("Logger::addHandler");
logstring.split(logdest, ";");
for(i = 0; i < logdest.size(); i++) {
+ DBUG_PRINT("info",("adding: %s",logdest[i]));
+
Vector v_type_args;
logdest[i].split(v_type_args, ":", 2);
@@ -191,16 +194,16 @@ Logger::addHandler(const BaseString &logstring) {
handler = new ConsoleLogHandler();
if(handler == NULL)
- return false;
+ DBUG_RETURN(false);
if(!handler->parseParams(params))
- return false;
+ DBUG_RETURN(false);
loghandlers.push_back(handler);
}
for(i = 0; i < loghandlers.size(); i++)
addHandler(loghandlers[i]);
- return true; /* @todo handle errors */
+ DBUG_RETURN(true); /* @todo handle errors */
}
bool
diff --git a/ndb/src/mgmsrv/InitConfigFileParser.cpp b/ndb/src/mgmsrv/InitConfigFileParser.cpp
index fdfe7823fc2..05102255eaa 100644
--- a/ndb/src/mgmsrv/InitConfigFileParser.cpp
+++ b/ndb/src/mgmsrv/InitConfigFileParser.cpp
@@ -213,48 +213,41 @@ InitConfigFileParser::parseConfig(FILE * file) {
// Parse Name-Value Pair
//****************************************************************************
-bool InitConfigFileParser::parseNameValuePair(Context& ctx, const char* line) {
-
- char tmpLine[MAX_LINE_LENGTH];
- char fname[MAX_LINE_LENGTH], rest[MAX_LINE_LENGTH];
- char* t;
- const char *separator_list[]= {":", "=", 0};
- const char *separator= 0;
-
+bool InitConfigFileParser::parseNameValuePair(Context& ctx, const char* line)
+{
if (ctx.m_currentSection == NULL){
ctx.reportError("Value specified outside section");
return false;
}
- strncpy(tmpLine, line, MAX_LINE_LENGTH);
-
// *************************************
- // Check if a separator exists in line
+ // Split string at first occurrence of
+ // '=' or ':'
// *************************************
- for(int i= 0; separator_list[i] != 0; i++) {
- if(strchr(tmpLine, separator_list[i][0])) {
- separator= separator_list[i];
- break;
- }
- }
- if (separator == 0) {
+ Vector tmp_string_split;
+ if (BaseString(line).split(tmp_string_split,
+ BaseString("=:"),
+ 2) != 2)
+ {
ctx.reportError("Parse error");
return false;
}
- // *******************************************
- // Get pointer to substring before separator
- // *******************************************
- t = strtok(tmpLine, separator);
-
- // *****************************************
- // Count number of tokens before separator
- // *****************************************
- if (sscanf(t, "%120s%120s", fname, rest) != 1) {
- ctx.reportError("Multiple names before \'%c\'", separator[0]);
- return false;
+ // *************************************
+ // Remove leading and trailing chars
+ // *************************************
+ {
+ for (int i = 0; i < 2; i++)
+ tmp_string_split[i].trim("\r\n \t");
}
+
+ // *************************************
+ // First in split is fname
+ // *************************************
+
+ const char *fname= tmp_string_split[0].c_str();
+
if (!ctx.m_currentInfo->contains(fname)) {
ctx.reportError("[%s] Unknown parameter: %s", ctx.fname, fname);
return false;
@@ -273,24 +266,11 @@ bool InitConfigFileParser::parseNameValuePair(Context& ctx, const char* line) {
}
}
- // ******************************************
- // Get pointer to substring after separator
- // ******************************************
- t = strtok(NULL, "\0");
- if (t == NULL) {
- ctx.reportError("No value for parameter");
- return false;
- }
-
- // ******************************************
- // Remove prefix and postfix spaces and tabs
- // *******************************************
- trim(t);
-
// ***********************
// Store name-value pair
// ***********************
- return storeNameValuePair(ctx, fname, t);
+
+ return storeNameValuePair(ctx, fname, tmp_string_split[1].c_str());
}
From 3d6e811ed556b63307383cccc44fd89afe493792 Mon Sep 17 00:00:00 2001
From: "bar@mysql.com" <>
Date: Thu, 25 Nov 2004 16:18:47 +0400
Subject: [PATCH 107/145] table.cc: Bug #6802 MySQL 4.0's VARCHAR(NN) BINARY
is interpreted as VARBINARY(NN) in 4.1
---
sql/table.cc | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/sql/table.cc b/sql/table.cc
index 20ac714020d..cb565097c0b 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -463,7 +463,26 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
/* old frm file */
field_type= (enum_field_types) f_packtype(pack_flag);
- charset=f_is_binary(pack_flag) ? &my_charset_bin : outparam->table_charset;
+ if (f_is_binary(pack_flag))
+ {
+ /*
+ Try to choose the best 4.1 type:
+ - for 4.0 "CHAR(N) BINARY" or "VARCHAR(N) BINARY"
+ try to find a binary collation for character set.
+ - for other types (e.g. BLOB) just use my_charset_bin.
+ */
+ if (!f_is_blob(pack_flag))
+ {
+ // 3.23 or 4.0 string
+ if (!(charset= get_charset_by_csname(outparam->table_charset->csname,
+ MY_CS_BINSORT, MYF(0))))
+ charset= &my_charset_bin;
+ }
+ else
+ charset= &my_charset_bin;
+ }
+ else
+ charset= outparam->table_charset;
bzero((char*) &comment, sizeof(comment));
}
*field_ptr=reg_field=
From 106f124eec733ef0cb1e771702bec0710d064b7f Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Thu, 25 Nov 2004 21:29:59 +0000
Subject: [PATCH 108/145] moved default setting to config.ini to MgmtSrvr only
try to connect to other ndb_mgmd if connect_string explicitly given or
config_file not given
---
ndb/src/mgmsrv/MgmtSrvr.cpp | 11 ++++++++---
ndb/src/mgmsrv/main.cpp | 1 -
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/ndb/src/mgmsrv/MgmtSrvr.cpp b/ndb/src/mgmsrv/MgmtSrvr.cpp
index 81b5eb9dfb3..986da71a8e8 100644
--- a/ndb/src/mgmsrv/MgmtSrvr.cpp
+++ b/ndb/src/mgmsrv/MgmtSrvr.cpp
@@ -432,15 +432,20 @@ MgmtSrvr::MgmtSrvr(SocketServer *socket_server,
theFacade = 0;
m_newConfig = NULL;
- m_configFilename.assign(config_filename);
+ if (config_filename)
+ m_configFilename.assign(config_filename);
+ else
+ m_configFilename.assign("config.ini");
m_nextConfigGenerationNumber = 0;
m_config_retriever= new ConfigRetriever(connect_string,
NDB_VERSION, NDB_MGM_NODE_TYPE_MGM);
-
+ // if connect_string explicitly given or
+ // no config filename is given then
// first try to allocate nodeid from another management server
- if(m_config_retriever->do_connect(0,0,0) == 0)
+ if ((connect_string || config_filename == NULL) &&
+ (m_config_retriever->do_connect(0,0,0) == 0))
{
int tmp_nodeid= 0;
tmp_nodeid= m_config_retriever->allocNodeId(0 /*retry*/,0 /*delay*/);
diff --git a/ndb/src/mgmsrv/main.cpp b/ndb/src/mgmsrv/main.cpp
index 1ab8cc0635e..400a5301a19 100644
--- a/ndb/src/mgmsrv/main.cpp
+++ b/ndb/src/mgmsrv/main.cpp
@@ -188,7 +188,6 @@ int main(int argc, char** argv)
#endif
global_mgmt_server_check = 1;
- glob.config_filename= "config.ini";
const char *load_default_groups[]= { "mysql_cluster","ndb_mgmd",0 };
load_defaults("my",load_default_groups,&argc,&argv);
From ccec75f9af0c021e36198714466c300afd58df74 Mon Sep 17 00:00:00 2001
From: "heikki@hundin.mysql.fi" <>
Date: Fri, 26 Nov 2004 00:12:50 +0200
Subject: [PATCH 109/145] Many files: Fix bug #6817 and bug #6827 : do not
crash the server if the buffer pool becomes filled by the locks of ONE huge
transaction, return error 1206 instead; do not crash the server, but return
error if we cannot allocate memory for the buffer pool at a mysqld startup
---
innobase/buf/buf0buf.c | 5 +++--
innobase/buf/buf0lru.c | 41 ++++++++++++++++++++++++++++++++++----
innobase/include/buf0lru.h | 10 ++++++++++
innobase/include/db0err.h | 6 +++++-
innobase/include/row0sel.h | 1 +
innobase/include/ut0mem.h | 4 +++-
innobase/mem/mem0pool.c | 2 +-
innobase/row/row0mysql.c | 3 ++-
innobase/row/row0sel.c | 11 ++++++++++
innobase/srv/srv0start.c | 3 +++
innobase/ut/ut0mem.c | 20 +++++++++++++------
11 files changed, 90 insertions(+), 16 deletions(-)
diff --git a/innobase/buf/buf0buf.c b/innobase/buf/buf0buf.c
index adb69f3c3a7..699ad5fb42e 100644
--- a/innobase/buf/buf0buf.c
+++ b/innobase/buf/buf0buf.c
@@ -547,8 +547,9 @@ buf_pool_init(
}
/*----------------------------------------*/
} else {
- buf_pool->frame_mem = ut_malloc(
- UNIV_PAGE_SIZE * (n_frames + 1));
+ buf_pool->frame_mem = ut_malloc_low(
+ UNIV_PAGE_SIZE * (n_frames + 1),
+ TRUE, FALSE);
}
if (buf_pool->frame_mem == NULL) {
diff --git a/innobase/buf/buf0lru.c b/innobase/buf/buf0lru.c
index 796311f0157..f3fb19ae183 100644
--- a/innobase/buf/buf0lru.c
+++ b/innobase/buf/buf0lru.c
@@ -42,6 +42,10 @@ initial segment in buf_LRU_get_recent_limit */
#define BUF_LRU_INITIAL_RATIO 8
+/* If we switch on the InnoDB monitor because there are too few available
+frames in the buffer pool, we set this to TRUE */
+ibool buf_lru_switched_on_innodb_mon = FALSE;
+
/**********************************************************************
Takes a block out of the LRU list and page hash table and sets the block
state to BUF_BLOCK_REMOVE_HASH. */
@@ -287,6 +291,32 @@ buf_LRU_try_free_flushed_blocks(void)
mutex_exit(&(buf_pool->mutex));
}
+/**********************************************************************
+Returns TRUE if less than 15 % of the buffer pool is available. This can be
+used in heuristics to prevent huge transactions eating up the whole buffer
+pool for their locks. */
+
+ibool
+buf_LRU_buf_pool_running_out(void)
+/*==============================*/
+ /* out: TRUE if less than 15 % of buffer pool
+ left */
+{
+ ibool ret = FALSE;
+
+ mutex_enter(&(buf_pool->mutex));
+
+ if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free)
+ + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 7) {
+
+ ret = TRUE;
+ }
+
+ mutex_exit(&(buf_pool->mutex));
+
+ return(ret);
+}
+
/**********************************************************************
Returns a free block from buf_pool. The block is taken off the free list.
If it is empty, blocks are moved from the end of the LRU list to the free
@@ -325,7 +355,8 @@ loop:
} else if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free)
+ UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 5) {
- if (!srv_print_innodb_monitor) {
+
+ if (!buf_lru_switched_on_innodb_mon) {
/* Over 80 % of the buffer pool is occupied by lock
heaps or the adaptive hash index. This may be a memory
@@ -342,16 +373,18 @@ loop:
"InnoDB: lock heap and hash index sizes.\n",
(ulong) (buf_pool->curr_size / (1024 * 1024 / UNIV_PAGE_SIZE)));
+ buf_lru_switched_on_innodb_mon = TRUE;
srv_print_innodb_monitor = TRUE;
os_event_set(srv_lock_timeout_thread_event);
}
- } else if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free)
- + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 4) {
+ } else if (buf_lru_switched_on_innodb_mon) {
/* Switch off the InnoDB Monitor; this is a simple way
to stop the monitor if the situation becomes less urgent,
- but may also surprise users! */
+ but may also surprise users if the user also switched on the
+ monitor! */
+ buf_lru_switched_on_innodb_mon = FALSE;
srv_print_innodb_monitor = FALSE;
}
diff --git a/innobase/include/buf0lru.h b/innobase/include/buf0lru.h
index 69a376f8cab..45164dd561e 100644
--- a/innobase/include/buf0lru.h
+++ b/innobase/include/buf0lru.h
@@ -25,6 +25,16 @@ wasted. */
void
buf_LRU_try_free_flushed_blocks(void);
/*==================================*/
+/**********************************************************************
+Returns TRUE if less than 15 % of the buffer pool is available. This can be
+used in heuristics to prevent huge transactions eating up the whole buffer
+pool for their locks. */
+
+ibool
+buf_LRU_buf_pool_running_out(void);
+/*==============================*/
+ /* out: TRUE if less than 15 % of buffer pool
+ left */
/*#######################################################################
These are low-level functions
diff --git a/innobase/include/db0err.h b/innobase/include/db0err.h
index be7667bfd0c..de5ac44e73f 100644
--- a/innobase/include/db0err.h
+++ b/innobase/include/db0err.h
@@ -53,7 +53,11 @@ Created 5/24/1996 Heikki Tuuri
name already exists */
#define DB_TABLESPACE_DELETED 44 /* tablespace does not exist or is
being dropped right now */
-
+#define DB_LOCK_TABLE_FULL 45 /* lock structs have exhausted the
+ buffer pool (for big transactions,
+ InnoDB stores the lock structs in the
+ buffer pool) */
+
/* The following are partial failure codes */
#define DB_FAIL 1000
#define DB_OVERFLOW 1001
diff --git a/innobase/include/row0sel.h b/innobase/include/row0sel.h
index bb6fb70ca86..8d5187bfc1c 100644
--- a/innobase/include/row0sel.h
+++ b/innobase/include/row0sel.h
@@ -120,6 +120,7 @@ row_search_for_mysql(
/* out: DB_SUCCESS,
DB_RECORD_NOT_FOUND,
DB_END_OF_INDEX, DB_DEADLOCK,
+ DB_LOCK_TABLE_FULL,
or DB_TOO_BIG_RECORD */
byte* buf, /* in/out: buffer for the fetched
row in the MySQL format */
diff --git a/innobase/include/ut0mem.h b/innobase/include/ut0mem.h
index 73ecb25101a..74357f6bf13 100644
--- a/innobase/include/ut0mem.h
+++ b/innobase/include/ut0mem.h
@@ -38,8 +38,10 @@ ut_malloc_low(
/*==========*/
/* out, own: allocated memory */
ulint n, /* in: number of bytes to allocate */
- ibool set_to_zero); /* in: TRUE if allocated memory should be set
+ ibool set_to_zero, /* in: TRUE if allocated memory should be set
to zero if UNIV_SET_MEM_TO_ZERO is defined */
+ ibool assert_on_error); /* in: if TRUE, we crash mysqld if the memory
+ cannot be allocated */
/**************************************************************************
Allocates memory. Sets it also to zero if UNIV_SET_MEM_TO_ZERO is
defined. */
diff --git a/innobase/mem/mem0pool.c b/innobase/mem/mem0pool.c
index 023369e8ec5..cb891a03092 100644
--- a/innobase/mem/mem0pool.c
+++ b/innobase/mem/mem0pool.c
@@ -199,7 +199,7 @@ mem_pool_create(
but only when allocated at a higher level in mem0mem.c.
This is to avoid masking useful Purify warnings. */
- pool->buf = ut_malloc_low(size, FALSE);
+ pool->buf = ut_malloc_low(size, FALSE, TRUE);
pool->size = size;
mutex_create(&(pool->mutex));
diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c
index 17747ae2a8e..9613da2e286 100644
--- a/innobase/row/row0mysql.c
+++ b/innobase/row/row0mysql.c
@@ -308,7 +308,8 @@ handle_new_error:
return(TRUE);
- } else if (err == DB_DEADLOCK || err == DB_LOCK_WAIT_TIMEOUT) {
+ } else if (err == DB_DEADLOCK || err == DB_LOCK_WAIT_TIMEOUT
+ || err == DB_LOCK_TABLE_FULL) {
/* Roll back the whole transaction; this resolution was added
to version 3.23.43 */
diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c
index 5b7d068d0c1..edaa555c555 100644
--- a/innobase/row/row0sel.c
+++ b/innobase/row/row0sel.c
@@ -730,8 +730,18 @@ sel_set_rec_lock(
ulint type, /* in: LOCK_ORDINARY, LOCK_GAP, or LOC_REC_NOT_GAP */
que_thr_t* thr) /* in: query thread */
{
+ trx_t* trx;
ulint err;
+ trx = thr_get_trx(thr);
+
+ if (UT_LIST_GET_LEN(trx->trx_locks) > 10000) {
+ if (buf_LRU_buf_pool_running_out()) {
+
+ return(DB_LOCK_TABLE_FULL);
+ }
+ }
+
if (index->type & DICT_CLUSTERED) {
err = lock_clust_rec_read_check_and_lock(0, rec, index, mode,
type, thr);
@@ -2765,6 +2775,7 @@ row_search_for_mysql(
/* out: DB_SUCCESS,
DB_RECORD_NOT_FOUND,
DB_END_OF_INDEX, DB_DEADLOCK,
+ DB_LOCK_TABLE_FULL,
or DB_TOO_BIG_RECORD */
byte* buf, /* in/out: buffer for the fetched
row in the MySQL format */
diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c
index 9709f5235de..69341a1d7d1 100644
--- a/innobase/srv/srv0start.c
+++ b/innobase/srv/srv0start.c
@@ -1172,6 +1172,9 @@ NetWare. */
}
if (ret == NULL) {
+ fprintf(stderr,
+"InnoDB: Fatal error: cannot allocate the memory for the buffer pool\n");
+
return(DB_ERROR);
}
diff --git a/innobase/ut/ut0mem.c b/innobase/ut/ut0mem.c
index a6002d7fd83..6ed61b0b5de 100644
--- a/innobase/ut/ut0mem.c
+++ b/innobase/ut/ut0mem.c
@@ -61,8 +61,10 @@ ut_malloc_low(
/*==========*/
/* out, own: allocated memory */
ulint n, /* in: number of bytes to allocate */
- ibool set_to_zero) /* in: TRUE if allocated memory should be set
+ ibool set_to_zero, /* in: TRUE if allocated memory should be set
to zero if UNIV_SET_MEM_TO_ZERO is defined */
+ ibool assert_on_error) /* in: if TRUE, we crash mysqld if the memory
+ cannot be allocated */
{
void* ret;
@@ -86,9 +88,7 @@ ut_malloc_low(
"InnoDB: Check if you should increase the swap file or\n"
"InnoDB: ulimits of your operating system.\n"
"InnoDB: On FreeBSD check you have compiled the OS with\n"
- "InnoDB: a big enough maximum process size.\n"
- "InnoDB: We now intentionally generate a seg fault so that\n"
- "InnoDB: on Linux we get a stack trace.\n",
+ "InnoDB: a big enough maximum process size.\n",
(ulong) n, (ulong) ut_total_allocated_memory,
#ifdef __WIN__
(ulong) GetLastError()
@@ -110,7 +110,15 @@ ut_malloc_low(
/* Intentional segfault on NetWare causes an abend. Avoid this
by graceful exit handling in ut_a(). */
#if (!defined __NETWARE__)
- if (*ut_mem_null_ptr) ut_mem_null_ptr = 0;
+ if (assert_on_error) {
+ fprintf(stderr,
+ "InnoDB: We now intentionally generate a seg fault so that\n"
+ "InnoDB: on Linux we get a stack trace.\n");
+
+ if (*ut_mem_null_ptr) ut_mem_null_ptr = 0;
+ } else {
+ return(NULL);
+ }
#else
ut_a(0);
#endif
@@ -144,7 +152,7 @@ ut_malloc(
/* out, own: allocated memory */
ulint n) /* in: number of bytes to allocate */
{
- return(ut_malloc_low(n, TRUE));
+ return(ut_malloc_low(n, TRUE, TRUE));
}
/**************************************************************************
From 14b60dfce4a8c84d5d66fa91f5fa4256633540c4 Mon Sep 17 00:00:00 2001
From: "heikki@hundin.mysql.fi" <>
Date: Fri, 26 Nov 2004 00:26:35 +0200
Subject: [PATCH 110/145] ha_innodb.cc: Add conversion of the InnoDB error
DB_LOCK_TABLE_FULL to the corresponding MySQL error
---
sql/ha_innodb.cc | 3 +++
1 file changed, 3 insertions(+)
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 07d8da63733..2515b4956d0 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -331,6 +331,9 @@ convert_error_code_to_mysql(
} else if (error == (int) DB_NO_SAVEPOINT) {
return(HA_ERR_NO_SAVEPOINT);
+ } else if (error == (int) DB_LOCK_TABLE_FULL) {
+
+ return(HA_ERR_LOCK_TABLE_FULL);
} else {
return(-1); // Unknown error
}
From eb304bd49f3228352a328d158db37c61f4cccd93 Mon Sep 17 00:00:00 2001
From: "monty@mysql.com" <>
Date: Fri, 26 Nov 2004 02:31:22 +0200
Subject: [PATCH 111/145] Fixes while reviewing code (Cleanups and better bug
fixes)
---
mysql-test/r/select.result | 32 +++++++++++++--------------
mysql-test/t/select.test | 2 +-
scripts/mysql_fix_privilege_tables.sh | 2 +-
sql/item_cmpfunc.cc | 7 +++---
sql/item_cmpfunc.h | 3 ---
sql/item_func.h | 2 +-
sql/slave.cc | 3 ++-
7 files changed, 25 insertions(+), 26 deletions(-)
diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result
index 3dd0603ed09..cc90547722f 100644
--- a/mysql-test/r/select.result
+++ b/mysql-test/r/select.result
@@ -2327,22 +2327,6 @@ select * from t2,t3 where t2.s = t3.s;
s s
two two
drop table t1, t2, t3;
-CREATE TABLE t1 (
-i int(11) NOT NULL default '0',
-c char(10) NOT NULL default '',
-PRIMARY KEY (i),
-UNIQUE KEY c (c)
-) TYPE=MyISAM;
-INSERT INTO t1 VALUES (1,'a');
-INSERT INTO t1 VALUES (2,'b');
-INSERT INTO t1 VALUES (3,'c');
-EXPLAIN SELECT i FROM t1 WHERE i=1;
-table type possible_keys key key_len ref rows Extra
-t1 const PRIMARY PRIMARY 4 const 1 Using index
-EXPLAIN SELECT i FROM t1 WHERE i=1;
-table type possible_keys key key_len ref rows Extra
-t1 const PRIMARY PRIMARY 4 const 1 Using index
-DROP TABLE t1;
create table t1 (a integer, b integer, index(a), index(b));
create table t2 (c integer, d integer, index(c), index(d));
insert into t1 values (1,2), (2,2), (3,2), (4,2);
@@ -2364,3 +2348,19 @@ a b c d
3 2 3 4
4 2 4 4
drop table t1, t2;
+CREATE TABLE t1 (
+i int(11) NOT NULL default '0',
+c char(10) NOT NULL default '',
+PRIMARY KEY (i),
+UNIQUE KEY c (c)
+) TYPE=MyISAM;
+INSERT INTO t1 VALUES (1,'a');
+INSERT INTO t1 VALUES (2,'b');
+INSERT INTO t1 VALUES (3,'c');
+EXPLAIN SELECT i FROM t1 WHERE i=1;
+table type possible_keys key key_len ref rows Extra
+t1 const PRIMARY PRIMARY 4 const 1 Using index
+EXPLAIN SELECT i FROM t1 WHERE i=1;
+table type possible_keys key key_len ref rows Extra
+t1 const PRIMARY PRIMARY 4 const 1 Using index
+DROP TABLE t1;
diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test
index f897703789b..e6b1ffbe8d7 100644
--- a/mysql-test/t/select.test
+++ b/mysql-test/t/select.test
@@ -1887,7 +1887,7 @@ explain select * from t1 left join t2 on a=c where d in (4);
select * from t1 left join t2 on a=c where d in (4);
explain select * from t1 left join t2 on a=c where d = 4;
select * from t1 left join t2 on a=c where d = 4;
-drop table t1, t2;R
+drop table t1, t2;
#
# Covering index is mentioned in EXPLAIN output for const tables (bug #5333)
diff --git a/scripts/mysql_fix_privilege_tables.sh b/scripts/mysql_fix_privilege_tables.sh
index 2fbcd76c318..381cf599e32 100644
--- a/scripts/mysql_fix_privilege_tables.sh
+++ b/scripts/mysql_fix_privilege_tables.sh
@@ -74,7 +74,7 @@ parse_arguments()
parse_arguments "$@"
if test -z "$cmd"; then
- cmd="$bindir/mysql -f --user=$user --host=$host"
+ cmd="$bindir/mysql --no-defaults --force --user=$user --host=$host"
if test ! -z "$root_password"; then
cmd="$cmd --password=$root_password"
fi
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index fbc1ad97e76..107a17815ae 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -293,9 +293,9 @@ void Item_func_interval::fix_length_and_dec()
}
maybe_null=0; max_length=2;
used_tables_cache|= item->used_tables();
- not_null_tables_cache&= item->not_null_tables();
+ not_null_tables_cache= item->not_null_tables();
with_sum_func= with_sum_func || item->with_sum_func;
- const_item_cache&=item->const_item();
+ const_item_cache&= item->const_item();
}
@@ -1087,7 +1087,8 @@ void Item_func_in::fix_length_and_dec()
maybe_null= item->maybe_null;
max_length=2;
used_tables_cache|= item->used_tables();
- not_null_tables_cache&= item->not_null_tables();
+ /* not_null_tables_cache is only dependent on the argument to in */
+ not_null_tables_cache= item->not_null_tables();
const_item_cache&= item->const_item();
}
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index d36429ab61e..8f1aa525190 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -432,9 +432,6 @@ class Item_func_in :public Item_int_func
{
bool res= (item->fix_fields(thd,tlist) || Item_func::fix_fields(thd,tlist));
with_sum_func= with_sum_func || item->with_sum_func;
- used_tables_cache|= item->used_tables();
- not_null_tables_cache|= item->not_null_tables();
- const_item_cache&= item->const_item();
return res;
}
void fix_length_and_dec();
diff --git a/sql/item_func.h b/sql/item_func.h
index 8a013f42c05..3627af4ebb1 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -600,7 +600,7 @@ public:
{
maybe_null=0; max_length=3;
used_tables_cache|= item->used_tables();
- not_null_tables_cache&= item->not_null_tables();
+ not_null_tables_cache= item->not_null_tables();
const_item_cache&= item->const_item();
with_sum_func= with_sum_func || item->with_sum_func;
}
diff --git a/sql/slave.cc b/sql/slave.cc
index 7e544572755..b0f911e7013 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -1637,7 +1637,8 @@ int init_master_info(MASTER_INFO* mi, const char* master_info_fname,
position is at the beginning of the file, and will read the
"signature" and then fast-forward to the last position read.
*/
- if (thread_mask & SLAVE_SQL) {
+ if (thread_mask & SLAVE_SQL)
+ {
my_b_seek(mi->rli.cur_log, (my_off_t) 0);
}
DBUG_RETURN(0);
From 4d52d9e50f012764573fe89b6ddaad86a2ddc9c8 Mon Sep 17 00:00:00 2001
From: "joreland@mysql.com" <>
Date: Fri, 26 Nov 2004 10:00:33 +0100
Subject: [PATCH 112/145] ndb - bugfix testScanPerf
---
ndb/test/ndbapi/testScanPerf.cpp | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/ndb/test/ndbapi/testScanPerf.cpp b/ndb/test/ndbapi/testScanPerf.cpp
index ee2a92e88a9..45f0468bc70 100644
--- a/ndb/test/ndbapi/testScanPerf.cpp
+++ b/ndb/test/ndbapi/testScanPerf.cpp
@@ -222,6 +222,7 @@ run_scan(){
int sum_time= 0;
int sample_rows = 0;
+ int tot_rows = 0;
NDB_TICKS sample_start = NdbTick_CurrentMillisecond();
Uint32 tot = g_paramters[P_ROWS].value;
@@ -296,7 +297,7 @@ run_scan(){
break;
}
}
- if(g_paramters[P_RESET].value == 1)
+ if(g_paramters[P_RESET].value == 2)
goto execute;
}
assert(pOp);
@@ -330,6 +331,9 @@ run_scan(){
}
assert(check == 0);
+ if(g_paramters[P_RESET].value == 1)
+ g_paramters[P_RESET].value = 2;
+
for(int i = 0; igetNoOfColumns(); i++){
pOp->getValue(i);
}
@@ -364,6 +368,7 @@ execute:
int time_passed= (int)(stop - start1);
sample_rows += rows;
sum_time+= time_passed;
+ tot_rows+= rows;
if(sample_rows >= tot)
{
@@ -375,8 +380,8 @@ execute:
sample_start = stop;
}
}
-
- g_err.println("Avg time: %d ms = %u rows/sec", sum_time/iter,
- (1000*tot*iter)/sum_time);
+
+ g_err.println("Avg time: %d ms = %u rows/sec", sum_time/tot_rows,
+ (1000*tot_rows)/sum_time);
return 0;
}
From 8c3144c133626ef728bc3d611320c3852b1d1da3 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Fri, 26 Nov 2004 09:44:57 +0000
Subject: [PATCH 113/145] cleaned up code a bit added command CONNECT
in management client added some verbose printouts removed prompt
printout on !isatty(0)
---
ndb/src/mgmapi/mgmapi.cpp | 22 ++++--
ndb/src/mgmclient/CommandInterpreter.cpp | 97 +++++++++++++-----------
ndb/src/mgmclient/main.cpp | 19 +++--
ndb/src/mgmclient/ndb_mgmclient.hpp | 2 +-
4 files changed, 81 insertions(+), 59 deletions(-)
diff --git a/ndb/src/mgmapi/mgmapi.cpp b/ndb/src/mgmapi/mgmapi.cpp
index ca3a2a2186d..831d14eac52 100644
--- a/ndb/src/mgmapi/mgmapi.cpp
+++ b/ndb/src/mgmapi/mgmapi.cpp
@@ -379,18 +379,30 @@ ndb_mgm_connect(NdbMgmHandle handle, int no_retries,
setError(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, __LINE__,
"Unable to connect with connect string: %s",
cfg.makeConnectString(buf,sizeof(buf)));
+ if (verbose == -2)
+ ndbout << ", failed." << endl;
return -1;
}
if (verbose == -1) {
- ndbout << "retrying every " << retry_delay_in_seconds << " seconds:";
+ ndbout << "Retrying every " << retry_delay_in_seconds << " seconds";
+ if (no_retries > 0)
+ ndbout << ". Attempts left:";
+ else
+ ndbout << ", until connected.";;
+ ndbout << flush;
verbose= -2;
}
- NdbSleep_SecSleep(retry_delay_in_seconds);
- if (verbose == -2) {
- ndbout << " " << no_retries;
+ if (no_retries > 0) {
+ if (verbose == -2) {
+ ndbout << " " << no_retries;
+ ndbout << flush;
+ }
+ no_retries--;
}
- no_retries--;
+ NdbSleep_SecSleep(retry_delay_in_seconds);
}
+ if (verbose == -2)
+ ndbout << endl;
handle->cfg_i = i;
diff --git a/ndb/src/mgmclient/CommandInterpreter.cpp b/ndb/src/mgmclient/CommandInterpreter.cpp
index 54beaa49d3f..bfe8b6786b4 100644
--- a/ndb/src/mgmclient/CommandInterpreter.cpp
+++ b/ndb/src/mgmclient/CommandInterpreter.cpp
@@ -44,7 +44,7 @@ public:
* Constructor
* @param mgmtSrvr: Management server to use when executing commands
*/
- CommandInterpreter(const char *);
+ CommandInterpreter(const char *, int verbose);
~CommandInterpreter();
/**
@@ -94,6 +94,7 @@ private:
*/
void executeHelp(char* parameters);
void executeShow(char* parameters);
+ void executeConnect(char* parameters);
void executePurge(char* parameters);
void executeShutdown(char* parameters);
void executeRun(char* parameters);
@@ -153,6 +154,7 @@ private:
NdbMgmHandle m_mgmsrv;
bool connected;
+ int m_verbose;
int try_reconnect;
#ifdef HAVE_GLOBAL_REPLICATION
NdbRepHandle m_repserver;
@@ -169,9 +171,9 @@ private:
#include "ndb_mgmclient.hpp"
#include "ndb_mgmclient.h"
-Ndb_mgmclient::Ndb_mgmclient(const char *host)
+Ndb_mgmclient::Ndb_mgmclient(const char *host,int verbose)
{
- m_cmd= new CommandInterpreter(host);
+ m_cmd= new CommandInterpreter(host,verbose);
}
Ndb_mgmclient::~Ndb_mgmclient()
{
@@ -275,6 +277,7 @@ static const char* helpText =
"REP CONNECT Connect to REP server on host:port\n"
#endif
"PURGE STALE SESSIONS Reset reserved nodeid's in the mgmt server\n"
+"CONNECT Connect to management server (reconnect if already connected)\n"
"QUIT Quit management client\n"
;
@@ -373,7 +376,8 @@ convert(const char* s, int& val) {
/*
* Constructor
*/
-CommandInterpreter::CommandInterpreter(const char *_host)
+CommandInterpreter::CommandInterpreter(const char *_host,int verbose)
+ : m_verbose(verbose)
{
m_mgmsrv = ndb_mgm_create_handle();
if(m_mgmsrv == NULL) {
@@ -437,7 +441,15 @@ CommandInterpreter::connect()
{
if(!connected) {
if(!ndb_mgm_connect(m_mgmsrv, try_reconnect-1, 5, 1))
+ {
connected = true;
+ if (m_verbose)
+ {
+ printf("Connected to Management Server at: %s:%d\n",
+ ndb_mgm_get_connected_host(m_mgmsrv),
+ ndb_mgm_get_connected_port(m_mgmsrv));
+ }
+ }
}
return connected;
}
@@ -445,7 +457,7 @@ CommandInterpreter::connect()
bool
CommandInterpreter::disconnect()
{
- if (ndb_mgm_disconnect(m_mgmsrv) == -1) {
+ if (connected && (ndb_mgm_disconnect(m_mgmsrv) == -1)) {
ndbout_c("Could not disconnect from management server");
printError();
}
@@ -459,18 +471,21 @@ CommandInterpreter::disconnect()
int
CommandInterpreter::execute(const char *_line, int _try_reconnect)
{
+ DBUG_ENTER("CommandInterpreter::execute");
+ DBUG_PRINT("info",("line=\"%s\"",_line));
+
if (_try_reconnect >= 0)
try_reconnect=_try_reconnect;
char * line;
if(_line == NULL) {
// ndbout << endl;
- return false;
+ DBUG_RETURN(false);
}
line = my_strdup(_line,MYF(MY_WME));
My_auto_ptr ptr(line);
if (emptyString(line)) {
- return true;
+ DBUG_RETURN(true);
}
for (unsigned int i = 0; i < strlen(line); ++i) {
@@ -484,41 +499,49 @@ CommandInterpreter::execute(const char *_line, int _try_reconnect)
if (strcmp(firstToken, "HELP") == 0 ||
strcmp(firstToken, "?") == 0) {
executeHelp(allAfterFirstToken);
- return true;
+ DBUG_RETURN(true);
}
- else if (strcmp(firstToken, "SHOW") == 0) {
+ else if (strcmp(firstToken, "CONNECT") == 0) {
+ executeConnect(allAfterFirstToken);
+ DBUG_RETURN(true);
+ }
+
+ if (!connect())
+ DBUG_RETURN(true);
+
+ if (strcmp(firstToken, "SHOW") == 0) {
executeShow(allAfterFirstToken);
- return true;
+ DBUG_RETURN(true);
}
else if (strcmp(firstToken, "SHUTDOWN") == 0) {
executeShutdown(allAfterFirstToken);
- return true;
+ DBUG_RETURN(true);
}
else if (strcmp(firstToken, "CLUSTERLOG") == 0){
executeClusterLog(allAfterFirstToken);
- return true;
+ DBUG_RETURN(true);
}
else if(strcmp(firstToken, "START") == 0 &&
allAfterFirstToken != NULL &&
strncmp(allAfterFirstToken, "BACKUP", sizeof("BACKUP") - 1) == 0){
executeStartBackup(allAfterFirstToken);
- return true;
+ DBUG_RETURN(true);
}
else if(strcmp(firstToken, "ABORT") == 0 &&
allAfterFirstToken != NULL &&
strncmp(allAfterFirstToken, "BACKUP", sizeof("BACKUP") - 1) == 0){
executeAbortBackup(allAfterFirstToken);
- return true;
+ DBUG_RETURN(true);
}
else if (strcmp(firstToken, "PURGE") == 0) {
executePurge(allAfterFirstToken);
- return true;
+ DBUG_RETURN(true);
}
#ifdef HAVE_GLOBAL_REPLICATION
else if(strcmp(firstToken, "REPLICATION") == 0 ||
strcmp(firstToken, "REP") == 0) {
executeRep(allAfterFirstToken);
- return true;
+ DBUG_RETURN(true);
}
#endif // HAVE_GLOBAL_REPLICATION
else if(strcmp(firstToken, "ENTER") == 0 &&
@@ -526,14 +549,14 @@ CommandInterpreter::execute(const char *_line, int _try_reconnect)
strncmp(allAfterFirstToken, "SINGLE USER MODE ",
sizeof("SINGLE USER MODE") - 1) == 0){
executeEnterSingleUser(allAfterFirstToken);
- return true;
+ DBUG_RETURN(true);
}
else if(strcmp(firstToken, "EXIT") == 0 &&
allAfterFirstToken != NULL &&
strncmp(allAfterFirstToken, "SINGLE USER MODE ",
sizeof("SINGLE USER MODE") - 1) == 0){
executeExitSingleUser(allAfterFirstToken);
- return true;
+ DBUG_RETURN(true);
}
else if (strcmp(firstToken, "ALL") == 0) {
analyseAfterFirstToken(-1, allAfterFirstToken);
@@ -542,7 +565,7 @@ CommandInterpreter::execute(const char *_line, int _try_reconnect)
strcmp(firstToken, "EXIT") == 0 ||
strcmp(firstToken, "BYE") == 0) &&
allAfterFirstToken == NULL){
- return false;
+ DBUG_RETURN(false);
} else {
/**
* First token should be a digit, node ID
@@ -552,18 +575,18 @@ CommandInterpreter::execute(const char *_line, int _try_reconnect)
if (! convert(firstToken, nodeId)) {
ndbout << "Invalid command: " << line << endl;
ndbout << "Type HELP for help." << endl << endl;
- return true;
+ DBUG_RETURN(true);
}
if (nodeId < 0) {
ndbout << "Invalid node ID: " << firstToken << "." << endl;
- return true;
+ DBUG_RETURN(true);
}
analyseAfterFirstToken(nodeId, allAfterFirstToken);
}
- return true;
+ DBUG_RETURN(true);
}
@@ -692,7 +715,6 @@ CommandInterpreter::executeForAll(const char * cmd, ExecuteFunction fun,
ndbout_c("Trying to start all nodes of system.");
ndbout_c("Use ALL STATUS to see the system start-up phases.");
} else {
- connect();
struct ndb_mgm_cluster_state *cl= ndb_mgm_get_status(m_mgmsrv);
if(cl == 0){
ndbout_c("Unable get status from management server");
@@ -826,8 +848,6 @@ CommandInterpreter::executeHelp(char* parameters)
void
CommandInterpreter::executeShutdown(char* parameters)
{
- connect();
-
ndb_mgm_cluster_state *state = ndb_mgm_get_status(m_mgmsrv);
if(state == NULL) {
ndbout_c("Could not get status");
@@ -979,7 +999,6 @@ CommandInterpreter::executePurge(char* parameters)
int i;
char *str;
- connect();
if (ndb_mgm_purge_stale_sessions(m_mgmsrv, &str)) {
ndbout_c("Command failed");
@@ -999,7 +1018,6 @@ void
CommandInterpreter::executeShow(char* parameters)
{
int i;
- connect();
if (emptyString(parameters)) {
ndbout << "Cluster Configuration" << endl
<< "---------------------" << endl;
@@ -1087,6 +1105,12 @@ CommandInterpreter::executeShow(char* parameters)
}
}
+void
+CommandInterpreter::executeConnect(char* parameters)
+{
+ disconnect();
+ connect();
+}
//*****************************************************************************
//*****************************************************************************
@@ -1094,7 +1118,6 @@ void
CommandInterpreter::executeClusterLog(char* parameters)
{
int i;
- connect();
if (parameters != 0 && strlen(parameters) != 0) {
enum ndb_mgm_clusterlog_level severity = NDB_MGM_CLUSTERLOG_ALL;
int isOk = true;
@@ -1240,7 +1263,6 @@ CommandInterpreter::executeClusterLog(char* parameters)
void
CommandInterpreter::executeStop(int processId, const char *, bool all)
{
- connect();
int result = 0;
if(all) {
result = ndb_mgm_stop(m_mgmsrv, 0, 0);
@@ -1262,7 +1284,6 @@ CommandInterpreter::executeStop(int processId, const char *, bool all)
void
CommandInterpreter::executeEnterSingleUser(char* parameters)
{
- connect();
strtok(parameters, " ");
struct ndb_mgm_reply reply;
char* id = strtok(NULL, " ");
@@ -1289,7 +1310,6 @@ CommandInterpreter::executeEnterSingleUser(char* parameters)
void
CommandInterpreter::executeExitSingleUser(char* parameters)
{
- connect();
int result = ndb_mgm_exit_single_user(m_mgmsrv, 0);
if (result != 0) {
ndbout_c("Exiting single user mode failed.");
@@ -1304,7 +1324,6 @@ void
CommandInterpreter::executeStart(int processId, const char* parameters,
bool all)
{
- connect();
int result;
if(all) {
result = ndb_mgm_start(m_mgmsrv, 0, 0);
@@ -1328,7 +1347,6 @@ void
CommandInterpreter::executeRestart(int processId, const char* parameters,
bool all)
{
- connect();
int result;
int nostart = 0;
int initialstart = 0;
@@ -1378,7 +1396,6 @@ CommandInterpreter::executeDumpState(int processId, const char* parameters,
ndbout << "Expected argument" << endl;
return;
}
- connect();
Uint32 no = 0;
int pars[25];
@@ -1418,7 +1435,6 @@ CommandInterpreter::executeStatus(int processId,
return;
}
- connect();
ndb_mgm_node_status status;
Uint32 startPhase, version;
bool system;
@@ -1469,7 +1485,6 @@ void
CommandInterpreter::executeLogLevel(int processId, const char* parameters,
bool all)
{
- connect();
(void) all;
BaseString tmp(parameters);
@@ -1525,7 +1540,6 @@ void CommandInterpreter::executeError(int processId,
return;
}
- connect();
// Copy parameters since strtok will modify it
char* newpar = my_strdup(parameters,MYF(MY_WME));
My_auto_ptr ap1(newpar);
@@ -1589,7 +1603,6 @@ void
CommandInterpreter::executeLog(int processId,
const char* parameters, bool all)
{
- connect();
struct ndb_mgm_reply reply;
Vector blocks;
if (! parseBlockSpecification(parameters, blocks)) {
@@ -1657,7 +1670,6 @@ CommandInterpreter::executeTestOn(int processId,
ndbout << "No parameters expected to this command." << endl;
return;
}
- connect();
struct ndb_mgm_reply reply;
int result = ndb_mgm_start_signallog(m_mgmsrv, processId, &reply);
if (result != 0) {
@@ -1676,7 +1688,6 @@ CommandInterpreter::executeTestOff(int processId,
ndbout << "No parameters expected to this command." << endl;
return;
}
- connect();
struct ndb_mgm_reply reply;
int result = ndb_mgm_stop_signallog(m_mgmsrv, processId, &reply);
if (result != 0) {
@@ -1798,8 +1809,6 @@ CommandInterpreter::executeEventReporting(int processId,
ndbout << "Expected argument" << endl;
return;
}
- connect();
-
BaseString tmp(parameters);
Vector spec;
tmp.split(spec, "=");
@@ -1850,7 +1859,6 @@ CommandInterpreter::executeEventReporting(int processId,
void
CommandInterpreter::executeStartBackup(char* /*parameters*/)
{
- connect();
struct ndb_mgm_reply reply;
unsigned int backupId;
@@ -1897,8 +1905,6 @@ CommandInterpreter::executeStartBackup(char* /*parameters*/)
void
CommandInterpreter::executeAbortBackup(char* parameters)
{
- connect();
-
strtok(parameters, " ");
struct ndb_mgm_reply reply;
char* id = strtok(NULL, "\0");
@@ -1952,7 +1958,6 @@ CommandInterpreter::executeRep(char* parameters)
return;
}
- connect();
char * line = my_strdup(parameters,MYF(MY_WME));
My_auto_ptr ap1((char*)line);
char * firstToken = strtok(line, " ");
diff --git a/ndb/src/mgmclient/main.cpp b/ndb/src/mgmclient/main.cpp
index f32cc683296..08d5d60cfab 100644
--- a/ndb/src/mgmclient/main.cpp
+++ b/ndb/src/mgmclient/main.cpp
@@ -56,17 +56,18 @@ handler(int sig){
}
}
-
+static const char default_prompt[]= "ndb_mgm> ";
static unsigned _try_reconnect;
static char *opt_connect_str= 0;
+static const char *prompt= default_prompt;
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",
+ "Specify number of tries for connecting to ndb_mgmd (0 = infinite)",
(gptr*) &_try_reconnect, (gptr*) &_try_reconnect, 0,
- GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+ GET_UINT, REQUIRED_ARG, 3, 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)
@@ -116,13 +117,13 @@ read_and_execute(int _try_reconnect)
}
#ifdef HAVE_READLINE
/* Get a line from the user. */
- line_read = readline ("ndb_mgm> ");
+ line_read = readline (prompt);
/* If the line has any text in it, save it on the history. */
if (line_read && *line_read)
add_history (line_read);
#else
static char linebuffer[254];
- fputs("ndb_mgm> ", stdout);
+ fputs(prompt, stdout);
linebuffer[sizeof(linebuffer)-1]=0;
line_read = fgets(linebuffer, sizeof(linebuffer)-1, stdin);
if (line_read == linebuffer) {
@@ -155,12 +156,16 @@ int main(int argc, char** argv){
opt_connect_str= buf;
}
+ if (!isatty(0))
+ {
+ prompt= 0;
+ }
+
ndbout << "-- NDB Cluster -- Management Client --" << endl;
- printf("Connecting to Management Server: %s\n", opt_connect_str ? opt_connect_str : "default");
signal(SIGPIPE, handler);
- com = new Ndb_mgmclient(opt_connect_str);
+ com = new Ndb_mgmclient(opt_connect_str,1);
while(read_and_execute(_try_reconnect));
delete com;
diff --git a/ndb/src/mgmclient/ndb_mgmclient.hpp b/ndb/src/mgmclient/ndb_mgmclient.hpp
index f6bcebc3896..ea592dfdf4e 100644
--- a/ndb/src/mgmclient/ndb_mgmclient.hpp
+++ b/ndb/src/mgmclient/ndb_mgmclient.hpp
@@ -21,7 +21,7 @@ class CommandInterpreter;
class Ndb_mgmclient
{
public:
- Ndb_mgmclient(const char*);
+ Ndb_mgmclient(const char*,int verbose=0);
~Ndb_mgmclient();
int execute(const char *_line, int _try_reconnect=-1);
int execute(int argc, char** argv, int _try_reconnect=-1);
From d58c186759bf264bc57a79882bc724d0485d3796 Mon Sep 17 00:00:00 2001
From: "marko@hundin.mysql.fi" <>
Date: Fri, 26 Nov 2004 13:16:37 +0200
Subject: [PATCH 114/145] srv0srv.c: srv_lock_timeout_and_monitor_thread():
write to srv_monitor_file only if --innodb_status_file=1
---
innobase/srv/srv0srv.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c
index 0a814268a36..99a2db57d79 100644
--- a/innobase/srv/srv0srv.c
+++ b/innobase/srv/srv0srv.c
@@ -1617,11 +1617,13 @@ loop:
srv_printf_innodb_monitor(stderr);
}
- mutex_enter(&srv_monitor_file_mutex);
- rewind(srv_monitor_file);
- srv_printf_innodb_monitor(srv_monitor_file);
- os_file_set_eof(srv_monitor_file);
- mutex_exit(&srv_monitor_file_mutex);
+ if (srv_innodb_status) {
+ mutex_enter(&srv_monitor_file_mutex);
+ rewind(srv_monitor_file);
+ srv_printf_innodb_monitor(srv_monitor_file);
+ os_file_set_eof(srv_monitor_file);
+ mutex_exit(&srv_monitor_file_mutex);
+ }
if (srv_print_innodb_tablespace_monitor
&& difftime(current_time, last_table_monitor_time) > 60) {
From 19dab11881e900c9e79db570b2f6456f67aa23fb Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Fri, 26 Nov 2004 13:20:48 +0000
Subject: [PATCH 115/145] added error code message for 897
---
ndb/src/ndbapi/ndberror.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/ndb/src/ndbapi/ndberror.c b/ndb/src/ndbapi/ndberror.c
index bc49358cc63..6744f4c1640 100644
--- a/ndb/src/ndbapi/ndberror.c
+++ b/ndb/src/ndbapi/ndberror.c
@@ -241,11 +241,12 @@ ErrorBundle ErrorCodes[] = {
{ 877, AE, "877" },
{ 878, AE, "878" },
{ 879, AE, "879" },
+ { 880, AE, "Tried to read too much - too many getValue calls" },
{ 884, AE, "Stack overflow in interpreter" },
{ 885, AE, "Stack underflow in interpreter" },
{ 886, AE, "More than 65535 instructions executed in interpreter" },
+ { 897, AE, "Update attempt of primary key via ndbcluster internal api (if this occurs via the MySQL server it is a bug, please report)" },
{ 4256, AE, "Must call Ndb::init() before this function" },
- { 880, AE, "Tried to read too much - too many getValue calls" },
{ 4257, AE, "Tried to read too much - too many getValue calls" },
/**
From 2e7cb4d011a50ed9c4b940eea4cb2c407def7fc7 Mon Sep 17 00:00:00 2001
From: "marko@hundin.mysql.fi" <>
Date: Sat, 27 Nov 2004 00:45:01 +0200
Subject: [PATCH 116/145] InnoDB: Make intermediate COMMITs in ALTER TABLE more
robust (Bug #6633)
---
innobase/include/lock0lock.h | 14 ++++++---
innobase/include/row0mysql.h | 4 ++-
innobase/lock/lock0lock.c | 52 +++++++++++++++++++++++--------
innobase/row/row0mysql.c | 5 +--
sql/ha_innodb.cc | 60 ++++++++++++++++++++++++++++--------
5 files changed, 102 insertions(+), 33 deletions(-)
diff --git a/innobase/include/lock0lock.h b/innobase/include/lock0lock.h
index f8435e14d97..fb44acc14f7 100644
--- a/innobase/include/lock0lock.h
+++ b/innobase/include/lock0lock.h
@@ -463,13 +463,17 @@ lock_rec_hash(
ulint space, /* in: space */
ulint page_no);/* in: page number */
/*************************************************************************
-Gets the table covered by an IX table lock. */
+Gets the table covered by an IX or IS table lock, if there are no
+other locks on the table. */
dict_table_t*
-lock_get_ix_table(
-/*==============*/
- /* out: the table covered by the lock */
- lock_t* lock); /* in: table lock */
+lock_get_table(
+/*===========*/
+ /* out: the table covered by the lock,
+ or NULL if it is not an IX or IS table lock,
+ or there are other locks on the table */
+ lock_t* lock, /* in: lock */
+ ulint* mode); /* out: lock mode of table */
/*************************************************************************
Checks that a transaction id is sensible, i.e., not in the future. */
diff --git a/innobase/include/row0mysql.h b/innobase/include/row0mysql.h
index 73f41dea0da..f47ce74ce37 100644
--- a/innobase/include/row0mysql.h
+++ b/innobase/include/row0mysql.h
@@ -177,10 +177,12 @@ row_lock_table_for_mysql(
/* out: error code or DB_SUCCESS */
row_prebuilt_t* prebuilt, /* in: prebuilt struct in the MySQL
table handle */
- dict_table_t* table); /* in: table to LOCK_IX, or NULL
+ dict_table_t* table, /* in: table to lock, or NULL
if prebuilt->table should be
locked as LOCK_TABLE_EXP |
prebuilt->select_lock_type */
+ ulint mode); /* in: lock mode of table */
+
/*************************************************************************
Does an insert for MySQL. */
diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c
index 78a78c9dd95..d9a10eb60c0 100644
--- a/innobase/lock/lock0lock.c
+++ b/innobase/lock/lock0lock.c
@@ -395,19 +395,6 @@ lock_rec_get_nth_bit(
return(ut_bit_get_nth(b, bit_index));
}
-/*************************************************************************
-Gets the table covered by an IX table lock. */
-
-dict_table_t*
-lock_get_ix_table(
-/*==============*/
- /* out: the table covered by the lock */
- lock_t* lock) /* in: table lock */
-{
- ut_a(lock->type_mode == (LOCK_TABLE | LOCK_IX));
- return(lock->un_member.tab_lock.table);
-}
-
/*************************************************************************/
#define lock_mutex_enter_kernel() mutex_enter(&kernel_mutex)
@@ -614,6 +601,45 @@ lock_get_wait(
return(FALSE);
}
+/*************************************************************************
+Gets the table covered by an IX or IS table lock, if there are no
+other locks on the table. */
+
+dict_table_t*
+lock_get_table(
+/*===========*/
+ /* out: the table covered by the lock,
+ or NULL if it is not an IX or IS table lock,
+ or there are other locks on the table */
+ lock_t* lock, /* in: lock */
+ ulint* mode) /* out: lock mode of table */
+{
+ dict_table_t* table;
+ ulint lock_mode;
+
+ table = NULL;
+ *mode = LOCK_NONE;
+
+ if (lock_get_type(lock) != LOCK_TABLE) {
+ return(table);
+ }
+
+ lock_mode = lock_get_mode(lock);
+ switch (lock_mode) {
+ case LOCK_IS:
+ case LOCK_IX:
+ *mode = lock_mode;
+ table = lock->un_member.tab_lock.table;
+ if (UT_LIST_GET_LEN(table->locks) != 1 ||
+ UT_LIST_GET_FIRST(table->locks) != lock) {
+ /* We only support the case when
+ there is only one lock on this table. */
+ table = NULL;
+ }
+ }
+ return(table);
+}
+
/*************************************************************************
Sets the wait flag of a lock and the back pointer in trx to lock. */
UNIV_INLINE
diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c
index 9613da2e286..dec2b19559c 100644
--- a/innobase/row/row0mysql.c
+++ b/innobase/row/row0mysql.c
@@ -782,10 +782,11 @@ row_lock_table_for_mysql(
/* out: error code or DB_SUCCESS */
row_prebuilt_t* prebuilt, /* in: prebuilt struct in the MySQL
table handle */
- dict_table_t* table) /* in: table to LOCK_IX, or NULL
+ dict_table_t* table, /* in: table to lock, or NULL
if prebuilt->table should be
locked as LOCK_TABLE_EXP |
prebuilt->select_lock_type */
+ ulint mode) /* in: lock mode of table */
{
trx_t* trx = prebuilt->trx;
que_thr_t* thr;
@@ -819,7 +820,7 @@ run_again:
trx_start_if_not_started(trx);
if (table) {
- err = lock_table(0, table, LOCK_IX, thr);
+ err = lock_table(0, table, mode, thr);
} else {
err = lock_table(LOCK_TABLE_EXP, prebuilt->table,
prebuilt->select_lock_type, thr);
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 2515b4956d0..2aaf69bd208 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -2324,20 +2324,55 @@ ha_innobase::write_row(
position in the source table need not be adjusted after the
intermediate COMMIT, since writes by other transactions are
being blocked by a MySQL table lock TL_WRITE_ALLOW_READ. */
- ut_a(prebuilt->trx->mysql_n_tables_locked == 2);
- ut_a(UT_LIST_GET_LEN(prebuilt->trx->trx_locks) >= 2);
- dict_table_t* table = lock_get_ix_table(
- UT_LIST_GET_FIRST(prebuilt->trx->trx_locks));
+
+ dict_table_t* table;
+ ibool mode;
+
num_write_row = 0;
+
/* Commit the transaction. This will release the table
locks, so they have to be acquired again. */
- innobase_commit(user_thd, prebuilt->trx);
- /* Note that this transaction is still active. */
- user_thd->transaction.all.innodb_active_trans = 1;
- /* Re-acquire the IX table lock on the source table. */
- row_lock_table_for_mysql(prebuilt, table);
- /* We will need an IX lock on the destination table. */
- prebuilt->sql_stat_start = TRUE;
+ switch (prebuilt->trx->mysql_n_tables_locked) {
+ case 1:
+ /* Altering to InnoDB format */
+ innobase_commit(user_thd, prebuilt->trx);
+ /* Note that this transaction is still active. */
+ user_thd->transaction.all.innodb_active_trans = 1;
+ /* We will need an IX lock on the destination table. */
+ prebuilt->sql_stat_start = TRUE;
+ break;
+ case 2:
+ /* Altering an InnoDB table */
+ ut_a(UT_LIST_GET_LEN(prebuilt->trx->trx_locks) >= 2);
+ table = lock_get_table(
+ UT_LIST_GET_FIRST(prebuilt->trx->trx_locks),
+ &mode);
+ if (!table) {
+ goto no_commit;
+ }
+
+ /* Commit the transaction. This will release the table
+ locks, so they have to be acquired again. */
+ innobase_commit(user_thd, prebuilt->trx);
+ /* Note that this transaction is still active. */
+ user_thd->transaction.all.innodb_active_trans = 1;
+ /* Re-acquire the table lock on the source table. */
+ row_lock_table_for_mysql(prebuilt, table, mode);
+ /* We will need an IX lock on the destination table. */
+ prebuilt->sql_stat_start = TRUE;
+ break;
+ default:
+ no_commit:
+ /* Unknown situation: do nothing (no commit) */
+ /*
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB error: ALTER TABLE is holding lock"
+ " on %lu tables!\n",
+ prebuilt->trx->mysql_n_tables_locked);
+ */
+ break;
+ }
}
num_write_row++;
@@ -5015,7 +5050,8 @@ ha_innobase::external_lock(
if (thd->in_lock_tables &&
thd->variables.innodb_table_locks) {
ulint error;
- error = row_lock_table_for_mysql(prebuilt, 0);
+ error = row_lock_table_for_mysql(prebuilt,
+ NULL, LOCK_TABLE_EXP);
if (error != DB_SUCCESS) {
error = convert_error_code_to_mysql(
From 77c32ac1739d78e39a51a1f6689858d4d193eb66 Mon Sep 17 00:00:00 2001
From: "kent@mysql.com" <>
Date: Sun, 28 Nov 2004 15:45:12 +0100
Subject: [PATCH 117/145] configure.in: A work-around for SCO, disable use of
clock_gettime
---
configure.in | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/configure.in b/configure.in
index 1fcba6b8f5f..0d6e797f571 100644
--- a/configure.in
+++ b/configure.in
@@ -1931,9 +1931,11 @@ AC_CHECK_FUNCS(alarm bcmp bfill bmove bzero chsize cuserid fchmod fcntl \
#
#
case "$target" in
- *-*-aix4*)
+ *-*-aix4* | *-*-sco*)
# (grr) aix 4.3 has a stub for clock_gettime, (returning ENOSYS)
# and using AC_TRY_RUN is hard when cross-compiling
+ # We also disable for SCO for the time being, the headers for the
+ # thread library we use conflicts with other headers.
;;
*) AC_CHECK_FUNCS(clock_gettime)
;;
From 7eccc3107fd65c1f066f93f33867799333a439ee Mon Sep 17 00:00:00 2001
From: "serg@serg.mylan" <>
Date: Sun, 28 Nov 2004 16:31:14 +0100
Subject: [PATCH 118/145] skip last compress test if we're short of RAM
---
mysql-test/r/func_compress.result | 4 ++--
mysql-test/t/func_compress.test | 5 ++++-
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/mysql-test/r/func_compress.result b/mysql-test/r/func_compress.result
index 11dbcca9431..9bc8e417e19 100644
--- a/mysql-test/r/func_compress.result
+++ b/mysql-test/r/func_compress.result
@@ -69,6 +69,6 @@ Error 1259 ZLIB: Input data corrupted
Error 1256 Uncompressed data size too large; the maximum size is 1048576 (probably, length of uncompressed data was corrupted)
drop table t1;
set @@max_allowed_packet=1048576*100;
-select compress(repeat('aaaaaaaaaa', 10000000)) is null;
-compress(repeat('aaaaaaaaaa', 10000000)) is null
+select compress(repeat('aaaaaaaaaa', IF(XXX, 10, 10000000))) is null;
+compress(repeat('aaaaaaaaaa', IF(XXX, 10, 10000000))) is null
0
diff --git a/mysql-test/t/func_compress.test b/mysql-test/t/func_compress.test
index 7b70289d2c0..f46589e9e0e 100644
--- a/mysql-test/t/func_compress.test
+++ b/mysql-test/t/func_compress.test
@@ -38,7 +38,10 @@ drop table t1;
#
# Bug #5497: a problem with large strings
+# note that when LOW_MEMORY is set the "test" below is meaningless
#
set @@max_allowed_packet=1048576*100;
-select compress(repeat('aaaaaaaaaa', 10000000)) is null;
+--replace_result "''" XXX "'1'" XXX
+eval select compress(repeat('aaaaaaaaaa', IF('$LOW_MEMORY', 10, 10000000))) is null;
+
From 989721d12f6c2a6b724c9010912be4b6d04a1ccb Mon Sep 17 00:00:00 2001
From: "serg@serg.mylan" <>
Date: Sun, 28 Nov 2004 17:06:40 +0100
Subject: [PATCH 119/145] bad merge fixed
---
mysql-test/r/rpl_start_stop_slave.result | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/mysql-test/r/rpl_start_stop_slave.result b/mysql-test/r/rpl_start_stop_slave.result
index 1b4d87124d1..1fcb586d1fb 100644
--- a/mysql-test/r/rpl_start_stop_slave.result
+++ b/mysql-test/r/rpl_start_stop_slave.result
@@ -1,9 +1,9 @@
-slave stop;
+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;
-slave start;
+start slave;
stop slave;
create table t1(n int);
start slave;
From cb538e45f5f18c71c22daed3acd983ec9ff97176 Mon Sep 17 00:00:00 2001
From: "serg@serg.mylan" <>
Date: Sun, 28 Nov 2004 19:48:41 +0100
Subject: [PATCH 120/145] post-merge fix
---
mysql-test/r/select.result | 62 +++++++++++++-------------------------
mysql-test/t/select.test | 2 --
2 files changed, 21 insertions(+), 43 deletions(-)
diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result
index 79af86777dc..a05b379ed88 100644
--- a/mysql-test/r/select.result
+++ b/mysql-test/r/select.result
@@ -2353,6 +2353,27 @@ select * from t2,t3 where t2.s = t3.s;
s s
two two
drop table t1, t2, t3;
+create table t1 (a integer, b integer, index(a), index(b));
+create table t2 (c integer, d integer, index(c), index(d));
+insert into t1 values (1,2), (2,2), (3,2), (4,2);
+insert into t2 values (1,3), (2,3), (3,4), (4,4);
+explain select * from t1 left join t2 on a=c where d in (4);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref c,d d 5 const 2 Using where
+1 SIMPLE t1 ALL a NULL NULL NULL 3 Using where
+select * from t1 left join t2 on a=c where d in (4);
+a b c d
+3 2 3 4
+4 2 4 4
+explain select * from t1 left join t2 on a=c where d = 4;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref c,d d 5 const 2 Using where
+1 SIMPLE t1 ALL a NULL NULL NULL 3 Using where
+select * from t1 left join t2 on a=c where d = 4;
+a b c d
+3 2 3 4
+4 2 4 4
+drop table t1, t2;
CREATE TABLE t1 (
i int(11) NOT NULL default '0',
c char(10) NOT NULL default '',
@@ -2365,45 +2386,4 @@ INSERT INTO t1 VALUES (3,'c');
EXPLAIN SELECT i FROM t1 WHERE i=1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index
-EXPLAIN SELECT i FROM t1 WHERE i=1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index
-DROP TABLE t1;
-create table t1 (a integer, b integer, index(a), index(b));
-create table t2 (c integer, d integer, index(c), index(d));
-insert into t1 values (1,2), (2,2), (3,2), (4,2);
-insert into t2 values (1,3), (2,3), (3,4), (4,4);
-explain select * from t1 left join t2 on a=c where d in (4);
-table type possible_keys key key_len ref rows Extra
-t2 ref c,d d 5 const 2 Using where
-t1 ALL a NULL NULL NULL 3 Using where
-select * from t1 left join t2 on a=c where d in (4);
-a b c d
-3 2 3 4
-4 2 4 4
-explain select * from t1 left join t2 on a=c where d = 4;
-table type possible_keys key key_len ref rows Extra
-t2 ref c,d d 5 const 2 Using where
-t1 ALL a NULL NULL NULL 3 Using where
-select * from t1 left join t2 on a=c where d = 4;
-a b c d
-3 2 3 4
-4 2 4 4
-drop table t1, t2;
-CREATE TABLE t1 (
-i int(11) NOT NULL default '0',
-c char(10) NOT NULL default '',
-PRIMARY KEY (i),
-UNIQUE KEY c (c)
-) TYPE=MyISAM;
-INSERT INTO t1 VALUES (1,'a');
-INSERT INTO t1 VALUES (2,'b');
-INSERT INTO t1 VALUES (3,'c');
-EXPLAIN SELECT i FROM t1 WHERE i=1;
-table type possible_keys key key_len ref rows Extra
-t1 const PRIMARY PRIMARY 4 const 1 Using index
-EXPLAIN SELECT i FROM t1 WHERE i=1;
-table type possible_keys key key_len ref rows Extra
-t1 const PRIMARY PRIMARY 4 const 1 Using index
->>>>>>>
DROP TABLE t1;
diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test
index 84aab132503..9bbd26a9c1c 100644
--- a/mysql-test/t/select.test
+++ b/mysql-test/t/select.test
@@ -1929,6 +1929,4 @@ INSERT INTO t1 VALUES (3,'c');
EXPLAIN SELECT i FROM t1 WHERE i=1;
-EXPLAIN SELECT i FROM t1 WHERE i=1;
-
DROP TABLE t1;
From 74bfe72d3d51e89098d786f72e6f4bebf87788d5 Mon Sep 17 00:00:00 2001
From: "joreland@mysql.com" <>
Date: Mon, 29 Nov 2004 09:00:39 +0100
Subject: [PATCH 121/145] ndb - scan bug fix + more test cases
---
ndb/include/ndbapi/NdbScanOperation.hpp | 11 +-
ndb/src/ndbapi/NdbConnectionScan.cpp | 2 +-
ndb/src/ndbapi/NdbScanOperation.cpp | 35 +-
ndb/test/ndbapi/testScan.cpp | 130 ++++++-
ndb/test/run-test/daily-basic-tests.txt | 496 +-----------------------
5 files changed, 172 insertions(+), 502 deletions(-)
diff --git a/ndb/include/ndbapi/NdbScanOperation.hpp b/ndb/include/ndbapi/NdbScanOperation.hpp
index 2e4d173ac75..5689b62526c 100644
--- a/ndb/include/ndbapi/NdbScanOperation.hpp
+++ b/ndb/include/ndbapi/NdbScanOperation.hpp
@@ -127,14 +127,23 @@ protected:
NdbReceiver** m_receivers; // All receivers
Uint32* m_prepared_receivers; // These are to be sent
-
+
+ /**
+ * owned by API/user thread
+ */
Uint32 m_current_api_receiver;
Uint32 m_api_receivers_count;
NdbReceiver** m_api_receivers; // These are currently used by api
+ /**
+ * owned by receiver thread
+ */
Uint32 m_conf_receivers_count; // NOTE needs mutex to access
NdbReceiver** m_conf_receivers; // receive thread puts them here
+ /**
+ * owned by receiver thread
+ */
Uint32 m_sent_receivers_count; // NOTE needs mutex to access
NdbReceiver** m_sent_receivers; // receive thread puts them here
diff --git a/ndb/src/ndbapi/NdbConnectionScan.cpp b/ndb/src/ndbapi/NdbConnectionScan.cpp
index a1a220caacf..b0c546c512a 100644
--- a/ndb/src/ndbapi/NdbConnectionScan.cpp
+++ b/ndb/src/ndbapi/NdbConnectionScan.cpp
@@ -56,7 +56,7 @@ NdbConnection::receiveSCAN_TABREF(NdbApiSignal* aSignal){
const ScanTabRef * ref = CAST_CONSTPTR(ScanTabRef, aSignal->getDataPtr());
if(checkState_TransId(&ref->transId1)){
- theScanningOp->theError.code = ref->errorCode;
+ theScanningOp->setErrorCode(ref->errorCode);
theScanningOp->execCLOSE_SCAN_REP();
if(!ref->closeNeeded){
return 0;
diff --git a/ndb/src/ndbapi/NdbScanOperation.cpp b/ndb/src/ndbapi/NdbScanOperation.cpp
index 282b831f8fd..6eb5167e385 100644
--- a/ndb/src/ndbapi/NdbScanOperation.cpp
+++ b/ndb/src/ndbapi/NdbScanOperation.cpp
@@ -277,9 +277,9 @@ NdbScanOperation::fix_receivers(Uint32 parallel){
void
NdbScanOperation::receiver_delivered(NdbReceiver* tRec){
if(theError.code == 0){
- if(DEBUG_NEXT_RESULT)
- ndbout_c("receiver_delivered");
-
+ if(DEBUG_NEXT_RESULT)
+ ndbout_c("receiver_delivered");
+
Uint32 idx = tRec->m_list_index;
Uint32 last = m_sent_receivers_count - 1;
if(idx != last){
@@ -492,6 +492,9 @@ int NdbScanOperation::nextResult(bool fetchAllowed)
Uint32 nodeId = theNdbCon->theDBnode;
TransporterFacade* tp = TransporterFacade::instance();
Guard guard(tp->theMutexPtr);
+ if(theError.code)
+ return -1;
+
Uint32 seq = theNdbCon->theNodeSequence;
if(seq == tp->getNodeSequence(nodeId) && send_next_scan(idx, false) == 0){
@@ -685,10 +688,8 @@ void NdbScanOperation::closeScan()
void
NdbScanOperation::execCLOSE_SCAN_REP(){
- m_api_receivers_count = 0;
m_conf_receivers_count = 0;
m_sent_receivers_count = 0;
- m_current_api_receiver = m_ordered ? theParallelism : 0;
}
void NdbScanOperation::release()
@@ -1333,6 +1334,8 @@ NdbIndexScanOperation::next_result_ordered(bool fetchAllowed){
if(DEBUG_NEXT_RESULT) ndbout_c("performing fetch...");
TransporterFacade* tp = TransporterFacade::instance();
Guard guard(tp->theMutexPtr);
+ if(theError.code)
+ return -1;
Uint32 seq = theNdbCon->theNodeSequence;
Uint32 nodeId = theNdbCon->theDBnode;
if(seq == tp->getNodeSequence(nodeId) && !send_next_scan_ordered(s_idx)){
@@ -1346,6 +1349,13 @@ NdbIndexScanOperation::next_result_ordered(bool fetchAllowed){
continue;
}
if(DEBUG_NEXT_RESULT) ndbout_c("return -1");
+ setErrorCode(4028);
+ return -1;
+ }
+
+ if(theError.code){
+ setErrorCode(theError.code);
+ if(DEBUG_NEXT_RESULT) ndbout_c("return -1");
return -1;
}
@@ -1355,11 +1365,9 @@ NdbIndexScanOperation::next_result_ordered(bool fetchAllowed){
memcpy(arr, m_conf_receivers, u_last * sizeof(char*));
if(DEBUG_NEXT_RESULT) ndbout_c("sent: %d recv: %d", tmp, u_last);
- if(theError.code){
- setErrorCode(theError.code);
- if(DEBUG_NEXT_RESULT) ndbout_c("return -1");
- return -1;
- }
+ } else {
+ setErrorCode(4028);
+ return -1;
}
} else {
if(DEBUG_NEXT_RESULT) ndbout_c("return 2");
@@ -1497,6 +1505,13 @@ NdbScanOperation::close_impl(TransporterFacade* tp){
}
}
+ if(theError.code)
+ {
+ m_api_receivers_count = 0;
+ m_current_api_receiver = m_ordered ? theParallelism : 0;
+ }
+
+
/**
* move all conf'ed into api
* so that send_next_scan can check if they needs to be closed
diff --git a/ndb/test/ndbapi/testScan.cpp b/ndb/test/ndbapi/testScan.cpp
index 51913e8fbf9..22ec3fff327 100644
--- a/ndb/test/ndbapi/testScan.cpp
+++ b/ndb/test/ndbapi/testScan.cpp
@@ -90,11 +90,59 @@ int runLoadAllTables(NDBT_Context* ctx, NDBT_Step* step){
return NDBT_OK;
}
+char orderedPkIdxName[255];
+
+int createOrderedPkIndex(NDBT_Context* ctx, NDBT_Step* step){
+
+ const NdbDictionary::Table* pTab = ctx->getTab();
+ Ndb* pNdb = GETNDB(step);
+
+ // Create index
+ BaseString::snprintf(orderedPkIdxName, sizeof(orderedPkIdxName),
+ "IDC_O_PK_%s", pTab->getName());
+ NdbDictionary::Index pIdx(orderedPkIdxName);
+ pIdx.setTable(pTab->getName());
+ pIdx.setType(NdbDictionary::Index::OrderedIndex);
+ pIdx.setLogging(false);
+
+ for (int c = 0; c< pTab->getNoOfColumns(); c++){
+ const NdbDictionary::Column * col = pTab->getColumn(c);
+ if(col->getPrimaryKey()){
+ pIdx.addIndexColumn(col->getName());
+ }
+ }
+
+ if (pNdb->getDictionary()->createIndex(pIdx) != 0){
+ ndbout << "FAILED! to create index" << endl;
+ const NdbError err = pNdb->getDictionary()->getNdbError();
+ ERR(err);
+ return NDBT_FAILED;
+ }
+
+ return NDBT_OK;
+}
+
+int createOrderedPkIndex_Drop(NDBT_Context* ctx, NDBT_Step* step){
+ const NdbDictionary::Table* pTab = ctx->getTab();
+ Ndb* pNdb = GETNDB(step);
+
+ // Drop index
+ if (pNdb->getDictionary()->dropIndex(orderedPkIdxName,
+ pTab->getName()) != 0){
+ ndbout << "FAILED! to drop index" << endl;
+ ERR(pNdb->getDictionary()->getNdbError());
+ return NDBT_FAILED;
+ }
+
+ return NDBT_OK;
+}
+
+
int runScanReadRandomTable(NDBT_Context* ctx, NDBT_Step* step){
int loops = ctx->getNumLoops();
int records = ctx->getNumRecords();
int parallelism = ctx->getProperty("Parallelism", 240);
- int abort = ctx->getProperty("AbortProb");
+ int abort = ctx->getProperty("AbortProb", 5);
int i = 0;
while (igetNumLoops();
int records = ctx->getNumRecords();
int parallelism = ctx->getProperty("Parallelism", 240);
- int abort = ctx->getProperty("AbortProb");
+ int abort = ctx->getProperty("AbortProb", 5);
int i = 0;
HugoTransactions hugoTrans(*ctx->getTab());
@@ -232,11 +280,58 @@ int runScanRead(NDBT_Context* ctx, NDBT_Step* step){
return NDBT_OK;
}
+int runRandScanRead(NDBT_Context* ctx, NDBT_Step* step){
+ int loops = ctx->getNumLoops();
+ int records = ctx->getNumRecords();
+ int parallelism = ctx->getProperty("Parallelism", 240);
+ int abort = ctx->getProperty("AbortProb", 5);
+
+ int i = 0;
+ HugoTransactions hugoTrans(*ctx->getTab());
+ while (iisTestStopped()) {
+ g_info << i << ": ";
+ NdbOperation::LockMode lm = (NdbOperation::LockMode)(rand() % 3);
+ if (hugoTrans.scanReadRecords(GETNDB(step),
+ records, abort, parallelism,
+ lm) != 0){
+ return NDBT_FAILED;
+ }
+ i++;
+ }
+ return NDBT_OK;
+}
+
+int runScanReadIndex(NDBT_Context* ctx, NDBT_Step* step){
+ int loops = ctx->getNumLoops();
+ int records = ctx->getNumRecords();
+ int parallelism = ctx->getProperty("Parallelism", 240);
+ int abort = ctx->getProperty("AbortProb", 5);
+ const NdbDictionary::Index * pIdx =
+ GETNDB(step)->getDictionary()->getIndex(orderedPkIdxName,
+ ctx->getTab()->getName());
+
+ int i = 0;
+ HugoTransactions hugoTrans(*ctx->getTab());
+ while (pIdx && iisTestStopped()) {
+ g_info << i << ": ";
+ bool sort = (rand() % 100) > 50 ? true : false;
+ NdbOperation::LockMode lm = (NdbOperation::LockMode)(rand() % 3);
+ if (hugoTrans.scanReadRecords(GETNDB(step), pIdx,
+ records, abort, parallelism,
+ lm,
+ sort) != 0){
+ return NDBT_FAILED;
+ }
+ i++;
+ }
+ return NDBT_OK;
+}
+
int runScanReadCommitted(NDBT_Context* ctx, NDBT_Step* step){
int loops = ctx->getNumLoops();
int records = ctx->getNumRecords();
int parallelism = ctx->getProperty("Parallelism", 240);
- int abort = ctx->getProperty("AbortProb");
+ int abort = ctx->getProperty("AbortProb", 5);
int i = 0;
HugoTransactions hugoTrans(*ctx->getTab());
@@ -425,7 +520,7 @@ int runScanUpdate(NDBT_Context* ctx, NDBT_Step* step){
int loops = ctx->getNumLoops();
int records = ctx->getNumRecords();
int parallelism = ctx->getProperty("Parallelism", 1);
- int abort = ctx->getProperty("AbortProb");
+ int abort = ctx->getProperty("AbortProb", 5);
int i = 0;
HugoTransactions hugoTrans(*ctx->getTab());
while (igetNumLoops();
int records = ctx->getNumRecords();
int parallelism = ctx->getProperty("Parallelism", 240);
- int abort = ctx->getProperty("AbortProb");
+ int abort = ctx->getProperty("AbortProb", 5);
int i = 0;
HugoTransactions hugoTrans(*ctx->getTab());
while (i
Date: Mon, 29 Nov 2004 08:06:53 +0000
Subject: [PATCH 122/145] ndb_grant.later: Rename:
mysql-test/t/ndb_grant.test -> mysql-test/t/ndb_grant.later
---
mysql-test/t/{ndb_grant.test => ndb_grant.later} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename mysql-test/t/{ndb_grant.test => ndb_grant.later} (100%)
diff --git a/mysql-test/t/ndb_grant.test b/mysql-test/t/ndb_grant.later
similarity index 100%
rename from mysql-test/t/ndb_grant.test
rename to mysql-test/t/ndb_grant.later
From 05d38dfcd8d29e586b4fa3281dcc3c88c8008625 Mon Sep 17 00:00:00 2001
From: "mats@mysql.com" <>
Date: Mon, 29 Nov 2004 10:24:40 +0100
Subject: [PATCH 123/145] rpl_start_stop_slave.result: Syntax change between
4.0 and 4.1.
---
mysql-test/r/rpl_start_stop_slave.result | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/mysql-test/r/rpl_start_stop_slave.result b/mysql-test/r/rpl_start_stop_slave.result
index 1b4d87124d1..1fcb586d1fb 100644
--- a/mysql-test/r/rpl_start_stop_slave.result
+++ b/mysql-test/r/rpl_start_stop_slave.result
@@ -1,9 +1,9 @@
-slave stop;
+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;
-slave start;
+start slave;
stop slave;
create table t1(n int);
start slave;
From b11f3feb530d92894909bf763c7ca820ec8fe038 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Mon, 29 Nov 2004 15:14:43 +0000
Subject: [PATCH 124/145] aligned backup errorcodes with rest of ndb error
codes giving it range from 1300 added new error type "configuration or
application error" Added check if backup is issued during diskless mode,
backup refuse returned added possibility to get error code as a result
from management client addded possibility to set connecstring with
CONNECT command changed to use strcasecmp instead of strcmp added
possibility to run one command on cammand client to ndb_mgm and get an
errorcode of command fails made thread safe veriosn of getErrorText in
management server aligned backup errorcodes with rest of ndb error codes
giving it range from 1300 print error message from regular ndberror
struct added new arrer type "cofiguration or application error"
commented on allocaded ranges for errors
---
ndb/include/kernel/signaldata/BackupImpl.hpp | 18 +-
.../kernel/signaldata/BackupSignalData.hpp | 27 +-
ndb/include/ndbapi/ndberror.h | 3 +-
ndb/src/kernel/blocks/backup/Backup.cpp | 7 +
ndb/src/kernel/blocks/backup/Backup.hpp | 1 +
ndb/src/kernel/blocks/backup/BackupInit.cpp | 1 +
ndb/src/mgmclient/CommandInterpreter.cpp | 236 ++++++++++--------
ndb/src/mgmclient/main.cpp | 23 +-
ndb/src/mgmclient/ndb_mgmclient.hpp | 4 +-
ndb/src/mgmsrv/CommandInterpreter.cpp | 47 ++--
ndb/src/mgmsrv/CommandInterpreter.hpp | 3 +
ndb/src/mgmsrv/MgmtSrvr.cpp | 27 +-
ndb/src/mgmsrv/MgmtSrvr.hpp | 2 +-
ndb/src/mgmsrv/Services.cpp | 34 +--
ndb/src/mgmsrv/Services.hpp | 3 +
ndb/src/ndbapi/ndberror.c | 53 ++++
16 files changed, 295 insertions(+), 194 deletions(-)
diff --git a/ndb/include/kernel/signaldata/BackupImpl.hpp b/ndb/include/kernel/signaldata/BackupImpl.hpp
index 1872069daa7..2ac91570aad 100644
--- a/ndb/include/kernel/signaldata/BackupImpl.hpp
+++ b/ndb/include/kernel/signaldata/BackupImpl.hpp
@@ -78,15 +78,15 @@ public:
STATIC_CONST( SignalLength = 3 );
enum ErrorCode {
- Undefined = 200,
- FailedToAllocateBuffers = 202,
- FailedToSetupFsBuffers = 203,
- FailedToAllocateTables = 204,
- FailedInsertFileHeader = 205,
- FailedInsertTableList = 206,
- FailedAllocateTableMem = 207,
- FailedToAllocateFileRecord = 208,
- FailedToAllocateAttributeRecord = 209
+ Undefined = 1340,
+ FailedToAllocateBuffers = 1342,
+ FailedToSetupFsBuffers = 1343,
+ FailedToAllocateTables = 1344,
+ FailedInsertFileHeader = 1345,
+ FailedInsertTableList = 1346,
+ FailedAllocateTableMem = 1347,
+ FailedToAllocateFileRecord = 1348,
+ FailedToAllocateAttributeRecord = 1349
};
private:
Uint32 backupId;
diff --git a/ndb/include/kernel/signaldata/BackupSignalData.hpp b/ndb/include/kernel/signaldata/BackupSignalData.hpp
index 42eb8464d53..fb018026a49 100644
--- a/ndb/include/kernel/signaldata/BackupSignalData.hpp
+++ b/ndb/include/kernel/signaldata/BackupSignalData.hpp
@@ -119,12 +119,13 @@ public:
private:
enum ErrorCodes {
- Undefined = 100,
- IAmNotMaster = 101,
- OutOfBackupRecord = 102,
- OutOfResources = 103,
- SequenceFailure = 104,
- BackupDefinitionNotImplemented = 105
+ Undefined = 1300,
+ IAmNotMaster = 1301,
+ OutOfBackupRecord = 1302,
+ OutOfResources = 1303,
+ SequenceFailure = 1304,
+ BackupDefinitionNotImplemented = 1305,
+ CannotBackupDiskless = 1306
};
Uint32 senderData;
Uint32 errorCode;
@@ -232,13 +233,13 @@ public:
STATIC_CONST( SignalLength = 3 );
enum RequestType {
- ClientAbort = 1,
- BackupComplete = 2,
- BackupFailure = 3, // General backup failure coordinator -> slave
- LogBufferFull = 4, // slave -> coordinator
- FileOrScanError = 5, // slave -> coordinator
- BackupFailureDueToNodeFail = 6, // slave -> slave
- OkToClean = 7 // master -> slave
+ ClientAbort = 1321,
+ BackupComplete = 1322,
+ BackupFailure = 1323, // General backup failure coordinator -> slave
+ LogBufferFull = 1324, // slave -> coordinator
+ FileOrScanError = 1325, // slave -> coordinator
+ BackupFailureDueToNodeFail = 1326, // slave -> slave
+ OkToClean = 1327 // master -> slave
};
private:
Uint32 requestType;
diff --git a/ndb/include/ndbapi/ndberror.h b/ndb/include/ndbapi/ndberror.h
index 5c2d85b82a6..ceb1881a4cc 100644
--- a/ndb/include/ndbapi/ndberror.h
+++ b/ndb/include/ndbapi/ndberror.h
@@ -46,7 +46,8 @@ typedef enum
ndberror_cl_internal_error = 12,
ndberror_cl_function_not_implemented = 13,
ndberror_cl_unknown_error_code = 14,
- ndberror_cl_node_shutdown = 15
+ ndberror_cl_node_shutdown = 15,
+ ndberror_cl_configuration = 16
} ndberror_classification_enum;
diff --git a/ndb/src/kernel/blocks/backup/Backup.cpp b/ndb/src/kernel/blocks/backup/Backup.cpp
index e6fe63d9014..9fc00883792 100644
--- a/ndb/src/kernel/blocks/backup/Backup.cpp
+++ b/ndb/src/kernel/blocks/backup/Backup.cpp
@@ -863,6 +863,13 @@ Backup::execBACKUP_REQ(Signal* signal)
sendBackupRef(senderRef, signal, senderData, BackupRef::IAmNotMaster);
return;
}//if
+
+ if (m_diskless)
+ {
+ sendBackupRef(senderRef, signal, senderData,
+ BackupRef::CannotBackupDiskless);
+ return;
+ }
if(dataLen32 != 0) {
jam();
diff --git a/ndb/src/kernel/blocks/backup/Backup.hpp b/ndb/src/kernel/blocks/backup/Backup.hpp
index 4dc2cd13ae0..fb29cb03b96 100644
--- a/ndb/src/kernel/blocks/backup/Backup.hpp
+++ b/ndb/src/kernel/blocks/backup/Backup.hpp
@@ -526,6 +526,7 @@ public:
NdbNodeBitmask c_aliveNodes;
DLList c_backups;
Config c_defaults;
+ Uint32 m_diskless;
STATIC_CONST(NO_OF_PAGES_META_FILE = 2);
diff --git a/ndb/src/kernel/blocks/backup/BackupInit.cpp b/ndb/src/kernel/blocks/backup/BackupInit.cpp
index 8daad05558b..d98541f2ea8 100644
--- a/ndb/src/kernel/blocks/backup/BackupInit.cpp
+++ b/ndb/src/kernel/blocks/backup/BackupInit.cpp
@@ -42,6 +42,7 @@ Backup::Backup(const Configuration & conf) :
ndbrequire(p != 0);
Uint32 noBackups = 0, noTables = 0, noAttribs = 0;
+ ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_DISCLESS, &m_diskless));
ndb_mgm_get_int_parameter(p, CFG_DB_PARALLEL_BACKUPS, &noBackups);
ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_NO_TABLES, &noTables));
ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_NO_ATTRIBUTES, &noAttribs));
diff --git a/ndb/src/mgmclient/CommandInterpreter.cpp b/ndb/src/mgmclient/CommandInterpreter.cpp
index bfe8b6786b4..0fc9ada408e 100644
--- a/ndb/src/mgmclient/CommandInterpreter.cpp
+++ b/ndb/src/mgmclient/CommandInterpreter.cpp
@@ -54,10 +54,11 @@ public:
*
* @return true until quit/bye/exit has been typed
*/
- int execute(const char *_line, int _try_reconnect=-1);
+ int execute(const char *_line, int _try_reconnect=-1, int *error= 0);
private:
void printError();
+ int execute_impl(const char *_line);
/**
* Analyse the command line, after the first token.
@@ -121,7 +122,7 @@ public:
void executeStatus(int processId, const char* parameters, bool all);
void executeEventReporting(int processId, const char* parameters, bool all);
void executeDumpState(int processId, const char* parameters, bool all);
- void executeStartBackup(char * parameters);
+ int executeStartBackup(char * parameters);
void executeAbortBackup(char * parameters);
void executeRep(char* parameters);
@@ -156,6 +157,7 @@ private:
bool connected;
int m_verbose;
int try_reconnect;
+ int m_error;
#ifdef HAVE_GLOBAL_REPLICATION
NdbRepHandle m_repserver;
const char *rep_host;
@@ -179,9 +181,9 @@ Ndb_mgmclient::~Ndb_mgmclient()
{
delete m_cmd;
}
-int Ndb_mgmclient::execute(const char *_line, int _try_reconnect)
+int Ndb_mgmclient::execute(const char *_line, int _try_reconnect, int *error)
{
- return m_cmd->execute(_line,_try_reconnect);
+ return m_cmd->execute(_line,_try_reconnect,error);
}
int
Ndb_mgmclient::disconnect()
@@ -227,7 +229,7 @@ extern "C" {
#include
#include
-int Ndb_mgmclient::execute(int argc, char** argv, int _try_reconnect)
+int Ndb_mgmclient::execute(int argc, char** argv, int _try_reconnect, int *error)
{
if (argc <= 0)
return 0;
@@ -236,7 +238,7 @@ int Ndb_mgmclient::execute(int argc, char** argv, int _try_reconnect)
{
_line.appfmt(" %s", argv[i]);
}
- return m_cmd->execute(_line.c_str(),_try_reconnect);
+ return m_cmd->execute(_line.c_str(),_try_reconnect, error);
}
/*****************************************************************************
@@ -277,7 +279,7 @@ static const char* helpText =
"REP CONNECT Connect to REP server on host:port\n"
#endif
"PURGE STALE SESSIONS Reset reserved nodeid's in the mgmt server\n"
-"CONNECT Connect to management server (reconnect if already connected)\n"
+"CONNECT [] Connect to management server (reconnect if already connected)\n"
"QUIT Quit management client\n"
;
@@ -469,13 +471,24 @@ CommandInterpreter::disconnect()
//*****************************************************************************
int
-CommandInterpreter::execute(const char *_line, int _try_reconnect)
+CommandInterpreter::execute(const char *_line, int _try_reconnect,
+ int *error)
{
- DBUG_ENTER("CommandInterpreter::execute");
- DBUG_PRINT("info",("line=\"%s\"",_line));
-
if (_try_reconnect >= 0)
try_reconnect=_try_reconnect;
+ int result= execute_impl(_line);
+ if (error)
+ *error= m_error;
+ return result;
+}
+
+int
+CommandInterpreter::execute_impl(const char *_line)
+{
+ DBUG_ENTER("CommandInterpreter::execute_impl");
+ DBUG_PRINT("enter",("line=\"%s\"",_line));
+ m_error= 0;
+
char * line;
if(_line == NULL) {
// ndbout << endl;
@@ -488,20 +501,16 @@ CommandInterpreter::execute(const char *_line, int _try_reconnect)
DBUG_RETURN(true);
}
- for (unsigned int i = 0; i < strlen(line); ++i) {
- line[i] = toupper(line[i]);
- }
-
// if there is anything in the line proceed
char* firstToken = strtok(line, " ");
char* allAfterFirstToken = strtok(NULL, "");
- if (strcmp(firstToken, "HELP") == 0 ||
- strcmp(firstToken, "?") == 0) {
+ if (strcasecmp(firstToken, "HELP") == 0 ||
+ strcasecmp(firstToken, "?") == 0) {
executeHelp(allAfterFirstToken);
DBUG_RETURN(true);
}
- else if (strcmp(firstToken, "CONNECT") == 0) {
+ else if (strcasecmp(firstToken, "CONNECT") == 0) {
executeConnect(allAfterFirstToken);
DBUG_RETURN(true);
}
@@ -509,61 +518,61 @@ CommandInterpreter::execute(const char *_line, int _try_reconnect)
if (!connect())
DBUG_RETURN(true);
- if (strcmp(firstToken, "SHOW") == 0) {
+ if (strcasecmp(firstToken, "SHOW") == 0) {
executeShow(allAfterFirstToken);
DBUG_RETURN(true);
}
- else if (strcmp(firstToken, "SHUTDOWN") == 0) {
+ else if (strcasecmp(firstToken, "SHUTDOWN") == 0) {
executeShutdown(allAfterFirstToken);
DBUG_RETURN(true);
}
- else if (strcmp(firstToken, "CLUSTERLOG") == 0){
+ else if (strcasecmp(firstToken, "CLUSTERLOG") == 0){
executeClusterLog(allAfterFirstToken);
DBUG_RETURN(true);
}
- else if(strcmp(firstToken, "START") == 0 &&
+ else if(strcasecmp(firstToken, "START") == 0 &&
allAfterFirstToken != NULL &&
- strncmp(allAfterFirstToken, "BACKUP", sizeof("BACKUP") - 1) == 0){
- executeStartBackup(allAfterFirstToken);
+ strncasecmp(allAfterFirstToken, "BACKUP", sizeof("BACKUP") - 1) == 0){
+ m_error= executeStartBackup(allAfterFirstToken);
DBUG_RETURN(true);
}
- else if(strcmp(firstToken, "ABORT") == 0 &&
+ else if(strcasecmp(firstToken, "ABORT") == 0 &&
allAfterFirstToken != NULL &&
- strncmp(allAfterFirstToken, "BACKUP", sizeof("BACKUP") - 1) == 0){
+ strncasecmp(allAfterFirstToken, "BACKUP", sizeof("BACKUP") - 1) == 0){
executeAbortBackup(allAfterFirstToken);
DBUG_RETURN(true);
}
- else if (strcmp(firstToken, "PURGE") == 0) {
+ else if (strcasecmp(firstToken, "PURGE") == 0) {
executePurge(allAfterFirstToken);
DBUG_RETURN(true);
}
#ifdef HAVE_GLOBAL_REPLICATION
- else if(strcmp(firstToken, "REPLICATION") == 0 ||
- strcmp(firstToken, "REP") == 0) {
+ else if(strcasecmp(firstToken, "REPLICATION") == 0 ||
+ strcasecmp(firstToken, "REP") == 0) {
executeRep(allAfterFirstToken);
DBUG_RETURN(true);
}
#endif // HAVE_GLOBAL_REPLICATION
- else if(strcmp(firstToken, "ENTER") == 0 &&
+ else if(strcasecmp(firstToken, "ENTER") == 0 &&
allAfterFirstToken != NULL &&
- strncmp(allAfterFirstToken, "SINGLE USER MODE ",
+ strncasecmp(allAfterFirstToken, "SINGLE USER MODE ",
sizeof("SINGLE USER MODE") - 1) == 0){
executeEnterSingleUser(allAfterFirstToken);
DBUG_RETURN(true);
}
- else if(strcmp(firstToken, "EXIT") == 0 &&
+ else if(strcasecmp(firstToken, "EXIT") == 0 &&
allAfterFirstToken != NULL &&
- strncmp(allAfterFirstToken, "SINGLE USER MODE ",
+ strncasecmp(allAfterFirstToken, "SINGLE USER MODE ",
sizeof("SINGLE USER MODE") - 1) == 0){
executeExitSingleUser(allAfterFirstToken);
DBUG_RETURN(true);
}
- else if (strcmp(firstToken, "ALL") == 0) {
+ else if (strcasecmp(firstToken, "ALL") == 0) {
analyseAfterFirstToken(-1, allAfterFirstToken);
}
- else if((strcmp(firstToken, "QUIT") == 0 ||
- strcmp(firstToken, "EXIT") == 0 ||
- strcmp(firstToken, "BYE") == 0) &&
+ else if((strcasecmp(firstToken, "QUIT") == 0 ||
+ strcasecmp(firstToken, "EXIT") == 0 ||
+ strcasecmp(firstToken, "BYE") == 0) &&
allAfterFirstToken == NULL){
DBUG_RETURN(false);
} else {
@@ -573,12 +582,12 @@ CommandInterpreter::execute(const char *_line, int _try_reconnect)
int nodeId;
if (! convert(firstToken, nodeId)) {
- ndbout << "Invalid command: " << line << endl;
+ ndbout << "Invalid command: " << _line << endl;
ndbout << "Type HELP for help." << endl << endl;
DBUG_RETURN(true);
}
- if (nodeId < 0) {
+ if (nodeId <= 0) {
ndbout << "Invalid node ID: " << firstToken << "." << endl;
DBUG_RETURN(true);
}
@@ -639,7 +648,7 @@ CommandInterpreter::analyseAfterFirstToken(int processId,
ExecuteFunction fun = 0;
const char * command = 0;
for(int i = 0; i*fun)(processId, allAfterSecondToken, false);
ndbout << endl;
@@ -705,10 +714,10 @@ CommandInterpreter::executeForAll(const char * cmd, ExecuteFunction fun,
const char * allAfterSecondToken)
{
int nodeId = 0;
- if(strcmp(cmd, "STOP") == 0) {
+ if(strcasecmp(cmd, "STOP") == 0) {
ndbout_c("Executing STOP on all nodes.");
(this->*fun)(nodeId, allAfterSecondToken, true);
- } else if(strcmp(cmd, "RESTART") == 0) {
+ } else if(strcasecmp(cmd, "RESTART") == 0) {
ndbout_c("Executing RESTART on all nodes.");
ndbout_c("Starting shutdown. This may take a while. Please wait...");
(this->*fun)(nodeId, allAfterSecondToken, true);
@@ -723,7 +732,7 @@ CommandInterpreter::executeForAll(const char * cmd, ExecuteFunction fun,
}
NdbAutoPtr ap1((char*)cl);
while(get_next_nodeid(cl, &nodeId, NDB_MGM_NODE_TYPE_NDB)) {
- if(strcmp(cmd, "STATUS") != 0)
+ if(strcasecmp(cmd, "STATUS") != 0)
ndbout_c("Executing %s on node %d.", cmd, nodeId);
(this->*fun)(nodeId, allAfterSecondToken, true);
ndbout << endl;
@@ -751,7 +760,7 @@ CommandInterpreter::parseBlockSpecification(const char* allAfterLog,
firstTokenAfterLog[i] = toupper(firstTokenAfterLog[i]);
}
- if (strcmp(firstTokenAfterLog, "BLOCK") != 0) {
+ if (strcasecmp(firstTokenAfterLog, "BLOCK") != 0) {
ndbout << "Unexpected value: " << firstTokenAfterLog
<< ". Expected BLOCK." << endl;
return false;
@@ -764,7 +773,7 @@ CommandInterpreter::parseBlockSpecification(const char* allAfterLog,
}
char* secondTokenAfterLog = strtok(allAfterFirstToken, " ");
- if (strcmp(secondTokenAfterLog, "=") != 0) {
+ if (strcasecmp(secondTokenAfterLog, "=") != 0) {
ndbout << "Unexpected value: " << secondTokenAfterLog
<< ". Expected =." << endl;
return false;
@@ -772,7 +781,7 @@ CommandInterpreter::parseBlockSpecification(const char* allAfterLog,
char* blockName = strtok(NULL, " ");
bool all = false;
- if (blockName != NULL && (strcmp(blockName, "ALL") == 0)) {
+ if (blockName != NULL && (strcasecmp(blockName, "ALL") == 0)) {
all = true;
}
while (blockName != NULL) {
@@ -823,15 +832,15 @@ CommandInterpreter::executeHelp(char* parameters)
ndbout << " = " << "0 - 15" << endl;
ndbout << " = " << "ALL | Any database node id" << endl;
ndbout << endl;
- } else if (strcmp(parameters, "SHOW") == 0) {
+ } else if (strcasecmp(parameters, "SHOW") == 0) {
ndbout << helpTextShow;
#ifdef HAVE_GLOBAL_REPLICATION
- } else if (strcmp(parameters, "REPLICATION") == 0 ||
- strcmp(parameters, "REP") == 0) {
+ } else if (strcasecmp(parameters, "REPLICATION") == 0 ||
+ strcasecmp(parameters, "REP") == 0) {
ndbout << helpTextRep;
#endif // HAVE_GLOBAL_REPLICATION
#ifdef VM_TRACE // DEBUG ONLY
- } else if (strcmp(parameters, "DEBUG") == 0) {
+ } else if (strcasecmp(parameters, "DEBUG") == 0) {
ndbout << helpTextDebug;
#endif
} else {
@@ -939,7 +948,7 @@ print_nodes(ndb_mgm_cluster_state *state, ndb_mgm_configuration_iterator *it,
const char *hostname= node_state->connect_address;
if (hostname == 0
|| strlen(hostname) == 0
- || strcmp(hostname,"0.0.0.0") == 0)
+ || strcasecmp(hostname,"0.0.0.0") == 0)
ndbout << " ";
else
ndbout << "\t@" << hostname;
@@ -984,9 +993,9 @@ CommandInterpreter::executePurge(char* parameters)
break;
char* firstToken = strtok(parameters, " ");
char* nextToken = strtok(NULL, " \0");
- if (strcmp(firstToken,"STALE") == 0 &&
+ if (strcasecmp(firstToken,"STALE") == 0 &&
nextToken &&
- strcmp(nextToken, "SESSIONS") == 0) {
+ strcasecmp(nextToken, "SESSIONS") == 0) {
command_ok= 1;
break;
}
@@ -1086,17 +1095,17 @@ CommandInterpreter::executeShow(char* parameters)
print_nodes(state, it, "mysqld", api_nodes, NDB_MGM_NODE_TYPE_API, 0);
// ndbout << helpTextShow;
return;
- } else if (strcmp(parameters, "PROPERTIES") == 0 ||
- strcmp(parameters, "PROP") == 0) {
+ } else if (strcasecmp(parameters, "PROPERTIES") == 0 ||
+ strcasecmp(parameters, "PROP") == 0) {
ndbout << "SHOW PROPERTIES is not yet implemented." << endl;
// ndbout << "_mgmtSrvr.getConfig()->print();" << endl; /* XXX */
- } else if (strcmp(parameters, "CONFIGURATION") == 0 ||
- strcmp(parameters, "CONFIG") == 0){
+ } else if (strcasecmp(parameters, "CONFIGURATION") == 0 ||
+ strcasecmp(parameters, "CONFIG") == 0){
ndbout << "SHOW CONFIGURATION is not yet implemented." << endl;
//nbout << "_mgmtSrvr.getConfig()->printConfigFile();" << endl; /* XXX */
- } else if (strcmp(parameters, "PARAMETERS") == 0 ||
- strcmp(parameters, "PARAMS") == 0 ||
- strcmp(parameters, "PARAM") == 0) {
+ } else if (strcasecmp(parameters, "PARAMETERS") == 0 ||
+ strcasecmp(parameters, "PARAMS") == 0 ||
+ strcasecmp(parameters, "PARAM") == 0) {
ndbout << "SHOW PARAMETERS is not yet implemented." << endl;
// ndbout << "_mgmtSrvr.getConfig()->getConfigInfo()->print();"
// << endl; /* XXX */
@@ -1109,6 +1118,14 @@ void
CommandInterpreter::executeConnect(char* parameters)
{
disconnect();
+ if (!emptyString(parameters)) {
+ if (ndb_mgm_set_connectstring(m_mgmsrv,
+ BaseString(parameters).trim().c_str()))
+ {
+ printError();
+ return;
+ }
+ }
connect();
}
@@ -1132,7 +1149,7 @@ CommandInterpreter::executeClusterLog(char* parameters)
/********************
* CLUSTERLOG FILTER
********************/
- if (strcmp(item, "FILTER") == 0) {
+ if (strcasecmp(item, "FILTER") == 0) {
item = strtok_r(NULL, " ", &tmpPtr);
if (item == NULL) {
@@ -1141,21 +1158,21 @@ CommandInterpreter::executeClusterLog(char* parameters)
while (item != NULL) {
snprintf(name, sizeof(name), item);
- if (strcmp(item, "ALL") == 0) {
+ if (strcasecmp(item, "ALL") == 0) {
severity = NDB_MGM_CLUSTERLOG_ALL;
- } else if (strcmp(item, "ALERT") == 0) {
+ } else if (strcasecmp(item, "ALERT") == 0) {
severity = NDB_MGM_CLUSTERLOG_ALERT;
- } else if (strcmp(item, "CRITICAL") == 0) {
+ } else if (strcasecmp(item, "CRITICAL") == 0) {
severity = NDB_MGM_CLUSTERLOG_CRITICAL;
- } else if (strcmp(item, "ERROR") == 0) {
+ } else if (strcasecmp(item, "ERROR") == 0) {
severity = NDB_MGM_CLUSTERLOG_ERROR;
- } else if (strcmp(item, "WARNING") == 0) {
+ } else if (strcasecmp(item, "WARNING") == 0) {
severity = NDB_MGM_CLUSTERLOG_WARNING;
- } else if (strcmp(item, "INFO") == 0) {
+ } else if (strcasecmp(item, "INFO") == 0) {
severity = NDB_MGM_CLUSTERLOG_INFO;
- } else if (strcmp(item, "DEBUG") == 0) {
+ } else if (strcasecmp(item, "DEBUG") == 0) {
severity = NDB_MGM_CLUSTERLOG_DEBUG;
- } else if (strcmp(item, "OFF") == 0) {
+ } else if (strcasecmp(item, "OFF") == 0) {
severity = NDB_MGM_CLUSTERLOG_OFF;
} else {
isOk = false;
@@ -1168,17 +1185,17 @@ CommandInterpreter::executeClusterLog(char* parameters)
ndbout << "Missing argument(s)." << endl;
} else if (isOk) {
if(ndb_mgm_filter_clusterlog(m_mgmsrv, severity, NULL)) {
- if(strcmp(name, "ALL") == 0 || strcmp(name, "all") == 0) {
+ if(strcasecmp(name, "ALL") == 0) {
ndbout << "All severities levels enabled." << endl;
- } else if(strcmp(name, "OFF") == 0 || strcmp(name, "off") == 0) {
+ } else if(strcasecmp(name, "OFF") == 0) {
ndbout << "Cluster logging enabled." << endl;
} else {
ndbout << name << " events disabled." << endl;
}
} else {
- if(strcmp(name, "ALL") == 0) {
+ if(strcasecmp(name, "ALL") == 0) {
ndbout << "All severities levels disabled." << endl;
- } else if(strcmp(name, "OFF") == 0) {
+ } else if(strcasecmp(name, "OFF") == 0) {
ndbout << "Cluster logging disabled." << endl;
} else {
ndbout << name << " events enabled." << endl;
@@ -1191,7 +1208,7 @@ CommandInterpreter::executeClusterLog(char* parameters)
/********************
* CLUSTERLOG INFO
********************/
- } else if (strcmp(item, "INFO") == 0) {
+ } else if (strcasecmp(item, "INFO") == 0) {
Uint32 *enabled = ndb_mgm_get_logfilter(m_mgmsrv);
if(enabled == NULL) {
ndbout << "Couldn't get status" << endl;
@@ -1216,7 +1233,7 @@ CommandInterpreter::executeClusterLog(char* parameters)
/********************
* CLUSTERLOG OFF
********************/
- } else if (strcmp(item, "OFF") == 0) {
+ } else if (strcasecmp(item, "OFF") == 0) {
Uint32 *enabled = ndb_mgm_get_logfilter(m_mgmsrv);
if(enabled == NULL) {
ndbout << "Couldn't get status" << endl;
@@ -1234,7 +1251,7 @@ CommandInterpreter::executeClusterLog(char* parameters)
/********************
* CLUSTERLOG ON
********************/
- } else if (strcmp(item, "ON") == 0) {
+ } else if (strcasecmp(item, "ON") == 0) {
Uint32 *enabled = ndb_mgm_get_logfilter(m_mgmsrv);
if(enabled == NULL) {
ndbout << "Could not get status" << endl;
@@ -1358,11 +1375,11 @@ CommandInterpreter::executeRestart(int processId, const char* parameters,
char * tmpPtr = 0;
char * item = strtok_r(tmpString, " ", &tmpPtr);
while(item != NULL){
- if(strcmp(item, "-N") == 0)
+ if(strcasecmp(item, "-N") == 0)
nostart = 1;
- if(strcmp(item, "-I") == 0)
+ if(strcasecmp(item, "-I") == 0)
initialstart = 1;
- if(strcmp(item, "-A") == 0)
+ if(strcasecmp(item, "-A") == 0)
abort = 1;
item = strtok_r(NULL, " ", &tmpPtr);
}
@@ -1591,7 +1608,7 @@ CommandInterpreter::executeTrace(int /*processId*/,
int result = _mgmtSrvr.setTraceNo(processId, traceNo);
if (result != 0) {
- ndbout << _mgmtSrvr.getErrorText(result) << endl;
+ ndbout << get_error_text(result) << endl;
}
#endif
}
@@ -1751,7 +1768,7 @@ CommandInterpreter::executeSet(int /*processId*/,
}
}
else {
- ndbout << _mgmtSrvr.getErrorText(result) << endl;
+ ndbout << get_error_text(result) << endl;
if (configBackupFileUpdated && configPrimaryFileUpdated) {
ndbout << "The configuration files are however updated and "
<< "the value will be used next time the process is restarted."
@@ -1786,7 +1803,7 @@ void CommandInterpreter::executeGetStat(int /*processId*/,
MgmtSrvr::Statistics statistics;
int result = _mgmtSrvr.getStatistics(processId, statistics);
if (result != 0) {
- ndbout << _mgmtSrvr.getErrorText(result) << endl;
+ ndbout << get_error_text(result) << endl;
return;
}
#endif
@@ -1856,7 +1873,7 @@ CommandInterpreter::executeEventReporting(int processId,
/*****************************************************************************
* Backup
*****************************************************************************/
-void
+int
CommandInterpreter::executeStartBackup(char* /*parameters*/)
{
struct ndb_mgm_reply reply;
@@ -1869,7 +1886,7 @@ CommandInterpreter::executeStartBackup(char* /*parameters*/)
ndbout << "Start of backup failed" << endl;
printError();
close(fd);
- return;
+ return result;
}
char *tmp;
@@ -1900,6 +1917,7 @@ CommandInterpreter::executeStartBackup(char* /*parameters*/)
} while(tmp && tmp[0] != 0);
close(fd);
+ return 0;
}
void
@@ -1966,7 +1984,7 @@ CommandInterpreter::executeRep(char* parameters)
unsigned int repId;
- if (!strcmp(firstToken, "CONNECT")) {
+ if (!strcasecmp(firstToken, "CONNECT")) {
char * host = strtok(NULL, "\0");
for (unsigned int i = 0; i < strlen(host); ++i) {
host[i] = tolower(host[i]);
@@ -2001,30 +2019,30 @@ CommandInterpreter::executeRep(char* parameters)
/********
* START
********/
- if (!strcmp(firstToken, "START")) {
+ if (!strcasecmp(firstToken, "START")) {
unsigned int req;
char *startType = strtok(NULL, "\0");
if (startType == NULL) {
req = GrepReq::START;
- } else if (!strcmp(startType, "SUBSCRIPTION")) {
+ } else if (!strcasecmp(startType, "SUBSCRIPTION")) {
req = GrepReq::START_SUBSCR;
- } else if (!strcmp(startType, "METALOG")) {
+ } else if (!strcasecmp(startType, "METALOG")) {
req = GrepReq::START_METALOG;
- } else if (!strcmp(startType, "METASCAN")) {
+ } else if (!strcasecmp(startType, "METASCAN")) {
req = GrepReq::START_METASCAN;
- } else if (!strcmp(startType, "DATALOG")) {
+ } else if (!strcasecmp(startType, "DATALOG")) {
req = GrepReq::START_DATALOG;
- } else if (!strcmp(startType, "DATASCAN")) {
+ } else if (!strcasecmp(startType, "DATASCAN")) {
req = GrepReq::START_DATASCAN;
- } else if (!strcmp(startType, "REQUESTOR")) {
+ } else if (!strcasecmp(startType, "REQUESTOR")) {
req = GrepReq::START_REQUESTOR;
- } else if (!strcmp(startType, "TRANSFER")) {
+ } else if (!strcasecmp(startType, "TRANSFER")) {
req = GrepReq::START_TRANSFER;
- } else if (!strcmp(startType, "APPLY")) {
+ } else if (!strcasecmp(startType, "APPLY")) {
req = GrepReq::START_APPLY;
- } else if (!strcmp(startType, "DELETE")) {
+ } else if (!strcasecmp(startType, "DELETE")) {
req = GrepReq::START_DELETE;
} else {
ndbout_c("Illegal argument to command 'REPLICATION START'");
@@ -2044,7 +2062,7 @@ CommandInterpreter::executeRep(char* parameters)
/********
* STOP
********/
- if (!strcmp(firstToken, "STOP")) {
+ if (!strcasecmp(firstToken, "STOP")) {
unsigned int req;
char *startType = strtok(NULL, " ");
unsigned int epoch = 0;
@@ -2054,7 +2072,7 @@ CommandInterpreter::executeRep(char* parameters)
* Stop immediately
*/
req = GrepReq::STOP;
- } else if (!strcmp(startType, "EPOCH")) {
+ } else if (!strcasecmp(startType, "EPOCH")) {
char *strEpoch = strtok(NULL, "\0");
if(strEpoch == NULL) {
ndbout_c("Epoch expected!");
@@ -2062,23 +2080,23 @@ CommandInterpreter::executeRep(char* parameters)
}
req = GrepReq::STOP;
epoch=atoi(strEpoch);
- } else if (!strcmp(startType, "SUBSCRIPTION")) {
+ } else if (!strcasecmp(startType, "SUBSCRIPTION")) {
req = GrepReq::STOP_SUBSCR;
- } else if (!strcmp(startType, "METALOG")) {
+ } else if (!strcasecmp(startType, "METALOG")) {
req = GrepReq::STOP_METALOG;
- } else if (!strcmp(startType, "METASCAN")) {
+ } else if (!strcasecmp(startType, "METASCAN")) {
req = GrepReq::STOP_METASCAN;
- } else if (!strcmp(startType, "DATALOG")) {
+ } else if (!strcasecmp(startType, "DATALOG")) {
req = GrepReq::STOP_DATALOG;
- } else if (!strcmp(startType, "DATASCAN")) {
+ } else if (!strcasecmp(startType, "DATASCAN")) {
req = GrepReq::STOP_DATASCAN;
- } else if (!strcmp(startType, "REQUESTOR")) {
+ } else if (!strcasecmp(startType, "REQUESTOR")) {
req = GrepReq::STOP_REQUESTOR;
- } else if (!strcmp(startType, "TRANSFER")) {
+ } else if (!strcasecmp(startType, "TRANSFER")) {
req = GrepReq::STOP_TRANSFER;
- } else if (!strcmp(startType, "APPLY")) {
+ } else if (!strcasecmp(startType, "APPLY")) {
req = GrepReq::STOP_APPLY;
- } else if (!strcmp(startType, "DELETE")) {
+ } else if (!strcasecmp(startType, "DELETE")) {
req = GrepReq::STOP_DELETE;
} else {
ndbout_c("Illegal argument to command 'REPLICATION STOP'");
@@ -2097,7 +2115,7 @@ CommandInterpreter::executeRep(char* parameters)
/*********
* STATUS
*********/
- if (!strcmp(firstToken, "STATUS")) {
+ if (!strcasecmp(firstToken, "STATUS")) {
struct rep_state repstate;
int result =
ndb_rep_get_status(m_repserver, &repId, &reply, &repstate);
@@ -2117,7 +2135,7 @@ CommandInterpreter::executeRep(char* parameters)
/*********
* QUERY (see repapi.h for querable counters)
*********/
- if (!strcmp(firstToken, "QUERY")) {
+ if (!strcasecmp(firstToken, "QUERY")) {
char *query = strtok(NULL, "\0");
int queryCounter=-1;
if(query != NULL) {
diff --git a/ndb/src/mgmclient/main.cpp b/ndb/src/mgmclient/main.cpp
index 08d5d60cfab..84e27790705 100644
--- a/ndb/src/mgmclient/main.cpp
+++ b/ndb/src/mgmclient/main.cpp
@@ -60,10 +60,15 @@ static const char default_prompt[]= "ndb_mgm> ";
static unsigned _try_reconnect;
static char *opt_connect_str= 0;
static const char *prompt= default_prompt;
+static char *opt_execute_str= 0;
static struct my_option my_long_options[] =
{
NDB_STD_OPTS("ndb_mgm"),
+ { "execute", 'e',
+ "execute command and exit",
+ (gptr*) &opt_execute_str, (gptr*) &opt_execute_str, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
{ "try-reconnect", 't',
"Specify number of tries for connecting to ndb_mgmd (0 = infinite)",
(gptr*) &_try_reconnect, (gptr*) &_try_reconnect, 0,
@@ -156,19 +161,25 @@ int main(int argc, char** argv){
opt_connect_str= buf;
}
- if (!isatty(0))
+ if (!isatty(0) || opt_execute_str)
{
prompt= 0;
}
- ndbout << "-- NDB Cluster -- Management Client --" << endl;
-
signal(SIGPIPE, handler);
-
com = new Ndb_mgmclient(opt_connect_str,1);
- while(read_and_execute(_try_reconnect));
+ int ret= 0;
+ if (!opt_execute_str)
+ {
+ ndbout << "-- NDB Cluster -- Management Client --" << endl;
+ while(read_and_execute(_try_reconnect));
+ }
+ else
+ {
+ com->execute(opt_execute_str,_try_reconnect, &ret);
+ }
delete com;
- return 0;
+ return ret;
}
diff --git a/ndb/src/mgmclient/ndb_mgmclient.hpp b/ndb/src/mgmclient/ndb_mgmclient.hpp
index ea592dfdf4e..bffdf69f920 100644
--- a/ndb/src/mgmclient/ndb_mgmclient.hpp
+++ b/ndb/src/mgmclient/ndb_mgmclient.hpp
@@ -23,8 +23,8 @@ class Ndb_mgmclient
public:
Ndb_mgmclient(const char*,int verbose=0);
~Ndb_mgmclient();
- int execute(const char *_line, int _try_reconnect=-1);
- int execute(int argc, char** argv, int _try_reconnect=-1);
+ int execute(const char *_line, int _try_reconnect=-1, int *error= 0);
+ int execute(int argc, char** argv, int _try_reconnect=-1, int *error= 0);
int disconnect();
private:
CommandInterpreter *m_cmd;
diff --git a/ndb/src/mgmsrv/CommandInterpreter.cpp b/ndb/src/mgmsrv/CommandInterpreter.cpp
index 2a054a01f1e..02bf24f1d9c 100644
--- a/ndb/src/mgmsrv/CommandInterpreter.cpp
+++ b/ndb/src/mgmsrv/CommandInterpreter.cpp
@@ -113,6 +113,11 @@ private:
void * m_ptr;
};
+const char *CommandInterpreter::get_error_text(int err_no)
+{
+ return _mgmtSrvr.getErrorText(err_no, m_err_str, sizeof(m_err_str));
+}
+
//*****************************************************************************
//*****************************************************************************
int CommandInterpreter::readAndExecute() {
@@ -600,8 +605,9 @@ stopCallback(int nodeId, void * anyData, int errCode){
ndbout << "\nNode " << nodeId << " has shutdown" << endl;
} else {
MgmtSrvr * mgm = (MgmtSrvr *)anyData;
+ char err_str[1024];
ndbout << "Node " << nodeId << " has not shutdown: "
- << mgm->getErrorText(errCode) << endl;
+ << mgm->getErrorText(errCode,err_str,sizeof(err_str)) << endl;
}
}
@@ -653,7 +659,8 @@ versionCallback(int nodeId, int version, void * anyData, int errCode){
} else {
MgmtSrvr * mgm = (MgmtSrvr *)anyData;
- ndbout << mgm->getErrorText(errCode) << endl;
+ char err_str[1024];
+ ndbout << mgm->getErrorText(errCode,err_str,sizeof(err_str)) << endl;
}
}
@@ -671,7 +678,7 @@ void CommandInterpreter::executeStop(int processId,
result = _mgmtSrvr.stopNode(processId, false, stopCallback, this);
if(result != 0)
- ndbout << _mgmtSrvr.getErrorText(result) << endl;
+ ndbout << get_error_text(result) << endl;
}
@@ -686,7 +693,7 @@ void CommandInterpreter::executeStart(int processId, const char* parameters,
int result = _mgmtSrvr.start(processId);
if (result != 0) {
- ndbout << _mgmtSrvr.getErrorText(result) << endl;
+ ndbout << get_error_text(result) << endl;
}
}
@@ -719,7 +726,7 @@ CommandInterpreter::executeRestart(int processId, const char* parameters,
stopCallback,
this);
if (result != 0) {
- ndbout << _mgmtSrvr.getErrorText(result) << endl;
+ ndbout << get_error_text(result) << endl;
}
}
@@ -760,7 +767,7 @@ CommandInterpreter::executeDumpState(int processId, const char* parameters,
free(tmpString);
int result = _mgmtSrvr.dumpState(processId, pars, no);
if (result != 0) {
- ndbout << _mgmtSrvr.getErrorText(result) << endl;
+ ndbout << get_error_text(result) << endl;
}
}
@@ -781,7 +788,7 @@ void CommandInterpreter::executeStatus(int processId,
&status, &version, &startPhase, &system,
&dynamicId, &nodeGroup, &connectCount);
if(result != 0){
- ndbout << _mgmtSrvr.getErrorText(result) << endl;
+ ndbout << get_error_text(result) << endl;
return;
}
@@ -875,7 +882,7 @@ void CommandInterpreter::executeLogLevel(int processId,
int result = _mgmtSrvr.setNodeLogLevel(processId, logLevel);
if (result != 0) {
- ndbout << _mgmtSrvr.getErrorText(result) << endl;
+ ndbout << get_error_text(result) << endl;
}
#endif
}
@@ -913,7 +920,7 @@ void CommandInterpreter::executeError(int processId,
int result = _mgmtSrvr.insertError(processId, errorNo);
if (result != 0) {
- ndbout << _mgmtSrvr.getErrorText(result) << endl;
+ ndbout << get_error_text(result) << endl;
}
free(newpar);
}
@@ -953,7 +960,7 @@ void CommandInterpreter::executeTrace(int processId,
int result = _mgmtSrvr.setTraceNo(processId, traceNo);
if (result != 0) {
- ndbout << _mgmtSrvr.getErrorText(result) << endl;
+ ndbout << get_error_text(result) << endl;
}
free(newpar);
}
@@ -974,7 +981,7 @@ void CommandInterpreter::executeLog(int processId,
int result = _mgmtSrvr.setSignalLoggingMode(processId, MgmtSrvr::InOut, blocks);
if (result != 0) {
- ndbout << _mgmtSrvr.getErrorText(result) << endl;
+ ndbout << get_error_text(result) << endl;
}
}
@@ -995,7 +1002,7 @@ void CommandInterpreter::executeLogIn(int processId,
int result = _mgmtSrvr.setSignalLoggingMode(processId, MgmtSrvr::In, blocks);
if (result != 0) {
- ndbout << _mgmtSrvr.getErrorText(result) << endl;
+ ndbout << get_error_text(result) << endl;
}
}
@@ -1014,7 +1021,7 @@ void CommandInterpreter::executeLogOut(int processId,
int result = _mgmtSrvr.setSignalLoggingMode(processId, MgmtSrvr::Out, blocks);
if (result != 0) {
- ndbout << _mgmtSrvr.getErrorText(result) << endl;
+ ndbout << get_error_text(result) << endl;
}
}
@@ -1035,7 +1042,7 @@ void CommandInterpreter::executeLogOff(int processId,
int result = _mgmtSrvr.setSignalLoggingMode(processId, MgmtSrvr::Off, blocks);
if (result != 0) {
- ndbout << _mgmtSrvr.getErrorText(result) << endl;
+ ndbout << get_error_text(result) << endl;
}
}
@@ -1054,7 +1061,7 @@ void CommandInterpreter::executeTestOn(int processId,
int result = _mgmtSrvr.startSignalTracing(processId);
if (result != 0) {
- ndbout << _mgmtSrvr.getErrorText(result) << endl;
+ ndbout << get_error_text(result) << endl;
}
}
@@ -1073,7 +1080,7 @@ void CommandInterpreter::executeTestOff(int processId,
int result = _mgmtSrvr.stopSignalTracing(processId);
if (result != 0) {
- ndbout << _mgmtSrvr.getErrorText(result) << endl;
+ ndbout << get_error_text(result) << endl;
}
}
@@ -1126,7 +1133,7 @@ void CommandInterpreter::executeEventReporting(int processId,
ndbout_c("processId %d", processId);
int result = _mgmtSrvr.setEventReportingLevel(processId, logLevel);
if (result != 0) {
- ndbout << _mgmtSrvr.getErrorText(result) << endl;
+ ndbout << get_error_text(result) << endl;
}
#endif
}
@@ -1136,7 +1143,7 @@ CommandInterpreter::executeStartBackup(char* parameters) {
Uint32 backupId;
int result = _mgmtSrvr.startBackup(backupId);
if (result != 0) {
- ndbout << _mgmtSrvr.getErrorText(result) << endl;
+ ndbout << get_error_text(result) << endl;
} else {
// ndbout << "Start of backup ordered" << endl;
}
@@ -1153,7 +1160,7 @@ CommandInterpreter::executeAbortBackup(char* parameters) {
}
int result = _mgmtSrvr.abortBackup(bid);
if (result != 0) {
- ndbout << _mgmtSrvr.getErrorText(result) << endl;
+ ndbout << get_error_text(result) << endl;
} else {
ndbout << "Abort of backup " << bid << " ordered" << endl;
}
@@ -1174,7 +1181,7 @@ CommandInterpreter::executeEnterSingleUser(char* parameters) {
}
int result = _mgmtSrvr.enterSingleUser(0, nodeId,0,0);
if (result != 0) {
- ndbout << _mgmtSrvr.getErrorText(result) << endl;
+ ndbout << get_error_text(result) << endl;
} else {
ndbout << "Entering single user mode, granting access for node "
<< nodeId << " OK." << endl;
diff --git a/ndb/src/mgmsrv/CommandInterpreter.hpp b/ndb/src/mgmsrv/CommandInterpreter.hpp
index db23f76a5bd..1a5184361d6 100644
--- a/ndb/src/mgmsrv/CommandInterpreter.hpp
+++ b/ndb/src/mgmsrv/CommandInterpreter.hpp
@@ -55,6 +55,9 @@ public:
int readAndExecute();
private:
+ char m_err_str[1024];
+ const char *get_error_text(int err_no);
+
/**
* Read a string, and return a pointer to it.
*
diff --git a/ndb/src/mgmsrv/MgmtSrvr.cpp b/ndb/src/mgmsrv/MgmtSrvr.cpp
index 986da71a8e8..061aa2e0cb8 100644
--- a/ndb/src/mgmsrv/MgmtSrvr.cpp
+++ b/ndb/src/mgmsrv/MgmtSrvr.cpp
@@ -49,6 +49,8 @@
#include
+#include
+
#include
#include
#include
@@ -264,16 +266,6 @@ MgmtSrvr::isEventLogFilterEnabled(int severity)
static ErrorItem errorTable[] =
{
- {200, "Backup undefined error"},
- {202, "Backup failed to allocate buffers (check configuration)"},
- {203, "Backup failed to setup fs buffers (check configuration)"},
- {204, "Backup failed to allocate tables (check configuration)"},
- {205, "Backup failed to insert file header (check configuration)"},
- {206, "Backup failed to insert table list (check configuration)"},
- {207, "Backup failed to allocate table memory (check configuration)"},
- {208, "Backup failed to allocate file record (check configuration)"},
- {209, "Backup failed to allocate attribute record (check configuration)"},
-
{MgmtSrvr::NO_CONTACT_WITH_PROCESS, "No contact with the process (dead ?)."},
{MgmtSrvr::PROCESS_NOT_CONFIGURED, "The process is not configured."},
{MgmtSrvr::WRONG_PROCESS_TYPE,
@@ -1856,18 +1848,21 @@ MgmtSrvr::dumpState(int processId, const Uint32 args[], Uint32 no)
//****************************************************************************
//****************************************************************************
-const char* MgmtSrvr::getErrorText(int errorCode)
+const char* MgmtSrvr::getErrorText(int errorCode, char *buf, int buf_sz)
{
- static char text[255];
for (int i = 0; i < noOfErrorCodes; ++i) {
if (errorCode == errorTable[i]._errorCode) {
- return errorTable[i]._errorText;
+ BaseString::snprintf(buf, buf_sz, errorTable[i]._errorText);
+ buf[buf_sz-1]= 0;
+ return buf;
}
}
-
- BaseString::snprintf(text, 255, "Unknown management server error code %d", errorCode);
- return text;
+
+ ndb_error_string(errorCode, buf, buf_sz);
+ buf[buf_sz-1]= 0;
+
+ return buf;
}
void
diff --git a/ndb/src/mgmsrv/MgmtSrvr.hpp b/ndb/src/mgmsrv/MgmtSrvr.hpp
index 2ab11250d81..1afb0848ecc 100644
--- a/ndb/src/mgmsrv/MgmtSrvr.hpp
+++ b/ndb/src/mgmsrv/MgmtSrvr.hpp
@@ -466,7 +466,7 @@ public:
* @param errorCode: Error code to get a match error text for.
* @return The error text.
*/
- const char* getErrorText(int errorCode);
+ const char* getErrorText(int errorCode, char *buf, int buf_sz);
/**
* Get configuration
diff --git a/ndb/src/mgmsrv/Services.cpp b/ndb/src/mgmsrv/Services.cpp
index 0394c4e80bb..0208805b2d3 100644
--- a/ndb/src/mgmsrv/Services.cpp
+++ b/ndb/src/mgmsrv/Services.cpp
@@ -579,7 +579,7 @@ MgmApiSession::insertError(Parser::Context &,
m_output->println("insert error reply");
if(result != 0)
- m_output->println("result: %s", m_mgmsrv.getErrorText(result));
+ m_output->println("result: %s", get_error_text(result));
else
m_output->println("result: Ok");
m_output->println("");
@@ -597,7 +597,7 @@ MgmApiSession::setTrace(Parser::Context &,
m_output->println("set trace reply");
if(result != 0)
- m_output->println("result: %s", m_mgmsrv.getErrorText(result));
+ m_output->println("result: %s", get_error_text(result));
else
m_output->println("result: Ok");
m_output->println("");
@@ -665,7 +665,7 @@ MgmApiSession::startBackup(Parser::Context &,
m_output->println("start backup reply");
if(result != 0)
- m_output->println("result: %s(%d)", m_mgmsrv.getErrorText(result), result);
+ m_output->println("result: %s(%d)", get_error_text(result), result);
else{
m_output->println("result: Ok");
m_output->println("id: %d", backupId);
@@ -685,7 +685,7 @@ MgmApiSession::startBackup(Parser::Context &,
m_output->println("start backup reply");
if(result != 0)
- m_output->println("result: %s", m_mgmsrv.getErrorText(result));
+ m_output->println("result: %s", get_error_text(result));
else{
m_output->println("result: Ok");
m_output->println("id: %d", backupId);
@@ -705,7 +705,7 @@ MgmApiSession::abortBackup(Parser::Context &,
m_output->println("abort backup reply");
if(result != 0)
- m_output->println("result: %s", m_mgmsrv.getErrorText(result));
+ m_output->println("result: %s", get_error_text(result));
else
m_output->println("result: Ok");
m_output->println("");
@@ -727,7 +727,7 @@ MgmApiSession::repCommand(Parser::Context &,
m_output->println("global replication reply");
if(result != 0)
- m_output->println("result: %s", m_mgmsrv.getErrorText(result));
+ m_output->println("result: %s", get_error_text(result));
else{
m_output->println("result: Ok");
m_output->println("id: %d", repReqId);
@@ -749,7 +749,7 @@ MgmApiSession::dumpState(Parser::Context &,
int result = m_mgmsrv.dumpState(node, args_str.c_str());
m_output->println("dump state reply");
if(result != 0)
- m_output->println("result: %s", m_mgmsrv.getErrorText(result));
+ m_output->println("result: %s", get_error_text(result));
else
m_output->println("result: Ok");
m_output->println("");
@@ -834,7 +834,7 @@ MgmApiSession::stopSignalLog(Parser::Context &,
m_output->println("stop signallog");
if(result != 0)
- m_output->println("result: %s", m_mgmsrv.getErrorText(result));
+ m_output->println("result: %s", get_error_text(result));
else
m_output->println("result: Ok");
m_output->println("");
@@ -874,7 +874,7 @@ MgmApiSession::restart(Parser::Context &,
m_output->println("restart reply");
if(result != 0){
- m_output->println("result: %d-%s", result, m_mgmsrv.getErrorText(result));
+ m_output->println("result: %d-%s", result, get_error_text(result));
} else
m_output->println("result: Ok");
m_output->println("restarted: %d", restarted);
@@ -898,7 +898,7 @@ MgmApiSession::restartAll(Parser::Context &,
m_output->println("restart reply");
if(result != 0)
- m_output->println("result: %s", m_mgmsrv.getErrorText(result));
+ m_output->println("result: %s", get_error_text(result));
else
m_output->println("result: Ok");
m_output->println("restarted: %d", count);
@@ -1029,7 +1029,7 @@ MgmApiSession::stop(Parser::Context &,
m_output->println("stop reply");
if(result != 0)
- m_output->println("result: %s", m_mgmsrv.getErrorText(result));
+ m_output->println("result: %s", get_error_text(result));
else
m_output->println("result: Ok");
m_output->println("stopped: %d", stopped);
@@ -1051,7 +1051,7 @@ MgmApiSession::stopAll(Parser::Context &,
m_output->println("stop reply");
if(result != 0)
- m_output->println("result: %s", m_mgmsrv.getErrorText(result));
+ m_output->println("result: %s", get_error_text(result));
else
m_output->println("result: Ok");
m_output->println("stopped: %d", stopped);
@@ -1067,7 +1067,7 @@ MgmApiSession::enterSingleUser(Parser::Context &,
int result = m_mgmsrv.enterSingleUser(&stopped, nodeId);
m_output->println("enter single user reply");
if(result != 0) {
- m_output->println("result: %s", m_mgmsrv.getErrorText(result));
+ m_output->println("result: %s", get_error_text(result));
}
else {
m_output->println("result: Ok");
@@ -1082,7 +1082,7 @@ MgmApiSession::exitSingleUser(Parser::Context &,
int result = m_mgmsrv.exitSingleUser(&stopped, false);
m_output->println("exit single user reply");
if(result != 0)
- m_output->println("result: %s", m_mgmsrv.getErrorText(result));
+ m_output->println("result: %s", get_error_text(result));
else
m_output->println("result: Ok");
m_output->println("");
@@ -1100,7 +1100,7 @@ MgmApiSession::startSignalLog(Parser::Context &,
m_output->println("start signallog reply");
if(result != 0)
- m_output->println("result: %s", m_mgmsrv.getErrorText(result));
+ m_output->println("result: %s", get_error_text(result));
else
m_output->println("result: Ok");
m_output->println("");
@@ -1145,7 +1145,7 @@ MgmApiSession::logSignals(Parser::Context &,
m_output->println("log signals reply");
if(result != 0)
- m_output->println("result: %s", m_mgmsrv.getErrorText(result));
+ m_output->println("result: %s", get_error_text(result));
else
m_output->println("result: Ok");
m_output->println("");
@@ -1162,7 +1162,7 @@ MgmApiSession::start(Parser::Context &,
m_output->println("start reply");
if(result != 0)
- m_output->println("result: %s", m_mgmsrv.getErrorText(result));
+ m_output->println("result: %s", get_error_text(result));
else
m_output->println("result: Ok");
m_output->println("");
diff --git a/ndb/src/mgmsrv/Services.hpp b/ndb/src/mgmsrv/Services.hpp
index bfc915f18f1..7d614d6241c 100644
--- a/ndb/src/mgmsrv/Services.hpp
+++ b/ndb/src/mgmsrv/Services.hpp
@@ -39,10 +39,13 @@ private:
OutputStream *m_output;
Parser_t *m_parser;
MgmtSrvr::Allocated_resources *m_allocated_resources;
+ char m_err_str[1024];
void getConfig_common(Parser_t::Context &ctx,
const class Properties &args,
bool compat = false);
+ const char *get_error_text(int err_no)
+ { return m_mgmsrv.getErrorText(err_no, m_err_str, sizeof(m_err_str)); }
public:
MgmApiSession(class MgmtSrvr & mgm, NDB_SOCKET_TYPE sock);
diff --git a/ndb/src/ndbapi/ndberror.c b/ndb/src/ndbapi/ndberror.c
index 6744f4c1640..c0a6b6ba122 100644
--- a/ndb/src/ndbapi/ndberror.c
+++ b/ndb/src/ndbapi/ndberror.c
@@ -35,6 +35,7 @@ typedef struct ErrorBundle {
#define NE ndberror_cl_none
#define AE ndberror_cl_application
+#define CE ndberror_cl_configuration
#define ND ndberror_cl_no_data_found
#define CV ndberror_cl_constraint_violation
#define SE ndberror_cl_schema_error
@@ -58,6 +59,27 @@ static const char REDO_BUFFER_MSG[]=
static const char* empty_string = "";
+/*
+ * Error code ranges are reserved for respective block
+ *
+ * 200 - TC
+ * 300 - DIH
+ * 400 - LQH
+ * 600 - ACC
+ * 700 - DICT
+ * 800 - TUP
+ * 1200 - LQH
+ * 1300 - BACKUP
+ * 4000 - API
+ * 4100 - ""
+ * 4200 - ""
+ * 4300 - ""
+ * 4400 - ""
+ * 4500 - ""
+ * 4600 - ""
+ * 5000 - Management server
+ */
+
static
const
ErrorBundle ErrorCodes[] = {
@@ -303,6 +325,36 @@ ErrorBundle ErrorCodes[] = {
*/
{ 4003, NI, "Function not implemented yet" },
+ /**
+ * Backup error codes
+ */
+
+ { 1300, IE, "Undefined error" },
+ { 1301, IE, "Backup issued to not master (reissue command to master)" },
+ { 1302, IE, "Out of backup record" },
+ { 1303, IS, "Out of resources" },
+ { 1304, IE, "Sequence failure" },
+ { 1305, IE, "Backup definition not implemented" },
+ { 1306, AE, "Backup not supported in diskless mode (change Diskless)" },
+
+ { 1321, IE, "Backup aborted by application" },
+ { 1322, IE, "Backup already completed" },
+ { 1323, IE, "1323" },
+ { 1324, IE, "Backup log buffer full" },
+ { 1325, IE, "File or scan error" },
+ { 1326, IE, "Backup abortet due to node failure" },
+ { 1327, IE, "1327" },
+
+ { 1340, IE, "Backup undefined error" },
+ { 1342, AE, "Backup failed to allocate buffers (check configuration)" },
+ { 1343, AE, "Backup failed to setup fs buffers (check configuration)" },
+ { 1344, AE, "Backup failed to allocate tables (check configuration)" },
+ { 1345, AE, "Backup failed to insert file header (check configuration)" },
+ { 1346, AE, "Backup failed to insert table list (check configuration)" },
+ { 1347, AE, "Backup failed to allocate table memory (check configuration)" },
+ { 1348, AE, "Backup failed to allocate file record (check configuration)" },
+ { 1349, AE, "Backup failed to allocate attribute record (check configuration)" },
+
/**
* Still uncategorized
*/
@@ -467,6 +519,7 @@ const
ErrorStatusClassification StatusClassificationMapping[] = {
{ ST_S, NE, "No error"},
{ ST_P, AE, "Application error"},
+ { ST_P, CE, "Configuration or application error"},
{ ST_P, ND, "No data found"},
{ ST_P, CV, "Constraint violation"},
{ ST_P, SE, "Schema error"},
From b09068f8a4e43b5ab6f48e8f124e510032de5612 Mon Sep 17 00:00:00 2001
From: "jani@a193-229-222-105.elisa-laajakaista.fi" <>
Date: Mon, 29 Nov 2004 17:41:47 +0200
Subject: [PATCH 125/145] Applied some Netware related patches.
---
client/mysqladmin.cc | 9 +++++++++
netware/comp_err.def | 2 +-
netware/isamchk.def | 2 +-
netware/isamlog.def | 2 +-
netware/libmysql.def | 2 +-
netware/my_print_defaults.def | 2 +-
netware/myisam_ftdump.def | 2 +-
netware/myisamchk.def | 2 +-
netware/myisamlog.def | 2 +-
netware/myisampack.def | 2 +-
netware/mysql.def | 2 +-
netware/mysql_install.def | 2 +-
netware/mysql_install_db.def | 2 +-
netware/mysql_test_run.def | 2 +-
netware/mysql_waitpid.def | 2 +-
netware/mysqladmin.def | 2 +-
netware/mysqlbinlog.def | 2 +-
netware/mysqlcheck.def | 2 +-
netware/mysqld.def | 2 +-
netware/mysqld_safe.def | 2 +-
netware/mysqldump.def | 2 +-
netware/mysqlimport.def | 2 +-
netware/mysqlshow.def | 2 +-
netware/mysqltest.def | 2 +-
netware/pack_isam.def | 2 +-
netware/perror.def | 2 +-
netware/replace.def | 2 +-
netware/resolve_stack_dump.def | 2 +-
netware/resolveip.def | 2 +-
sql/mysqld.cc | 25 +++++++++++++++----------
30 files changed, 52 insertions(+), 38 deletions(-)
diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc
index 8491d0df7b5..b95ad83f7e8 100644
--- a/client/mysqladmin.cc
+++ b/client/mysqladmin.cc
@@ -125,6 +125,10 @@ static TYPELIB command_typelib=
static struct my_option my_long_options[] =
{
+#ifdef __NETWARE__
+ {"autoclose", 'a', " Auto close the screen on exit for NetWare",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+#endif
{"count", 'c',
"Number of iterations to make. This works with -i (--sleep) only.",
(gptr*) &nr_iterations, (gptr*) &nr_iterations, 0, GET_UINT,
@@ -218,6 +222,11 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
int error = 0;
switch(optid) {
+#ifdef __NETWARE__
+ case 'a':
+ setscreenmode(SCR_AUTOCLOSE_ON_EXIT); // auto close the screen /
+ break;
+#endif
case 'c':
opt_count_iterations= 1;
break;
diff --git a/netware/comp_err.def b/netware/comp_err.def
index d694c07174a..f27b40c7b78 100644
--- a/netware/comp_err.def
+++ b/netware/comp_err.def
@@ -2,7 +2,7 @@
# MySQL Error File Compiler
#------------------------------------------------------------------------------
MODULE libc.nlm
-COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
DESCRIPTION "MySQL Error File Compiler"
VERSION 4, 0
XDCDATA ../netware/mysql.xdc
diff --git a/netware/isamchk.def b/netware/isamchk.def
index 69e8ac0405b..31cf3fc569a 100644
--- a/netware/isamchk.def
+++ b/netware/isamchk.def
@@ -3,7 +3,7 @@
#------------------------------------------------------------------------------
MODULE libc.nlm
SCREENNAME "MySQL ISAM Table Check Tool"
-COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
DESCRIPTION "MySQL ISAM Table Check Tool"
VERSION 4, 0
STACKSIZE 65536
diff --git a/netware/isamlog.def b/netware/isamlog.def
index bb8312066ef..52f9de0d928 100644
--- a/netware/isamlog.def
+++ b/netware/isamlog.def
@@ -2,7 +2,7 @@
# ISAM Log
#------------------------------------------------------------------------------
MODULE libc.nlm
-COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
DESCRIPTION "MySQL ISAM Table Log Tool"
VERSION 4, 0
XDCDATA ../netware/mysql.xdc
diff --git a/netware/libmysql.def b/netware/libmysql.def
index 7804c4468a5..fea117dedd1 100644
--- a/netware/libmysql.def
+++ b/netware/libmysql.def
@@ -3,7 +3,7 @@
#------------------------------------------------------------------------------
MODULE libc.nlm
EXPORT @libmysql.imp
-COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
DESCRIPTION "MySQL Client Library"
VERSION 4, 0
AUTOUNLOAD
diff --git a/netware/my_print_defaults.def b/netware/my_print_defaults.def
index 49f167341ae..826981256b5 100644
--- a/netware/my_print_defaults.def
+++ b/netware/my_print_defaults.def
@@ -2,7 +2,7 @@
# My Print Defaults
#------------------------------------------------------------------------------
MODULE libc.nlm
-COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
DESCRIPTION "MySQL Print Defaults Tool"
VERSION 4, 0
XDCDATA ../netware/mysql.xdc
diff --git a/netware/myisam_ftdump.def b/netware/myisam_ftdump.def
index 259d6617445..9639404b53b 100644
--- a/netware/myisam_ftdump.def
+++ b/netware/myisam_ftdump.def
@@ -3,7 +3,7 @@
#------------------------------------------------------------------------------
MODULE libc.nlm
SCREENNAME "MySQL MyISAM Table Dump Tool"
-COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
DESCRIPTION "MySQL MyISAM Table Dump Tool"
VERSION 4, 0
STACKSIZE 65536
diff --git a/netware/myisamchk.def b/netware/myisamchk.def
index cdfe186058f..eaa01730872 100644
--- a/netware/myisamchk.def
+++ b/netware/myisamchk.def
@@ -3,7 +3,7 @@
#------------------------------------------------------------------------------
MODULE libc.nlm
SCREENNAME "MySQL MyISAM Table Check Tool"
-COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
DESCRIPTION "MySQL MyISAM Table Check Tool"
VERSION 4, 0
STACKSIZE 65536
diff --git a/netware/myisamlog.def b/netware/myisamlog.def
index 5c4cbb23361..3580c870c10 100644
--- a/netware/myisamlog.def
+++ b/netware/myisamlog.def
@@ -3,7 +3,7 @@
#------------------------------------------------------------------------------
MODULE libc.nlm
SCREENNAME "MySQL MyISAM Table Log Tool"
-COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
DESCRIPTION "MySQL MyISAM Table Log Tool"
VERSION 4, 0
XDCDATA ../netware/mysql.xdc
diff --git a/netware/myisampack.def b/netware/myisampack.def
index 9111538c2c0..a6946982236 100644
--- a/netware/myisampack.def
+++ b/netware/myisampack.def
@@ -3,7 +3,7 @@
#------------------------------------------------------------------------------
MODULE libc.nlm
SCREENNAME "MySQL MyISAM Table Pack Tool"
-COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
DESCRIPTION "MySQL MyISAM Table Pack Tool"
VERSION 4, 0
XDCDATA ../netware/mysql.xdc
diff --git a/netware/mysql.def b/netware/mysql.def
index 9b4424ed4fb..5ae8dc102a0 100644
--- a/netware/mysql.def
+++ b/netware/mysql.def
@@ -3,7 +3,7 @@
#------------------------------------------------------------------------------
MODULE libc.nlm
SCREENNAME "MySQL Monitor"
-COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
DESCRIPTION "MySQL Monitor"
VERSION 4, 0
MULTIPLE
diff --git a/netware/mysql_install.def b/netware/mysql_install.def
index 87fc76919f9..3392afb7298 100644
--- a/netware/mysql_install.def
+++ b/netware/mysql_install.def
@@ -2,7 +2,7 @@
# My Print Defaults
#------------------------------------------------------------------------------
MODULE libc.nlm
-COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
DESCRIPTION "MySQL Install Tool"
VERSION 4, 0
XDCDATA ../netware/mysql.xdc
diff --git a/netware/mysql_install_db.def b/netware/mysql_install_db.def
index 4653638b5ad..1657b7c17af 100644
--- a/netware/mysql_install_db.def
+++ b/netware/mysql_install_db.def
@@ -3,7 +3,7 @@
#------------------------------------------------------------------------------
MODULE libc.nlm
SCREENNAME "MySQL Install"
-COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
DESCRIPTION "MySQL Initial Database Installer"
VERSION 4, 0
XDCDATA ../netware/mysql.xdc
diff --git a/netware/mysql_test_run.def b/netware/mysql_test_run.def
index b34f62a1f91..d4d4baee168 100644
--- a/netware/mysql_test_run.def
+++ b/netware/mysql_test_run.def
@@ -4,7 +4,7 @@
MODULE libc.nlm
STACKSIZE 65536
SCREENNAME "MySQL Test Run"
-COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
DESCRIPTION "MySQL Test Run"
VERSION 4, 0
XDCDATA ../netware/mysql.xdc
diff --git a/netware/mysql_waitpid.def b/netware/mysql_waitpid.def
index 4d56d29c42f..da0884ccba3 100644
--- a/netware/mysql_waitpid.def
+++ b/netware/mysql_waitpid.def
@@ -3,7 +3,7 @@
#------------------------------------------------------------------------------
MODULE libc.nlm
#SCREENNAME "MySQL Tool - Wait for a Program to Terminate"
-COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
DESCRIPTION "MySQL Tool - Wait for a Program to Terminate"
VERSION 4, 0
STACKSIZE 65536
diff --git a/netware/mysqladmin.def b/netware/mysqladmin.def
index 0ace36992b1..46f90d531fa 100644
--- a/netware/mysqladmin.def
+++ b/netware/mysqladmin.def
@@ -3,7 +3,7 @@
#------------------------------------------------------------------------------
MODULE libc.nlm
SCREENNAME "MySQL Admin"
-COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
DESCRIPTION "MySQL Admin Tool"
VERSION 4, 0
XDCDATA ../netware/mysql.xdc
diff --git a/netware/mysqlbinlog.def b/netware/mysqlbinlog.def
index 89677b4a353..25a470e7353 100644
--- a/netware/mysqlbinlog.def
+++ b/netware/mysqlbinlog.def
@@ -3,7 +3,7 @@
#------------------------------------------------------------------------------
MODULE libc.nlm
SCREENNAME "MySQL Binary Log Dump Tool"
-COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
DESCRIPTION "MySQL Binary Log Dump Tool"
VERSION 4, 0
XDCDATA ../netware/mysql.xdc
diff --git a/netware/mysqlcheck.def b/netware/mysqlcheck.def
index 8820e9aae8e..7067b1d1729 100644
--- a/netware/mysqlcheck.def
+++ b/netware/mysqlcheck.def
@@ -3,7 +3,7 @@
#------------------------------------------------------------------------------
MODULE libc.nlm
SCREENNAME "MySQL Check Tool"
-COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
DESCRIPTION "MySQL Check Tool"
VERSION 4, 0
XDCDATA ../netware/mysql.xdc
diff --git a/netware/mysqld.def b/netware/mysqld.def
index 6856aefe56c..42c2d176a1b 100644
--- a/netware/mysqld.def
+++ b/netware/mysqld.def
@@ -2,7 +2,7 @@
# MySQL Server
#------------------------------------------------------------------------------
MODULE libc.nlm
-COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
DESCRIPTION "MySQL Database Server"
VERSION 4, 0
MULTIPLE
diff --git a/netware/mysqld_safe.def b/netware/mysqld_safe.def
index 9080ef783c9..2a9ef04b47d 100644
--- a/netware/mysqld_safe.def
+++ b/netware/mysqld_safe.def
@@ -3,7 +3,7 @@
#------------------------------------------------------------------------------
MODULE libc.nlm
SCREENNAME "MySQL Database Server"
-COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
DESCRIPTION "MySQL Database Server Monitor"
VERSION 4, 0
MULTIPLE
diff --git a/netware/mysqldump.def b/netware/mysqldump.def
index 901c9b262dc..ddacf7bc0d5 100644
--- a/netware/mysqldump.def
+++ b/netware/mysqldump.def
@@ -3,7 +3,7 @@
#------------------------------------------------------------------------------
MODULE libc.nlm
SCREENNAME "MySQL Dump Tool"
-COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
DESCRIPTION "MySQL Dump Tool"
VERSION 4, 0
XDCDATA ../netware/mysql.xdc
diff --git a/netware/mysqlimport.def b/netware/mysqlimport.def
index d6f7fcb6bbd..5253da42567 100644
--- a/netware/mysqlimport.def
+++ b/netware/mysqlimport.def
@@ -3,7 +3,7 @@
#------------------------------------------------------------------------------
MODULE libc.nlm
SCREENNAME "MySQL Import"
-COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
DESCRIPTION "MySQL Import Tool"
VERSION 4, 0
XDCDATA ../netware/mysql.xdc
diff --git a/netware/mysqlshow.def b/netware/mysqlshow.def
index 2b41386f643..0b61b81dcf9 100644
--- a/netware/mysqlshow.def
+++ b/netware/mysqlshow.def
@@ -3,7 +3,7 @@
#------------------------------------------------------------------------------
MODULE libc.nlm
SCREENNAME "MySQL Show"
-COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
DESCRIPTION "MySQL Show Tool"
VERSION 4, 0
XDCDATA ../netware/mysql.xdc
diff --git a/netware/mysqltest.def b/netware/mysqltest.def
index d98f6436a4a..e134acede07 100644
--- a/netware/mysqltest.def
+++ b/netware/mysqltest.def
@@ -2,7 +2,7 @@
# MySQL Admin
#------------------------------------------------------------------------------
MODULE libc.nlm
-COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
DESCRIPTION "MySQL Test Case Tool"
VERSION 4, 0
XDCDATA ../netware/mysql.xdc
diff --git a/netware/pack_isam.def b/netware/pack_isam.def
index f0f5a7e328a..b93cfdffbeb 100644
--- a/netware/pack_isam.def
+++ b/netware/pack_isam.def
@@ -2,7 +2,7 @@
# Pack ISAM
#------------------------------------------------------------------------------
MODULE libc.nlm
-COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
DESCRIPTION "MySQL ISAM Table Pack Tool"
VERSION 4, 0
XDCDATA ../netware/mysql.xdc
diff --git a/netware/perror.def b/netware/perror.def
index f1d23715f55..18c95d8b236 100644
--- a/netware/perror.def
+++ b/netware/perror.def
@@ -2,7 +2,7 @@
# PERROR
#------------------------------------------------------------------------------
MODULE libc.nlm
-COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
DESCRIPTION "MySQL Error Code Description Tool"
VERSION 4, 0
XDCDATA ../netware/mysql.xdc
diff --git a/netware/replace.def b/netware/replace.def
index b55690152b9..19348ee4245 100644
--- a/netware/replace.def
+++ b/netware/replace.def
@@ -2,7 +2,7 @@
# Replace
#------------------------------------------------------------------------------
MODULE libc.nlm
-COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
DESCRIPTION "MySQL Text Replacement Tool"
VERSION 4, 0
XDCDATA ../netware/mysql.xdc
diff --git a/netware/resolve_stack_dump.def b/netware/resolve_stack_dump.def
index 21fd177fbc7..01042699d61 100644
--- a/netware/resolve_stack_dump.def
+++ b/netware/resolve_stack_dump.def
@@ -3,7 +3,7 @@
#------------------------------------------------------------------------------
MODULE libc.nlm
#SCREENNAME "MySQL Stack Dump Resolve Tool"
-COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
DESCRIPTION "MySQL Stack Dump Resolve Tool"
VERSION 4, 0
STACKSIZE 65536
diff --git a/netware/resolveip.def b/netware/resolveip.def
index 10b99304e22..244f52bb969 100644
--- a/netware/resolveip.def
+++ b/netware/resolveip.def
@@ -2,7 +2,7 @@
# Resolve IP
#------------------------------------------------------------------------------
MODULE libc.nlm
-COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
DESCRIPTION "MySQL IP/Hostname Resolve Tool"
VERSION 4, 0
XDCDATA ../netware/mysql.xdc
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 43407b345fa..46de547e665 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -146,6 +146,7 @@ static VolumeID_t datavolid;
static event_handle_t eh;
static Report_t ref;
static void *refneb= NULL;
+my_bool event_flag= FALSE;
static int volumeid= -1;
/* NEB event callback */
@@ -815,7 +816,8 @@ static void __cdecl kill_server(int sig_ptr)
else
unireg_end();
#ifdef __NETWARE__
- pthread_join(select_thread, NULL); // wait for main thread
+ if (!event_flag)
+ pthread_join(select_thread, NULL); // wait for main thread
#endif /* __NETWARE__ */
pthread_exit(0); /* purecov: deadcode */
@@ -1525,20 +1527,20 @@ static void check_data_home(const char *path)
// down server event callback
void mysql_down_server_cb(void *, void *)
{
+ event_flag = TRUE;
kill_server(0);
}
// destroy callback resources
void mysql_cb_destroy(void *)
-{
- UnRegisterEventNotification(eh); // cleanup down event notification
+{
+ UnRegisterEventNotification(eh); // cleanup down event notification
NX_UNWRAP_INTERFACE(ref);
-
- /* Deregister NSS volume deactivation event */
- NX_UNWRAP_INTERFACE(refneb);
+ /* Deregister NSS volume deactivation event */
+ NX_UNWRAP_INTERFACE(refneb);
if (neb_consumer_id)
- UnRegisterConsumer(neb_consumer_id, NULL);
+ UnRegisterConsumer(neb_consumer_id, NULL);
}
@@ -1558,7 +1560,7 @@ void mysql_cb_init()
Register for volume deactivation event
Wrap the callback function, as it is called by non-LibC thread
*/
- (void)NX_WRAP_INTERFACE(neb_event_callback, 1, &refneb);
+ (void *) NX_WRAP_INTERFACE(neb_event_callback, 1, &refneb);
registerwithneb();
NXVmRegisterExitHandler(mysql_cb_destroy, NULL); // clean-up
@@ -1655,7 +1657,9 @@ ulong neb_event_callback(struct EventBlock *eblock)
{
consoleprintf("MySQL data volume is deactivated, shutting down MySQL Server \n");
nw_panic = TRUE;
+ event_flag= TRUE;
kill_server(0);
+
}
}
return 0;
@@ -1729,8 +1733,8 @@ static void init_signals(void)
for (uint i=0 ; i < sizeof(signals)/sizeof(int) ; i++)
signal(signals[i], kill_server);
mysql_cb_init(); // initialize callbacks
-}
+}
static void start_signal_handler(void)
{
@@ -3008,7 +3012,7 @@ we force server id to 2, but this MySQL server will not act as a slave.");
#endif /* __NT__ */
/* (void) pthread_attr_destroy(&connection_attrib); */
-
+
DBUG_PRINT("quit",("Exiting main thread"));
#ifndef __WIN__
@@ -3058,6 +3062,7 @@ we force server id to 2, but this MySQL server will not act as a slave.");
#endif
clean_up_mutexes();
my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
+
exit(0);
return(0); /* purecov: deadcode */
}
From 474f23a402ae77ff822dd2fe9710fb857d249318 Mon Sep 17 00:00:00 2001
From: "joreland@mysql.com" <>
Date: Tue, 30 Nov 2004 07:41:26 +0100
Subject: [PATCH 126/145] ndb - fixed long overdue problems with unique indexes
and null values
---
mysql-test/r/ndb_index_unique.result | 36 +++++++++++++++++++++++
mysql-test/t/ndb_index_unique.test | 20 +++++++++++++
sql/ha_ndbcluster.cc | 44 ++++++++++++++++++++++++----
3 files changed, 94 insertions(+), 6 deletions(-)
diff --git a/mysql-test/r/ndb_index_unique.result b/mysql-test/r/ndb_index_unique.result
index af9b84022ed..9a5ef4dcca7 100644
--- a/mysql-test/r/ndb_index_unique.result
+++ b/mysql-test/r/ndb_index_unique.result
@@ -522,3 +522,39 @@ uid gid rid cid
1 1 2 3
1 1 2 4
drop table t1,t2,t3,t4,t5,t6,t7;
+CREATE TABLE t1 (
+a int unsigned NOT NULL PRIMARY KEY,
+b int unsigned,
+c int unsigned,
+UNIQUE bc(b,c) ) engine = ndb;
+insert into t1 values(1,1,1),(2,NULL,2),(3,NULL,NULL),(4,4,NULL);
+select * from t1 where b=1 and c=1;
+a b c
+1 1 1
+select * from t1 where b is null and c is null;
+a b c
+3 NULL NULL
+select * from t1 where b is null and c = 2;
+a b c
+2 NULL 2
+select * from t1 where b = 4 and c is null;
+a b c
+4 4 NULL
+create table t8 as
+select * from t1 where (b = 1 and c = 1)
+or (b is null and c is null)
+or (b is null and c = 2)
+or (b = 4 and c is null);
+select * from t8 order by a;
+a b c
+1 1 1
+2 NULL 2
+3 NULL NULL
+4 4 NULL
+select * from t1 order by a;
+a b c
+1 1 1
+2 NULL 2
+3 NULL NULL
+4 4 NULL
+drop table t1, t8;
diff --git a/mysql-test/t/ndb_index_unique.test b/mysql-test/t/ndb_index_unique.test
index bdb23949763..5cfc069d75f 100644
--- a/mysql-test/t/ndb_index_unique.test
+++ b/mysql-test/t/ndb_index_unique.test
@@ -231,4 +231,24 @@ select * from t4 where rid = 2 order by cid;
drop table t1,t2,t3,t4,t5,t6,t7;
+# test null in indexes
+CREATE TABLE t1 (
+ a int unsigned NOT NULL PRIMARY KEY,
+ b int unsigned,
+ c int unsigned,
+ UNIQUE bc(b,c) ) engine = ndb;
+
+insert into t1 values(1,1,1),(2,NULL,2),(3,NULL,NULL),(4,4,NULL);
+select * from t1 where b=1 and c=1;
+select * from t1 where b is null and c is null;
+select * from t1 where b is null and c = 2;
+select * from t1 where b = 4 and c is null;
+create table t8 as
+select * from t1 where (b = 1 and c = 1)
+ or (b is null and c is null)
+ or (b is null and c = 2)
+ or (b = 4 and c is null);
+select * from t8 order by a;
+select * from t1 order by a;
+drop table t1, t8;
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index 1962065d617..77adf0d7ed3 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -1156,9 +1156,10 @@ int ha_ndbcluster::unique_index_read(const byte *key,
for (i= 0; key_part != end; key_part++, i++)
{
- if (set_ndb_key(op, key_part->field, i, key_ptr))
+ if (set_ndb_key(op, key_part->field, i,
+ key_part->null_bit ? key_ptr + 1 : key_ptr))
ERR_RETURN(trans->getNdbError());
- key_ptr+= key_part->length;
+ key_ptr+= key_part->store_length;
}
// Get non-index attribute(s)
@@ -2243,6 +2244,28 @@ int ha_ndbcluster::index_end()
DBUG_RETURN(close_scan());
}
+/**
+ * Check if key contains null
+ */
+static
+int
+check_null_in_key(const KEY* key_info, const byte *key, uint key_len)
+{
+ KEY_PART_INFO *curr_part, *end_part;
+ const byte* end_ptr = key + key_len;
+ curr_part= key_info->key_part;
+ end_part= curr_part + key_info->key_parts;
+
+
+ for (; curr_part != end_part && key < end_ptr; curr_part++)
+ {
+ if(curr_part->null_bit && *key)
+ return 1;
+
+ key += curr_part->store_length;
+ }
+ return 0;
+}
int ha_ndbcluster::index_read(byte *buf,
const byte *key, uint key_len,
@@ -2260,6 +2283,8 @@ int ha_ndbcluster::index_read(byte *buf,
case PRIMARY_KEY_INDEX:
if (find_flag == HA_READ_KEY_EXACT && key_info->key_length == key_len)
{
+ if(m_active_cursor && (error= close_scan()))
+ DBUG_RETURN(error);
DBUG_RETURN(pk_read(key, key_len, buf));
}
else if (type == PRIMARY_KEY_INDEX)
@@ -2269,8 +2294,11 @@ int ha_ndbcluster::index_read(byte *buf,
break;
case UNIQUE_ORDERED_INDEX:
case UNIQUE_INDEX:
- if (find_flag == HA_READ_KEY_EXACT && key_info->key_length == key_len)
+ if (find_flag == HA_READ_KEY_EXACT && key_info->key_length == key_len &&
+ !check_null_in_key(key_info, key, key_len))
{
+ if(m_active_cursor && (error= close_scan()))
+ DBUG_RETURN(error);
DBUG_RETURN(unique_index_read(key, key_len, buf));
}
else if (type == UNIQUE_INDEX)
@@ -2374,6 +2402,8 @@ int ha_ndbcluster::read_range_first_to_buf(const key_range *start_key,
start_key->length == key_info->key_length &&
start_key->flag == HA_READ_KEY_EXACT)
{
+ if(m_active_cursor && (error= close_scan()))
+ DBUG_RETURN(error);
error= pk_read(start_key->key, start_key->length, buf);
DBUG_RETURN(error == HA_ERR_KEY_NOT_FOUND ? HA_ERR_END_OF_FILE : error);
}
@@ -2381,10 +2411,12 @@ int ha_ndbcluster::read_range_first_to_buf(const key_range *start_key,
case UNIQUE_ORDERED_INDEX:
case UNIQUE_INDEX:
key_info= table->key_info + active_index;
- if (start_key &&
- start_key->length == key_info->key_length &&
- start_key->flag == HA_READ_KEY_EXACT)
+ if (start_key && start_key->length == key_info->key_length &&
+ start_key->flag == HA_READ_KEY_EXACT &&
+ !check_null_in_key(key_info, start_key->key, start_key->length))
{
+ if(m_active_cursor && (error= close_scan()))
+ DBUG_RETURN(error);
error= unique_index_read(start_key->key, start_key->length, buf);
DBUG_RETURN(error == HA_ERR_KEY_NOT_FOUND ? HA_ERR_END_OF_FILE : error);
}
From f3e201886adbbe9596a1f9839af461bd69315bec Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Tue, 30 Nov 2004 08:41:16 +0000
Subject: [PATCH 127/145] added use of mysql_cluster in mysqld (e.g. for
ndb-connectstring) added warning printout if --ndbcluster switch is given in
a "non-cluster" binary
---
sql/mysqld.cc | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 43407b345fa..da9bbb161ab 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -2237,7 +2237,13 @@ extern "C" pthread_handler_decl(handle_shutdown,arg)
#endif
-const char *load_default_groups[]= { "mysqld","server",MYSQL_BASE_VERSION,0,0};
+const char *load_default_groups[]= {
+#ifdef HAVE_NDBCLUSTER_DB
+"mysql_cluster",
+#endif
+"mysqld","server",MYSQL_BASE_VERSION,0,0};
+static const int load_default_groups_sz=
+sizeof(load_default_groups)/sizeof(load_default_groups[0]);
bool open_log(MYSQL_LOG *log, const char *hostname,
const char *opt_name, const char *extension,
@@ -2813,6 +2819,7 @@ int win_main(int argc, char **argv)
int main(int argc, char **argv)
#endif
{
+
DEBUGGER_OFF;
MY_INIT(argv[0]); // init my_sys library & pthreads
@@ -3184,7 +3191,7 @@ int main(int argc, char **argv)
and we are now stuck with it.
*/
if (my_strcasecmp(system_charset_info, argv[1],"mysql"))
- load_default_groups[3]= argv[1];
+ load_default_groups[load_default_groups_sz-2]= argv[1];
start_mode= 1;
Service.Init(argv[1], mysql_service);
return 0;
@@ -3205,7 +3212,7 @@ int main(int argc, char **argv)
opt_argv=argv;
start_mode= 1;
if (my_strcasecmp(system_charset_info, argv[2],"mysql"))
- load_default_groups[3]= argv[2];
+ load_default_groups[load_default_groups_sz-2]= argv[2];
Service.Init(argv[2], mysql_service);
return 0;
}
@@ -6109,6 +6116,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
have_ndbcluster= SHOW_OPTION_YES;
else
have_ndbcluster= SHOW_OPTION_DISABLED;
+#else
+ push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ 0,"this binary does not contain ndbcluster storage engine");
#endif
break;
case OPT_INNODB:
From 3f741570e9e7c91f6910c3b7cd42752c02a10dc0 Mon Sep 17 00:00:00 2001
From: "ram@gw.mysql.r18.ru" <>
Date: Tue, 30 Nov 2004 13:19:35 +0400
Subject: [PATCH 128/145] An additional test for 'CREATE DATABASE' with
non-default character set.
---
mysql-test/r/mysqldump.result | 22 ++++++++++++++++++++++
mysql-test/t/mysqldump.test | 4 ++++
2 files changed, 26 insertions(+)
diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result
index 5d6fbd713e8..239418733ba 100644
--- a/mysql-test/r/mysqldump.result
+++ b/mysql-test/r/mysqldump.result
@@ -352,3 +352,25 @@ USE `test`;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+create database mysqldump_test_db character set latin2 collate latin2_bin;
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE="NO_AUTO_VALUE_ON_ZERO" */;
+
+CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqldump_test_db` /*!40100 DEFAULT CHARACTER SET latin2 COLLATE latin2_bin */;
+
+USE `mysqldump_test_db`;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+
+drop database mysqldump_test_db;
diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test
index 3d8f417bad0..295658f21a8 100644
--- a/mysql-test/t/mysqldump.test
+++ b/mysql-test/t/mysqldump.test
@@ -133,3 +133,7 @@ drop table t1;
#
--exec $MYSQL_DUMP --skip-comments --databases test
+
+create database mysqldump_test_db character set latin2 collate latin2_bin;
+--exec $MYSQL_DUMP --skip-comments --databases mysqldump_test_db;
+drop database mysqldump_test_db;
From 91aec870865aa0137e7c9a6f60afec42678f38e3 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Tue, 30 Nov 2004 09:22:33 +0000
Subject: [PATCH 129/145] add warnings for INNODB,BDB,ISAM being unavailable if
switch to use is supplied, i.e. --bdb,--isam,--innodb
---
sql/mysqld.cc | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index f253ee682e6..0e0ce2cb179 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -6105,6 +6105,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
have_berkeley_db= SHOW_OPTION_YES;
else
have_berkeley_db= SHOW_OPTION_DISABLED;
+#else
+ push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ 0,"this binary does not contain DBD storage engine");
#endif
break;
case OPT_ISAM:
@@ -6113,6 +6116,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
have_isam= SHOW_OPTION_YES;
else
have_isam= SHOW_OPTION_DISABLED;
+#else
+ push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ 0,"this binary does not contain ISAM storage engine");
#endif
break;
case OPT_NDBCLUSTER:
@@ -6123,7 +6129,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
have_ndbcluster= SHOW_OPTION_DISABLED;
#else
push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
- 0,"this binary does not contain ndbcluster storage engine");
+ 0,"this binary does not contain NDBCLUSTER storage engine");
#endif
break;
case OPT_INNODB:
@@ -6132,6 +6138,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
have_innodb= SHOW_OPTION_YES;
else
have_innodb= SHOW_OPTION_DISABLED;
+#else
+ push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ 0,"this binary does not contain INNODB storage engine");
#endif
break;
case OPT_INNODB_DATA_FILE_PATH:
From d437a56bad6c5fbac15a266b6ba975b33a173421 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Tue, 30 Nov 2004 10:19:49 +0000
Subject: [PATCH 130/145] fixed bug/compiler warning rewrote safer
added return value to shutdown nicer printouts removed exit at
shutdown
---
ndb/src/common/logger/Logger.cpp | 2 +-
ndb/src/mgmapi/LocalConfig.cpp | 22 ++++++++++++++-------
ndb/src/mgmclient/CommandInterpreter.cpp | 24 ++++++++++++-----------
ndb/src/ndbapi/ndb_cluster_connection.cpp | 2 +-
4 files changed, 30 insertions(+), 20 deletions(-)
diff --git a/ndb/src/common/logger/Logger.cpp b/ndb/src/common/logger/Logger.cpp
index 1dc3bd43716..f6f70fbeff7 100644
--- a/ndb/src/common/logger/Logger.cpp
+++ b/ndb/src/common/logger/Logger.cpp
@@ -174,7 +174,7 @@ Logger::addHandler(const BaseString &logstring) {
logstring.split(logdest, ";");
for(i = 0; i < logdest.size(); i++) {
- DBUG_PRINT("info",("adding: %s",logdest[i]));
+ DBUG_PRINT("info",("adding: %s",logdest[i].c_str()));
Vector v_type_args;
logdest[i].split(v_type_args, ":", 2);
diff --git a/ndb/src/mgmapi/LocalConfig.cpp b/ndb/src/mgmapi/LocalConfig.cpp
index 8f1e2ee8100..1dc805557ee 100644
--- a/ndb/src/mgmapi/LocalConfig.cpp
+++ b/ndb/src/mgmapi/LocalConfig.cpp
@@ -298,13 +298,21 @@ char *
LocalConfig::makeConnectString(char *buf, int sz)
{
int p= BaseString::snprintf(buf,sz,"nodeid=%d", _ownNodeId);
- for (int i = 0; (i < ids.size()) && (sz-p > 0); i++)
- {
- if (ids[i].type != MgmId_TCP)
- continue;
- p+=BaseString::snprintf(buf+p,sz-p,",%s:%d",
- ids[i].name.c_str(), ids[i].port);
- }
+ if (p < sz)
+ for (unsigned i = 0; i < ids.size(); i++)
+ {
+ if (ids[i].type != MgmId_TCP)
+ continue;
+ int new_p= p+BaseString::snprintf(buf+p,sz-p,",%s:%d",
+ ids[i].name.c_str(), ids[i].port);
+ if (new_p < sz)
+ p= new_p;
+ else
+ {
+ buf[p]= 0;
+ break;
+ }
+ }
buf[sz-1]=0;
return buf;
}
diff --git a/ndb/src/mgmclient/CommandInterpreter.cpp b/ndb/src/mgmclient/CommandInterpreter.cpp
index 0fc9ada408e..ce8bafc36c5 100644
--- a/ndb/src/mgmclient/CommandInterpreter.cpp
+++ b/ndb/src/mgmclient/CommandInterpreter.cpp
@@ -97,7 +97,7 @@ private:
void executeShow(char* parameters);
void executeConnect(char* parameters);
void executePurge(char* parameters);
- void executeShutdown(char* parameters);
+ int executeShutdown(char* parameters);
void executeRun(char* parameters);
void executeInfo(char* parameters);
void executeClusterLog(char* parameters);
@@ -523,7 +523,7 @@ CommandInterpreter::execute_impl(const char *_line)
DBUG_RETURN(true);
}
else if (strcasecmp(firstToken, "SHUTDOWN") == 0) {
- executeShutdown(allAfterFirstToken);
+ m_error= executeShutdown(allAfterFirstToken);
DBUG_RETURN(true);
}
else if (strcasecmp(firstToken, "CLUSTERLOG") == 0){
@@ -854,23 +854,23 @@ CommandInterpreter::executeHelp(char* parameters)
* SHUTDOWN
*****************************************************************************/
-void
+int
CommandInterpreter::executeShutdown(char* parameters)
{
ndb_mgm_cluster_state *state = ndb_mgm_get_status(m_mgmsrv);
if(state == NULL) {
ndbout_c("Could not get status");
printError();
- return;
+ return 1;
}
NdbAutoPtr ap1((char*)state);
int result = 0;
result = ndb_mgm_stop(m_mgmsrv, 0, 0);
if (result < 0) {
- ndbout << "Shutdown failed." << endl;
+ ndbout << "Shutdown off NDB Cluster storage node(s) failed." << endl;
printError();
- return;
+ return result;
}
ndbout << result << " NDB Cluster storage node(s) have shutdown." << endl;
@@ -885,21 +885,23 @@ CommandInterpreter::executeShutdown(char* parameters)
ndbout << "Unable to locate management server, "
<< "shutdown manually with STOP"
<< endl;
- return;
+ return 1;
}
}
}
- result = 0;
result = ndb_mgm_stop(m_mgmsrv, 1, &mgm_id);
if (result <= 0) {
- ndbout << "Shutdown failed." << endl;
+ ndbout << "Shutdown of NDB Cluster management server failed." << endl;
printError();
- return;
+ if (result == 0)
+ return 1;
+ return result;
}
+ connected = false;
ndbout << "NDB Cluster management server shutdown." << endl;
- exit(0);
+ return 0;
}
/*****************************************************************************
diff --git a/ndb/src/ndbapi/ndb_cluster_connection.cpp b/ndb/src/ndbapi/ndb_cluster_connection.cpp
index b2043b2c2c1..8a5a61df171 100644
--- a/ndb/src/ndbapi/ndb_cluster_connection.cpp
+++ b/ndb/src/ndbapi/ndb_cluster_connection.cpp
@@ -128,7 +128,7 @@ int Ndb_cluster_connection::connect(int reconnect)
new ConfigRetriever(m_connect_string, NDB_VERSION, NODE_TYPE_API);
if (m_config_retriever->hasError())
{
- printf("Could not connect initialize handle to management server",
+ printf("Could not connect initialize handle to management server: %s",
m_config_retriever->getErrorString());
DBUG_RETURN(-1);
}
From d209371a46a5a18b559907edcdeab64411385164 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Tue, 30 Nov 2004 10:22:50 +0000
Subject: [PATCH 131/145] mysqld.cc: fixed typo
---
sql/mysqld.cc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 0e0ce2cb179..bb1a6bc25ba 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -6107,7 +6107,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
have_berkeley_db= SHOW_OPTION_DISABLED;
#else
push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
- 0,"this binary does not contain DBD storage engine");
+ 0,"this binary does not contain BDB storage engine");
#endif
break;
case OPT_ISAM:
From c15b45df506231142899ae2ba89722f1404497ce Mon Sep 17 00:00:00 2001
From: "ram@gw.mysql.r18.ru" <>
Date: Tue, 30 Nov 2004 15:10:48 +0400
Subject: [PATCH 132/145] Portability fix. Why not to use UINT_MAX32 here?
---
sql/field.cc | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sql/field.cc b/sql/field.cc
index 72c27b6adf9..db4b8f352c7 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -1860,9 +1860,9 @@ int Field_long::store(double nr)
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
- else if (nr > (double) (ulong) ~0L)
+ else if (nr > (double) UINT_MAX32)
{
- res=(int32) (uint32) ~0L;
+ res= UINT_MAX32;
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
From e5d03d1b7ca13e305bc8eebe4f67d05b0f76f1ae Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Tue, 30 Nov 2004 12:02:53 +0000
Subject: [PATCH 133/145] added check connection mgmapi method added
ndb_mgm_check_connection when error is printed
---
ndb/include/mgmapi/mgmapi.h | 1 +
ndb/src/mgmapi/mgmapi.cpp | 34 ++++++++++++++++++++++++
ndb/src/mgmclient/CommandInterpreter.cpp | 7 ++---
ndb/src/mgmsrv/Services.cpp | 11 ++++++++
ndb/src/mgmsrv/Services.hpp | 1 +
5 files changed, 51 insertions(+), 3 deletions(-)
diff --git a/ndb/include/mgmapi/mgmapi.h b/ndb/include/mgmapi/mgmapi.h
index a23417f153a..26add86a468 100644
--- a/ndb/include/mgmapi/mgmapi.h
+++ b/ndb/include/mgmapi/mgmapi.h
@@ -746,6 +746,7 @@ extern "C" {
int ndb_mgm_get_string_parameter(const ndb_mgm_configuration_iterator*,
int param, const char ** value);
int ndb_mgm_purge_stale_sessions(NdbMgmHandle handle, char **);
+ int ndb_mgm_check_connection(NdbMgmHandle handle);
#ifdef __cplusplus
}
#endif
diff --git a/ndb/src/mgmapi/mgmapi.cpp b/ndb/src/mgmapi/mgmapi.cpp
index 831d14eac52..e6328604c1b 100644
--- a/ndb/src/mgmapi/mgmapi.cpp
+++ b/ndb/src/mgmapi/mgmapi.cpp
@@ -1934,4 +1934,38 @@ ndb_mgm_purge_stale_sessions(NdbMgmHandle handle, char **purged){
return res;
}
+extern "C"
+int
+ndb_mgm_check_connection(NdbMgmHandle handle){
+ CHECK_HANDLE(handle, 0);
+ CHECK_CONNECTED(handle, 0);
+ SocketOutputStream out(handle->socket);
+ SocketInputStream in(handle->socket, handle->read_timeout);
+ char buf[32];
+
+ if (out.println("check connection"))
+ goto ndb_mgm_check_connection_error;
+
+ if (out.println(""))
+ goto ndb_mgm_check_connection_error;
+
+ in.gets(buf, sizeof(buf));
+ if(strcmp("check connection reply\n", buf))
+ goto ndb_mgm_check_connection_error;
+
+ in.gets(buf, sizeof(buf));
+ if(strcmp("result: Ok\n", buf))
+ goto ndb_mgm_check_connection_error;
+
+ in.gets(buf, sizeof(buf));
+ if(strcmp("\n", buf))
+ goto ndb_mgm_check_connection_error;
+
+ return 0;
+
+ndb_mgm_check_connection_error:
+ ndb_mgm_disconnect(handle);
+ return -1;
+}
+
template class Vector*>;
diff --git a/ndb/src/mgmclient/CommandInterpreter.cpp b/ndb/src/mgmclient/CommandInterpreter.cpp
index ce8bafc36c5..f36dddf815d 100644
--- a/ndb/src/mgmclient/CommandInterpreter.cpp
+++ b/ndb/src/mgmclient/CommandInterpreter.cpp
@@ -429,6 +429,8 @@ emptyString(const char* s)
void
CommandInterpreter::printError()
{
+ if (ndb_mgm_check_connection(m_mgmsrv))
+ connected= false;
ndbout_c("* %5d: %s",
ndb_mgm_get_latest_error(m_mgmsrv),
ndb_mgm_get_latest_error_msg(m_mgmsrv));
@@ -1030,9 +1032,6 @@ CommandInterpreter::executeShow(char* parameters)
{
int i;
if (emptyString(parameters)) {
- ndbout << "Cluster Configuration" << endl
- << "---------------------" << endl;
-
ndb_mgm_cluster_state *state = ndb_mgm_get_status(m_mgmsrv);
if(state == NULL) {
ndbout_c("Could not get status");
@@ -1092,6 +1091,8 @@ CommandInterpreter::executeShow(char* parameters)
}
}
+ ndbout << "Cluster Configuration" << endl
+ << "---------------------" << endl;
print_nodes(state, it, "ndbd", ndb_nodes, NDB_MGM_NODE_TYPE_NDB, master_id);
print_nodes(state, it, "ndb_mgmd", mgm_nodes, NDB_MGM_NODE_TYPE_MGM, 0);
print_nodes(state, it, "mysqld", api_nodes, NDB_MGM_NODE_TYPE_API, 0);
diff --git a/ndb/src/mgmsrv/Services.cpp b/ndb/src/mgmsrv/Services.cpp
index 0208805b2d3..5834d40cc78 100644
--- a/ndb/src/mgmsrv/Services.cpp
+++ b/ndb/src/mgmsrv/Services.cpp
@@ -244,6 +244,8 @@ ParserRow commands[] = {
MGM_CMD("purge stale sessions", &MgmApiSession::purge_stale_sessions, ""),
+ MGM_CMD("check connection", &MgmApiSession::check_connection, ""),
+
MGM_END()
};
@@ -1454,6 +1456,15 @@ MgmApiSession::purge_stale_sessions(Parser_t::Context &ctx,
m_output->println("");
}
+void
+MgmApiSession::check_connection(Parser_t::Context &ctx,
+ const class Properties &args)
+{
+ m_output->println("check connection reply");
+ m_output->println("result: Ok");
+ m_output->println("");
+}
+
template class MutexVector;
template class Vector const*>;
template class Vector;
diff --git a/ndb/src/mgmsrv/Services.hpp b/ndb/src/mgmsrv/Services.hpp
index 7d614d6241c..6a5f06a659e 100644
--- a/ndb/src/mgmsrv/Services.hpp
+++ b/ndb/src/mgmsrv/Services.hpp
@@ -91,6 +91,7 @@ public:
void listen_event(Parser_t::Context &ctx, const class Properties &args);
void purge_stale_sessions(Parser_t::Context &ctx, const class Properties &args);
+ void check_connection(Parser_t::Context &ctx, const class Properties &args);
void repCommand(Parser_t::Context &ctx, const class Properties &args);
};
From 2d1458ea5bbb91595dd5284533566f7052445c9e Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Tue, 30 Nov 2004 14:52:05 +0000
Subject: [PATCH 134/145] mysqld.cc: fixed erroneous previous push
---
sql/mysqld.cc | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index bb1a6bc25ba..f3c89b110af 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -6106,8 +6106,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
else
have_berkeley_db= SHOW_OPTION_DISABLED;
#else
- push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
- 0,"this binary does not contain BDB storage engine");
+ if (opt_bdb)
+ push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ 0,"this binary does not contain BDB storage engine");
#endif
break;
case OPT_ISAM:
@@ -6117,8 +6118,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
else
have_isam= SHOW_OPTION_DISABLED;
#else
- push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
- 0,"this binary does not contain ISAM storage engine");
+ if (opt_isam)
+ push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ 0,"this binary does not contain ISAM storage engine");
#endif
break;
case OPT_NDBCLUSTER:
@@ -6128,8 +6130,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
else
have_ndbcluster= SHOW_OPTION_DISABLED;
#else
- push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
- 0,"this binary does not contain NDBCLUSTER storage engine");
+ if (opt_ndbcluster)
+ push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ 0,"this binary does not contain NDBCLUSTER storage engine");
#endif
break;
case OPT_INNODB:
@@ -6139,8 +6142,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
else
have_innodb= SHOW_OPTION_DISABLED;
#else
- push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
- 0,"this binary does not contain INNODB storage engine");
+ if (opt_innodb)
+ push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ 0,"this binary does not contain INNODB storage engine");
#endif
break;
case OPT_INNODB_DATA_FILE_PATH:
From abb50b38ee25fa60087b692609cb9368bb539d92 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Tue, 30 Nov 2004 15:08:26 +0000
Subject: [PATCH 135/145] ps_7ndb.result, ps_7ndb.test: ndb now runs ps tests
just like the others
---
mysql-test/r/ps_7ndb.result | 154 +++++++++-------
mysql-test/t/ps_7ndb.test | 358 +-----------------------------------
2 files changed, 91 insertions(+), 421 deletions(-)
diff --git a/mysql-test/r/ps_7ndb.result b/mysql-test/r/ps_7ndb.result
index 70118509d0b..4fe7f57973f 100644
--- a/mysql-test/r/ps_7ndb.result
+++ b/mysql-test/r/ps_7ndb.result
@@ -2,20 +2,19 @@ use test;
drop table if exists t1, t9 ;
create table t1
(
-a int not null, b varchar(30),
+a int, b varchar(30),
primary key(a)
) engine = 'NDB' ;
-drop table if exists t9;
create table t9
(
-c1 tinyint not null, c2 smallint, c3 mediumint, c4 int,
+c1 tinyint, c2 smallint, c3 mediumint, c4 int,
c5 integer, c6 bigint, c7 float, c8 double,
c9 double precision, c10 real, c11 decimal(7, 4), c12 numeric(8, 4),
c13 date, c14 datetime, c15 timestamp(14), c16 time,
c17 year, c18 bit, c19 bool, c20 char,
-c21 char(10), c22 varchar(30), c23 char(100), c24 char(100),
-c25 char(100), c26 char(100), c27 char(100), c28 char(100),
-c29 char(100), c30 char(100), c31 enum('one', 'two', 'three'),
+c21 char(10), c22 varchar(30), c23 tinyblob, c24 tinytext,
+c25 blob, c26 text, c27 mediumblob, c28 mediumtext,
+c29 longblob, c30 longtext, c31 enum('one', 'two', 'three'),
c32 set('monday', 'tuesday', 'wednesday'),
primary key(c1)
) engine = 'NDB' ;
@@ -72,14 +71,14 @@ def test t9 t9 c19 c19 1 1 1 Y 32768 0 63
def test t9 t9 c20 c20 254 1 1 Y 0 0 8
def test t9 t9 c21 c21 253 10 10 Y 0 0 8
def test t9 t9 c22 c22 253 30 30 Y 0 0 8
-def test t9 t9 c23 c23 253 100 8 Y 0 0 8
-def test t9 t9 c24 c24 253 100 8 Y 0 0 8
-def test t9 t9 c25 c25 253 100 4 Y 0 0 8
-def test t9 t9 c26 c26 253 100 4 Y 0 0 8
-def test t9 t9 c27 c27 253 100 10 Y 0 0 8
-def test t9 t9 c28 c28 253 100 10 Y 0 0 8
-def test t9 t9 c29 c29 253 100 8 Y 0 0 8
-def test t9 t9 c30 c30 253 100 8 Y 0 0 8
+def test t9 t9 c23 c23 252 255 8 Y 144 0 63
+def test t9 t9 c24 c24 252 255 8 Y 16 0 8
+def test t9 t9 c25 c25 252 65535 4 Y 144 0 63
+def test t9 t9 c26 c26 252 65535 4 Y 16 0 8
+def test t9 t9 c27 c27 252 16777215 10 Y 144 0 63
+def test t9 t9 c28 c28 252 16777215 10 Y 16 0 8
+def test t9 t9 c29 c29 252 16777215 8 Y 144 0 63
+def test t9 t9 c30 c30 252 16777215 8 Y 16 0 8
def test t9 t9 c31 c31 254 5 3 Y 256 0 8
def test t9 t9 c32 c32 254 24 7 Y 2048 0 8
c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32
@@ -1188,7 +1187,7 @@ c29= 'longblob', c30= 'longtext', c31='two', c32= 'tuesday';
commit ;
prepare stmt1 from 'delete from t1 where a=2' ;
execute stmt1;
-select a,b from t1 where a=2 order by b;
+select a,b from t1 where a=2;
a b
execute stmt1;
insert into t1 values(0,NULL);
@@ -1270,18 +1269,23 @@ execute stmt1 using @arg00, @arg00;
select a,b from t1 where a=@arg00;
a b
2 two
+execute stmt1 using @arg01, @arg00;
select a,b from t1 where a=@arg01;
a b
+22 two
execute stmt1 using @arg00, @arg01;
select a,b from t1 where a=@arg00;
a b
2 two
set @arg00=NULL;
set @arg01=2;
+execute stmt1 using @arg00, @arg01;
+Warnings:
+Warning 1263 Data truncated; NULL supplied to NOT NULL column 'a' at row 1
select a,b from t1 order by a;
a b
+0 two
1 one
-2 two
3 three
4 four
set @arg00=0;
@@ -1302,15 +1306,19 @@ create table t2 as select a,b from t1 ;
prepare stmt1 from 'update t1 set a=? where b=?
and a in (select ? from t2
where b = ? or a = ?)';
+execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04 ;
+affected rows: 1
+info: Rows matched: 1 Changed: 1 Warnings: 0
select a,b from t1 where a = @arg00 ;
a b
+23 two
prepare stmt1 from 'update t1 set a=? where b=?
and a not in (select ? from t2
where b = ? or a = ?)';
execute stmt1 using @arg04, @arg01, @arg02, @arg03, @arg00 ;
-affected rows: 0
-info: Rows matched: 0 Changed: 0 Warnings: 0
-select a,b from t1 order by a;
+affected rows: 1
+info: Rows matched: 1 Changed: 1 Warnings: 0
+select a,b from t1 order by a ;
a b
1 one
2 two
@@ -1319,21 +1327,25 @@ a b
drop table t2 ;
create table t2
(
-a int not null, b varchar(30),
+a int, b varchar(30),
primary key(a)
) engine = 'NDB' ;
insert into t2(a,b) select a, b from t1 ;
prepare stmt1 from 'update t1 set a=? where b=?
and a in (select ? from t2
where b = ? or a = ?)';
+execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04 ;
+affected rows: 1
+info: Rows matched: 1 Changed: 1 Warnings: 0
select a,b from t1 where a = @arg00 ;
a b
+23 two
prepare stmt1 from 'update t1 set a=? where b=?
and a not in (select ? from t2
where b = ? or a = ?)';
execute stmt1 using @arg04, @arg01, @arg02, @arg03, @arg00 ;
-affected rows: 0
-info: Rows matched: 0 Changed: 0 Warnings: 0
+affected rows: 1
+info: Rows matched: 1 Changed: 1 Warnings: 0
select a,b from t1 order by a ;
a b
1 one
@@ -1474,7 +1486,7 @@ set @arg02=82 ;
set @arg03='8-2' ;
prepare stmt1 from 'insert into t1 values(?,?),(?,?)';
execute stmt1 using @arg00, @arg01, @arg02, @arg03 ;
-select a,b from t1 where a in (@arg00,@arg02) order by a ;
+select a,b from t1 where a in (@arg00,@arg02) ;
a b
81 8-1
82 8-2
@@ -1489,6 +1501,7 @@ set @arg00=6 ;
set @arg01=1 ;
prepare stmt1 from 'insert into t1 set a=?, b=''sechs''
on duplicate key update a=a + ?, b=concat(b,''modified'') ';
+execute stmt1 using @arg00, @arg01;
select * from t1 order by a;
a b
0 NULL
@@ -1497,13 +1510,15 @@ a b
3 three
4 four
5 five
-6 six
+7 sixmodified
8 eight
9 nine
81 8-1
82 8-2
set @arg00=81 ;
set @arg01=1 ;
+execute stmt1 using @arg00, @arg01;
+ERROR 23000: Duplicate entry '82' for key 1
drop table if exists t2 ;
create table t2 (id int auto_increment primary key)
ENGINE= 'NDB' ;
@@ -1526,23 +1541,32 @@ set @x1100="x1100" ;
set @100=100 ;
set @updated="updated" ;
insert into t1 values(1000,'x1000_1') ;
+insert into t1 values(@1000,@x1000_2),(@1000,@x1000_3)
+on duplicate key update a = a + @100, b = concat(b,@updated) ;
select a,b from t1 where a >= 1000 order by a ;
a b
-1000 x1000_1
+1000 x1000_3
+1100 x1000_1updated
delete from t1 where a >= 1000 ;
insert into t1 values(1000,'x1000_1') ;
prepare stmt1 from ' insert into t1 values(?,?),(?,?)
on duplicate key update a = a + ?, b = concat(b,?) ';
+execute stmt1 using @1000, @x1000_2, @1000, @x1000_3, @100, @updated ;
select a,b from t1 where a >= 1000 order by a ;
a b
-1000 x1000_1
+1000 x1000_3
+1100 x1000_1updated
delete from t1 where a >= 1000 ;
insert into t1 values(1000,'x1000_1') ;
+execute stmt1 using @1000, @x1000_2, @1100, @x1000_3, @100, @updated ;
select a,b from t1 where a >= 1000 order by a ;
a b
-1000 x1000_1
+1200 x1000_1updatedupdated
delete from t1 where a >= 1000 ;
prepare stmt1 from ' replace into t1 (a,b) select 100, ''hundred'' ';
+execute stmt1;
+execute stmt1;
+execute stmt1;
test_sequence
------ multi table tests ------
delete from t1 ;
@@ -1891,13 +1915,13 @@ def @arg19 254 20 1 Y 128 31 63
def @arg20 254 8192 1 Y 0 31 8
def @arg21 254 8192 10 Y 0 31 8
def @arg22 254 8192 30 Y 0 31 8
-def @arg23 254 8192 8 Y 0 31 8
+def @arg23 254 8192 8 Y 128 31 63
def @arg24 254 8192 8 Y 0 31 8
-def @arg25 254 8192 4 Y 0 31 8
+def @arg25 254 8192 4 Y 128 31 63
def @arg26 254 8192 4 Y 0 31 8
-def @arg27 254 8192 10 Y 0 31 8
+def @arg27 254 8192 10 Y 128 31 63
def @arg28 254 8192 10 Y 0 31 8
-def @arg29 254 8192 8 Y 0 31 8
+def @arg29 254 8192 8 Y 128 31 63
def @arg30 254 8192 8 Y 0 31 8
def @arg31 254 8192 3 Y 0 31 8
def @arg32 254 8192 6 Y 128 31 63
@@ -1938,13 +1962,13 @@ def @arg19 254 20 0 Y 128 31 63
def @arg20 254 8192 0 Y 0 31 8
def @arg21 254 8192 0 Y 0 31 8
def @arg22 254 8192 0 Y 0 31 8
-def @arg23 254 8192 0 Y 0 31 8
+def @arg23 254 8192 0 Y 128 31 63
def @arg24 254 8192 0 Y 0 31 8
-def @arg25 254 8192 0 Y 0 31 8
+def @arg25 254 8192 0 Y 128 31 63
def @arg26 254 8192 0 Y 0 31 8
-def @arg27 254 8192 0 Y 0 31 8
+def @arg27 254 8192 0 Y 128 31 63
def @arg28 254 8192 0 Y 0 31 8
-def @arg29 254 8192 0 Y 0 31 8
+def @arg29 254 8192 0 Y 128 31 63
def @arg30 254 8192 0 Y 0 31 8
def @arg31 254 8192 0 Y 0 31 8
def @arg32 254 8192 0 Y 0 31 8
@@ -1988,13 +2012,13 @@ def @arg19 254 20 1 Y 128 31 63
def @arg20 254 8192 1 Y 0 31 8
def @arg21 254 8192 10 Y 0 31 8
def @arg22 254 8192 30 Y 0 31 8
-def @arg23 254 8192 8 Y 0 31 8
+def @arg23 254 8192 8 Y 128 31 63
def @arg24 254 8192 8 Y 0 31 8
-def @arg25 254 8192 4 Y 0 31 8
+def @arg25 254 8192 4 Y 128 31 63
def @arg26 254 8192 4 Y 0 31 8
-def @arg27 254 8192 10 Y 0 31 8
+def @arg27 254 8192 10 Y 128 31 63
def @arg28 254 8192 10 Y 0 31 8
-def @arg29 254 8192 8 Y 0 31 8
+def @arg29 254 8192 8 Y 128 31 63
def @arg30 254 8192 8 Y 0 31 8
def @arg31 254 8192 3 Y 0 31 8
def @arg32 254 8192 6 Y 128 31 63
@@ -2028,13 +2052,13 @@ def @arg19 254 20 0 Y 128 31 63
def @arg20 254 8192 0 Y 0 31 8
def @arg21 254 8192 0 Y 0 31 8
def @arg22 254 8192 0 Y 0 31 8
-def @arg23 254 8192 0 Y 0 31 8
+def @arg23 254 8192 0 Y 128 31 63
def @arg24 254 8192 0 Y 0 31 8
-def @arg25 254 8192 0 Y 0 31 8
+def @arg25 254 8192 0 Y 128 31 63
def @arg26 254 8192 0 Y 0 31 8
-def @arg27 254 8192 0 Y 0 31 8
+def @arg27 254 8192 0 Y 128 31 63
def @arg28 254 8192 0 Y 0 31 8
-def @arg29 254 8192 0 Y 0 31 8
+def @arg29 254 8192 0 Y 128 31 63
def @arg30 254 8192 0 Y 0 31 8
def @arg31 254 8192 0 Y 0 31 8
def @arg32 254 8192 0 Y 0 31 8
@@ -2076,13 +2100,13 @@ def @arg19 254 20 1 Y 128 31 63
def @arg20 254 8192 1 Y 0 31 8
def @arg21 254 8192 10 Y 0 31 8
def @arg22 254 8192 30 Y 0 31 8
-def @arg23 254 8192 8 Y 0 31 8
+def @arg23 254 8192 8 Y 128 31 63
def @arg24 254 8192 8 Y 0 31 8
-def @arg25 254 8192 4 Y 0 31 8
+def @arg25 254 8192 4 Y 128 31 63
def @arg26 254 8192 4 Y 0 31 8
-def @arg27 254 8192 10 Y 0 31 8
+def @arg27 254 8192 10 Y 128 31 63
def @arg28 254 8192 10 Y 0 31 8
-def @arg29 254 8192 8 Y 0 31 8
+def @arg29 254 8192 8 Y 128 31 63
def @arg30 254 8192 8 Y 0 31 8
def @arg31 254 8192 3 Y 0 31 8
def @arg32 254 8192 6 Y 128 31 63
@@ -2120,13 +2144,13 @@ def @arg19 254 20 0 Y 128 31 63
def @arg20 254 8192 0 Y 0 31 8
def @arg21 254 8192 0 Y 0 31 8
def @arg22 254 8192 0 Y 0 31 8
-def @arg23 254 8192 0 Y 0 31 8
+def @arg23 254 8192 0 Y 128 31 63
def @arg24 254 8192 0 Y 0 31 8
-def @arg25 254 8192 0 Y 0 31 8
+def @arg25 254 8192 0 Y 128 31 63
def @arg26 254 8192 0 Y 0 31 8
-def @arg27 254 8192 0 Y 0 31 8
+def @arg27 254 8192 0 Y 128 31 63
def @arg28 254 8192 0 Y 0 31 8
-def @arg29 254 8192 0 Y 0 31 8
+def @arg29 254 8192 0 Y 128 31 63
def @arg30 254 8192 0 Y 0 31 8
def @arg31 254 8192 0 Y 0 31 8
def @arg32 254 8192 0 Y 0 31 8
@@ -2166,13 +2190,13 @@ def @arg19 254 20 1 Y 128 31 63
def @arg20 254 8192 1 Y 0 31 8
def @arg21 254 8192 10 Y 0 31 8
def @arg22 254 8192 30 Y 0 31 8
-def @arg23 254 8192 8 Y 0 31 8
+def @arg23 254 8192 8 Y 128 31 63
def @arg24 254 8192 8 Y 0 31 8
-def @arg25 254 8192 4 Y 0 31 8
+def @arg25 254 8192 4 Y 128 31 63
def @arg26 254 8192 4 Y 0 31 8
-def @arg27 254 8192 10 Y 0 31 8
+def @arg27 254 8192 10 Y 128 31 63
def @arg28 254 8192 10 Y 0 31 8
-def @arg29 254 8192 8 Y 0 31 8
+def @arg29 254 8192 8 Y 128 31 63
def @arg30 254 8192 8 Y 0 31 8
def @arg31 254 8192 3 Y 0 31 8
def @arg32 254 8192 6 Y 128 31 63
@@ -2204,13 +2228,13 @@ def @arg19 254 20 0 Y 128 31 63
def @arg20 254 8192 0 Y 0 31 8
def @arg21 254 8192 0 Y 0 31 8
def @arg22 254 8192 0 Y 0 31 8
-def @arg23 254 8192 0 Y 0 31 8
+def @arg23 254 8192 0 Y 128 31 63
def @arg24 254 8192 0 Y 0 31 8
-def @arg25 254 8192 0 Y 0 31 8
+def @arg25 254 8192 0 Y 128 31 63
def @arg26 254 8192 0 Y 0 31 8
-def @arg27 254 8192 0 Y 0 31 8
+def @arg27 254 8192 0 Y 128 31 63
def @arg28 254 8192 0 Y 0 31 8
-def @arg29 254 8192 0 Y 0 31 8
+def @arg29 254 8192 0 Y 128 31 63
def @arg30 254 8192 0 Y 0 31 8
def @arg31 254 8192 0 Y 0 31 8
def @arg32 254 8192 0 Y 0 31 8
@@ -2770,14 +2794,14 @@ c1 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30
41 4 41 41 41 41 41 41 41 41 41 41
42 4 42 42 42 42 42 42 42 42 42 42
43 4 43 43 43 43 43 43 43 43 43 43
-50 5 50 50 50 50 50 50 50 50 50 50
+50 5 50 50 50.00 50.00 50.00 50.00 50.00 50.00 50.00 50.00
51 5 51 51 51 51 51 51 51 51 51 51
-52 5 52 52 52 52 52 52 52 52 52 52
-53 5 53 53 53 53 53 53 53 53 53 53
-54 5 54 54 54 54 54 54 54 54 54 54
+52 5 52 52 52.00 52.00 52.00 52.00 52.00 52.00 52.00 52.00
+53 5 53 53 53.00 53.00 53.00 53.00 53.00 53.00 53.00 53.00
+54 5 54 54 54.00 54.00 54.00 54.00 54.00 54.00 54.00 54.00
55 5 55 55 55 55 55 55 55 55 55 55
-56 6 56 56 56 56 56 56 56 56 56 56
-57 6 57 57 57 57 57 57 57 57 57 57
+56 6 56 56 56.00 56.00 56.00 56.00 56.00 56.00 56.00 56.00
+57 6 57 57 57.00 57.00 57.00 57.00 57.00 57.00 57.00 57.00
60 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL
61 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL
62 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL
diff --git a/mysql-test/t/ps_7ndb.test b/mysql-test/t/ps_7ndb.test
index 22370a7f3ac..b558f2f3c21 100644
--- a/mysql-test/t/ps_7ndb.test
+++ b/mysql-test/t/ps_7ndb.test
@@ -12,365 +12,11 @@ use test;
-- source include/have_ndb.inc
let $type= 'NDB' ;
---disable_warnings
-drop table if exists t1, t9 ;
---enable_warnings
-eval create table t1
-(
- a int not null, b varchar(30),
- primary key(a)
-) engine = $type ;
-
---disable_warnings
-drop table if exists t9;
---enable_warnings
-# The used table type doesn't support BLOB/TEXT columns.
-# (The server would send error 1163 .)
-# So we use char(100) instead.
-eval create table t9
-(
- c1 tinyint not null, c2 smallint, c3 mediumint, c4 int,
- c5 integer, c6 bigint, c7 float, c8 double,
- c9 double precision, c10 real, c11 decimal(7, 4), c12 numeric(8, 4),
- c13 date, c14 datetime, c15 timestamp(14), c16 time,
- c17 year, c18 bit, c19 bool, c20 char,
- c21 char(10), c22 varchar(30), c23 char(100), c24 char(100),
- c25 char(100), c26 char(100), c27 char(100), c28 char(100),
- c29 char(100), c30 char(100), c31 enum('one', 'two', 'three'),
- c32 set('monday', 'tuesday', 'wednesday'),
- primary key(c1)
-) engine = $type ;
+-- source include/ps_create.inc
-- source include/ps_renew.inc
-- source include/ps_query.inc
-# The following line is deactivated, because the ndb storage engine is not able
-# to do primary key column updates .
-#-- source include/ps_modify.inc
-# let's include all statements which will work
---disable_query_log
-select '------ delete tests ------' as test_sequence ;
---enable_query_log
---source include/ps_renew.inc
-
-## delete without parameter
-prepare stmt1 from 'delete from t1 where a=2' ;
-execute stmt1;
-select a,b from t1 where a=2 order by b;
-# delete with row not found
-execute stmt1;
-
-## delete with one parameter in the where clause
-insert into t1 values(0,NULL);
-set @arg00=NULL;
-prepare stmt1 from 'delete from t1 where b=?' ;
-execute stmt1 using @arg00;
-select a,b from t1 where b is NULL ;
-set @arg00='one';
-execute stmt1 using @arg00;
-select a,b from t1 where b=@arg00;
-
-## truncate a table
---error 1295
-prepare stmt1 from 'truncate table t1' ;
-
-
---disable_query_log
-select '------ update tests ------' as test_sequence ;
---enable_query_log
---source include/ps_renew.inc
-
-## update without parameter
-prepare stmt1 from 'update t1 set b=''a=two'' where a=2' ;
-execute stmt1;
-select a,b from t1 where a=2;
-# dummy update
-execute stmt1;
-select a,b from t1 where a=2;
-
-## update with one parameter in the set clause
-set @arg00=NULL;
-prepare stmt1 from 'update t1 set b=? where a=2' ;
-execute stmt1 using @arg00;
-select a,b from t1 where a=2;
-set @arg00='two';
-execute stmt1 using @arg00;
-select a,b from t1 where a=2;
-
-## update with one parameter in the where cause
-set @arg00=2;
-prepare stmt1 from 'update t1 set b=NULL where a=?' ;
-execute stmt1 using @arg00;
-select a,b from t1 where a=@arg00;
-update t1 set b='two' where a=@arg00;
-# row not found in update
-set @arg00=2000;
-execute stmt1 using @arg00;
-select a,b from t1 where a=@arg00;
-
-## update on primary key column (two parameters)
-set @arg00=2;
-set @arg01=22;
-prepare stmt1 from 'update t1 set a=? where a=?' ;
-# dummy update
-execute stmt1 using @arg00, @arg00;
-select a,b from t1 where a=@arg00;
-# deactivated primary key column update
-# execute stmt1 using @arg01, @arg00;
-select a,b from t1 where a=@arg01;
-execute stmt1 using @arg00, @arg01;
-select a,b from t1 where a=@arg00;
-set @arg00=NULL;
-set @arg01=2;
-# deactivated primary key column update
-# execute stmt1 using @arg00, @arg01;
-select a,b from t1 order by a;
-set @arg00=0;
-execute stmt1 using @arg01, @arg00;
-select a,b from t1 order by a;
-
-## update with subquery and several parameters
-set @arg00=23;
-set @arg01='two';
-set @arg02=2;
-set @arg03='two';
-set @arg04=2;
---disable_warnings
-drop table if exists t2;
---enable_warnings
-# t2 will be of table type 'MYISAM'
-create table t2 as select a,b from t1 ;
-prepare stmt1 from 'update t1 set a=? where b=?
- and a in (select ? from t2
- where b = ? or a = ?)';
---enable_info
-# deactivated primary key column update
-# execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04 ;
---disable_info
-select a,b from t1 where a = @arg00 ;
-prepare stmt1 from 'update t1 set a=? where b=?
- and a not in (select ? from t2
- where b = ? or a = ?)';
---enable_info
-execute stmt1 using @arg04, @arg01, @arg02, @arg03, @arg00 ;
---disable_info
-select a,b from t1 order by a;
-drop table t2 ;
-# t2 is now of table type '$type'
-# The test battery for table type 'MERGE' gets here only a 'MYISAM' table
-eval create table t2
-(
- a int not null, b varchar(30),
- primary key(a)
-) engine = $type ;
-insert into t2(a,b) select a, b from t1 ;
-prepare stmt1 from 'update t1 set a=? where b=?
- and a in (select ? from t2
- where b = ? or a = ?)';
---enable_info
-# deactivated primary key column update
-# execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04 ;
---disable_info
-select a,b from t1 where a = @arg00 ;
-prepare stmt1 from 'update t1 set a=? where b=?
- and a not in (select ? from t2
- where b = ? or a = ?)';
---enable_info
-execute stmt1 using @arg04, @arg01, @arg02, @arg03, @arg00 ;
---disable_info
-select a,b from t1 order by a ;
-drop table t2 ;
-
-## update with parameters in limit
-set @arg00=1;
-prepare stmt1 from 'update t1 set b=''bla''
-where a=2
-limit 1';
-execute stmt1 ;
-select a,b from t1 where b = 'bla' ;
-# currently (May 2004, Version 4.1) it is impossible
--- error 1064
-prepare stmt1 from 'update t1 set b=''bla''
-where a=2
-limit ?';
-
---disable_query_log
-select '------ insert tests ------' as test_sequence ;
---enable_query_log
---source include/ps_renew.inc
-
-## insert without parameter
-prepare stmt1 from 'insert into t1 values(5, ''five'' )';
-execute stmt1;
-select a,b from t1 where a = 5;
-
-## insert with one parameter in values part
-set @arg00='six' ;
-prepare stmt1 from 'insert into t1 values(6, ? )';
-execute stmt1 using @arg00;
-select a,b from t1 where b = @arg00;
-# the second insert fails, because the first column is primary key
---error 1062
-execute stmt1 using @arg00;
-set @arg00=NULL ;
-prepare stmt1 from 'insert into t1 values(0, ? )';
-execute stmt1 using @arg00;
-select a,b from t1 where b is NULL;
-
-## insert with two parameter in values part
-set @arg00=8 ;
-set @arg01='eight' ;
-prepare stmt1 from 'insert into t1 values(?, ? )';
-execute stmt1 using @arg00, @arg01 ;
-select a,b from t1 where b = @arg01;
-# cases derived from client_test.c: test_null()
-set @NULL= null ;
-set @arg00= 'abc' ;
-# execute must fail, because first column is primary key (-> not null)
---error 1048
-execute stmt1 using @NULL, @NULL ;
---error 1048
-execute stmt1 using @NULL, @NULL ;
---error 1048
-execute stmt1 using @NULL, @arg00 ;
---error 1048
-execute stmt1 using @NULL, @arg00 ;
-let $1 = 2;
-while ($1)
-{
- eval set @arg01= 10000 + $1 ;
- execute stmt1 using @arg01, @arg00 ;
- dec $1;
-}
-select * from t1 where a > 10000 order by a ;
-delete from t1 where a > 10000 ;
-let $1 = 2;
-while ($1)
-{
- eval set @arg01= 10000 + $1 ;
- execute stmt1 using @arg01, @NULL ;
- dec $1;
-}
-select * from t1 where a > 10000 order by a ;
-delete from t1 where a > 10000 ;
-let $1 = 10;
-while ($1)
-{
- eval set @arg01= 10000 + $1 ;
- execute stmt1 using @arg01, @arg01 ;
- dec $1;
-}
-select * from t1 where a > 10000 order by a ;
-delete from t1 where a > 10000 ;
-
-
-## insert with two rows in values part
-set @arg00=81 ;
-set @arg01='8-1' ;
-set @arg02=82 ;
-set @arg03='8-2' ;
-prepare stmt1 from 'insert into t1 values(?,?),(?,?)';
-execute stmt1 using @arg00, @arg01, @arg02, @arg03 ;
-select a,b from t1 where a in (@arg00,@arg02) order by a ;
-
-## insert with two parameter in the set part
-set @arg00=9 ;
-set @arg01='nine' ;
-prepare stmt1 from 'insert into t1 set a=?, b=? ';
-execute stmt1 using @arg00, @arg01 ;
-select a,b from t1 where a = @arg00 ;
-
-## insert with parameters in the ON DUPLICATE KEY part
-set @arg00=6 ;
-set @arg01=1 ;
-prepare stmt1 from 'insert into t1 set a=?, b=''sechs''
- on duplicate key update a=a + ?, b=concat(b,''modified'') ';
-# There is no primary key collision, so there will be no key column update
-# If a key column update would be necessary occurs BUG#4312
-# deactivated, activate when BUG#4312: is solved
-# execute stmt1 using @arg00, @arg01;
-select * from t1 order by a;
-set @arg00=81 ;
-set @arg01=1 ;
-# deactivated, activate when BUG#4312: is solved
-# execute stmt1 using @arg00, @arg01;
-
-## insert, autoincrement column and ' SELECT LAST_INSERT_ID() '
-# cases derived from client_test.c: test_bug3117()
---disable_warnings
-drop table if exists t2 ;
---enable_warnings
-# The test battery for table type 'MERGE' gets here only a 'MYISAM' table
-eval create table t2 (id int auto_increment primary key)
-ENGINE= $type ;
-prepare stmt1 from ' select last_insert_id() ' ;
-insert into t2 values (NULL) ;
-execute stmt1 ;
-insert into t2 values (NULL) ;
-execute stmt1 ;
-drop table t2 ;
-
-## many parameters
-set @1000=1000 ;
-set @x1000_2="x1000_2" ;
-set @x1000_3="x1000_3" ;
-
-set @x1000="x1000" ;
-set @1100=1100 ;
-set @x1100="x1100" ;
-set @100=100 ;
-set @updated="updated" ;
-insert into t1 values(1000,'x1000_1') ;
-# deactivated, activate when BUG#4312: is solved
-# insert into t1 values(@1000,@x1000_2),(@1000,@x1000_3)
-# on duplicate key update a = a + @100, b = concat(b,@updated) ;
-select a,b from t1 where a >= 1000 order by a ;
-delete from t1 where a >= 1000 ;
-insert into t1 values(1000,'x1000_1') ;
-prepare stmt1 from ' insert into t1 values(?,?),(?,?)
- on duplicate key update a = a + ?, b = concat(b,?) ';
-# deactivated, activate when BUG#4312: is solved
-# execute stmt1 using @1000, @x1000_2, @1000, @x1000_3, @100, @updated ;
-select a,b from t1 where a >= 1000 order by a ;
-delete from t1 where a >= 1000 ;
-insert into t1 values(1000,'x1000_1') ;
-# deactivated, activate when BUG#4312: is solved
-# execute stmt1 using @1000, @x1000_2, @1100, @x1000_3, @100, @updated ;
-select a,b from t1 where a >= 1000 order by a ;
-delete from t1 where a >= 1000 ;
-
-## replace
-prepare stmt1 from ' replace into t1 (a,b) select 100, ''hundred'' ';
---error 1031
-
-## multi table statements
---disable_query_log
-select '------ multi table tests ------' as test_sequence ;
---enable_query_log
-# cases derived from client_test.c: test_multi
-delete from t1 ;
-delete from t9 ;
-insert into t1(a,b) values (1, 'one'), (2, 'two'), (3, 'three') ;
-insert into t9 (c1,c21)
- values (1, 'one'), (2, 'two'), (3, 'three') ;
-prepare stmt_delete from " delete t1, t9
- from t1, t9 where t1.a=t9.c1 and t1.b='updated' ";
-prepare stmt_update from " update t1, t9
- set t1.b='updated', t9.c21='updated'
- where t1.a=t9.c1 and t1.a=? ";
-prepare stmt_select1 from " select a, b from t1 order by a" ;
-prepare stmt_select2 from " select c1, c21 from t9 order by c1" ;
-set @arg00= 1 ;
-let $1= 3 ;
-while ($1)
-{
- execute stmt_update using @arg00 ;
- execute stmt_delete ;
- execute stmt_select1 ;
- execute stmt_select2 ;
- set @arg00= @arg00 + 1 ;
- dec $1 ;
-}
-
+-- source include/ps_modify.inc
-- source include/ps_modify1.inc
-- source include/ps_conv.inc
From a35a93aa3ca57767c2f3152367e436b850d2876f Mon Sep 17 00:00:00 2001
From: "marko@hundin.mysql.fi" <>
Date: Tue, 30 Nov 2004 17:34:37 +0200
Subject: [PATCH 136/145] InnoDB: Allow ALTER TABLE to do intermediate COMMIT
also when the table contains auto_increment columns. (Bug #6633)
---
innobase/include/lock0lock.h | 33 ++++++---
innobase/lock/lock0lock.c | 137 ++++++++++++++++++++++++++++-------
sql/ha_innodb.cc | 51 +++++++------
3 files changed, 161 insertions(+), 60 deletions(-)
diff --git a/innobase/include/lock0lock.h b/innobase/include/lock0lock.h
index fb44acc14f7..ff5b6aae02e 100644
--- a/innobase/include/lock0lock.h
+++ b/innobase/include/lock0lock.h
@@ -463,17 +463,32 @@ lock_rec_hash(
ulint space, /* in: space */
ulint page_no);/* in: page number */
/*************************************************************************
-Gets the table covered by an IX or IS table lock, if there are no
-other locks on the table. */
+Gets the source table of an ALTER TABLE transaction. The table must be
+covered by an IX or IS table lock. */
dict_table_t*
-lock_get_table(
-/*===========*/
- /* out: the table covered by the lock,
- or NULL if it is not an IX or IS table lock,
- or there are other locks on the table */
- lock_t* lock, /* in: lock */
- ulint* mode); /* out: lock mode of table */
+lock_get_src_table(
+/*===============*/
+ /* out: the source table of transaction,
+ if it is covered by an IX or IS table lock;
+ dest if there is no source table, and
+ NULL if the transaction is locking more than
+ two tables or an inconsistency is found */
+ trx_t* trx, /* in: transaction */
+ dict_table_t* dest, /* in: destination of ALTER TABLE */
+ ulint* mode); /* out: lock mode of the source table */
+/*************************************************************************
+Determine if the given table is exclusively "owned" by the given
+transaction, i.e., transaction holds LOCK_IX and possibly LOCK_AUTO_INC
+on the table. */
+
+ibool
+lock_table_exclusive(
+/*=================*/
+ /* out: TRUE if table is only locked by trx,
+ with LOCK_IX, and possibly LOCK_AUTO_INC */
+ dict_table_t* table, /* in: table */
+ trx_t* trx); /* in: transaction */
/*************************************************************************
Checks that a transaction id is sensible, i.e., not in the future. */
diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c
index d9a10eb60c0..16c4ddfd96d 100644
--- a/innobase/lock/lock0lock.c
+++ b/innobase/lock/lock0lock.c
@@ -602,42 +602,125 @@ lock_get_wait(
}
/*************************************************************************
-Gets the table covered by an IX or IS table lock, if there are no
-other locks on the table. */
+Gets the source table of an ALTER TABLE transaction. The table must be
+covered by an IX or IS table lock. */
dict_table_t*
-lock_get_table(
-/*===========*/
- /* out: the table covered by the lock,
- or NULL if it is not an IX or IS table lock,
- or there are other locks on the table */
- lock_t* lock, /* in: lock */
- ulint* mode) /* out: lock mode of table */
+lock_get_src_table(
+/*===============*/
+ /* out: the source table of transaction,
+ if it is covered by an IX or IS table lock;
+ dest if there is no source table, and
+ NULL if the transaction is locking more than
+ two tables or an inconsistency is found */
+ trx_t* trx, /* in: transaction */
+ dict_table_t* dest, /* in: destination of ALTER TABLE */
+ ulint* mode) /* out: lock mode of the source table */
{
- dict_table_t* table;
- ulint lock_mode;
+ dict_table_t* src;
+ lock_t* lock;
- table = NULL;
+ src = NULL;
*mode = LOCK_NONE;
- if (lock_get_type(lock) != LOCK_TABLE) {
- return(table);
- }
+ for (lock = UT_LIST_GET_FIRST(trx->trx_locks);
+ lock;
+ lock = UT_LIST_GET_NEXT(trx_locks, lock)) {
+ lock_table_t* tab_lock;
+ ulint lock_mode;
+ if (!(lock_get_type(lock) & LOCK_TABLE)) {
+ /* We are only interested in table locks. */
+ continue;
+ }
+ tab_lock = &lock->un_member.tab_lock;
+ if (dest == tab_lock->table) {
+ /* We are not interested in the destination table. */
+ continue;
+ } else if (!src) {
+ /* This presumably is the source table. */
+ src = tab_lock->table;
+ if (UT_LIST_GET_LEN(src->locks) != 1 ||
+ UT_LIST_GET_FIRST(src->locks) != lock) {
+ /* We only support the case when
+ there is only one lock on this table. */
+ return(NULL);
+ }
+ } else if (src != tab_lock->table) {
+ /* The transaction is locking more than
+ two tables (src and dest): abort */
+ return(NULL);
+ }
- lock_mode = lock_get_mode(lock);
- switch (lock_mode) {
- case LOCK_IS:
- case LOCK_IX:
- *mode = lock_mode;
- table = lock->un_member.tab_lock.table;
- if (UT_LIST_GET_LEN(table->locks) != 1 ||
- UT_LIST_GET_FIRST(table->locks) != lock) {
- /* We only support the case when
- there is only one lock on this table. */
- table = NULL;
+ /* Check that the source table is locked by
+ LOCK_IX or LOCK_IS. */
+ lock_mode = lock_get_mode(lock);
+ switch (lock_mode) {
+ case LOCK_IX:
+ case LOCK_IS:
+ if (*mode != LOCK_NONE && *mode != lock_mode) {
+ /* There are multiple locks on src. */
+ return(NULL);
+ }
+ *mode = lock_mode;
+ break;
}
}
- return(table);
+
+ if (!src) {
+ /* No source table lock found: flag the situation to caller */
+ src = dest;
+ }
+
+ return(src);
+}
+
+/*************************************************************************
+Determine if the given table is exclusively "owned" by the given
+transaction, i.e., transaction holds LOCK_IX and possibly LOCK_AUTO_INC
+on the table. */
+
+ibool
+lock_is_table_exclusive(
+/*====================*/
+ /* out: TRUE if table is only locked by trx,
+ with LOCK_IX, and possibly LOCK_AUTO_INC */
+ dict_table_t* table, /* in: table */
+ trx_t* trx) /* in: transaction */
+{
+ lock_t* lock;
+ bool ok = FALSE;
+
+ ut_ad(table && trx);
+
+ for (lock = UT_LIST_GET_FIRST(table->locks);
+ lock;
+ lock = UT_LIST_GET_NEXT(locks, &lock->un_member.tab_lock)) {
+ if (lock->trx != trx) {
+ /* A lock on the table is held
+ by some other transaction. */
+ return(FALSE);
+ }
+
+ if (!(lock_get_type(lock) & LOCK_TABLE)) {
+ /* We are interested in table locks only. */
+ continue;
+ }
+
+ switch (lock_get_mode(lock)) {
+ case LOCK_IX:
+ ok = TRUE;
+ break;
+ case LOCK_AUTO_INC:
+ /* It is allowed for trx to hold an
+ auto_increment lock. */
+ break;
+ default:
+ /* Other table locks than LOCK_IX are not allowed. */
+ return(FALSE);
+ }
+ }
+
+ return(ok);
}
/*************************************************************************
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 2aaf69bd208..cc69762cbdb 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -2325,29 +2325,44 @@ ha_innobase::write_row(
intermediate COMMIT, since writes by other transactions are
being blocked by a MySQL table lock TL_WRITE_ALLOW_READ. */
- dict_table_t* table;
+ dict_table_t* src_table;
ibool mode;
num_write_row = 0;
/* Commit the transaction. This will release the table
locks, so they have to be acquired again. */
- switch (prebuilt->trx->mysql_n_tables_locked) {
- case 1:
+
+ /* Altering an InnoDB table */
+ /* Get the source table. */
+ src_table = lock_get_src_table(
+ prebuilt->trx, prebuilt->table, &mode);
+ if (!src_table) {
+ no_commit:
+ /* Unknown situation: do not commit */
+ /*
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB error: ALTER TABLE is holding lock"
+ " on %lu tables!\n",
+ prebuilt->trx->mysql_n_tables_locked);
+ */
+ ;
+ } else if (src_table == prebuilt->table) {
+ /* Source table is not in InnoDB format:
+ no need to re-acquire locks on it. */
+
/* Altering to InnoDB format */
innobase_commit(user_thd, prebuilt->trx);
/* Note that this transaction is still active. */
user_thd->transaction.all.innodb_active_trans = 1;
/* We will need an IX lock on the destination table. */
prebuilt->sql_stat_start = TRUE;
- break;
- case 2:
- /* Altering an InnoDB table */
- ut_a(UT_LIST_GET_LEN(prebuilt->trx->trx_locks) >= 2);
- table = lock_get_table(
- UT_LIST_GET_FIRST(prebuilt->trx->trx_locks),
- &mode);
- if (!table) {
+ } else {
+ /* Ensure that there are no other table locks than
+ LOCK_IX and LOCK_AUTO_INC on the destination table. */
+ if (!lock_is_table_exclusive(prebuilt->table,
+ prebuilt->trx)) {
goto no_commit;
}
@@ -2357,21 +2372,9 @@ ha_innobase::write_row(
/* Note that this transaction is still active. */
user_thd->transaction.all.innodb_active_trans = 1;
/* Re-acquire the table lock on the source table. */
- row_lock_table_for_mysql(prebuilt, table, mode);
+ row_lock_table_for_mysql(prebuilt, src_table, mode);
/* We will need an IX lock on the destination table. */
prebuilt->sql_stat_start = TRUE;
- break;
- default:
- no_commit:
- /* Unknown situation: do nothing (no commit) */
- /*
- ut_print_timestamp(stderr);
- fprintf(stderr,
- " InnoDB error: ALTER TABLE is holding lock"
- " on %lu tables!\n",
- prebuilt->trx->mysql_n_tables_locked);
- */
- break;
}
}
From 922c9146cd2c42b68e470504c6ff8270bd073fe5 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Tue, 30 Nov 2004 15:48:29 +0000
Subject: [PATCH 137/145] use sql_print_warning instead of push_warning in
mysqld.cc
---
sql/mysqld.cc | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index f3c89b110af..57ca15e3b4c 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -6107,8 +6107,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
have_berkeley_db= SHOW_OPTION_DISABLED;
#else
if (opt_bdb)
- push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
- 0,"this binary does not contain BDB storage engine");
+ sql_print_warning("this binary does not contain BDB storage engine");
#endif
break;
case OPT_ISAM:
@@ -6119,8 +6118,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
have_isam= SHOW_OPTION_DISABLED;
#else
if (opt_isam)
- push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
- 0,"this binary does not contain ISAM storage engine");
+ sql_print_warning("this binary does not contain ISAM storage engine");
#endif
break;
case OPT_NDBCLUSTER:
@@ -6131,8 +6129,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
have_ndbcluster= SHOW_OPTION_DISABLED;
#else
if (opt_ndbcluster)
- push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
- 0,"this binary does not contain NDBCLUSTER storage engine");
+ sql_print_warning("this binary does not contain NDBCLUSTER storage engine");
#endif
break;
case OPT_INNODB:
@@ -6143,8 +6140,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
have_innodb= SHOW_OPTION_DISABLED;
#else
if (opt_innodb)
- push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
- 0,"this binary does not contain INNODB storage engine");
+ sql_print_warning("this binary does not contain INNODB storage engine");
#endif
break;
case OPT_INNODB_DATA_FILE_PATH:
From c7ed52456db365fe61d2d3c3f2b5e012d50ff427 Mon Sep 17 00:00:00 2001
From: "heikki@hundin.mysql.fi" <>
Date: Tue, 30 Nov 2004 17:48:30 +0200
Subject: [PATCH 138/145] row0sel.c: Remove compiler warning as I had
forgotten an include file
---
innobase/row/row0sel.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c
index edaa555c555..ce76f48e7a7 100644
--- a/innobase/row/row0sel.c
+++ b/innobase/row/row0sel.c
@@ -31,6 +31,7 @@ Created 12/19/1997 Heikki Tuuri
#include "pars0pars.h"
#include "row0mysql.h"
#include "read0read.h"
+#include "buf0lru.h"
/* Maximum number of rows to prefetch; MySQL interface has another parameter */
#define SEL_MAX_N_PREFETCH 16
From 12738cd23a18ca4457eb9444378ed3e25cb0cf3d Mon Sep 17 00:00:00 2001
From: "heikki@hundin.mysql.fi" <>
Date: Tue, 30 Nov 2004 17:51:10 +0200
Subject: [PATCH 139/145] lock0lock.c: If UNIV_DEBUG is defined,
lock_get_type() was called before function definition: fix this
---
innobase/lock/lock0lock.c | 29 +++++++++++++++--------------
1 file changed, 15 insertions(+), 14 deletions(-)
diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c
index 78a78c9dd95..da1cb9d33cd 100644
--- a/innobase/lock/lock0lock.c
+++ b/innobase/lock/lock0lock.c
@@ -365,6 +365,21 @@ lock_deadlock_recursive(
ulint* cost); /* in/out: number of calculation steps thus
far: if this exceeds LOCK_MAX_N_STEPS_...
we return TRUE */
+
+/*************************************************************************
+Gets the type of a lock. */
+UNIV_INLINE
+ulint
+lock_get_type(
+/*==========*/
+ /* out: LOCK_TABLE or LOCK_REC */
+ lock_t* lock) /* in: lock */
+{
+ ut_ad(lock);
+
+ return(lock->type_mode & LOCK_TYPE_MASK);
+}
+
/*************************************************************************
Gets the nth bit of a record lock. */
UNIV_INLINE
@@ -581,20 +596,6 @@ lock_get_mode(
return(lock->type_mode & LOCK_MODE_MASK);
}
-/*************************************************************************
-Gets the type of a lock. */
-UNIV_INLINE
-ulint
-lock_get_type(
-/*==========*/
- /* out: LOCK_TABLE or LOCK_REC */
- lock_t* lock) /* in: lock */
-{
- ut_ad(lock);
-
- return(lock->type_mode & LOCK_TYPE_MASK);
-}
-
/*************************************************************************
Gets the wait flag of a lock. */
UNIV_INLINE
From aec0b4e4d784eb406386c0e3b41725c9c546d97d Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Tue, 30 Nov 2004 17:47:47 +0000
Subject: [PATCH 140/145] fixed error in test result added extra calls
to retrieve connectstring used reengineered connect somewhat to make
retries etc explicit
---
mysql-test/r/ndb_index_unique.result | 2 +
ndb/include/mgmapi/mgmapi.h | 1 +
ndb/include/mgmcommon/ConfigRetriever.hpp | 1 +
ndb/include/ndbapi/ndb_cluster_connection.hpp | 6 +-
ndb/src/common/mgmcommon/ConfigRetriever.cpp | 5 ++
ndb/src/mgmapi/mgmapi.cpp | 7 +-
ndb/src/mgmclient/CommandInterpreter.cpp | 12 ++--
ndb/src/ndbapi/Ndbinit.cpp | 2 +-
ndb/src/ndbapi/ndb_cluster_connection.cpp | 69 ++++++++++---------
ndb/tools/listTables.cpp | 3 +-
sql/ha_ndbcluster.cc | 23 +++++--
11 files changed, 82 insertions(+), 49 deletions(-)
diff --git a/mysql-test/r/ndb_index_unique.result b/mysql-test/r/ndb_index_unique.result
index 7ec1319a579..f9cc89ee4cc 100644
--- a/mysql-test/r/ndb_index_unique.result
+++ b/mysql-test/r/ndb_index_unique.result
@@ -77,8 +77,10 @@ a b c
3 NULL NULL
select * from t1 use index (bc) where b IS NULL and c IS NULL order by a;
a b c
+3 NULL NULL
select * from t1 use index (bc) where b IS NULL and c = 2 order by a;
a b c
+2 NULL 2
select * from t1 use index (bc) where b < 4 order by a;
a b c
1 1 1
diff --git a/ndb/include/mgmapi/mgmapi.h b/ndb/include/mgmapi/mgmapi.h
index 26add86a468..dc4f745adb2 100644
--- a/ndb/include/mgmapi/mgmapi.h
+++ b/ndb/include/mgmapi/mgmapi.h
@@ -375,6 +375,7 @@ extern "C" {
int ndb_mgm_get_configuration_nodeid(NdbMgmHandle handle);
int ndb_mgm_get_connected_port(NdbMgmHandle handle);
const char *ndb_mgm_get_connected_host(NdbMgmHandle handle);
+ const char *ndb_mgm_get_connectstring(NdbMgmHandle handle, char *buf, int buf_sz);
/**
* Destroy a management server handle
diff --git a/ndb/include/mgmcommon/ConfigRetriever.hpp b/ndb/include/mgmcommon/ConfigRetriever.hpp
index 80449628867..8461658748e 100644
--- a/ndb/include/mgmcommon/ConfigRetriever.hpp
+++ b/ndb/include/mgmcommon/ConfigRetriever.hpp
@@ -72,6 +72,7 @@ public:
Uint32 get_mgmd_port() const;
const char *get_mgmd_host() const;
+ const char *get_connectstring(char *buf, int buf_sz) const;
Uint32 get_configuration_nodeid() const;
private:
diff --git a/ndb/include/ndbapi/ndb_cluster_connection.hpp b/ndb/include/ndbapi/ndb_cluster_connection.hpp
index 59d5a038844..6fa25caf5d0 100644
--- a/ndb/include/ndbapi/ndb_cluster_connection.hpp
+++ b/ndb/include/ndbapi/ndb_cluster_connection.hpp
@@ -30,12 +30,14 @@ class Ndb_cluster_connection {
public:
Ndb_cluster_connection(const char * connect_string = 0);
~Ndb_cluster_connection();
- int connect(int reconnect= 0);
+ int connect(int no_retries, int retry_delay_in_seconds, int verbose);
int start_connect_thread(int (*connect_callback)(void)= 0);
+ const char *get_connectstring(char *buf, int buf_sz) const;
+ int get_connected_port() const;
+ const char *get_connected_host() const;
private:
friend void* run_ndb_cluster_connection_connect_thread(void*);
void connect_thread();
- char *m_connect_string;
TransporterFacade *m_facade;
ConfigRetriever *m_config_retriever;
NdbThread *m_connect_thread;
diff --git a/ndb/src/common/mgmcommon/ConfigRetriever.cpp b/ndb/src/common/mgmcommon/ConfigRetriever.cpp
index 0af5eb2f83c..744412870f5 100644
--- a/ndb/src/common/mgmcommon/ConfigRetriever.cpp
+++ b/ndb/src/common/mgmcommon/ConfigRetriever.cpp
@@ -90,6 +90,11 @@ const char *ConfigRetriever::get_mgmd_host() const
return ndb_mgm_get_connected_host(m_handle);
}
+const char *ConfigRetriever::get_connectstring(char *buf, int buf_sz) const
+{
+ return ndb_mgm_get_connectstring(m_handle, buf, buf_sz);
+}
+
//****************************************************************************
//****************************************************************************
diff --git a/ndb/src/mgmapi/mgmapi.cpp b/ndb/src/mgmapi/mgmapi.cpp
index e6328604c1b..651a4a8a725 100644
--- a/ndb/src/mgmapi/mgmapi.cpp
+++ b/ndb/src/mgmapi/mgmapi.cpp
@@ -84,7 +84,6 @@ typedef Parser Parser_t;
#define NDB_MGM_MAX_ERR_DESC_SIZE 256
struct ndb_mgm_handle {
- char * connectstring;
int cfg_i;
int connected;
@@ -1677,6 +1676,12 @@ const char *ndb_mgm_get_connected_host(NdbMgmHandle handle)
return handle->cfg.ids[handle->cfg_i].name.c_str();
}
+extern "C"
+const char *ndb_mgm_get_connectstring(NdbMgmHandle handle, char *buf, int buf_sz)
+{
+ return handle->cfg.makeConnectString(buf,buf_sz);
+}
+
extern "C"
int
ndb_mgm_alloc_nodeid(NdbMgmHandle handle, unsigned int version, int nodetype)
diff --git a/ndb/src/mgmclient/CommandInterpreter.cpp b/ndb/src/mgmclient/CommandInterpreter.cpp
index f36dddf815d..7ef62da9bb3 100644
--- a/ndb/src/mgmclient/CommandInterpreter.cpp
+++ b/ndb/src/mgmclient/CommandInterpreter.cpp
@@ -516,6 +516,12 @@ CommandInterpreter::execute_impl(const char *_line)
executeConnect(allAfterFirstToken);
DBUG_RETURN(true);
}
+ else if((strcasecmp(firstToken, "QUIT") == 0 ||
+ strcasecmp(firstToken, "EXIT") == 0 ||
+ strcasecmp(firstToken, "BYE") == 0) &&
+ allAfterFirstToken == NULL){
+ DBUG_RETURN(false);
+ }
if (!connect())
DBUG_RETURN(true);
@@ -571,12 +577,6 @@ CommandInterpreter::execute_impl(const char *_line)
}
else if (strcasecmp(firstToken, "ALL") == 0) {
analyseAfterFirstToken(-1, allAfterFirstToken);
- }
- else if((strcasecmp(firstToken, "QUIT") == 0 ||
- strcasecmp(firstToken, "EXIT") == 0 ||
- strcasecmp(firstToken, "BYE") == 0) &&
- allAfterFirstToken == NULL){
- DBUG_RETURN(false);
} else {
/**
* First token should be a digit, node ID
diff --git a/ndb/src/ndbapi/Ndbinit.cpp b/ndb/src/ndbapi/Ndbinit.cpp
index 698bbcde4c6..48e62c36a5f 100644
--- a/ndb/src/ndbapi/Ndbinit.cpp
+++ b/ndb/src/ndbapi/Ndbinit.cpp
@@ -58,7 +58,7 @@ Ndb::Ndb( const char* aDataBase , const char* aSchema) {
theNoOfNdbObjects++;
if (global_ndb_cluster_connection == 0) {
global_ndb_cluster_connection= new Ndb_cluster_connection(ndbConnectString);
- global_ndb_cluster_connection->connect();
+ global_ndb_cluster_connection->connect(12,5,1);
}
setup(global_ndb_cluster_connection, aDataBase, aSchema);
DBUG_VOID_RETURN;
diff --git a/ndb/src/ndbapi/ndb_cluster_connection.cpp b/ndb/src/ndbapi/ndb_cluster_connection.cpp
index 8a5a61df171..f436ee56ede 100644
--- a/ndb/src/ndbapi/ndb_cluster_connection.cpp
+++ b/ndb/src/ndbapi/ndb_cluster_connection.cpp
@@ -40,10 +40,7 @@ Ndb_cluster_connection::Ndb_cluster_connection(const char *connect_string)
DBUG_ENTER("Ndb_cluster_connection");
DBUG_PRINT("enter",("Ndb_cluster_connection this=0x%x", this));
m_facade= TransporterFacade::theFacadeInstance= new TransporterFacade();
- if (connect_string)
- m_connect_string= my_strdup(connect_string,MYF(MY_WME));
- else
- m_connect_string= 0;
+
m_config_retriever= 0;
m_connect_thread= 0;
m_connect_callback= 0;
@@ -58,9 +55,39 @@ Ndb_cluster_connection::Ndb_cluster_connection(const char *connect_string)
ndb_print_state_mutex= NdbMutex_Create();
}
#endif
+ m_config_retriever=
+ new ConfigRetriever(connect_string, NDB_VERSION, NODE_TYPE_API);
+ if (m_config_retriever->hasError())
+ {
+ printf("Could not connect initialize handle to management server: %s",
+ m_config_retriever->getErrorString());
+ delete m_config_retriever;
+ m_config_retriever= 0;
+ }
DBUG_VOID_RETURN;
}
+int Ndb_cluster_connection::get_connected_port() const
+{
+ if (m_config_retriever)
+ return m_config_retriever->get_mgmd_port();
+ return -1;
+}
+
+const char *Ndb_cluster_connection::get_connected_host() const
+{
+ if (m_config_retriever)
+ return m_config_retriever->get_mgmd_host();
+ return 0;
+}
+
+const char *Ndb_cluster_connection::get_connectstring(char *buf, int buf_sz) const
+{
+ if (m_config_retriever)
+ return m_config_retriever->get_connectstring(buf,buf_sz);
+ return 0;
+}
+
extern "C" pthread_handler_decl(run_ndb_cluster_connection_connect_thread, me)
{
my_thread_init();
@@ -77,7 +104,7 @@ void Ndb_cluster_connection::connect_thread()
int r;
do {
NdbSleep_SecSleep(1);
- if ((r = connect(1)) == 0)
+ if ((r = connect(0,0,0)) == 0)
break;
if (r == -1) {
printf("Ndb_cluster_connection::connect_thread error\n");
@@ -98,7 +125,7 @@ int Ndb_cluster_connection::start_connect_thread(int (*connect_callback)(void))
int r;
DBUG_ENTER("Ndb_cluster_connection::start_connect_thread");
m_connect_callback= connect_callback;
- if ((r = connect(1)) == 1)
+ if ((r = connect(0,0,0)) == 1)
{
DBUG_PRINT("info",("starting thread"));
m_connect_thread=
@@ -117,36 +144,15 @@ int Ndb_cluster_connection::start_connect_thread(int (*connect_callback)(void))
DBUG_RETURN(0);
}
-int Ndb_cluster_connection::connect(int reconnect)
+int Ndb_cluster_connection::connect(int no_retries, int retry_delay_in_seconds, int verbose)
{
DBUG_ENTER("Ndb_cluster_connection::connect");
const char* error = 0;
do {
if (m_config_retriever == 0)
- {
- m_config_retriever=
- new ConfigRetriever(m_connect_string, NDB_VERSION, NODE_TYPE_API);
- if (m_config_retriever->hasError())
- {
- printf("Could not connect initialize handle to management server: %s",
- m_config_retriever->getErrorString());
- DBUG_RETURN(-1);
- }
- }
- else
- if (reconnect == 0)
- DBUG_RETURN(0);
- if (reconnect)
- {
- int r= m_config_retriever->do_connect(0,0,0);
- if (r == 1)
- DBUG_RETURN(1); // mgmt server not up yet
- if (r == -1)
- break;
- }
- else
- if(m_config_retriever->do_connect(12,5,1) == -1)
- break;
+ DBUG_RETURN(-1);
+ if (m_config_retriever->do_connect(no_retries,retry_delay_in_seconds,verbose))
+ DBUG_RETURN(1); // mgmt server not up yet
Uint32 nodeId = m_config_retriever->allocNodeId(4/*retries*/,3/*delay*/);
if(nodeId == 0)
@@ -189,7 +195,6 @@ Ndb_cluster_connection::~Ndb_cluster_connection()
abort();
TransporterFacade::theFacadeInstance= 0;
}
- my_free(m_connect_string,MYF(MY_ALLOW_ZERO_PTR));
if (m_config_retriever)
delete m_config_retriever;
DBUG_VOID_RETURN;
diff --git a/ndb/tools/listTables.cpp b/ndb/tools/listTables.cpp
index b923207a4fe..ccb6967e2dc 100644
--- a/ndb/tools/listTables.cpp
+++ b/ndb/tools/listTables.cpp
@@ -228,10 +228,11 @@ int main(int argc, char** argv){
_tabname = argv[0];
ndb_cluster_connection = new Ndb_cluster_connection(opt_connect_str);
+ if (ndb_cluster_connection->connect(12,5,1))
+ fatal("unable to connect");
ndb = new Ndb(ndb_cluster_connection, _dbname);
if (ndb->init() != 0)
fatal("init");
- ndb_cluster_connection->connect();
if (ndb->waitUntilReady(30) < 0)
fatal("waitUntilReady");
dic = ndb->getDictionary();
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index ee68f8d8974..6c609cd54ac 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -4231,7 +4231,7 @@ bool ndbcluster_init()
new Ndb_cluster_connection(ndbcluster_connectstring)) == 0)
{
DBUG_PRINT("error",("Ndb_cluster_connection(%s)",ndbcluster_connectstring));
- DBUG_RETURN(TRUE);
+ goto ndbcluster_init_error;
}
// Create a Ndb object to open the connection to NDB
@@ -4240,25 +4240,33 @@ bool ndbcluster_init()
if (g_ndb->init() != 0)
{
ERR_PRINT (g_ndb->getNdbError());
- DBUG_RETURN(TRUE);
+ goto ndbcluster_init_error;
}
- if ((res= g_ndb_cluster_connection->connect(1)) == 0)
+ if ((res= g_ndb_cluster_connection->connect(0,0,0)) == 0)
{
+ DBUG_PRINT("info",("NDBCLUSTER storage engine at %s on port %d",
+ g_ndb_cluster_connection->get_connected_host(),
+ g_ndb_cluster_connection->get_connected_port()));
g_ndb->waitUntilReady(10);
}
else if(res == 1)
{
if (g_ndb_cluster_connection->start_connect_thread()) {
DBUG_PRINT("error", ("g_ndb_cluster_connection->start_connect_thread()"));
- DBUG_RETURN(TRUE);
+ goto ndbcluster_init_error;
+ }
+ {
+ char buf[1024];
+ DBUG_PRINT("info",("NDBCLUSTER storage engine not started, will connect using %s",
+ g_ndb_cluster_connection->get_connectstring(buf,sizeof(buf))));
}
}
else
{
DBUG_ASSERT(res == -1);
DBUG_PRINT("error", ("permanent error"));
- DBUG_RETURN(TRUE);
+ goto ndbcluster_init_error;
}
(void) hash_init(&ndbcluster_open_tables,system_charset_info,32,0,0,
@@ -4268,9 +4276,12 @@ bool ndbcluster_init()
ndbcluster_inited= 1;
#ifdef USE_DISCOVER_ON_STARTUP
if (ndb_discover_tables() != 0)
- DBUG_RETURN(TRUE);
+ goto ndbcluster_init_error;
#endif
DBUG_RETURN(FALSE);
+ ndbcluster_init_error:
+ ndbcluster_end();
+ DBUG_RETURN(TRUE);
}
From 8551a482e28d372234b2ac2241990e6c2b4bfcc9 Mon Sep 17 00:00:00 2001
From: "serg@serg.mylan" <>
Date: Tue, 30 Nov 2004 21:17:03 +0100
Subject: [PATCH 141/145] typo fixed
---
innobase/include/lock0lock.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/innobase/include/lock0lock.h b/innobase/include/lock0lock.h
index ff5b6aae02e..db8dd24973d 100644
--- a/innobase/include/lock0lock.h
+++ b/innobase/include/lock0lock.h
@@ -483,7 +483,7 @@ transaction, i.e., transaction holds LOCK_IX and possibly LOCK_AUTO_INC
on the table. */
ibool
-lock_table_exclusive(
+lock_is_table_exclusive(
/*=================*/
/* out: TRUE if table is only locked by trx,
with LOCK_IX, and possibly LOCK_AUTO_INC */
From 900e507b146d530c1d8075b67a2f9caecf01ee70 Mon Sep 17 00:00:00 2001
From: "tomas@poseidon.ndb.mysql.com" <>
Date: Tue, 30 Nov 2004 20:51:57 +0000
Subject: [PATCH 142/145] fixed so that warning on missing support for engine
only printed once even if option given multiple times
---
sql/mysqld.cc | 62 +++++++++++++++++++++++++++++++++++++--------------
1 file changed, 45 insertions(+), 17 deletions(-)
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 57ca15e3b4c..baab3017623 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -36,6 +36,28 @@
#ifdef HAVE_NDBCLUSTER_DB
#include "ha_ndbcluster.h"
#endif
+
+#ifdef HAVE_INNOBASE_DB
+#define OPT_INNODB_DEFAULT 1
+#else
+#define OPT_INNODB_DEFAULT 0
+#endif
+#ifdef HAVE_BERKLEY_DB
+#define OPT_BDB_DEFAULT 1
+#else
+#define OPT_BDB_DEFAULT 0
+#endif
+#ifdef HAVE_ISAM_DB
+#define OPT_ISAM_DEFAULT 1
+#else
+#define OPT_ISAM_DEFAULT 0
+#endif
+#ifdef HAVE_NDBCLUSTER_DB
+#define OPT_NDBCLUSTER_DEFAULT 0
+#else
+#define OPT_NDBCLUSTER_DEFAULT 0
+#endif
+
#include
#include
#include
@@ -4089,7 +4111,7 @@ struct my_option my_long_options[] =
0, 0, 0, 0, 0, 0},
{"bdb", OPT_BDB, "Enable Berkeley DB (if this version of MySQL supports it). \
Disable with --skip-bdb (will save memory).",
- (gptr*) &opt_bdb, (gptr*) &opt_bdb, 0, GET_BOOL, NO_ARG, 1, 0, 0,
+ (gptr*) &opt_bdb, (gptr*) &opt_bdb, 0, GET_BOOL, NO_ARG, OPT_BDB_DEFAULT, 0, 0,
0, 0, 0},
#ifdef HAVE_BERKELEY_DB
{"bdb-home", OPT_BDB_HOME, "Berkeley home directory.", (gptr*) &berkeley_home,
@@ -4226,7 +4248,7 @@ Disable with --skip-bdb (will save memory).",
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"innodb", OPT_INNODB, "Enable InnoDB (if this version of MySQL supports it). \
Disable with --skip-innodb (will save memory).",
- (gptr*) &opt_innodb, (gptr*) &opt_innodb, 0, GET_BOOL, NO_ARG, 1, 0, 0,
+ (gptr*) &opt_innodb, (gptr*) &opt_innodb, 0, GET_BOOL, NO_ARG, OPT_INNODB_DEFAULT, 0, 0,
0, 0, 0},
{"innodb_data_file_path", OPT_INNODB_DATA_FILE_PATH,
"Path to individual files and their sizes.",
@@ -4286,7 +4308,7 @@ Disable with --skip-innodb (will save memory).",
#endif /* End HAVE_INNOBASE_DB */
{"isam", OPT_ISAM, "Enable ISAM (if this version of MySQL supports it). \
Disable with --skip-isam.",
- (gptr*) &opt_isam, (gptr*) &opt_isam, 0, GET_BOOL, NO_ARG, 1, 0, 0,
+ (gptr*) &opt_isam, (gptr*) &opt_isam, 0, GET_BOOL, NO_ARG, OPT_ISAM_DEFAULT, 0, 0,
0, 0, 0},
{"language", 'L',
"Client error messages in given language. May be given as a full path.",
@@ -4413,8 +4435,8 @@ master-ssl",
GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
{"ndbcluster", OPT_NDBCLUSTER, "Enable NDB Cluster (if this version of MySQL supports it). \
Disable with --skip-ndbcluster (will save memory).",
- (gptr*) &opt_ndbcluster, (gptr*) &opt_ndbcluster, 0, GET_BOOL, NO_ARG, 1, 0, 0,
- 0, 0, 0},
+ (gptr*) &opt_ndbcluster, (gptr*) &opt_ndbcluster, 0, GET_BOOL, NO_ARG,
+ OPT_NDBCLUSTER_DEFAULT, 0, 0, 0, 0, 0},
#ifdef HAVE_NDBCLUSTER_DB
{"ndb-connectstring", OPT_NDB_CONNECTSTRING,
"Connect string for ndbcluster.",
@@ -6105,9 +6127,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
have_berkeley_db= SHOW_OPTION_YES;
else
have_berkeley_db= SHOW_OPTION_DISABLED;
-#else
- if (opt_bdb)
- sql_print_warning("this binary does not contain BDB storage engine");
#endif
break;
case OPT_ISAM:
@@ -6116,9 +6135,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
have_isam= SHOW_OPTION_YES;
else
have_isam= SHOW_OPTION_DISABLED;
-#else
- if (opt_isam)
- sql_print_warning("this binary does not contain ISAM storage engine");
#endif
break;
case OPT_NDBCLUSTER:
@@ -6127,9 +6143,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
have_ndbcluster= SHOW_OPTION_YES;
else
have_ndbcluster= SHOW_OPTION_DISABLED;
-#else
- if (opt_ndbcluster)
- sql_print_warning("this binary does not contain NDBCLUSTER storage engine");
#endif
break;
case OPT_INNODB:
@@ -6138,9 +6151,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
have_innodb= SHOW_OPTION_YES;
else
have_innodb= SHOW_OPTION_DISABLED;
-#else
- if (opt_innodb)
- sql_print_warning("this binary does not contain INNODB storage engine");
#endif
break;
case OPT_INNODB_DATA_FILE_PATH:
@@ -6260,6 +6270,24 @@ static void get_options(int argc,char **argv)
if ((ho_error= handle_options(&argc, &argv, my_long_options,
get_one_option)))
exit(ho_error);
+
+#ifndef HAVE_NDBCLUSTER_DB
+ if (opt_ndbcluster)
+ sql_print_warning("this binary does not contain NDBCLUSTER storage engine");
+#endif
+#ifndef HAVE_INNOBASE_DB
+ if (opt_innodb)
+ sql_print_warning("this binary does not contain INNODB storage engine");
+#endif
+#ifndef HAVE_ISAM
+ if (opt_isam)
+ sql_print_warning("this binary does not contain ISAM storage engine");
+#endif
+#ifndef HAVE_BERKELEY_DB
+ if (opt_bdb)
+ sql_print_warning("this binary does not contain BDB storage engine");
+#endif
+
if (argc > 0)
{
fprintf(stderr, "%s: Too many arguments (first extra is '%s').\nUse --help to get a list of available options\n", my_progname, *argv);
From 2cb2461229102a360f399914b4dfd46013cbb377 Mon Sep 17 00:00:00 2001
From: "marko@hundin.mysql.fi" <>
Date: Tue, 30 Nov 2004 23:10:17 +0200
Subject: [PATCH 143/145] lock0lock.h: Rename lock_table_exclusive to
lock_is_table_exclusive (somehow this change was omitted from last
changeset)
---
innobase/include/lock0lock.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/innobase/include/lock0lock.h b/innobase/include/lock0lock.h
index ff5b6aae02e..1fd7492d517 100644
--- a/innobase/include/lock0lock.h
+++ b/innobase/include/lock0lock.h
@@ -483,8 +483,8 @@ transaction, i.e., transaction holds LOCK_IX and possibly LOCK_AUTO_INC
on the table. */
ibool
-lock_table_exclusive(
-/*=================*/
+lock_is_table_exclusive(
+/*====================*/
/* out: TRUE if table is only locked by trx,
with LOCK_IX, and possibly LOCK_AUTO_INC */
dict_table_t* table, /* in: table */
From 7219d2be90cb9d401b20690f4cd294a42e08134d Mon Sep 17 00:00:00 2001
From: "guilhem@mysql.com" <>
Date: Tue, 30 Nov 2004 22:20:52 +0100
Subject: [PATCH 144/145] two-line fix for BUG#6732 "FLUSH TABLES WITH READ
LOCK + COMMIT makes next FLUSH...LOCK hang forever" (originally reported as
"second run of innobackup hangs forever and can even hang server"). Plus
testcase for the bugfix and comments about global read locks.
---
mysql-test/r/flush_block_commit.result | 8 +++
mysql-test/t/flush_block_commit.test | 14 ++++++
sql/lock.cc | 69 +++++++++++++++++++++++---
3 files changed, 85 insertions(+), 6 deletions(-)
diff --git a/mysql-test/r/flush_block_commit.result b/mysql-test/r/flush_block_commit.result
index 3205dd9dad9..20917147e4d 100644
--- a/mysql-test/r/flush_block_commit.result
+++ b/mysql-test/r/flush_block_commit.result
@@ -20,4 +20,12 @@ commit;
a
1
unlock tables;
+commit;
+begin;
+insert into t1 values(10);
+flush tables with read lock;
+commit;
+unlock tables;
+flush tables with read lock;
+unlock tables;
drop table t1;
diff --git a/mysql-test/t/flush_block_commit.test b/mysql-test/t/flush_block_commit.test
index 20ecec1361c..8b99a59c979 100644
--- a/mysql-test/t/flush_block_commit.test
+++ b/mysql-test/t/flush_block_commit.test
@@ -45,5 +45,19 @@ reap;
connection con3;
reap;
unlock tables;
+
+# BUG#6732 FLUSH TABLES WITH READ LOCK + COMMIT hangs later FLUSH TABLES
+# WITH READ LOCK
+
+connection con2;
+commit; # unlock InnoDB row locks to allow insertions
connection con1;
+begin;
+insert into t1 values(10);
+flush tables with read lock;
+commit;
+unlock tables;
+connection con2;
+flush tables with read lock; # bug caused hang here
+unlock tables;
drop table t1;
diff --git a/sql/lock.cc b/sql/lock.cc
index bf0160291f8..c7e6ebfda83 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -665,15 +665,70 @@ static void print_lock_error(int error)
/****************************************************************************
Handling of global read locks
- The global locks are handled through the global variables:
- global_read_lock
- global_read_lock_blocks_commit
- waiting_for_read_lock
- protect_against_global_read_lock
-
Taking the global read lock is TWO steps (2nd step is optional; without
it, COMMIT of existing transactions will be allowed):
lock_global_read_lock() THEN make_global_read_lock_block_commit().
+
+ The global locks are handled through the global variables:
+ global_read_lock
+ count of threads which have the global read lock (i.e. have completed at
+ least the first step above)
+ global_read_lock_blocks_commit
+ count of threads which have the global read lock and block
+ commits (i.e. have completed the second step above)
+ waiting_for_read_lock
+ count of threads which want to take a global read lock but cannot
+ protect_against_global_read_lock
+ count of threads which have set protection against global read lock.
+
+ How blocking of threads by global read lock is achieved: that's
+ advisory. Any piece of code which should be blocked by global read lock must
+ be designed like this:
+ - call to wait_if_global_read_lock(). When this returns 0, no global read
+ lock is owned; if argument abort_on_refresh was 0, none can be obtained.
+ - job
+ - if abort_on_refresh was 0, call to start_waiting_global_read_lock() to
+ allow other threads to get the global read lock. I.e. removal of the
+ protection.
+ (Note: it's a bit like an implementation of rwlock).
+
+ [ I am sorry to mention some SQL syntaxes below I know I shouldn't but found
+ no better descriptive way ]
+
+ Why does FLUSH TABLES WITH READ LOCK need to block COMMIT: because it's used
+ to read a non-moving SHOW MASTER STATUS, and a COMMIT writes to the binary
+ log.
+
+ Why getting the global read lock is two steps and not one. Because FLUSH
+ TABLES WITH READ LOCK needs to insert one other step between the two:
+ flushing tables. So the order is
+ 1) lock_global_read_lock() (prevents any new table write locks, i.e. stalls
+ all new updates)
+ 2) close_cached_tables() (the FLUSH TABLES), which will wait for tables
+ currently opened and being updated to close (so it's possible that there is
+ a moment where all new updates of server are stalled *and* FLUSH TABLES WITH
+ READ LOCK is, too).
+ 3) make_global_read_lock_block_commit().
+ If we have merged 1) and 3) into 1), we would have had this deadlock:
+ imagine thread 1 and 2, in non-autocommit mode, thread 3, and an InnoDB
+ table t.
+ thd1: SELECT * FROM t FOR UPDATE;
+ thd2: UPDATE t SET a=1; # blocked by row-level locks of thd1
+ thd3: FLUSH TABLES WITH READ LOCK; # blocked in close_cached_tables() by the
+ table instance of thd2
+ thd1: COMMIT; # blocked by thd3.
+ thd1 blocks thd2 which blocks thd3 which blocks thd1: deadlock.
+
+ Note that we need to support that one thread does
+ FLUSH TABLES WITH READ LOCK; and then COMMIT;
+ (that's what innobackup does, for some good reason).
+ So in this exceptional case the COMMIT should not be blocked by the FLUSH
+ TABLES WITH READ LOCK.
+
+ TODO in MySQL 5.x: make_global_read_lock_block_commit() should be
+ killable. Normally CPU does not spend a long time in this function (COMMITs
+ are quite fast), but it would still be nice.
+
****************************************************************************/
volatile uint global_read_lock=0;
@@ -783,6 +838,8 @@ void start_waiting_global_read_lock(THD *thd)
{
bool tmp;
DBUG_ENTER("start_waiting_global_read_lock");
+ if (unlikely(thd->global_read_lock))
+ DBUG_VOID_RETURN;
(void) pthread_mutex_lock(&LOCK_open);
tmp= (!--protect_against_global_read_lock && waiting_for_read_lock);
(void) pthread_mutex_unlock(&LOCK_open);
From 2e0d1b3f9cde6fbbb16c9f8eca4eb5e0013d7404 Mon Sep 17 00:00:00 2001
From: "mwagner@mysql.com" <>
Date: Wed, 1 Dec 2004 02:35:02 +0100
Subject: [PATCH 145/145] openssl_1.result, have_openssl_1.require,
openssl_1.test: Update SSL Cipher so that 'openssl_1' test passes
(BUG#6152)
---
BitKeeper/etc/logging_ok | 1 +
mysql-test/r/have_openssl_1.require | 2 +-
mysql-test/r/openssl_1.result | 6 +++---
mysql-test/t/openssl_1.test | 6 +++---
4 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok
index 0483e6b4fa3..00f4c86d319 100644
--- a/BitKeeper/etc/logging_ok
+++ b/BitKeeper/etc/logging_ok
@@ -140,6 +140,7 @@ msvensson@build.mysql.com
mwagner@cash.mwagner.org
mwagner@evoq.mwagner.org
mwagner@here.mwagner.org
+mwagner@mysql.com
mwagner@work.mysql.com
mydev@mysql.com
mysql@home.(none)
diff --git a/mysql-test/r/have_openssl_1.require b/mysql-test/r/have_openssl_1.require
index 032b60d544a..b33a1d2854f 100644
--- a/mysql-test/r/have_openssl_1.require
+++ b/mysql-test/r/have_openssl_1.require
@@ -1,2 +1,2 @@
Variable_name Value
-Ssl_cipher EDH-RSA-DES-CBC3-SHA
+Ssl_cipher DHE-RSA-AES256-SHA
diff --git a/mysql-test/r/openssl_1.result b/mysql-test/r/openssl_1.result
index a87d0c33559..f7cb17a1a74 100644
--- a/mysql-test/r/openssl_1.result
+++ b/mysql-test/r/openssl_1.result
@@ -2,9 +2,9 @@ drop table if exists t1;
create table t1(f1 int);
insert into t1 values (5);
grant select on test.* to ssl_user1@localhost require SSL;
-grant select on test.* to ssl_user2@localhost require cipher "EDH-RSA-DES-CBC3-SHA";
-grant select on test.* to ssl_user3@localhost require cipher "EDH-RSA-DES-CBC3-SHA" AND SUBJECT "/C=SE/L=Uppsala/O=MySQL AB/CN=MySQL Client/Email=abstract.mysql.developer@mysql.com";
-grant select on test.* to ssl_user4@localhost require cipher "EDH-RSA-DES-CBC3-SHA" AND SUBJECT "/C=SE/L=Uppsala/O=MySQL AB/CN=MySQL Client/Email=abstract.mysql.developer@mysql.com" ISSUER "/C=SE/L=Uppsala/O=MySQL AB/CN=Abstract MySQL Developer/Email=abstract.mysql.developer@mysql.com";
+grant select on test.* to ssl_user2@localhost require cipher "DHE-RSA-AES256-SHA";
+grant select on test.* to ssl_user3@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/L=Uppsala/O=MySQL AB/CN=MySQL Client/Email=abstract.mysql.developer@mysql.com";
+grant select on test.* to ssl_user4@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/L=Uppsala/O=MySQL AB/CN=MySQL Client/Email=abstract.mysql.developer@mysql.com" ISSUER "/C=SE/L=Uppsala/O=MySQL AB/CN=Abstract MySQL Developer/Email=abstract.mysql.developer@mysql.com";
flush privileges;
select * from t1;
f1
diff --git a/mysql-test/t/openssl_1.test b/mysql-test/t/openssl_1.test
index 39612f680f3..912c9fb9bec 100644
--- a/mysql-test/t/openssl_1.test
+++ b/mysql-test/t/openssl_1.test
@@ -9,9 +9,9 @@ create table t1(f1 int);
insert into t1 values (5);
grant select on test.* to ssl_user1@localhost require SSL;
-grant select on test.* to ssl_user2@localhost require cipher "EDH-RSA-DES-CBC3-SHA";
-grant select on test.* to ssl_user3@localhost require cipher "EDH-RSA-DES-CBC3-SHA" AND SUBJECT "/C=SE/L=Uppsala/O=MySQL AB/CN=MySQL Client/Email=abstract.mysql.developer@mysql.com";
-grant select on test.* to ssl_user4@localhost require cipher "EDH-RSA-DES-CBC3-SHA" AND SUBJECT "/C=SE/L=Uppsala/O=MySQL AB/CN=MySQL Client/Email=abstract.mysql.developer@mysql.com" ISSUER "/C=SE/L=Uppsala/O=MySQL AB/CN=Abstract MySQL Developer/Email=abstract.mysql.developer@mysql.com";
+grant select on test.* to ssl_user2@localhost require cipher "DHE-RSA-AES256-SHA";
+grant select on test.* to ssl_user3@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/L=Uppsala/O=MySQL AB/CN=MySQL Client/Email=abstract.mysql.developer@mysql.com";
+grant select on test.* to ssl_user4@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/L=Uppsala/O=MySQL AB/CN=MySQL Client/Email=abstract.mysql.developer@mysql.com" ISSUER "/C=SE/L=Uppsala/O=MySQL AB/CN=Abstract MySQL Developer/Email=abstract.mysql.developer@mysql.com";
flush privileges;
connect (con1,localhost,ssl_user1,,);
connect (con2,localhost,ssl_user2,,);
|