From 95aaf57ce4647811a411d55db347f84af1b5ef4d Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 25 Apr 2005 11:08:38 +0200 Subject: [PATCH 01/19] valgrind: initialise variable in QUICK_SELECT_I sql/opt_range.cc: Initialise number of records in QUICK_SELECT_I --- sql/opt_range.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 2ced24f87bb..96b5cb305f8 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -713,7 +713,8 @@ SQL_SELECT::~SQL_SELECT() QUICK_SELECT_I::QUICK_SELECT_I() :max_used_key_length(0), - used_key_parts(0) + used_key_parts(0), + records(0) {} QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(THD *thd, TABLE *table, uint key_nr, From 410b6a9ebc1d6d4b0cae68da3ec7c5f5a6ec38f9 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 13 May 2005 07:18:41 -0700 Subject: [PATCH 02/19] Avoid doing a seek when first setting up the IO cache for a file, which allows a FIFO to be used for the non-binary logs. (Bug #8271) mysys/mf_iocache.c: Don't set seek_not_done if the position of the file is already where we expected it to be. --- mysys/mf_iocache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c index b86e9daf92d..32800c832b3 100644 --- a/mysys/mf_iocache.c +++ b/mysys/mf_iocache.c @@ -171,7 +171,7 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize, info->arg = 0; info->alloced_buffer = 0; info->buffer=0; - info->seek_not_done= test(file >= 0); + info->seek_not_done= test(file >= 0 && seek_offset != my_tell(file, MYF(0))); info->disk_writes= 0; #ifdef THREAD info->share=0; From faa12bf0c7fc73bfe54c655553869bff2a52e3af Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 14 May 2005 17:08:43 +0300 Subject: [PATCH 03/19] Fixed compiler failure --- sql/unireg.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/sql/unireg.cc b/sql/unireg.cc index f81370539c6..748e45f8b0a 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -27,6 +27,7 @@ #define USES_TYPES #include "mysql_priv.h" #include +#include #define FCOMP 11 /* Byte per packat f{lt */ From 06736ab48a6ea988c230127896a8083bf88557d9 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 15 May 2005 22:56:45 +0200 Subject: [PATCH 04/19] Fix for BUG#10095: {wrong query results because of incorrect constant propagation} The problem: base_list::remove didn't modify base_list::last when removing the last list element. The fix: If we remove the last element, find the element before it (by walking from the beginning of the list) and set base_list::last accordingly. The list gets corrupted in both 4.0 and 4.1. There are no visible problems in current 4.1 because current 4.1 doesn't call where_cond->fix_fields() after constant propagation step. mysql-test/r/select.result: Testcase for BUG#10095 mysql-test/t/select.test: Testcase for BUG#10095 sql/sql_list.h: Fix for BUG#10095: {wrong query results because of incorrect constant propagation} The problem: base_list::remove didn't modify base_list::last when removing the last list element. The fix: If we remove the last element, find the element before it (by walking from the beginning of the list) and set base_list::last accordingly. --- mysql-test/r/select.result | 54 ++++++++++++++++++++++++++++ mysql-test/t/select.test | 59 ++++++++++++++++++++++++++++++ sql/sql_list.h | 74 ++++++++++++++++++++++++++++++++++++-- 3 files changed, 185 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 17897b2f549..3c7a74c0c57 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -2377,3 +2377,57 @@ table type possible_keys key key_len ref rows Extra t1 ALL NULL NULL NULL NULL 5 t2 ref a a 23 t1.a 5 DROP TABLE t1, t2; +CREATE TABLE t1 ( +kunde_intern_id int(10) unsigned NOT NULL default '0', +kunde_id int(10) unsigned NOT NULL default '0', +FK_firma_id int(10) unsigned NOT NULL default '0', +aktuell enum('Ja','Nein') NOT NULL default 'Ja', +vorname varchar(128) NOT NULL default '', +nachname varchar(128) NOT NULL default '', +geloescht enum('Ja','Nein') NOT NULL default 'Nein', +firma varchar(128) NOT NULL default '' +); +INSERT INTO t1 VALUES +(3964,3051,1,'Ja','Vorname1','1Nachname','Nein','Print Schau XXXX'), +(3965,3051111,1,'Ja','Vorname1111','1111Nachname','Nein','Print Schau XXXX'); +SELECT kunde_id ,FK_firma_id ,aktuell, vorname, nachname, geloescht FROM t1 +WHERE +( +( +( '' != '' AND firma LIKE CONCAT('%', '', '%')) +OR +(vorname LIKE CONCAT('%', 'Vorname1', '%') AND +nachname LIKE CONCAT('%', '1Nachname', '%') AND +'Vorname1' != '' AND 'xxxx' != '') +) +AND +( +aktuell = 'Ja' AND geloescht = 'Nein' AND FK_firma_id = 2 +) +) +; +kunde_id FK_firma_id aktuell vorname nachname geloescht +SELECT kunde_id ,FK_firma_id ,aktuell, vorname, nachname, +geloescht FROM t1 +WHERE +( +( +aktuell = 'Ja' AND geloescht = 'Nein' AND FK_firma_id = 2 +) +AND +( +( '' != '' AND firma LIKE CONCAT('%', '', '%') ) +OR +( vorname LIKE CONCAT('%', 'Vorname1', '%') AND +nachname LIKE CONCAT('%', '1Nachname', '%') AND 'Vorname1' != '' AND +'xxxx' != '') +) +) +; +kunde_id FK_firma_id aktuell vorname nachname geloescht +SELECT COUNT(*) FROM t1 WHERE +( 0 OR (vorname LIKE '%Vorname1%' AND nachname LIKE '%1Nachname%' AND 1)) +AND FK_firma_id = 2; +COUNT(*) +0 +drop table t1; diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index 9be08b8390b..6626397e9e5 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -1924,3 +1924,62 @@ EXPLAIN SELECT * FROM t1 LEFT JOIN t2 USE INDEX (a) ON t1.a=t2.a; EXPLAIN SELECT * FROM t1 LEFT JOIN t2 FORCE INDEX (a) ON t1.a=t2.a; DROP TABLE t1, t2; + +# Test for BUG#10095 +CREATE TABLE t1 ( + kunde_intern_id int(10) unsigned NOT NULL default '0', + kunde_id int(10) unsigned NOT NULL default '0', + FK_firma_id int(10) unsigned NOT NULL default '0', + aktuell enum('Ja','Nein') NOT NULL default 'Ja', + vorname varchar(128) NOT NULL default '', + nachname varchar(128) NOT NULL default '', + geloescht enum('Ja','Nein') NOT NULL default 'Nein', + firma varchar(128) NOT NULL default '' +); + +INSERT INTO t1 VALUES + (3964,3051,1,'Ja','Vorname1','1Nachname','Nein','Print Schau XXXX'), + (3965,3051111,1,'Ja','Vorname1111','1111Nachname','Nein','Print Schau XXXX'); + + +SELECT kunde_id ,FK_firma_id ,aktuell, vorname, nachname, geloescht FROM t1 + WHERE + ( + ( + ( '' != '' AND firma LIKE CONCAT('%', '', '%')) + OR + (vorname LIKE CONCAT('%', 'Vorname1', '%') AND + nachname LIKE CONCAT('%', '1Nachname', '%') AND + 'Vorname1' != '' AND 'xxxx' != '') + ) + AND + ( + aktuell = 'Ja' AND geloescht = 'Nein' AND FK_firma_id = 2 + ) + ) + ; + +SELECT kunde_id ,FK_firma_id ,aktuell, vorname, nachname, +geloescht FROM t1 + WHERE + ( + ( + aktuell = 'Ja' AND geloescht = 'Nein' AND FK_firma_id = 2 + ) + AND + ( + ( '' != '' AND firma LIKE CONCAT('%', '', '%') ) + OR + ( vorname LIKE CONCAT('%', 'Vorname1', '%') AND +nachname LIKE CONCAT('%', '1Nachname', '%') AND 'Vorname1' != '' AND +'xxxx' != '') + ) + ) + ; + +SELECT COUNT(*) FROM t1 WHERE +( 0 OR (vorname LIKE '%Vorname1%' AND nachname LIKE '%1Nachname%' AND 1)) +AND FK_firma_id = 2; + +drop table t1; + diff --git a/sql/sql_list.h b/sql/sql_list.h index 370642df2d0..9e62b7ce730 100644 --- a/sql/sql_list.h +++ b/sql/sql_list.h @@ -110,10 +110,32 @@ public: void remove(list_node **prev) { list_node *node=(*prev)->next; + if (&(*prev)->next == last) + { + /* + We're removing the last element from the list. Adjust "last" to point + to the previous element. + The other way to fix this would be to change this function to + remove_next() and have base_list_iterator save ptr to previous node + (one extra assignment in iterator++) but as the remove() of the last + element isn't a common operation it's faster to just walk through the + list from the beginning here. + */ + list_node *cur= first; + if (cur == *prev) + { + last= &first; + } + else + { + while (cur->next != *prev) + cur= cur->next; + last= &(cur->next); + } + } delete *prev; *prev=node; - if (!--elements) - last= &first; + elements--; } inline void *pop(void) { @@ -130,6 +152,54 @@ public: inline list_node *last_ref() { return &end_of_list; } friend class base_list_iterator; +#ifdef LIST_EXTRA_DEBUG + /* + Check list invariants and print results into trace. Invariants are: + - (*last) points to end_of_list + - There are no NULLs in the list. + - base_list::elements is the number of elements in the list. + + SYNOPSIS + check_list() + name Name to print to trace file + + RETURN + 1 The list is Ok. + 0 List invariants are not met. + */ + + bool check_list(const char *name) + { + base_list *list= this; + list_node *node= first; + uint cnt= 0; + + while (node->next != &end_of_list) + { + if (!node->info) + { + DBUG_PRINT("list_invariants",("%s: error: NULL element in the list", + name)); + return FALSE; + } + node= node->next; + cnt++; + } + if (last != &(node->next)) + { + DBUG_PRINT("list_invariants", ("%s: error: wrong last pointer", name)); + return FALSE; + } + if (cnt+1 != elements) + { + DBUG_PRINT("list_invariants", ("%s: error: wrong element count", name)); + return FALSE; + } + DBUG_PRINT("list_invariants", ("%s: list is ok", name)); + return TRUE; + } +#endif // LIST_EXTRA_DEBUG + protected: void after(void *info,list_node *node) { From 446d4631c7ab899fb7caef68ff260fbc642a4698 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 18 May 2005 20:50:29 +0200 Subject: [PATCH 05/19] BUG#9626 - Fix valgrind warnings - Remove static db, schema and table name buffers from Ndb.cpp mysys/thr_alarm.c: Initialise sact to zero ndb/include/kernel/ndb_limits.h: Set MAX_ATTR_NAME_SIZE to NAME_LEN which is tha maximum in MySQL ndb/include/kernel/signaldata/GetTabInfo.hpp: Clean up ndb/include/ndbapi/Ndb.hpp: Remove NDB_MAX_INTERNAL_NAME_LENGTH and all char buffers for schema, db and tablename. Made them dynamic and moved to NdbImpl.hpp ndb/include/ndbapi/ndbapi_limits.h: Remove the static length's of attr, db, schema and table name. ndb/src/common/transporter/Packer.cpp: Set theSignalId to ~0 when unpacking signal ndb/src/ndbapi/Ndb.cpp: Moved schema, database and tablename to NdbImpl.hpp ndb/src/ndbapi/NdbDictionaryImpl.cpp: Add NdbIndexImpl::init and NdbEventImpl::init Init all vars in NdbIndexImpl, NdbEventImpl, NdbTableImpl and NdbIndexImpl Delete the pseudo column NDB$RANGE_NO Copy tablename to internal buff in NdbDictInterface to get proper alignment. Convert length of table name from bytes words, when setting sz of LinearSectionPtr Set LinearSectionPtr array size to number of LinearSections used - save some stack. ndb/src/ndbapi/NdbDictionaryImpl.hpp: Add NdbEventImpl::init and NdbIndexImpl::init Remove clearNewProperties and copyNewProperties, it's easier to check if all vars are initied if it's done in the same func. Add buffer for tabname ti NdbDictInterface, memset it to 0 in initializer. ndb/src/ndbapi/NdbImpl.hpp: Use BaseString for table, schema and db names. ndb/src/ndbapi/Ndbinit.cpp: Move schema and db name to NdbImpl and use BaseString ndb/src/ndbapi/ndb_cluster_connection.cpp: Destroy ndb_global_event_buffer_mutex and ndb_print_state_mutex sql/ha_ndbcluster.cc: Check if pTrans is not null before calling closeTransaction Remove NDB_MAX_ATTR_NAME_SIZE Remove truncation of attr names. When attr name length is same in NDB as in MySQL this will be checked in functin check_column_name --- mysys/thr_alarm.c | 1 + ndb/include/kernel/ndb_limits.h | 4 +- ndb/include/kernel/signaldata/GetTabInfo.hpp | 32 ++-- ndb/include/ndbapi/Ndb.hpp | 11 +- ndb/include/ndbapi/ndbapi_limits.h | 4 - ndb/src/common/transporter/Packer.cpp | 1 + ndb/src/ndbapi/Ndb.cpp | 54 ++---- ndb/src/ndbapi/NdbDictionaryImpl.cpp | 167 +++++++++++-------- ndb/src/ndbapi/NdbDictionaryImpl.hpp | 12 +- ndb/src/ndbapi/NdbImpl.hpp | 31 ++++ ndb/src/ndbapi/Ndbinit.cpp | 14 +- ndb/src/ndbapi/ndb_cluster_connection.cpp | 24 ++- sql/ha_ndbcluster.cc | 22 +-- 13 files changed, 194 insertions(+), 183 deletions(-) diff --git a/mysys/thr_alarm.c b/mysys/thr_alarm.c index 19611a6027a..44bbb385047 100644 --- a/mysys/thr_alarm.c +++ b/mysys/thr_alarm.c @@ -85,6 +85,7 @@ void init_thr_alarm(uint max_alarms) #else { struct sigaction sact; + bzero(&sact, sizeof(sact)); sact.sa_flags = 0; sact.sa_handler = thread_alarm; sigaction(THR_CLIENT_ALARM, &sact, (struct sigaction*) 0); diff --git a/ndb/include/kernel/ndb_limits.h b/ndb/include/kernel/ndb_limits.h index 2646b54fa02..d91d30baf56 100644 --- a/ndb/include/kernel/ndb_limits.h +++ b/ndb/include/kernel/ndb_limits.h @@ -17,6 +17,8 @@ #ifndef NDB_LIMITS_H #define NDB_LIMITS_H +#include + #define RNIL 0xffffff00 /** @@ -52,7 +54,7 @@ #define MAX_TUPLES_BITS 13 /* 13 bits = 8191 tuples per page */ #define MAX_TABLES 1600 #define MAX_TAB_NAME_SIZE 128 -#define MAX_ATTR_NAME_SIZE 32 +#define MAX_ATTR_NAME_SIZE NAME_LEN /* From mysql_com.h */ #define MAX_ATTR_DEFAULT_VALUE_SIZE 128 #define MAX_ATTRIBUTES_IN_TABLE 128 #define MAX_ATTRIBUTES_IN_INDEX 32 diff --git a/ndb/include/kernel/signaldata/GetTabInfo.hpp b/ndb/include/kernel/signaldata/GetTabInfo.hpp index cb6e38872d3..6b223cab119 100644 --- a/ndb/include/kernel/signaldata/GetTabInfo.hpp +++ b/ndb/include/kernel/signaldata/GetTabInfo.hpp @@ -39,23 +39,16 @@ class GetTabInfoReq { friend bool printGET_TABINFO_REQ(FILE *, const Uint32 *, Uint32, Uint16); public: STATIC_CONST( SignalLength = 5 ); - // STATIC_CONST( MaxTableNameLengthInWords = 20 ); public: - Uint32 senderData; + Uint32 senderData; Uint32 senderRef; - - /** - * 0 = request by id, 1 = request by name - */ - Uint32 requestType; - + Uint32 requestType; // Bitmask of GetTabInfoReq::RequestType union { - Uint32 tableId; + Uint32 tableId; Uint32 tableNameLen; }; Uint32 unused; // This is located here so that Req & Ref have the same format - // Uint32 tableName[MaxTableNameLengthInWords]; - + enum RequestType { RequestById = 0, RequestByName = 1, @@ -79,22 +72,21 @@ class GetTabInfoRef { friend bool printGET_TABINFO_REF(FILE *, const Uint32 *, Uint32, Uint16); public: STATIC_CONST( SignalLength = 5 ); - public: - Uint32 senderData; + Uint32 senderData; Uint32 senderRef; - Uint32 requestType; // 0 = request by id, 1 = request by name + Uint32 requestType; // Bitmask of GetTabInfoReq::RequestType union { - Uint32 tableId; + Uint32 tableId; Uint32 tableNameLen; }; - Uint32 errorCode; + Uint32 errorCode; enum ErrorCode { - InvalidTableId = 709, + InvalidTableId = 709, TableNotDefined = 723, TableNameTooLong = 702, - Busy = 701 + Busy = 701 }; }; @@ -114,10 +106,10 @@ class GetTabInfoConf { friend bool printGET_TABINFO_CONF(FILE *, const Uint32 *, Uint32, Uint16); public: STATIC_CONST( SignalLength = 4 ); - + SECTION( DICT_TAB_INFO = 0 ); public: - Uint32 senderData; + Uint32 senderData; Uint32 tableId; Uint32 gci; // For table Uint32 totalLen; // In words diff --git a/ndb/include/ndbapi/Ndb.hpp b/ndb/include/ndbapi/Ndb.hpp index 41085e6e06a..a36cdc2b475 100644 --- a/ndb/include/ndbapi/Ndb.hpp +++ b/ndb/include/ndbapi/Ndb.hpp @@ -999,10 +999,6 @@ typedef void (* NdbEventCallback)(NdbEventOperation*, Ndb*, void*); #define WAITFOR_RESPONSE_TIMEOUT 120000 // Milliseconds #endif -#define NDB_MAX_INTERNAL_TABLE_LENGTH NDB_MAX_DATABASE_NAME_SIZE + \ - NDB_MAX_SCHEMA_NAME_SIZE + \ - NDB_MAX_TAB_NAME_SIZE*2 - /** * @class Ndb * @brief Represents the NDB kernel and is the main class of the NDB API. @@ -1626,12 +1622,7 @@ private: bool fullyQualifiedNames; - // Ndb database name. - char theDataBase[NDB_MAX_DATABASE_NAME_SIZE]; - // Ndb database schema name. - char theDataBaseSchema[NDB_MAX_SCHEMA_NAME_SIZE]; - char prefixName[NDB_MAX_INTERNAL_TABLE_LENGTH]; - char * prefixEnd; + class NdbImpl * theImpl; class NdbDictionaryImpl* theDictionary; diff --git a/ndb/include/ndbapi/ndbapi_limits.h b/ndb/include/ndbapi/ndbapi_limits.h index d1cb135b39d..5c4db71b747 100644 --- a/ndb/include/ndbapi/ndbapi_limits.h +++ b/ndb/include/ndbapi/ndbapi_limits.h @@ -19,10 +19,6 @@ #define NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY 32 #define NDB_MAX_ATTRIBUTES_IN_INDEX NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY -#define NDB_MAX_DATABASE_NAME_SIZE 128 -#define NDB_MAX_SCHEMA_NAME_SIZE 128 -#define NDB_MAX_TAB_NAME_SIZE 128 -#define NDB_MAX_ATTR_NAME_SIZE 32 #define NDB_MAX_ATTRIBUTES_IN_TABLE 128 #define NDB_MAX_TUPLE_SIZE_IN_WORDS 2013 diff --git a/ndb/src/common/transporter/Packer.cpp b/ndb/src/common/transporter/Packer.cpp index 9eba335330d..bcfac8417bb 100644 --- a/ndb/src/common/transporter/Packer.cpp +++ b/ndb/src/common/transporter/Packer.cpp @@ -93,6 +93,7 @@ TransporterRegistry::unpack(Uint32 * readPtr, signalHeader.theSendersSignalId = * signalData; signalData ++; }//if + signalHeader.theSignalId= ~0; Uint32 * sectionPtr = signalData + signalHeader.theLength; Uint32 * sectionData = sectionPtr + signalHeader.m_noOfSections; diff --git a/ndb/src/ndbapi/Ndb.cpp b/ndb/src/ndbapi/Ndb.cpp index 5efef1b0112..5b1a33ce68f 100644 --- a/ndb/src/ndbapi/Ndb.cpp +++ b/ndb/src/ndbapi/Ndb.cpp @@ -1041,39 +1041,31 @@ convertEndian(Uint32 Data) } const char * Ndb::getCatalogName() const { - return theDataBase; + return theImpl->m_dbname.c_str(); } - + + void Ndb::setCatalogName(const char * a_catalog_name) { - if (a_catalog_name) { - BaseString::snprintf(theDataBase, sizeof(theDataBase), "%s", - a_catalog_name ? a_catalog_name : ""); - - int len = BaseString::snprintf(prefixName, sizeof(prefixName), "%s%c%s%c", - theDataBase, table_name_separator, - theDataBaseSchema, table_name_separator); - prefixEnd = prefixName + (len < (int) sizeof(prefixName) ? len : - sizeof(prefixName) - 1); + if (a_catalog_name) + { + theImpl->m_dbname.assign(a_catalog_name); + theImpl->update_prefix(); } } - + + const char * Ndb::getSchemaName() const { - return theDataBaseSchema; + return theImpl->m_schemaname.c_str(); } - + + void Ndb::setSchemaName(const char * a_schema_name) { if (a_schema_name) { - BaseString::snprintf(theDataBaseSchema, sizeof(theDataBase), "%s", - a_schema_name ? a_schema_name : ""); - - int len = BaseString::snprintf(prefixName, sizeof(prefixName), "%s%c%s%c", - theDataBase, table_name_separator, - theDataBaseSchema, table_name_separator); - prefixEnd = prefixName + (len < (int) sizeof(prefixName) ? len : - sizeof(prefixName) - 1); + theImpl->m_schemaname.assign(a_schema_name); + theImpl->update_prefix(); } } @@ -1153,10 +1145,8 @@ Ndb::externalizeIndexName(const char * internalIndexName) const char * Ndb::internalizeTableName(const char * externalTableName) { - if (fullyQualifiedNames) { - strncpy(prefixEnd, externalTableName, NDB_MAX_TAB_NAME_SIZE); - return prefixName; - } + if (fullyQualifiedNames) + return theImpl->internalize_table_name(externalTableName); else return externalTableName; } @@ -1165,16 +1155,8 @@ const char * Ndb::internalizeIndexName(const NdbTableImpl * table, const char * externalIndexName) { - if (fullyQualifiedNames) { - char tableId[10]; - sprintf(tableId, "%d", table->m_tableId); - Uint32 tabIdLen = strlen(tableId); - strncpy(prefixEnd, tableId, tabIdLen); - prefixEnd[tabIdLen] = table_name_separator; - strncpy(prefixEnd + tabIdLen + 1, - externalIndexName, NDB_MAX_TAB_NAME_SIZE); - return prefixName; - } + if (fullyQualifiedNames) + return theImpl->internalize_index_name(table, externalIndexName); else return externalIndexName; } diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/ndb/src/ndbapi/NdbDictionaryImpl.cpp index 96c8f6020e5..1bce2897b76 100644 --- a/ndb/src/ndbapi/NdbDictionaryImpl.cpp +++ b/ndb/src/ndbapi/NdbDictionaryImpl.cpp @@ -172,6 +172,7 @@ NdbColumnImpl::init(Type t) m_length = 1; // legal m_cs = NULL; break; + default: case Undefined: assert(false); break; @@ -297,22 +298,25 @@ NdbTableImpl::~NdbTableImpl() void NdbTableImpl::init(){ - clearNewProperties(); + m_changeMask= 0; + m_tableId= RNIL; m_frm.clear(); - m_fragmentType = NdbDictionary::Object::FragAllSmall; - m_logging = true; - m_kvalue = 6; - m_minLoadFactor = 78; - m_maxLoadFactor = 80; - - m_index = 0; - m_indexType = NdbDictionary::Index::Undefined; - - m_noOfKeys = 0; - m_noOfDistributionKeys = 0; - m_fragmentCount = 0; - m_keyLenInWords = 0; - m_noOfBlobs = 0; + m_fragmentType= NdbDictionary::Object::FragAllSmall; + m_hashValueMask= 0; + m_hashpointerValue= 0; + m_logging= true; + m_kvalue= 6; + m_minLoadFactor= 78; + m_maxLoadFactor= 80; + m_keyLenInWords= 0; + m_fragmentCount= 0; + m_dictionary= NULL; + m_index= NULL; + m_indexType= NdbDictionary::Index::Undefined; + m_noOfKeys= 0; + m_noOfDistributionKeys= 0; + m_noOfBlobs= 0; + m_replicaCount= 0; } bool @@ -426,19 +430,6 @@ NdbTableImpl::getName() const return m_newExternalName.c_str(); } -void NdbTableImpl::clearNewProperties() -{ - m_newExternalName.assign(""); - m_changeMask = 0; -} - -void NdbTableImpl::copyNewProperties() -{ - if (!m_newExternalName.empty()) { - m_externalName.assign(m_newExternalName); - AlterTableReq::setNameFlag(m_changeMask, true); - } -} void NdbTableImpl::buildColumnHash(){ @@ -535,14 +526,22 @@ NdbIndexImpl::NdbIndexImpl() : NdbDictionary::Index(* this), m_facade(this) { - m_logging = true; + init(); } NdbIndexImpl::NdbIndexImpl(NdbDictionary::Index & f) : NdbDictionary::Index(* this), m_facade(&f) { - m_logging = true; + init(); +} + +void NdbIndexImpl::init() +{ + m_indexId= RNIL; + m_type= NdbDictionary::Index::Undefined; + m_logging= true; + m_table= NULL; } NdbIndexImpl::~NdbIndexImpl(){ @@ -587,20 +586,26 @@ NdbEventImpl::NdbEventImpl() : NdbDictionary::Event(* this), m_facade(this) { - mi_type = 0; - m_dur = NdbDictionary::Event::ED_UNDEFINED; - eventOp = NULL; - m_tableImpl = NULL; + init(); } NdbEventImpl::NdbEventImpl(NdbDictionary::Event & f) : NdbDictionary::Event(* this), m_facade(&f) { - mi_type = 0; - m_dur = NdbDictionary::Event::ED_UNDEFINED; - eventOp = NULL; - m_tableImpl = NULL; + init(); +} + +void NdbEventImpl::init() +{ + m_eventId= RNIL; + m_eventKey= RNIL; + m_tableId= RNIL; + mi_type= 0; + m_dur= NdbDictionary::Event::ED_UNDEFINED; + m_tableImpl= NULL; + m_bufferId= RNIL; + eventOp= NULL; } NdbEventImpl::~NdbEventImpl() @@ -713,11 +718,13 @@ NdbDictionaryImpl::~NdbDictionaryImpl() delete NdbDictionary::Column::ROW_COUNT; delete NdbDictionary::Column::COMMIT_COUNT; delete NdbDictionary::Column::ROW_SIZE; + delete NdbDictionary::Column::RANGE_NO; NdbDictionary::Column::FRAGMENT= 0; NdbDictionary::Column::FRAGMENT_MEMORY= 0; NdbDictionary::Column::ROW_COUNT= 0; NdbDictionary::Column::COMMIT_COUNT= 0; NdbDictionary::Column::ROW_SIZE= 0; + NdbDictionary::Column::RANGE_NO= 0; } m_globalHash->unlock(); } else { @@ -1047,61 +1054,75 @@ NdbDictInterface::dictSignal(NdbApiSignal* signal, DBUG_RETURN(-1); } -/***************************************************************** - * get tab info +/* + Get dictionary information for a table using table id as reference + + DESCRIPTION + Sends a GET_TABINFOREQ signal containing the table id */ -NdbTableImpl * +NdbTableImpl * NdbDictInterface::getTable(int tableId, bool fullyQualifiedNames) { NdbApiSignal tSignal(m_reference); - GetTabInfoReq * const req = CAST_PTR(GetTabInfoReq, tSignal.getDataPtrSend()); - + GetTabInfoReq* const req = CAST_PTR(GetTabInfoReq, tSignal.getDataPtrSend()); + req->senderRef = m_reference; req->senderData = 0; - req->requestType = + req->requestType = GetTabInfoReq::RequestById | GetTabInfoReq::LongSignalConf; req->tableId = tableId; tSignal.theReceiversBlockNumber = DBDICT; tSignal.theVerId_signalNumber = GSN_GET_TABINFOREQ; tSignal.theLength = GetTabInfoReq::SignalLength; - + return getTable(&tSignal, 0, 0, fullyQualifiedNames); } -NdbTableImpl * + +/* + Get dictionary information for a table using table name as the reference + + DESCRIPTION + Send GET_TABINFOREQ signal with the table name in the first + long section part +*/ +NdbTableImpl * NdbDictInterface::getTable(const char * name, bool fullyQualifiedNames) { NdbApiSignal tSignal(m_reference); - GetTabInfoReq * const req = CAST_PTR(GetTabInfoReq, tSignal.getDataPtrSend()); - - const Uint32 strLen = strlen(name) + 1; // NULL Terminated - if(strLen > MAX_TAB_NAME_SIZE) {//sizeof(req->tableName)){ - m_error.code= 4307; - return 0; - } + GetTabInfoReq* const req = CAST_PTR(GetTabInfoReq, tSignal.getDataPtrSend()); - req->senderRef = m_reference; - req->senderData = 0; - req->requestType = + const Uint32 str_len= strlen(name) + 1; // NULL terminated + + /* Note! It might be a good idea to check that the length of + table name does not exceed the max size of a long signal */ + + m_namebuf.clear(); + m_namebuf.grow(str_len+(4-str_len%4)); // Round up to word size + m_namebuf.append(name, str_len); + + req->senderRef= m_reference; + req->senderData= 0; + req->requestType= GetTabInfoReq::RequestByName | GetTabInfoReq::LongSignalConf; - req->tableNameLen = strLen; - tSignal.theReceiversBlockNumber = DBDICT; - tSignal.theVerId_signalNumber = GSN_GET_TABINFOREQ; - // tSignal.theLength = GetTabInfoReq::HeaderLength + ((strLen + 3) / 4); - tSignal.theLength = GetTabInfoReq::SignalLength; + req->tableNameLen= str_len; + tSignal.theReceiversBlockNumber= DBDICT; + tSignal.theVerId_signalNumber= GSN_GET_TABINFOREQ; + tSignal.theLength= GetTabInfoReq::SignalLength; + LinearSectionPtr ptr[1]; - ptr[0].p = (Uint32*)name; - ptr[0].sz = strLen; - + ptr[0].p= (Uint32*)m_namebuf.get_data(); + ptr[0].sz= (str_len + 3)/ 4; // Size in words + return getTable(&tSignal, ptr, 1, fullyQualifiedNames); } + NdbTableImpl * -NdbDictInterface::getTable(class NdbApiSignal * signal, +NdbDictInterface::getTable(class NdbApiSignal * signal, LinearSectionPtr ptr[3], Uint32 noOfSections, bool fullyQualifiedNames) { - //GetTabInfoReq * const req = CAST_PTR(GetTabInfoReq, signal->getDataPtrSend()); int errCodes[] = {GetTabInfoRef::Busy }; int r = dictSignal(signal,ptr,noOfSections, @@ -1462,7 +1483,7 @@ NdbDictionaryImpl::createBlobTables(NdbTableImpl &t) return -1; // Save BLOB table handle Ndb_local_table_info *info= - get_local_table_info(bt.m_internalName.c_str(),false); + get_local_table_info(bt.m_internalName.c_str(), false); if (info == 0) { return -1; } @@ -1558,7 +1579,11 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb, DBUG_RETURN(-1); } - impl.copyNewProperties(); + if (!impl.m_newExternalName.empty()) { + impl.m_externalName.assign(impl.m_newExternalName); + AlterTableReq::setNameFlag(impl.m_changeMask, true); + } + //validate(); //aggregate(); @@ -1675,7 +1700,7 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb, NdbApiSignal tSignal(m_reference); tSignal.theReceiversBlockNumber = DBDICT; - LinearSectionPtr ptr[3]; + LinearSectionPtr ptr[1]; ptr[0].p = (Uint32*)m_buffer.get_data(); ptr[0].sz = m_buffer.length() / 4; int ret; @@ -2180,7 +2205,7 @@ NdbDictInterface::createIndex(Ndb & ndb, } attributeList.id[i] = col->m_attrId; } - LinearSectionPtr ptr[3]; + LinearSectionPtr ptr[2]; ptr[0].p = (Uint32*)&attributeList; ptr[0].sz = 1 + attributeList.sz; ptr[1].p = (Uint32*)m_buffer.get_data(); @@ -2487,7 +2512,7 @@ NdbDictInterface::createEvent(class Ndb & ndb, w.add(SimpleProperties::StringValue, ndb.internalizeTableName(evnt.m_tableName.c_str())); - LinearSectionPtr ptr[3]; + LinearSectionPtr ptr[1]; ptr[0].p = (Uint32*)m_buffer.get_data(); ptr[0].sz = (m_buffer.length()+3) >> 2; diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.hpp b/ndb/src/ndbapi/NdbDictionaryImpl.hpp index 59a5956715a..d61bc2ecc55 100644 --- a/ndb/src/ndbapi/NdbDictionaryImpl.hpp +++ b/ndb/src/ndbapi/NdbDictionaryImpl.hpp @@ -161,8 +161,6 @@ public: */ bool equal(const NdbTableImpl&) const; void assign(const NdbTableImpl&); - void clearNewProperties(); - void copyNewProperties(); static NdbTableImpl & getImpl(NdbDictionary::Table & t); static NdbTableImpl & getImpl(const NdbDictionary::Table & t); @@ -180,6 +178,7 @@ public: NdbIndexImpl(NdbDictionary::Index &); ~NdbIndexImpl(); + void init(); void setName(const char * name); const char * getName() const; void setTable(const char * table); @@ -209,6 +208,7 @@ public: NdbEventImpl(NdbDictionary::Event &); ~NdbEventImpl(); + void init(); void setName(const char * name); const char * getName() const; void setTable(const NdbDictionary::Table& table); @@ -368,6 +368,8 @@ private: Uint32 m_fragmentId; UtilBuffer m_buffer; + // Buffer used when requesting a table by name + UtilBuffer m_namebuf; }; class NdbDictionaryImpl : public NdbDictionary::Dictionary { @@ -378,7 +380,7 @@ public: bool setTransporter(class Ndb * ndb, class TransporterFacade * tf); bool setTransporter(class TransporterFacade * tf); - + int createTable(NdbTableImpl &t); int createBlobTables(NdbTableImpl &); int addBlobTables(NdbTableImpl &); @@ -560,7 +562,7 @@ NdbTableImpl::getColumn(const char * name){ do { if(hashValue == (tmp & 0xFFFE)){ NdbColumnImpl* col = cols[tmp >> 16]; - if(strncmp(name, col->m_name.c_str(), NDB_MAX_ATTR_NAME_SIZE-1) == 0){ + if(strncmp(name, col->m_name.c_str(), col->m_name.length()) == 0){ return col; } } @@ -578,7 +580,7 @@ NdbTableImpl::getColumn(const char * name){ } else { for(Uint32 i = 0; im_name.c_str(), NDB_MAX_ATTR_NAME_SIZE-1) == 0) + if(col != 0 && strncmp(name, col->m_name.c_str(), col->m_name.length()) == 0) return col; } } diff --git a/ndb/src/ndbapi/NdbImpl.hpp b/ndb/src/ndbapi/NdbImpl.hpp index d649b39c5eb..f4ce76fee61 100644 --- a/ndb/src/ndbapi/NdbImpl.hpp +++ b/ndb/src/ndbapi/NdbImpl.hpp @@ -59,6 +59,37 @@ public: NdbWaiter theWaiter; int m_optimized_node_selection; + + + BaseString m_dbname; // Database name + BaseString m_schemaname; // Schema name + + BaseString m_prefix; // Buffer for preformatted internal name // + BaseString m_internalname; + + void update_prefix() + { + m_prefix.assfmt("%s%c%s%c", m_dbname.c_str(), table_name_separator, + m_schemaname.c_str(), table_name_separator); + } + + const char* internalize_table_name(const char* ext_name) + { + // Internal table name format // + return m_internalname.assign(m_prefix).append(ext_name).c_str(); + } + + const char* internalize_index_name(const NdbTableImpl *table, + const char* ext_name) + { + // Internal index name format ///
+ return m_internalname.assign(m_prefix).appfmt("%d%c%s", + table->m_tableId, + table_name_separator, + ext_name).c_str(); + } + + }; #ifdef VM_TRACE diff --git a/ndb/src/ndbapi/Ndbinit.cpp b/ndb/src/ndbapi/Ndbinit.cpp index 4db9d05b59c..ccd0cf85c5e 100644 --- a/ndb/src/ndbapi/Ndbinit.cpp +++ b/ndb/src/ndbapi/Ndbinit.cpp @@ -62,7 +62,6 @@ void Ndb::setup(Ndb_cluster_connection *ndb_cluster_connection, theNoOfAllocatedTransactions= 0; theMaxNoOfTransactions= 0; theMinNoOfEventsToWakeUp= 0; - prefixEnd= NULL; theConIdleList= NULL; theOpIdleList= NULL; theScanOpIdleList= NULL; @@ -109,17 +108,10 @@ void Ndb::setup(Ndb_cluster_connection *ndb_cluster_connection, theFirstTupleId[i] = 0; theLastTupleId[i] = 0; }//for - - BaseString::snprintf(theDataBase, sizeof(theDataBase), "%s", - aDataBase ? aDataBase : ""); - BaseString::snprintf(theDataBaseSchema, sizeof(theDataBaseSchema), "%s", - aSchema ? aSchema : ""); - int len = BaseString::snprintf(prefixName, sizeof(prefixName), "%s%c%s%c", - theDataBase, table_name_separator, - theDataBaseSchema, table_name_separator); - prefixEnd = prefixName + (len < (int) sizeof(prefixName) ? len : - sizeof(prefixName) - 1); + theImpl->m_dbname.assign(aDataBase); + theImpl->m_schemaname.assign(aSchema); + theImpl->update_prefix(); theImpl->theWaiter.m_mutex = TransporterFacade::instance()->theMutexPtr; diff --git a/ndb/src/ndbapi/ndb_cluster_connection.cpp b/ndb/src/ndbapi/ndb_cluster_connection.cpp index 49aded8e0ac..7625da609b0 100644 --- a/ndb/src/ndbapi/ndb_cluster_connection.cpp +++ b/ndb/src/ndbapi/ndb_cluster_connection.cpp @@ -265,14 +265,11 @@ Ndb_cluster_connection_impl::Ndb_cluster_connection_impl(const char * m_connect_callback= 0; if (ndb_global_event_buffer_mutex == NULL) - { ndb_global_event_buffer_mutex= NdbMutex_Create(); - } + #ifdef VM_TRACE if (ndb_print_state_mutex == NULL) - { ndb_print_state_mutex= NdbMutex_Create(); - } #endif m_config_retriever= new ConfigRetriever(connect_string, NDB_VERSION, NODE_TYPE_API); @@ -294,7 +291,6 @@ Ndb_cluster_connection_impl::Ndb_cluster_connection_impl(const char * Ndb_cluster_connection_impl::~Ndb_cluster_connection_impl() { DBUG_ENTER("~Ndb_cluster_connection"); - DBUG_PRINT("enter",("~Ndb_cluster_connection this=0x%x", this)); TransporterFacade::stop_instance(); if (m_connect_thread) { @@ -312,10 +308,22 @@ Ndb_cluster_connection_impl::~Ndb_cluster_connection_impl() TransporterFacade::theFacadeInstance= 0; } if (m_config_retriever) + { delete m_config_retriever; - - // fragmentToNodeMap.release(); - + m_config_retriever= NULL; + } + if (ndb_global_event_buffer_mutex != NULL) + { + NdbMutex_Destroy(ndb_global_event_buffer_mutex); + ndb_global_event_buffer_mutex= NULL; + } +#ifdef VM_TRACE + if (ndb_print_state_mutex != NULL) + { + NdbMutex_Destroy(ndb_print_state_mutex); + ndb_print_state_mutex= NULL; + } +#endif DBUG_VOID_RETURN; } diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 372a178b59a..6ccaa668df9 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -985,16 +985,13 @@ static int fix_unique_index_attr_order(NDB_INDEX_DATA &data, for (unsigned i= 0; key_part != end; key_part++, i++) { const char *field_name= key_part->field->field_name; - unsigned name_sz= strlen(field_name); - if (name_sz >= NDB_MAX_ATTR_NAME_SIZE) - name_sz= NDB_MAX_ATTR_NAME_SIZE-1; #ifndef DBUG_OFF data.unique_index_attrid_map[i]= 255; #endif for (unsigned j= 0; j < sz; j++) { const NDBCOL *c= index->getColumn(j); - if (strncmp(field_name, c->getName(), name_sz) == 0) + if (strcmp(field_name, c->getName()) == 0) { data.unique_index_attrid_map[i]= j; break; @@ -3545,12 +3542,7 @@ static int create_ndb_column(NDBCOL &col, HA_CREATE_INFO *info) { // Set name - { - char truncated_field_name[NDB_MAX_ATTR_NAME_SIZE]; - strnmov(truncated_field_name,field->field_name,sizeof(truncated_field_name)); - truncated_field_name[sizeof(truncated_field_name)-1]= '\0'; - col.setName(truncated_field_name); - } + col.setName(field->field_name); // Get char set CHARSET_INFO *cs= field->charset(); // Set type and sizes @@ -4040,12 +4032,7 @@ int ha_ndbcluster::create_index(const char *name, { Field *field= key_part->field; DBUG_PRINT("info", ("attr: %s", field->field_name)); - { - char truncated_field_name[NDB_MAX_ATTR_NAME_SIZE]; - strnmov(truncated_field_name,field->field_name,sizeof(truncated_field_name)); - truncated_field_name[sizeof(truncated_field_name)-1]= '\0'; - ndb_index.addColumnName(truncated_field_name); - } + ndb_index.addColumnName(field->field_name); } if (dict->createIndex(ndb_index)) @@ -5507,7 +5494,8 @@ ndb_get_table_statistics(Ndb* ndb, const char * table, DBUG_RETURN(0); } while(0); - ndb->closeTransaction(pTrans); + if (pTrans) + ndb->closeTransaction(pTrans); DBUG_PRINT("exit", ("failed")); DBUG_RETURN(-1); } From e507f6a15ec33b762c7d6475a49d8c760316d19c Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 18 May 2005 21:31:39 +0200 Subject: [PATCH 06/19] udf: when banning paths from soname in CREATE FUNCTION, check for \ on windows. when reporting an error, use an appropriate buffer for udf->name --- sql/sql_udf.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index ae83cfef305..556e015e111 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -190,7 +190,9 @@ void udf_init() This is done to ensure that only approved dll from the system directories are used (to make this even remotely secure). */ - if (strchr(dl_name, '/') || strlen(name) > NAME_LEN) + if (strchr(dl_name, '/') || + IF_WIN(strchr(dl_name, '\\'),0) || + strlen(name) > NAME_LEN) { sql_print_error("Invalid row in mysql.func table for function '%.64s'", name); @@ -219,7 +221,7 @@ void udf_init() } tmp->dlhandle = dl; { - char buf[MAX_FIELD_NAME+16], *missing; + char buf[NAME_LEN+16], *missing; if ((missing= init_syms(tmp, buf))) { sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), missing); @@ -403,7 +405,7 @@ int mysql_create_function(THD *thd,udf_func *udf) This is done to ensure that only approved dll from the system directories are used (to make this even remotely secure). */ - if (strchr(udf->dl, '/')) + if (strchr(udf->dl, '/') || IF_WIN(strchr(dl_name, '\\'),0)) { send_error(&thd->net, ER_UDF_NO_PATHS,ER(ER_UDF_NO_PATHS)); DBUG_RETURN(1); @@ -433,7 +435,7 @@ int mysql_create_function(THD *thd,udf_func *udf) } udf->dlhandle=dl; { - char buf[MAX_FIELD_NAME+16], *missing; + char buf[NAME_LEN+16], *missing; if ((missing= init_syms(udf, buf))) { net_printf(&thd->net, ER_CANT_FIND_DL_ENTRY, missing); From 275aa247405e3fbd364598132858b27e9e47cc7d Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 May 2005 09:47:13 +0200 Subject: [PATCH 07/19] after merge fix --- mysql-test/r/select.result | 2 +- sql/sql_udf.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 38ebd26abe4..c39d1a322e4 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -2454,7 +2454,7 @@ select all distinct * from t1; ERROR HY000: Incorrect usage of ALL and DISTINCT select distinct all * from t1; ERROR HY000: Incorrect usage of ALL and DISTINCT -DROP TABLE t1; +drop table t1; CREATE TABLE t1 ( kunde_intern_id int(10) unsigned NOT NULL default '0', kunde_id int(10) unsigned NOT NULL default '0', diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index 7157111b25c..31205c0a614 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -195,7 +195,7 @@ void udf_init() */ if (strchr(dl_name, '/') || IF_WIN(strchr(dl_name, '\\'),0) || - strlen(name) > NAME_LEN) + strlen(name.str) > NAME_LEN) { sql_print_error("Invalid row in mysql.func table for function '%.64s'", name.str); From 50bb2039792a406f7ba1a5de9cddfc47d4a6c4fd Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 May 2005 12:53:44 +0200 Subject: [PATCH 08/19] Fix ndb/src/ndbapi/NdbDictionaryImpl.hpp: Don't use length when comparing column names --- ndb/src/ndbapi/NdbDictionaryImpl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.hpp b/ndb/src/ndbapi/NdbDictionaryImpl.hpp index d61bc2ecc55..7e3e3b19294 100644 --- a/ndb/src/ndbapi/NdbDictionaryImpl.hpp +++ b/ndb/src/ndbapi/NdbDictionaryImpl.hpp @@ -580,7 +580,7 @@ NdbTableImpl::getColumn(const char * name){ } else { for(Uint32 i = 0; im_name.c_str(), col->m_name.length()) == 0) + if(col != 0 && strcmp(name, col->m_name.c_str()) == 0) return col; } } From 4387f4d9670a5edb9298d4c4e2c99b6ace46eca5 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 May 2005 17:59:14 +0500 Subject: [PATCH 09/19] a fix (bug #10599: Numeric function 'abs' make server crash). sql/item_func.cc: a fix (bug #10599: Numeric function 'abs' make server crash). Item_func_abs::decimal_op() now returns 0 if NULL. trivial optimization - get rid of an extra jump for common situations. fixed Item_func_neg::decimal_op() return value if NULL. --- mysql-test/r/type_newdecimal.result | 6 +++ mysql-test/t/type_newdecimal.test | 7 +++ sql/item_func.cc | 66 +++++++++++++++-------------- 3 files changed, 47 insertions(+), 32 deletions(-) diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result index e775724ff54..f03f2f5a862 100644 --- a/mysql-test/r/type_newdecimal.result +++ b/mysql-test/r/type_newdecimal.result @@ -885,3 +885,9 @@ SELECT GRADE FROM t1 WHERE GRADE= 151; GRADE 151 DROP TABLE t1; +select abs(10/0); +abs(10/0) +NULL +select abs(NULL); +abs(NULL) +NULL diff --git a/mysql-test/t/type_newdecimal.test b/mysql-test/t/type_newdecimal.test index 78ad5ed2286..9b09c415379 100644 --- a/mysql-test/t/type_newdecimal.test +++ b/mysql-test/t/type_newdecimal.test @@ -916,3 +916,10 @@ INSERT INTO t1 (GRADE) VALUES (151),(252),(343); SELECT GRADE FROM t1 WHERE GRADE > 160 AND GRADE < 300; SELECT GRADE FROM t1 WHERE GRADE= 151; DROP TABLE t1; + +# +# Bug #10599: problem with NULL +# + +select abs(10/0); +select abs(NULL); diff --git a/sql/item_func.cc b/sql/item_func.cc index f9a9b610e4f..89f9111101a 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1063,11 +1063,11 @@ my_decimal *Item_func_plus::decimal_op(my_decimal *decimal_value) if ((null_value= args[0]->null_value)) return 0; val2= args[1]->val_decimal(&value2); - if ((null_value= (args[1]->null_value || - my_decimal_add(E_DEC_FATAL_ERROR, decimal_value, val1, - val2) > 1))) - return 0; - return decimal_value; + if (!(null_value= (args[1]->null_value || + my_decimal_add(E_DEC_FATAL_ERROR, decimal_value, val1, + val2) > 1))) + return decimal_value; + return 0; } /* @@ -1136,11 +1136,11 @@ my_decimal *Item_func_minus::decimal_op(my_decimal *decimal_value) if ((null_value= args[0]->null_value)) return 0; val2= args[1]->val_decimal(&value2); - if ((null_value= (args[1]->null_value || - my_decimal_sub(E_DEC_FATAL_ERROR, decimal_value, val1, - val2) > 1))) - return 0; - return decimal_value; + if (!(null_value= (args[1]->null_value || + my_decimal_sub(E_DEC_FATAL_ERROR, decimal_value, val1, + val2) > 1))) + return decimal_value; + return 0; } @@ -1174,11 +1174,11 @@ my_decimal *Item_func_mul::decimal_op(my_decimal *decimal_value) if ((null_value= args[0]->null_value)) return 0; val2= args[1]->val_decimal(&value2); - if ((null_value= (args[1]->null_value || - my_decimal_mul(E_DEC_FATAL_ERROR, decimal_value, val1, - val2) > 1))) - return 0; - return decimal_value; + if (!(null_value= (args[1]->null_value || + my_decimal_mul(E_DEC_FATAL_ERROR, decimal_value, val1, + val2) > 1))) + return decimal_value; + return 0; } @@ -1396,8 +1396,9 @@ my_decimal *Item_func_neg::decimal_op(my_decimal *decimal_value) { my_decimal2decimal(value, decimal_value); my_decimal_neg(decimal_value); + return decimal_value; } - return decimal_value; + return 0; } @@ -1460,8 +1461,9 @@ my_decimal *Item_func_abs::decimal_op(my_decimal *decimal_value) my_decimal2decimal(value, decimal_value); if (decimal_value->sign()) my_decimal_neg(decimal_value); + return decimal_value; } - return decimal_value; + return 0; } @@ -1761,11 +1763,11 @@ double Item_func_ceiling::real_op() my_decimal *Item_func_ceiling::decimal_op(my_decimal *decimal_value) { my_decimal val, *value= args[0]->val_decimal(&val); - if ((null_value= (args[0]->null_value || - my_decimal_ceiling(E_DEC_FATAL_ERROR, value, - decimal_value) > 1))) - return 0; - return decimal_value; + if (!(null_value= (args[0]->null_value || + my_decimal_ceiling(E_DEC_FATAL_ERROR, value, + decimal_value) > 1))) + return decimal_value; + return 0; } @@ -1808,11 +1810,11 @@ double Item_func_floor::real_op() my_decimal *Item_func_floor::decimal_op(my_decimal *decimal_value) { my_decimal val, *value= args[0]->val_decimal(&val); - if ((null_value= (args[0]->null_value || - my_decimal_floor(E_DEC_FATAL_ERROR, value, - decimal_value) > 1))) - return 0; - return decimal_value; + if (!(null_value= (args[0]->null_value || + my_decimal_floor(E_DEC_FATAL_ERROR, value, + decimal_value) > 1))) + return decimal_value; + return 0; } @@ -1955,11 +1957,11 @@ my_decimal *Item_func_round::decimal_op(my_decimal *decimal_value) { decimals= min(dec, DECIMAL_MAX_SCALE); // to get correct output } - if ((null_value= (args[0]->null_value || args[1]->null_value || - my_decimal_round(E_DEC_FATAL_ERROR, value, dec, truncate, - decimal_value) > 1))) - return 0; - return decimal_value; + if (!(null_value= (args[0]->null_value || args[1]->null_value || + my_decimal_round(E_DEC_FATAL_ERROR, value, dec, truncate, + decimal_value) > 1))) + return decimal_value; + return 0; } From 2f240961727716d77bd15857df2da401529d32f1 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 May 2005 18:56:01 +0500 Subject: [PATCH 10/19] a fix (#10742: Can't compile "sql_lex.cc" on AIX 5.2). sql/gen_lex_hash.cc: a fix (#10742: Can't compile "sql_lex.cc" on AIX 5.2). typo fixed. --- sql/gen_lex_hash.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc index c3206de3cd4..7e0b178f7af 100644 --- a/sql/gen_lex_hash.cc +++ b/sql/gen_lex_hash.cc @@ -459,8 +459,8 @@ int main(int argc,char **argv) generate_find_structs(); print_find_structs(); - printf("\static unsigned int sql_functions_max_len=%d;\n",max_len); - printf("\static unsigned int symbols_max_len=%d;\n\n",max_len2); + printf("\nstatic unsigned int sql_functions_max_len=%d;\n", max_len); + printf("\nstatic unsigned int symbols_max_len=%d;\n\n", max_len2); printf("\ static inline SYMBOL *get_hash_symbol(const char *s,\n\ From 1dfd89e0264768e332cd7413cf19ee35d02bc20b Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 May 2005 16:00:32 +0200 Subject: [PATCH 11/19] Fix ndb/src/kernel/blocks/ndbfs/AsyncFile.cpp: Removed fix, does not work. --- ndb/src/kernel/blocks/ndbfs/AsyncFile.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/ndb/src/kernel/blocks/ndbfs/AsyncFile.cpp b/ndb/src/kernel/blocks/ndbfs/AsyncFile.cpp index b3fc6e04d6c..f76440a462a 100644 --- a/ndb/src/kernel/blocks/ndbfs/AsyncFile.cpp +++ b/ndb/src/kernel/blocks/ndbfs/AsyncFile.cpp @@ -799,11 +799,7 @@ AsyncFile::rmrfReq(Request * request, char * path, bool removePath){ request->error = errno; return; } -#if defined(__INTEL_COMPILER) - struct dirent64 * dp; -#else struct dirent * dp; -#endif while ((dp = readdir(dirp)) != NULL){ if ((strcmp(".", dp->d_name) != 0) && (strcmp("..", dp->d_name) != 0)) { BaseString::snprintf(path_add, (size_t)path_max_copy, "%s%s", From b8d22413c0cd11d7cb6d8a45a67bf2359e604fe1 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 May 2005 22:53:35 +0500 Subject: [PATCH 12/19] hf's fix for bug #10626 ( gis.test fails) sql/spatial.cc: just float8get doesn't work well with the local variables - they can be of processor-specific floating type - not the standard decimal (by hf) --- sql/spatial.cc | 47 ++++++++++++++++++++++------------------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/sql/spatial.cc b/sql/spatial.cc index bcfefd9dde8..1afb7bb7dec 100644 --- a/sql/spatial.cc +++ b/sql/spatial.cc @@ -96,6 +96,12 @@ static Geometry::Class_info geometrycollection_class("GEOMETRYCOLLECTION",Geometry::wkb_geometrycollection, create_geometrycollection); +static void get_point(double *x, double *y, const char *data) +{ + float8get(*x, data); + float8get(*y, data + SIZEOF_STORED_DOUBLE); +} + /***************************** Geometry *******************************/ Geometry::Class_info *Geometry::find_class(const char *name, uint32 len) @@ -266,14 +272,13 @@ const char *Geometry::append_points(String *txt, uint32 n_points, { while (n_points--) { - double d; + double x,y; data+= offset; - float8get(d, data); - txt->qs_append(d); - txt->qs_append(' '); - float8get(d, data + SIZEOF_STORED_DOUBLE); + get_point(&x, &y, data); data+= SIZEOF_STORED_DOUBLE * 2; - txt->qs_append(d); + txt->qs_append(x); + txt->qs_append(' '); + txt->qs_append(y); txt->qs_append(','); } return data; @@ -426,8 +431,7 @@ bool Gis_line_string::get_data_as_wkt(String *txt, const char **end) const while (n_points--) { double x, y; - float8get(x, data); - float8get(y, data + SIZEOF_STORED_DOUBLE); + get_point(&x, &y, data); data+= SIZEOF_STORED_DOUBLE * 2; txt->qs_append(x); txt->qs_append(' '); @@ -460,15 +464,13 @@ int Gis_line_string::length(double *len) const if (n_points < 1 || no_data(data, SIZEOF_STORED_DOUBLE * 2 * n_points)) return 1; - float8get(prev_x, data); - float8get(prev_y, data + SIZEOF_STORED_DOUBLE); + get_point(&prev_x, &prev_y, data); data+= SIZEOF_STORED_DOUBLE*2; while (--n_points) { double x, y; - float8get(x, data); - float8get(y, data + SIZEOF_STORED_DOUBLE); + get_point(&x, &y, data); data+= SIZEOF_STORED_DOUBLE * 2; *len+= sqrt(pow(prev_x-x,2)+pow(prev_y-y,2)); prev_x= x; @@ -497,13 +499,11 @@ int Gis_line_string::is_closed(int *closed) const return 1; /* Get first point */ - float8get(x1, data); - float8get(y1, data + SIZEOF_STORED_DOUBLE); + get_point(&x1, &y1, data); /* get last point */ data+= SIZEOF_STORED_DOUBLE*2 + (n_points-2)*POINT_DATA_SIZE; - float8get(x2, data); - float8get(y2, data + SIZEOF_STORED_DOUBLE); + get_point(&x2, &y2, data); *closed= (x1==x2) && (y1==y2); return 0; @@ -681,15 +681,13 @@ int Gis_polygon::area(double *ar, const char **end_of_data) const n_points= uint4korr(data); if (no_data(data, (SIZEOF_STORED_DOUBLE*2) * n_points)) return 1; - float8get(prev_x, data+4); - float8get(prev_y, data+(4+SIZEOF_STORED_DOUBLE)); + get_point(&prev_x, &prev_y, data+4); data+= (4+SIZEOF_STORED_DOUBLE*2); while (--n_points) // One point is already read { double x, y; - float8get(x, data); - float8get(y, data + SIZEOF_STORED_DOUBLE); + get_point(&x, &y, data); data+= (SIZEOF_STORED_DOUBLE*2); /* QQ: Is the following prev_x+x right ? */ lr_area+= (prev_x + x)* (prev_y - y); @@ -779,7 +777,8 @@ int Gis_polygon::interior_ring_n(uint32 num, String *result) const int Gis_polygon::centroid_xy(double *x, double *y) const { uint32 n_linear_rings; - double res_area, res_cx, res_cy; + double res_area; + double res_cx, res_cy; const char *data= m_data; bool first_loop= 1; LINT_INIT(res_area); @@ -805,15 +804,13 @@ int Gis_polygon::centroid_xy(double *x, double *y) const data+= 4; if (no_data(data, (SIZEOF_STORED_DOUBLE*2) * n_points)) return 1; - float8get(prev_x, data); - float8get(prev_y, data+SIZEOF_STORED_DOUBLE); + get_point(&prev_x, &prev_y, data); data+= (SIZEOF_STORED_DOUBLE*2); while (--n_points) // One point is already read { double x, y; - float8get(x, data); - float8get(y, data + SIZEOF_STORED_DOUBLE); + get_point(&x, &y, data); data+= (SIZEOF_STORED_DOUBLE*2); /* QQ: Is the following prev_x+x right ? */ cur_area+= (prev_x + x) * (prev_y - y); From 384456fc10c124d767e2d94bba4f59d8afc9ee4f Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 May 2005 20:38:48 +0200 Subject: [PATCH 13/19] BUG#9626 valgrind warnings - after review fixes mysql-test/r/ndb_basic.result: Test using table with long name mysql-test/t/ndb_basic.test: Test using table with long name ndb/include/transporter/TransporterDefinitions.hpp: Define constant for max section size ndb/src/ndbapi/NdbDictionaryImpl.cpp: Add check for not sending too long table name to ndb kernel --- mysql-test/r/ndb_basic.result | 6 ++++++ mysql-test/t/ndb_basic.test | 9 +++++++++ ndb/include/transporter/TransporterDefinitions.hpp | 3 ++- ndb/src/ndbapi/NdbDictionaryImpl.cpp | 13 +++++++++---- 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/ndb_basic.result b/mysql-test/r/ndb_basic.result index 6383a636cad..a374f845933 100644 --- a/mysql-test/r/ndb_basic.result +++ b/mysql-test/r/ndb_basic.result @@ -667,3 +667,9 @@ counter datavalue 57 newval 58 newval drop table t1; +create table atablewithareallylongandirritatingname (a int); +insert into atablewithareallylongandirritatingname values (2); +select * from atablewithareallylongandirritatingname; +a +2 +drop table atablewithareallylongandirritatingname; diff --git a/mysql-test/t/ndb_basic.test b/mysql-test/t/ndb_basic.test index 051a95ca42a..c0d5b14c2ea 100644 --- a/mysql-test/t/ndb_basic.test +++ b/mysql-test/t/ndb_basic.test @@ -605,3 +605,12 @@ insert into t1 (datavalue) select datavalue from t1 where counter < 100; select * from t1 order by counter; drop table t1; + + +# +# Test long table name +# +create table atablewithareallylongandirritatingname (a int); +insert into atablewithareallylongandirritatingname values (2); +select * from atablewithareallylongandirritatingname; +drop table atablewithareallylongandirritatingname; diff --git a/ndb/include/transporter/TransporterDefinitions.hpp b/ndb/include/transporter/TransporterDefinitions.hpp index 18d1ec76a3c..43af6749a85 100644 --- a/ndb/include/transporter/TransporterDefinitions.hpp +++ b/ndb/include/transporter/TransporterDefinitions.hpp @@ -45,8 +45,9 @@ enum SendStatus { * Protocol6 Header + * (optional signal id) + (optional checksum) + (signal data) */ +const Uint32 MAX_SECTION_SIZE= 4096; //const Uint32 MAX_MESSAGE_SIZE = (12+4+4+(4*25)); -const Uint32 MAX_MESSAGE_SIZE = (12+4+4+(4*25)+(3*4)+4*4096); +const Uint32 MAX_MESSAGE_SIZE = (12+4+4+(4*25)+(3*4)+4*MAX_SECTION_SIZE); /** * TransporterConfiguration diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/ndb/src/ndbapi/NdbDictionaryImpl.cpp index a4e96440cd1..fe2df815f1f 100644 --- a/ndb/src/ndbapi/NdbDictionaryImpl.cpp +++ b/ndb/src/ndbapi/NdbDictionaryImpl.cpp @@ -1088,6 +1088,7 @@ NdbDictInterface::getTable(int tableId, bool fullyQualifiedNames) Send GET_TABINFOREQ signal with the table name in the first long section part */ + NdbTableImpl * NdbDictInterface::getTable(const char * name, bool fullyQualifiedNames) { @@ -1095,12 +1096,16 @@ NdbDictInterface::getTable(const char * name, bool fullyQualifiedNames) GetTabInfoReq* const req = CAST_PTR(GetTabInfoReq, tSignal.getDataPtrSend()); const Uint32 str_len= strlen(name) + 1; // NULL terminated + const Uint32 str_len_words= (str_len + 3) / 4; // Size in words - /* Note! It might be a good idea to check that the length of - table name does not exceed the max size of a long signal */ + if (str_len > MAX_SECTION_SIZE) + { + m_error.code= 4307; + return 0; + } m_namebuf.clear(); - m_namebuf.grow(str_len+(4-str_len%4)); // Round up to word size + m_namebuf.grow(str_len_words*4); // Word size aligned number of bytes m_namebuf.append(name, str_len); req->senderRef= m_reference; @@ -1114,7 +1119,7 @@ NdbDictInterface::getTable(const char * name, bool fullyQualifiedNames) LinearSectionPtr ptr[1]; ptr[0].p= (Uint32*)m_namebuf.get_data(); - ptr[0].sz= (str_len + 3)/ 4; // Size in words + ptr[0].sz= str_len_words; return getTable(&tSignal, ptr, 1, fullyQualifiedNames); } From 0100b28de82094e9d2b452c6ede7c1451e3caffe Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 May 2005 20:54:37 +0200 Subject: [PATCH 14/19] after merge --- mysql-test/r/select.result | 126 +++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 8debcb2646a..8932d2c78ae 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -2355,6 +2355,74 @@ 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 BLOB, INDEX (a(20)) ); +CREATE TABLE t2 ( a BLOB, INDEX (a(20)) ); +INSERT INTO t1 VALUES ('one'),('two'),('three'),('four'),('five'); +INSERT INTO t2 VALUES ('one'),('two'),('three'),('four'),('five'); +EXPLAIN SELECT * FROM t1 LEFT JOIN t2 USE INDEX (a) ON t1.a=t2.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 +1 SIMPLE t2 ref a a 23 test.t1.a 2 +EXPLAIN SELECT * FROM t1 LEFT JOIN t2 FORCE INDEX (a) ON t1.a=t2.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 +1 SIMPLE t2 ref a a 23 test.t1.a 2 +DROP TABLE t1, t2; +CREATE TABLE t1 ( city char(30) ); +INSERT INTO t1 VALUES ('London'); +INSERT INTO t1 VALUES ('Paris'); +SELECT * FROM t1 WHERE city='London'; +city +London +SELECT * FROM t1 WHERE city='london'; +city +London +EXPLAIN SELECT * FROM t1 WHERE city='London' AND city='london'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where +SELECT * FROM t1 WHERE city='London' AND city='london'; +city +London +EXPLAIN SELECT * FROM t1 WHERE city LIKE '%london%' AND city='London'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where +SELECT * FROM t1 WHERE city LIKE '%london%' AND city='London'; +city +London +DROP TABLE t1; +create table t1 (a int(11) unsigned, b int(11) unsigned); +insert into t1 values (1,0), (1,1), (1,2); +select a-b from t1 order by 1; +a-b +0 +1 +18446744073709551615 +select a-b , (a-b < 0) from t1 order by 1; +a-b (a-b < 0) +0 0 +1 0 +18446744073709551615 0 +select a-b as d, (a-b >= 0), b from t1 group by b having d >= 0; +d (a-b >= 0) b +1 1 0 +0 1 1 +18446744073709551615 1 2 +select cast((a - b) as unsigned) from t1 order by 1; +cast((a - b) as unsigned) +0 +1 +18446744073709551615 +drop table t1; +create table t1 (a int(11)); +select all all * from t1; +a +select distinct distinct * from t1; +a +select all distinct * from t1; +ERROR HY000: Incorrect usage of ALL and DISTINCT +select distinct all * from t1; +ERROR HY000: Incorrect usage of ALL and DISTINCT +drop table t1; CREATE TABLE t1 ( K2C4 varchar(4) character set latin1 collate latin1_bin NOT NULL default '', K4N4 varchar(4) character set latin1 collate latin1_bin NOT NULL default '0000', @@ -2486,6 +2554,64 @@ ERROR HY000: Incorrect usage of ALL and DISTINCT select distinct all * from t1; ERROR HY000: Incorrect usage of ALL and DISTINCT drop table t1; +CREATE TABLE t1 ( a BLOB, INDEX (a(20)) ); +CREATE TABLE t2 ( a BLOB, INDEX (a(20)) ); +INSERT INTO t1 VALUES ('one'),('two'),('three'),('four'),('five'); +INSERT INTO t2 VALUES ('one'),('two'),('three'),('four'),('five'); +EXPLAIN SELECT * FROM t1 LEFT JOIN t2 USE INDEX (a) ON t1.a=t2.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 +1 SIMPLE t2 ref a a 23 test.t1.a 2 +EXPLAIN SELECT * FROM t1 LEFT JOIN t2 FORCE INDEX (a) ON t1.a=t2.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 +1 SIMPLE t2 ref a a 23 test.t1.a 2 +DROP TABLE t1, t2; +CREATE TABLE t1 ( city char(30) ); +INSERT INTO t1 VALUES ('London'); +INSERT INTO t1 VALUES ('Paris'); +SELECT * FROM t1 WHERE city='London'; +city +London +SELECT * FROM t1 WHERE city='london'; +city +London +EXPLAIN SELECT * FROM t1 WHERE city='London' AND city='london'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where +SELECT * FROM t1 WHERE city='London' AND city='london'; +city +London +EXPLAIN SELECT * FROM t1 WHERE city LIKE '%london%' AND city='London'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where +SELECT * FROM t1 WHERE city LIKE '%london%' AND city='London'; +city +London +DROP TABLE t1; +create table t1 (a int(11) unsigned, b int(11) unsigned); +insert into t1 values (1,0), (1,1), (1,2); +select a-b from t1 order by 1; +a-b +0 +1 +18446744073709551615 +select a-b , (a-b < 0) from t1 order by 1; +a-b (a-b < 0) +0 0 +1 0 +18446744073709551615 0 +select a-b as d, (a-b >= 0), b from t1 group by b having d >= 0; +d (a-b >= 0) b +1 1 0 +0 1 1 +18446744073709551615 1 2 +select cast((a - b) as unsigned) from t1 order by 1; +cast((a - b) as unsigned) +0 +1 +18446744073709551615 +drop table t1; create table t1 (a int(11)); select all all * from t1; a From 4482604ec687e8ec46fdaf90c63e141e7ef2d502 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 20 May 2005 01:04:08 +0500 Subject: [PATCH 15/19] hf's fix for bug #9060 (FORMAT returns incorrect result) we need proper rounding there mysql-test/r/func_math.result: test result fixed mysql-test/t/func_math.test: test case added sql/item_func.cc: my_double_round implementation added sql/item_strfunc.cc: my_double_round used sql/mysql_priv.h: my_double_round interface --- mysql-test/r/func_math.result | 3 +++ mysql-test/t/func_math.test | 5 +++++ sql/item_func.cc | 22 ++++++++++++++-------- sql/item_strfunc.cc | 1 + sql/mysql_priv.h | 1 + 5 files changed, 24 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/func_math.result b/mysql-test/r/func_math.result index 005f41f7063..0798a034c3e 100644 --- a/mysql-test/r/func_math.result +++ b/mysql-test/r/func_math.result @@ -120,6 +120,9 @@ ASIN(0.8+0.2) SELECT ASIN(1.2-0.2); ASIN(1.2-0.2) 1.5707963267949 +select format(4.55, 1), format(4.551, 1); +format(4.55, 1) format(4.551, 1) +4.6 4.6 explain extended select degrees(pi()),radians(360); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used diff --git a/mysql-test/t/func_math.test b/mysql-test/t/func_math.test index 33b672e42b5..0eac72782a8 100644 --- a/mysql-test/t/func_math.test +++ b/mysql-test/t/func_math.test @@ -54,6 +54,11 @@ SELECT ASIN(1.2-0.2); #select floor(log(8)/log(2)); #select floor(log(16)/log(2)); +# +# Bug #9060 (format returns incorrect result) +# +select format(4.55, 1), format(4.551, 1); + explain extended select degrees(pi()),radians(360); # diff --git a/sql/item_func.cc b/sql/item_func.cc index 89f9111101a..db2aa735b0e 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1880,22 +1880,16 @@ void Item_func_round::fix_length_and_dec() } } -double Item_func_round::real_op() +double my_double_round(double value, int dec, bool truncate) { - double value= args[0]->val_real(); - int dec=(int) args[1]->val_int(); - if (dec > 0) - decimals= dec; // to get correct output - uint abs_dec=abs(dec); double tmp; + uint abs_dec= abs(dec); /* tmp2 is here to avoid return the value with 80 bit precision This will fix that the test round(0.1,1) = round(0.1,1) is true */ volatile double tmp2; - if ((null_value=args[0]->null_value || args[1]->null_value)) - return 0.0; tmp=(abs_dec < array_elements(log_10) ? log_10[abs_dec] : pow(10.0,(double) abs_dec)); @@ -1912,6 +1906,18 @@ double Item_func_round::real_op() } +double Item_func_round::real_op() +{ + double value= args[0]->val_real(); + int dec= (int) args[1]->val_int(); + + if (!(null_value= args[0]->null_value || args[1]->null_value)) + return my_double_round(value, dec, truncate); + + return 0.0; +} + + longlong Item_func_round::int_op() { longlong value= args[0]->val_int(); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 52449f6d91c..857140dba8f 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1673,6 +1673,7 @@ String *Item_func_format::val_str(String *str) int diff; if ((null_value=args[0]->null_value)) return 0; /* purecov: inspected */ + nr= my_double_round(nr, decimals, FALSE); dec= decimals ? decimals+1 : 0; /* Here default_charset() is right as this is not an automatic conversion */ str->set(nr,decimals, default_charset()); diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index d46ee655165..645e835d9ca 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1251,6 +1251,7 @@ ha_rows filesort(THD *thd, TABLE *form,struct st_sort_field *sortorder, ha_rows max_rows, ha_rows *examined_rows); void filesort_free_buffers(TABLE *table); void change_double_for_sort(double nr,byte *to); +double my_double_round(double value, int dec, bool truncate); int get_quick_record(SQL_SELECT *select); int calc_weekday(long daynr,bool sunday_first_day_of_week); uint calc_week(TIME *l_time, uint week_behaviour, uint *year); From 4679c7a8fe36819df60ecf769351e10efa911548 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 20 May 2005 01:44:05 +0500 Subject: [PATCH 16/19] WL#2286 - Compile MySQL w/YASSL support compilation fixes extra/yassl/src/cert_wrapper.cpp: yaSSL compilation fix on nocona extra/yassl/taocrypt/include/error.hpp: yaSSL compilation fix extra/yassl/taocrypt/include/misc.hpp: yaSSL compilation fix on many platforms tools/Makefile.am: mysqltestmanager with yaSSL enabled compilation fix on FreeBSD 5.3 --- extra/yassl/src/cert_wrapper.cpp | 4 ++-- extra/yassl/taocrypt/include/error.hpp | 2 +- extra/yassl/taocrypt/include/misc.hpp | 2 +- tools/Makefile.am | 5 +++-- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/extra/yassl/src/cert_wrapper.cpp b/extra/yassl/src/cert_wrapper.cpp index ab3cb471990..98861d01287 100644 --- a/extra/yassl/src/cert_wrapper.cpp +++ b/extra/yassl/src/cert_wrapper.cpp @@ -273,8 +273,8 @@ int CertManager::SetPrivateKey(const x509& key) privateKey_.assign(key.get_buffer(), key.get_length()); // set key type - if (x509* cert = list_.front()) { - TaoCrypt::Source source(cert->get_buffer(), cert->get_length()); + if (x509* cert509 = list_.front()) { + TaoCrypt::Source source(cert509->get_buffer(), cert509->get_length()); TaoCrypt::CertDecoder cert(source, false); cert.DecodeToKey(); if (int err = cert.GetError().What()) diff --git a/extra/yassl/taocrypt/include/error.hpp b/extra/yassl/taocrypt/include/error.hpp index cb7f82731c7..6170d0349b5 100644 --- a/extra/yassl/taocrypt/include/error.hpp +++ b/extra/yassl/taocrypt/include/error.hpp @@ -65,7 +65,7 @@ UNKOWN_HASH_E = 1034, // "unknown hash OID" DSA_SZ_E = 1035, // "bad DSA r or s size" BEFORE_DATE_E = 1036, // "before date in the future" AFTER_DATE_E = 1037, // "after date in the past" -SIG_CONFIRM_E = 1038, // "bad signature confirmation" +SIG_CONFIRM_E = 1038 // "bad signature confirmation" }; diff --git a/extra/yassl/taocrypt/include/misc.hpp b/extra/yassl/taocrypt/include/misc.hpp index 01a3e8ee731..b9cc9a6fe71 100644 --- a/extra/yassl/taocrypt/include/misc.hpp +++ b/extra/yassl/taocrypt/include/misc.hpp @@ -97,7 +97,7 @@ typedef unsigned int word32; typedef word32 word; typedef word64 dword; #else - typedef word8 hword; + typedef byte hword; typedef word16 word; typedef word32 dword; #endif diff --git a/tools/Makefile.am b/tools/Makefile.am index 3b84aafeaa9..036f0b8a76e 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -17,8 +17,9 @@ INCLUDES=-I$(top_srcdir)/include $(openssl_includes) \ -I$(top_builddir)/include -LDADD= @CLIENT_EXTRA_LDFLAGS@ @openssl_libs@ \ - $(top_builddir)/libmysql_r/libmysqlclient_r.la @ZLIB_LIBS@ +LDADD= @CLIENT_EXTRA_LDFLAGS@ \ + $(top_builddir)/libmysql_r/libmysqlclient_r.la \ + @openssl_libs@ @ZLIB_LIBS@ bin_PROGRAMS= mysqltestmanager mysqltestmanager_SOURCES= mysqlmanager.c mysqltestmanager_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) From fb00361bae9eb780a0724966121d93d0ed2f9ab9 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 May 2005 14:43:10 -0700 Subject: [PATCH 17/19] Fix change to allow FIFO as log. (Bug #8271) mysys/mf_iocache.c: Reset seek_not_done after doing a seek. --- mysys/mf_iocache.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c index 32800c832b3..a55a2d81c2c 100644 --- a/mysys/mf_iocache.c +++ b/mysys/mf_iocache.c @@ -184,8 +184,10 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize, { /* Assume file isn't growing */ if (!(cache_myflags & MY_DONT_CHECK_FILESIZE)) { - /* Calculate end of file to not allocate to big buffers */ + /* Calculate end of file to avoid allocating oversized buffers */ end_of_file=my_seek(file,0L,MY_SEEK_END,MYF(0)); + /* Need to reset seek_not_done now that we just did a seek. */ + info->seek_not_done= end_of_file == seek_offset ? 0 : 1; if (end_of_file < seek_offset) end_of_file=seek_offset; /* Trim cache size if the file is very small */ From bdf5dbcd9a73afbfdfd51a107470ebf65bbd1d2a Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 May 2005 23:52:17 +0200 Subject: [PATCH 18/19] Cset exclude: matt@mysql.com|ChangeSet|20050519052223|06259 Cset exclude: msvensson@neptunus.(none)|ChangeSet|20050425090838|60886 configure.in: Exclude sql/opt_range.cc: Exclude --- configure.in | 2 +- sql/opt_range.cc | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/configure.in b/configure.in index 332b851402d..bc00a15fed1 100644 --- a/configure.in +++ b/configure.in @@ -6,7 +6,7 @@ AC_PREREQ(2.50)dnl Minimum Autoconf version required. AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # Don't forget to also update the NDB lines below. -AM_INIT_AUTOMAKE(mysql, 5.0.7-beta) +AM_INIT_AUTOMAKE(mysql, 5.0.6-beta) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 diff --git a/sql/opt_range.cc b/sql/opt_range.cc index a0b7c1a52d7..b81a083d9b3 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -713,8 +713,7 @@ SQL_SELECT::~SQL_SELECT() QUICK_SELECT_I::QUICK_SELECT_I() :max_used_key_length(0), - used_key_parts(0), - records(0) + used_key_parts(0) {} QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(THD *thd, TABLE *table, uint key_nr, From f0c4cc2683ab75a8b5d44c9b481624e8b7428f58 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 20 May 2005 00:04:43 +0200 Subject: [PATCH 19/19] Change to 5.0.7(again) configure.in: Bump version number --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index bc00a15fed1..332b851402d 100644 --- a/configure.in +++ b/configure.in @@ -6,7 +6,7 @@ AC_PREREQ(2.50)dnl Minimum Autoconf version required. AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # Don't forget to also update the NDB lines below. -AM_INIT_AUTOMAKE(mysql, 5.0.6-beta) +AM_INIT_AUTOMAKE(mysql, 5.0.7-beta) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10