diff options
author | unknown <monty@donna.mysql.com> | 2001-01-31 04:47:55 +0200 |
---|---|---|
committer | unknown <monty@donna.mysql.com> | 2001-01-31 04:47:55 +0200 |
commit | 3a1fad21f97434b6b5151322e430861a394ee055 (patch) | |
tree | d591bcd6697fb3a346f26cfd51f551ec4a935774 | |
parent | f2fb5b69b1a3e09ef574535e0142260620befc84 (diff) | |
parent | fc8f92ca9d70644c72c92260483c13d7d7246340 (diff) | |
download | mariadb-git-3a1fad21f97434b6b5151322e430861a394ee055.tar.gz |
Merge work:/my/mysql into donna.mysql.com:/home/my/bk/mysql
-rw-r--r-- | Docs/manual.texi | 74 | ||||
-rw-r--r-- | client/mysqladmin.c | 8 | ||||
-rw-r--r-- | include/myisam.h | 2 | ||||
-rw-r--r-- | libmysql/libmysql.c | 10 | ||||
-rw-r--r-- | myisam/mi_check.c | 10 | ||||
-rw-r--r-- | myisam/mi_delete_table.c | 3 | ||||
-rw-r--r-- | myisam/mi_key.c | 3 | ||||
-rw-r--r-- | myisam/myisamchk.c | 20 | ||||
-rw-r--r-- | mysql-test/r/case.result | 8 | ||||
-rw-r--r-- | mysql-test/r/func_time.result | 6 | ||||
-rw-r--r-- | mysql-test/r/type_blob.result | 4 | ||||
-rw-r--r-- | mysql-test/r/type_datetime.result | 2 | ||||
-rw-r--r-- | mysql-test/t/case.test | 11 | ||||
-rw-r--r-- | mysql-test/t/func_time.test | 16 | ||||
-rw-r--r-- | mysql-test/t/type_blob.test | 10 | ||||
-rw-r--r-- | mysql-test/t/type_datetime.test | 3 | ||||
-rw-r--r-- | mysys/my_bitmap.c | 65 | ||||
-rw-r--r-- | sql-bench/limits/ms-sql.cfg | 53 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 27 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 1 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 4 | ||||
-rw-r--r-- | sql/sql_db.cc | 15 | ||||
-rw-r--r-- | sql/sql_parse.cc | 50 | ||||
-rw-r--r-- | sql/table.cc | 2 |
24 files changed, 302 insertions, 105 deletions
diff --git a/Docs/manual.texi b/Docs/manual.texi index d4a4c2d0b17..52eec6213e2 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -9952,7 +9952,7 @@ for this is that negative numbers caused problems when wrapping from -1 to 0. @code{AUTO_INCREMENT} is now for MyISAM tables handled at a lower level and is much faster than before. For MyISAM tables old numbers are also not reused anymore, even if you delete some rows from the table. -@item @code{INNER}, @code{DELAYED}, @code{RIGHT}, @code{CASE}, @code{THEN}, @code{WHEN}, @code{ELSE}, @code{END} and @code{WHEN} are now reserved words. +@item @code{CASE}, @code{DELAYED}, @code{ELSE}, @code{END}, @code{FULLTEXT}, @code{INNER}, @code{RIGHT}, @code{THEN} and @code{WHEN} are now reserved words. @item @code{FLOAT(X)} is now a true floating-point type and not a value with a fixed number of decimals. @item When declaring @code{DECIMAL(length,dec)} the length argument no @@ -15814,6 +15814,10 @@ mysql> SELECT CASE BINARY "B" when "a" then 1 when "b" then 2 END; @end example @end table +The type of the return value (@code{INTEGER}, @code{DOUBLE} or +@code{STRING}) is the same as the type of the first returned value (the +expression after the first @code{THEN}). + @findex mathematical functions @findex functions, mathematical @node Mathematical functions, String functions, Control flow functions, Functions @@ -30619,11 +30623,11 @@ utility. @xref{Table types}. In the following text we will talk about @code{myisamchk}, but everything also applies to the old @code{isamchk}. -You can use the @code{myisamchk} utility to get information about your database -tables, check and repair them, or optimize them. The following sections -describe how to invoke @code{myisamchk} (including a description of its -options), how to set up a table maintenance schedule, and how to use -@code{myisamchk} to perform its various functions. +You can use the @code{myisamchk} utility to get information about your +database tables, check and repair them, or optimize them. The following +sections describe how to invoke @code{myisamchk} (including a +description of its options), how to set up a table maintenance schedule, +and how to use @code{myisamchk} to perform its various functions. You can, in most cases, also use the command @code{OPTIMIZE TABLES} to optimize and repair tables, but this is not as fast or reliable (in case @@ -30713,9 +30717,9 @@ the file or that has died without closing the file properly. If you @code{mysqld} is running, you must force a sync/close of all tables with @code{FLUSH TABLES} and ensure that no one is using the -tables while you are running @code{myisamchk}. In MySQL Version 3.23 the easiest -way to avoid this problem is to use @code{CHECK TABLE} instead of -@code{myisamchk} to check tables. +tables while you are running @code{myisamchk}. In @strong{MySQL} Version 3.23 +the easiest way to avoid this problem is to use @code{CHECK TABLE} +instead of @code{myisamchk} to check tables. @cindex options, @code{myisamchk} @cindex @code{myisamchk}, options @@ -30740,9 +30744,30 @@ for myisamchk can be examined with @code{myisamchk --help}: @item decode_bits @tab 9 @end multitable -@code{key_buffer_size} is only used when you check the table with @code{-e} or -repair it with @code{-o}. -@code{sort_buffer_size} is used when you repair the table with @code{-r}. +@code{sort_buffer_size} is used when the keys are reparied by sorting +keys, which is the normal case when you use @code{--recover}. + +@code{key_buffer_size} is used when you are checking the table with +@code{--extended-check} or when the keys are repaired by inserting key +row by row in to the table (like when doing normal inserts). Repairing +through the key buffer is used in the following cases: + +@itemize @bullet +@item +If you use @code{--safe-recover}. +@item +If you are using a @code{FULLTEXT} index. +@item +If the temporary files needed to sort the keys would be more than twice +as big as when creating the key file directly. This is often the case +when you have big @code{CHAR}, @code{VARCHAR} or @code{TEXT} keys as the +sort needs to store the whole keys during sorting. If you have lots +of temporary space and you can force @code{myisamchk} to repair by sorting +you can use the @code{--sort-recover} option. +@end itemize + +Reparing through the key buffer takes much less disk space than using +sorting, but is also much slower. If you want a faster repair, set the above variables to about 1/4 of your available memory. You can set both variables to big values, as only one @@ -30851,6 +30876,11 @@ space than @code{-r}. Normally one should always first repair with If you have lots of memory, you should increase the size of @code{key_buffer_size}! +@item -n or --sort-recover +Force @code{myisamchk} to use sorting to resolve the keys even if the +temporary files should be very big. This will not have any effect if you have +fulltext keys in the table. + @item --character-sets-dir=... Directory where character sets are stored. @item --set-character-set=name @@ -30933,8 +30963,9 @@ Space for the new index file that replaces the old one. The old index file is truncated at start, so one usually ignore this space. This space is needed on the same disk as the original index file! @item -When using @code{--repair} (but not when using @code{--safe-repair}, you -will need space for a sort buffer for: +When using @code{--recover} or @code{--sort-recover} +(but not when using @code{--safe-recover}, you will need space for a +sort buffer for: @code{(largest_key + row_pointer_length)*number_of_rows * 2}. You can check the length of the keys and the row_pointer_length with @code{myisamchk -dv table}. @@ -30943,7 +30974,7 @@ This space is allocated on the temporary disk (specified by @code{TMPDIR} or @end itemize If you have a problem with disk space during repair, you can try to use -@code{--safe-repair} instead of @code{--repair}. +@code{--safe-recover} instead of @code{--recover}. @cindex maintaining, tables @cindex tables, maintenance regimen @@ -39486,6 +39517,8 @@ javascript, 2d/3d graphics, and PHP3/MySQL. All pages are generated from a database. @c Added 990614; EMAIL: downey@image.dk (Rune Madsen) +@item @uref{http://www.softwarezrus.com/, Softwarezrus.com} +Ecommerce site that is selling computers. @end itemize @cindex consultants, list of @@ -39782,6 +39815,10 @@ OLEDB handler for @code{MySQL}. By SWsoft. Examples and documentation for MyOLEDB. By SWsoft. @item @uref{http://www.mysql.com/Downloads/Win32/Myoledb.zip, Myoledb.zip} Source for MyOLEDB. By SWsoft. +@item @uref{http://www.mysql.com/Downloads/Win32/MyOLEDB.chm, MyOLEDB.chm} +Help files for MyOLEDB. +@item @uref{http://www.mysql.com/Downloads/Win32/libmyodbc.zip, libmyodbc.zip} +Static MyODBC library used for build MyOLEDB. Based on MyODBC code. @end itemize @cindex C++ @@ -40950,6 +40987,13 @@ not yet 100 % confident in this code. @appendixsubsec Changes in release 3.23.33 @itemize bullet @item +Fixed 'no found rows' bug in @code{MyISAM} tables when a @code{BLOB} was +first part of a multi-part key. +@item +Fixed bug where @code{CASE} didn't work with @code{GROUP BY}. +@item +Added option @code{--sort-recover} to @code{myisamchk}. +@item @code{myisamchk -S} and @code{OPTIMIZE TABLE} now works on Windows. @item Fixed bug when using @code{DISTINCT} on results from functions that refered to diff --git a/client/mysqladmin.c b/client/mysqladmin.c index 2a9d47edf44..7420593591e 100644 --- a/client/mysqladmin.c +++ b/client/mysqladmin.c @@ -28,7 +28,7 @@ #include <my_pthread.h> /* because of signal() */ #endif -#define ADMIN_VERSION "8.14" +#define ADMIN_VERSION "8.15" #define MAX_MYSQL_VAR 64 #define MAX_TIME_TO_WAIT 3600 /* Wait for shutdown */ #define MAX_TRUNC_LENGTH 3 @@ -404,7 +404,11 @@ static my_bool execute_commands(MYSQL *mysql,int argc, char **argv) } sprintf(buff,"create database %.*s",FN_REFLEN,argv[1]); if (mysql_query(mysql,buff)) + { + my_printf_error(0,"Create failed; error: '%-.200s'",MYF(ME_BELL), + mysql_error(mysql)); return 1; + } else { argc--; argv++; @@ -762,7 +766,7 @@ static my_bool execute_commands(MYSQL *mysql,int argc, char **argv) mysql->reconnect=1; /* Automatic reconnect is default */ break; default: - my_printf_error(0,"Unknown command: '%s'",MYF(ME_BELL),argv[0]); + my_printf_error(0,"Unknown command: '%-.60s'",MYF(ME_BELL),argv[0]); return 1; } } diff --git a/include/myisam.h b/include/myisam.h index d198d6af80e..52a04e956aa 100644 --- a/include/myisam.h +++ b/include/myisam.h @@ -324,7 +324,7 @@ typedef struct st_mi_check_param uint testflag; uint8 language; my_bool using_global_keycache, opt_lock_memory, opt_follow_links; - my_bool retry_repair,retry_without_quick; + my_bool retry_repair,retry_without_quick, force_sort; char temp_filename[FN_REFLEN],*isam_file_name,*tmpdir; int tmpfile_createflag; myf myf_rw; diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 52c76c4043a..0d77162fc08 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -485,7 +485,7 @@ static void free_old_query(MYSQL *mysql) DBUG_VOID_RETURN; } -#ifdef HAVE_GETPWUID +#if defined(HAVE_GETPWUID) && defined(NO_GETPWUID_DECL) struct passwd *getpwuid(uid_t); char* getlogin(void); #endif @@ -501,14 +501,6 @@ static void read_user_name(char *name) #ifdef HAVE_GETPWUID struct passwd *skr; const char *str; -/*#ifdef __cplusplus - extern "C" struct passwd *getpwuid(uid_t); - extern "C" { char* getlogin(void); } -#else - char * getlogin(); - struct passwd *getpwuid(uid_t); -#endif -*/ if ((str=getlogin()) == NULL) { if ((skr=getpwuid(geteuid())) != NULL) diff --git a/myisam/mi_check.c b/myisam/mi_check.c index 467e9a9bcb4..2736e98cea9 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -1464,6 +1464,7 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name) my_off_t index_pos[MI_MAX_POSSIBLE_KEY]; uint r_locks,w_locks; MYISAM_SHARE *share=info->s; + MI_STATE_INFO old_state; DBUG_ENTER("sort_index"); if (!(param->testflag & T_SILENT)) @@ -1502,9 +1503,10 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name) /* Flush key cache for this file if we are calling this outside myisamchk */ flush_key_blocks(share->kfile, FLUSH_IGNORE_CHANGED); - /* Put same locks as old file */ share->state.version=(ulong) time((time_t*) 0); + old_state=share->state; /* save state if not stored */ r_locks=share->r_locks; w_locks=share->w_locks; + /* Put same locks as old file */ share->r_locks=share->w_locks=0; (void) _mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE); VOID(my_close(share->kfile,MYF(MY_WME))); @@ -1518,6 +1520,7 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name) _mi_readinfo(info,F_WRLCK,0); /* Will lock the table */ info->lock_type=F_WRLCK; share->r_locks=r_locks; share->w_locks=w_locks; + share->state=old_state; /* Restore old state */ info->state->key_file_length=param->new_file_pos; info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); @@ -3144,7 +3147,7 @@ void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows) */ my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows, - my_bool force __attribute__((unused))) + my_bool force) { MYISAM_SHARE *share=info->s; uint i; @@ -3160,7 +3163,8 @@ my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows, is very time-consuming process, it's better to leave it to repair stage but this repair shouldn't be repair_by_sort (serg) */ - if (mi_too_big_key_for_sort(key,rows) || (key->flag & HA_FULLTEXT)) + if (!force && mi_too_big_key_for_sort(key,rows) || + (key->flag & HA_FULLTEXT)) return FALSE; } return TRUE; diff --git a/myisam/mi_delete_table.c b/myisam/mi_delete_table.c index 360956ad110..995106160ef 100644 --- a/myisam/mi_delete_table.c +++ b/myisam/mi_delete_table.c @@ -37,7 +37,8 @@ int mi_delete_table(const char *name) #ifdef USE_RAID { MI_INFO *info; - if (!(info=mi_open(name, O_RDONLY, 0))) + /* we use 'open_for_repair' to be able to delete a crashed table */ + if (!(info=mi_open(name, O_RDONLY, HA_OPEN_FOR_REPAIR))) DBUG_RETURN(my_errno); raid_type = info->s->base.raid_type; raid_chunks = info->s->base.raid_chunks; diff --git a/myisam/mi_key.c b/myisam/mi_key.c index bf2f5c292dd..9f4e2cb1524 100644 --- a/myisam/mi_key.c +++ b/myisam/mi_key.c @@ -184,8 +184,9 @@ uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old, /* Length of key-part used with mi_rkey() always 2 */ uint tmp_length=uint2korr(pos); k_length-= 2+length; - set_if_smaller(length,tmp_length); + set_if_smaller(length,tmp_length); /* Safety */ store_key_length_inc(key,length); + old+=2; /* Skipp length */ memcpy((byte*) key, pos+2,(size_t) length); key+= length; continue; diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c index 8e794b7e708..7c86ea14c2d 100644 --- a/myisam/myisamchk.c +++ b/myisam/myisamchk.c @@ -189,6 +189,7 @@ static struct option long_options[] = {"silent", no_argument, 0, 's'}, {"sort-index", no_argument, 0, 'S'}, {"sort-records", required_argument, 0, 'R'}, + {"sort-recover", no_argument, 0, 'n'}, {"tmpdir", required_argument, 0, 't'}, {"update-state", no_argument, 0, 'U'}, {"unpack", no_argument, 0, 'u'}, @@ -200,7 +201,7 @@ static struct option long_options[] = static void print_version(void) { - printf("%s Ver 1.41 for %s at %s\n",my_progname,SYSTEM_TYPE, + printf("%s Ver 1.42 for %s at %s\n",my_progname,SYSTEM_TYPE, MACHINE_TYPE); } @@ -255,9 +256,11 @@ static void usage(void) myisamchk repairs the table a symlink points at.\n\ -r, --recover Can fix almost anything except unique keys that aren't\n\ unique.\n\ + -n, --sort-recover Force recovering with sorting even if the temporary\n\ + file would be very big.\n\ -o, --safe-recover Uses old recovery method; Slower than '-r' but can\n\ - handle a couple of cases where '-r' reports that it can't\n\ - fix the data file.\n\ + handle a couple of cases where '-r' reports that it\n\ + can't fix the data file.\n\ --character-sets-dir=...\n\ Directory where character sets are\n\ --set-character-set=name\n\ @@ -306,7 +309,8 @@ static void get_options(register int *argc,register char ***argv) set_all_changeable_vars(changeable_vars); if (isatty(fileno(stdout))) check_param.testflag|=T_WRITE_LOOP; - while ((c=getopt_long(*argc,*argv,"aBcCdeifF?lqrmosSTuUvVw#:b:D:k:O:R:A::t:", + while ((c=getopt_long(*argc,*argv, + "aBcCdeifF?lqrmnosSTuUvVw#:b:D:k:O:R:A::t:", long_options, &option_index)) != EOF) { switch(c) { @@ -374,8 +378,13 @@ static void get_options(register int *argc,register char ***argv) break; case 'o': check_param.testflag= (check_param.testflag & ~T_REP_BY_SORT) | T_REP; + check_param.force_sort=0; my_disable_async_io=1; /* More safety */ break; + case 'n': + check_param.testflag= (check_param.testflag & ~T_REP) | T_REP_BY_SORT; + check_param.force_sort=1; + break; case 'q': check_param.opt_rep_quick++; break; @@ -683,7 +692,8 @@ static int myisamchk(MI_CHECK *param, my_string filename) if ((param->testflag & T_REP_BY_SORT) && (share->state.key_map || (rep_quick && !param->keys_in_use && !recreate)) && - mi_test_if_sort_rep(info, info->state->records, 1)) + mi_test_if_sort_rep(info, info->state->records, + check_param.force_sort)) { error=mi_repair_by_sort(&check_param,info,fixed_name,rep_quick); state_updated=1; diff --git a/mysql-test/r/case.result b/mysql-test/r/case.result index 66538c2fbee..073164aa035 100644 --- a/mysql-test/r/case.result +++ b/mysql-test/r/case.result @@ -32,3 +32,11 @@ case when 1>0 then "TRUE" else "FALSE" END TRUE case when 1<0 then "TRUE" else "FALSE" END FALSE +fcase count(*) +0 2 +2 1 +3 1 +fcase count(*) +nothing 2 +one 1 +two 1 diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index 79a03bdbd48..5c55475e628 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -186,3 +186,9 @@ extract(SECOND FROM "1999-01-02 10:11:12") 12 ctime hour(ctime) 2001-01-12 12:23:40 12 +monthname(date) +NULL +January +monthname(date) +NULL +January diff --git a/mysql-test/r/type_blob.result b/mysql-test/r/type_blob.result index 0ead1c30200..bc80ba38452 100644 --- a/mysql-test/r/type_blob.result +++ b/mysql-test/r/type_blob.result @@ -257,3 +257,7 @@ hello hello word count(*) 2 +foobar boggle +fish 10 +foobar boggle +fish 10 diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result index 3a816e2ff68..7028b5ffe33 100644 --- a/mysql-test/r/type_datetime.result +++ b/mysql-test/r/type_datetime.result @@ -13,6 +13,8 @@ t 9999-12-31 23:59:59 Table Op Msg_type Msg_text test.t1 optimize status OK +Table Op Msg_type Msg_text +test.t1 check status OK t 2000-01-01 00:00:00 2069-12-31 00:00:00 diff --git a/mysql-test/t/case.test b/mysql-test/t/case.test index 9e594675c19..79511f5f546 100644 --- a/mysql-test/t/case.test +++ b/mysql-test/t/case.test @@ -2,6 +2,8 @@ # Testing of CASE # +drop table if exists t1; + select CASE "b" when "a" then 1 when "b" then 2 END; select CASE "c" when "a" then 1 when "b" then 2 END; select CASE "c" when "a" then 1 when "b" then 2 ELSE 3 END; @@ -19,3 +21,12 @@ select (case 1/0 when "a" then "true" END) | 0; select (case 1/0 when "a" then "true" END) + 0.0; select case when 1>0 then "TRUE" else "FALSE" END; select case when 1<0 then "TRUE" else "FALSE" END; + +# +# Test bug when using GROUP BY on CASE +# +create table t1 (a int); +insert into t1 values(1),(2),(3),(4); +select case a when 1 then 2 when 2 then 3 else 0 end as fcase, count(*) from t1 group by fcase; +select case a when 1 then "one" when 2 then "two" else "nothing" end as fcase, count(*) from t1 group by fcase; +drop table t1; diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index d6427d121ec..f9424ed4320 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -1,6 +1,8 @@ # # time functions # +drop table if exists t1,t2; + select from_days(to_days("960101")),to_days(960201)-to_days("19960101"),to_days(date_add(curdate(), interval 1 day))-to_days(curdate()),weekday("1997-11-29"); select period_add("9602",-12),period_diff(199505,"9404") ; select now()-now(),weekday(curdate())-weekday(now()),unix_timestamp()-unix_timestamp(now()); @@ -99,9 +101,21 @@ select extract(MINUTE FROM "10:11:12"); select extract(MINUTE_SECOND FROM "10:11:12"); select extract(SECOND FROM "1999-01-02 10:11:12"); -drop table if exists t1; create table t1 (ctime varchar(20)); insert into t1 values ('2001-01-12 12:23:40'); select ctime, hour(ctime) from t1; drop table t1; +# +# Test bug with monthname() and NULL +# + +create table t1 (id int); +create table t2 (id int, date date); +insert into t1 values (1); +insert into t2 values (1, "0000-00-00"); +insert into t1 values (2); +insert into t2 values (2, "2000-01-01"); +select monthname(date) from t1 inner join t2 on t1.id = t2.id; +select monthname(date) from t1 inner join t2 on t1.id = t2.id order by t1.id; +drop table t1,t2; diff --git a/mysql-test/t/type_blob.test b/mysql-test/t/type_blob.test index 80c7f3538dd..2b23617ec8b 100644 --- a/mysql-test/t/type_blob.test +++ b/mysql-test/t/type_blob.test @@ -239,3 +239,13 @@ INSERT INTO t1 VALUES (0,'traktor','1111111111111'); INSERT INTO t1 VALUES (1,'traktor','1111111111111111111111111'); select count(*) from t1 where f2='traktor'; drop table t1; + +# +# Test of found bug when blob is first key part +# + +create table t1 (foobar tinyblob not null, boggle smallint not null, key (foobar(32), boggle)); +insert into t1 values ('fish', 10),('bear', 20); +select foobar, boggle from t1 where foobar = 'fish'; +select foobar, boggle from t1 where foobar = 'fish' and boggle = 10; +drop table t1; diff --git a/mysql-test/t/type_datetime.test b/mysql-test/t/type_datetime.test index 36f9629b53b..1e7bd11bab1 100644 --- a/mysql-test/t/type_datetime.test +++ b/mysql-test/t/type_datetime.test @@ -1,11 +1,14 @@ # # testing different DATETIME ranges # + +drop table if exists t1; create table t1 (t datetime); insert into t1 values(101),(691231),(700101),(991231),(10000101),(99991231),(101000000),(691231000000),(700101000000),(991231235959),(10000101000000),(99991231235959); select * from t1; delete from t1 where t > 0; optimize table t1; +check table t1; insert into t1 values("000101"),("691231"),("700101"),("991231"),("00000101"),("00010101"),("99991231"),("00101000000"),("691231000000"),("700101000000"),("991231235959"),("10000101000000"),("99991231235959"); select * from t1; drop table t1; diff --git a/mysys/my_bitmap.c b/mysys/my_bitmap.c index 1434f472f98..848df42d4d4 100644 --- a/mysys/my_bitmap.c +++ b/mysys/my_bitmap.c @@ -17,6 +17,13 @@ /* Handling of uchar arrays as large bitmaps. + We assume that the size of the used bitmap is less than ~(uint) 0 + + TODO: + + create an unique structure for this that includes the mutex and bitmap size + make a init function that will allocate the bitmap and init the mutex + make an end function that will free everything */ #include "mysys_priv.h" @@ -24,37 +31,51 @@ pthread_mutex_t LOCK_bitmap; -void bitmap_set_bit(uchar *bitmap, uint bitmap_size, uint bitmap_bit) { - if((bitmap_bit != MY_BIT_NONE) && (bitmap_bit < bitmap_size*8)) { +void bitmap_set_bit(uchar *bitmap, uint bitmap_size, uint bitmap_bit) +{ + if (bitmap_bit < bitmap_size*8) + { pthread_mutex_lock(&LOCK_bitmap); - bitmap[bitmap_bit / 8] |= (1 << bitmap_bit % 8); + bitmap[bitmap_bit / 8] |= (1 << (bitmap_bit & 7)); pthread_mutex_unlock(&LOCK_bitmap); - }; -}; + } +} -uint bitmap_set_next(uchar *bitmap, uint bitmap_size) { +uint bitmap_set_next(uchar *bitmap, uint bitmap_size) +{ uint bit_found = MY_BIT_NONE; - int i, b; + uint i; pthread_mutex_lock(&LOCK_bitmap); - for(i=0; (i<bitmap_size) && (bit_found==MY_BIT_NONE); i++) { - if(bitmap[i] == 0xff) continue; - for(b=0; (b<8) && (bit_found==MY_BIT_NONE); b++) - if((bitmap[i] & 1<<b) == 0) { - bit_found = (i*8)+b; - bitmap[i] |= 1<<b; - }; - }; + for (i=0; i < bitmap_size ; i++, bitmap++) + { + if (*bitmap != 0xff) + { /* Found slot with free bit */ + uint b; + for (b=0; ; b++) + { + if (!(*bitmap & (1 << b))) + { + *bitmap |= 1<<b; + bit_found = (i*8)+b; + break; + } + } + break; /* Found bit */ + } + } pthread_mutex_unlock(&LOCK_bitmap); - return bit_found; -}; +} + -void bitmap_clear_bit(uchar *bitmap, uint bitmap_size, uint bitmap_bit) { - if((bitmap_bit != MY_BIT_NONE) && (bitmap_bit < bitmap_size*8)) { +void bitmap_clear_bit(uchar *bitmap, uint bitmap_size, uint bitmap_bit) +{ + if (bitmap_bit < bitmap_size*8) + { pthread_mutex_lock(&LOCK_bitmap); - bitmap[bitmap_bit / 8] &= ~(1 << bitmap_bit % 8); + bitmap[bitmap_bit / 8] &= ~ (1 << (bitmap_bit & 7)); pthread_mutex_unlock(&LOCK_bitmap); - }; -}; + } +} diff --git a/sql-bench/limits/ms-sql.cfg b/sql-bench/limits/ms-sql.cfg index 9307590cd40..aad17231786 100644 --- a/sql-bench/limits/ms-sql.cfg +++ b/sql-bench/limits/ms-sql.cfg @@ -1,4 +1,4 @@ -#This file is automaticly generated by crash-me 1.45 +#This file is automaticly generated by crash-me 1.54 NEG=yes # update of column= -column Need_cast_for_null=no # Need to cast NULL for arithmetic @@ -19,25 +19,25 @@ alter_modify_col=no # Alter table modify column alter_rename_table=no # Alter table rename table atomic_updates=yes # atomic updates atomic_updates_with_rollback=yes # atomic_updates_with_rollback -automatic_rowid=no # Automatic rowid +automatic_rowid=no # Automatic row id binary_numbers=yes # binary numbers (0b1001) binary_strings=no # binary strings (b'0110') -case_insensitive_strings=yes # case insensitive compare +case_insensitive_strings=yes # Case insensitive compare char_is_space_filled=no # char are space filled column_alias=yes # Column alias columns_in_group_by=+64 # number of columns in group by columns_in_order_by=+64 # number of columns in order by comment_#=no # # as comment -comment_--=yes # -- as comment +comment_--=yes # -- as comment (ANSI) comment_/**/=yes # /* */ as comment -comment_//=no # // as comment +comment_//=no # // as comment (ANSI) compute=yes # Compute connections=1000 # Simultaneous connections (installation default) constraint_check=no # Column constraints constraint_check_table=yes # Table constraints constraint_null=yes # NULL constraint (SyBase style) -crash_me_safe=no # crash me safe -crash_me_version=1.45 # crash me version +crash_me_safe=yes # crash me safe +crash_me_version=1.54 # crash me version create_default=yes # default value for column create_default_func=no # default value function for column create_if_not_exists=no # create table if not exists @@ -46,14 +46,18 @@ create_schema=yes # Create SCHEMA create_table_select=no # create table from select cross_join=yes # cross join (same as from a,b) date_as_string=no # String functions on date columns +date_infinity=no # Supports 'infinity dates date_last=no # Supports 9999-12-31 dates date_one=no # Supports 0001-01-01 dates date_with_YY=no # Supports YY-MM-DD dates date_zero=no # Supports 0000-00-00 dates domains=no # Domains (ANSI SQL) +dont_require_cast_to_float=yes # No need to cast from integer to float double_quotes=yes # Double '' as ' in strings drop_if_exists=no # drop table if exists drop_index=with 'table.index' # drop index +drop_requires_cascade=no # drop table require cascade/restrict +drop_restrict=no # drop table with cascade/restrict end_colon=yes # allows end ';' except=no # except except_all=no # except all @@ -161,6 +165,7 @@ func_extra_version=no # Function VERSION func_extra_weekday=no # Function WEEKDAY func_extra_|=yes # Function | (bitwise or) func_extra_||=no # Function OR as '||' +func_extra_~*=no # Function ~* (case insensitive compare) func_odbc_abs=yes # Function ABS func_odbc_acos=yes # Function ACOS func_odbc_ascii=yes # Function ASCII @@ -243,7 +248,8 @@ func_sql_extract_sql=no # Function EXTRACT func_sql_localtime=no # Function LOCALTIME func_sql_localtimestamp=no # Function LOCALTIMESTAMP func_sql_lower=yes # Function LOWER -func_sql_nullif=yes # Function NULLIF +func_sql_nullif_num=yes # Function NULLIF with numbers +func_sql_nullif_string=yes # Function NULLIF with strings func_sql_octet_length=no # Function OCTET_LENGTH func_sql_position=no # Function POSITION func_sql_searched_case=yes # Function searched CASE @@ -273,7 +279,7 @@ func_where_unique=no # Function UNIQUE functions=yes # Functions group_by=yes # Group by group_by_alias=no # Group by alias -group_by_null=yes # group on column with null values +group_by_null=yes # Group on column with null values group_by_position=no # Group by position group_distinct_functions=yes # Group functions with distinct group_func_extra_bit_and=no # Group function BIT_AND @@ -282,28 +288,33 @@ group_func_extra_count_distinct_list=no # Group function COUNT(DISTINCT expr,exp group_func_extra_std=no # Group function STD group_func_extra_stddev=no # Group function STDDEV group_func_extra_variance=no # Group function VARIANCE +group_func_sql_any=no # Group function ANY group_func_sql_avg=yes # Group function AVG group_func_sql_count_*=yes # Group function COUNT (*) group_func_sql_count_column=yes # Group function COUNT column name group_func_sql_count_distinct=yes # Group function COUNT(DISTINCT expr) +group_func_sql_every=no # Group function EVERY group_func_sql_max=yes # Group function MAX on numbers group_func_sql_max_str=yes # Group function MAX on strings group_func_sql_min=yes # Group function MIN on numbers group_func_sql_min_str=yes # Group function MIN on strings +group_func_sql_some=no # Group function SOME group_func_sql_sum=yes # Group function SUM group_functions=yes # Group functions +group_on_unused=yes # Group on unused column has_true_false=no # TRUE and FALSE having=yes # Having having_with_alias=no # Having on alias having_with_group=yes # Having with group function hex_numbers=yes # hex numbers (0x41) hex_strings=no # hex strings (x'1ace') -ignore_end_space=yes # ignore end space in compare +ignore_end_space=yes # Ignore end space in compare index_in_create=no # index in create table index_namespace=yes # different namespace for index index_parts=no # index on column part (extension) inner_join=yes # inner join insert_empty_string=yes # insert empty string +insert_multi_value=no # INSERT with Value lists insert_select=yes # insert INTO ... SELECT ... insert_with_set=no # INSERT with set syntax intersect=no # intersect @@ -317,12 +328,12 @@ like_with_column=yes # column LIKE column like_with_number=yes # LIKE on numbers lock_tables=no # lock table logical_value=not supported # Value of logical operation (1=1) -max_big_expressions=7 # big expressions +max_big_expressions=10 # big expressions max_char_size=8000 # max char() size max_column_name=128 # column name length max_columns=1024 # Columns in table -max_conditions=10922 # OR and AND in WHERE -max_expressions=2783 # simple expressions +max_conditions=13104 # OR and AND in WHERE +max_expressions=656 # simple expressions max_index=+64 # max index max_index_length=900 # index length max_index_name=128 # index name length @@ -345,7 +356,6 @@ multi_drop=no # many tables to drop table multi_strings=no # Multiple line strings multi_table_delete=no # DELETE FROM table1,table2... multi_table_update=no # Update with many tables -insert_multi_value=no # Value lists in INSERT natural_join=no # natural join natural_join_incompat=no # natural join (incompatible lists) natural_left_outer_join=no # natural left outer join @@ -354,6 +364,7 @@ null_concat_expr=no # Is concat('a',NULL) = NULL null_in_index=yes # null in index null_in_unique=no # null in unique index null_num_expr=yes # Is 1+NULL = NULL +nulls_in_unique=no # null combination in unique index odbc_left_outer_join=yes # left outer join odbc style operating_system=Microsoft Windows 2000 [Version 5.00.2195] # crash-me tested on order_by=yes # Order by @@ -361,6 +372,7 @@ order_by_alias=yes # Order by alias order_by_function=yes # Order by function order_by_position=yes # Order by position order_by_remember_desc=no # Order by DESC is remembered +order_on_unused=yes # Order by on unused column primary_key_in_create=yes # primary key in create table psm_functions=no # PSM functions (ANSI SQL) psm_modules=no # PSM modules (ANSI SQL) @@ -374,7 +386,7 @@ quote_with_"=no # Allows ' and " as string markers recursive_subqueries=40 # recursive subqueries remember_end_space=no # Remembers end space in char() remember_end_space_varchar=yes # Remembers end space in varchar() -repeat_string_size=8000 # return string size from function +rename_table=no # rename table right_outer_join=yes # right outer join rowid=no # Type for row id select_constants=yes # Select constants @@ -383,15 +395,16 @@ select_limit2=no # SELECT with LIMIT #,# select_string_size=16777207 # constant string size in SELECT select_table_update=yes # Update with sub select select_without_from=yes # SELECT without FROM -server_version=Microsoft SQL Server 7.00 - 7.00.842 (Intel X86) # server version +server_version=Microsoft SQL Server 2000 - 8.00.194 (Intel X86) # server version simple_joins=yes # ANSI SQL simple joins storage_of_float=round # Storage of float values subqueries=yes # subqueries table_alias=yes # Table alias table_name_case=yes # case independent table names table_wildcard=yes # Select table_name.* -tempoary_table=no # temporary tables +temporary_table=no # temporary tables transactions=yes # transactions +truncate_table=no # truncate type_extra_abstime=no # Type abstime type_extra_bfile=no # Type bfile type_extra_blob=no # Type blob @@ -399,6 +412,7 @@ type_extra_bool=no # Type bool type_extra_box=no # Type box type_extra_byte=no # Type byte type_extra_char(1_arg)_binary=no # Type char(1 arg) binary +type_extra_cidr=no # Type cidr type_extra_circle=no # Type circle type_extra_clob=no # Type clob type_extra_datetime=yes # Type datetime @@ -408,6 +422,7 @@ type_extra_float(2_arg)=no # Type float(2 arg) type_extra_float4=no # Type float4 type_extra_float8=no # Type float8 type_extra_image=yes # Type image +type_extra_inet=no # Type inet type_extra_int(1_arg)_zerofill=no # Type int(1 arg) zerofill type_extra_int1=no # Type int1 type_extra_int2=no # Type int2 @@ -424,6 +439,7 @@ type_extra_long_raw=no # Type long raw type_extra_long_varbinary=no # Type long varbinary type_extra_long_varchar(1_arg)=no # Type long varchar(1 arg) type_extra_lseg=no # Type lseg +type_extra_macaddr=no # Type macaddr type_extra_mediumint=no # Type mediumint type_extra_mediumtext=no # Type mediumtext type_extra_middleint=no # Type middleint @@ -451,7 +467,7 @@ type_extra_timespan=no # Type timespan type_extra_uint=no # Type uint type_extra_varchar2(1_arg)=no # Type varchar2(1 arg) type_extra_year=no # Type year -type_odbc_bigint=no # Type bigint +type_odbc_bigint=yes # Type bigint type_odbc_binary(1_arg)=yes # Type binary(1 arg) type_odbc_datetime=yes # Type datetime type_odbc_tinyint=yes # Type tinyint @@ -459,6 +475,7 @@ type_odbc_varbinary(1_arg)=yes # Type varbinary(1 arg) type_sql_bit=yes # Type bit type_sql_bit(1_arg)=no # Type bit(1 arg) type_sql_bit_varying(1_arg)=no # Type bit varying(1 arg) +type_sql_boolean=no # Type boolean type_sql_char(1_arg)=yes # Type char(1 arg) type_sql_char_varying(1_arg)=yes # Type char varying(1 arg) type_sql_character(1_arg)=yes # Type character(1 arg) diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 84b18201ad1..e7a6c52dfd9 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -721,17 +721,41 @@ double Item_func_case::val() bool Item_func_case::fix_fields(THD *thd,TABLE_LIST *tables) { - if (first_expr && first_expr->fix_fields(thd,tables) || else_expr && else_expr->fix_fields(thd,tables)) return 1; if (Item_func::fix_fields(thd,tables)) return 1; + if (first_expr) + { + used_tables_cache|=(first_expr)->used_tables(); + const_item_cache&= (first_expr)->const_item(); + } + if (else_expr) + { + used_tables_cache|=(else_expr)->used_tables(); + const_item_cache&= (else_expr)->const_item(); + } if (!else_expr || else_expr->maybe_null) maybe_null=1; // The result may be NULL return 0; } +void Item_func_case::update_used_tables() +{ + Item_func::update_used_tables(); + if (first_expr) + { + used_tables_cache|=(first_expr)->used_tables(); + const_item_cache&= (first_expr)->const_item(); + } + if (else_expr) + { + used_tables_cache|=(else_expr)->used_tables(); + const_item_cache&= (else_expr)->const_item(); + } +} + void Item_func_case::fix_length_and_dec() { @@ -750,6 +774,7 @@ void Item_func_case::fix_length_and_dec() } } +/* TODO: Fix this so that it prints the whole CASE expression */ void Item_func_case::print(String *str) { diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 95b2c3bf723..5ee0687c064 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -254,6 +254,7 @@ public: longlong val_int(); String *val_str(String *); void fix_length_and_dec(); + void update_used_tables(); enum Item_result result_type () const { return cached_result_type; } const char *func_name() const { return "case"; } void print(String *str); diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 49bce381901..b305b5ccec3 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -135,7 +135,11 @@ String* Item_func_monthname::val_str(String* str) { uint month=(uint) Item_func_month::val_int(); if (!month) // This is also true for NULL + { + null_value=1; return (String*) 0; + } + null_value=0; return &month_names[month-1]; } diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 25bbe75e944..3786e771ecb 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -28,6 +28,8 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *path, uint level); +/* db-name is already validated when we come here */ + void mysql_create_db(THD *thd, char *db, uint create_options) { char path[FN_REFLEN+16]; @@ -35,11 +37,6 @@ void mysql_create_db(THD *thd, char *db, uint create_options) long result=1; DBUG_ENTER("mysql_create_db"); - if (!stripp_sp(db) || check_db_name(db)) - { - net_printf(&thd->net,ER_WRONG_DB_NAME, db); - DBUG_VOID_RETURN; - } VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); /* Check directory */ @@ -96,6 +93,8 @@ static TYPELIB deletable_extentions= {array_elements(del_exts)-1,"del_exts", del_exts}; +/* db-name is already validated when we come here */ + void mysql_rm_db(THD *thd,char *db,bool if_exists) { long deleted=0; @@ -103,12 +102,6 @@ void mysql_rm_db(THD *thd,char *db,bool if_exists) MY_DIR *dirp; DBUG_ENTER("mysql_rm_db"); - if (!stripp_sp(db) || check_db_name(db)) - { - net_printf(&thd->net,ER_WRONG_DB_NAME, db); - DBUG_VOID_RETURN; - } - VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); VOID(pthread_mutex_lock(&LOCK_open)); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 2926f59547f..854a47fd9c0 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -510,7 +510,7 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd) int error = 0; DBUG_ENTER("mysql_table_dump"); db = (db && db[0]) ? db : thd->db; - if(!(table_list = (TABLE_LIST*) sql_calloc(sizeof(TABLE_LIST)))) + if (!(table_list = (TABLE_LIST*) sql_calloc(sizeof(TABLE_LIST)))) DBUG_RETURN(1); // out of memory table_list->db = db; table_list->real_name = table_list->name = tbl_name; @@ -518,9 +518,14 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd) table_list->next = 0; remove_escape(table_list->real_name); - if(!(table=open_ltable(thd, table_list, TL_READ_NO_INSERT))) + if (!(table=open_ltable(thd, table_list, TL_READ_NO_INSERT))) DBUG_RETURN(1); + if (!db || check_db_name(db)) + { + net_printf(&thd->net,ER_WRONG_DB_NAME, db ? db : "NULL"); + goto err; + } if (check_access(thd, SELECT_ACL, db, &table_list->grant.privilege)) goto err; if (grant_option && check_grant(thd, SELECT_ACL, table_list)) @@ -710,6 +715,12 @@ bool do_command(THD *thd) case COM_CREATE_DB: { char *db=thd->strdup(packet+1); + // null test to handle EOM + if (!db || !stripp_sp(db) || check_db_name(db)) + { + net_printf(&thd->net,ER_WRONG_DB_NAME, db ? db : "NULL"); + break; + } if (check_access(thd,CREATE_ACL,db,0,1)) break; mysql_log.write(thd,command,packet+1); @@ -719,6 +730,12 @@ bool do_command(THD *thd) case COM_DROP_DB: { char *db=thd->strdup(packet+1); + // null test to handle EOM + if (!db || !stripp_sp(db) || check_db_name(db)) + { + net_printf(&thd->net,ER_WRONG_DB_NAME, db ? db : "NULL"); + break; + } if (check_access(thd,DROP_ACL,db,0,1) || end_active_trans(thd)) break; mysql_log.write(thd,command,db); @@ -1503,10 +1520,10 @@ mysql_execute_command(void) goto error; /* purecov: inspected */ } remove_escape(db); // Fix escaped '_' - if (strlen(db) > NAME_LEN) + if (check_db_name(db)) { - net_printf(&thd->net,ER_WRONG_DB_NAME, db); - goto error; + net_printf(&thd->net,ER_WRONG_DB_NAME, db); + goto error; } if (check_access(thd,SELECT_ACL,db,&thd->col_access)) goto error; /* purecov: inspected */ @@ -1666,6 +1683,11 @@ mysql_execute_command(void) break; case SQLCOM_CREATE_DB: { + if (!stripp_sp(lex->name) || check_db_name(lex->name)) + { + net_printf(&thd->net,ER_WRONG_DB_NAME, lex->name); + break; + } if (check_access(thd,CREATE_ACL,lex->name,0,1)) break; mysql_create_db(thd,lex->name,lex->create_info.options); @@ -1673,6 +1695,11 @@ mysql_execute_command(void) } case SQLCOM_DROP_DB: { + if (!stripp_sp(lex->name) || check_db_name(lex->name)) + { + net_printf(&thd->net,ER_WRONG_DB_NAME, lex->name); + break; + } if (check_access(thd,DROP_ACL,lex->name,0,1) || end_active_trans(thd)) break; @@ -1887,12 +1914,6 @@ check_access(THD *thd,uint want_access,const char *db, uint *save_priv, if (db == any_db) return FALSE; // Allow select on anything - if (strlen(db) > NAME_LEN || check_db_name(db)) - { - net_printf(&thd->net,ER_WRONG_DB_NAME, db); - return TRUE; - } - if (db && (!thd->db || strcmp(db,thd->db))) db_access=acl_get(thd->host, thd->ip, (char*) &thd->remote.sin_addr, thd->priv_user, db); /* purecov: inspected */ @@ -1970,7 +1991,8 @@ static bool check_db_used(THD *thd,TABLE_LIST *tables) } -static bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *table_list) +static bool check_merge_table_access(THD *thd, char *db, + TABLE_LIST *table_list) { int error=0; if (table_list) @@ -2463,8 +2485,8 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias, DBUG_RETURN(0); // End of memory alias_str= alias ? alias->str : table->table.str; if (table->table.length > NAME_LEN || - table->db.str && table->db.length > NAME_LEN || - check_table_name(table->table.str,table->table.length)) + check_table_name(table->table.str,table->table.length) || + table->db.str && check_db_name(table->db.str)) { net_printf(&thd->net,ER_WRONG_TABLE_NAME,table->table.str); DBUG_RETURN(0); diff --git a/sql/table.cc b/sql/table.cc index 8ee6ee02d68..b6fde659cd9 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1033,7 +1033,7 @@ char *get_field(MEM_ROOT *mem, TABLE *table, uint fieldnr) bool check_db_name(const char *name) { - const char *start=end; + const char *start=name; while (*name) { #if defined(USE_MB) && defined(USE_MB_IDENT) |