summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2012-05-04 07:16:38 +0200
committerSergei Golubchik <sergii@pisem.net>2012-05-04 07:16:38 +0200
commit44cf9ee5f7acd2148dc32f4eee4519a087c52b93 (patch)
tree5b67e89f11e9cdac90d6cc13655e61a55400addd /sql
parent550d6871a5eb93013435055e11a4fe3009490c82 (diff)
parentd335b471918b4ab0bca05984a70669653cf3169f (diff)
downloadmariadb-git-44cf9ee5f7acd2148dc32f4eee4519a087c52b93.tar.gz
5.3 merge
Diffstat (limited to 'sql')
-rw-r--r--sql/innodb_priv.h36
-rw-r--r--sql/item.cc2
-rw-r--r--sql/item_cmpfunc.h1
-rw-r--r--sql/item_subselect.cc71
-rw-r--r--sql/item_subselect.h10
-rw-r--r--sql/opt_subselect.cc11
-rw-r--r--sql/opt_subselect.h4
-rw-r--r--sql/parse_file.cc51
-rw-r--r--sql/parse_file.h1
-rw-r--r--sql/slave.cc5
-rw-r--r--sql/sql_acl.cc8
-rw-r--r--sql/sql_base.cc5
-rw-r--r--sql/sql_lex.cc15
-rw-r--r--sql/sql_select.cc17
-rw-r--r--sql/sql_select.h3
-rw-r--r--sql/sql_update.cc4
-rw-r--r--sql/sql_view.cc2
-rw-r--r--sql/table.cc3
-rw-r--r--sql/table.h17
19 files changed, 222 insertions, 44 deletions
diff --git a/sql/innodb_priv.h b/sql/innodb_priv.h
new file mode 100644
index 00000000000..5406c292b18
--- /dev/null
+++ b/sql/innodb_priv.h
@@ -0,0 +1,36 @@
+/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#ifndef INNODB_PRIV_INCLUDED
+#define INNODB_PRIV_INCLUDED
+
+/** @file Declaring server-internal functions that are used by InnoDB. */
+
+#include <sql_priv.h>
+
+class THD;
+
+int get_quote_char_for_identifier(THD *thd, const char *name, uint length);
+bool schema_table_store_record(THD *thd, TABLE *table);
+void localtime_to_TIME(MYSQL_TIME *to, struct tm *from);
+bool check_global_access(THD *thd, ulong want_access);
+uint strconvert(CHARSET_INFO *from_cs, const char *from,
+ CHARSET_INFO *to_cs, char *to, uint to_length,
+ uint *errors);
+void sql_print_error(const char *format, ...);
+
+
+
+#endif /* INNODB_PRIV_INCLUDED */
diff --git a/sql/item.cc b/sql/item.cc
index f9032c79c12..9400af0f79f 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -8787,7 +8787,7 @@ bool Item_cache_temporal::cache_value()
value_cached= true;
MYSQL_TIME ltime;
- if (example->get_date(&ltime, TIME_FUZZY_DATE))
+ if (example->get_date_result(&ltime, TIME_FUZZY_DATE))
value=0;
else
value= pack_time(&ltime);
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 5558b77d67d..b9740c7af03 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -1560,6 +1560,7 @@ public:
friend int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
COND **conds);
void top_level_item() { abort_on_null=1; }
+ bool top_level() { return abort_on_null; }
void copy_andor_arguments(THD *thd, Item_cond *item);
bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
Item *transform(Item_transformer transformer, uchar *arg);
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index b1829c1892a..276f35fe301 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -769,7 +769,8 @@ void Item_subselect::fix_length_and_dec()
table_map Item_subselect::used_tables() const
{
- return (table_map) (engine->uncacheable() ? used_tables_cache : 0L);
+ return (table_map) ((engine->uncacheable() & ~UNCACHEABLE_EXPLAIN)?
+ used_tables_cache : 0L);
}
@@ -900,6 +901,15 @@ void Item_maxmin_subselect::print(String *str, enum_query_type query_type)
}
+void Item_maxmin_subselect::no_rows_in_result()
+{
+ value= 0;
+ null_value= 0;
+ was_values= 0;
+ make_const();
+}
+
+
void Item_singlerow_subselect::reset()
{
Item_subselect::reset();
@@ -1095,6 +1105,8 @@ void Item_singlerow_subselect::bring_value()
double Item_singlerow_subselect::val_real()
{
DBUG_ASSERT(fixed == 1);
+ if (forced_const)
+ return value->val_real();
if (!exec() && !value->null_value)
{
null_value= FALSE;
@@ -1110,6 +1122,8 @@ double Item_singlerow_subselect::val_real()
longlong Item_singlerow_subselect::val_int()
{
DBUG_ASSERT(fixed == 1);
+ if (forced_const)
+ return value->val_int();
if (!exec() && !value->null_value)
{
null_value= FALSE;
@@ -1124,6 +1138,9 @@ longlong Item_singlerow_subselect::val_int()
String *Item_singlerow_subselect::val_str(String *str)
{
+ DBUG_ASSERT(fixed == 1);
+ if (forced_const)
+ return value->val_str(str);
if (!exec() && !value->null_value)
{
null_value= FALSE;
@@ -1139,6 +1156,9 @@ String *Item_singlerow_subselect::val_str(String *str)
my_decimal *Item_singlerow_subselect::val_decimal(my_decimal *decimal_value)
{
+ DBUG_ASSERT(fixed == 1);
+ if (forced_const)
+ return value->val_decimal(decimal_value);
if (!exec() && !value->null_value)
{
null_value= FALSE;
@@ -1154,6 +1174,9 @@ my_decimal *Item_singlerow_subselect::val_decimal(my_decimal *decimal_value)
bool Item_singlerow_subselect::val_bool()
{
+ DBUG_ASSERT(fixed == 1);
+ if (forced_const)
+ return value->val_bool();
if (!exec() && !value->null_value)
{
null_value= FALSE;
@@ -1167,6 +1190,24 @@ bool Item_singlerow_subselect::val_bool()
}
+bool Item_singlerow_subselect::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate)
+{
+ DBUG_ASSERT(fixed == 1);
+ if (forced_const)
+ return value->get_date(ltime, fuzzydate);
+ if (!exec() && !value->null_value)
+ {
+ null_value= FALSE;
+ return value->get_date(ltime, fuzzydate);
+ }
+ else
+ {
+ reset();
+ return 0;
+ }
+}
+
+
Item_exists_subselect::Item_exists_subselect(st_select_lex *select_lex):
Item_subselect()
{
@@ -1323,10 +1364,17 @@ Item* Item_exists_subselect::expr_cache_insert_transformer(uchar *thd_arg)
}
+void Item_exists_subselect::no_rows_in_result()
+{
+ value= 0;
+ null_value= 0;
+ make_const();
+}
+
double Item_exists_subselect::val_real()
{
DBUG_ASSERT(fixed == 1);
- if (exec())
+ if (!forced_const && exec())
{
reset();
return 0;
@@ -1337,7 +1385,7 @@ double Item_exists_subselect::val_real()
longlong Item_exists_subselect::val_int()
{
DBUG_ASSERT(fixed == 1);
- if (exec())
+ if (!forced_const && exec())
{
reset();
return 0;
@@ -1362,7 +1410,7 @@ longlong Item_exists_subselect::val_int()
String *Item_exists_subselect::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
- if (exec())
+ if (!forced_const && exec())
reset();
str->set((ulonglong)value,&my_charset_bin);
return str;
@@ -1385,7 +1433,7 @@ String *Item_exists_subselect::val_str(String *str)
my_decimal *Item_exists_subselect::val_decimal(my_decimal *decimal_value)
{
DBUG_ASSERT(fixed == 1);
- if (exec())
+ if (!forced_const && exec())
reset();
int2my_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
return decimal_value;
@@ -1395,7 +1443,7 @@ my_decimal *Item_exists_subselect::val_decimal(my_decimal *decimal_value)
bool Item_exists_subselect::val_bool()
{
DBUG_ASSERT(fixed == 1);
- if (exec())
+ if (!forced_const && exec())
{
reset();
return 0;
@@ -2660,6 +2708,15 @@ void Item_allany_subselect::print(String *str, enum_query_type query_type)
}
+void Item_allany_subselect::no_rows_in_result()
+{
+ value= 0;
+ null_value= 0;
+ was_null= 0;
+ make_const();
+}
+
+
void subselect_engine::set_thd(THD *thd_arg)
{
thd= thd_arg;
@@ -2869,7 +2926,7 @@ void subselect_engine::set_row(List<Item> &item_list, Item_cache **row)
item->decimals= sel_item->decimals;
item->unsigned_flag= sel_item->unsigned_flag;
maybe_null= sel_item->maybe_null;
- if (!(row[i]= Item_cache::get_cache(sel_item)))
+ if (!(row[i]= Item_cache::get_cache(sel_item, sel_item->cmp_type())))
return;
row[i]->setup(sel_item);
//psergey-backport-timours: row[i]->store(sel_item);
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index 57f413f1ccd..1a4c8a25a01 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -158,6 +158,11 @@ public:
eliminated= FALSE;
null_value= 1;
}
+ /**
+ Set the subquery result to the default value for the predicate when the
+ subquery is known to produce an empty result.
+ */
+ void no_rows_in_result()= 0;
virtual bool select_transformer(JOIN *join);
bool assigned() { return value_assigned; }
void assigned(bool a) { value_assigned= a; }
@@ -274,6 +279,7 @@ public:
subs_type substype() { return SINGLEROW_SUBS; }
void reset();
+ void no_rows_in_result() { reset(); make_const(); }
bool select_transformer(JOIN *join);
void store(uint i, Item* item);
double val_real();
@@ -281,6 +287,7 @@ public:
String *val_str (String *);
my_decimal *val_decimal(my_decimal *);
bool val_bool();
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
enum Item_result result_type() const;
enum_field_types field_type() const;
void fix_length_and_dec();
@@ -326,6 +333,7 @@ public:
bool any_value() { return was_values; }
void register_value() { was_values= TRUE; }
void reset_value_registration() { was_values= FALSE; }
+ void no_rows_in_result();
};
/* exists subselect */
@@ -347,6 +355,7 @@ public:
eliminated= FALSE;
value= 0;
}
+ void no_rows_in_result();
enum Item_result result_type() const { return INT_RESULT;}
longlong val_int();
@@ -676,6 +685,7 @@ public:
virtual void print(String *str, enum_query_type query_type);
bool is_maxmin_applicable(JOIN *join);
bool transform_into_max_min(JOIN *join);
+ void no_rows_in_result();
};
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index 56b76f5982e..9bf1aaf4039 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -5467,8 +5467,8 @@ bool JOIN::choose_tableless_subquery_plan()
/*
If the optimizer determined that his query has an empty result,
in most cases the subquery predicate is a known constant value -
- either FALSE or NULL. The implementation of Item_subselect::reset()
- determines which one.
+ either of TRUE, FALSE or NULL. The implementation of
+ Item_subselect::no_rows_in_result() determines which one.
*/
if (zero_result_cause)
{
@@ -5476,14 +5476,13 @@ bool JOIN::choose_tableless_subquery_plan()
{
/*
Both group by queries and non-group by queries without aggregate
- functions produce empty subquery result.
+ functions produce empty subquery result. There is no need to further
+ rewrite the subquery because it will not be executed at all.
*/
- subs_predicate->reset();
- subs_predicate->make_const();
return FALSE;
}
- /* TODO:
+ /* @todo
A further optimization is possible when a non-group query with
MIN/MAX/COUNT is optimized by opt_sum_query. Then, if there are
only MIN/MAX functions over an empty result set, the subquery
diff --git a/sql/opt_subselect.h b/sql/opt_subselect.h
index a12e0c11620..7b8f3142851 100644
--- a/sql/opt_subselect.h
+++ b/sql/opt_subselect.h
@@ -146,7 +146,9 @@ public:
void add_keyuse(table_map remaining_tables, KEYUSE *keyuse)
{
- if (try_loosescan && keyuse->sj_pred_no != UINT_MAX)
+ if (try_loosescan && keyuse->sj_pred_no != UINT_MAX &&
+ (keyuse->table->file->index_flags(keyuse->key, 0, 1 ) & HA_READ_ORDER))
+
{
if (!(remaining_tables & keyuse->used_tables))
{
diff --git a/sql/parse_file.cc b/sql/parse_file.cc
index 699aa7e2b95..a6e3aa7ed66 100644
--- a/sql/parse_file.cc
+++ b/sql/parse_file.cc
@@ -86,6 +86,40 @@ write_escaped_string(IO_CACHE *file, LEX_STRING *val_s)
return FALSE;
}
+static ulonglong view_algo_to_frm(ulonglong val)
+{
+ switch(val)
+ {
+ case VIEW_ALGORITHM_UNDEFINED:
+ return VIEW_ALGORITHM_UNDEFINED_FRM;
+ case VIEW_ALGORITHM_MERGE:
+ return VIEW_ALGORITHM_MERGE_FRM;
+ case VIEW_ALGORITHM_TMPTABLE:
+ return VIEW_ALGORITHM_TMPTABLE_FRM;
+ }
+ DBUG_ASSERT(0); /* Should never happen */
+ return VIEW_ALGORITHM_UNDEFINED;
+}
+
+static ulonglong view_algo_from_frm(ulonglong val)
+{
+ switch(val)
+ {
+ case VIEW_ALGORITHM_UNDEFINED_FRM:
+ return VIEW_ALGORITHM_UNDEFINED;
+ case VIEW_ALGORITHM_MERGE_FRM:
+ return VIEW_ALGORITHM_MERGE;
+ case VIEW_ALGORITHM_TMPTABLE_FRM:
+ return VIEW_ALGORITHM_TMPTABLE;
+ }
+
+ /*
+ Early versions of MariaDB 5.2/5.3 had identical in-memory and frm values
+ Return input value.
+ */
+ return val;
+}
+
/**
Write parameter value to IO_CACHE.
@@ -124,8 +158,14 @@ write_parameter(IO_CACHE *file, uchar* base, File_option *parameter)
break;
}
case FILE_OPTIONS_ULONGLONG:
+ case FILE_OPTIONS_VIEW_ALGO:
{
- num.set(*((ulonglong *)(base + parameter->offset)), &my_charset_bin);
+ ulonglong val= *(ulonglong *)(base + parameter->offset);
+
+ if (parameter->type == FILE_OPTIONS_VIEW_ALGO)
+ val= view_algo_to_frm(val);
+
+ num.set(val, &my_charset_bin);
if (my_b_append(file, (const uchar *)num.ptr(), num.length()))
DBUG_RETURN(TRUE);
break;
@@ -769,6 +809,7 @@ File_parser::parse(uchar* base, MEM_ROOT *mem_root,
break;
}
case FILE_OPTIONS_ULONGLONG:
+ case FILE_OPTIONS_VIEW_ALGO:
if (!(eol= strchr(ptr, '\n')))
{
my_error(ER_FPARSER_ERROR_IN_PARAMETER, MYF(0),
@@ -777,8 +818,12 @@ File_parser::parse(uchar* base, MEM_ROOT *mem_root,
}
{
int not_used;
- *((ulonglong*)(base + parameter->offset))=
- my_strtoll10(ptr, 0, &not_used);
+ ulonglong val= (ulonglong)my_strtoll10(ptr, 0, &not_used);
+
+ if (parameter->type == FILE_OPTIONS_VIEW_ALGO)
+ val= view_algo_from_frm(val);
+
+ *((ulonglong*)(base + parameter->offset))= val;
}
ptr= eol+1;
break;
diff --git a/sql/parse_file.h b/sql/parse_file.h
index 20e3051e671..2a0266e98b7 100644
--- a/sql/parse_file.h
+++ b/sql/parse_file.h
@@ -31,6 +31,7 @@ enum file_opt_type {
FILE_OPTIONS_STRING, /**< String (LEX_STRING) */
FILE_OPTIONS_ESTRING, /**< Escaped string (LEX_STRING) */
FILE_OPTIONS_ULONGLONG, /**< ulonglong parameter (ulonglong) */
+ FILE_OPTIONS_VIEW_ALGO, /**< Similar to longlong, but needs conversion */
FILE_OPTIONS_TIMESTAMP, /**< timestamp (LEX_STRING have to be
allocated with length 20 (19+1) */
FILE_OPTIONS_STRLIST, /**< list of escaped strings
diff --git a/sql/slave.cc b/sql/slave.cc
index 941a275cd84..94af12472c1 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -4431,10 +4431,9 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
(event_pos= uint4korr(buf+LOG_POS_OFFSET)) > mi->master_log_pos + inc_pos)
{
inc_pos= event_pos - mi->master_log_pos;
- DBUG_PRINT("info", ("Adjust master_log_pos %lu->%lu to account for "
+ DBUG_PRINT("info", ("Adjust master_log_pos %llu->%llu to account for "
"master-side filtering",
- (unsigned long)(mi->master_log_pos + inc_pos),
- event_pos));
+ mi->master_log_pos + inc_pos, event_pos));
}
/*
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 15c3999be54..41c04b9c413 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -8559,14 +8559,16 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio,
if (find_mpvio_user(mpvio))
return packet_error;
- if (thd->client_capabilities & CLIENT_PLUGIN_AUTH)
+ if ((thd->client_capabilities & CLIENT_PLUGIN_AUTH) &&
+ (client_plugin < (char *)net->read_pos + pkt_len))
{
- if (client_plugin >= (char *)net->read_pos + pkt_len)
- return packet_error;
client_plugin= fix_plugin_ptr(client_plugin);
}
else
{
+ /* Some clients lie. Sad, but true */
+ thd->client_capabilities &= ~CLIENT_PLUGIN_AUTH;
+
if (thd->client_capabilities & CLIENT_SECURE_CONNECTION)
client_plugin= native_password_plugin_name.str;
else
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 624fc87815c..7a29bea8049 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -8499,6 +8499,11 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
}
}
#endif
+ /*
+ field_iterator.create_item() builds used_items which we
+ have to save because changes made once and they are persistent
+ */
+ tables->persistent_used_items= tables->used_items;
if ((field= field_iterator.field()))
{
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 246f03a7754..6fd6e53424f 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -3420,6 +3420,11 @@ bool st_select_lex::optimize_unflattened_subqueries()
continue;
}
+ bool empty_union_result= true;
+ /*
+ If the subquery is a UNION, optimize all the subqueries in the UNION. If
+ there is no UNION, then the loop will execute once for the subquery.
+ */
for (SELECT_LEX *sl= un->first_select(); sl; sl= sl->next_select())
{
JOIN *inner_join= sl->join;
@@ -3442,9 +3447,19 @@ bool st_select_lex::optimize_unflattened_subqueries()
res= inner_join->optimize();
inner_join->select_options= save_options;
un->thd->lex->current_select= save_select;
+ if (empty_union_result)
+ {
+ /*
+ If at least one subquery in a union is non-empty, the UNION result
+ is non-empty. If there is no UNION, the only subquery is non-empy.
+ */
+ empty_union_result= inner_join->empty_result();
+ }
if (res)
return TRUE;
}
+ if (empty_union_result)
+ subquery_predicate->no_rows_in_result();
}
}
return FALSE;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 8f8ecd1725d..916e521d3b9 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -12178,9 +12178,10 @@ static COND* substitute_for_best_equal_field(JOIN_TAB *context_tab,
@param cond condition whose multiple equalities are to be checked
@param table constant table that has been read
+ @param const_key mark key parts as constant
*/
-static void update_const_equal_items(COND *cond, JOIN_TAB *tab)
+static void update_const_equal_items(COND *cond, JOIN_TAB *tab, bool const_key)
{
if (!(cond->used_tables() & tab->table->map))
return;
@@ -12191,7 +12192,10 @@ static void update_const_equal_items(COND *cond, JOIN_TAB *tab)
List_iterator_fast<Item> li(*cond_list);
Item *item;
while ((item= li++))
- update_const_equal_items(item, tab);
+ update_const_equal_items(item, tab,
+ (((Item_cond*) cond)->top_level() &&
+ ((Item_cond*) cond)->functype() ==
+ Item_func::COND_AND_FUNC));
}
else if (cond->type() == Item::FUNC_ITEM &&
((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC)
@@ -12221,7 +12225,8 @@ static void update_const_equal_items(COND *cond, JOIN_TAB *tab)
TABLE *tab= field->table;
KEYUSE *use;
for (use= stat->keyuse; use && use->table == tab; use++)
- if (!use->is_for_hash_join() && possible_keys.is_set(use->key) &&
+ if (const_key &&
+ !use->is_for_hash_join() && possible_keys.is_set(use->key) &&
tab->key_info[use->key].key_part[use->keypart].field ==
field)
tab->const_key_parts[use->key]|= use->keypart_map;
@@ -16428,7 +16433,7 @@ join_read_const_table(JOIN_TAB *tab, POSITION *pos)
List_iterator<TABLE_LIST> ti(join->select_lex->leaf_tables);
/* Check appearance of new constant items in Item_equal objects */
if (join->conds)
- update_const_equal_items(join->conds, tab);
+ update_const_equal_items(join->conds, tab, TRUE);
while ((tbl= ti++))
{
TABLE_LIST *embedded;
@@ -16437,7 +16442,7 @@ join_read_const_table(JOIN_TAB *tab, POSITION *pos)
{
embedded= embedding;
if (embedded->on_expr)
- update_const_equal_items(embedded->on_expr, tab);
+ update_const_equal_items(embedded->on_expr, tab, TRUE);
embedding= embedded->embedding;
}
while (embedding &&
@@ -18265,7 +18270,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
int ref_key;
uint UNINIT_VAR(ref_key_parts);
int order_direction= 0;
- uint used_key_parts;
+ uint used_key_parts= 0;
TABLE *table=tab->table;
SQL_SELECT *select=tab->select;
key_map usable_keys;
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 53f2356853e..08ddc27e204 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -36,7 +36,7 @@
#if defined(WITH_ARIA_STORAGE_ENGINE)
-#include "../storage/maria/ha_maria.h"
+#include <maria.h>
#endif
#if defined(USE_ARIA_FOR_TMP_TABLES)
#define TMP_ENGINE_HTON maria_hton
@@ -1319,6 +1319,7 @@ public:
return (do_send_rows && implicit_grouping && !group_optimized_away &&
having_value != Item::COND_FALSE);
}
+ bool empty_result() { return (zero_result_cause && !implicit_grouping); }
bool change_result(select_result *result);
bool is_top_level_join() const
{
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index f9502589beb..7d5fe875d64 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -1406,11 +1406,7 @@ bool mysql_multi_update(THD *thd,
DBUG_PRINT("info",("res: %d report_error: %d", res, (int) thd->is_error()));
res|= thd->is_error();
if (unlikely(res))
- {
- /* If we had a another error reported earlier then this will be ignored */
- (*result)->send_error(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR));
(*result)->abort_result_set();
- }
thd->abort_on_warning= 0;
DBUG_RETURN(res);
}
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index b6a7cf010ed..bbc5c324573 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -752,7 +752,7 @@ static File_option view_parameters[]=
FILE_OPTIONS_ULONGLONG},
{{ C_STRING_WITH_LEN("algorithm")},
my_offsetof(TABLE_LIST, algorithm),
- FILE_OPTIONS_ULONGLONG},
+ FILE_OPTIONS_VIEW_ALGO},
{{ C_STRING_WITH_LEN("definer_user")},
my_offsetof(TABLE_LIST, definer.user),
FILE_OPTIONS_STRING},
diff --git a/sql/table.cc b/sql/table.cc
index dc8ab3c6b42..40304dc6fdc 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -6696,7 +6696,8 @@ bool TABLE_LIST::change_refs_to_fields()
We need to restore the pointers after the execution of the
prepared statement.
*/
- thd->change_item_tree((Item **)&ref->ref, (Item*)materialized_items + idx);
+ thd->change_item_tree((Item **)&ref->ref,
+ (Item*)(materialized_items + idx));
}
return FALSE;
diff --git a/sql/table.h b/sql/table.h
index 7b50caae536..f3f9d5ac036 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -1363,12 +1363,6 @@ typedef struct st_schema_table
/*
Types of derived tables. The ending part is a bitmap of phases that are
applicable to a derived table of the type.
- * /
-#define VIEW_ALGORITHM_UNDEFINED 0
-#define VIEW_ALGORITHM_MERGE 1 + DT_COMMON + DT_MERGE
-#define DERIVED_ALGORITHM_MERGE 2 + DT_COMMON + DT_MERGE
-#define VIEW_ALGORITHM_TMPTABLE 3 + DT_COMMON + DT_MATERIALIZE
-#define DERIVED_ALGORITHM_MATERIALIZE 4 + DT_COMMON + DT_MATERIALIZE
*/
#define DTYPE_ALGORITHM_UNDEFINED 0
#define DTYPE_VIEW 1
@@ -1401,7 +1395,16 @@ typedef struct st_schema_table
#define VIEW_ALGORITHM_UNDEFINED 0
#define VIEW_ALGORITHM_MERGE (DTYPE_VIEW | DTYPE_MERGE)
-#define VIEW_ALGORITHM_TMPTABLE (DTYPE_VIEW + DTYPE_MATERIALIZE )
+#define VIEW_ALGORITHM_TMPTABLE (DTYPE_VIEW | DTYPE_MATERIALIZE)
+
+/*
+ View algorithm values as stored in the FRM. Values differ from in-memory
+ representation for backward compatibility.
+*/
+
+#define VIEW_ALGORITHM_UNDEFINED_FRM 0
+#define VIEW_ALGORITHM_MERGE_FRM 1
+#define VIEW_ALGORITHM_TMPTABLE_FRM 2
#define JOIN_TYPE_LEFT 1
#define JOIN_TYPE_RIGHT 2