1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

Changed IF(expr, column, NULL) to take type from column

Fixed some windows portability problems and removed some compiler warnings
 Cleaned up QUOTE() function and fixed bug in \0 and \Z handling.
This commit is contained in:
monty@hundin.mysql.fi
2002-08-12 03:33:46 +03:00
parent deaec7b0e0
commit c99c1fd384
15 changed files with 144 additions and 67 deletions

View File

@@ -31071,6 +31071,10 @@ mysql> SELECT IF(STRCMP('test','test1'),'no','yes');
-> 'no' -> 'no'
@end example @end example
If @code{expr2} or @code{expr3} is explicitely @code{NULL} then the
result type of the @code{IF()} function is the type of the not
@code{NULL} column. (This behavior is new in MySQL 4.0.3).
@code{expr1} is evaluated as an integer value, which means that if you are @code{expr1} is evaluated as an integer value, which means that if you are
testing floating-point or string values, you should do so using a comparison testing floating-point or string values, you should do so using a comparison
operation: operation:
@@ -50226,10 +50230,13 @@ each individual 4.0.x release.
@itemize @bullet @itemize @bullet
@item @item
Fixed security bug in database hash Changed behavior of @code{IF(condition,column,NULL)} so that it returns
the value of the column type.
@item
Made @code{safe_mysqld} a symlink to @code{mysqld_safe} in binary distribution. Made @code{safe_mysqld} a symlink to @code{mysqld_safe} in binary distribution.
@item @item
Fixed security bug when having an empty databasename in the user.db table. Fixed security bug when having an empty databasename in the @code{user.db}
table.
@item @item
Fixed some problems with @code{CREATE TABLE ... SELECT function()}. Fixed some problems with @code{CREATE TABLE ... SELECT function()}.
@item @item

View File

@@ -89,7 +89,6 @@ EXPORTS
mysql_read_query_result mysql_read_query_result
mysql_real_escape_string mysql_real_escape_string
mysql_ssl_set mysql_ssl_set
mysql_ssl_clear
mysql_real_connect mysql_real_connect
mysql_master_query mysql_master_query
mysql_master_send_query mysql_master_send_query

View File

@@ -1097,7 +1097,6 @@ int _mi_cmp_dynamic_unique(MI_INFO *info, MI_UNIQUEDEF *def,
const byte *record, my_off_t pos) const byte *record, my_off_t pos)
{ {
byte *rec_buff,*old_record; byte *rec_buff,*old_record;
uint alloced_rec_buff_length;
int error; int error;
DBUG_ENTER("_mi_cmp_dynamic_unique"); DBUG_ENTER("_mi_cmp_dynamic_unique");

View File

@@ -152,6 +152,9 @@ quote('\'\"\\test')
select quote(concat('abc\'', '\\cba')); select quote(concat('abc\'', '\\cba'));
quote(concat('abc\'', '\\cba')) quote(concat('abc\'', '\\cba'))
'abc\'\\cba' 'abc\'\\cba'
select quote(1/0), quote('\0\Z');
quote(1/0) quote('\0\Z')
NULL '\0\Z'
select reverse(""); select reverse("");
reverse("") reverse("")

View File

@@ -63,6 +63,7 @@ select decode(encode("abcdef","monty"),"monty")="abcdef";
select quote('\'\"\\test'); select quote('\'\"\\test');
select quote(concat('abc\'', '\\cba')); select quote(concat('abc\'', '\\cba'));
select quote(1/0), quote('\0\Z');
# #
# Wrong usage of functions # Wrong usage of functions

View File

@@ -521,8 +521,9 @@ int _my_b_read_r(register IO_CACHE *info, byte *Buffer, uint Count)
length=(length <= info->read_length) ? length=(length <= info->read_length) ?
length + IO_ROUND_DN(info->read_length - length) : length + IO_ROUND_DN(info->read_length - length) :
length - IO_ROUND_UP(length - info->read_length) ; length - IO_ROUND_UP(length - info->read_length) ;
if (info->type != READ_FIFO && (length > info->end_of_file - pos_in_file)) if (info->type != READ_FIFO &&
length=info->end_of_file - pos_in_file; (length > (uint) (info->end_of_file - pos_in_file)))
length= (uint) (info->end_of_file - pos_in_file);
if (length == 0) if (length == 0)
{ {
info->error=(int) read_len; info->error=(int) read_len;

View File

@@ -306,7 +306,8 @@ innobase_mysql_print_thd(
*buf++=' '; *buf++=' ';
buf=strnmov(buf, thd->query, 150); buf=strnmov(buf, thd->query, 150);
} }
*buf='\n'; buf[0]='\n';
buf[1]=0;
} }
} }

