summaryrefslogtreecommitdiff
path: root/sql/item.cc
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2011-06-15 21:48:38 -0700
committerIgor Babaev <igor@askmonty.org>2011-06-15 21:48:38 -0700
commit078b59f5bcb2f4f5d45451a40b798cc92913f7fb (patch)
tree3e1874756e544c0c0c4852ac5a6b3d5fe60b26bd /sql/item.cc
parenta9d73e093aa68351fd6776a892012deffa27fb7d (diff)
parentab411f8f1c2e84082623c038eb024c15c58745b5 (diff)
downloadmariadb-git-078b59f5bcb2f4f5d45451a40b798cc92913f7fb.tar.gz
Merge of mwl #106 into 5.3.
Diffstat (limited to 'sql/item.cc')
-rw-r--r--sql/item.cc121
1 files changed, 109 insertions, 12 deletions
diff --git a/sql/item.cc b/sql/item.cc
index 35e18ed68eb..cad3e60e5fc 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -735,7 +735,7 @@ void Item_ident::cleanup()
bool Item_ident::remove_dependence_processor(uchar * arg)
{
DBUG_ENTER("Item_ident::remove_dependence_processor");
- if (depended_from == (st_select_lex *) arg)
+ if (get_depended_from() == (st_select_lex *) arg)
depended_from= 0;
context= &((st_select_lex *) arg)->context;
DBUG_RETURN(0);
@@ -850,6 +850,23 @@ bool Item_field::register_field_in_bitmap(uchar *arg)
return 0;
}
+
+/*
+ Mark field in write_map
+
+ NOTES
+ This is used by UPDATE to register underlying fields of used view fields.
+*/
+
+bool Item_field::register_field_in_write_map(uchar *arg)
+{
+ TABLE *table= (TABLE *) arg;
+ if (field->table == table || !table)
+ bitmap_set_bit(field->table->write_set, field->field_index);
+ return 0;
+}
+
+
bool Item::check_cols(uint c)
{
if (c != 1)
@@ -2379,13 +2396,17 @@ table_map Item_field::used_tables() const
{
if (field->table->const_table)
return 0; // const item
- return (depended_from ? OUTER_REF_TABLE_BIT : field->table->map);
+ return (get_depended_from() ? OUTER_REF_TABLE_BIT : field->table->map);
}
+table_map Item_field::all_used_tables() const
+{
+ return (get_depended_from() ? OUTER_REF_TABLE_BIT : field->table->map);
+}
void Item_field::fix_after_pullout(st_select_lex *new_parent, Item **ref)
{
- if (new_parent == depended_from)
+ if (new_parent == get_depended_from())
depended_from= NULL;
Name_resolution_context *ctx= new Name_resolution_context();
ctx->outer_context= NULL; // We don't build a complete name resolver
@@ -2634,7 +2655,7 @@ my_decimal *Item_float::val_decimal(my_decimal *decimal_value)
void Item_string::print(String *str, enum_query_type query_type)
{
- if (query_type == QT_ORDINARY && is_cs_specified())
+ if (query_type != QT_IS && is_cs_specified())
{
str->append('_');
str->append(collation.collation->csname);
@@ -2642,7 +2663,7 @@ void Item_string::print(String *str, enum_query_type query_type)
str->append('\'');
- if (query_type == QT_ORDINARY ||
+ if (query_type != QT_IS ||
my_charset_same(str_value.charset(), system_charset_info))
{
str_value.print(str);
@@ -4140,6 +4161,34 @@ resolve_ref_in_select_and_group(THD *thd, Item_ident *ref, SELECT_LEX *select)
}
+/*
+ @brief
+ Whether a table belongs to an outer select.
+
+ @param table table to check
+ @param select current select
+
+ @details
+ Try to find select the table belongs to by ascending the derived tables chain.
+*/
+
+static
+bool is_outer_table(TABLE_LIST *table, SELECT_LEX *select)
+{
+ DBUG_ASSERT(table->select_lex != select);
+ TABLE_LIST *tl;
+
+ for (tl= select->master_unit()->derived;
+ tl && tl->is_merged_derived();
+ select= tl->select_lex, tl= select->master_unit()->derived)
+ {
+ if (tl->select_lex == table->select_lex)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
/**
Resolve the name of an outer select column reference.
@@ -4588,7 +4637,8 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
if (!outer_fixed && cached_table && cached_table->select_lex &&
context->select_lex &&
- cached_table->select_lex != context->select_lex)
+ cached_table->select_lex != context->select_lex &&
+ is_outer_table(cached_table, context->select_lex))
{
int ret;
if ((ret= fix_outer_field(thd, &from_field, reference)) < 0)
@@ -6051,8 +6101,9 @@ public:
st_select_lex *sel;
for (sel= current_select; sel; sel= sel->outer_select())
{
+ List_iterator<TABLE_LIST> li(sel->leaf_tables);
TABLE_LIST *tbl;
- for (tbl= sel->leaf_tables; tbl; tbl= tbl->next_leaf)
+ while ((tbl= li++))
{
if (tbl->table == item->field->table)
{
@@ -6347,12 +6398,13 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
last_checked_context->select_lex->nest_level);
}
}
- else
+ else if (ref_type() != VIEW_REF)
{
if (depended_from && reference)
{
- DBUG_ASSERT(context->select_lex != depended_from);
- context->select_lex->register_dependency_item(depended_from, reference);
+ DBUG_ASSERT(context->select_lex != get_depended_from());
+ context->select_lex->register_dependency_item(get_depended_from(),
+ reference);
}
/*
It could be that we're referring to something that's in ancestor selects.
@@ -7299,7 +7351,7 @@ bool Item_outer_ref::fix_fields(THD *thd, Item **reference)
void Item_outer_ref::fix_after_pullout(st_select_lex *new_parent, Item **ref)
{
- if (depended_from == new_parent)
+ if (get_depended_from() == new_parent)
{
*ref= outer_ref;
(*ref)->fix_after_pullout(new_parent, ref);
@@ -7309,7 +7361,7 @@ void Item_outer_ref::fix_after_pullout(st_select_lex *new_parent, Item **ref)
void Item_ref::fix_after_pullout(st_select_lex *new_parent, Item **refptr)
{
(*ref)->fix_after_pullout(new_parent, ref);
- if (depended_from == new_parent)
+ if (get_depended_from() == new_parent)
depended_from= NULL;
}
@@ -8650,6 +8702,8 @@ Item_result Item_type_holder::result_type() const
enum_field_types Item_type_holder::get_real_type(Item *item)
{
+ if (item->type() == REF_ITEM)
+ item= item->real_item();
switch(item->type())
{
case FIELD_ITEM:
@@ -9025,6 +9079,49 @@ void view_error_processor(THD *thd, void *data)
((TABLE_LIST *)data)->hide_view_error(thd);
}
+
+st_select_lex *Item_ident::get_depended_from() const
+{
+ st_select_lex *dep;
+ if ((dep= depended_from))
+ for ( ; dep->merged_into; dep= dep->merged_into) ;
+ return dep;
+}
+
+
+table_map Item_ref::used_tables() const
+{
+ return get_depended_from() ? OUTER_REF_TABLE_BIT : (*ref)->used_tables();
+}
+
+
+void Item_ref::update_used_tables()
+{
+ if (!get_depended_from())
+ (*ref)->update_used_tables();
+}
+
+
+table_map Item_direct_view_ref::used_tables() const
+{
+ return get_depended_from() ?
+ OUTER_REF_TABLE_BIT :
+ (view->merged ? (*ref)->used_tables() : view->table->map);
+}
+
+
+/*
+ we add RAND_TABLE_BIT to prevent moving this item from HAVING to WHERE
+*/
+table_map Item_ref_null_helper::used_tables() const
+{
+ return (get_depended_from() ?
+ OUTER_REF_TABLE_BIT :
+ (*ref)->used_tables() | RAND_TABLE_BIT);
+}
+
+
+
/*****************************************************************************
** Instantiate templates
*****************************************************************************/