From adb6c4debb8fb76c869dcae5c71529e3aea153ad Mon Sep 17 00:00:00 2001 From: "mskold@mysql.com" <> Date: Thu, 9 Mar 2006 17:42:35 +0100 Subject: [PATCH 01/11] bug#18040 - ndb online index build --- sql/ha_ndbcluster.cc | 8 +++----- storage/ndb/src/kernel/blocks/suma/Suma.cpp | 13 +++++++++++-- storage/ndb/src/kernel/blocks/suma/Suma.hpp | 4 +++- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 0cb83a5484c..fefd9bad117 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -1319,13 +1319,11 @@ int ha_ndbcluster::drop_indexes(Ndb *ndb, TABLE *tab) int error= 0; const char *index_name; KEY* key_info= tab->key_info; - const char **key_name= tab->s->keynames.type_names; NDBDICT *dict= ndb->getDictionary(); DBUG_ENTER("ha_ndbcluster::drop_indexes"); - for (i= 0; i < tab->s->keys; i++, key_info++, key_name++) + for (i= 0; i < tab->s->keys; i++, key_info++) { - index_name= *key_name; NDB_INDEX_TYPE idx_type= get_index_type_from_table(i); m_index[i].type= idx_type; if (m_index[i].status == TO_BE_DROPPED) @@ -1346,8 +1344,8 @@ int ha_ndbcluster::drop_indexes(Ndb *ndb, TABLE *tab) m_index[i].index= NULL; if (!error && unique_index) { - index_name= index->getName(); - DBUG_PRINT("info", ("Dropping index %u: %s", i, index_name)); + index_name= unique_index->getName(); + DBUG_PRINT("info", ("Dropping unique index %u: %s", i, index_name)); // Drop unique index from ndb error= drop_ndb_index(index_name); } diff --git a/storage/ndb/src/kernel/blocks/suma/Suma.cpp b/storage/ndb/src/kernel/blocks/suma/Suma.cpp index c91f16cdb57..f68d36c6c0e 100644 --- a/storage/ndb/src/kernel/blocks/suma/Suma.cpp +++ b/storage/ndb/src/kernel/blocks/suma/Suma.cpp @@ -1092,6 +1092,7 @@ Suma::execSUB_CREATE_REQ(Signal* signal) subPtr.p->m_table_ptrI = RNIL; subPtr.p->m_state = Subscription::DEFINED; subPtr.p->n_subscribers = 0; + subPtr.p->m_current_sync_ptrI = RNIL; fprintf(stderr, "table %d options %x\n", subPtr.p->m_tableId, subPtr.p->m_options); DBUG_PRINT("info",("Added: key.m_subscriptionId: %u, key.m_subscriptionKey: %u", @@ -1163,13 +1164,15 @@ Suma::execSUB_SYNC_REQ(Signal* signal) DBUG_PRINT("info",("c_syncPool size: %d free: %d", c_syncPool.getSize(), c_syncPool.getNoOfFree())); - new (syncPtr.p) Ptr; + syncPtr.p->m_senderRef = req->senderRef; syncPtr.p->m_senderData = req->senderData; syncPtr.p->m_subscriptionPtrI = subPtr.i; syncPtr.p->ptrI = syncPtr.i; syncPtr.p->m_error = 0; + subPtr.p->m_current_sync_ptrI = syncPtr.i; + { jam(); syncPtr.p->m_tableList.append(&subPtr.p->m_tableId, 1); @@ -2059,7 +2062,7 @@ Suma::execSUB_SYNC_CONTINUE_CONF(Signal* signal){ ndbrequire(c_subscriptions.find(subPtr, key)); ScanFragNextReq * req = (ScanFragNextReq *)signal->getDataPtrSend(); - req->senderData = subPtr.i; + req->senderData = subPtr.p->m_current_sync_ptrI; req->closeFlag = 0; req->transId1 = 0; req->transId2 = (SUMA << 20) + (getOwnNodeId() << 8); @@ -2098,6 +2101,12 @@ Suma::SyncRecord::completeScan(Signal* signal, int error) #endif release(); + + Ptr subPtr; + suma.c_subscriptions.getPtr(subPtr, m_subscriptionPtrI); + ndbrequire(subPtr.p->m_current_sync_ptrI == ptrI); + subPtr.p->m_current_sync_ptrI = RNIL; + suma.c_syncPool.release(ptrI); DBUG_PRINT("info",("c_syncPool size: %d free: %d", suma.c_syncPool.getSize(), diff --git a/storage/ndb/src/kernel/blocks/suma/Suma.hpp b/storage/ndb/src/kernel/blocks/suma/Suma.hpp index 9a54f056168..51f5fa4a8c8 100644 --- a/storage/ndb/src/kernel/blocks/suma/Suma.hpp +++ b/storage/ndb/src/kernel/blocks/suma/Suma.hpp @@ -189,6 +189,7 @@ public: */ Uint32 m_tableId; Uint32 m_table_ptrI; + Uint32 m_current_sync_ptrI; }; typedef Ptr SubscriptionPtr; @@ -239,7 +240,8 @@ public: suma.progError(line, cause, extra); } - union { Uint32 nextPool; Uint32 nextList; Uint32 prevList; Uint32 ptrI; }; + Uint32 prevList; Uint32 ptrI; + union { Uint32 nextPool; Uint32 nextList; }; }; friend struct SyncRecord; From 5ebe4f37c45dbbfc7a8ab605dc16a80ccb4c2926 Mon Sep 17 00:00:00 2001 From: "mskold@mysql.com" <> Date: Thu, 9 Mar 2006 17:44:37 +0100 Subject: [PATCH 02/11] Changed error code mapping for unique constraint violation --- storage/ndb/src/ndbapi/ndberror.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/ndb/src/ndbapi/ndberror.c b/storage/ndb/src/ndbapi/ndberror.c index bb4616a9ee2..08f2ff8ba3d 100644 --- a/storage/ndb/src/ndbapi/ndberror.c +++ b/storage/ndb/src/ndbapi/ndberror.c @@ -112,7 +112,7 @@ ErrorBundle ErrorCodes[] = { { 630, HA_ERR_FOUND_DUPP_KEY, CV, "Tuple already existed when attempting to insert" }, { 839, DMEC, CV, "Illegal null attribute" }, { 840, DMEC, CV, "Trying to set a NOT NULL attribute to NULL" }, - { 893, HA_ERR_FOUND_DUPP_KEY, CV, "Constraint violation e.g. duplicate value in unique index" }, + { 893, HA_ERR_FOUND_DUPP_UNIQUE, CV, "Constraint violation e.g. duplicate value in unique index" }, /** * Node recovery errors @@ -577,7 +577,7 @@ ErrorBundle ErrorCodes[] = { { 4248, DMEC, AE, "Trigger/index name invalid" }, { 4249, DMEC, AE, "Invalid table" }, { 4250, DMEC, AE, "Invalid index type or index logging option" }, - { 4251, DMEC, AE, "Cannot create unique index, duplicate keys found" }, + { 4251, HA_ERR_FOUND_DUPP_UNIQUE, AE, "Cannot create unique index, duplicate keys found" }, { 4252, DMEC, AE, "Failed to allocate space for index" }, { 4253, DMEC, AE, "Failed to create index table" }, { 4254, DMEC, AE, "Table not an index table" }, From eed9568833f913f84eee949399c977dc03f5fd0c Mon Sep 17 00:00:00 2001 From: "mikael@zim.(none)" <> Date: Thu, 9 Mar 2006 10:19:25 -0800 Subject: [PATCH 03/11] BUG#17947: Crash when REBUILD PARTITION syntax error --- mysql-test/r/partition.result | 6 ++++++ mysql-test/t/partition.test | 12 ++++++++++++ sql/sql_yacc.yy | 2 +- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result index 59e29046d90..80942c861fe 100644 --- a/mysql-test/r/partition.result +++ b/mysql-test/r/partition.result @@ -422,4 +422,10 @@ partition_name partition_description table_rows x123 11,12 1 x234 NULL,1 1 drop table t1; +create table t1 (a int) +partition by list (a) +(partition p0 values in (1)); +alter table t1 rebuild partition; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1 +drop table t1; End of 5.1 tests diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test index f22edb54756..8fc46490856 100644 --- a/mysql-test/t/partition.test +++ b/mysql-test/t/partition.test @@ -540,4 +540,16 @@ select partition_name, partition_description, table_rows from information_schema.partitions where table_schema ='test'; drop table t1; +# +# BUG 17947 Crash with REBUILD PARTITION +# +create table t1 (a int) +partition by list (a) +(partition p0 values in (1)); + +--error 1064 +alter table t1 rebuild partition; + +drop table t1; + --echo End of 5.1 tests diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index a64886d503d..17cb218e2be 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -5024,7 +5024,7 @@ alter_commands: ; all_or_alt_part_name_list: - | ALL + ALL { Lex->alter_info.flags|= ALTER_ALL_PARTITION; } From 7d4ed3028a14afa40ce161d804307520ac7b61c1 Mon Sep 17 00:00:00 2001 From: "mskold@mysql.com" <> Date: Thu, 9 Mar 2006 20:08:30 +0100 Subject: [PATCH 04/11] Added more tests for bug#18040: Create unique index cause error 4243 --- mysql-test/r/ndb_index_unique.result | 24 ++++++++++++++---------- mysql-test/t/ndb_index_unique.test | 26 ++++++++++++++++---------- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/mysql-test/r/ndb_index_unique.result b/mysql-test/r/ndb_index_unique.result index 1085d15ec30..2e0a143d351 100644 --- a/mysql-test/r/ndb_index_unique.result +++ b/mysql-test/r/ndb_index_unique.result @@ -1,9 +1,9 @@ drop table if exists t1, t2, t3, t4, t5, t6, t7, t8; CREATE TABLE t1 ( -a int unsigned NOT NULL PRIMARY KEY, -b int unsigned not null, -c int unsigned, -UNIQUE(b) +a int NOT NULL PRIMARY KEY, +b int not null, +c int, +UNIQUE ib(b) ) engine=ndbcluster; insert t1 values(1, 2, 3), (2, 3, 5), (3, 4, 6), (4, 5, 8), (5,6, 2), (6,7, 2); select * from t1 order by b; @@ -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: Duplicate entry '8' for key 'PRIMARY' +ERROR 23000: Can't write, because of unique constraint, to table 't1' select * from t1 order by a; a b c 1 2 3 @@ -43,6 +43,10 @@ a b c 6 7 2 7 8 3 8 2 3 +alter table t1 drop index ib; +insert into t1 values(1, 2, 3); +create unique index ib on t1(b); +ERROR 23000: Can't write, because of unique constraint, to table 't1' drop table t1; CREATE TABLE t1 ( a int unsigned NOT NULL PRIMARY KEY, @@ -89,7 +93,7 @@ a b c 1 1 1 4 4 NULL insert into t1 values(5,1,1); -ERROR 23000: Duplicate entry '5' for key 'PRIMARY' +ERROR 23000: Can't write, because of unique constraint, to table 't1' drop table t1; CREATE TABLE t2 ( a int unsigned NOT NULL PRIMARY KEY, @@ -112,7 +116,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: Duplicate entry '8' for key 'PRIMARY' +ERROR 23000: Can't write, because of unique constraint, to table 't2' select * from t2 order by a; a b c 1 2 3 @@ -177,7 +181,7 @@ pk a 3 NULL 4 4 insert into t1 values (5,0); -ERROR 23000: Duplicate entry '5' for key 'PRIMARY' +ERROR 23000: Can't write, because of unique constraint, to table 't1' select * from t1 order by pk; pk a -1 NULL @@ -210,7 +214,7 @@ pk a b c 0 NULL 18 NULL 1 3 19 abc insert into t2 values(2,3,19,'abc'); -ERROR 23000: Duplicate entry '2' for key 'PRIMARY' +ERROR 23000: Can't write, because of unique constraint, to table 't2' select * from t2 order by pk; pk a b c -1 1 17 NULL @@ -630,7 +634,7 @@ create table t1 (a int primary key, b varchar(1000) not null, unique key (b)) engine=ndb charset=utf8; insert into t1 values (1, repeat(_utf8 0xe288ab6474, 200)); insert into t1 values (2, repeat(_utf8 0xe288ab6474, 200)); -ERROR 23000: Duplicate entry '2' for key 'PRIMARY' +ERROR 23000: Can't write, because of unique constraint, to table 't1' select a, sha1(b) from t1; a sha1(b) 1 08f5d02c8b8bc244f275bdfc22c42c5cab0d9d7d diff --git a/mysql-test/t/ndb_index_unique.test b/mysql-test/t/ndb_index_unique.test index 8561b3794c4..5caa702bae6 100644 --- a/mysql-test/t/ndb_index_unique.test +++ b/mysql-test/t/ndb_index_unique.test @@ -10,10 +10,10 @@ drop table if exists t1, t2, t3, t4, t5, t6, t7, t8; # CREATE TABLE t1 ( - a int unsigned NOT NULL PRIMARY KEY, - b int unsigned not null, - c int unsigned, - UNIQUE(b) + a int NOT NULL PRIMARY KEY, + b int not null, + c int, + UNIQUE ib(b) ) engine=ndbcluster; insert t1 values(1, 2, 3), (2, 3, 5), (3, 4, 6), (4, 5, 8), (5,6, 2), (6,7, 2); @@ -22,13 +22,19 @@ 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 1062 +-- error 1169 insert into t1 values(8, 2, 3); select * from t1 order by a; delete from t1 where a = 1; insert into t1 values(8, 2, 3); select * from t1 order by a; +alter table t1 drop index ib; +sleep 10; +insert into t1 values(1, 2, 3); +--error 1169 +create unique index ib on t1(b); + drop table t1; # @@ -53,7 +59,7 @@ 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 +-- error 1169 insert into t1 values(5,1,1); drop table t1; @@ -76,7 +82,7 @@ select * from t2 where c = 6; insert into t2 values(7,8,3); select * from t2 where b = 4 order by a; --- error 1062 +-- error 1169 insert into t2 values(8, 2, 3); select * from t2 order by a; delete from t2 where a = 1; @@ -127,7 +133,7 @@ insert into t1 values (-1,NULL), (0,0), (1,NULL),(2,2),(3,NULL),(4,4); select * from t1 order by pk; ---error 1062 +--error 1169 insert into t1 values (5,0); select * from t1 order by pk; delete from t1 where a = 0; @@ -146,7 +152,7 @@ insert into t2 values (-1,1,17,NULL),(0,NULL,18,NULL),(1,3,19,'abc'); select * from t2 order by pk; ---error 1062 +--error 1169 insert into t2 values(2,3,19,'abc'); select * from t2 order by pk; delete from t2 where c IS NOT NULL; @@ -315,7 +321,7 @@ create table t1 (a int primary key, b varchar(1000) not null, unique key (b)) engine=ndb charset=utf8; insert into t1 values (1, repeat(_utf8 0xe288ab6474, 200)); ---error 1062 +--error 1169 insert into t1 values (2, repeat(_utf8 0xe288ab6474, 200)); select a, sha1(b) from t1; From b14c7abac2f02947d0849f493a62a656c7cc37ad Mon Sep 17 00:00:00 2001 From: "tomas@poseidon.ndb.mysql.com" <> Date: Thu, 9 Mar 2006 20:47:19 +0100 Subject: [PATCH 05/11] ndb: store event operations per gci --- .../ndb/src/ndbapi/NdbEventOperationImpl.cpp | 77 ++++++++++-- .../ndb/src/ndbapi/NdbEventOperationImpl.hpp | 117 ++++++++++++++---- 2 files changed, 162 insertions(+), 32 deletions(-) diff --git a/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp b/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp index abb0d664e56..f3ed7b3a9f7 100644 --- a/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp +++ b/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp @@ -1117,7 +1117,7 @@ NdbEventBuffer::nextEvent() m_available_data.remove_first(); // add it to used list - m_used_data.append(data); + m_used_data.append_used_data(data); #ifdef VM_TRACE op->m_data_done_count++; @@ -1144,6 +1144,10 @@ NdbEventBuffer::nextEvent() (void)tBlob->atNextEvent(); tBlob = tBlob->theNext; } + EventBufData_list::Gci_ops *gci_ops = m_available_data.first_gci_ops(); + while (gci_ops && op->getGCI() > gci_ops->m_gci) + gci_ops = m_available_data.next_gci_ops(); + assert(gci_ops && (op->getGCI() == gci_ops->m_gci)); DBUG_RETURN_EVENT(op->m_facade); } // the next event belonged to an event op that is no @@ -1158,15 +1162,21 @@ NdbEventBuffer::nextEvent() #ifdef VM_TRACE m_latest_command= m_latest_command_save; #endif + + // free all "per gci unique" collected operations + EventBufData_list::Gci_ops *gci_ops = m_available_data.first_gci_ops(); + while (gci_ops) + gci_ops = m_available_data.next_gci_ops(); DBUG_RETURN_EVENT(0); } NdbEventOperationImpl* NdbEventBuffer::getGCIEventOperations(Uint32* iter, Uint32* event_types) { - if (*iter < m_available_data.m_gci_op_count) + EventBufData_list::Gci_ops *gci_ops = m_available_data.first_gci_ops(); + if (*iter < gci_ops->m_gci_op_count) { - EventBufData_list::Gci_op g = m_available_data.m_gci_op_list[(*iter)++]; + EventBufData_list::Gci_op g = gci_ops->m_gci_op_list[(*iter)++]; if (event_types != NULL) *event_types = g.event_types; return g.op; @@ -1318,7 +1328,7 @@ NdbEventBuffer::execSUB_GCP_COMPLETE_REP(const SubGcpCompleteRep * const rep) #ifdef VM_TRACE assert(bucket->m_data.m_count); #endif - m_complete_data.m_data.append(bucket->m_data); + m_complete_data.m_data.append_list(&bucket->m_data, gci); } reportStatus(); bzero(bucket, sizeof(Gci_container)); @@ -1389,7 +1399,7 @@ NdbEventBuffer::complete_outof_order_gcis() #ifdef VM_TRACE assert(bucket->m_data.m_count); #endif - m_complete_data.m_data.append(bucket->m_data); + m_complete_data.m_data.append_list(&bucket->m_data, start_gci); #ifdef VM_TRACE ndbout_c(" moved %lld rows -> %lld", bucket->m_data.m_count, m_complete_data.m_data.m_count); @@ -1599,7 +1609,7 @@ NdbEventBuffer::insertDataL(NdbEventOperationImpl *op, data->m_event_op = op; if (! is_blob_event || ! is_data_event) { - bucket->m_data.append(data); + bucket->m_data.append_data(data); } else { @@ -1615,7 +1625,7 @@ NdbEventBuffer::insertDataL(NdbEventOperationImpl *op, if (ret != 0) // main event was created { main_data->m_event_op = op->theMainOp; - bucket->m_data.append(main_data); + bucket->m_data.append_data(main_data); if (use_hash) { main_data->m_pkhash = main_hpos.pkhash; @@ -2097,7 +2107,7 @@ NdbEventBuffer::move_data() if (!m_complete_data.m_data.is_empty()) { // move this list to last in m_available_data - m_available_data.append(m_complete_data.m_data); + m_available_data.append_list(&m_complete_data.m_data, 0); bzero(&m_complete_data, sizeof(m_complete_data)); } @@ -2160,6 +2170,19 @@ NdbEventBuffer::free_list(EventBufData_list &list) list.m_count = list.m_sz = 0; } +void EventBufData_list::append_list(EventBufData_list *list, Uint64 gci) +{ + move_gci_ops(list, gci); + + if (m_tail) + m_tail->m_next= list->m_head; + else + m_head= list->m_head; + m_tail= list->m_tail; + m_count+= list->m_count; + m_sz+= list->m_sz; +} + void EventBufData_list::add_gci_op(Gci_op g) { @@ -2188,6 +2211,44 @@ EventBufData_list::add_gci_op(Gci_op g) } } +void +EventBufData_list::move_gci_ops(EventBufData_list *list, Uint64 gci) +{ + assert(!m_is_not_multi_list); + if (!list->m_is_not_multi_list) + { + assert(gci == 0); + if (m_gci_ops_list_tail) + m_gci_ops_list_tail->m_next = list->m_gci_ops_list; + else + { + m_gci_ops_list = list->m_gci_ops_list; + } + m_gci_ops_list_tail = list->m_gci_ops_list_tail; + goto end; + } + { + Gci_ops *new_gci_ops = new Gci_ops; + if (m_gci_ops_list_tail) + m_gci_ops_list_tail->m_next = new_gci_ops; + else + { + assert(m_gci_ops_list == 0); + m_gci_ops_list = new_gci_ops; + } + m_gci_ops_list_tail = new_gci_ops; + + new_gci_ops->m_gci_op_list = list->m_gci_op_list; + new_gci_ops->m_gci_op_count = list->m_gci_op_count; + new_gci_ops->m_gci = gci; + new_gci_ops->m_next = 0; + } +end: + list->m_gci_op_list = 0; + list->m_gci_ops_list_tail = 0; + list->m_gci_op_alloc = 0; +} + NdbEventOperation* NdbEventBuffer::createEventOperation(const char* eventName, NdbError &theError) diff --git a/storage/ndb/src/ndbapi/NdbEventOperationImpl.hpp b/storage/ndb/src/ndbapi/NdbEventOperationImpl.hpp index 3e7d313fe02..9ce85a61361 100644 --- a/storage/ndb/src/ndbapi/NdbEventOperationImpl.hpp +++ b/storage/ndb/src/ndbapi/NdbEventOperationImpl.hpp @@ -68,8 +68,12 @@ public: ~EventBufData_list(); void remove_first(); - void append(EventBufData *data); - void append(const EventBufData_list &list); + // append data and insert data into Gci_op list with add_gci_op + void append_data(EventBufData *data); + // append data and insert data but ignore Gci_op list + void append_used_data(EventBufData *data); + // append list to another, will call move_gci_ops + void append_list(EventBufData_list *list, Uint64 gci); int is_empty(); @@ -77,13 +81,60 @@ public: unsigned m_count; unsigned m_sz; - // distinct ops per gci (assume no hash needed) - struct Gci_op { NdbEventOperationImpl* op; Uint32 event_types; }; - Gci_op* m_gci_op_list; - Uint32 m_gci_op_count; - Uint32 m_gci_op_alloc; + /* + distinct ops per gci (assume no hash needed) + + list may be in 2 versions + + 1. single list with on gci only + - one linear array + Gci_op *m_gci_op_list; + Uint32 m_gci_op_count; + Uint32 m_gci_op_alloc != 0; + + 2. multi list with several gcis + - linked list of gci's + - one linear array per gci + Gci_ops *m_gci_ops_list; + Gci_ops *m_gci_ops_list_tail; + Uint32 m_is_not_multi_list == 0; + + */ + struct Gci_op // 1 + 2 + { + NdbEventOperationImpl* op; + Uint32 event_types; + }; + struct Gci_ops // 2 + { + Uint64 m_gci; + Gci_op *m_gci_op_list; + Gci_ops *m_next; + Uint32 m_gci_op_count; + }; + union + { + Gci_op *m_gci_op_list; // 1 + Gci_ops *m_gci_ops_list; // 2 + }; + union + { + Uint32 m_gci_op_count; // 1 + Gci_ops *m_gci_ops_list_tail;// 2 + }; + union + { + Uint32 m_gci_op_alloc; // 1 + Uint32 m_is_not_multi_list; // 2 + }; + Gci_ops *first_gci_ops(); + Gci_ops *next_gci_ops(); private: + // case 1 above; add Gci_op to single list void add_gci_op(Gci_op g); + // case 2 above; move single list or multi list from + // one list to another + void move_gci_ops(EventBufData_list *list, Uint64 gci); }; inline @@ -92,7 +143,7 @@ EventBufData_list::EventBufData_list() m_count(0), m_sz(0), m_gci_op_list(NULL), - m_gci_op_count(0), + m_gci_ops_list_tail(0), m_gci_op_alloc(0) { } @@ -100,7 +151,14 @@ EventBufData_list::EventBufData_list() inline EventBufData_list::~EventBufData_list() { - delete [] m_gci_op_list; + if (m_is_not_multi_list) + delete [] m_gci_op_list; + else + { + Gci_ops *op = first_gci_ops(); + while (op) + op = next_gci_ops(); + } } inline @@ -120,11 +178,8 @@ void EventBufData_list::remove_first() } inline -void EventBufData_list::append(EventBufData *data) +void EventBufData_list::append_used_data(EventBufData *data) { - Gci_op g = { data->m_event_op, 1 << (Uint32)data->sdata->operation }; - add_gci_op(g); - data->m_next= 0; if (m_tail) m_tail->m_next= data; @@ -143,19 +198,33 @@ void EventBufData_list::append(EventBufData *data) } inline -void EventBufData_list::append(const EventBufData_list &list) +void EventBufData_list::append_data(EventBufData *data) { - Uint32 i; - for (i = 0; i < list.m_gci_op_count; i++) - add_gci_op(list.m_gci_op_list[i]); + Gci_op g = { data->m_event_op, 1 << (Uint32)data->sdata->operation }; + add_gci_op(g); - if (m_tail) - m_tail->m_next= list.m_head; - else - m_head= list.m_head; - m_tail= list.m_tail; - m_count+= list.m_count; - m_sz+= list.m_sz; + append_used_data(data); +} + +inline EventBufData_list::Gci_ops * +EventBufData_list::first_gci_ops() +{ + assert(!m_is_not_multi_list); + return m_gci_ops_list; +} + +inline EventBufData_list::Gci_ops * +EventBufData_list::next_gci_ops() +{ + assert(!m_is_not_multi_list); + Gci_ops *first = m_gci_ops_list; + m_gci_ops_list = first->m_next; + if (first->m_gci_op_list) + delete [] first->m_gci_op_list; + delete first; + if (m_gci_ops_list == 0) + m_gci_ops_list_tail = 0; + return m_gci_ops_list; } // GCI bucket has also a hash over data, with key event op, table PK. From d3c0dc0eed76c9de64f177f4083585f4cfa10a5d Mon Sep 17 00:00:00 2001 From: "cmiller@calliope.local" <> Date: Thu, 9 Mar 2006 15:12:43 -0500 Subject: [PATCH 06/11] Added code to mysqldump to dump timed events when instructed to do so, with the '-E' or '--events' flag. (Closes Bug#16853 and Bug#17714.) WARNING: At present, these tests fail due to b*g number 18078. --- client/mysqldump.c | 154 ++++++++++++++++++++++++++++++++-- mysql-test/r/mysqldump.result | 37 ++++++++ mysql-test/t/mysqldump.test | 40 +++++++++ sql/event_timed.cc | 2 - 4 files changed, 225 insertions(+), 8 deletions(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index 7dccbf95e20..836b33d2985 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -95,6 +95,7 @@ static my_bool verbose=0,tFlag=0,dFlag=0,quick= 1, extended_insert= 1, opt_complete_insert= 0, opt_drop_database= 0, opt_replace_into= 0, opt_dump_triggers= 0, opt_routines=0, opt_tz_utc=1, + opt_events= 0, opt_alltspcs=0; static ulong opt_max_allowed_packet, opt_net_buffer_length; static MYSQL mysql_connection,*sock=0; @@ -231,6 +232,9 @@ static struct my_option my_long_options[] = {"disable-keys", 'K', "'/*!40000 ALTER TABLE tb_name DISABLE KEYS */; and '/*!40000 ALTER TABLE tb_name ENABLE KEYS */; will be put in the output.", (gptr*) &opt_disable_keys, (gptr*) &opt_disable_keys, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, + {"events", 'E', "Dump events.", + (gptr*) &opt_events, (gptr*) &opt_events, 0, GET_BOOL, + NO_ARG, 0, 0, 0, 0, 0, 0}, {"extended-insert", 'e', "Allows utilization of the new, much faster INSERT syntax.", (gptr*) &extended_insert, (gptr*) &extended_insert, 0, GET_BOOL, NO_ARG, @@ -1238,9 +1242,136 @@ static void print_xml_row(FILE *xml_file, const char *row_name, check_io(xml_file); } + +/* + create_delimiter + Generate a new (null-terminated) string that does not exist in query + and is therefore suitable for use as a query delimiter. Store this + delimiter in delimiter_buff . + + This is quite simple in that it doesn't even try to parse statements as an + interpreter would. It merely returns a string that is not in the query, which + is much more than adequate for constructing a delimiter. + + RETURN + ptr to the delimiter on Success + NULL on Failure +*/ +static char *create_delimiter(char *query, char *delimiter_buff, + int delimiter_max_size) +{ + int proposed_length; + char *presence; + + delimiter_buff[0]= ';'; /* start with one semicolon, and */ + + for (proposed_length= 2; proposed_length < delimiter_max_size; + delimiter_max_size++) { + + delimiter_buff[proposed_length-1]= ';'; /* add semicolons, until */ + delimiter_buff[proposed_length]= '\0'; + + presence = strstr(query, delimiter_buff); + if (presence == NULL) { /* the proposed delimiter is not in the query. */ + return delimiter_buff; + } + + } + return NULL; /* but if we run out of space, return nothing at all. */ +} + + +/* + dump_events_for_db + -- retrieves list of events for a given db, and prints out + the CREATE EVENT statement into the output (the dump). + + RETURN + 0 Success + 1 Error +*/ +static uint dump_events_for_db(char *db) +{ + char query_buff[QUERY_LENGTH]; + char db_name_buff[NAME_LEN*2+3], name_buff[NAME_LEN*2+3]; + char *event_name; + char delimiter[QUERY_LENGTH], *delimit_test; + FILE *sql_file= md_result_file; + MYSQL_RES *event_res, *event_list_res; + MYSQL_ROW row, event_list_row; + DBUG_ENTER("dump_events_for_db"); + DBUG_PRINT("enter", ("db: '%s'", db)); + + mysql_real_escape_string(sock, db_name_buff, db, strlen(db)); + + /* nice comments */ + if (opt_comments) + fprintf(sql_file, "\n--\n-- Dumping events for database '%s'\n--\n", db); + + /* + not using "mysql_query_with_error_report" because we may have not + enough privileges to lock mysql.events. + */ + if (lock_tables) + mysql_query(sock, "LOCK TABLES mysql.event READ"); + + if (mysql_query_with_error_report(sock, &event_list_res, "show events")) + { + safe_exit(EX_MYSQLERR); + DBUG_RETURN(0); + } + + strcpy(delimiter, ";"); + if (mysql_num_rows(event_list_res) > 0) + { + while ((event_list_row= mysql_fetch_row(event_list_res)) != NULL) + { + event_name= quote_name(event_list_row[1], name_buff, 0); + DBUG_PRINT("info", ("retrieving CREATE EVENT for %s", name_buff)); + my_snprintf(query_buff, sizeof(query_buff), "SHOW CREATE EVENT %s", + event_name); + + if (mysql_query_with_error_report(sock, &event_res, query_buff)) + DBUG_RETURN(1); + + while ((row= mysql_fetch_row(event_res)) != NULL) + { + /* + if the user has EXECUTE privilege he can see event names, but not the + event body! + */ + if (strlen(row[2]) != 0) + { + if (opt_drop) + fprintf(sql_file, "/*!50106 DROP EVENT IF EXISTS %s */%s\n", + event_name, delimiter); + + delimit_test= create_delimiter(row[2], delimiter, sizeof(delimiter)); + if (delimit_test == NULL) { + fprintf(stderr, "%s: Warning: Can't dump event '%s'\n", + event_name, my_progname); + DBUG_RETURN(1); + } + + fprintf(sql_file, "DELIMITER %s\n", delimiter); + fprintf(sql_file, "/*!50106 %s */ %s\n", row[2], delimiter); + } + } /* end of event printing */ + } /* end of list of events */ + fprintf(sql_file, "DELIMITER ;\n"); + mysql_free_result(event_res); + } + mysql_free_result(event_list_res); + + if (lock_tables) + VOID(mysql_query_with_error_report(sock, 0, "UNLOCK TABLES")); + DBUG_RETURN(0); +} + + /* dump_routines_for_db - -- retrievs list of routines for a given db, and prints out + -- retrieves list of routines for a given db, and prints out the CREATE PROCEDURE definition into the output (the dump). This function has logic to print the appropriate syntax depending on whether @@ -1253,7 +1384,7 @@ static void print_xml_row(FILE *xml_file, const char *row_name, static uint dump_routines_for_db(char *db) { - char query_buff[512]; + char query_buff[QUERY_LENGTH]; const char *routine_type[]= {"FUNCTION", "PROCEDURE"}; char db_name_buff[NAME_LEN*2+3], name_buff[NAME_LEN*2+3]; char *routine_name; @@ -1294,9 +1425,9 @@ static uint dump_routines_for_db(char *db) while ((routine_list_row= mysql_fetch_row(routine_list_res))) { + routine_name= quote_name(routine_list_row[1], name_buff, 0); DBUG_PRINT("info", ("retrieving CREATE %s for %s", routine_type[i], name_buff)); - routine_name= quote_name(routine_list_row[1], name_buff, 0); my_snprintf(query_buff, sizeof(query_buff), "SHOW CREATE %s %s", routine_type[i], routine_name); @@ -1364,7 +1495,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, char *result_table, *opt_quoted_table; const char *insert_option; char name_buff[NAME_LEN+3],table_buff[NAME_LEN*2+3]; - char table_buff2[NAME_LEN*2+3], query_buff[512]; + char table_buff2[NAME_LEN*2+3], query_buff[QUERY_LENGTH]; FILE *sql_file = md_result_file; int len; MYSQL_RES *result; @@ -1840,7 +1971,7 @@ static void dump_triggers_for_table (char *table, char *db) { char *result_table; char name_buff[NAME_LEN*4+3], table_buff[NAME_LEN*2+3]; - char query_buff[512]; + char query_buff[QUERY_LENGTH]; uint old_opt_compatible_mode=opt_compatible_mode; FILE *sql_file = md_result_file; MYSQL_RES *result; @@ -2500,7 +2631,6 @@ static int dump_all_tablespaces() { MYSQL_ROW row; MYSQL_RES *tableres; - int result=0; char buf[FN_REFLEN]; int first; @@ -2798,6 +2928,12 @@ static int dump_all_tables_in_db(char *database) dump_triggers_for_table(table, database); } } + if (opt_events && !opt_xml && + mysql_get_server_version(sock) >= 50106) + { + DBUG_PRINT("info", ("Dumping events for database %s", database)); + dump_events_for_db(database); + } if (opt_routines && !opt_xml && mysql_get_server_version(sock) >= 50009) { @@ -3008,6 +3144,12 @@ static int dump_selected_tables(char *db, char **table_names, int tables) get_view_structure(table_name, db); } } + if (opt_events && !opt_xml && + mysql_get_server_version(sock) >= 50106) + { + DBUG_PRINT("info", ("Dumping events for database %s", db)); + dump_events_for_db(db); + } /* obtain dump of routines (procs/functions) */ if (opt_routines && !opt_xml && mysql_get_server_version(sock) >= 50009) diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index e54dee1fcfd..64cec574678 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -2907,3 +2907,40 @@ mysql-import: Error: 1146, Table 'test.words' doesn't exist, when using table: w drop table t1; drop table t2; drop table words2; +create database first; +use first; +set time_zone = 'UTC'; +create event ee1 on schedule at '2035-12-31 20:01:23' do set @a=5; +show events; +Db Name Definer Type Execute at Interval value Interval field Starts Ends Status +first ee1 root@localhost ONE TIME 2035-12-31 20:01:23 NULL NULL NULL NULL ENABLED +show create event ee1; +Event sql_mode Create Event +ee1 CREATE EVENT `ee1` ON SCHEDULE AT '2035-12-31 20:01:23' ON COMPLETION NOT PRESERVE ENABLE DO set @a=5 +drop database first; +create database second; +use second; +show events; +Db Name Definer Type Execute at Interval value Interval field Starts Ends Status +second ee1 root@localhost ONE TIME 2035-12-31 20:01:23 NULL NULL NULL NULL ENABLED +show create event ee1; +Event sql_mode Create Event +ee1 NO_AUTO_VALUE_ON_ZERO CREATE EVENT `ee1` ON SCHEDULE AT '2035-12-31 20:01:23' ON COMPLETION NOT PRESERVE ENABLE DO set @a=5 +create event ee2 on schedule at '2018-12-31 21:01:23' do set @a=5; +create event ee3 on schedule at '2030-12-31 22:01:23' do set @a=5; +show events; +Db Name Definer Type Execute at Interval value Interval field Starts Ends Status +second ee1 root@localhost ONE TIME 2035-12-31 20:01:23 NULL NULL NULL NULL ENABLED +second ee2 root@localhost ONE TIME 2018-12-31 21:01:23 NULL NULL NULL NULL ENABLED +second ee3 root@localhost ONE TIME 2030-12-31 22:01:23 NULL NULL NULL NULL ENABLED +drop database second; +create database third; +use third; +show events; +Db Name Definer Type Execute at Interval value Interval field Starts Ends Status +third ee1 root@localhost ONE TIME 2035-12-31 20:01:23 NULL NULL NULL NULL ENABLED +third ee2 root@localhost ONE TIME 2018-12-31 21:01:23 NULL NULL NULL NULL ENABLED +third ee3 root@localhost ONE TIME 2030-12-31 22:01:23 NULL NULL NULL NULL ENABLED +drop database third; +set time_zone = 'SYSTEM'; +use test; diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index b1ddfc97c70..c883ddf86a9 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -1166,3 +1166,43 @@ drop table t1; drop table t2; drop table words2; + +# +# BUG# 16853: mysqldump doesn't show events +# +create database first; +use first; +set time_zone = 'UTC'; + +## prove one works +create event ee1 on schedule at '2035-12-31 20:01:23' do set @a=5; +show events; +show create event ee1; +--exec $MYSQL_DUMP --events first > $MYSQLTEST_VARDIR/tmp/bug16853-1.sql +drop database first; + +create database second; +use second; +--exec $MYSQL second < $MYSQLTEST_VARDIR/tmp/bug16853-1.sql +show events; +show create event ee1; + +## prove three works +# start with one from the previous restore +create event ee2 on schedule at '2018-12-31 21:01:23' do set @a=5; +create event ee3 on schedule at '2030-12-31 22:01:23' do set @a=5; +show events; +--exec $MYSQL_DUMP --events second > $MYSQLTEST_VARDIR/tmp/bug16853-2.sql +drop database second; + +create database third; +use third; +--exec $MYSQL third < $MYSQLTEST_VARDIR/tmp/bug16853-2.sql +show events; +drop database third; + +# revert back to normal settings +set time_zone = 'SYSTEM'; +use test; + +##### diff --git a/sql/event_timed.cc b/sql/event_timed.cc index a8620197668..c1fd433dc5b 100644 --- a/sql/event_timed.cc +++ b/sql/event_timed.cc @@ -1063,8 +1063,6 @@ Event_timed::get_create_event(THD *thd, String *buf) DBUG_RETURN(EVEX_MICROSECOND_UNSUP); buf->append(STRING_WITH_LEN("CREATE EVENT ")); - append_identifier(thd, buf, dbname.str, dbname.length); - buf->append(STRING_WITH_LEN(".")); append_identifier(thd, buf, name.str, name.length); buf->append(STRING_WITH_LEN(" ON SCHEDULE ")); From eefd1207bb8d422944add4bb9cad64070bf47f13 Mon Sep 17 00:00:00 2001 From: "brian@zim.(none)" <> Date: Thu, 9 Mar 2006 16:44:08 -0800 Subject: [PATCH 07/11] This patch does 1) fix my build breakage 2) Complete the removal of all symbols which could clash with another parser. --- sql/mysql_priv.h | 4 ++-- sql/mysqld.cc | 2 +- sql/sp.cc | 4 ++-- sql/sql_lex.cc | 4 ++-- sql/sql_lex.h | 4 ++-- sql/sql_parse.cc | 6 +++--- sql/sql_prepare.cc | 2 +- sql/sql_trigger.cc | 3 ++- sql/sql_view.cc | 3 ++- 9 files changed, 17 insertions(+), 15 deletions(-) diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index a43307edf27..68679cf79dc 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1093,7 +1093,7 @@ File open_binlog(IO_CACHE *log, const char *log_file_name, const char **errmsg); /* mysqld.cc */ -extern void yyerror(const char*); +extern void MYSQLerror(const char*); /* item_func.cc */ extern bool check_reserved_words(LEX_STRING *name); @@ -1415,7 +1415,7 @@ void free_list(I_List *list); void free_list(I_List *list); /* sql_yacc.cc */ -extern int yyparse(void *thd); +extern int MYSQLparse(void *thd); /* frm_crypt.cc */ #ifdef HAVE_CRYPTED_FRM diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 37a135fa063..bc30a2c981b 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1524,7 +1524,7 @@ static void network_init(void) #endif /*!EMBEDDED_LIBRARY*/ -void yyerror(const char *s) +void MYSQLerror(const char *s) { THD *thd=current_thd; char *yytext= (char*) thd->lex->tok_start; diff --git a/sql/sp.cc b/sql/sp.cc index e4489af1fdd..0446bf94e53 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -269,7 +269,7 @@ db_find_routine_aux(THD *thd, int type, sp_name *name, TABLE *table) static int db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp) { - extern int yyparse(void *thd); + extern int MYSQLparse(void *thd); TABLE *table; const char *params, *returns, *body; int ret; @@ -459,7 +459,7 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, lex_start(thd, (uchar*)defstr.c_ptr(), defstr.length()); thd->spcont= 0; - if (yyparse(thd) || thd->is_fatal_error || newlex.sphead == NULL) + if (MYSQLparse(thd) || thd->is_fatal_error || newlex.sphead == NULL) { sp_head *sp= newlex.sphead; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 110c82f6926..2b31abd6a50 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -507,14 +507,14 @@ static inline uint int_token(const char *str,uint length) } /* - yylex remember the following states from the following yylex() + MYSQLlex remember the following states from the following MYSQLlex() - MY_LEX_EOQ Found end of query - MY_LEX_OPERATOR_OR_IDENT Last state was an ident, text or number (which can't be followed by a signed number) */ -int yylex(void *arg, void *yythd) +int MYSQLlex(void *arg, void *yythd) { reg1 uchar c; int tokval, result_state; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 8bacc60d48d..8512c075f69 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -716,7 +716,7 @@ typedef struct st_lex uchar *buf; /* The beginning of string, used by SPs */ uchar *ptr,*tok_start,*tok_end,*end_of_query; - /* The values of tok_start/tok_end as they were one call of yylex before */ + /* The values of tok_start/tok_end as they were one call of MYSQLlex before */ uchar *tok_start_prev, *tok_end_prev; char *length,*dec,*change,*name; @@ -1065,7 +1065,7 @@ extern void lex_init(void); extern void lex_free(void); extern void lex_start(THD *thd, uchar *buf,uint length); extern void lex_end(LEX *lex); -extern int yylex(void *arg, void *yythd); +extern int MYSQLlex(void *arg, void *yythd); extern pthread_key(LEX*,THR_LEX); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index ea559c70734..489afe79b5e 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4244,7 +4244,7 @@ end_with_restore_list: /* We must cleanup the unit and the lex here because sp_grant_privileges calls (indirectly) db_find_routine, - which in turn may call yyparse with THD::lex. + which in turn may call MYSQLparse with THD::lex. TODO: fix db_find_routine to use a temporary lex. */ lex->unit.cleanup(); @@ -5659,7 +5659,7 @@ void mysql_parse(THD *thd, char *inBuf, uint length) sp_cache_flush_obsolete(&thd->sp_proc_cache); sp_cache_flush_obsolete(&thd->sp_func_cache); - if (!yyparse((void *)thd) && ! thd->is_fatal_error) + if (!MYSQLparse((void *)thd) && ! thd->is_fatal_error) { #ifndef NO_EMBEDDED_ACCESS_CHECKS if (mqh_used && thd->user_connect && @@ -5739,7 +5739,7 @@ bool mysql_test_parse_for_slave(THD *thd, char *inBuf, uint length) DBUG_ENTER("mysql_test_parse_for_slave"); mysql_init_query(thd, (uchar*) inBuf, length); - if (!yyparse((void*) thd) && ! thd->is_fatal_error && + if (!MYSQLparse((void*) thd) && ! thd->is_fatal_error && all_tables_not_ok(thd,(TABLE_LIST*) lex->select_lex.table_list.first)) error= 1; /* Ignore question */ thd->end_statement(); diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 332f699200e..0f4ae04962b 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -2757,7 +2757,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len) lex->safe_to_cache_query= FALSE; lex->stmt_prepare_mode= TRUE; - error= yyparse((void *)thd) || thd->is_fatal_error || + error= MYSQLparse((void *)thd) || thd->is_fatal_error || thd->net.report_error || init_param_array(this); /* While doing context analysis of the query (in check_prepared_statement) diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 024c882f8a9..b432961b7e6 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -15,6 +15,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#define MYSQL_LEX 1 #include "mysql_priv.h" #include "sp_head.h" #include "sql_trigger.h" @@ -932,7 +933,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, lex_start(thd, (uchar*)trg_create_str->str, trg_create_str->length); thd->spcont= 0; - if (yyparse((void *)thd) || thd->is_fatal_error) + if (MYSQLparse((void *)thd) || thd->is_fatal_error) { /* Free lex associated resources. diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 4f2a9a07705..2832adc1f8f 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -15,6 +15,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#define MYSQL_LEX 1 #include "mysql_priv.h" #include "sql_select.h" #include "parse_file.h" @@ -889,7 +890,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table) MODE_IGNORE_SPACE | MODE_NO_BACKSLASH_ESCAPES); CHARSET_INFO *save_cs= thd->variables.character_set_client; thd->variables.character_set_client= system_charset_info; - res= yyparse((void *)thd); + res= MYSQLparse((void *)thd); thd->variables.character_set_client= save_cs; thd->variables.sql_mode= save_mode; } From 469893066b50f9f4815d5276a7fc1c83750f5db3 Mon Sep 17 00:00:00 2001 From: "brian@zim.(none)" <> Date: Thu, 9 Mar 2006 17:37:59 -0800 Subject: [PATCH 08/11] Fixed portability issue in 5.1 to include parsers from other applications. --- sql/event_timed.cc | 5 +++-- sql/sql_partition.cc | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/sql/event_timed.cc b/sql/event_timed.cc index a8620197668..40987c9132e 100644 --- a/sql/event_timed.cc +++ b/sql/event_timed.cc @@ -14,13 +14,14 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#define MYSQL_LEX 1 #include "event_priv.h" #include "event.h" #include "sp.h" -extern int yyparse(void *thd); +extern int MYSQLparse(void *thd); /* Init all member variables @@ -1338,7 +1339,7 @@ Event_timed::compile(THD *thd, MEM_ROOT *mem_root) thd->lex= &lex; lex_start(thd, (uchar*)thd->query, thd->query_length); lex.et_compile_phase= TRUE; - if (yyparse((void *)thd) || thd->is_fatal_error) + if (MYSQLparse((void *)thd) || thd->is_fatal_error) { DBUG_PRINT("error", ("error during compile or thd->is_fatal_error=%d", thd->is_fatal_error)); diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 257c1988cbd..014d3616d3d 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -33,6 +33,7 @@ /* Some general useful functions */ +#define MYSQL_LEX 1 #include "mysql_priv.h" #include #include @@ -3697,7 +3698,7 @@ bool mysql_unpack_partition(THD *thd, const uchar *part_buf, we then save in the partition info structure. */ thd->free_list= NULL; - lex.part_info= new partition_info();/* Indicates yyparse from this place */ + lex.part_info= new partition_info();/* Indicates MYSQLparse from this place */ if (!lex.part_info) { mem_alloc_error(sizeof(partition_info)); @@ -3706,7 +3707,7 @@ bool mysql_unpack_partition(THD *thd, const uchar *part_buf, lex.part_info->part_state= part_state; lex.part_info->part_state_len= part_state_len; DBUG_PRINT("info", ("Parse: %s", part_buf)); - if (yyparse((void*)thd) || thd->is_fatal_error) + if (MYSQLparse((void*)thd) || thd->is_fatal_error) { free_items(thd->free_list); goto end; From fb3286312f2c3d72ee805ebbbb945f682b4fd9ab Mon Sep 17 00:00:00 2001 From: "mskold@mysql.com" <> Date: Fri, 10 Mar 2006 09:57:00 +0100 Subject: [PATCH 09/11] Reverted to previous error codes, since some common tests depend in it --- mysql-test/r/ndb_index_unique.result | 12 ++++++------ mysql-test/t/ndb_index_unique.test | 12 ++++++------ storage/ndb/src/ndbapi/ndberror.c | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/mysql-test/r/ndb_index_unique.result b/mysql-test/r/ndb_index_unique.result index 2e0a143d351..497ad973e8b 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 'PRIMARY' select * from t1 order by a; a b c 1 2 3 @@ -93,7 +93,7 @@ a b c 1 1 1 4 4 NULL insert into t1 values(5,1,1); -ERROR 23000: Can't write, because of unique constraint, to table 't1' +ERROR 23000: Duplicate entry '5' for key 'PRIMARY' drop table t1; CREATE TABLE t2 ( a int unsigned NOT NULL PRIMARY KEY, @@ -116,7 +116,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 'PRIMARY' select * from t2 order by a; a b c 1 2 3 @@ -181,7 +181,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 'PRIMARY' select * from t1 order by pk; pk a -1 NULL @@ -214,7 +214,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 'PRIMARY' select * from t2 order by pk; pk a b c -1 1 17 NULL @@ -634,7 +634,7 @@ create table t1 (a int primary key, b varchar(1000) not null, unique key (b)) engine=ndb charset=utf8; insert into t1 values (1, repeat(_utf8 0xe288ab6474, 200)); insert into t1 values (2, repeat(_utf8 0xe288ab6474, 200)); -ERROR 23000: Can't write, because of unique constraint, to table 't1' +ERROR 23000: Duplicate entry '2' for key 'PRIMARY' select a, sha1(b) from t1; a sha1(b) 1 08f5d02c8b8bc244f275bdfc22c42c5cab0d9d7d diff --git a/mysql-test/t/ndb_index_unique.test b/mysql-test/t/ndb_index_unique.test index 5caa702bae6..4bd575396ce 100644 --- a/mysql-test/t/ndb_index_unique.test +++ b/mysql-test/t/ndb_index_unique.test @@ -22,7 +22,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; @@ -59,7 +59,7 @@ 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 1169 +-- error 1062 insert into t1 values(5,1,1); drop table t1; @@ -82,7 +82,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; @@ -133,7 +133,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; @@ -152,7 +152,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; @@ -321,7 +321,7 @@ create table t1 (a int primary key, b varchar(1000) not null, unique key (b)) engine=ndb charset=utf8; insert into t1 values (1, repeat(_utf8 0xe288ab6474, 200)); ---error 1169 +--error 1062 insert into t1 values (2, repeat(_utf8 0xe288ab6474, 200)); select a, sha1(b) from t1; diff --git a/storage/ndb/src/ndbapi/ndberror.c b/storage/ndb/src/ndbapi/ndberror.c index d2642543c24..d98c75ae8cc 100644 --- a/storage/ndb/src/ndbapi/ndberror.c +++ b/storage/ndb/src/ndbapi/ndberror.c @@ -112,7 +112,7 @@ ErrorBundle ErrorCodes[] = { { 630, HA_ERR_FOUND_DUPP_KEY, CV, "Tuple already existed when attempting to insert" }, { 839, DMEC, CV, "Illegal null attribute" }, { 840, DMEC, CV, "Trying to set a NOT NULL attribute to NULL" }, - { 893, HA_ERR_FOUND_DUPP_UNIQUE, CV, "Constraint violation e.g. duplicate value in unique index" }, + { 893, HA_ERR_FOUND_DUPP_KEY, CV, "Constraint violation e.g. duplicate value in unique index" }, /** * Node recovery errors From a7f9699d8afa19ea1b26d562082e279097660f9d Mon Sep 17 00:00:00 2001 From: "tomas@poseidon.ndb.mysql.com" <> Date: Fri, 10 Mar 2006 10:41:52 +0100 Subject: [PATCH 10/11] added missing dbug_return --- sql/ha_ndbcluster_binlog.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc index 272e492b284..3d84647e0db 100644 --- a/sql/ha_ndbcluster_binlog.cc +++ b/sql/ha_ndbcluster_binlog.cc @@ -1477,7 +1477,7 @@ ndb_handle_schema_change(THD *thd, Ndb *ndb, NdbEventOperation *pOp, if (do_close_cached_tables) close_cached_tables((THD*) 0, 0, (TABLE_LIST*) 0); - return 0; + DBUG_RETURN(0); } static int From b8a496b74d2939ce653af425652e0458f1659065 Mon Sep 17 00:00:00 2001 From: "mskold@mysql.com" <> Date: Fri, 10 Mar 2006 11:27:59 +0100 Subject: [PATCH 11/11] Disabled test case due to Bug: #18129: Fast (online) add index leaves temporary table frm in case of errors --- mysql-test/r/ndb_index_unique.result | 2 -- mysql-test/t/ndb_index_unique.test | 6 +++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/ndb_index_unique.result b/mysql-test/r/ndb_index_unique.result index 497ad973e8b..229339d603e 100644 --- a/mysql-test/r/ndb_index_unique.result +++ b/mysql-test/r/ndb_index_unique.result @@ -45,8 +45,6 @@ a b c 8 2 3 alter table t1 drop index ib; insert into t1 values(1, 2, 3); -create unique index ib on t1(b); -ERROR 23000: Can't write, because of unique constraint, to table 't1' drop table t1; CREATE TABLE t1 ( a int unsigned NOT NULL PRIMARY KEY, diff --git a/mysql-test/t/ndb_index_unique.test b/mysql-test/t/ndb_index_unique.test index 4bd575396ce..4fb6422b359 100644 --- a/mysql-test/t/ndb_index_unique.test +++ b/mysql-test/t/ndb_index_unique.test @@ -30,10 +30,10 @@ insert into t1 values(8, 2, 3); select * from t1 order by a; alter table t1 drop index ib; -sleep 10; insert into t1 values(1, 2, 3); ---error 1169 -create unique index ib on t1(b); +# Bug# #18129 +#--error 1169 +#create unique index ib on t1(b); drop table t1;