View File

@@ -486,6 +486,7 @@ Item_func_ifnull::val_str(String *str)
return res; return res;
} }
void void
Item_func_if::fix_length_and_dec() Item_func_if::fix_length_and_dec()
{ {
@@ -494,16 +495,32 @@ Item_func_if::fix_length_and_dec()
decimals=max(args[1]->decimals,args[2]->decimals); decimals=max(args[1]->decimals,args[2]->decimals);
enum Item_result arg1_type=args[1]->result_type(); enum Item_result arg1_type=args[1]->result_type();
enum Item_result arg2_type=args[2]->result_type(); enum Item_result arg2_type=args[2]->result_type();
binary=1; bool null1=args[1]->null_value;
if (arg1_type == STRING_RESULT || arg2_type == STRING_RESULT) bool null2=args[2]->null_value;
if (null1)
{
cached_result_type= arg2_type;
binary= args[1]->binary;
}
else if (null2)
{
cached_result_type= arg2_type;
binary= args[2]->binary;
}
else if (arg1_type == STRING_RESULT || arg2_type == STRING_RESULT)
{ {
cached_result_type = STRING_RESULT; cached_result_type = STRING_RESULT;
binary=args[1]->binary | args[2]->binary; binary=args[1]->binary | args[2]->binary;
} }
else if (arg1_type == REAL_RESULT || arg2_type == REAL_RESULT)
cached_result_type = REAL_RESULT;
else else
cached_result_type=arg1_type; // Should be INT_RESULT {
binary=1; // Number
if (arg1_type == REAL_RESULT || arg2_type == REAL_RESULT)
cached_result_type = REAL_RESULT;
else
cached_result_type=arg1_type; // Should be INT_RESULT
}
} }

View File

