summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <monty@hundin.mysql.fi>2002-05-16 18:20:49 +0300
committerunknown <monty@hundin.mysql.fi>2002-05-16 18:20:49 +0300
commit4d094257dbb785d792785e610ab3cdf41eae9b8c (patch)
tree12de711f3f9d8ad9eee9d28cf71e5487f17315d3 /sql
parent2618c6963c5bf1349c47ce3af6e55213ea9773f4 (diff)
parent74d29a07712a0caf57fca62dacfeb14b110beca4 (diff)
downloadmariadb-git-4d094257dbb785d792785e610ab3cdf41eae9b8c.tar.gz
merge with 3.23.51
BitKeeper/etc/ignore: auto-union BitKeeper/etc/logging_ok: auto-union BitKeeper/deleted/.del-mysql_fix_extensions.sh: Delete: scripts/mysql_fix_extensions.sh Build-tools/Do-rpm: Auto merged Makefile.am: Auto merged client/mysqldump.c: Auto merged client/mysqltest.c: Auto merged extra/resolve_stack_dump.c: Auto merged include/my_pthread.h: Auto merged include/my_sys.h: Auto merged include/mysqld_error.h: Auto merged innobase/row/row0ins.c: Auto merged innobase/row/row0mysql.c: Auto merged innobase/row/row0sel.c: Auto merged isam/pack_isam.c: Auto merged libmysql/libmysql.c: Auto merged mysql-test/r/func_if.result: Auto merged mysql-test/t/join.test: Auto merged mysys/array.c: Auto merged mysys/charset.c: Auto merged mysys/default.c: Auto merged mysys/hash.c: Auto merged mysys/my_thr_init.c: Auto merged mysys/raid.cc: Auto merged mysql-test/t/type_decimal.test: Auto merged sql/hostname.cc: Auto merged sql/item.h: Auto merged sql/item_cmpfunc.h: Auto merged sql/item_timefunc.h: Auto merged sql/log.cc: Auto merged sql/mini_client.cc: Auto merged sql/sql_parse.cc: Auto merged sql/sql_select.cc: Auto merged strings/Makefile.am: Auto merged
Diffstat (limited to 'sql')
-rw-r--r--sql/field.cc48
-rw-r--r--sql/hostname.cc7
-rw-r--r--sql/item.h19
-rw-r--r--sql/item_cmpfunc.cc53
-rw-r--r--sql/item_cmpfunc.h7
-rw-r--r--sql/item_timefunc.h2
-rw-r--r--sql/mini_client.cc15
-rw-r--r--sql/sql_acl.cc5
-rw-r--r--sql/sql_db.cc1
-rw-r--r--sql/sql_parse.cc4
-rw-r--r--sql/sql_yacc.yy2
11 files changed, 111 insertions, 52 deletions
diff --git a/sql/field.cc b/sql/field.cc
index 23419a53d3d..c6880a29cee 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -63,8 +63,8 @@ const char field_separator=',';
*****************************************************************************/
/*
- ** Calculate length of number and its parts
- ** Increment cuted_fields if wrong number
+ Calculate length of number and its parts
+ Increment cuted_fields if wrong number
*/
static bool
@@ -381,13 +381,34 @@ Field_decimal::reset(void)
void Field_decimal::overflow(bool negative)
{
uint len=field_length;
- char *to=ptr;
- if (negative && !unsigned_flag)
+ char *to=ptr, filler= '9';
+ if (negative)
{
- *to++ = '-';
- len--;
+ if (!unsigned_flag)
+ {
+ /* Put - sign as a first digit so we'll have -999..999 or 999..999 */
+ *to++ = '-';
+ len--;
+ }
+ else
+ {
+ filler= '0'; // Fill up with 0
+ if (!zerofill)
+ {
+ /*
+ Handle unsigned integer without zerofill, in which case
+ the number should be of format ' 0' or ' 0.000'
+ */
+ uint whole_part=field_length- (dec ? dec+2 : 1);
+ // Fill with spaces up to the first digit
+ bfill(to, whole_part, ' ');
+ to+= whole_part;
+ len-= whole_part;
+ // The main code will also handle the 0 before the decimal point
+ }
+ }
}
- bfill(to,len,negative && unsigned_flag ? '0' : '9');
+ bfill(to, len, filler);
if (dec)
ptr[field_length-dec-1]='.';
return;
@@ -422,10 +443,15 @@ void Field_decimal::store(const char *from,uint len)
from++;
if (unsigned_flag) // No sign with zerofill
{
- if (!error)
- current_thd->cuted_fields++;
- Field_decimal::overflow(1);
- return;
+ if (decstr.sign_char == '+') // just remove "+"
+ decstr.sign= 0;
+ else
+ {
+ if (!error)
+ current_thd->cuted_fields++;
+ Field_decimal::overflow(1);
+ return;
+ }
}
}
/*
diff --git a/sql/hostname.cc b/sql/hostname.cc
index 7d4e4a8ca75..5359f876522 100644
--- a/sql/hostname.cc
+++ b/sql/hostname.cc
@@ -171,17 +171,22 @@ my_string ip_to_hostname(struct in_addr *in, uint *errors)
{
DBUG_PRINT("error",("gethostbyname_r returned %d",tmp_errno));
add_wrong_ip(in);
+ my_gethostbyname_r_free();
DBUG_RETURN(0);
}
if (!hp->h_name[0])
{
DBUG_PRINT("error",("Got an empty hostname"));
add_wrong_ip(in);
+ my_gethostbyname_r_free();
DBUG_RETURN(0); // Don't allow empty hostnames
}
if (!(name=my_strdup(hp->h_name,MYF(0))))
+ {
+ my_gethostbyname_r_free();
DBUG_RETURN(0); // out of memory
-
+ }
+ my_gethostbyname_r_free();
#else
VOID(pthread_mutex_lock(&LOCK_hostname));
if (!(hp=gethostbyaddr((char*) in,sizeof(*in), AF_INET)))
diff --git a/sql/item.h b/sql/item.h
index 575af197e7d..1ce29748d2e 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -364,6 +364,25 @@ public:
};
+/*
+ The following class is used to optimize comparing of date columns
+ We need to save the original item, to be able to set the field to the
+ original value in 'opt_range'.
+*/
+
+class Item_int_with_ref :public Item_int
+{
+ Item *ref;
+public:
+ Item_int_with_ref(longlong i, Item *ref_arg) :Item_int(i), ref(ref_arg)
+ {}
+ bool save_in_field(Field *field)
+ {
+ return ref->save_in_field(field);
+ }
+};
+
+
#include "item_sum.h"
#include "item_func.h"
#include "item_cmpfunc.h"
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index c560e1de974..09c2bdc593a 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -25,9 +25,9 @@
#include <m_ctype.h>
/*
-** Test functions
-** These returns 0LL if false and 1LL if true and null if some arg is null
-** 'AND' and 'OR' never return null
+ Test functions
+ These returns 0LL if false and 1LL if true and null if some arg is null
+ 'AND' and 'OR' never return null
*/
longlong Item_func_not::val_int()
@@ -45,8 +45,8 @@ static bool convert_constant_item(Field *field, Item **item)
(*item)->save_in_field(field);
if (!((*item)->null_value))
{
- Item *tmp=new Item_int(field->val_int());
- if ((tmp))
+ Item *tmp=new Item_int_with_ref(field->val_int(), *item);
+ if (tmp)
*item=tmp;
return 1;
}
@@ -59,8 +59,10 @@ void Item_bool_func2::fix_length_and_dec()
{
max_length=1;
- /* As some compare functions are generated after sql_yacc,
- we have to check for out of memory conditons here */
+ /*
+ As some compare functions are generated after sql_yacc,
+ we have to check for out of memory conditons here
+ */
if (!args[0] || !args[1])
return;
// Make a special case of compare with fields to get nicer DATE comparisons
@@ -336,8 +338,10 @@ void Item_func_between::fix_length_and_dec()
{
max_length=1;
- /* As some compare functions are generated after sql_yacc,
- we have to check for out of memory conditons here */
+ /*
+ As some compare functions are generated after sql_yacc,
+ we have to check for out of memory conditons here
+ */
if (!args[0] || !args[1] || !args[2])
return;
cmp_type=args[0]->result_type();
@@ -389,7 +393,7 @@ longlong Item_func_between::val_int()
{
longlong value=args[0]->val_int(),a,b;
if ((null_value=args[0]->null_value))
- return 0; /* purecov: inspected */
+ return 0; /* purecov: inspected */
a=args[1]->val_int();
b=args[2]->val_int();
if (!args[1]->null_value && !args[2]->null_value)
@@ -409,7 +413,7 @@ longlong Item_func_between::val_int()
{
double value=args[0]->val(),a,b;
if ((null_value=args[0]->null_value))
- return 0; /* purecov: inspected */
+ return 0; /* purecov: inspected */
a=args[1]->val();
b=args[2]->val();
if (!args[1]->null_value && !args[2]->null_value)
@@ -594,11 +598,10 @@ Item_func_nullif::val_str(String *str)
}
/*
-** CASE expression
+ CASE expression
+ Return the matching ITEM or NULL if all compares (including else) failed
*/
-/* Return the matching ITEM or NULL if all compares (including else) failed */
-
Item *Item_func_case::find_item(String *str)
{
String *first_expr_str,*tmp;
@@ -786,7 +789,7 @@ void Item_func_case::print(String *str)
}
/*
-** Coalesce - return first not NULL argument.
+ Coalesce - return first not NULL argument.
*/
String *Item_func_coalesce::val_str(String *str)
@@ -842,7 +845,7 @@ void Item_func_coalesce::fix_length_and_dec()
}
/****************************************************************************
-** classes and function for the IN operator
+ Classes and function for the IN operator
****************************************************************************/
static int cmp_longlong(longlong *a,longlong *b)
@@ -915,7 +918,7 @@ byte *in_longlong::get_value(Item *item)
{
tmp=item->val_int();
if (item->null_value)
- return 0; /* purecov: inspected */
+ return 0; /* purecov: inspected */
return (byte*) &tmp;
}
@@ -933,7 +936,7 @@ byte *in_double::get_value(Item *item)
{
tmp=item->val();
if (item->null_value)
- return 0; /* purecov: inspected */
+ return 0; /* purecov: inspected */
return (byte*) &tmp;
}
@@ -1171,9 +1174,11 @@ longlong Item_cond_and::val_int()
{
if (item->val_int() == 0)
{
- /* TODO: In case of NULL, ANSI would require us to continue evaluation
- until we get a FALSE value or run out of values; This would
- require a lot of unnecessary evaluation, which we skip for now */
+ /*
+ TODO: In case of NULL, ANSI would require us to continue evaluation
+ until we get a FALSE value or run out of values; This would
+ require a lot of unnecessary evaluation, which we skip for now
+ */
null_value=item->null_value;
return 0;
}
@@ -1202,6 +1207,12 @@ longlong Item_cond_or::val_int()
longlong Item_func_isnull::val_int()
{
+ /*
+ Handle optimization if the argument can't be null
+ This has to be here because of the test in update_used_tables().
+ */
+ if (!used_tables_cache)
+ return cached_value;
return args[0]->is_null() ? 1: 0;
}
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index c9c7d5654d6..2048c4baea8 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -430,6 +430,7 @@ class Item_func_in :public Item_int_func
class Item_func_isnull :public Item_bool_func
{
+ longlong cached_value;
public:
Item_func_isnull(Item *a) :Item_bool_func(a) {}
longlong val_int();
@@ -450,6 +451,12 @@ public:
args[0]->update_used_tables();
used_tables_cache=args[0]->used_tables();
}
+ if (!used_tables_cache)
+ {
+ /* Remember if the value is always NULL or never NULL */
+ args[0]->val();
+ cached_value= args[0]->null_value ? (longlong) 1 : (longlong) 0;
+ }
}
optimize_type select_optimize() const { return OPTIMIZE_NULL; }
};
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index aa4140192ab..cc5902b4920 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -47,7 +47,7 @@ public:
Item_func_to_days(Item *a) :Item_int_func(a) {}
longlong val_int();
const char *func_name() const { return "to_days"; }
- void fix_length_and_dec() { decimals=0; max_length=6; }
+ void fix_length_and_dec() { decimals=0; max_length=6; maybe_null=1; }
};
diff --git a/sql/mini_client.cc b/sql/mini_client.cc
index c31fa573fea..ffb5d659238 100644
--- a/sql/mini_client.cc
+++ b/sql/mini_client.cc
@@ -620,7 +620,6 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
memcpy_fixed(&sock_addr.sin_addr,&ip_addr,sizeof(ip_addr));
}
else
-#if defined(HAVE_GETHOSTBYNAME_R) && defined(_REENTRANT) && defined(THREAD)
{
int tmp_errno;
struct hostent tmp_hostent,*hp;
@@ -631,22 +630,12 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
{
net->last_errno=CR_UNKNOWN_HOST;
sprintf(net->last_error, ER(CR_UNKNOWN_HOST), host, tmp_errno);
+ my_gethostbyname_r_free();
goto error;
}
memcpy(&sock_addr.sin_addr,hp->h_addr, (size_t) hp->h_length);
+ my_gethostbyname_r_free();
}
-#else
- {
- struct hostent *hp;
- if (!(hp=gethostbyname(host)))
- {
- net->last_errno=CR_UNKNOWN_HOST;
- sprintf(net->last_error, ER(CR_UNKNOWN_HOST), host, socket_errno);
- goto error;
- }
- memcpy(&sock_addr.sin_addr,hp->h_addr, (size_t) hp->h_length);
- }
-#endif
sock_addr.sin_port = (ushort) htons((ushort) port);
if (mc_sock_connect(sock,(struct sockaddr *) &sock_addr, sizeof(sock_addr),
mysql->options.connect_timeout) <0)
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 9c2eb9feb69..0b2d4ad76e8 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -1182,12 +1182,13 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
password=empty_string;
empty_string[0]=0;
+
if (combo.password.str && combo.password.str[0])
{
if (combo.password.length != HASH_PASSWORD_LENGTH)
{
- send_error(&thd->net, ER_PASSWORD_NO_MATCH);
- DBUG_RETURN(1);
+ my_error(ER_PASSWORD_NO_MATCH,MYF(0));
+ DBUG_RETURN(-1);
}
password=combo.password.str;
}
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index 9198cb4ba82..07e7c5e6680 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -310,6 +310,7 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db,
#endif
/* Remove last FN_LIBCHAR to not cause a problem on OS/2 */
pos=strend(path);
+
if (pos > path && pos[-1] == FN_LIBCHAR)
*--pos=0;
/* Don't give errors if we can't delete 'RAID' directory */
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 315c4b85a1c..87b7b0238b7 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -2862,9 +2862,9 @@ bool add_field_to_list(char *field_name, enum_field_types type,
uint sign_len=type_modifier & UNSIGNED_FLAG ? 0 : 1;
if (new_field->length && new_field->decimals &&
- new_field->length < new_field->decimals+2 &&
+ new_field->length < new_field->decimals+1 &&
new_field->decimals != NOT_FIXED_DEC)
- new_field->length=new_field->decimals+2; /* purecov: inspected */
+ new_field->length=new_field->decimals+1; /* purecov: inspected */
switch (type) {
case FIELD_TYPE_TINY:
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 670585fe443..ba07aab2859 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -2682,7 +2682,7 @@ describe:
}
opt_describe_column
| describe_command select
- { Lex->select_lex.options|= SELECT_DESCRIBE; };
+ { Lex->select_lex.options|= SELECT_DESCRIBE; };
describe_command: