summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorJonathan Perkin <jonathan.perkin@oracle.com>2011-02-08 14:43:27 +0100
committerJonathan Perkin <jonathan.perkin@oracle.com>2011-02-08 14:43:27 +0100
commitd2495d17961995cf661ff7e1e89738b922fefe93 (patch)
treeb84e667b7060882e689e2c7e28066b7f09723869 /sql
parent0a8419dfdd6d80b6029c354fb0a82683b2fef617 (diff)
parentb831c6dbbb29a9dc7dd3e3b7910f5b39e96fe2af (diff)
downloadmariadb-git-d2495d17961995cf661ff7e1e89738b922fefe93.tar.gz
Merge from mysql-5.0.92-release
Diffstat (limited to 'sql')
-rw-r--r--sql/field.cc2
-rw-r--r--sql/item_cmpfunc.cc9
-rw-r--r--sql/item_func.cc26
-rw-r--r--sql/item_func.h1
-rw-r--r--sql/sql_base.cc12
-rw-r--r--sql/sql_select.cc27
-rw-r--r--sql/sql_select.h1
7 files changed, 63 insertions, 15 deletions
diff --git a/sql/field.cc b/sql/field.cc
index 0b74f9e5a65..5cbbf98eedd 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -1365,7 +1365,7 @@ void Field::make_field(Send_field *field)
}
else
field->org_table_name= field->db_name= "";
- if (orig_table)
+ if (orig_table && orig_table->alias)
{
field->table_name= orig_table->alias;
field->org_col_name= field_name;
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 60c8cbdad45..4eb41b40994 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -4220,13 +4220,14 @@ Item_func::optimize_type Item_func_like::select_optimize() const
if (args[1]->const_item())
{
String* res2= args[1]->val_str((String *)&tmp_value2);
+ const char *ptr2;
- if (!res2)
+ if (!res2 || !(ptr2= res2->ptr()))
return OPTIMIZE_NONE;
- if (*res2->ptr() != wild_many)
+ if (*ptr2 != wild_many)
{
- if (args[0]->result_type() != STRING_RESULT || *res2->ptr() != wild_one)
+ if (args[0]->result_type() != STRING_RESULT || *ptr2 != wild_one)
return OPTIMIZE_OP;
}
}
@@ -4247,7 +4248,7 @@ bool Item_func_like::fix_fields(THD *thd, Item **ref)
return TRUE;
}
- if (escape_item->const_item())
+ if (escape_item->const_item() && !thd->lex->view_prepare_mode)
{
/* If we are on execution stage */
String *escape_str= escape_item->val_str(&tmp_value1);
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 579ef44b14f..b8893ac12dc 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -2250,6 +2250,8 @@ void Item_func_min_max::fix_length_and_dec()
else if ((cmp_type == DECIMAL_RESULT) || (cmp_type == INT_RESULT))
max_length= my_decimal_precision_to_length(max_int_part+decimals, decimals,
unsigned_flag);
+ else if (cmp_type == REAL_RESULT)
+ max_length= float_length(decimals);
cached_field_type= agg_field_type(args, arg_count);
}
@@ -2268,7 +2270,7 @@ void Item_func_min_max::fix_length_and_dec()
stored to the value pointer, if latter is provided.
RETURN
- 0 If one of arguments is NULL
+ 0 If one of arguments is NULL or there was a execution error
# index of the least/greatest argument
*/
@@ -2282,6 +2284,14 @@ uint Item_func_min_max::cmp_datetimes(ulonglong *value)
Item **arg= args + i;
bool is_null;
longlong res= get_datetime_value(thd, &arg, 0, datetime_item, &is_null);
+
+ /* Check if we need to stop (because of error or KILL) and stop the loop */
+ if (thd->net.report_error)
+ {
+ null_value= 1;
+ return 0;
+ }
+
if ((null_value= args[i]->null_value))
return 0;
if (i == 0 || (res < min_max ? cmp_sign : -cmp_sign) > 0)
@@ -2310,6 +2320,12 @@ String *Item_func_min_max::val_str(String *str)
if (null_value)
return 0;
str_res= args[min_max_idx]->val_str(str);
+ if (args[min_max_idx]->null_value)
+ {
+ // check if the call to val_str() above returns a NULL value
+ null_value= 1;
+ return NULL;
+ }
str_res->set_charset(collation.collation);
return str_res;
}
@@ -4301,6 +4317,14 @@ longlong Item_func_set_user_var::val_int_result()
return entry->val_int(&null_value);
}
+bool Item_func_set_user_var::val_bool_result()
+{
+ DBUG_ASSERT(fixed == 1);
+ check(TRUE);
+ update(); // Store expression
+ return entry->val_int(&null_value) != 0;
+}
+
String *Item_func_set_user_var::str_result(String *str)
{
DBUG_ASSERT(fixed == 1);
diff --git a/sql/item_func.h b/sql/item_func.h
index 96af2602821..b36124691ed 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -1300,6 +1300,7 @@ public:
my_decimal *val_decimal(my_decimal *);
double val_result();
longlong val_int_result();
+ bool val_bool_result();
String *str_result(String *str);
my_decimal *val_decimal_result(my_decimal *);
bool is_null_result();
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 4a1d3a96ef8..7ba7a084599 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -3657,6 +3657,8 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
/*
Find field by name in a base table or a view with temp table algorithm.
+ The caller is expected to check column-level privileges.
+
SYNOPSIS
find_field_in_table()
thd thread handler
@@ -3753,6 +3755,8 @@ find_field_in_table(THD *thd, TABLE *table, const char *name, uint length,
This procedure detects the type of the table reference 'table_list'
and calls the corresponding search routine.
+ The routine checks column-level privieleges for the found field.
+
RETURN
0 field is not found
view_ref_found found value in VIEW (real result is in *ref)
@@ -3944,8 +3948,16 @@ find_field_in_tables(THD *thd, Item_ident *item,
when table_ref->field_translation != NULL.
*/
if (table_ref->table && !table_ref->view)
+ {
found= find_field_in_table(thd, table_ref->table, name, length,
TRUE, &(item->cached_field_index));
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ /* Check if there are sufficient access rights to the found field. */
+ if (found && check_privileges &&
+ check_column_grant_in_table_ref(thd, table_ref, name, length))
+ found= WRONG_GRANT;
+#endif
+ }
else
found= find_field_in_table_ref(thd, table_ref, name, length, item->name,
NULL, NULL, ref, check_privileges,
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 904610b9031..cb7add3a874 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -501,7 +501,7 @@ JOIN::prepare(Item ***rref_pointer_array,
thd->lex->allow_sum_func= save_allow_sum_func;
}
- if (!thd->lex->view_prepare_mode)
+ if (!thd->lex->view_prepare_mode && !(select_options & SELECT_DESCRIBE))
{
Item_subselect *subselect;
/* Is it subselect? */
@@ -2226,13 +2226,8 @@ JOIN::destroy()
cleanup(1);
/* Cleanup items referencing temporary table columns */
- if (!tmp_all_fields3.is_empty())
- {
- List_iterator_fast<Item> it(tmp_all_fields3);
- Item *item;
- while ((item= it++))
- item->cleanup();
- }
+ cleanup_item_list(tmp_all_fields1);
+ cleanup_item_list(tmp_all_fields3);
if (exec_tmp_table1)
free_tmp_table(thd, exec_tmp_table1);
if (exec_tmp_table2)
@@ -2243,6 +2238,19 @@ JOIN::destroy()
DBUG_RETURN(error);
}
+
+void JOIN::cleanup_item_list(List<Item> &items) const
+{
+ if (!items.is_empty())
+ {
+ List_iterator_fast<Item> it(items);
+ Item *item;
+ while ((item= it++))
+ item->cleanup();
+ }
+}
+
+
/*
An entry point to single-unit select (a select without UNION).
@@ -6861,7 +6869,8 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond,
*simple_order=0; // Must do a temp table to sort
else if (!(order_tables & not_const_tables))
{
- if (order->item[0]->with_subselect)
+ if (order->item[0]->with_subselect &&
+ !(join->select_lex->options & SELECT_DESCRIBE))
order->item[0]->val_str(&order->item[0]->str_value);
DBUG_PRINT("info",("removing: %s", order->item[0]->full_name()));
continue; // skip const item
diff --git a/sql/sql_select.h b/sql/sql_select.h
index a885507446e..15dc57a3eb1 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -489,6 +489,7 @@ public:
}
private:
bool make_simple_join(JOIN *join, TABLE *tmp_table);
+ void cleanup_item_list(List<Item> &items) const;
};