summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <bell@sanja.is.com.ua>2005-04-30 19:32:45 +0300
committerunknown <bell@sanja.is.com.ua>2005-04-30 19:32:45 +0300
commit371b26e11c2a982dc3025481f743bd7d4c636f0a (patch)
treeeac9f0e2faf22dcc7105d6142721bebde96422b4 /sql
parentd45f95f04ab8011d2d1c7fe361ec4df3dbdbe697 (diff)
parentd1d474c812a1020af48bebe6ecc68bdc51d0674c (diff)
downloadmariadb-git-371b26e11c2a982dc3025481f743bd7d4c636f0a.tar.gz
Merge sanja.is.com.ua:/home/bell/mysql/bk/mysql-5.0
into sanja.is.com.ua:/home/bell/mysql/bk/work-test-5.0 sql/item.h: Auto merged
Diffstat (limited to 'sql')
-rw-r--r--sql/field.h2
-rw-r--r--sql/handler.cc7
-rw-r--r--sql/hostname.cc9
-rw-r--r--sql/item.h7
-rw-r--r--sql/item_func.cc88
-rw-r--r--sql/item_func.h10
-rw-r--r--sql/sql_insert.cc4
-rw-r--r--sql/sql_select.cc12
-rw-r--r--sql/unireg.cc7
9 files changed, 122 insertions, 24 deletions
diff --git a/sql/field.h b/sql/field.h
index 0f1cc0b95aa..ac9c2f351b3 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -118,6 +118,7 @@ public:
String *val_int_as_str(String *val_buffer, my_bool unsigned_flag);
virtual Item_result result_type () const=0;
virtual Item_result cmp_type () const { return result_type(); }
+ virtual Item_result cast_to_int_type () const { return result_type(); }
static enum_field_types field_type_merge(enum_field_types, enum_field_types);
static Item_result result_merge_type(enum_field_types);
bool eq(Field *field)
@@ -1216,6 +1217,7 @@ public:
}
enum_field_types type() const { return FIELD_TYPE_STRING; }
enum Item_result cmp_type () const { return INT_RESULT; }
+ enum Item_result cast_to_int_type () const { return INT_RESULT; }
enum ha_base_keytype key_type() const;
int store(const char *to,uint length,CHARSET_INFO *charset);
int store(double nr);
diff --git a/sql/handler.cc b/sql/handler.cc
index d2501afe97a..7318de1c503 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -185,9 +185,10 @@ enum db_type ha_checktype(enum db_type database_type)
thd= current_thd;
return ((enum db_type) thd->variables.table_type != DB_TYPE_UNKNOWN ?
(enum db_type) thd->variables.table_type :
- (enum db_type) global_system_variables.table_type !=
- DB_TYPE_UNKNOWN ?
- (enum db_type) global_system_variables.table_type : DB_TYPE_MYISAM);
+ ((enum db_type) global_system_variables.table_type !=
+ DB_TYPE_UNKNOWN ?
+ (enum db_type) global_system_variables.table_type : DB_TYPE_MYISAM)
+ );
} /* ha_checktype */
diff --git a/sql/hostname.cc b/sql/hostname.cc
index c74d230bbcb..fe2fad6f3b2 100644
--- a/sql/hostname.cc
+++ b/sql/hostname.cc
@@ -177,7 +177,14 @@ my_string ip_to_hostname(struct in_addr *in, uint *errors)
&tmp_errno)))
{
DBUG_PRINT("error",("gethostbyname_r returned %d",tmp_errno));
- add_wrong_ip(in);
+ /*
+ Don't cache responses when the DSN server is down, as otherwise
+ transient DNS failure may leave any number of clients (those
+ that attempted to connect during the outage) unable to connect
+ indefinitely.
+ */
+ if (tmp_errno == HOST_NOT_FOUND || tmp_error == NO_DATA)
+ add_wrong_ip(in);
my_gethostbyname_r_free();
DBUG_RETURN(0);
}
diff --git a/sql/item.h b/sql/item.h
index fd7c6d0edc3..f762896ba34 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -302,7 +302,8 @@ public:
{ return save_in_field(field, 1); }
virtual bool send(Protocol *protocol, String *str);
virtual bool eq(const Item *, bool binary_cmp) const;
- virtual Item_result result_type () const { return REAL_RESULT; }
+ virtual Item_result result_type() const { return REAL_RESULT; }
+ virtual Item_result cast_to_int_type() const { return result_type(); }
virtual enum_field_types field_type() const;
virtual enum Type type() const =0;
/* valXXX methods must return NULL or 0 or 0.0 if null_value is set. */
@@ -738,6 +739,10 @@ public:
{
return field->result_type();
}
+ Item_result cast_to_int_type() const
+ {
+ return field->cast_to_int_type();
+ }
enum_field_types field_type() const
{
return field->type();
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 24a3f7927ae..c2afc2fd685 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -904,6 +904,58 @@ void Item_func_signed::print(String *str)
}
+longlong Item_func_signed::val_int_from_str(int *error)
+{
+ char buff[MAX_FIELD_WIDTH], *end;
+ String tmp(buff,sizeof(buff), &my_charset_bin), *res;
+ longlong value;
+
+ /*
+ For a string result, we must first get the string and then convert it
+ to a longlong
+ */
+
+ if (!(res= args[0]->val_str(&tmp)))
+ {
+ null_value= 1;
+ *error= 0;
+ return 0;
+ }
+ null_value= 0;
+ end= (char*) res->ptr()+ res->length();
+ value= my_strtoll10(res->ptr(), &end, error);
+ if (*error > 0 || end != res->ptr()+ res->length())
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_TRUNCATED_WRONG_VALUE,
+ ER(ER_TRUNCATED_WRONG_VALUE), "INTEGER",
+ res->c_ptr());
+ return value;
+}
+
+
+longlong Item_func_signed::val_int()
+{
+ longlong value;
+ int error;
+
+ if (args[0]->cast_to_int_type() != STRING_RESULT)
+ {
+ value= args[0]->val_int();
+ null_value= args[0]->null_value;
+ return value;
+ }
+
+ value= val_int_from_str(&error);
+ if (value < 0 && error == 0)
+ {
+ push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
+ "Cast to signed converted positive out-of-range integer to "
+ "it's negative complement");
+ }
+ return value;
+}
+
+
void Item_func_unsigned::print(String *str)
{
str->append("cast(", 5);
@@ -913,6 +965,27 @@ void Item_func_unsigned::print(String *str)
}
+longlong Item_func_unsigned::val_int()
+{
+ longlong value;
+ int error;
+
+ if (args[0]->cast_to_int_type() != STRING_RESULT)
+ {
+ value= args[0]->val_int();
+ null_value= args[0]->null_value;
+ return value;
+ }
+
+ value= val_int_from_str(&error);
+ if (error < 0)
+ push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
+ "Cast to unsigned converted negative integer to it's "
+ "positive complement");
+ return value;
+}
+
+
String *Item_decimal_typecast::val_str(String *str)
{
my_decimal tmp_buf, *tmp= val_decimal(&tmp_buf);
@@ -3271,7 +3344,8 @@ bool Item_func_set_user_var::fix_fields(THD *thd, TABLE_LIST *tables,
from the argument if the argument is NULL
and the variable has previously been initialized.
*/
- if (!entry->collation.collation || !args[0]->null_value)
+ null_item= (args[0]->type() == NULL_ITEM);
+ if (!entry->collation.collation || !null_item)
entry->collation.set(args[0]->collation.collation, DERIVATION_IMPLICIT);
collation.set(entry->collation.collation, DERIVATION_IMPLICIT);
cached_result_type= args[0]->result_type();
@@ -3315,8 +3389,8 @@ update_hash(user_var_entry *entry, bool set_null, void *ptr, uint length,
char *pos= (char*) entry+ ALIGN_SIZE(sizeof(user_var_entry));
if (entry->value && entry->value != pos)
my_free(entry->value,MYF(0));
- entry->value=0;
- entry->length=0;
+ entry->value= 0;
+ entry->length= 0;
}
else
{
@@ -3355,9 +3429,9 @@ update_hash(user_var_entry *entry, bool set_null, void *ptr, uint length,
if (type == DECIMAL_RESULT)
((my_decimal*)entry->value)->fix_buffer_pointer();
entry->length= length;
- entry->type=type;
entry->collation.set(cs, dv);
}
+ entry->type=type;
return 0;
}
@@ -3366,6 +3440,12 @@ bool
Item_func_set_user_var::update_hash(void *ptr, uint length, Item_result type,
CHARSET_INFO *cs, Derivation dv)
{
+ /*
+ If we set a variable explicitely to NULL then keep the old
+ result type of the variable
+ */
+ if ((null_value= args[0]->null_value) && null_item)
+ type= entry->type; // Don't change type of item
if (::update_hash(entry, (null_value= args[0]->null_value),
ptr, length, type, cs, dv))
{
diff --git a/sql/item_func.h b/sql/item_func.h
index cb0b7dc02a4..76d1151f3bf 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -262,12 +262,8 @@ public:
null_value= args[0]->null_value;
return tmp;
}
- longlong val_int()
- {
- longlong tmp= args[0]->val_int();
- null_value= args[0]->null_value;
- return tmp;
- }
+ longlong val_int();
+ longlong val_int_from_str(int *error);
void fix_length_and_dec()
{ max_length=args[0]->max_length; unsigned_flag=0; }
void print(String *str);
@@ -281,6 +277,7 @@ public:
const char *func_name() const { return "cast_as_unsigned"; }
void fix_length_and_dec()
{ max_length=args[0]->max_length; unsigned_flag=1; }
+ longlong val_int();
void print(String *str);
};
@@ -1071,6 +1068,7 @@ class Item_func_set_user_var :public Item_func
char buffer[MAX_FIELD_WIDTH];
String value;
my_decimal decimal_buff;
+ bool null_item;
union
{
longlong vint;
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index ac8f5a06745..729f9751bba 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -89,7 +89,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
}
if (values.elements != table->s->fields)
{
- my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1);
+ my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1L);
return -1;
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
@@ -112,7 +112,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
int res;
if (fields.elements != values.elements)
{
- my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1);
+ my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1L);
return -1;
}
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 49e77e1c2dd..fa774c6d89e 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -2492,8 +2492,8 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end,
KEY_OPTIMIZE_EXISTS) |
((old->optimize | new_fields->optimize) &
KEY_OPTIMIZE_REF_OR_NULL));
- old->null_rejecting= old->null_rejecting &&
- new_fields->null_rejecting;
+ old->null_rejecting= (old->null_rejecting &&
+ new_fields->null_rejecting);
}
}
else if (old->eq_func && new_fields->eq_func &&
@@ -2505,8 +2505,8 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end,
KEY_OPTIMIZE_EXISTS) |
((old->optimize | new_fields->optimize) &
KEY_OPTIMIZE_REF_OR_NULL));
- old->null_rejecting= old->null_rejecting &&
- new_fields->null_rejecting;
+ old->null_rejecting= (old->null_rejecting &&
+ new_fields->null_rejecting);
}
else if (old->eq_func && new_fields->eq_func &&
(old->val->is_null() || new_fields->val->is_null()))
@@ -2518,7 +2518,7 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end,
if (old->val->is_null())
old->val= new_fields->val;
/* The referred expression can be NULL: */
- old->null_rejecting= false;
+ old->null_rejecting= 0;
}
else
{
@@ -2680,6 +2680,8 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond,
If the condition has form "tbl.keypart = othertbl.field" and
othertbl.field can be NULL, there will be no matches if othertbl.field
has NULL value.
+ We use null_rejecting in add_not_null_conds() to add
+ 'othertbl.field IS NOT NULL' to tab->select_cond.
*/
(*key_fields)->null_rejecting= (cond->functype() == Item_func::EQ_FUNC) &&
((*value)->type() == Item::FIELD_ITEM) &&
diff --git a/sql/unireg.cc b/sql/unireg.cc
index 929ca5c672e..95a383e0f01 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -685,6 +685,9 @@ static bool make_empty_rec(THD *thd, File file,enum db_type table_type,
thd->count_cuted_fields= CHECK_FIELD_WARN; // To find wrong default values
while ((field=it++))
{
+ /*
+ regfield don't have to be deleted as it's allocated with sql_alloc()
+ */
Field *regfield=make_field((char*) buff+field->offset,field->length,
null_pos,
null_count & 7,
@@ -696,7 +699,8 @@ static bool make_empty_rec(THD *thd, File file,enum db_type table_type,
field->interval,
field->field_name,
&table);
- DBUG_ASSERT(regfield);
+ if (!regfield)
+ goto err; // End of memory
if (!(field->flags & NOT_NULL_FLAG))
null_count++;
@@ -730,7 +734,6 @@ static bool make_empty_rec(THD *thd, File file,enum db_type table_type,
regfield->store(ER(ER_NO), (uint) strlen(ER(ER_NO)),system_charset_info);
else
regfield->reset();
- delete regfield;
}
/* Fill not used startpos */