diff --git a/mysql-test/r/ndb_subquery.result b/mysql-test/r/ndb_subquery.result new file mode 100644 index 00000000000..f65f09b71b3 --- /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) order by p; +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) order by p; +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) order by p; +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) order by p; +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..cebc1920eaa --- /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) order by p; + +# 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) order by p; + +# 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) order by p; + +# 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) order by p; + +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..d270c6acc61 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() @@ -11359,6 +11367,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 +11426,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 +11441,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/ndb/test/run-test/atrt-mysql-test-run b/ndb/test/run-test/atrt-mysql-test-run index 7657140d0fa..dd7b709bd06 100755 --- a/ndb/test/run-test/atrt-mysql-test-run +++ b/ndb/test/run-test/atrt-mysql-test-run @@ -3,7 +3,7 @@ set -x p=`pwd` cd $MYSQL_BASE_DIR/mysql-test -./mysql-test-run --with-ndbcluster --ndbconnectstring=$NDB_CONNECTSTRING $* | tee $p/output.txt +./mysql-test-run --with-ndbcluster --ndb-connectstring=$NDB_CONNECTSTRING $* | tee $p/output.txt f=`grep -c fail $p/output.txt` o=`grep -c pass $p/output.txt` 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); } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 5e40398574b..5242eca2521 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -963,7 +963,7 @@ void clean_up(bool print_message) if (print_message && errmesg) sql_print_information(ER(ER_SHUTDOWN_COMPLETE),my_progname); -#if !defined(__WIN__) && !defined(EMBEDDED_LIBRARY) +#if !defined(EMBEDDED_LIBRARY) if (!opt_bootstrap) (void) my_delete(pidfile_name,MYF(0)); // This may not always exist #endif @@ -1500,7 +1500,11 @@ static void init_signals(void) } static void start_signal_handler(void) -{} +{ + // Save vm id of this process + if (!opt_bootstrap) + create_pid_file(); +} static void check_data_home(const char *path) {} @@ -2934,10 +2938,10 @@ we force server id to 2, but this MySQL server will not act as a slave."); #ifndef __NETWARE__ (void) pthread_kill(signal_thread, MYSQL_KILL_SIGNAL); #endif /* __NETWARE__ */ -#ifndef __WIN__ + if (!opt_bootstrap) (void) my_delete(pidfile_name,MYF(MY_WME)); // Not needed anymore -#endif + if (unix_sock != INVALID_SOCKET) unlink(mysqld_unix_port); exit(1);