summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/ndb_subquery.result42
-rw-r--r--mysql-test/t/ndb_subquery.test38
-rw-r--r--ndb/src/kernel/blocks/dbtc/DbtcMain.cpp25
-rw-r--r--sql/ha_ndbcluster.cc44
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);
}