summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorKentoku SHIBA <kentokushiba@gmail.com>2019-04-25 20:11:37 +0900
committerGitHub <noreply@github.com>2019-04-25 20:11:37 +0900
commit80e8fee90732c4cf2436dde5d02f4edc7824f06b (patch)
tree7d9d5df2ca140335905c6e8e2e24fb28e90a7d63 /sql
parentebf3376677f9803a914cadc034c71ec2881f9eb4 (diff)
parentca7fbcea6c4fe13c295cf43b80d05351aba59e95 (diff)
downloadmariadb-git-bb-10.4-MDEV-18995.tar.gz
Merge branch '10.4' into bb-10.4-MDEV-18995bb-10.4-MDEV-18995
Diffstat (limited to 'sql')
-rw-r--r--sql/CMakeLists.txt16
-rw-r--r--sql/field.cc52
-rw-r--r--sql/field.h27
-rw-r--r--sql/handle_connections_win.cc5
-rw-r--r--sql/item.h16
-rw-r--r--sql/item_cmpfunc.h2
-rw-r--r--sql/item_func.h2
-rw-r--r--sql/item_subselect.cc20
-rw-r--r--sql/item_subselect.h2
-rw-r--r--sql/opt_range.cc6
-rw-r--r--sql/opt_subselect.cc19
-rw-r--r--sql/share/errmsg-utf8.txt2
-rw-r--r--sql/slave.cc17
-rw-r--r--sql/sql_acl.cc67
-rw-r--r--sql/sql_derived.cc38
-rw-r--r--sql/sql_derived.h1
-rw-r--r--sql/sql_lex.cc15
-rw-r--r--sql/sql_lex.h2
-rw-r--r--sql/sql_plugin_services.ic3
-rw-r--r--sql/sql_prepare.cc4
-rw-r--r--sql/sql_select.cc10
-rw-r--r--sql/sql_sequence.cc4
-rw-r--r--sql/sql_type.cc13
-rw-r--r--sql/sql_type.h9
-rw-r--r--sql/sql_union.cc10
-rw-r--r--sql/sql_view.cc2
-rw-r--r--sql/sql_yacc.yy1
-rw-r--r--sql/sql_yacc_ora.yy1
-rw-r--r--sql/sys_vars.cc6
-rw-r--r--sql/table.cc7
-rw-r--r--sql/threadpool.h7
-rw-r--r--sql/unireg.cc61
-rw-r--r--sql/wsrep_dummy.cc3
33 files changed, 305 insertions, 145 deletions
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
index ecca723b9e4..da4de86d950 100644
--- a/sql/CMakeLists.txt
+++ b/sql/CMakeLists.txt
@@ -126,7 +126,7 @@ SET (SQL_SOURCE
opt_index_cond_pushdown.cc opt_subselect.cc
opt_table_elimination.cc sql_expression_cache.cc
gcalc_slicescan.cc gcalc_tools.cc
- threadpool_common.cc ../sql-common/mysql_async.c
+ ../sql-common/mysql_async.c
my_apc.cc mf_iocache_encr.cc item_jsonfunc.cc
my_json_writer.cc
rpl_gtid.cc rpl_parallel.cc
@@ -152,17 +152,21 @@ SET (SQL_SOURCE
${MYSYS_LIBWRAP_SOURCE}
)
-IF (CMAKE_SYSTEM_NAME MATCHES "Linux" OR
- CMAKE_SYSTEM_NAME MATCHES "Windows" OR
- CMAKE_SYSTEM_NAME MATCHES "SunOS" OR
- HAVE_KQUEUE)
+IF ((CMAKE_SYSTEM_NAME MATCHES "Linux" OR
+ CMAKE_SYSTEM_NAME MATCHES "SunOS" OR
+ WIN32 OR
+ HAVE_KQUEUE)
+ AND (NOT DISABLE_THREADPOOL))
ADD_DEFINITIONS(-DHAVE_POOL_OF_THREADS)
IF(WIN32)
SET(SQL_SOURCE ${SQL_SOURCE} threadpool_win.cc)
- SET(SQL_SOURCE ${SQL_SOURCE} handle_connections_win.cc)
ENDIF()
SET(SQL_SOURCE ${SQL_SOURCE} threadpool_generic.cc)
+ SET(SQL_SOURCE ${SQL_SOURCE} threadpool_common.cc)
+ENDIF()
+IF(WIN32)
+ SET(SQL_SOURCE ${SQL_SOURCE} handle_connections_win.cc)
ENDIF()
MYSQL_ADD_PLUGIN(partition ha_partition.cc STORAGE_ENGINE DEFAULT STATIC_ONLY
diff --git a/sql/field.cc b/sql/field.cc
index 4a93464b2e8..1056a99a498 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -67,14 +67,19 @@ inline bool Field::marked_for_read() const
ptr < table->record[0] + table->s->reclength)));
}
+/*
+ The name of this function is a bit missleading as in 10.4 we don't
+ have to test anymore if the field is computed. Instead we mark
+ changed fields with DBUG_FIX_WRITE_SET() in table.cc
+*/
inline bool Field::marked_for_write_or_computed() const
{
- return is_stat_field || !table ||
- (!table->write_set ||
- bitmap_is_set(table->write_set, field_index) ||
- (!(ptr >= table->record[0] &&
- ptr < table->record[0] + table->s->reclength)));
+ return (is_stat_field || !table ||
+ (!table->write_set ||
+ bitmap_is_set(table->write_set, field_index) ||
+ (!(ptr >= table->record[0] &&
+ ptr < table->record[0] + table->s->reclength))));
}
@@ -1377,6 +1382,14 @@ error:
}
+bool Field::make_empty_rec_store_default_value(THD *thd, Item *item)
+{
+ DBUG_ASSERT(!(flags & BLOB_FLAG));
+ int res= item->save_in_field(this, true);
+ return res != 0 && res != 3;
+}
+
+
/**
Numeric fields base class constructor.
*/
@@ -2436,6 +2449,15 @@ void Field_null::sql_type(String &res) const
}
+uint Field_null::is_equal(Create_field *new_field)
+{
+ DBUG_ASSERT(!compression_method());
+ return new_field->type_handler() == type_handler() &&
+ new_field->charset == field_charset &&
+ new_field->length == max_display_length();
+}
+
+
/****************************************************************************
Field_row, e.g. for ROW-type SP variables
****************************************************************************/
@@ -7069,14 +7091,10 @@ int Field_str::store(double nr)
return store(buff, (uint)length, &my_charset_numeric);
}
-uint Field::is_equal(Create_field *new_field)
-{
- return new_field->type_handler() == type_handler();
-}
-
-uint Field_str::is_equal(Create_field *new_field)
+uint Field_string::is_equal(Create_field *new_field)
{
+ DBUG_ASSERT(!compression_method());
if (new_field->type_handler() != type_handler())
return IS_EQUAL_NO;
if (new_field->length < max_display_length())
@@ -8763,6 +8781,18 @@ void Field_blob::make_send_field(Send_field *field)
}
+bool Field_blob::make_empty_rec_store_default_value(THD *thd, Item *item)
+{
+ DBUG_ASSERT(flags & BLOB_FLAG);
+ int res= item->save_in_field(this, true);
+ DBUG_ASSERT(res != 3); // Field_blob never returns 3
+ if (res)
+ return true; // E.g. truncation happened
+ reset(); // Clear the pointer to a String, it should not be written to frm
+ return false;
+}
+
+
int Field_blob_compressed::store(const char *from, size_t length,
CHARSET_INFO *cs)
{
diff --git a/sql/field.h b/sql/field.h
index 8bd7343931b..a1fae26dfcc 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -464,6 +464,7 @@ inline bool is_temporal_type_with_date(enum_field_types type)
case MYSQL_TYPE_DATETIME2:
case MYSQL_TYPE_TIMESTAMP2:
DBUG_ASSERT(0); // field->real_type() should not get to here.
+ return false;
default:
return false;
}
@@ -781,6 +782,11 @@ public:
@retval false - conversion is needed
*/
virtual bool memcpy_field_possible(const Field *from) const= 0;
+ virtual bool make_empty_rec_store_default_value(THD *thd, Item *item);
+ virtual void make_empty_rec_reset(THD *thd)
+ {
+ reset();
+ }
virtual int store(const char *to, size_t length,CHARSET_INFO *cs)=0;
virtual int store_hex_hybrid(const char *str, size_t length);
virtual int store(double nr)=0;
@@ -1504,7 +1510,7 @@ public:
of a table is compatible with the old definition so that it can
determine if data needs to be copied over (table data change).
*/
- virtual uint is_equal(Create_field *new_field);
+ virtual uint is_equal(Create_field *new_field)= 0;
/* convert decimal to longlong with overflow check */
longlong convert_decimal2longlong(const my_decimal *val, bool unsigned_flag,
int *err);
@@ -1868,7 +1874,6 @@ public:
my_decimal *val_decimal(my_decimal *);
bool val_bool() { return val_real() != 0e0; }
virtual bool str_needs_quotes() { return TRUE; }
- uint is_equal(Create_field *new_field);
bool eq_cmp_as_binary() { return MY_TEST(flags & BINARY_FLAG); }
virtual uint length_size() { return 0; }
double pos_in_interval(Field *min, Field *max)
@@ -2640,6 +2645,7 @@ public:
my_decimal *val_decimal(my_decimal *) { return 0; }
String *val_str(String *value,String *value2)
{ value2->length(0); return value2;}
+ uint is_equal(Create_field *new_field);
int cmp(const uchar *a, const uchar *b) { return 0;}
void sort_string(uchar *buff, uint length) {}
uint32 pack_length() const { return 0; }
@@ -3563,6 +3569,7 @@ public:
int cmp(const uchar *,const uchar *);
void sort_string(uchar *buff,uint length);
void sql_type(String &str) const;
+ uint is_equal(Create_field *new_field);
virtual uchar *pack(uchar *to, const uchar *from,
uint max_length);
virtual const uchar *unpack(uchar* to, const uchar *from,
@@ -3893,6 +3900,7 @@ public:
!compression_method() == !from->compression_method() &&
!table->copy_blobs;
}
+ bool make_empty_rec_store_default_value(THD *thd, Item *item);
int store(const char *to, size_t length, CHARSET_INFO *charset);
using Field_str::store;
double val_real(void);
@@ -4210,6 +4218,16 @@ public:
return save_in_field_str(to);
}
bool memcpy_field_possible(const Field *from) const { return false; }
+ void make_empty_rec_reset(THD *thd)
+ {
+ if (flags & NOT_NULL_FLAG)
+ {
+ set_notnull();
+ store((longlong) 1, true);
+ }
+ else
+ reset();
+ }
int store(const char *to,size_t length,CHARSET_INFO *charset);
int store(double nr);
int store(longlong nr, bool unsigned_val);
@@ -4276,6 +4294,11 @@ public:
{
flags=(flags & ~ENUM_FLAG) | SET_FLAG;
}
+ void make_empty_rec_reset(THD *thd)
+ {
+ Field::make_empty_rec_reset(thd);
+ }
+
int store_field(Field *from) { return from->save_in_field(this); }
int store(const char *to,size_t length,CHARSET_INFO *charset);
int store(double nr) { return Field_set::store((longlong) nr, FALSE); }
diff --git a/sql/handle_connections_win.cc b/sql/handle_connections_win.cc
index 6724a2a1f30..e5b601d7fe0 100644
--- a/sql/handle_connections_win.cc
+++ b/sql/handle_connections_win.cc
@@ -28,8 +28,13 @@
/* From mysqld.cc */
extern HANDLE hEventShutdown;
extern MYSQL_SOCKET base_ip_sock, extra_ip_sock;
+#ifdef HAVE_POOL_OF_THREADS
extern PTP_CALLBACK_ENVIRON get_threadpool_win_callback_environ();
extern void tp_win_callback_prolog();
+#else
+#define get_threadpool_win_callback_environ() 0
+#define tp_win_callback_prolog() do{}while(0)
+#endif
static SECURITY_ATTRIBUTES pipe_security;
/**
diff --git a/sql/item.h b/sql/item.h
index 97d31e6ba34..d88216141ce 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -714,6 +714,8 @@ public:
/****************************************************************************/
+#define STOP_PTR ((void *) 1)
+
class Item: public Value_source,
public Type_all_attributes
{
@@ -1829,8 +1831,10 @@ public:
/*========= Item processors, to be used with Item::walk() ========*/
virtual bool remove_dependence_processor(void *arg) { return 0; }
virtual bool cleanup_processor(void *arg);
- virtual bool cleanup_excluding_fields_processor(void *arg) { return cleanup_processor(arg); }
- virtual bool cleanup_excluding_const_fields_processor(void *arg) { return cleanup_processor(arg); }
+ virtual bool cleanup_excluding_fields_processor (void *arg)
+ { return cleanup_processor(arg); }
+ virtual bool cleanup_excluding_const_fields_processor (void *arg)
+ { return cleanup_processor(arg); }
virtual bool collect_item_field_processor(void *arg) { return 0; }
virtual bool collect_outer_ref_processor(void *arg) {return 0; }
virtual bool check_inner_refs_processor(void *arg) { return 0; }
@@ -1943,6 +1947,12 @@ public:
virtual bool check_partition_func_processor(void *arg) { return 1;}
virtual bool post_fix_fields_part_expr_processor(void *arg) { return 0; }
virtual bool rename_fields_processor(void *arg) { return 0; }
+ /*
+ TRUE if the function is knowingly TRUE or FALSE.
+ Not to be used for AND/OR formulas.
+ */
+ virtual bool is_simplified_cond_processor(void *arg) { return false; }
+
/** Processor used to check acceptability of an item in the defining
expression for a virtual column
@@ -6535,6 +6545,8 @@ public:
virtual void set_null();
bool walk(Item_processor processor, bool walk_subquery, void *arg)
{
+ if (arg == STOP_PTR)
+ return FALSE;
if (example && example->walk(processor, walk_subquery, arg))
return TRUE;
return (this->*processor)(arg);
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index a6bf0a6d427..5793dda9e9a 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -2661,7 +2661,6 @@ class Item_func_like :public Item_bool_func2
bool escape_used_in_parsing;
bool use_sampling;
- bool negated;
DTCollation cmp_collation;
String cmp_value1, cmp_value2;
@@ -2678,6 +2677,7 @@ protected:
Item_func::Functype type, Item *value);
public:
int escape;
+ bool negated;
Item_func_like(THD *thd, Item *a, Item *b, Item *escape_arg, bool escape_used):
Item_bool_func2(thd, a, b), canDoTurboBM(FALSE), pattern(0), pattern_len(0),
diff --git a/sql/item_func.h b/sql/item_func.h
index 44e9691c9df..27cb245db6b 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -398,6 +398,8 @@ public:
bool with_sum_func() const { return m_with_sum_func; }
With_sum_func_cache* get_with_sum_func_cache() { return this; }
Item_func *get_item_func() { return this; }
+ bool is_simplified_cond_processor(void *arg)
+ { return const_item() && !val_int(); }
};
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 4fb9abce0e2..2b1c4c174c7 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -54,7 +54,8 @@ Item_subselect::Item_subselect(THD *thd_arg):
value_assigned(0), own_engine(0), thd(0), old_engine(0),
have_to_be_excluded(0),
inside_first_fix_fields(0), done_first_fix_fields(FALSE),
- expr_cache(0), forced_const(FALSE), substitution(0), engine(0), eliminated(FALSE),
+ expr_cache(0), forced_const(FALSE), expensive_fl(FALSE),
+ substitution(0), engine(0), eliminated(FALSE),
changed(0), is_correlated(FALSE), with_recursive_reference(0)
{
DBUG_ENTER("Item_subselect::Item_subselect");
@@ -585,6 +586,9 @@ bool Item_subselect::is_expensive()
double examined_rows= 0;
bool all_are_simple= true;
+ if (!expensive_fl && is_evaluated())
+ return false;
+
/* check extremely simple select */
if (!unit->first_select()->next_select()) // no union
{
@@ -595,7 +599,7 @@ bool Item_subselect::is_expensive()
SELECT_LEX *sl= unit->first_select();
JOIN *join = sl->join;
if (join && !join->tables_list && !sl->first_inner_unit())
- return false;
+ return (expensive_fl= false);
}
@@ -605,14 +609,14 @@ bool Item_subselect::is_expensive()
/* not optimized subquery */
if (!cur_join)
- return true;
+ return (expensive_fl= true);
/*
If the subquery is not optimised or in the process of optimization
it supposed to be expensive
*/
if (cur_join->optimization_state != JOIN::OPTIMIZATION_DONE)
- return true;
+ return (expensive_fl= true);
if (!cur_join->tables_list && !sl->first_inner_unit())
continue;
@@ -634,7 +638,7 @@ bool Item_subselect::is_expensive()
considered optimized if it has a join plan.
*/
if (!cur_join->join_tab)
- return true;
+ return (expensive_fl= true);
if (sl->first_inner_unit())
{
@@ -642,15 +646,15 @@ bool Item_subselect::is_expensive()
Subqueries that contain subqueries are considered expensive.
@todo: accumulate the cost of subqueries.
*/
- return true;
+ return (expensive_fl= true);
}
examined_rows+= cur_join->get_examined_rows();
}
// here we are sure that subquery is optimized so thd is set
- return !all_are_simple &&
- (examined_rows > thd->variables.expensive_subquery_limit);
+ return (expensive_fl= !all_are_simple &&
+ (examined_rows > thd->variables.expensive_subquery_limit));
}
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index 0e771bae42e..bbc24d336f0 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -73,6 +73,8 @@ protected:
to substitute 'this' with a constant item.
*/
bool forced_const;
+ /* Set to the result of the last call of is_expensive() */
+ bool expensive_fl;
#ifndef DBUG_OFF
/* Count the number of times this subquery predicate has been executed. */
uint exec_counter;
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 5ab3d70214d..ed9cd541f70 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -9044,7 +9044,11 @@ int and_range_trees(RANGE_OPT_PARAM *param, SEL_TREE *tree1, SEL_TREE *tree2,
if (key && key->type == SEL_ARG::IMPOSSIBLE)
{
result->type= SEL_TREE::IMPOSSIBLE;
- param->table->with_impossible_ranges.set_bit(param->real_keynr[key_no]);
+ if (param->using_real_indexes)
+ {
+ param->table->with_impossible_ranges.set_bit(param->
+ real_keynr[key_no]);
+ }
DBUG_RETURN(1);
}
result_keys.set_bit(key_no);
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index 32b70b41eb3..2fedd8a4ed3 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -5723,12 +5723,6 @@ Item *and_new_conditions_to_optimized_cond(THD *thd, Item *cond,
&((Item_cond_and *) cond)->m_cond_equal,
false, NULL);
}
- /*
- Check if equalities that can't be transformed into multiple
- equalities are knowingly true or false.
- */
- if (item->const_item() && !item->val_int())
- is_simplified_cond= true;
and_args->push_back(item, thd->mem_root);
}
and_args->append((List<Item> *) cond_equalities);
@@ -5821,12 +5815,6 @@ Item *and_new_conditions_to_optimized_cond(THD *thd, Item *cond,
{
item= item->build_equal_items(thd, inherited, false, NULL);
}
- /*
- Check if equalities that can't be transformed into multiple
- equalities are knowingly true or false.
- */
- if (item->const_item() && !item->val_int())
- is_simplified_cond= true;
new_conds_list.push_back(item, thd->mem_root);
}
new_conds_list.append((List<Item> *)&new_cond_equal.current_level);
@@ -5870,7 +5858,14 @@ Item *and_new_conditions_to_optimized_cond(THD *thd, Item *cond,
cond= cond->propagate_equal_fields(thd,
Item::Context_boolean(),
*cond_eq);
+ cond->update_used_tables();
}
+ /* Check if conds has knowingly true or false parts. */
+ if (cond &&
+ !is_simplified_cond &&
+ cond->walk(&Item::is_simplified_cond_processor, 0, 0))
+ is_simplified_cond= true;
+
/*
If it was found that there are some knowingly true or false equalities
diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt
index db38b157406..feb47f9af94 100644
--- a/sql/share/errmsg-utf8.txt
+++ b/sql/share/errmsg-utf8.txt
@@ -7012,7 +7012,7 @@ ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_FK_RENAME
eng "Columns participating in a foreign key are renamed"
ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_COLUMN_TYPE
- eng "Cannot change column type INPLACE"
+ eng "Cannot change column type"
ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_FK_CHECK
eng "Adding foreign keys needs foreign_key_checks=OFF"
diff --git a/sql/slave.cc b/sql/slave.cc
index 52cecf2fd36..1430c9fa153 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -995,6 +995,8 @@ static void make_slave_transaction_retry_errors_printable(void)
}
+#define DEFAULT_SLAVE_RETRY_ERRORS 9
+
bool init_slave_transaction_retry_errors(const char* arg)
{
const char *p;
@@ -1006,7 +1008,7 @@ bool init_slave_transaction_retry_errors(const char* arg)
if (!arg)
arg= "";
- slave_transaction_retry_error_length= 2;
+ slave_transaction_retry_error_length= DEFAULT_SLAVE_RETRY_ERRORS;
for (;my_isspace(system_charset_info,*arg);++arg)
/* empty */;
for (p= arg; *p; )
@@ -1029,11 +1031,18 @@ bool init_slave_transaction_retry_errors(const char* arg)
currently, InnoDB deadlock detected by InnoDB or lock
wait timeout (innodb_lock_wait_timeout exceeded
*/
- slave_transaction_retry_errors[0]= ER_LOCK_DEADLOCK;
- slave_transaction_retry_errors[1]= ER_LOCK_WAIT_TIMEOUT;
+ slave_transaction_retry_errors[0]= ER_NET_READ_ERROR;
+ slave_transaction_retry_errors[1]= ER_NET_READ_INTERRUPTED;
+ slave_transaction_retry_errors[2]= ER_NET_ERROR_ON_WRITE;
+ slave_transaction_retry_errors[3]= ER_NET_WRITE_INTERRUPTED;
+ slave_transaction_retry_errors[4]= ER_LOCK_WAIT_TIMEOUT;
+ slave_transaction_retry_errors[5]= ER_LOCK_DEADLOCK;
+ slave_transaction_retry_errors[6]= ER_CONNECT_TO_FOREIGN_DATA_SOURCE;
+ slave_transaction_retry_errors[7]= 2013; /* CR_SERVER_LOST */
+ slave_transaction_retry_errors[8]= 12701; /* ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM */
/* Add user codes after this */
- for (p= arg, i= 2; *p; )
+ for (p= arg, i= DEFAULT_SLAVE_RETRY_ERRORS; *p; )
{
if (!(p= str2int(p, 10, 0, LONG_MAX, &err_code)))
break;
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 97a08f72191..d8b5b7364a9 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -119,6 +119,9 @@ class ACL_ACCESS {
public:
ulong sort;
ulong access;
+ ACL_ACCESS()
+ :sort(0), access(0)
+ { }
};
/* ACL_HOST is used if no host is specified */
@@ -134,15 +137,25 @@ class ACL_USER_BASE :public ACL_ACCESS, public Sql_alloc
{
public:
+ ACL_USER_BASE()
+ :flags(0), user(null_clex_str)
+ {
+ bzero(&role_grants, sizeof(role_grants));
+ }
uchar flags; // field used to store various state information
LEX_CSTRING user;
/* list to hold references to granted roles (ACL_ROLE instances) */
DYNAMIC_ARRAY role_grants;
+ const char *get_username() { return user.str; }
};
-class ACL_USER :public ACL_USER_BASE
+class ACL_USER_PARAM
{
public:
+ ACL_USER_PARAM()
+ {
+ bzero(this, sizeof(*this));
+ }
acl_host_and_ip host;
size_t hostname_length;
USER_RESOURCES user_resource;
@@ -161,6 +174,18 @@ public:
{
return !(auth= (AUTH*) alloc_root(root, (nauth= n)*sizeof(AUTH)));
}
+};
+
+
+class ACL_USER :public ACL_USER_BASE,
+ public ACL_USER_PARAM
+{
+public:
+
+ ACL_USER() { }
+ ACL_USER(THD *thd, const LEX_USER &combo,
+ const Account_options &options,
+ const ulong privileges);
ACL_USER *copy(MEM_ROOT *root)
{
@@ -206,8 +231,6 @@ public:
bool eq(const char *user2, const char *host2) { return !cmp(user2, host2); }
- const char *get_username(){ return user.str; }
-
bool wild_eq(const char *user2, const char *host2, const char *ip2)
{
if (strcmp(user.str, user2))
@@ -1931,12 +1954,10 @@ enum enum_acl_lists
ACL_ROLE::ACL_ROLE(ACL_USER *user, MEM_ROOT *root) : counter(0)
{
-
access= user->access;
/* set initial role access the same as the table row privileges */
initial_role_access= user->access;
this->user= user->user;
- bzero(&role_grants, sizeof(role_grants));
bzero(&parent_grantee, sizeof(parent_grantee));
flags= IS_ROLE;
}
@@ -1947,7 +1968,6 @@ ACL_ROLE::ACL_ROLE(const char * rolename, ulong privileges, MEM_ROOT *root) :
this->access= initial_role_access;
this->user.str= safe_strdup_root(root, rolename);
this->user.length= strlen(rolename);
- bzero(&role_grants, sizeof(role_grants));
bzero(&parent_grantee, sizeof(parent_grantee));
flags= IS_ROLE;
}
@@ -2348,7 +2368,6 @@ static bool acl_load(THD *thd, const Grant_tables& tables)
{
ACL_USER user;
bool is_role= FALSE;
- bzero(&user, sizeof(user));
update_hostname(&user.host, user_table.get_host(&acl_memroot));
char *username= safe_str(user_table.get_user(&acl_memroot));
user.user.str= username;
@@ -3122,26 +3141,25 @@ static void acl_update_role(const char *rolename, ulong privileges)
}
+ACL_USER::ACL_USER(THD *thd, const LEX_USER &combo,
+ const Account_options &options,
+ const ulong privileges)
+{
+ user= safe_lexcstrdup_root(&acl_memroot, combo.user);
+ update_hostname(&host, safe_strdup_root(&acl_memroot, combo.host.str));
+ hostname_length= combo.host.length;
+ sort= get_sort(2, host.hostname, user.str);
+ password_last_changed= thd->query_start();
+ password_lifetime= -1;
+ my_init_dynamic_array(&role_grants, sizeof(ACL_USER *), 0, 8, MYF(0));
+}
+
+
static int acl_user_update(THD *thd, ACL_USER *acl_user, uint nauth,
- const ACL_USER *from, const LEX_USER &combo,
+ const LEX_USER &combo,
const Account_options &options,
const ulong privileges)
{
- if (from)
- *acl_user= *from;
- else
- {
- bzero(acl_user, sizeof(*acl_user));
- acl_user->user= safe_lexcstrdup_root(&acl_memroot, combo.user);
- update_hostname(&acl_user->host, safe_strdup_root(&acl_memroot, combo.host.str));
- acl_user->hostname_length= combo.host.length;
- acl_user->sort= get_sort(2, acl_user->host.hostname, acl_user->user.str);
- acl_user->password_last_changed= thd->query_start();
- acl_user->password_lifetime= -1;
- my_init_dynamic_array(&acl_user->role_grants, sizeof(ACL_USER *),
- 0, 8, MYF(0));
- }
-
if (nauth)
{
if (acl_user->nauth >= nauth)
@@ -4424,8 +4442,9 @@ static int replace_user_table(THD *thd, const User_table &user_table,
my_error(ER_PASSWORD_NO_MATCH, MYF(0));
goto end;
}
+ new_acl_user= old_row_exists ? *old_acl_user :
+ ACL_USER(thd, *combo, lex->account_options, rights);
if (acl_user_update(thd, &new_acl_user, nauth,
- old_row_exists ? old_acl_user : NULL,
*combo, lex->account_options, rights))
goto end;
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index 548383e818c..102999c42d7 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -38,14 +38,15 @@
typedef bool (*dt_processor)(THD *thd, LEX *lex, TABLE_LIST *derived);
-bool mysql_derived_init(THD *thd, LEX *lex, TABLE_LIST *derived);
-bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived);
-bool mysql_derived_optimize(THD *thd, LEX *lex, TABLE_LIST *derived);
-bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived);
-bool mysql_derived_create(THD *thd, LEX *lex, TABLE_LIST *derived);
-bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived);
-bool mysql_derived_reinit(THD *thd, LEX *lex, TABLE_LIST *derived);
-bool mysql_derived_merge_for_insert(THD *thd, LEX *lex, TABLE_LIST *derived);
+static bool mysql_derived_init(THD *thd, LEX *lex, TABLE_LIST *derived);
+static bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived);
+static bool mysql_derived_optimize(THD *thd, LEX *lex, TABLE_LIST *derived);
+static bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived);
+static bool mysql_derived_create(THD *thd, LEX *lex, TABLE_LIST *derived);
+static bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived);
+static bool mysql_derived_reinit(THD *thd, LEX *lex, TABLE_LIST *derived);
+static bool mysql_derived_merge_for_insert(THD *thd, LEX *lex,
+ TABLE_LIST *derived);
dt_processor processors[]=
{
@@ -182,7 +183,10 @@ mysql_handle_single_derived(LEX *lex, TABLE_LIST *derived, uint phases)
if (!lex->derived_tables)
DBUG_RETURN(FALSE);
- derived->select_lex->changed_elements|= TOUCHED_SEL_DERIVED;
+ if (derived->select_lex)
+ derived->select_lex->changed_elements|= TOUCHED_SEL_DERIVED;
+ else
+ DBUG_ASSERT(derived->prelocking_placeholder);
lex->thd->derived_tables_processing= TRUE;
for (uint phase= 0; phase < DT_PHASES; phase++)
@@ -331,6 +335,7 @@ mysql_handle_single_derived(LEX *lex, TABLE_LIST *derived, uint phases)
@return TRUE if an error occur.
*/
+static
bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived)
{
bool res= FALSE;
@@ -513,6 +518,7 @@ unconditional_materialization:
@return TRUE if an error occur.
*/
+static
bool mysql_derived_merge_for_insert(THD *thd, LEX *lex, TABLE_LIST *derived)
{
DBUG_ENTER("mysql_derived_merge_for_insert");
@@ -569,7 +575,7 @@ bool mysql_derived_merge_for_insert(THD *thd, LEX *lex, TABLE_LIST *derived)
true Error
*/
-
+static
bool mysql_derived_init(THD *thd, LEX *lex, TABLE_LIST *derived)
{
SELECT_LEX_UNIT *unit= derived->get_unit();
@@ -646,7 +652,7 @@ bool mysql_derived_init(THD *thd, LEX *lex, TABLE_LIST *derived)
true Error
*/
-
+static
bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived)
{
SELECT_LEX_UNIT *unit= derived->get_unit();
@@ -917,6 +923,7 @@ exit:
@return TRUE if an error occur.
*/
+static
bool mysql_derived_optimize(THD *thd, LEX *lex, TABLE_LIST *derived)
{
SELECT_LEX_UNIT *unit= derived->get_unit();
@@ -1028,6 +1035,7 @@ err:
@return TRUE if an error occur.
*/
+static
bool mysql_derived_create(THD *thd, LEX *lex, TABLE_LIST *derived)
{
DBUG_ENTER("mysql_derived_create");
@@ -1138,7 +1146,7 @@ bool TABLE_LIST::fill_recursive(THD *thd)
@return TRUE Error
*/
-
+static
bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived)
{
Field_iterator_table field_iterator;
@@ -1280,6 +1288,7 @@ err:
@return TRUE Error
*/
+static
bool mysql_derived_reinit(THD *thd, LEX *lex, TABLE_LIST *derived)
{
DBUG_ENTER("mysql_derived_reinit");
@@ -1293,11 +1302,6 @@ bool mysql_derived_reinit(THD *thd, LEX *lex, TABLE_LIST *derived)
unit->types.empty();
/* for derived tables & PS (which can't be reset by Item_subselect) */
unit->reinit_exec_mechanism();
- for (st_select_lex *sl= unit->first_select(); sl; sl= sl->next_select())
- {
- sl->cond_pushed_into_where= NULL;
- sl->cond_pushed_into_having= NULL;
- }
unit->set_thd(thd);
DBUG_RETURN(FALSE);
}
diff --git a/sql/sql_derived.h b/sql/sql_derived.h
index abfdb007072..2454d40ba79 100644
--- a/sql/sql_derived.h
+++ b/sql/sql_derived.h
@@ -22,7 +22,6 @@ struct LEX;
bool mysql_handle_derived(LEX *lex, uint phases);
bool mysql_handle_single_derived(LEX *lex, TABLE_LIST *derived, uint phases);
-bool mysql_derived_reinit(THD *thd, LEX *lex, TABLE_LIST *derived);
bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived);
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 3f28ab91b9a..8ea0bc50956 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -1504,6 +1504,8 @@ int Lex_input_stream::lex_one_token(YYSTYPE *yylval, THD *thd)
next_state= MY_LEX_START;
return PERCENT_ORACLE_SYM;
}
+ if (c == '[' && (m_thd->variables.sql_mode & MODE_MSSQL))
+ return scan_ident_delimited(thd, &yylval->ident_cli, ']');
/* Fall through */
case MY_LEX_SKIP: // This should not happen
if (c != ')')
@@ -1664,7 +1666,7 @@ int Lex_input_stream::lex_one_token(YYSTYPE *yylval, THD *thd)
return scan_ident_start(thd, &yylval->ident_cli);
case MY_LEX_USER_VARIABLE_DELIMITER: // Found quote char
- return scan_ident_delimited(thd, &yylval->ident_cli);
+ return scan_ident_delimited(thd, &yylval->ident_cli, m_tok_start[0]);
case MY_LEX_INT_OR_REAL: // Complete int or incomplete real
if (c != '.' || yyPeek() == '.')
@@ -2236,11 +2238,12 @@ int Lex_input_stream::scan_ident_middle(THD *thd, Lex_ident_cli_st *str,
int Lex_input_stream::scan_ident_delimited(THD *thd,
- Lex_ident_cli_st *str)
+ Lex_ident_cli_st *str,
+ uchar quote_char)
{
CHARSET_INFO *const cs= thd->charset();
uint double_quotes= 0;
- uchar c, quote_char= m_tok_start[0];
+ uchar c;
DBUG_ASSERT(m_ptr == m_tok_start + 1);
while ((c= yyGet()))
@@ -10109,7 +10112,7 @@ Item *remove_pushed_top_conjuncts_for_having(THD *thd, Item *cond)
Multiple equalities are not removed but marked with DELETION_FL flag.
They will be deleted later in substitite_for_best_equal_field() called
for the HAVING condition.
- 5. Unwrap fields wrapped in Item_ref wrappers contain in the condition
+ 5. Unwrap fields wrapped in Item_ref wrappers contained in the condition
of attach_to_conds so the condition could be pushed into WHERE.
@note
@@ -10200,7 +10203,7 @@ Item *st_select_lex::pushdown_from_having_into_where(THD *thd, Item *having)
join->having_equal= 0;
/*
- 5. Unwrap fields wrapped in Item_ref wrappers contain in the condition
+ 5. Unwrap fields wrapped in Item_ref wrappers contained in the condition
of attach_to_conds so the condition could be pushed into WHERE.
*/
it.rewind();
@@ -10210,7 +10213,7 @@ Item *st_select_lex::pushdown_from_having_into_where(THD *thd, Item *having)
&Item::field_transformer_for_having_pushdown,
(uchar *)this);
- if (item->walk(&Item::cleanup_processor, 0, 0) ||
+ if (item->walk(&Item:: cleanup_processor, 0, STOP_PTR) ||
item->fix_fields(thd, NULL))
{
attach_to_conds.empty();
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 3d314537822..4b23d87feb1 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -2678,7 +2678,7 @@ private:
int scan_ident_start(THD *thd, Lex_ident_cli_st *str);
int scan_ident_middle(THD *thd, Lex_ident_cli_st *str,
CHARSET_INFO **cs, my_lex_states *);
- int scan_ident_delimited(THD *thd, Lex_ident_cli_st *str);
+ int scan_ident_delimited(THD *thd, Lex_ident_cli_st *str, uchar quote_char);
bool get_7bit_or_8bit_ident(THD *thd, uchar *last_char);
/** Current thread. */
diff --git a/sql/sql_plugin_services.ic b/sql/sql_plugin_services.ic
index 36748121360..955b9a0ce3a 100644
--- a/sql/sql_plugin_services.ic
+++ b/sql/sql_plugin_services.ic
@@ -172,7 +172,8 @@ static struct wsrep_service_st wsrep_handler = {
wsrep_thd_skip_locking,
wsrep_get_sr_table_name,
wsrep_get_debug,
- wsrep_commit_ordered
+ wsrep_commit_ordered,
+ wsrep_thd_is_applying
};
static struct thd_specifics_service_st thd_specifics_handler=
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 06701d9808d..fc4aaa82f33 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -3026,6 +3026,10 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
for (order= win_spec->order_list->first; order; order= order->next)
order->item= &order->item_ptr;
}
+
+ // Reinit Pushdown
+ sl->cond_pushed_into_where= NULL;
+ sl->cond_pushed_into_having= NULL;
}
if (sl->changed_elements & TOUCHED_SEL_DERIVED)
{
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index f96b3409578..df582a1cd14 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -7815,6 +7815,10 @@ best_access_path(JOIN *join,
DBUG_ASSERT(tmp >= 0);
}
}
+ else
+ {
+ best_filter= 0;
+ }
loose_scan_opt.check_range_access(join, idx, s->quick);
}
@@ -13463,8 +13467,10 @@ void JOIN::join_free()
void JOIN::cleanup(bool full)
{
DBUG_ENTER("JOIN::cleanup");
- DBUG_PRINT("enter", ("full %u", (uint) full));
-
+ DBUG_PRINT("enter", ("select: %d (%p) join: %p full: %u",
+ select_lex->select_number, select_lex, this,
+ (uint) full));
+
if (full)
have_query_plan= QEP_DELETED;
diff --git a/sql/sql_sequence.cc b/sql/sql_sequence.cc
index 1ed0bb38e64..9f17590a315 100644
--- a/sql/sql_sequence.cc
+++ b/sql/sql_sequence.cc
@@ -88,13 +88,13 @@ bool sequence_definition::check_and_adjust(bool set_reserved_until)
/*
If min_value is not set, set it to LONGLONG_MIN or 1, depending on
- increment
+ real_increment
*/
if (!(used_fields & seq_field_used_min_value))
min_value= real_increment < 0 ? LONGLONG_MIN+1 : 1;
/*
- If min_value is not set, set it to LONGLONG_MAX or -1, depending on
+ If max_value is not set, set it to LONGLONG_MAX or -1, depending on
real_increment
*/
if (!(used_fields & seq_field_used_max_value))
diff --git a/sql/sql_type.cc b/sql/sql_type.cc
index 4906eee064d..032530deebc 100644
--- a/sql/sql_type.cc
+++ b/sql/sql_type.cc
@@ -7892,6 +7892,19 @@ bool Type_handler_string_result::Item_eq_value(THD *thd,
/***************************************************************************/
+bool Type_handler_string_result::union_element_finalize(const Item * item) const
+{
+ if (item->collation.derivation == DERIVATION_NONE)
+ {
+ my_error(ER_CANT_AGGREGATE_NCOLLATIONS, MYF(0), "UNION");
+ return true;
+ }
+ return false;
+}
+
+
+/***************************************************************************/
+
void Type_handler_var_string::
Column_definition_implicit_upgrade(Column_definition *c) const
{
diff --git a/sql/sql_type.h b/sql/sql_type.h
index da9913c1265..569e8742d2f 100644
--- a/sql/sql_type.h
+++ b/sql/sql_type.h
@@ -3356,6 +3356,14 @@ public:
virtual Field *make_conversion_table_field(TABLE *TABLE,
uint metadata,
const Field *target) const= 0;
+ /*
+ Performs the final data type validation for a UNION element,
+ after the regular "aggregation for result" was done.
+ */
+ virtual bool union_element_finalize(const Item * item) const
+ {
+ return false;
+ }
// Automatic upgrade, e.g. for ALTER TABLE t1 FORCE
virtual void Column_definition_implicit_upgrade(Column_definition *c) const
{ }
@@ -4580,6 +4588,7 @@ public:
void sortlength(THD *thd,
const Type_std_attributes *item,
SORT_FIELD_ATTR *attr) const;
+ bool union_element_finalize(const Item * item) const;
bool Column_definition_prepare_stage1(THD *thd,
MEM_ROOT *mem_root,
Column_definition *c,
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 528292e5177..e10c0af2e16 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -1085,12 +1085,12 @@ cont:
while ((type= tp++))
{
- if (type->cmp_type() == STRING_RESULT &&
- type->collation.derivation == DERIVATION_NONE)
- {
- my_error(ER_CANT_AGGREGATE_NCOLLATIONS, MYF(0), "UNION");
+ /*
+ Test if the aggregated data type is OK for a UNION element.
+ E.g. in case of string data, DERIVATION_NONE is not allowed.
+ */
+ if (type->type_handler()->union_element_finalize(type))
goto err;
- }
}
/*
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 3014065d28b..13b5caba539 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -1200,7 +1200,7 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table,
in which case the reinit call wasn't done.
See MDEV-6668 for details.
*/
- mysql_derived_reinit(thd, NULL, table);
+ mysql_handle_single_derived(thd->lex, table, DT_REINIT);
DEBUG_SYNC(thd, "after_cached_view_opened");
DBUG_RETURN(0);
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 11634f47e1b..7be705a9090 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -9415,6 +9415,7 @@ for_portion_of_time_clause:
Vers_history_point(VERS_TIMESTAMP, $9),
$5);
}
+ ;
opt_for_portion_of_time_clause:
/* empty */
diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy
index f5a4e55b66f..333bca4af86 100644
--- a/sql/sql_yacc_ora.yy
+++ b/sql/sql_yacc_ora.yy
@@ -9528,6 +9528,7 @@ for_portion_of_time_clause:
Vers_history_point(VERS_TIMESTAMP, $9),
$5);
}
+ ;
opt_for_portion_of_time_clause:
/* empty */
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index 5626fc5bdaf..14d5ae85462 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -5223,8 +5223,10 @@ static Sys_var_ulonglong Sys_read_binlog_speed_limit(
static Sys_var_charptr Sys_slave_transaction_retry_errors(
"slave_transaction_retry_errors", "Tells the slave thread to retry "
"transaction for replication when a query event returns an error from "
- "the provided list. Deadlock and elapsed lock wait timeout errors are "
- "automatically added to this list",
+ "the provided list. Deadlock error, elapsed lock wait timeout, "
+ "net read error, net read timeout, net write error, net write timeout, "
+ "connect error and 2 types of lost connection error are automatically "
+ "added to this list",
READ_ONLY GLOBAL_VAR(opt_slave_transaction_retry_errors), CMD_LINE(REQUIRED_ARG),
IN_SYSTEM_CHARSET, DEFAULT(0));
diff --git a/sql/table.cc b/sql/table.cc
index f605ebf9d31..dcf74172b41 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -2690,7 +2690,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
field->key_start.set_bit(key);
if (field->key_length() == key_part->length &&
!(field->flags & BLOB_FLAG) &&
- key_info->algorithm != HA_KEY_ALG_LONG_HASH)
+ keyinfo->algorithm != HA_KEY_ALG_LONG_HASH)
{
if (handler_file->index_flags(key, i, 0) & HA_KEYREAD_ONLY)
{
@@ -8080,10 +8080,10 @@ public:
/*
- to satisfy ASSERT_COLUMN_MARKED_FOR_WRITE Field's assert we temporarily
+ to satisfy marked_for_write_or_computed() Field's assert we temporarily
mark field for write before storing the generated value in it
*/
-#ifndef DBUG_OFF
+#ifdef DBUG_ASSERT_EXISTS
#define DBUG_FIX_WRITE_SET(f) bool _write_set_fixed= !bitmap_fast_test_and_set(write_set, (f)->field_index)
#define DBUG_RESTORE_WRITE_SET(f) if (_write_set_fixed) bitmap_clear_bit(write_set, (f)->field_index)
#else
@@ -9409,6 +9409,7 @@ bool vers_select_conds_t::eq(const vers_select_conds_t &conds) const
return true;
case SYSTEM_TIME_BEFORE:
DBUG_ASSERT(0);
+ return false;
case SYSTEM_TIME_AS_OF:
return start.eq(conds.start);
case SYSTEM_TIME_FROM_TO:
diff --git a/sql/threadpool.h b/sql/threadpool.h
index ba17dc042c2..57750b73e42 100644
--- a/sql/threadpool.h
+++ b/sql/threadpool.h
@@ -1,3 +1,7 @@
+#ifndef THREADPOOL_H_INCLUDED
+#define THREADPOOL_H_INCLUDED
+
+#ifdef HAVE_POOL_OF_THREADS
/* Copyright (C) 2012 Monty Program Ab
This program is free software; you can redistribute it and/or modify
@@ -154,3 +158,6 @@ struct TP_pool_generic :TP_pool
virtual int set_stall_limit(uint);
virtual int get_idle_thread_count();
};
+
+#endif /* HAVE_POOL_OF_THREADS */
+#endif /* THREADPOOL_H_INCLUDED */
diff --git a/sql/unireg.cc b/sql/unireg.cc
index 1d6bb0cdfce..02d876e1455 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -974,13 +974,36 @@ static bool pack_fields(uchar **buff_arg, List<Create_field> &create_fields,
DBUG_RETURN(0);
}
+
+static bool make_empty_rec_store_default(THD *thd, Field *regfield,
+ Virtual_column_info *default_value)
+{
+ if (default_value && !default_value->flags)
+ {
+ Item *expr= default_value->expr;
+ // may be already fixed if ALTER TABLE
+ if (expr->fix_fields_if_needed(thd, &expr))
+ return true;
+ DBUG_ASSERT(expr == default_value->expr); // Should not change
+ if (regfield->make_empty_rec_store_default_value(thd, expr))
+ {
+ my_error(ER_INVALID_DEFAULT, MYF(0), regfield->field_name.str);
+ return true;
+ }
+ return false;
+ }
+ regfield->make_empty_rec_reset(thd);
+ return false;
+}
+
+
/* save an empty record on start of formfile */
static bool make_empty_rec(THD *thd, uchar *buff, uint table_options,
List<Create_field> &create_fields,
uint reclength, ulong data_offset)
{
- int error= 0;
+ int error= false;
uint null_count;
uchar *null_pos;
TABLE table;
@@ -1020,7 +1043,7 @@ static bool make_empty_rec(THD *thd, uchar *buff, uint table_options,
field->flags);
if (!regfield)
{
- error= 1;
+ error= true;
goto err; // End of memory
}
@@ -1037,36 +1060,10 @@ static bool make_empty_rec(THD *thd, uchar *buff, uint table_options,
!f_bit_as_char(field->pack_flag))
null_count+= field->length & 7;
- if (field->default_value && !field->default_value->flags &&
- (!(field->flags & BLOB_FLAG) ||
- field->real_field_type() == MYSQL_TYPE_GEOMETRY))
- {
- Item *expr= field->default_value->expr;
- // may be already fixed if ALTER TABLE
- int res= expr->fix_fields_if_needed(thd, &expr);
- if (!res)
- res= expr->save_in_field(regfield, 1);
- if (!res && (field->flags & BLOB_FLAG))
- regfield->reset();
-
- /* If not ok or warning of level 'note' */
- if (res != 0 && res != 3)
- {
- my_error(ER_INVALID_DEFAULT, MYF(0), regfield->field_name.str);
- error= 1;
- delete regfield; //To avoid memory leak
- goto err;
- }
- delete regfield; //To avoid memory leak
- }
- else if (regfield->real_type() == MYSQL_TYPE_ENUM &&
- (field->flags & NOT_NULL_FLAG))
- {
- regfield->set_notnull();
- regfield->store((longlong) 1, TRUE);
- }
- else
- regfield->reset();
+ error= make_empty_rec_store_default(thd, regfield, field->default_value);
+ delete regfield; // Avoid memory leaks
+ if (error)
+ goto err;
}
DBUG_ASSERT(data_offset == ((null_count + 7) / 8));
diff --git a/sql/wsrep_dummy.cc b/sql/wsrep_dummy.cc
index bd37042992a..01f2ad88ed5 100644
--- a/sql/wsrep_dummy.cc
+++ b/sql/wsrep_dummy.cc
@@ -135,3 +135,6 @@ my_bool wsrep_get_debug()
void wsrep_commit_ordered(THD* )
{ }
+
+my_bool wsrep_thd_is_applying(const THD*)
+{ return 0;}