diff options
author | unknown <monty@hundin.mysql.fi> | 2002-05-16 18:20:49 +0300 |
---|---|---|
committer | unknown <monty@hundin.mysql.fi> | 2002-05-16 18:20:49 +0300 |
commit | 4d094257dbb785d792785e610ab3cdf41eae9b8c (patch) | |
tree | 12de711f3f9d8ad9eee9d28cf71e5487f17315d3 /sql | |
parent | 2618c6963c5bf1349c47ce3af6e55213ea9773f4 (diff) | |
parent | 74d29a07712a0caf57fca62dacfeb14b110beca4 (diff) | |
download | mariadb-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.cc | 48 | ||||
-rw-r--r-- | sql/hostname.cc | 7 | ||||
-rw-r--r-- | sql/item.h | 19 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 53 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 7 | ||||
-rw-r--r-- | sql/item_timefunc.h | 2 | ||||
-rw-r--r-- | sql/mini_client.cc | 15 | ||||
-rw-r--r-- | sql/sql_acl.cc | 5 | ||||
-rw-r--r-- | sql/sql_db.cc | 1 | ||||
-rw-r--r-- | sql/sql_parse.cc | 4 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 2 |
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: |