@@ -2071,41 +2071,90 @@ String* Item_func_inet_ntoa::val_str(String* str)
return str; return str;
} }
/*
QUOTE() function returns argument string in single quotes suitable for
using in a SQL statement.
DESCRIPTION
Adds a \ before all characters that needs to be escaped in a SQL string.
We also escape '^Z' (END-OF-FILE in windows) to avoid probelms when
running commands from a file in windows.
This function is very useful when you want to generate SQL statements
RETURN VALUES
str Quoted string
NULL Argument to QUOTE() was NULL or out of memory.
*/
#define get_esc_bit(mask, num) (1 & (*((mask) + ((num) >> 3))) >> ((num) & 7)) #define get_esc_bit(mask, num) (1 & (*((mask) + ((num) >> 3))) >> ((num) & 7))
/*
QUOTE() function returns argument string in single quotes,
also adds a \ before \, ' CHAR(0) and CHAR(24)
*/
String *Item_func_quote::val_str(String *str) String *Item_func_quote::val_str(String *str)
{ {
static char escmask[32] = {0x01, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x00, /*
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, Bit mask that has 1 for set for the position of the following characters:
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0, \, ' and ^Z
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; */
String *arg= args[0]->val_str(str);
char *from, *to, *end;
uint delta= 2; /* for beginning and ending ' signs */
if (!arg) static char escmask[32]=
goto null;
for (from= (char*) arg->ptr(), end= from + arg->length(); from < end; from++)
delta+= get_esc_bit(escmask, *from);
if (str->alloc(arg->length() + delta))
goto null;
to= (char*) str->ptr() + arg->length() + delta - 1;
*to--= '\'';
for (end= (char*) arg->ptr(), from= end + arg->length() - 1; from >= end;
from--, to--)
{ {
*to= *from; 0x01, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x00,
if (get_esc_bit(escmask, *from)) 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
*--to= '\\'; 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
char *from, *to, *end, *start;
String *arg= args[0]->val_str(str);
uint arg_length, new_length;
if (!arg) // Null argument
goto null;
arg_length= arg->length();
new_length= arg_length+2; /* for beginning and ending ' signs */
for (from= (char*) arg->ptr(), end= from + arg_length; from < end; from++)
new_length+= get_esc_bit(escmask, *from);
/*
We have to use realloc() instead of alloc() as we want to keep the
old result in str
*/
if (str->realloc(new_length))
goto null;
/*
As 'arg' and 'str' may be the same string, we must replace characters
from the end to the beginning
*/
to= (char*) str->ptr() + new_length - 1;
*to--= '\'';
for (start= (char*) arg->ptr() ; end-- != start; to--)
{
/*
We can't use the bitmask here as we want to replace \O and ^Z with 0
and Z
*/
switch (*end) {
case 0:
*to--= '0';
*to= '\\';
break;
case '\032':
*to--= 'Z';
*to= '\\';
break;
case '\'':
case '\\':
*to--= *end;
*to= '\\';
break;
default:
*to= *end;
break;
}
} }
*to= '\''; *to= '\'';
str->length(arg->length() + delta); str->length(new_length);
return str; return str;
null: null:

View File

@@ -451,7 +451,6 @@ int MYSQL_LOG::find_log_pos(LOG_INFO *linfo, const char *log_name,
} }
} }
err:
if (need_lock) if (need_lock)
pthread_mutex_unlock(&LOCK_index); pthread_mutex_unlock(&LOCK_index);
DBUG_RETURN(error); DBUG_RETURN(error);
@@ -602,15 +601,15 @@ err:
- Read the first file name from the index file and store in rli->linfo - Read the first file name from the index file and store in rli->linfo
RETURN VALUES RETURN VALUES
0 ok 0 ok
1 error LOG_INFO_EOF End of log-index-file found
LOG_INFO_SEEK Could not allocate IO cache
LOG_INFO_IO Got IO error while reading file
*/ */
int MYSQL_LOG::purge_first_log(struct st_relay_log_info* rli) int MYSQL_LOG::purge_first_log(struct st_relay_log_info* rli)
{ {
File file; int error;
bool error= 1;
my_off_t offset, init_offset;
DBUG_ENTER("purge_first_log"); DBUG_ENTER("purge_first_log");
/* /*

View File

@@ -640,7 +640,7 @@ extern bool opt_using_transactions, use_temp_pool, mysql_embedded;
extern bool using_update_log, opt_large_files; extern bool using_update_log, opt_large_files;
extern bool opt_log, opt_update_log, opt_bin_log, opt_slow_log; extern bool opt_log, opt_update_log, opt_bin_log, opt_slow_log;
extern bool opt_sql_bin_update, opt_safe_user_create, opt_no_mix_types; extern bool opt_sql_bin_update, opt_safe_user_create, opt_no_mix_types;
extern bool opt_disable_networking, opt_skip_show_db; extern bool opt_disable_networking, opt_skip_show_db, opt_enable_named_pipe;
extern bool volatile abort_loop, shutdown_in_progress, grant_option; extern bool volatile abort_loop, shutdown_in_progress, grant_option;
extern uint volatile thread_count, thread_running, global_read_lock; extern uint volatile thread_count, thread_running, global_read_lock;
extern my_bool opt_safe_show_db, opt_local_infile, lower_case_table_names; extern my_bool opt_safe_show_db, opt_local_infile, lower_case_table_names;

View File

@@ -181,7 +181,6 @@ static SECURITY_DESCRIPTOR sdPipeDescriptor;
static HANDLE hPipe = INVALID_HANDLE_VALUE; static HANDLE hPipe = INVALID_HANDLE_VALUE;
static pthread_cond_t COND_handler_count; static pthread_cond_t COND_handler_count;
static uint handler_count; static uint handler_count;
static bool opt_enable_named_pipe = 0;
#endif #endif
#ifdef __WIN__ #ifdef __WIN__
static bool opt_console=0, start_mode=0, use_opt_args; static bool opt_console=0, start_mode=0, use_opt_args;
@@ -258,6 +257,7 @@ ulong back_log, connect_timeout, concurrency;
char mysql_home[FN_REFLEN], pidfile_name[FN_REFLEN], time_zone[30]; char mysql_home[FN_REFLEN], pidfile_name[FN_REFLEN], time_zone[30];
bool opt_log, opt_update_log, opt_bin_log, opt_slow_log; bool opt_log, opt_update_log, opt_bin_log, opt_slow_log;
bool opt_disable_networking=0, opt_skip_show_db=0; bool opt_disable_networking=0, opt_skip_show_db=0;
bool opt_enable_named_pipe= 0;
my_bool opt_local_infile, opt_external_locking, opt_slave_compressed_protocol; my_bool opt_local_infile, opt_external_locking, opt_slave_compressed_protocol;
static bool opt_do_pstack = 0; static bool opt_do_pstack = 0;
@@ -1045,8 +1045,8 @@ static void server_init(void)
PIPE_READMODE_BYTE | PIPE_READMODE_BYTE |
PIPE_WAIT, PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES, PIPE_UNLIMITED_INSTANCES,
(int) global_variables.net_buffer_length, (int) global_system_variables.net_buffer_length,
(int) global_variables.net_buffer_length, (int) global_system_variables.net_buffer_length,
NMPWAIT_USE_DEFAULT_WAIT, NMPWAIT_USE_DEFAULT_WAIT,
&saPipeSecurity )) == INVALID_HANDLE_VALUE) &saPipeSecurity )) == INVALID_HANDLE_VALUE)
{ {
@@ -2275,7 +2275,8 @@ int main(int argc, char **argv)
if (Service.IsService(argv[1])) if (Service.IsService(argv[1]))
{ {
/* start an optional service */ /* start an optional service */
event_name = load_default_groups[0]= argv[1]; event_name= argv[1];
load_default_groups[0]= argv[1];
start_mode= 1; start_mode= 1;
Service.Init(event_name, mysql_service); Service.Init(event_name, mysql_service);
return 0; return 0;
@@ -2285,8 +2286,8 @@ int main(int argc, char **argv)
{ {
/* Add service name after filename */ /* Add service name after filename */
uint length=strlen(file_path); uint length=strlen(file_path);
strxnmov(file_path + length, sizeof(file_path)-length-2, " ", *strxnmov(file_path + length, sizeof(file_path)-length-2, " ",
argv[2], NullS)= '\0'; argv[2], NullS)= '\0';
if (!default_service_handling(argv, argv[2], argv[2], file_path)) if (!default_service_handling(argv, argv[2], argv[2], file_path))
return 0; return 0;
@@ -2309,8 +2310,8 @@ int main(int argc, char **argv)
mysqld --install-manual mysqldopt --defaults-file=c:\miguel\my.ini mysqld --install-manual mysqldopt --defaults-file=c:\miguel\my.ini
*/ */
uint length=strlen(file_path); uint length=strlen(file_path);
strxnmov(file_path + length, sizeof(file_path)-length-2, " ", *strxnmov(file_path + length, sizeof(file_path)-length-2, " ",
argv[3], " ", argv[2], NullS)= '\0'; argv[3], " ", argv[2], NullS)= '\0';
if (!default_service_handling(argv, argv[2], argv[2], file_path)) if (!default_service_handling(argv, argv[2], argv[2], file_path))
return 0; return 0;
} }
@@ -2724,8 +2725,8 @@ pthread_handler_decl(handle_connections_namedpipes,arg)
PIPE_READMODE_BYTE | PIPE_READMODE_BYTE |
PIPE_WAIT, PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES, PIPE_UNLIMITED_INSTANCES,
(int) global_variables.net_buffer_length, (int) global_system_variables.net_buffer_length,
(int) global_variables.net_buffer_length, (int) global_systenm_ariables.net_buffer_length,
NMPWAIT_USE_DEFAULT_WAIT, NMPWAIT_USE_DEFAULT_WAIT,
&saPipeSecurity )) == &saPipeSecurity )) ==
INVALID_HANDLE_VALUE ) INVALID_HANDLE_VALUE )
@@ -2742,8 +2743,8 @@ pthread_handler_decl(handle_connections_namedpipes,arg)
PIPE_READMODE_BYTE | PIPE_READMODE_BYTE |
PIPE_WAIT, PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES, PIPE_UNLIMITED_INSTANCES,
(int) global_variables.net_buffer_length, (int) global_system_variables.net_buffer_length,
(int) global_variables.net_buffer_length, (int) global_system_variables.net_buffer_length,
NMPWAIT_USE_DEFAULT_WAIT, NMPWAIT_USE_DEFAULT_WAIT,
&saPipeSecurity)) == &saPipeSecurity)) ==
INVALID_HANDLE_VALUE) INVALID_HANDLE_VALUE)
@@ -4446,7 +4447,8 @@ static void fix_paths(void)
} }
char *end=convert_dirname(buff, opt_mysql_tmpdir, NullS); char *end=convert_dirname(buff, opt_mysql_tmpdir, NullS);
if (!(mysql_tmpdir= my_memdup(buff,(uint) (end-buff)+1, MYF(MY_FAE)))) if (!(mysql_tmpdir= my_memdup((byte*) buff,(uint) (end-buff)+1,
MYF(MY_FAE))))
exit(1); exit(1);
if (!slave_load_tmpdir) if (!slave_load_tmpdir)
{ {

View File

@@ -669,7 +669,7 @@ bool sys_var_thd_ulong::update(THD *thd, set_var *var)
{ {
/* Lock is needed to make things safe on 32 bit systems */ /* Lock is needed to make things safe on 32 bit systems */
pthread_mutex_lock(&LOCK_global_system_variables); pthread_mutex_lock(&LOCK_global_system_variables);
global_system_variables.*offset=tmp; global_system_variables.*offset= (ulong) tmp;
pthread_mutex_unlock(&LOCK_global_system_variables); pthread_mutex_unlock(&LOCK_global_system_variables);
} }
else else
@@ -998,7 +998,7 @@ bool sys_var_slave_skip_counter::update(THD *thd, set_var *var)
if (!active_mi->rli.slave_running) if (!active_mi->rli.slave_running)
{ {
pthread_mutex_lock(&active_mi->rli.data_lock); pthread_mutex_lock(&active_mi->rli.data_lock);
active_mi->rli.slave_skip_counter= var->value->val_int(); active_mi->rli.slave_skip_counter= (ulong) var->value->val_int();
pthread_mutex_unlock(&active_mi->rli.data_lock); pthread_mutex_unlock(&active_mi->rli.data_lock);
} }
pthread_mutex_unlock(&active_mi->rli.run_lock); pthread_mutex_unlock(&active_mi->rli.run_lock);

View File

@@ -855,7 +855,7 @@ static int check_master_version(MYSQL* mysql, MASTER_INFO* mi)
errmsg = "Master reported unrecognized MySQL version"; errmsg = "Master reported unrecognized MySQL version";
break; break;
} }
err:
if (errmsg) if (errmsg)
{ {
sql_print_error(errmsg); sql_print_error(errmsg);
@@ -874,7 +874,7 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db,
TABLE_LIST tables; TABLE_LIST tables;
int error= 1; int error= 1;
handler *file; handler *file;
uint save_options; ulong save_options;
if (packet_len == packet_error) if (packet_len == packet_error)
{ {
@@ -903,7 +903,7 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db,
/* we do not want to log create table statement */ /* we do not want to log create table statement */
save_options = thd->options; save_options = thd->options;
thd->options &= ~(ulong) OPTION_BIN_LOG; thd->options &= ~(ulong) (OPTION_BIN_LOG);
thd->proc_info = "Creating table from master dump"; thd->proc_info = "Creating table from master dump";
// save old db in case we are creating in a different database // save old db in case we are creating in a different database
char* save_db = thd->db; char* save_db = thd->db;
@@ -2642,7 +2642,7 @@ bool flush_relay_log_info(RELAY_LOG_INFO* rli)
*pos++='\n'; *pos++='\n';
pos=longlong2str(rli->master_log_pos, pos, 10); pos=longlong2str(rli->master_log_pos, pos, 10);
*pos='\n'; *pos='\n';
if (my_b_write(file, buff, (ulong) (pos-buff)+1)) if (my_b_write(file, (byte*) buff, (ulong) (pos-buff)+1))
error=1; error=1;
if (flush_io_cache(file)) if (flush_io_cache(file))
error=1; error=1;

View File

@@ -1152,7 +1152,6 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables,
String packet2(buff,sizeof(buff)); String packet2(buff,sizeof(buff));
List<Item> field_list; List<Item> field_list;
CONVERT *convert=thd->variables.convert_set; CONVERT *convert=thd->variables.convert_set;
ulong offset;
DBUG_ENTER("mysqld_show"); DBUG_ENTER("mysqld_show");
field_list.push_back(new Item_empty_string("Variable_name",30)); field_list.push_back(new Item_empty_string("Variable_name",30));
@@ -1173,7 +1172,7 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables,
if (show_type == SHOW_SYS) if (show_type == SHOW_SYS)
{ {
show_type= ((sys_var*) value)->type(); show_type= ((sys_var*) value)->type();
value= ((sys_var*) value)->value_ptr(thd, value_type); value= (char*) ((sys_var*) value)->value_ptr(thd, value_type);
} }
switch (show_type) { switch (show_type) {