diff options
-rw-r--r-- | mysql-test/r/ndb_subquery.result | 42 | ||||
-rw-r--r-- | mysql-test/t/ndb_subquery.test | 38 | ||||
-rw-r--r-- | ndb/src/kernel/blocks/dbtc/DbtcMain.cpp | 25 | ||||
-rw-r--r-- | sql/ha_ndbcluster.cc | 44 |
4 files changed, 141 insertions, 8 deletions
diff --git a/mysql-test/r/ndb_subquery.result b/mysql-test/r/ndb_subquery.result new file mode 100644 index 00000000000..8c89805a765 --- /dev/null +++ b/mysql-test/r/ndb_subquery.result @@ -0,0 +1,42 @@ +drop table if exists t1; +drop table if exists t2; +create table t1 (p int not null primary key, u int not null, o int not null, +unique (u), key(o)) engine=ndb; +create table t2 (p int not null primary key, u int not null, o int not null, +unique (u), key(o)) engine=ndb; +insert into t1 values (1,1,1),(2,2,2),(3,3,3); +insert into t2 values (1,1,1),(2,2,2),(3,3,3), (4,4,4), (5,5,5); +explain select * from t2 where p NOT IN (select p from t1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using where +2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 Using index +select * from t2 where p NOT IN (select p from t1); +p u o +4 4 4 +5 5 5 +explain select * from t2 where p NOT IN (select u from t1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using where +2 DEPENDENT SUBQUERY t1 unique_subquery u u 4 func 1 Using index +select * from t2 where p NOT IN (select u from t1); +p u o +4 4 4 +5 5 5 +explain select * from t2 where p NOT IN (select o from t1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using where +2 DEPENDENT SUBQUERY t1 index_subquery o o 4 func 1 Using index +select * from t2 where p NOT IN (select o from t1); +p u o +4 4 4 +5 5 5 +explain select * from t2 where p NOT IN (select p+0 from t1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 3 Using where +select * from t2 where p NOT IN (select p+0 from t1); +p u o +4 4 4 +5 5 5 +drop table t1; +drop table t2; diff --git a/mysql-test/t/ndb_subquery.test b/mysql-test/t/ndb_subquery.test new file mode 100644 index 00000000000..e80d9b16b46 --- /dev/null +++ b/mysql-test/t/ndb_subquery.test @@ -0,0 +1,38 @@ +-- source include/have_ndb.inc + +--disable_warnings +drop table if exists t1; +drop table if exists t2; +--enable_warnings + +########## +# bug#5367 +create table t1 (p int not null primary key, u int not null, o int not null, +unique (u), key(o)) engine=ndb; + +create table t2 (p int not null primary key, u int not null, o int not null, +unique (u), key(o)) engine=ndb; + +insert into t1 values (1,1,1),(2,2,2),(3,3,3); +insert into t2 values (1,1,1),(2,2,2),(3,3,3), (4,4,4), (5,5,5); + +# Use pk +explain select * from t2 where p NOT IN (select p from t1); +select * from t2 where p NOT IN (select p from t1); + +# Use unique index +explain select * from t2 where p NOT IN (select u from t1); +select * from t2 where p NOT IN (select u from t1); + +# Use ordered index +explain select * from t2 where p NOT IN (select o from t1); +select * from t2 where p NOT IN (select o from t1); + +# Use scan +explain select * from t2 where p NOT IN (select p+0 from t1); +select * from t2 where p NOT IN (select p+0 from t1); + +drop table t1; +drop table t2; +# bug#5367 +########## diff --git a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp index 5b5578cb579..765d77d5dd6 100644 --- a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp +++ b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp @@ -1249,7 +1249,8 @@ void Dbtc::execTCRELEASEREQ(Signal* signal) jam(); signal->theData[0] = tuserpointer; signal->theData[1] = ZINVALID_CONNECTION; - sendSignal(tapiBlockref, GSN_TCRELEASEREF, signal, 2, JBB); + signal->theData[2] = __LINE__; + sendSignal(tapiBlockref, GSN_TCRELEASEREF, signal, 3, JBB); return; } else { jam(); @@ -1262,7 +1263,9 @@ void Dbtc::execTCRELEASEREQ(Signal* signal) sendSignal(tapiBlockref, GSN_TCRELEASECONF, signal, 1, JBB); } else { if (tapiBlockref == apiConnectptr.p->ndbapiBlockref) { - if (apiConnectptr.p->apiConnectstate == CS_CONNECTED) { + if (apiConnectptr.p->apiConnectstate == CS_CONNECTED || + (apiConnectptr.p->apiConnectstate == CS_ABORTING && + apiConnectptr.p->abortState == AS_IDLE)){ jam(); /* JUST REPLY OK */ releaseApiCon(signal, apiConnectptr.i); signal->theData[0] = tuserpointer; @@ -1272,14 +1275,19 @@ void Dbtc::execTCRELEASEREQ(Signal* signal) jam(); signal->theData[0] = tuserpointer; signal->theData[1] = ZINVALID_CONNECTION; + signal->theData[2] = __LINE__; + signal->theData[3] = apiConnectptr.p->apiConnectstate; sendSignal(tapiBlockref, - GSN_TCRELEASEREF, signal, 2, JBB); + GSN_TCRELEASEREF, signal, 4, JBB); } } else { jam(); signal->theData[0] = tuserpointer; signal->theData[1] = ZINVALID_CONNECTION; - sendSignal(tapiBlockref, GSN_TCRELEASEREF, signal, 2, JBB); + signal->theData[2] = __LINE__; + signal->theData[3] = tapiBlockref; + signal->theData[4] = apiConnectptr.p->ndbapiBlockref; + sendSignal(tapiBlockref, GSN_TCRELEASEREF, signal, 5, JBB); }//if }//if }//Dbtc::execTCRELEASEREQ() @@ -6037,6 +6045,7 @@ void Dbtc::timeOutFoundLab(Signal* signal, Uint32 TapiConPtr) << " - place: " << c_apiConTimer_line[apiConnectptr.i]); switch (apiConnectptr.p->apiConnectstate) { case CS_STARTED: + ndbrequire(c_apiConTimer_line[apiConnectptr.i] != 3615); if(apiConnectptr.p->lqhkeyreqrec == apiConnectptr.p->lqhkeyconfrec){ jam(); /* @@ -11359,6 +11368,7 @@ void Dbtc::execTCKEYCONF(Signal* signal) Uint32 Ttcindxrec = regApiPtr->tcindxrec; // Copy reply from TcKeyConf + ndbassert(regApiPtr->noIndexOp); regApiPtr->noIndexOp--; // Decrease count regApiPtr->tcIndxSendArray[Ttcindxrec] = indexOp->tcIndxReq.senderData; regApiPtr->tcIndxSendArray[Ttcindxrec + 1] = @@ -11417,6 +11427,12 @@ void Dbtc::execTCKEYREF(Signal* signal) abortErrorLab(signal); break; } + /** + * Increase count as it will be decreased below... + * (and the code is written to handle failing lookup on "real" table + * not lookup on index table) + */ + regApiPtr->noIndexOp++; // else continue } case(IOS_INDEX_OPERATION): { @@ -11426,6 +11442,7 @@ void Dbtc::execTCKEYREF(Signal* signal) TcIndxReq * const tcIndxReq = &indexOp->tcIndxReq; TcIndxRef * const tcIndxRef = (TcIndxRef *)signal->getDataPtrSend(); + ndbassert(regApiPtr->noIndexOp); regApiPtr->noIndexOp--; // Decrease count tcIndxRef->connectPtr = tcIndxReq->senderData; tcIndxRef->transId[0] = tcKeyRef->transId[0]; diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 57232778d48..8faa0b33756 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -2135,11 +2135,47 @@ int ha_ndbcluster::index_read(byte *buf, DBUG_PRINT("enter", ("active_index: %u, key_len: %u, find_flag: %d", active_index, key_len, find_flag)); + int error; + ndb_index_type type = get_index_type(active_index); + const KEY* key_info = table->key_info+active_index; + switch (type){ + case PRIMARY_KEY_ORDERED_INDEX: + case PRIMARY_KEY_INDEX: + if (find_flag == HA_READ_KEY_EXACT && key_info->key_length == key_len) + { + DBUG_RETURN(pk_read(key, key_len, buf)); + } + else if (type == PRIMARY_KEY_INDEX) + { + DBUG_RETURN(1); + } + break; + case UNIQUE_ORDERED_INDEX: + case UNIQUE_INDEX: + if (find_flag == HA_READ_KEY_EXACT && key_info->key_length == key_len) + { + DBUG_RETURN(unique_index_read(key, key_len, buf)); + } + else if (type == UNIQUE_INDEX) + { + DBUG_RETURN(1); + } + break; + case ORDERED_INDEX: + break; + default: + case UNDEFINED_INDEX: + DBUG_ASSERT(false); + return 1; + break; + } + key_range start_key; - start_key.key= key; - start_key.length= key_len; - start_key.flag= find_flag; - DBUG_RETURN(read_range_first_to_buf(&start_key, NULL, false, true, buf)); + start_key.key = key; + start_key.length = key_len; + start_key.flag = find_flag; + error= ordered_index_scan(&start_key, 0, true, buf); + DBUG_RETURN(error == HA_ERR_END_OF_FILE ? HA_ERR_KEY_NOT_FOUND : error); } |