bug#5736, subqueries and not in

and testcases
parent 96458f8f
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;
-- 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
##########
...@@ -1249,7 +1249,8 @@ void Dbtc::execTCRELEASEREQ(Signal* signal) ...@@ -1249,7 +1249,8 @@ void Dbtc::execTCRELEASEREQ(Signal* signal)
jam(); jam();
signal->theData[0] = tuserpointer; signal->theData[0] = tuserpointer;
signal->theData[1] = ZINVALID_CONNECTION; signal->theData[1] = ZINVALID_CONNECTION;
sendSignal(tapiBlockref, GSN_TCRELEASEREF, signal, 2, JBB); signal->theData[2] = __LINE__;
sendSignal(tapiBlockref, GSN_TCRELEASEREF, signal, 3, JBB);
return; return;
} else { } else {
jam(); jam();
...@@ -1262,7 +1263,9 @@ void Dbtc::execTCRELEASEREQ(Signal* signal) ...@@ -1262,7 +1263,9 @@ void Dbtc::execTCRELEASEREQ(Signal* signal)
sendSignal(tapiBlockref, GSN_TCRELEASECONF, signal, 1, JBB); sendSignal(tapiBlockref, GSN_TCRELEASECONF, signal, 1, JBB);
} else { } else {
if (tapiBlockref == apiConnectptr.p->ndbapiBlockref) { 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 */ jam(); /* JUST REPLY OK */
releaseApiCon(signal, apiConnectptr.i); releaseApiCon(signal, apiConnectptr.i);
signal->theData[0] = tuserpointer; signal->theData[0] = tuserpointer;
...@@ -1272,14 +1275,19 @@ void Dbtc::execTCRELEASEREQ(Signal* signal) ...@@ -1272,14 +1275,19 @@ void Dbtc::execTCRELEASEREQ(Signal* signal)
jam(); jam();
signal->theData[0] = tuserpointer; signal->theData[0] = tuserpointer;
signal->theData[1] = ZINVALID_CONNECTION; signal->theData[1] = ZINVALID_CONNECTION;
signal->theData[2] = __LINE__;
signal->theData[3] = apiConnectptr.p->apiConnectstate;
sendSignal(tapiBlockref, sendSignal(tapiBlockref,
GSN_TCRELEASEREF, signal, 2, JBB); GSN_TCRELEASEREF, signal, 4, JBB);
} }
} else { } else {
jam(); jam();
signal->theData[0] = tuserpointer; signal->theData[0] = tuserpointer;
signal->theData[1] = ZINVALID_CONNECTION; 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
}//if }//if
}//Dbtc::execTCRELEASEREQ() }//Dbtc::execTCRELEASEREQ()
...@@ -6037,6 +6045,7 @@ void Dbtc::timeOutFoundLab(Signal* signal, Uint32 TapiConPtr) ...@@ -6037,6 +6045,7 @@ void Dbtc::timeOutFoundLab(Signal* signal, Uint32 TapiConPtr)
<< " - place: " << c_apiConTimer_line[apiConnectptr.i]); << " - place: " << c_apiConTimer_line[apiConnectptr.i]);
switch (apiConnectptr.p->apiConnectstate) { switch (apiConnectptr.p->apiConnectstate) {
case CS_STARTED: case CS_STARTED:
ndbrequire(c_apiConTimer_line[apiConnectptr.i] != 3615);
if(apiConnectptr.p->lqhkeyreqrec == apiConnectptr.p->lqhkeyconfrec){ if(apiConnectptr.p->lqhkeyreqrec == apiConnectptr.p->lqhkeyconfrec){
jam(); jam();
/* /*
...@@ -11359,6 +11368,7 @@ void Dbtc::execTCKEYCONF(Signal* signal) ...@@ -11359,6 +11368,7 @@ void Dbtc::execTCKEYCONF(Signal* signal)
Uint32 Ttcindxrec = regApiPtr->tcindxrec; Uint32 Ttcindxrec = regApiPtr->tcindxrec;
// Copy reply from TcKeyConf // Copy reply from TcKeyConf
ndbassert(regApiPtr->noIndexOp);
regApiPtr->noIndexOp--; // Decrease count regApiPtr->noIndexOp--; // Decrease count
regApiPtr->tcIndxSendArray[Ttcindxrec] = indexOp->tcIndxReq.senderData; regApiPtr->tcIndxSendArray[Ttcindxrec] = indexOp->tcIndxReq.senderData;
regApiPtr->tcIndxSendArray[Ttcindxrec + 1] = regApiPtr->tcIndxSendArray[Ttcindxrec + 1] =
...@@ -11417,6 +11427,12 @@ void Dbtc::execTCKEYREF(Signal* signal) ...@@ -11417,6 +11427,12 @@ void Dbtc::execTCKEYREF(Signal* signal)
abortErrorLab(signal); abortErrorLab(signal);
break; 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 // else continue
} }
case(IOS_INDEX_OPERATION): { case(IOS_INDEX_OPERATION): {
...@@ -11426,6 +11442,7 @@ void Dbtc::execTCKEYREF(Signal* signal) ...@@ -11426,6 +11442,7 @@ void Dbtc::execTCKEYREF(Signal* signal)
TcIndxReq * const tcIndxReq = &indexOp->tcIndxReq; TcIndxReq * const tcIndxReq = &indexOp->tcIndxReq;
TcIndxRef * const tcIndxRef = (TcIndxRef *)signal->getDataPtrSend(); TcIndxRef * const tcIndxRef = (TcIndxRef *)signal->getDataPtrSend();
ndbassert(regApiPtr->noIndexOp);
regApiPtr->noIndexOp--; // Decrease count regApiPtr->noIndexOp--; // Decrease count
tcIndxRef->connectPtr = tcIndxReq->senderData; tcIndxRef->connectPtr = tcIndxReq->senderData;
tcIndxRef->transId[0] = tcKeyRef->transId[0]; tcIndxRef->transId[0] = tcKeyRef->transId[0];
......
...@@ -2135,11 +2135,47 @@ int ha_ndbcluster::index_read(byte *buf, ...@@ -2135,11 +2135,47 @@ int ha_ndbcluster::index_read(byte *buf,
DBUG_PRINT("enter", ("active_index: %u, key_len: %u, find_flag: %d", DBUG_PRINT("enter", ("active_index: %u, key_len: %u, find_flag: %d",
active_index, key_len, find_flag)); 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; key_range start_key;
start_key.key= key; start_key.key = key;
start_key.length= key_len; start_key.length = key_len;
start_key.flag= find_flag; start_key.flag = find_flag;
DBUG_RETURN(read_range_first_to_buf(&start_key, NULL, false, true, buf)); error= ordered_index_scan(&start_key, 0, true, buf);
DBUG_RETURN(error == HA_ERR_END_OF_FILE ? HA_ERR_KEY_NOT_FOUND : error);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment