summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/ha_innodb.cc18
-rw-r--r--sql/item.cc6
-rw-r--r--sql/item_cmpfunc.h9
-rw-r--r--sql/item_func.cc18
-rw-r--r--sql/item_func.h4
-rw-r--r--sql/item_subselect.cc16
-rw-r--r--sql/mysql_priv.h1
-rw-r--r--sql/sql_base.cc14
-rw-r--r--sql/sql_cache.cc4
-rw-r--r--sql/sql_class.cc8
-rw-r--r--sql/sql_class.h1
-rw-r--r--sql/sql_lex.cc5
-rw-r--r--sql/sql_lex.h1
-rw-r--r--sql/sql_select.cc2
-rw-r--r--sql/sql_table.cc6
15 files changed, 89 insertions, 24 deletions
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 502f8eb92f3..1d75ce99aee 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -4672,12 +4672,12 @@ ha_innobase::update_table_comment(
dict_print_info_on_foreign_keys(FALSE, file,
prebuilt->trx, prebuilt->table);
flen = ftell(file);
- if(length + flen + 3 > 64000) {
+ if (flen < 0) {
+ flen = 0;
+ } else if (length + flen + 3 > 64000) {
flen = 64000 - 3 - length;
}
- ut_ad(flen > 0);
-
/* allocate buffer for the full string, and
read the contents of the temporary file */
@@ -4741,12 +4741,12 @@ ha_innobase::get_foreign_key_create_info(void)
prebuilt->trx->op_info = (char*)"";
flen = ftell(file);
- if(flen > 64000 - 1) {
+ if (flen < 0) {
+ flen = 0;
+ } else if(flen > 64000 - 1) {
flen = 64000 - 1;
}
- ut_ad(flen >= 0);
-
/* allocate buffer for the string, and
read the contents of the temporary file */
@@ -5142,12 +5142,12 @@ innodb_show_status(
srv_printf_innodb_monitor(srv_monitor_file);
flen = ftell(srv_monitor_file);
os_file_set_eof(srv_monitor_file);
- if(flen > 64000 - 1) {
+ if (flen < 0) {
+ flen = 0;
+ } else if (flen > 64000 - 1) {
flen = 64000 - 1;
}
- ut_ad(flen > 0);
-
/* allocate buffer for the string, and
read the contents of the temporary file */
diff --git a/sql/item.cc b/sql/item.cc
index 8c45dffce75..ab29c147dfb 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1482,12 +1482,13 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
}
else if (refer != (Item **)not_found_item)
{
- if (!(*refer)->fixed)
+ if (!last->ref_pointer_array[counter])
{
my_error(ER_ILLEGAL_REFERENCE, MYF(0), name,
"forward reference in item list");
return -1;
}
+ DBUG_ASSERT((*refer)->fixed);
/*
Here, a subset of actions performed by Item_ref::set_properties
is not enough. So we pass ptr to NULL into Item_[direct]_ref
@@ -2161,12 +2162,13 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
mark_as_dependent(thd, last, thd->lex->current_select, fld);
return 0;
}
- if (!(*ref)->fixed)
+ if (!last->ref_pointer_array[counter])
{
my_error(ER_ILLEGAL_REFERENCE, MYF(0), name,
"forward reference in item list");
return -1;
}
+ DBUG_ASSERT((*ref)->fixed);
mark_as_dependent(thd, last, thd->lex->current_select,
this);
if (place == IN_HAVING)
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 6834799688d..061ed468b78 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -213,7 +213,7 @@ class Item_bool_rowready_func2 :public Item_bool_func2
public:
Item_bool_rowready_func2(Item *a, Item *b) :Item_bool_func2(a, b)
{
- allowed_arg_cols= a->cols();
+ allowed_arg_cols= 0; // Fetch this value from first argument
}
Item *neg_transformer(THD *thd);
virtual Item *negated_item();
@@ -390,7 +390,10 @@ class Item_func_interval :public Item_int_func
double *intervals;
public:
Item_func_interval(Item_row *a)
- :Item_int_func(a),row(a),intervals(0) { allowed_arg_cols= a->cols(); }
+ :Item_int_func(a),row(a),intervals(0)
+ {
+ allowed_arg_cols= 0; // Fetch this value from first argument
+ }
longlong val_int();
void fix_length_and_dec();
const char *func_name() const { return "interval"; }
@@ -743,7 +746,7 @@ class Item_func_in :public Item_int_func
Item_func_in(List<Item> &list)
:Item_int_func(list), array(0), in_item(0), have_null(0)
{
- allowed_arg_cols= args[0]->cols();
+ allowed_arg_cols= 0; // Fetch this value from first argument
}
longlong val_int();
void fix_length_and_dec();
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 7125f4704b8..bff49541252 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -303,10 +303,24 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
We can't yet set item to *arg as fix_fields may change *arg
We shouldn't call fix_fields() twice, so check 'fixed' field first
*/
- if ((!(*arg)->fixed && (*arg)->fix_fields(thd, tables, arg)) ||
- (*arg)->check_cols(allowed_arg_cols))
+ if ((!(*arg)->fixed && (*arg)->fix_fields(thd, tables, arg)))
return 1; /* purecov: inspected */
+
item= *arg;
+
+ if (allowed_arg_cols)
+ {
+ if (item->check_cols(allowed_arg_cols))
+ return 1;
+ }
+ else
+ {
+ /* we have to fetch allowed_arg_cols from first argument */
+ DBUG_ASSERT(arg == args); // it is first argument
+ allowed_arg_cols= item->cols();
+ DBUG_ASSERT(allowed_arg_cols); // Can't be 0 any more
+ }
+
if (item->maybe_null)
maybe_null=1;
diff --git a/sql/item_func.h b/sql/item_func.h
index ce2b34499d6..8a5347d675e 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -32,6 +32,10 @@ class Item_func :public Item_result_field
{
protected:
Item **args, *tmp_arg[2];
+ /*
+ Allowed numbers of columns in result (usually 1, which means scalar value)
+ 0 means get this number from first argument
+ */
uint allowed_arg_cols;
public:
uint arg_count;
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 8516ea76a7e..16186b1a6d3 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -995,6 +995,10 @@ Item_in_subselect::row_value_transformer(JOIN *join)
List_iterator_fast<Item> li(select_lex->item_list);
for (uint i= 0; i < n; i++)
{
+ DBUG_ASSERT(left_expr->fixed && select_lex->ref_pointer_array[i]->fixed);
+ if (select_lex->ref_pointer_array[i]->
+ check_cols(left_expr->el(i)->cols()))
+ goto err;
Item *func= new Item_ref_null_helper(this,
select_lex->ref_pointer_array+i,
(char *) "<no matter>",
@@ -1123,6 +1127,7 @@ void subselect_single_select_engine::cleanup()
DBUG_ENTER("subselect_single_select_engine::cleanup");
prepared= optimized= executed= 0;
join= 0;
+ result->cleanup();
DBUG_VOID_RETURN;
}
@@ -1131,6 +1136,7 @@ void subselect_union_engine::cleanup()
{
DBUG_ENTER("subselect_union_engine::cleanup");
unit->reinit_exec_mechanism();
+ result->cleanup();
DBUG_VOID_RETURN;
}
@@ -1138,6 +1144,10 @@ void subselect_union_engine::cleanup()
void subselect_uniquesubquery_engine::cleanup()
{
DBUG_ENTER("subselect_uniquesubquery_engine::cleanup");
+ /*
+ subselect_uniquesubquery_engine have not 'result' assigbed, so we do not
+ cleanup() it
+ */
DBUG_VOID_RETURN;
}
@@ -1421,13 +1431,15 @@ int subselect_indexsubquery_engine::exec()
uint subselect_single_select_engine::cols()
{
- return select_lex->item_list.elements;
+ DBUG_ASSERT(select_lex->join); // should be called after fix_fields()
+ return select_lex->join->fields_list.elements;
}
uint subselect_union_engine::cols()
{
- return unit->first_select()->item_list.elements;
+ DBUG_ASSERT(unit->is_prepared()); // should be called after fix_fields()
+ return unit->types.elements;
}
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 06a17acd2a1..6218bc49f53 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -377,6 +377,7 @@ Item *negate_expression(THD *thd, Item *expr);
struct Query_cache_query_flags
{
unsigned int client_long_flag:1;
+ unsigned int client_protocol_41:1;
uint character_set_client_num;
uint character_set_results_num;
uint collation_connection_num;
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 7d26996856d..7434897ab90 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -2405,6 +2405,20 @@ int setup_fields(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
thd->allow_sum_func= allow_sum_func;
thd->where="field list";
+ /*
+ To prevent fail on forward lookup we fill it with zerows,
+ then if we got pointer on zero after find_item_in_list we will know
+ that it is forward lookup.
+
+ There is other way to solve problem: fill array with pointers to list,
+ but it will be slower.
+
+ TODO: remove it when (if) we made one list for allfields and
+ ref_pointer_array
+ */
+ if (ref_pointer_array)
+ bzero(ref_pointer_array, sizeof(Item *) * fields.elements);
+
Item **ref= ref_pointer_array;
while ((item= it++))
{
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index 55e96ec0c6d..e1367412601 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -776,6 +776,8 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used)
bzero(&flags, QUERY_CACHE_FLAGS_SIZE);
flags.client_long_flag= (thd->client_capabilities & CLIENT_LONG_FLAG ?
1 : 0);
+ flags.client_protocol_41= (thd->client_capabilities & CLIENT_PROTOCOL_41 ?
+ 1 : 0);
flags.character_set_client_num=
thd->variables.character_set_client->number;
flags.character_set_results_num=
@@ -968,6 +970,8 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
bzero(&flags, QUERY_CACHE_FLAGS_SIZE);
flags.client_long_flag= (thd->client_capabilities & CLIENT_LONG_FLAG ?
1 : 0);
+ flags.client_protocol_41= (thd->client_capabilities & CLIENT_PROTOCOL_41 ?
+ 1 : 0);
flags.character_set_client_num= thd->variables.character_set_client->number;
flags.character_set_results_num=
(thd->variables.character_set_results ?
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 596097d9dc2..e11d8369f57 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1240,6 +1240,14 @@ bool select_singlerow_subselect::send_data(List<Item> &items)
}
+void select_max_min_finder_subselect::cleanup()
+{
+ DBUG_ENTER("select_max_min_finder_subselect::cleanup");
+ cache= 0;
+ DBUG_VOID_RETURN;
+}
+
+
bool select_max_min_finder_subselect::send_data(List<Item> &items)
{
DBUG_ENTER("select_max_min_finder_subselect::send_data");
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 8128690ab02..657a92b394c 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1386,6 +1386,7 @@ public:
select_max_min_finder_subselect(Item_subselect *item, bool mx)
:select_subselect(item), cache(0), fmax(mx)
{}
+ void cleanup();
bool send_data(List<Item> &items);
bool cmp_real();
bool cmp_int();
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 3ac783da9c4..ed974a48ad3 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -164,7 +164,10 @@ void lex_start(THD *thd, uchar *buf,uint length)
void lex_end(LEX *lex)
{
- lex->select_lex.expr_list.delete_elements(); // If error when parsing sql-varargs
+ for (SELECT_LEX *sl= lex->all_selects_list;
+ sl;
+ sl= sl->next_select_in_list())
+ sl->expr_list.delete_elements(); // If error when parsing sql-varargs
x_free(lex->yacc_yyss);
x_free(lex->yacc_yyvs);
}
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index e2e0bc61c23..7cb71607edf 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -371,6 +371,7 @@ public:
ulong init_prepare_fake_select_lex(THD *thd);
int change_result(select_subselect *result, select_subselect *old_result);
+ inline bool is_prepared() { return prepared; }
friend void lex_start(THD *thd, uchar *buf, uint length);
friend int subselect_union_engine::exec();
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index ccfcb213068..8353ca9333d 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1320,7 +1320,7 @@ JOIN::exec()
curr_join->select_distinct=0; /* Each row is unique */
curr_join->join_free(0); /* Free quick selects */
- if (select_distinct && ! group_list)
+ if (curr_join->select_distinct && ! curr_join->group_list)
{
thd->proc_info="Removing duplicates";
if (curr_join->tmp_having)
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 423a309767b..f3c107c2696 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -2272,8 +2272,7 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table,
strxmov(src_path, (*tmp_table)->path, reg_ext, NullS);
else
{
- strxmov(src_path, mysql_data_home, "/", src_db, "/", src_table,
- reg_ext, NullS);
+ fn_format( src_path, src_table, src_db, reg_ext, MYF(MY_UNPACK_FILENAME));
if (access(src_path, F_OK))
{
my_error(ER_BAD_TABLE_ERROR, MYF(0), src_table);
@@ -2300,8 +2299,7 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table,
}
else
{
- strxmov(dst_path, mysql_data_home, "/", db, "/", table_name,
- reg_ext, NullS);
+ fn_format( dst_path, table_name, db, reg_ext, MYF(MY_UNPACK_FILENAME));
if (!access(dst_path, F_OK))
goto table_exists;
}