Commit 50c4cc1f authored by unknown's avatar unknown

Merge work:/my/mysql into donna.mysql.com:/home/my/bk/mysql

parents f9339b35 495231ea
...@@ -9952,7 +9952,7 @@ for this is that negative numbers caused problems when wrapping from -1 to 0. ...@@ -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 @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 is much faster than before. For MyISAM tables old numbers are also not reused
anymore, even if you delete some rows from the table. 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 @item @code{FLOAT(X)} is now a true floating-point type and not a value with
a fixed number of decimals. a fixed number of decimals.
@item When declaring @code{DECIMAL(length,dec)} the length argument no @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; ...@@ -15814,6 +15814,10 @@ mysql> SELECT CASE BINARY "B" when "a" then 1 when "b" then 2 END;
@end example @end example
@end table @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 mathematical functions
@findex functions, mathematical @findex functions, mathematical
@node Mathematical functions, String functions, Control flow functions, Functions @node Mathematical functions, String functions, Control flow functions, Functions
...@@ -30619,11 +30623,11 @@ utility. @xref{Table types}. ...@@ -30619,11 +30623,11 @@ utility. @xref{Table types}.
In the following text we will talk about @code{myisamchk}, but everything In the following text we will talk about @code{myisamchk}, but everything
also applies to the old @code{isamchk}. also applies to the old @code{isamchk}.
You can use the @code{myisamchk} utility to get information about your database You can use the @code{myisamchk} utility to get information about your
tables, check and repair them, or optimize them. The following sections database tables, check and repair them, or optimize them. The following
describe how to invoke @code{myisamchk} (including a description of its sections describe how to invoke @code{myisamchk} (including a
options), how to set up a table maintenance schedule, and how to use description of its options), how to set up a table maintenance schedule,
@code{myisamchk} to perform its various functions. and how to use @code{myisamchk} to perform its various functions.
You can, in most cases, also use the command @code{OPTIMIZE TABLES} to 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 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. ...@@ -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 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 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 tables while you are running @code{myisamchk}. In @strong{MySQL} Version 3.23
way to avoid this problem is to use @code{CHECK TABLE} instead of the easiest way to avoid this problem is to use @code{CHECK TABLE}
@code{myisamchk} to check tables. instead of @code{myisamchk} to check tables.
@cindex options, @code{myisamchk} @cindex options, @code{myisamchk}
@cindex @code{myisamchk}, options @cindex @code{myisamchk}, options
...@@ -30740,9 +30744,30 @@ for myisamchk can be examined with @code{myisamchk --help}: ...@@ -30740,9 +30744,30 @@ for myisamchk can be examined with @code{myisamchk --help}:
@item decode_bits @tab 9 @item decode_bits @tab 9
@end multitable @end multitable
@code{key_buffer_size} is only used when you check the table with @code{-e} or @code{sort_buffer_size} is used when the keys are reparied by sorting
repair it with @code{-o}. keys, which is the normal case when you use @code{--recover}.
@code{sort_buffer_size} is used when you repair the table with @code{-r}.
@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 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 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 ...@@ -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 If you have lots of memory, you should increase the size of
@code{key_buffer_size}! @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=... @item --character-sets-dir=...
Directory where character sets are stored. Directory where character sets are stored.
@item --set-character-set=name @item --set-character-set=name
...@@ -30933,8 +30963,9 @@ Space for the new index file that replaces the old one. The old ...@@ -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. 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! This space is needed on the same disk as the original index file!
@item @item
When using @code{--repair} (but not when using @code{--safe-repair}, you When using @code{--recover} or @code{--sort-recover}
will need space for a sort buffer for: (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}. @code{(largest_key + row_pointer_length)*number_of_rows * 2}.
You can check the length of the keys and the row_pointer_length with You can check the length of the keys and the row_pointer_length with
@code{myisamchk -dv table}. @code{myisamchk -dv table}.
...@@ -30943,7 +30974,7 @@ This space is allocated on the temporary disk (specified by @code{TMPDIR} or ...@@ -30943,7 +30974,7 @@ This space is allocated on the temporary disk (specified by @code{TMPDIR} or
@end itemize @end itemize
If you have a problem with disk space during repair, you can try to use 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 maintaining, tables
@cindex tables, maintenance regimen @cindex tables, maintenance regimen
...@@ -39486,6 +39517,8 @@ javascript, 2d/3d graphics, and PHP3/MySQL. All pages are generated from ...@@ -39486,6 +39517,8 @@ javascript, 2d/3d graphics, and PHP3/MySQL. All pages are generated from
a database. a database.
@c Added 990614; EMAIL: downey@image.dk (Rune Madsen) @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 @end itemize
@cindex consultants, list of @cindex consultants, list of
...@@ -39782,6 +39815,10 @@ OLEDB handler for @code{MySQL}. By SWsoft. ...@@ -39782,6 +39815,10 @@ OLEDB handler for @code{MySQL}. By SWsoft.
Examples and documentation for MyOLEDB. By SWsoft. Examples and documentation for MyOLEDB. By SWsoft.
@item @uref{http://www.mysql.com/Downloads/Win32/Myoledb.zip, Myoledb.zip} @item @uref{http://www.mysql.com/Downloads/Win32/Myoledb.zip, Myoledb.zip}
Source for MyOLEDB. By SWsoft. 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 @end itemize
@cindex C++ @cindex C++
...@@ -40950,6 +40987,13 @@ not yet 100 % confident in this code. ...@@ -40950,6 +40987,13 @@ not yet 100 % confident in this code.
@appendixsubsec Changes in release 3.23.33 @appendixsubsec Changes in release 3.23.33
@itemize bullet @itemize bullet
@item @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. @code{myisamchk -S} and @code{OPTIMIZE TABLE} now works on Windows.
@item @item
Fixed bug when using @code{DISTINCT} on results from functions that refered to Fixed bug when using @code{DISTINCT} on results from functions that refered to
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
#include <my_pthread.h> /* because of signal() */ #include <my_pthread.h> /* because of signal() */
#endif #endif
#define ADMIN_VERSION "8.14" #define ADMIN_VERSION "8.15"
#define MAX_MYSQL_VAR 64 #define MAX_MYSQL_VAR 64
#define MAX_TIME_TO_WAIT 3600 /* Wait for shutdown */ #define MAX_TIME_TO_WAIT 3600 /* Wait for shutdown */
#define MAX_TRUNC_LENGTH 3 #define MAX_TRUNC_LENGTH 3
...@@ -404,7 +404,11 @@ static my_bool execute_commands(MYSQL *mysql,int argc, char **argv) ...@@ -404,7 +404,11 @@ static my_bool execute_commands(MYSQL *mysql,int argc, char **argv)
} }
sprintf(buff,"create database %.*s",FN_REFLEN,argv[1]); sprintf(buff,"create database %.*s",FN_REFLEN,argv[1]);
if (mysql_query(mysql,buff)) if (mysql_query(mysql,buff))
{
my_printf_error(0,"Create failed; error: '%-.200s'",MYF(ME_BELL),
mysql_error(mysql));
return 1; return 1;
}
else else
{ {
argc--; argv++; argc--; argv++;
...@@ -762,7 +766,7 @@ static my_bool execute_commands(MYSQL *mysql,int argc, char **argv) ...@@ -762,7 +766,7 @@ static my_bool execute_commands(MYSQL *mysql,int argc, char **argv)
mysql->reconnect=1; /* Automatic reconnect is default */ mysql->reconnect=1; /* Automatic reconnect is default */
break; break;
default: 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; return 1;
} }
} }
......
...@@ -324,7 +324,7 @@ typedef struct st_mi_check_param ...@@ -324,7 +324,7 @@ typedef struct st_mi_check_param
uint testflag; uint testflag;
uint8 language; uint8 language;
my_bool using_global_keycache, opt_lock_memory, opt_follow_links; 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; char temp_filename[FN_REFLEN],*isam_file_name,*tmpdir;
int tmpfile_createflag; int tmpfile_createflag;
myf myf_rw; myf myf_rw;
......
...@@ -485,7 +485,7 @@ static void free_old_query(MYSQL *mysql) ...@@ -485,7 +485,7 @@ static void free_old_query(MYSQL *mysql)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
#ifdef HAVE_GETPWUID #if defined(HAVE_GETPWUID) && defined(NO_GETPWUID_DECL)
struct passwd *getpwuid(uid_t); struct passwd *getpwuid(uid_t);
char* getlogin(void); char* getlogin(void);
#endif #endif
...@@ -501,14 +501,6 @@ static void read_user_name(char *name) ...@@ -501,14 +501,6 @@ static void read_user_name(char *name)
#ifdef HAVE_GETPWUID #ifdef HAVE_GETPWUID
struct passwd *skr; struct passwd *skr;
const char *str; 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 ((str=getlogin()) == NULL)
{ {
if ((skr=getpwuid(geteuid())) != NULL) if ((skr=getpwuid(geteuid())) != NULL)
......
...@@ -1464,6 +1464,7 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name) ...@@ -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]; my_off_t index_pos[MI_MAX_POSSIBLE_KEY];
uint r_locks,w_locks; uint r_locks,w_locks;
MYISAM_SHARE *share=info->s; MYISAM_SHARE *share=info->s;
MI_STATE_INFO old_state;
DBUG_ENTER("sort_index"); DBUG_ENTER("sort_index");
if (!(param->testflag & T_SILENT)) if (!(param->testflag & T_SILENT))
...@@ -1502,9 +1503,10 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name) ...@@ -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 cache for this file if we are calling this outside myisamchk */
flush_key_blocks(share->kfile, FLUSH_IGNORE_CHANGED); flush_key_blocks(share->kfile, FLUSH_IGNORE_CHANGED);
/* Put same locks as old file */
share->state.version=(ulong) time((time_t*) 0); 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; r_locks=share->r_locks; w_locks=share->w_locks;
/* Put same locks as old file */
share->r_locks=share->w_locks=0; share->r_locks=share->w_locks=0;
(void) _mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE); (void) _mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE);
VOID(my_close(share->kfile,MYF(MY_WME))); 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) ...@@ -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 */ _mi_readinfo(info,F_WRLCK,0); /* Will lock the table */
info->lock_type=F_WRLCK; info->lock_type=F_WRLCK;
share->r_locks=r_locks; share->w_locks=w_locks; 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->state->key_file_length=param->new_file_pos;
info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); 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) ...@@ -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 mi_test_if_sort_rep(MI_INFO *info, ha_rows rows,
my_bool force __attribute__((unused))) my_bool force)
{ {
MYISAM_SHARE *share=info->s; MYISAM_SHARE *share=info->s;
uint i; uint i;
...@@ -3160,7 +3163,8 @@ my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows, ...@@ -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 is very time-consuming process, it's better to leave it to repair stage
but this repair shouldn't be repair_by_sort (serg) 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 FALSE;
} }
return TRUE; return TRUE;
......
...@@ -37,7 +37,8 @@ int mi_delete_table(const char *name) ...@@ -37,7 +37,8 @@ int mi_delete_table(const char *name)
#ifdef USE_RAID #ifdef USE_RAID
{ {
MI_INFO *info; 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); DBUG_RETURN(my_errno);
raid_type = info->s->base.raid_type; raid_type = info->s->base.raid_type;
raid_chunks = info->s->base.raid_chunks; raid_chunks = info->s->base.raid_chunks;
......
...@@ -184,8 +184,9 @@ uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old, ...@@ -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 */ /* Length of key-part used with mi_rkey() always 2 */
uint tmp_length=uint2korr(pos); uint tmp_length=uint2korr(pos);
k_length-= 2+length; k_length-= 2+length;
set_if_smaller(length,tmp_length); set_if_smaller(length,tmp_length); /* Safety */
store_key_length_inc(key,length); store_key_length_inc(key,length);
old+=2; /* Skipp length */
memcpy((byte*) key, pos+2,(size_t) length); memcpy((byte*) key, pos+2,(size_t) length);
key+= length; key+= length;
continue; continue;
......
...@@ -189,6 +189,7 @@ static struct option long_options[] = ...@@ -189,6 +189,7 @@ static struct option long_options[] =
{"silent", no_argument, 0, 's'}, {"silent", no_argument, 0, 's'},
{"sort-index", no_argument, 0, 'S'}, {"sort-index", no_argument, 0, 'S'},
{"sort-records", required_argument, 0, 'R'}, {"sort-records", required_argument, 0, 'R'},
{"sort-recover", no_argument, 0, 'n'},
{"tmpdir", required_argument, 0, 't'}, {"tmpdir", required_argument, 0, 't'},
{"update-state", no_argument, 0, 'U'}, {"update-state", no_argument, 0, 'U'},
{"unpack", no_argument, 0, 'u'}, {"unpack", no_argument, 0, 'u'},
...@@ -200,7 +201,7 @@ static struct option long_options[] = ...@@ -200,7 +201,7 @@ static struct option long_options[] =
static void print_version(void) 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); MACHINE_TYPE);
} }
...@@ -255,9 +256,11 @@ static void usage(void) ...@@ -255,9 +256,11 @@ static void usage(void)
myisamchk repairs the table a symlink points at.\n\ myisamchk repairs the table a symlink points at.\n\
-r, --recover Can fix almost anything except unique keys that aren't\n\ -r, --recover Can fix almost anything except unique keys that aren't\n\
unique.\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\ -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\ handle a couple of cases where '-r' reports that it\n\
fix the data file.\n\ can't fix the data file.\n\
--character-sets-dir=...\n\ --character-sets-dir=...\n\
Directory where character sets are\n\ Directory where character sets are\n\
--set-character-set=name\n\ --set-character-set=name\n\
...@@ -306,7 +309,8 @@ static void get_options(register int *argc,register char ***argv) ...@@ -306,7 +309,8 @@ static void get_options(register int *argc,register char ***argv)
set_all_changeable_vars(changeable_vars); set_all_changeable_vars(changeable_vars);
if (isatty(fileno(stdout))) if (isatty(fileno(stdout)))
check_param.testflag|=T_WRITE_LOOP; 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) long_options, &option_index)) != EOF)
{ {
switch(c) { switch(c) {
...@@ -374,8 +378,13 @@ static void get_options(register int *argc,register char ***argv) ...@@ -374,8 +378,13 @@ static void get_options(register int *argc,register char ***argv)
break; break;
case 'o': case 'o':
check_param.testflag= (check_param.testflag & ~T_REP_BY_SORT) | T_REP; check_param.testflag= (check_param.testflag & ~T_REP_BY_SORT) | T_REP;
check_param.force_sort=0;
my_disable_async_io=1; /* More safety */ my_disable_async_io=1; /* More safety */
break; break;
case 'n':
check_param.testflag= (check_param.testflag & ~T_REP) | T_REP_BY_SORT;
check_param.force_sort=1;
break;
case 'q': case 'q':
check_param.opt_rep_quick++; check_param.opt_rep_quick++;
break; break;
...@@ -683,7 +692,8 @@ static int myisamchk(MI_CHECK *param, my_string filename) ...@@ -683,7 +692,8 @@ static int myisamchk(MI_CHECK *param, my_string filename)
if ((param->testflag & T_REP_BY_SORT) && if ((param->testflag & T_REP_BY_SORT) &&
(share->state.key_map || (share->state.key_map ||
(rep_quick && !param->keys_in_use && !recreate)) && (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); error=mi_repair_by_sort(&check_param,info,fixed_name,rep_quick);
state_updated=1; state_updated=1;
......
...@@ -32,3 +32,11 @@ case when 1>0 then "TRUE" else "FALSE" END ...@@ -32,3 +32,11 @@ case when 1>0 then "TRUE" else "FALSE" END
TRUE TRUE
case when 1<0 then "TRUE" else "FALSE" END case when 1<0 then "TRUE" else "FALSE" END
FALSE FALSE
fcase count(*)
0 2
2 1
3 1
fcase count(*)
nothing 2
one 1
two 1
...@@ -186,3 +186,9 @@ extract(SECOND FROM "1999-01-02 10:11:12") ...@@ -186,3 +186,9 @@ extract(SECOND FROM "1999-01-02 10:11:12")
12 12
ctime hour(ctime) ctime hour(ctime)
2001-01-12 12:23:40 12 2001-01-12 12:23:40 12
monthname(date)
NULL
January
monthname(date)
NULL
January
...@@ -257,3 +257,7 @@ hello ...@@ -257,3 +257,7 @@ hello
hello word hello word
count(*) count(*)
2 2
foobar boggle
fish 10
foobar boggle
fish 10
...@@ -13,6 +13,8 @@ t ...@@ -13,6 +13,8 @@ t
9999-12-31 23:59:59 9999-12-31 23:59:59
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
test.t1 optimize status OK test.t1 optimize status OK
Table Op Msg_type Msg_text
test.t1 check status OK
t t
2000-01-01 00:00:00 2000-01-01 00:00:00
2069-12-31 00:00:00 2069-12-31 00:00:00
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
# Testing of CASE # Testing of CASE
# #
drop table if exists t1;
select CASE "b" when "a" then 1 when "b" then 2 END; 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 END;
select CASE "c" when "a" then 1 when "b" then 2 ELSE 3 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; ...@@ -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 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;
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;
# #
# time functions # 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 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 period_add("9602",-12),period_diff(199505,"9404") ;
select now()-now(),weekday(curdate())-weekday(now()),unix_timestamp()-unix_timestamp(now()); select now()-now(),weekday(curdate())-weekday(now()),unix_timestamp()-unix_timestamp(now());
...@@ -99,9 +101,21 @@ select extract(MINUTE FROM "10:11:12"); ...@@ -99,9 +101,21 @@ select extract(MINUTE FROM "10:11:12");
select extract(MINUTE_SECOND FROM "10:11:12"); select extract(MINUTE_SECOND FROM "10:11:12");
select extract(SECOND FROM "1999-01-02 10:11:12"); select extract(SECOND FROM "1999-01-02 10:11:12");
drop table if exists t1;
create table t1 (ctime varchar(20)); create table t1 (ctime varchar(20));
insert into t1 values ('2001-01-12 12:23:40'); insert into t1 values ('2001-01-12 12:23:40');
select ctime, hour(ctime) from t1; select ctime, hour(ctime) from t1;
drop table 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;
...@@ -239,3 +239,13 @@ INSERT INTO t1 VALUES (0,'traktor','1111111111111'); ...@@ -239,3 +239,13 @@ INSERT INTO t1 VALUES (0,'traktor','1111111111111');
INSERT INTO t1 VALUES (1,'traktor','1111111111111111111111111'); INSERT INTO t1 VALUES (1,'traktor','1111111111111111111111111');
select count(*) from t1 where f2='traktor'; select count(*) from t1 where f2='traktor';
drop table t1; 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;
# #
# testing different DATETIME ranges # testing different DATETIME ranges
# #
drop table if exists t1;
create table t1 (t datetime); create table t1 (t datetime);
insert into t1 values(101),(691231),(700101),(991231),(10000101),(99991231),(101000000),(691231000000),(700101000000),(991231235959),(10000101000000),(99991231235959); insert into t1 values(101),(691231),(700101),(991231),(10000101),(99991231),(101000000),(691231000000),(700101000000),(991231235959),(10000101000000),(99991231235959);
select * from t1; select * from t1;
delete from t1 where t > 0; delete from t1 where t > 0;
optimize table t1; optimize table t1;
check table t1;
insert into t1 values("000101"),("691231"),("700101"),("991231"),("00000101"),("00010101"),("99991231"),("00101000000"),("691231000000"),("700101000000"),("991231235959"),("10000101000000"),("99991231235959"); insert into t1 values("000101"),("691231"),("700101"),("991231"),("00000101"),("00010101"),("99991231"),("00101000000"),("691231000000"),("700101000000"),("991231235959"),("10000101000000"),("99991231235959");
select * from t1; select * from t1;
drop table t1; drop table t1;
......
...@@ -17,6 +17,13 @@ ...@@ -17,6 +17,13 @@
/* /*
Handling of uchar arrays as large bitmaps. 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" #include "mysys_priv.h"
...@@ -24,37 +31,51 @@ ...@@ -24,37 +31,51 @@
pthread_mutex_t LOCK_bitmap; pthread_mutex_t LOCK_bitmap;
void bitmap_set_bit(uchar *bitmap, uint bitmap_size, uint bitmap_bit) { void bitmap_set_bit(uchar *bitmap, uint bitmap_size, uint bitmap_bit)
if((bitmap_bit != MY_BIT_NONE) && (bitmap_bit < bitmap_size*8)) { {
if (bitmap_bit < bitmap_size*8)
{
pthread_mutex_lock(&LOCK_bitmap); 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); 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; uint bit_found = MY_BIT_NONE;
int i, b; uint i;
pthread_mutex_lock(&LOCK_bitmap); pthread_mutex_lock(&LOCK_bitmap);
for(i=0; (i<bitmap_size) && (bit_found==MY_BIT_NONE); i++) { for (i=0; i < bitmap_size ; i++, bitmap++)
if(bitmap[i] == 0xff) continue; {
for(b=0; (b<8) && (bit_found==MY_BIT_NONE); b++) if (*bitmap != 0xff)
if((bitmap[i] & 1<<b) == 0) { { /* Found slot with free bit */
uint b;
for (b=0; ; b++)
{
if (!(*bitmap & (1 << b)))
{
*bitmap |= 1<<b;
bit_found = (i*8)+b; bit_found = (i*8)+b;
bitmap[i] |= 1<<b; break;
}; }
}; }
break; /* Found bit */
}
}
pthread_mutex_unlock(&LOCK_bitmap); pthread_mutex_unlock(&LOCK_bitmap);
return bit_found; return bit_found;
}; }
void bitmap_clear_bit(uchar *bitmap, uint bitmap_size, uint bitmap_bit) { void bitmap_clear_bit(uchar *bitmap, uint bitmap_size, uint bitmap_bit)
if((bitmap_bit != MY_BIT_NONE) && (bitmap_bit < bitmap_size*8)) { {
if (bitmap_bit < bitmap_size*8)
{
pthread_mutex_lock(&LOCK_bitmap); 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); pthread_mutex_unlock(&LOCK_bitmap);
}; }
}; }
#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 NEG=yes # update of column= -column
Need_cast_for_null=no # Need to cast NULL for arithmetic Need_cast_for_null=no # Need to cast NULL for arithmetic
...@@ -19,25 +19,25 @@ alter_modify_col=no # Alter table modify column ...@@ -19,25 +19,25 @@ alter_modify_col=no # Alter table modify column
alter_rename_table=no # Alter table rename table alter_rename_table=no # Alter table rename table
atomic_updates=yes # atomic updates atomic_updates=yes # atomic updates
atomic_updates_with_rollback=yes # atomic_updates_with_rollback 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_numbers=yes # binary numbers (0b1001)
binary_strings=no # binary strings (b'0110') 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 char_is_space_filled=no # char are space filled
column_alias=yes # Column alias column_alias=yes # Column alias
columns_in_group_by=+64 # number of columns in group by columns_in_group_by=+64 # number of columns in group by
columns_in_order_by=+64 # number of columns in order by columns_in_order_by=+64 # number of columns in order by
comment_#=no # # as comment comment_#=no # # as comment
comment_--=yes # -- as comment comment_--=yes # -- as comment (ANSI)
comment_/**/=yes # /* */ as comment comment_/**/=yes # /* */ as comment
comment_//=no # // as comment comment_//=no # // as comment (ANSI)
compute=yes # Compute compute=yes # Compute
connections=1000 # Simultaneous connections (installation default) connections=1000 # Simultaneous connections (installation default)
constraint_check=no # Column constraints constraint_check=no # Column constraints
constraint_check_table=yes # Table constraints constraint_check_table=yes # Table constraints
constraint_null=yes # NULL constraint (SyBase style) constraint_null=yes # NULL constraint (SyBase style)
crash_me_safe=no # crash me safe crash_me_safe=yes # crash me safe
crash_me_version=1.45 # crash me version crash_me_version=1.54 # crash me version
create_default=yes # default value for column create_default=yes # default value for column
create_default_func=no # default value function for column create_default_func=no # default value function for column
create_if_not_exists=no # create table if not exists create_if_not_exists=no # create table if not exists
...@@ -46,14 +46,18 @@ create_schema=yes # Create SCHEMA ...@@ -46,14 +46,18 @@ create_schema=yes # Create SCHEMA
create_table_select=no # create table from select create_table_select=no # create table from select
cross_join=yes # cross join (same as from a,b) cross_join=yes # cross join (same as from a,b)
date_as_string=no # String functions on date columns date_as_string=no # String functions on date columns
date_infinity=no # Supports 'infinity dates
date_last=no # Supports 9999-12-31 dates date_last=no # Supports 9999-12-31 dates
date_one=no # Supports 0001-01-01 dates date_one=no # Supports 0001-01-01 dates
date_with_YY=no # Supports YY-MM-DD dates date_with_YY=no # Supports YY-MM-DD dates
date_zero=no # Supports 0000-00-00 dates date_zero=no # Supports 0000-00-00 dates
domains=no # Domains (ANSI SQL) 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 double_quotes=yes # Double '' as ' in strings
drop_if_exists=no # drop table if exists drop_if_exists=no # drop table if exists
drop_index=with 'table.index' # drop index 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 ';' end_colon=yes # allows end ';'
except=no # except except=no # except
except_all=no # except all except_all=no # except all
...@@ -161,6 +165,7 @@ func_extra_version=no # Function VERSION ...@@ -161,6 +165,7 @@ func_extra_version=no # Function VERSION
func_extra_weekday=no # Function WEEKDAY func_extra_weekday=no # Function WEEKDAY
func_extra_|=yes # Function | (bitwise or) func_extra_|=yes # Function | (bitwise or)
func_extra_||=no # Function OR as '||' func_extra_||=no # Function OR as '||'
func_extra_~*=no # Function ~* (case insensitive compare)
func_odbc_abs=yes # Function ABS func_odbc_abs=yes # Function ABS
func_odbc_acos=yes # Function ACOS func_odbc_acos=yes # Function ACOS
func_odbc_ascii=yes # Function ASCII func_odbc_ascii=yes # Function ASCII
...@@ -243,7 +248,8 @@ func_sql_extract_sql=no # Function EXTRACT ...@@ -243,7 +248,8 @@ func_sql_extract_sql=no # Function EXTRACT
func_sql_localtime=no # Function LOCALTIME func_sql_localtime=no # Function LOCALTIME
func_sql_localtimestamp=no # Function LOCALTIMESTAMP func_sql_localtimestamp=no # Function LOCALTIMESTAMP
func_sql_lower=yes # Function LOWER 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_octet_length=no # Function OCTET_LENGTH
func_sql_position=no # Function POSITION func_sql_position=no # Function POSITION
func_sql_searched_case=yes # Function searched CASE func_sql_searched_case=yes # Function searched CASE
...@@ -273,7 +279,7 @@ func_where_unique=no # Function UNIQUE ...@@ -273,7 +279,7 @@ func_where_unique=no # Function UNIQUE
functions=yes # Functions functions=yes # Functions
group_by=yes # Group by group_by=yes # Group by
group_by_alias=no # Group by alias 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_by_position=no # Group by position
group_distinct_functions=yes # Group functions with distinct group_distinct_functions=yes # Group functions with distinct
group_func_extra_bit_and=no # Group function BIT_AND 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 ...@@ -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_std=no # Group function STD
group_func_extra_stddev=no # Group function STDDEV group_func_extra_stddev=no # Group function STDDEV
group_func_extra_variance=no # Group function VARIANCE 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_avg=yes # Group function AVG
group_func_sql_count_*=yes # Group function COUNT (*) group_func_sql_count_*=yes # Group function COUNT (*)
group_func_sql_count_column=yes # Group function COUNT column name 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_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=yes # Group function MAX on numbers
group_func_sql_max_str=yes # Group function MAX on strings 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=yes # Group function MIN on numbers
group_func_sql_min_str=yes # Group function MIN on strings 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_func_sql_sum=yes # Group function SUM
group_functions=yes # Group functions group_functions=yes # Group functions
group_on_unused=yes # Group on unused column
has_true_false=no # TRUE and FALSE has_true_false=no # TRUE and FALSE
having=yes # Having having=yes # Having
having_with_alias=no # Having on alias having_with_alias=no # Having on alias
having_with_group=yes # Having with group function having_with_group=yes # Having with group function
hex_numbers=yes # hex numbers (0x41) hex_numbers=yes # hex numbers (0x41)
hex_strings=no # hex strings (x'1ace') 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_in_create=no # index in create table
index_namespace=yes # different namespace for index index_namespace=yes # different namespace for index
index_parts=no # index on column part (extension) index_parts=no # index on column part (extension)
inner_join=yes # inner join inner_join=yes # inner join
insert_empty_string=yes # insert empty string insert_empty_string=yes # insert empty string
insert_multi_value=no # INSERT with Value lists
insert_select=yes # insert INTO ... SELECT ... insert_select=yes # insert INTO ... SELECT ...
insert_with_set=no # INSERT with set syntax insert_with_set=no # INSERT with set syntax
intersect=no # intersect intersect=no # intersect
...@@ -317,12 +328,12 @@ like_with_column=yes # column LIKE column ...@@ -317,12 +328,12 @@ like_with_column=yes # column LIKE column
like_with_number=yes # LIKE on numbers like_with_number=yes # LIKE on numbers
lock_tables=no # lock table lock_tables=no # lock table
logical_value=not supported # Value of logical operation (1=1) 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_char_size=8000 # max char() size
max_column_name=128 # column name length max_column_name=128 # column name length
max_columns=1024 # Columns in table max_columns=1024 # Columns in table
max_conditions=10922 # OR and AND in WHERE max_conditions=13104 # OR and AND in WHERE
max_expressions=2783 # simple expressions max_expressions=656 # simple expressions
max_index=+64 # max index max_index=+64 # max index
max_index_length=900 # index length max_index_length=900 # index length
max_index_name=128 # index name length max_index_name=128 # index name length
...@@ -345,7 +356,6 @@ multi_drop=no # many tables to drop table ...@@ -345,7 +356,6 @@ multi_drop=no # many tables to drop table
multi_strings=no # Multiple line strings multi_strings=no # Multiple line strings
multi_table_delete=no # DELETE FROM table1,table2... multi_table_delete=no # DELETE FROM table1,table2...
multi_table_update=no # Update with many tables multi_table_update=no # Update with many tables
insert_multi_value=no # Value lists in INSERT
natural_join=no # natural join natural_join=no # natural join
natural_join_incompat=no # natural join (incompatible lists) natural_join_incompat=no # natural join (incompatible lists)
natural_left_outer_join=no # natural left outer join natural_left_outer_join=no # natural left outer join
...@@ -354,6 +364,7 @@ null_concat_expr=no # Is concat('a',NULL) = NULL ...@@ -354,6 +364,7 @@ null_concat_expr=no # Is concat('a',NULL) = NULL
null_in_index=yes # null in index null_in_index=yes # null in index
null_in_unique=no # null in unique index null_in_unique=no # null in unique index
null_num_expr=yes # Is 1+NULL = NULL 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 odbc_left_outer_join=yes # left outer join odbc style
operating_system=Microsoft Windows 2000 [Version 5.00.2195] # crash-me tested on operating_system=Microsoft Windows 2000 [Version 5.00.2195] # crash-me tested on
order_by=yes # Order by order_by=yes # Order by
...@@ -361,6 +372,7 @@ order_by_alias=yes # Order by alias ...@@ -361,6 +372,7 @@ order_by_alias=yes # Order by alias
order_by_function=yes # Order by function order_by_function=yes # Order by function
order_by_position=yes # Order by position order_by_position=yes # Order by position
order_by_remember_desc=no # Order by DESC is remembered 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 primary_key_in_create=yes # primary key in create table
psm_functions=no # PSM functions (ANSI SQL) psm_functions=no # PSM functions (ANSI SQL)
psm_modules=no # PSM modules (ANSI SQL) psm_modules=no # PSM modules (ANSI SQL)
...@@ -374,7 +386,7 @@ quote_with_"=no # Allows ' and " as string markers ...@@ -374,7 +386,7 @@ quote_with_"=no # Allows ' and " as string markers
recursive_subqueries=40 # recursive subqueries recursive_subqueries=40 # recursive subqueries
remember_end_space=no # Remembers end space in char() remember_end_space=no # Remembers end space in char()
remember_end_space_varchar=yes # Remembers end space in varchar() 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 right_outer_join=yes # right outer join
rowid=no # Type for row id rowid=no # Type for row id
select_constants=yes # Select constants select_constants=yes # Select constants
...@@ -383,15 +395,16 @@ select_limit2=no # SELECT with LIMIT #,# ...@@ -383,15 +395,16 @@ select_limit2=no # SELECT with LIMIT #,#
select_string_size=16777207 # constant string size in SELECT select_string_size=16777207 # constant string size in SELECT
select_table_update=yes # Update with sub select select_table_update=yes # Update with sub select
select_without_from=yes # SELECT without FROM 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 simple_joins=yes # ANSI SQL simple joins
storage_of_float=round # Storage of float values storage_of_float=round # Storage of float values
subqueries=yes # subqueries subqueries=yes # subqueries
table_alias=yes # Table alias table_alias=yes # Table alias
table_name_case=yes # case independent table names table_name_case=yes # case independent table names
table_wildcard=yes # Select table_name.* table_wildcard=yes # Select table_name.*
tempoary_table=no # temporary tables temporary_table=no # temporary tables
transactions=yes # transactions transactions=yes # transactions
truncate_table=no # truncate
type_extra_abstime=no # Type abstime type_extra_abstime=no # Type abstime
type_extra_bfile=no # Type bfile type_extra_bfile=no # Type bfile
type_extra_blob=no # Type blob type_extra_blob=no # Type blob
...@@ -399,6 +412,7 @@ type_extra_bool=no # Type bool ...@@ -399,6 +412,7 @@ type_extra_bool=no # Type bool
type_extra_box=no # Type box type_extra_box=no # Type box
type_extra_byte=no # Type byte type_extra_byte=no # Type byte
type_extra_char(1_arg)_binary=no # Type char(1 arg) binary 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_circle=no # Type circle
type_extra_clob=no # Type clob type_extra_clob=no # Type clob
type_extra_datetime=yes # Type datetime type_extra_datetime=yes # Type datetime
...@@ -408,6 +422,7 @@ type_extra_float(2_arg)=no # Type float(2 arg) ...@@ -408,6 +422,7 @@ type_extra_float(2_arg)=no # Type float(2 arg)
type_extra_float4=no # Type float4 type_extra_float4=no # Type float4
type_extra_float8=no # Type float8 type_extra_float8=no # Type float8
type_extra_image=yes # Type image 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_int(1_arg)_zerofill=no # Type int(1 arg) zerofill
type_extra_int1=no # Type int1 type_extra_int1=no # Type int1
type_extra_int2=no # Type int2 type_extra_int2=no # Type int2
...@@ -424,6 +439,7 @@ type_extra_long_raw=no # Type long raw ...@@ -424,6 +439,7 @@ type_extra_long_raw=no # Type long raw
type_extra_long_varbinary=no # Type long varbinary type_extra_long_varbinary=no # Type long varbinary
type_extra_long_varchar(1_arg)=no # Type long varchar(1 arg) type_extra_long_varchar(1_arg)=no # Type long varchar(1 arg)
type_extra_lseg=no # Type lseg type_extra_lseg=no # Type lseg
type_extra_macaddr=no # Type macaddr
type_extra_mediumint=no # Type mediumint type_extra_mediumint=no # Type mediumint
type_extra_mediumtext=no # Type mediumtext type_extra_mediumtext=no # Type mediumtext
type_extra_middleint=no # Type middleint type_extra_middleint=no # Type middleint
...@@ -451,7 +467,7 @@ type_extra_timespan=no # Type timespan ...@@ -451,7 +467,7 @@ type_extra_timespan=no # Type timespan
type_extra_uint=no # Type uint type_extra_uint=no # Type uint
type_extra_varchar2(1_arg)=no # Type varchar2(1 arg) type_extra_varchar2(1_arg)=no # Type varchar2(1 arg)
type_extra_year=no # Type year 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_binary(1_arg)=yes # Type binary(1 arg)
type_odbc_datetime=yes # Type datetime type_odbc_datetime=yes # Type datetime
type_odbc_tinyint=yes # Type tinyint type_odbc_tinyint=yes # Type tinyint
...@@ -459,6 +475,7 @@ type_odbc_varbinary(1_arg)=yes # Type varbinary(1 arg) ...@@ -459,6 +475,7 @@ type_odbc_varbinary(1_arg)=yes # Type varbinary(1 arg)
type_sql_bit=yes # Type bit type_sql_bit=yes # Type bit
type_sql_bit(1_arg)=no # Type bit(1 arg) type_sql_bit(1_arg)=no # Type bit(1 arg)
type_sql_bit_varying(1_arg)=no # Type bit varying(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(1_arg)=yes # Type char(1 arg)
type_sql_char_varying(1_arg)=yes # Type char varying(1 arg) type_sql_char_varying(1_arg)=yes # Type char varying(1 arg)
type_sql_character(1_arg)=yes # Type character(1 arg) type_sql_character(1_arg)=yes # Type character(1 arg)
......
...@@ -721,17 +721,41 @@ double Item_func_case::val() ...@@ -721,17 +721,41 @@ double Item_func_case::val()
bool bool
Item_func_case::fix_fields(THD *thd,TABLE_LIST *tables) Item_func_case::fix_fields(THD *thd,TABLE_LIST *tables)
{ {
if (first_expr && first_expr->fix_fields(thd,tables) || if (first_expr && first_expr->fix_fields(thd,tables) ||
else_expr && else_expr->fix_fields(thd,tables)) else_expr && else_expr->fix_fields(thd,tables))
return 1; return 1;
if (Item_func::fix_fields(thd,tables)) if (Item_func::fix_fields(thd,tables))
return 1; 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) if (!else_expr || else_expr->maybe_null)
maybe_null=1; // The result may be NULL maybe_null=1; // The result may be NULL
return 0; 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() void Item_func_case::fix_length_and_dec()
{ {
...@@ -750,6 +774,7 @@ 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) void Item_func_case::print(String *str)
{ {
......
...@@ -254,6 +254,7 @@ public: ...@@ -254,6 +254,7 @@ public:
longlong val_int(); longlong val_int();
String *val_str(String *); String *val_str(String *);
void fix_length_and_dec(); void fix_length_and_dec();
void update_used_tables();
enum Item_result result_type () const { return cached_result_type; } enum Item_result result_type () const { return cached_result_type; }
const char *func_name() const { return "case"; } const char *func_name() const { return "case"; }
void print(String *str); void print(String *str);
......
...@@ -135,7 +135,11 @@ String* Item_func_monthname::val_str(String* str) ...@@ -135,7 +135,11 @@ String* Item_func_monthname::val_str(String* str)
{ {
uint month=(uint) Item_func_month::val_int(); uint month=(uint) Item_func_month::val_int();
if (!month) // This is also true for NULL if (!month) // This is also true for NULL
{
null_value=1;
return (String*) 0; return (String*) 0;
}
null_value=0;
return &month_names[month-1]; return &month_names[month-1];
} }
......
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *path, static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *path,
uint level); uint level);
/* db-name is already validated when we come here */
void mysql_create_db(THD *thd, char *db, uint create_options) void mysql_create_db(THD *thd, char *db, uint create_options)
{ {
char path[FN_REFLEN+16]; char path[FN_REFLEN+16];
...@@ -35,11 +37,6 @@ void mysql_create_db(THD *thd, char *db, uint create_options) ...@@ -35,11 +37,6 @@ void mysql_create_db(THD *thd, char *db, uint create_options)
long result=1; long result=1;
DBUG_ENTER("mysql_create_db"); 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)); VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
/* Check directory */ /* Check directory */
...@@ -96,6 +93,8 @@ static TYPELIB deletable_extentions= ...@@ -96,6 +93,8 @@ static TYPELIB deletable_extentions=
{array_elements(del_exts)-1,"del_exts", del_exts}; {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) void mysql_rm_db(THD *thd,char *db,bool if_exists)
{ {
long deleted=0; long deleted=0;
...@@ -103,12 +102,6 @@ void mysql_rm_db(THD *thd,char *db,bool if_exists) ...@@ -103,12 +102,6 @@ void mysql_rm_db(THD *thd,char *db,bool if_exists)
MY_DIR *dirp; MY_DIR *dirp;
DBUG_ENTER("mysql_rm_db"); 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_mysql_create_db));
VOID(pthread_mutex_lock(&LOCK_open)); VOID(pthread_mutex_lock(&LOCK_open));
......
...@@ -510,7 +510,7 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd) ...@@ -510,7 +510,7 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd)
int error = 0; int error = 0;
DBUG_ENTER("mysql_table_dump"); DBUG_ENTER("mysql_table_dump");
db = (db && db[0]) ? db : thd->db; 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 DBUG_RETURN(1); // out of memory
table_list->db = db; table_list->db = db;
table_list->real_name = table_list->name = tbl_name; 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) ...@@ -518,9 +518,14 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd)
table_list->next = 0; table_list->next = 0;
remove_escape(table_list->real_name); 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); 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)) if (check_access(thd, SELECT_ACL, db, &table_list->grant.privilege))
goto err; goto err;
if (grant_option && check_grant(thd, SELECT_ACL, table_list)) if (grant_option && check_grant(thd, SELECT_ACL, table_list))
...@@ -710,6 +715,12 @@ bool do_command(THD *thd) ...@@ -710,6 +715,12 @@ bool do_command(THD *thd)
case COM_CREATE_DB: case COM_CREATE_DB:
{ {
char *db=thd->strdup(packet+1); 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)) if (check_access(thd,CREATE_ACL,db,0,1))
break; break;
mysql_log.write(thd,command,packet+1); mysql_log.write(thd,command,packet+1);
...@@ -719,6 +730,12 @@ bool do_command(THD *thd) ...@@ -719,6 +730,12 @@ bool do_command(THD *thd)
case COM_DROP_DB: case COM_DROP_DB:
{ {
char *db=thd->strdup(packet+1); 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)) if (check_access(thd,DROP_ACL,db,0,1) || end_active_trans(thd))
break; break;
mysql_log.write(thd,command,db); mysql_log.write(thd,command,db);
...@@ -1503,7 +1520,7 @@ mysql_execute_command(void) ...@@ -1503,7 +1520,7 @@ mysql_execute_command(void)
goto error; /* purecov: inspected */ goto error; /* purecov: inspected */
} }
remove_escape(db); // Fix escaped '_' remove_escape(db); // Fix escaped '_'
if (strlen(db) > NAME_LEN) if (check_db_name(db))
{ {
net_printf(&thd->net,ER_WRONG_DB_NAME, db); net_printf(&thd->net,ER_WRONG_DB_NAME, db);
goto error; goto error;
...@@ -1666,6 +1683,11 @@ mysql_execute_command(void) ...@@ -1666,6 +1683,11 @@ mysql_execute_command(void)
break; break;
case SQLCOM_CREATE_DB: 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)) if (check_access(thd,CREATE_ACL,lex->name,0,1))
break; break;
mysql_create_db(thd,lex->name,lex->create_info.options); mysql_create_db(thd,lex->name,lex->create_info.options);
...@@ -1673,6 +1695,11 @@ mysql_execute_command(void) ...@@ -1673,6 +1695,11 @@ mysql_execute_command(void)
} }
case SQLCOM_DROP_DB: 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) || if (check_access(thd,DROP_ACL,lex->name,0,1) ||
end_active_trans(thd)) end_active_trans(thd))
break; break;
...@@ -1887,12 +1914,6 @@ check_access(THD *thd,uint want_access,const char *db, uint *save_priv, ...@@ -1887,12 +1914,6 @@ check_access(THD *thd,uint want_access,const char *db, uint *save_priv,
if (db == any_db) if (db == any_db)
return FALSE; // Allow select on anything 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))) if (db && (!thd->db || strcmp(db,thd->db)))
db_access=acl_get(thd->host, thd->ip, (char*) &thd->remote.sin_addr, db_access=acl_get(thd->host, thd->ip, (char*) &thd->remote.sin_addr,
thd->priv_user, db); /* purecov: inspected */ thd->priv_user, db); /* purecov: inspected */
...@@ -1970,7 +1991,8 @@ static bool check_db_used(THD *thd,TABLE_LIST *tables) ...@@ -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; int error=0;
if (table_list) if (table_list)
...@@ -2463,8 +2485,8 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias, ...@@ -2463,8 +2485,8 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias,
DBUG_RETURN(0); // End of memory DBUG_RETURN(0); // End of memory
alias_str= alias ? alias->str : table->table.str; alias_str= alias ? alias->str : table->table.str;
if (table->table.length > NAME_LEN || 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); net_printf(&thd->net,ER_WRONG_TABLE_NAME,table->table.str);
DBUG_RETURN(0); DBUG_RETURN(0);
......
...@@ -1033,7 +1033,7 @@ char *get_field(MEM_ROOT *mem, TABLE *table, uint fieldnr) ...@@ -1033,7 +1033,7 @@ char *get_field(MEM_ROOT *mem, TABLE *table, uint fieldnr)
bool check_db_name(const char *name) bool check_db_name(const char *name)
{ {
const char *start=end; const char *start=name;
while (*name) while (*name)
{ {
#if defined(USE_MB) && defined(USE_MB_IDENT) #if defined(USE_MB) && defined(USE_MB_IDENT)
......
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