diff --git a/bdb/dist/RELEASE b/bdb/dist/RELEASE index 20b648efa04..61151b8589c 100644 --- a/bdb/dist/RELEASE +++ b/bdb/dist/RELEASE @@ -16,7 +16,7 @@ DB_VERSION_STRING="Sleepycat Software: Berkeley DB $DB_VERSION: ($DB_RELEASE_DAT # bitkeeper doesn't like somebody to mess with permissions! chmod() { - #echo "chmod $1 $2" + echo "chmod $1 $2" >/dev/null } # useful trick to find auto-generated files diff --git a/bdb/dist/s_all b/bdb/dist/s_all index c0e3ac72f3a..51c9afabcae 100644 --- a/bdb/dist/s_all +++ b/bdb/dist/s_all @@ -1,7 +1,22 @@ #!/bin/sh - # $Id: s_all,v 1.10 2001/08/04 14:01:44 bostic Exp $ -sh s_perm # permissions. +make_dir() +{ + if test ! -d $1; then + echo "mkdir $1" + mkdir $1 + status=$? + if test $status -ne 0 && test ! -d $1; then + echo "error: $status" + fi + fi +} + +make_dir ../test_server +make_dir ../dbinc_auto + +#sh s_perm # permissions. sh s_symlink # symbolic links. sh s_readme # db/README file. diff --git a/heap/hp_create.c b/heap/hp_create.c index 6c38d54cb12..40b8202d94f 100644 --- a/heap/hp_create.c +++ b/heap/hp_create.c @@ -55,6 +55,22 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef, if (keyinfo->algorithm == HA_KEY_ALG_BTREE) keyinfo->rb_tree.size_of_element++; } + switch (keyinfo->seg[j].type) { + case HA_KEYTYPE_SHORT_INT: + case HA_KEYTYPE_LONG_INT: + case HA_KEYTYPE_FLOAT: + case HA_KEYTYPE_DOUBLE: + case HA_KEYTYPE_USHORT_INT: + case HA_KEYTYPE_ULONG_INT: + case HA_KEYTYPE_LONGLONG: + case HA_KEYTYPE_ULONGLONG: + case HA_KEYTYPE_INT24: + case HA_KEYTYPE_UINT24: + case HA_KEYTYPE_INT8: + keyinfo->seg[j].flag|= HA_SWAP_KEY; + default: + break; + } } keyinfo->length= length; length+= keyinfo->rb_tree.size_of_element + diff --git a/heap/hp_hash.c b/heap/hp_hash.c index 946659621fe..cd70d2ab532 100644 --- a/heap/hp_hash.c +++ b/heap/hp_hash.c @@ -443,6 +443,43 @@ uint hp_rb_make_key(HP_KEYDEF *keydef, byte *key, if (!(*key++= 1 - test(rec[seg->null_pos] & seg->null_bit))) continue; } + if (seg->flag & HA_SWAP_KEY) + { + uint length= seg->length; + byte *pos= (byte*) rec + seg->start; + +#ifdef HAVE_ISNAN + if (seg->type == HA_KEYTYPE_FLOAT) + { + float nr; + float4get(nr, pos); + if (isnan(nr)) + { + /* Replace NAN with zero */ + bzero(key, length); + key+= length; + continue; + } + } + else if (seg->type == HA_KEYTYPE_DOUBLE) + { + double nr; + float8get(nr, pos); + if (isnan(nr)) + { + bzero(key, length); + key+= length; + continue; + } + } +#endif + pos+= length; + while (length--) + { + *key++= *--pos; + } + continue; + } memcpy(key, rec + seg->start, (size_t) seg->length); key+= seg->length; } @@ -467,6 +504,18 @@ uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old, uint k_len) continue; } } + if (seg->flag & HA_SWAP_KEY) + { + uint length= seg->length; + byte *pos= (byte*) old + length; + + k_len-= length; + while (length--) + { + *key++= *--pos; + } + continue; + } memcpy((byte*) key, old, seg->length); key+= seg->length; k_len-= seg->length; diff --git a/include/.my_sys.h.swp b/include/.my_sys.h.swp deleted file mode 100644 index e9d01f0e65d..00000000000 Binary files a/include/.my_sys.h.swp and /dev/null differ diff --git a/include/Makefile.am b/include/Makefile.am index 2df8b46d369..c88e1ee1e40 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -20,7 +20,7 @@ pkginclude_HEADERS = dbug.h m_string.h my_sys.h my_list.h \ mysql.h mysql_com.h mysqld_error.h mysql_embed.h \ my_semaphore.h my_pthread.h my_no_pthread.h raid.h \ errmsg.h my_global.h my_net.h my_alloc.h \ - my_getopt.h sslopt-longopts.h \ + my_getopt.h sslopt-longopts.h typelib.h \ sslopt-vars.h sslopt-case.h $(BUILT_SOURCES) noinst_HEADERS = config-win.h config-os2.h \ nisam.h heap.h merge.h my_bitmap.h\ diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index cc1780a12d0..49a42872fa3 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -158,3 +158,6 @@ select * from t1; if('2002'='2002','Y','N') Y drop table if exists t1; +create table t1 (a int, key(a)); +create table t2 (b int, foreign key(b) references t1(a), key(b)); +drop table if exists t1,t2; diff --git a/mysql-test/r/derived.result b/mysql-test/r/derived.result index 0290d0755d5..204ca86f306 100644 --- a/mysql-test/r/derived.result +++ b/mysql-test/r/derived.result @@ -40,3 +40,28 @@ a select 1 from (select 1); 1 1 +drop table if exists t1; +create table t1(a int not null, t char(8), index(a)); +SELECT * FROM (SELECT * FROM t1) ORDER BY a ASC LIMIT 0,20; +a t +1 1 +2 2 +3 3 +4 4 +5 5 +6 6 +7 7 +8 8 +9 9 +10 10 +11 11 +12 12 +13 13 +14 14 +15 15 +16 16 +17 17 +18 18 +19 19 +20 20 +drop table if exists t1; diff --git a/mysql-test/r/select_found.result b/mysql-test/r/select_found.result index 1c2cd7da894..a48e1e16d37 100644 --- a/mysql-test/r/select_found.result +++ b/mysql-test/r/select_found.result @@ -168,4 +168,19 @@ test2 2 2 SELECT FOUND_ROWS(); FOUND_ROWS() 2 +SELECT SQL_CALC_FOUND_ROWS 1 FROM (SELECT 1) LIMIT 0; +1 +SELECT FOUND_ROWS(); +FOUND_ROWS() +1 +SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE numeropost > 1 LIMIT 0; +titre numeropost maxnumrep +SELECT FOUND_ROWS(); +FOUND_ROWS() +2 +SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 0; +titre numeropost maxnumrep +SELECT FOUND_ROWS(); +FOUND_ROWS() +3 drop table t1; diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index d3b9e1320f3..72ed01d4bab 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -269,3 +269,23 @@ INSERT INTO iftest VALUES (); SELECT field FROM iftest WHERE 1=(SELECT 1 UNION ALL SELECT 1 FROM (SELECT 1) HAVING field='b'); Subselect returns more than 1 record drop table iftest; +drop table if exists threadhardwarefr7; +CREATE TABLE `threadhardwarefr7` ( +`numeropost` mediumint(8) unsigned NOT NULL default '0', +`numreponse` int(10) unsigned NOT NULL auto_increment, +`pseudo` varchar(35) NOT NULL default '', +PRIMARY KEY (`numeropost`,`numreponse`), +UNIQUE KEY `numreponse` (`numreponse`), +KEY `pseudo` (`pseudo`,`numeropost`) +) TYPE=MyISAM; +INSERT INTO threadhardwarefr7 (numeropost,numreponse,pseudo) VALUES (1,1,'joce'),(1,2,'joce'),(1,3,'test'); +EXPLAIN SELECT numreponse FROM threadhardwarefr7 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM threadhardwarefr7 WHERE numeropost='1'); +Subselect returns more than 1 record +EXPLAIN SELECT MAX(numreponse) FROM threadhardwarefr7 WHERE numeropost='1'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE Select tables optimized away +EXPLAIN SELECT numreponse FROM threadhardwarefr7 WHERE numeropost='1' AND numreponse=(SELECT MAX(numreponse) FROM threadhardwarefr7 WHERE numeropost='1'); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY threadhardwarefr7 const PRIMARY,numreponse PRIMARY 7 const,const 1 +2 SUBSELECT Select tables optimized away +drop table if exists threadhardwarefrtest7; diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index 65be9683061..3bad053875c 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -110,3 +110,6 @@ drop table t1; create table t1 select if('2002'='2002','Y','N'); select * from t1; drop table if exists t1; +create table t1 (a int, key(a)); +create table t2 (b int, foreign key(b) references t1(a), key(b)); +drop table if exists t1,t2; diff --git a/mysql-test/t/derived.test b/mysql-test/t/derived.test index 501d4db26fa..de765a0e280 100644 --- a/mysql-test/t/derived.test +++ b/mysql-test/t/derived.test @@ -22,3 +22,15 @@ drop table if exists t1.t2,t3; select * from (select 1); select a from (select 1 as a); select 1 from (select 1); +drop table if exists t1; +create table t1(a int not null, t char(8), index(a)); +disable_query_log; +let $1 = 10000; +while ($1) + { + eval insert into t1 values ($1,'$1'); + dec $1; + } +enable_query_log; +SELECT * FROM (SELECT * FROM t1) ORDER BY a ASC LIMIT 0,20; +drop table if exists t1; \ No newline at end of file diff --git a/mysql-test/t/select_found.test b/mysql-test/t/select_found.test index 0a483c860cb..b380c86d2db 100644 --- a/mysql-test/t/select_found.test +++ b/mysql-test/t/select_found.test @@ -84,4 +84,10 @@ INSERT INTO t1 (titre,maxnumrep) VALUES ('test1','1'),('test2','2'),('test3','3'); SELECT SQL_CALC_FOUND_ROWS titre,numeropost,maxnumrep FROM t1 WHERE numeropost IN (1,2) ORDER BY maxnumrep DESC LIMIT 0, 1; SELECT FOUND_ROWS(); +SELECT SQL_CALC_FOUND_ROWS 1 FROM (SELECT 1) LIMIT 0; +SELECT FOUND_ROWS(); +SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE numeropost > 1 LIMIT 0; +SELECT FOUND_ROWS(); +SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 0; +SELECT FOUND_ROWS(); drop table t1; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 63f689d2608..7a507be4ed2 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -166,3 +166,19 @@ INSERT INTO iftest VALUES (); -- error 1240 SELECT field FROM iftest WHERE 1=(SELECT 1 UNION ALL SELECT 1 FROM (SELECT 1) HAVING field='b'); drop table iftest; + +drop table if exists threadhardwarefr7; +CREATE TABLE `threadhardwarefr7` ( + `numeropost` mediumint(8) unsigned NOT NULL default '0', + `numreponse` int(10) unsigned NOT NULL auto_increment, + `pseudo` varchar(35) NOT NULL default '', + PRIMARY KEY (`numeropost`,`numreponse`), + UNIQUE KEY `numreponse` (`numreponse`), + KEY `pseudo` (`pseudo`,`numeropost`) +) TYPE=MyISAM; +INSERT INTO threadhardwarefr7 (numeropost,numreponse,pseudo) VALUES (1,1,'joce'),(1,2,'joce'),(1,3,'test'); +-- error 1240 +EXPLAIN SELECT numreponse FROM threadhardwarefr7 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM threadhardwarefr7 WHERE numeropost='1'); +EXPLAIN SELECT MAX(numreponse) FROM threadhardwarefr7 WHERE numeropost='1'; +EXPLAIN SELECT numreponse FROM threadhardwarefr7 WHERE numeropost='1' AND numreponse=(SELECT MAX(numreponse) FROM threadhardwarefr7 WHERE numeropost='1'); +drop table if exists threadhardwarefrtest7; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index e6acab6a244..996c70a0305 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -881,8 +881,9 @@ bool select_singleval_subselect::send_data(List &items) { DBUG_ENTER("select_singleval_subselect::send_data"); Item_singleval_subselect *it= (Item_singleval_subselect *)item; - if (it->assigned()){ - my_message(ER_SUBSELECT_NO_1_ROW, ER(ER_SUBSELECT_NO_1_ROW), MYF(0)); + if (it->assigned()) + { + my_message(ER_SUBSELECT_NO_1_ROW, ER(ER_SUBSELECT_NO_1_ROW), MYF(0)); DBUG_RETURN(1); } if (unit->offset_limit_cnt) diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 64945fa2d4d..2d869fdda49 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -35,13 +35,13 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order, SQL_SELECT *select=0; READ_RECORD info; bool using_limit=limit != HA_POS_ERROR; - bool using_transactions; + bool using_transactions, safe_update; ha_rows deleted; DBUG_ENTER("mysql_delete"); if (!table_list->db) table_list->db=thd->db; - if ((thd->options & OPTION_SAFE_UPDATES) && !conds) + if (((safe_update=thd->options & OPTION_SAFE_UPDATES)) && !conds) { send_error(thd,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE); DBUG_RETURN(1); @@ -58,7 +58,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order, /* Test if the user wants to delete all rows */ if (!using_limit && (!conds || conds->const_item()) && - !(specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE))) + !(specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE)) && !safe_update) { deleted= table->file->records; if (!(error=table->file->delete_all_rows())) @@ -79,9 +79,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order, select=make_select(table,0,0,conds,&error); if (error) DBUG_RETURN(-1); - if ((select && select->check_quick(test(thd->options & OPTION_SAFE_UPDATES), - limit)) || - !limit) + if ((select && select->check_quick(safe_update, limit)) || !limit) { delete select; send_ok(thd,0L); @@ -92,7 +90,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order, if (!table->quick_keys) { thd->lex.select_lex.options|=QUERY_NO_INDEX_USED; - if ((thd->options & OPTION_SAFE_UPDATES) && limit == HA_POS_ERROR) + if (safe_update && !using_limit) { delete select; send_error(thd,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE); diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 56636f299a7..b3d2b1602d0 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -119,7 +119,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t) table->tmp_table=TMP_TABLE; if (!lex->describe) sl->exclude(); - t->db=""; + t->db=(char *)""; t->derived=(SELECT_LEX *)0; // just in case ... } } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index a3672e47d42..abaa7cd7a68 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -324,6 +324,7 @@ JOIN::prepare(TABLE_LIST *tables_init, this->group= group_list != 0; row_limit= ((select_distinct || order || group_list) ? HA_POS_ERROR : unit->select_limit_cnt); + do_send_rows = (row_limit) ? 1 : 0; this->unit= unit; #ifdef RESTRICTED_GROUP @@ -371,14 +372,18 @@ JOIN::optimize() } #endif - conds=optimize_cond(conds,&cond_value); - if (thd->fatal_error || thd->net.report_error) + conds= optimize_cond(conds,&cond_value); + if (thd->fatal_error) { + // quick abort delete procedure; - error = 0; + error= 0; DBUG_RETURN(1); - } - if (cond_value == Item::COND_FALSE || !unit->select_limit_cnt) + } else if (thd->net.report_error) + // normal error processing & cleanup + DBUG_RETURN(-1); + + if (cond_value == Item::COND_FALSE || (!unit->select_limit_cnt && !(select_options & OPTION_FOUND_ROWS))) { /* Impossible cond */ zero_result_cause= "Impossible WHERE"; DBUG_RETURN(0); @@ -395,13 +400,7 @@ JOIN::optimize() zero_result_cause= "No matching min/max row"; DBUG_RETURN(0); } - if (select_options & SELECT_DESCRIBE) - { - select_describe(this, false, false, false, - "Select tables optimized away"); - delete procedure; - DBUG_RETURN(1); - } + zero_result_cause= "Select tables optimized away"; tables_list= 0; // All tables resolved } } @@ -663,7 +662,8 @@ JOIN::exec() { // Only test of functions error=0; if (select_options & SELECT_DESCRIBE) - select_describe(this, false, false, false, "No tables used"); + select_describe(this, false, false, false, + (zero_result_cause?zero_result_cause:"No tables used")); else { result->send_fields(fields_list,1); @@ -672,7 +672,10 @@ JOIN::exec() if (do_send_rows && result->send_data(fields_list)) error= 1; else + { error= (int) result->send_eof(); + send_records=1; + } } else error=(int) result->send_eof(); @@ -2613,8 +2616,8 @@ make_simple_join(JOIN *join,TABLE *tmp_table) join->sum_funcs=0; join->send_records=(ha_rows) 0; join->group=0; - join->do_send_rows = 1; join->row_limit=join->unit->select_limit_cnt; + join->do_send_rows = (join->row_limit) ? 1 : 0; join_tab->cache.buff=0; /* No cacheing */ join_tab->table=tmp_table; @@ -7527,8 +7530,8 @@ int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result) break; } - if (res > 0) - res= -res; // mysql_explain_select do not report error + if (res > 0 || thd->net.report_error) + res= -1; // mysql_explain_select do not report error DBUG_RETURN(res); } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 5187351258e..abb4cf8d3f9 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -523,19 +523,19 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, key_iterator.rewind(); key_number=0; - for (; (key=key_iterator++) ; key_info++, key_number++) + for (; (key=key_iterator++) ; key_number++) { uint key_length=0; key_part_spec *column; switch(key->type){ - case Key::MULTIPLE: + case Key::MULTIPLE: key_info->flags = 0; break; - case Key::FULLTEXT: + case Key::FULLTEXT: key_info->flags = HA_FULLTEXT; break; - case Key::SPATIAL: + case Key::SPATIAL: key_info->flags = HA_SPATIAL; break; case Key::FOREIGN_KEY: @@ -734,6 +734,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, my_error(ER_TOO_LONG_KEY,MYF(0),max_key_length); DBUG_RETURN(-1); } + key_info++; } if (!unique_key && !primary_key && (file->table_flags() & HA_REQUIRE_PRIMARY_KEY))