summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/field.cc38
-rw-r--r--sql/field.h2
-rw-r--r--sql/ha_federated.cc110
-rw-r--r--sql/handler.cc2
-rw-r--r--sql/item_func.cc8
-rw-r--r--sql/item_sum.cc4
-rw-r--r--sql/lock.cc2
-rw-r--r--sql/log_event.cc2
-rw-r--r--sql/mysql_priv.h35
-rw-r--r--sql/opt_range.cc6
-rw-r--r--sql/sp_head.cc36
-rw-r--r--sql/sql_acl.cc29
-rw-r--r--sql/sql_acl.h2
-rw-r--r--sql/sql_base.cc6
-rw-r--r--sql/sql_delete.cc2
-rw-r--r--sql/sql_error.cc5
-rw-r--r--sql/sql_help.cc2
-rw-r--r--sql/sql_parse.cc54
-rw-r--r--sql/sql_prepare.cc2
-rw-r--r--sql/sql_rename.cc2
-rw-r--r--sql/sql_select.cc36
-rw-r--r--sql/sql_show.cc34
-rw-r--r--sql/sql_string.cc12
-rw-r--r--sql/sql_table.cc282
-rw-r--r--sql/sql_udf.cc13
-rw-r--r--sql/sql_update.cc4
-rw-r--r--sql/sql_yacc.yy246
-rw-r--r--sql/table.cc6
28 files changed, 565 insertions, 417 deletions
diff --git a/sql/field.cc b/sql/field.cc
index 26575d97f69..b6dd00d62a7 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -5328,11 +5328,11 @@ Field *Field_string::new_field(MEM_ROOT *root, struct st_table *new_table)
int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
{
- int error= 0;
uint32 not_used, copy_length;
char buff[STRING_BUFFER_USUAL_SIZE];
String tmpstr(buff,sizeof(buff), &my_charset_bin);
- bool lost_only_spaces= FALSE;
+ int error_code= 0;
+ enum MYSQL_ERROR::enum_warning_level level= MYSQL_ERROR::WARN_LEVEL_WARN;
/* Convert character set if necessary */
if (String::needs_conversion(length, cs, field_charset, &not_used))
@@ -5342,7 +5342,7 @@ int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
from= tmpstr.ptr();
length= tmpstr.length();
if (conv_errors)
- error= 1;
+ error_code= WARN_DATA_TRUNCATED;
}
/*
Make sure we don't break a multibyte sequence
@@ -5359,30 +5359,26 @@ int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
int2store(ptr, copy_length);
// Check if we lost something other than just trailing spaces
- if ((copy_length < length) && table->in_use->count_cuted_fields)
+ if ((copy_length < length) && table->in_use->count_cuted_fields &&
+ !error_code)
{
const char *end= from + length;
from+= copy_length;
from+= field_charset->cset->scan(field_charset, from, end, MY_SEQ_SPACES);
- /*
- If we lost only spaces then produce a NOTE, not a WARNING.
- But if we have already had errors (e.g with charset conversion),
- then don't reset level to NOTE.
- */
- if (from == end && !error)
- lost_only_spaces= TRUE;
- error= 1;
+ /* If we lost only spaces then produce a NOTE, not a WARNING */
+ if (from == end)
+ level= MYSQL_ERROR::WARN_LEVEL_NOTE;
+ error_code= WARN_DATA_TRUNCATED;
}
- if (error)
+ if (error_code)
{
- if (lost_only_spaces)
- set_warning(MYSQL_ERROR::WARN_LEVEL_NOTE, WARN_DATA_TRUNCATED, 1);
- else if (table->in_use->abort_on_warning)
- set_warning(MYSQL_ERROR::WARN_LEVEL_ERROR, ER_DATA_TOO_LONG, 1);
- else
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
+ if (level == MYSQL_ERROR::WARN_LEVEL_WARN &&
+ table->in_use->abort_on_warning)
+ error_code= ER_DATA_TOO_LONG;
+ set_warning(level, error_code, 1);
+ return 1;
}
- return error;
+ return 0;
}
@@ -7562,7 +7558,7 @@ create_field::create_field(Field *old_field,Field *orig_field)
false - otherwise
*/
bool
-Field::set_warning(const uint level, const uint code, int cuted_increment)
+Field::set_warning(uint level, uint code, int cuted_increment)
{
THD *thd= table->in_use;
if (thd->count_cuted_fields)
diff --git a/sql/field.h b/sql/field.h
index 083af27d6d9..5b13ba1042a 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -279,7 +279,7 @@ public:
virtual CHARSET_INFO *sort_charset(void) const { return charset(); }
virtual bool has_charset(void) const { return FALSE; }
virtual void set_charset(CHARSET_INFO *charset) { }
- bool set_warning(const unsigned int level, const unsigned int code,
+ bool set_warning(unsigned int level, unsigned int code,
int cuted_increment);
bool check_int(const char *str, int length, const char *int_end,
CHARSET_INFO *cs);
diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc
index 215a8daf200..cddd0fd5927 100644
--- a/sql/ha_federated.cc
+++ b/sql/ha_federated.cc
@@ -634,23 +634,12 @@ static int parse_url(FEDERATED_SHARE *share, TABLE *table,
share->port= MYSQL_PORT;
}
- DBUG_PRINT("ha_federated::parse_url",
+ DBUG_PRINT("info",
("scheme %s username %s password %s \
hostname %s port %d database %s tablename %s\n",
share->scheme, share->username, share->password,
share->hostname, share->port, share->database,
share->table_base_name));
-
- /* If creation, check first if we can connect and that the table exists */
- /*if (table_create_flag)
- {
- if (check_foreign_data_source(share))
- goto error;
- */
- /* free share->schema even if no error, since this is a create */
- /*
- my_free((gptr) share->scheme, MYF(0));
- }*/
}
else
goto error;
@@ -662,7 +651,7 @@ static int parse_url(FEDERATED_SHARE *share, TABLE *table,
error:
my_error(error_num, MYF(0),
- "this connection string is not in the correct format!\n");
+ "connection string is not in the correct format",0);
DBUG_RETURN(1);
}
@@ -760,7 +749,7 @@ bool ha_federated::create_where_from_key(String *to, KEY *key_info,
if (to->append("IS NULL", 7))
DBUG_RETURN(1);
- DBUG_PRINT("ha_federated::create_where_from_key",
+ DBUG_PRINT("info",
("NULL type %s", to->c_ptr_quick()));
key_length-= key_part->store_length;
key+= key_part->store_length - 1;
@@ -790,8 +779,6 @@ bool ha_federated::create_where_from_key(String *to, KEY *key_info,
if (to->append(buff, (uint)(ptr - buff)))
DBUG_RETURN(1);
- DBUG_PRINT("ha_federated::create_where_from_key",
- ("bit type %s", to->c_ptr_quick()));
key_length-= length;
continue;
}
@@ -805,8 +792,6 @@ bool ha_federated::create_where_from_key(String *to, KEY *key_info,
if (append_escaped(to, &tmp))
DBUG_RETURN(1);
- DBUG_PRINT("ha_federated::create_where_from_key",
- ("blob type %s", to->c_ptr_quick()));
length= key_part->length;
}
else if (key_part->key_part_flag & HA_VAR_LENGTH_PART)
@@ -816,14 +801,9 @@ bool ha_federated::create_where_from_key(String *to, KEY *key_info,
tmp.set_quick((char*) key, length, &my_charset_bin);
if (append_escaped(to, &tmp))
DBUG_RETURN(1);
-
- DBUG_PRINT("ha_federated::create_where_from_key",
- ("varchar type %s", to->c_ptr_quick()));
}
else
{
- DBUG_PRINT("ha_federated::create_where_from_key",
- ("else block, unknown type so far"));
char buff[MAX_FIELD_WIDTH];
String str(buff, sizeof(buff), field->charset()), *res;
@@ -833,16 +813,13 @@ bool ha_federated::create_where_from_key(String *to, KEY *key_info,
if (append_escaped(to, res))
DBUG_RETURN(1);
res= field->val_str(&str, (char*) (key));
-
- DBUG_PRINT("ha_federated::create_where_from_key",
- ("else block, string type", to->c_ptr_quick()));
}
else if (to->append(res->ptr(), res->length()))
DBUG_RETURN(1);
}
if (needs_quotes && to->append("'"))
DBUG_RETURN(1);
- DBUG_PRINT("ha_federated::create_where_from_key",
+ DBUG_PRINT("info",
("final value for 'to' %s", to->c_ptr_quick()));
key+= length;
key_length-= length;
@@ -869,7 +846,7 @@ static FEDERATED_SHARE *get_share(const char *table_name, TABLE *table)
/* share->table_name has the file location - we want the table's name! */
table_base_name= (char*) table->s->table_name;
- DBUG_PRINT("ha_federated::get_share", ("table_name %s", table_base_name));
+ DBUG_PRINT("info", ("table_name %s", table_base_name));
/*
So why does this exist? There is no way currently to init a storage engine.
Innodb and BDB both have modifications to the server to allow them to
@@ -909,7 +886,7 @@ static FEDERATED_SHARE *get_share(const char *table_name, TABLE *table)
share->select_query= select_query;
strmov(share->table_name, table_name);
strmov(share->select_query, query.ptr());
- DBUG_PRINT("ha_federated::get_share",
+ DBUG_PRINT("info",
("share->select_query %s", share->select_query));
if (my_hash_insert(&federated_open_tables, (byte*) share))
goto error;
@@ -996,11 +973,11 @@ int ha_federated::open(const char *name, int mode, uint test_if_locked)
/* Connect to foreign database mysql_real_connect() */
mysql= mysql_init(0);
- DBUG_PRINT("ha_federated::open", ("hostname %s", share->hostname));
- DBUG_PRINT("ha_federated::open", ("username %s", share->username));
- DBUG_PRINT("ha_federated::open", ("password %s", share->password));
- DBUG_PRINT("ha_federated::open", ("database %s", share->database));
- DBUG_PRINT("ha_federated::open", ("port %d", share->port));
+ DBUG_PRINT("info", ("hostname %s", share->hostname));
+ DBUG_PRINT("info", ("username %s", share->username));
+ DBUG_PRINT("info", ("password %s", share->password));
+ DBUG_PRINT("info", ("database %s", share->database));
+ DBUG_PRINT("info", ("port %d", share->port));
if (!mysql_real_connect(mysql,
share->hostname,
share->username,
@@ -1034,7 +1011,7 @@ int ha_federated::close(void)
/* free the result set */
if (result)
{
- DBUG_PRINT("ha_federated::close",
+ DBUG_PRINT("info",
("mysql_free_result result at address %lx", result));
mysql_free_result(result);
result= 0;
@@ -1120,7 +1097,7 @@ int ha_federated::write_row(byte *buf)
insert_field_value_string.length(0);
DBUG_ENTER("ha_federated::write_row");
- DBUG_PRINT("ha_federated::write_row", ("table charset name %s csname %s",
+ DBUG_PRINT("info", ("table charset name %s csname %s",
table->s->table_charset->name, table->s->table_charset->csname));
statistic_increment(table->in_use->status_var.ha_write_count, &LOCK_status);
@@ -1133,8 +1110,7 @@ int ha_federated::write_row(byte *buf)
this query id
*/
current_query_id= table->in_use->query_id;
- DBUG_PRINT("ha_federated::write_row", ("current query id %d",
- current_query_id));
+ DBUG_PRINT("info", ("current query id %d", current_query_id));
/* start off our string */
insert_string.append("INSERT INTO `");
@@ -1160,9 +1136,9 @@ int ha_federated::write_row(byte *buf)
loop through the field pointer array, add any fields to both the values
list and the fields list that match the current query id
*/
+ x=0;
for (field= table->field; *field; field++, x++)
{
- DBUG_PRINT("ha_federated::write_row", ("field type %d", (*field)->type()));
/* if there is a query id and if it's equal to the current query id */
if (((*field)->query_id && (*field)->query_id == current_query_id)
|| all_fields_have_same_query_id)
@@ -1171,16 +1147,16 @@ int ha_federated::write_row(byte *buf)
if ((*field)->is_null())
{
- DBUG_PRINT("ha_federated::write_row",
- ("current query id %d field is_null query id %d",
- current_query_id, (*field)->query_id));
+ DBUG_PRINT("info",
+ ("column %d current query id %d field is_null query id %d",
+ x, current_query_id, (*field)->query_id));
insert_field_value_string.append("NULL");
}
else
{
- DBUG_PRINT("ha_federated::write_row",
- ("current query id %d field is not null query ID %d",
- current_query_id, (*field)->query_id));
+ DBUG_PRINT("info",
+ ("column %d current query id %d field is not null query ID %d",
+ x, current_query_id, (*field)->query_id));
(*field)->val_str(&insert_field_value_string);
/* quote these fields if they require it */
(*field)->quote_data(&insert_field_value_string); }
@@ -1194,10 +1170,6 @@ int ha_federated::write_row(byte *buf)
/* append commas between both fields and fieldnames */
insert_string.append(',');
values_string.append(',');
- DBUG_PRINT("ha_federated::write_row",
- ("insert_string %s values_string %s insert_field_value_string %s",
- insert_string.c_ptr_quick(), values_string.c_ptr_quick(),
- insert_field_value_string.c_ptr_quick()));
}
}
@@ -1215,7 +1187,7 @@ int ha_federated::write_row(byte *buf)
AND, we don't want to chop off the last char '('
insert will be "INSERT INTO t1 VALUES ();"
*/
- DBUG_PRINT("ha_federated::write_row", ("x %d num fields %d", x, num_fields));
+ DBUG_PRINT("info", ("x %d num fields %d", x, num_fields));
if (num_fields > 0)
{
/* chops off leading commas */
@@ -1228,8 +1200,7 @@ int ha_federated::write_row(byte *buf)
/* add the values */
insert_string.append(values_string);
- DBUG_PRINT("ha_federated::write_row", ("insert query %s",
- insert_string.c_ptr_quick()));
+ DBUG_PRINT("info", ("insert query %s", insert_string.c_ptr_quick()));
if (mysql_real_query(mysql, insert_string.ptr(), insert_string.length()))
{
@@ -1240,6 +1211,7 @@ int ha_federated::write_row(byte *buf)
DBUG_RETURN(0);
}
+
/*
Yes, update_row() does what you expect, it updates a row. old_data will have
the previous row record in it, while new_data will have the newest data in
@@ -1286,7 +1258,7 @@ int ha_federated::update_row(const byte *old_data, byte *new_data)
primary_key_field_num= has_a_primary_key ?
table->key_info[table->s->primary_key].key_part->fieldnr - 1 : -1;
if (has_a_primary_key)
- DBUG_PRINT("ha_federated::update_row", ("has a primary key"));
+ DBUG_PRINT("info", ("has a primary key"));
update_string.append("UPDATE `");
update_string.append(share->table_base_name);
@@ -1324,7 +1296,10 @@ int ha_federated::update_row(const byte *old_data, byte *new_data)
update_string.append('=');
if ((*field)->is_null())
+ {
+ DBUG_PRINT("info", ("column %d is NULL", x ));
new_field_value.append("NULL");
+ }
else
{
/* otherwise = */
@@ -1356,12 +1331,18 @@ int ha_federated::update_row(const byte *old_data, byte *new_data)
where_string.append(" IS NULL ");
else
{
+ uint o_len;
(*field)->val_str(&old_field_value,
(char*) (old_data + (*field)->offset()));
+ o_len= (*field)->pack_length();
+ DBUG_PRINT("info", ("o_len %lu", o_len));
(*field)->quote_data(&old_field_value);
where_string.append(old_field_value);
}
}
+ DBUG_PRINT("info",
+ ("column %d new value %s old value %s",
+ x, new_field_value.c_ptr_quick(), old_field_value.c_ptr_quick() ));
update_string.append(new_field_value);
new_field_value.length(0);
@@ -1378,7 +1359,7 @@ int ha_federated::update_row(const byte *old_data, byte *new_data)
if (! has_a_primary_key)
update_string.append(" LIMIT 1");
- DBUG_PRINT("ha_federated::update_row", ("Final update query: %s",
+ DBUG_PRINT("info", ("Final update query: %s",
update_string.c_ptr_quick()));
if (mysql_real_query(mysql, update_string.ptr(), update_string.length()))
{
@@ -1447,7 +1428,7 @@ int ha_federated::delete_row(const byte *buf)
}
delete_string.append(" LIMIT 1");
- DBUG_PRINT("ha_federated::delete_row",
+ DBUG_PRINT("info",
("Delete sql: %s", delete_string.c_ptr_quick()));
if (mysql_real_query(mysql, delete_string.ptr(), delete_string.length()))
{
@@ -1513,12 +1494,12 @@ int ha_federated::index_read_idx(byte *buf, uint index, const byte *key,
create_where_from_key(&index_string, &table->key_info[index], key, keylen);
sql_query.append(index_string);
- DBUG_PRINT("ha_federated::index_read_idx",
+ DBUG_PRINT("info",
("current key %d key value %s index_string value %s length %d",
index, (char*) key, index_string.c_ptr_quick(),
index_string.length()));
- DBUG_PRINT("ha_federated::index_read_idx",
+ DBUG_PRINT("info",
("current position %d sql_query %s", current_position,
sql_query.c_ptr_quick()));
@@ -1554,7 +1535,7 @@ int ha_federated::index_init(uint keynr)
{
int error;
DBUG_ENTER("ha_federated::index_init");
- DBUG_PRINT("ha_federated::index_init",
+ DBUG_PRINT("info",
("table: '%s' key: %d", table->s->table_name, keynr));
active_index= keynr;
DBUG_RETURN(0);
@@ -1623,11 +1604,10 @@ int ha_federated::rnd_init(bool scan)
scan_flag= scan;
if (scan)
{
- DBUG_PRINT("ha_federated::rnd_init",
- ("share->select_query %s", share->select_query));
+ DBUG_PRINT("info", ("share->select_query %s", share->select_query));
if (result)
{
- DBUG_PRINT("ha_federated::rnd_init",
+ DBUG_PRINT("info",
("mysql_free_result address %lx", result));
mysql_free_result(result);
result= 0;
@@ -1652,8 +1632,7 @@ int ha_federated::rnd_end()
DBUG_ENTER("ha_federated::rnd_end");
if (result)
{
- DBUG_PRINT("ha_federated::index_end",
- ("mysql_free_result address %lx", result));
+ DBUG_PRINT("info", ("mysql_free_result address %lx", result));
mysql_free_result(result);
result= 0;
}
@@ -1696,8 +1675,7 @@ int ha_federated::rnd_next(byte *buf)
/* Fetch a row, insert it back in a row format. */
current_position= result->data_cursor;
- DBUG_PRINT("ha_federated::rnd_next",
- ("current position %d", current_position));
+ DBUG_PRINT("info", ("current position %d", current_position));
if (!(row= mysql_fetch_row(result)))
DBUG_RETURN(HA_ERR_END_OF_FILE);
@@ -1941,7 +1919,7 @@ int ha_federated::create(const char *name, TABLE *table_arg,
DBUG_RETURN(0);
error:
- DBUG_PRINT("ha_federated::create", ("errors, returning %d", ER_CANT_CREATE_TABLE));
+ DBUG_PRINT("info", ("errors, returning %d", ER_CANT_CREATE_TABLE));
my_free((gptr) tmp.scheme, MYF(0));
DBUG_RETURN(ER_CANT_CREATE_TABLE);
diff --git a/sql/handler.cc b/sql/handler.cc
index c7bd65bf24c..1ef73a9136f 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -841,7 +841,7 @@ int ha_recover(HASH *commit_list)
for now, only InnoDB supports 2pc. It means we can always safely
rollback all pending transactions, without risking inconsistent data
*/
- DBUG_ASSERT(total_ha_2pc == opt_bin_log+1); // only InnoDB and binlog
+ DBUG_ASSERT(total_ha_2pc == (ulong) opt_bin_log+1); // only InnoDB and binlog
tc_heuristic_recover= TC_HEURISTIC_RECOVER_ROLLBACK; // forcing ROLLBACK
dry_run=FALSE;
#endif
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 0a993b6f3d8..684ba814cd4 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -4467,19 +4467,19 @@ Item_func_sp::Item_func_sp(sp_name *name)
{
maybe_null= 1;
m_name->init_qname(current_thd);
- dummy_table= (TABLE *)sql_alloc(sizeof(TABLE));
- bzero(dummy_table, sizeof(TABLE));
+ dummy_table= (TABLE*) sql_calloc(sizeof(TABLE));
}
+
Item_func_sp::Item_func_sp(sp_name *name, List<Item> &list)
:Item_func(list), m_name(name), m_sp(NULL)
{
maybe_null= 1;
m_name->init_qname(current_thd);
- dummy_table= (TABLE *)sql_alloc(sizeof(TABLE));
- bzero(dummy_table, sizeof(TABLE));
+ dummy_table= (TABLE*) sql_calloc(sizeof(TABLE));
}
+
const char *
Item_func_sp::func_name() const
{
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 174e2ba4b85..b18653ed5a4 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -727,7 +727,7 @@ Item_sum_avg_distinct::fix_length_and_dec()
AVG() will divide val by count. We need to reserve digits
after decimal point as the result can be fractional.
*/
- decimals+= 4;
+ decimals= min(decimals + 4, NOT_FIXED_DEC);
}
@@ -927,7 +927,7 @@ void Item_sum_variance::fix_length_and_dec()
{
DBUG_ENTER("Item_sum_variance::fix_length_and_dec");
maybe_null= null_value= 1;
- decimals= args[0]->decimals + 4;
+ decimals= min(args[0]->decimals + 4, NOT_FIXED_DEC);
switch (args[0]->result_type()) {
case REAL_RESULT:
case STRING_RESULT:
diff --git a/sql/lock.cc b/sql/lock.cc
index b4a51abba70..266e8dc4d4d 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -562,7 +562,7 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list)
my_free((gptr) table,MYF(0));
DBUG_RETURN(-1);
}
- if (remove_table_from_cache(thd, db, table_list->table_name))
+ if (remove_table_from_cache(thd, db, table_list->table_name, 0))
DBUG_RETURN(1); // Table is in use
DBUG_RETURN(0);
}
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 3176cdfd5cb..ba018e859c1 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -2610,7 +2610,7 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli,
"data truncated" warning but which is absorbed and never gets to the
error log); still we init it to avoid a Valgrind message.
*/
- mysql_reset_errors(thd);
+ mysql_reset_errors(thd, 0);
TABLE_LIST tables;
bzero((char*) &tables,sizeof(tables));
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 43bb28a5f36..ba9f382fc33 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -457,7 +457,7 @@ bool check_procedure_access(THD *thd,ulong want_access,char *db,char *name,
bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table);
bool check_merge_table_access(THD *thd, char *db,
TABLE_LIST *table_list);
-bool check_some_routine_access(THD *thd, char *db, char *name);
+bool check_some_routine_access(THD *thd, const char *db, const char *name);
bool multi_update_precheck(THD *thd, TABLE_LIST *tables);
bool multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count);
bool mysql_multi_update_prepare(THD *thd);
@@ -632,10 +632,11 @@ int mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *t);
int mysql_derived_filling(THD *thd, LEX *lex, TABLE_LIST *t);
Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
Item ***copy_func, Field **from_field,
- bool group, bool modify_item, uint convert_blob_length);
+ bool group, bool modify_item,
+ uint convert_blob_length);
int prepare_create_field(create_field *sql_field,
- uint &blob_columns,
- int &timestamps, int &timestamps_with_niladic,
+ uint *blob_columns,
+ int *timestamps, int *timestamps_with_niladic,
uint table_flags);
int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
List<create_field> &fields,
@@ -661,7 +662,7 @@ bool mysql_alter_table(THD *thd, char *new_db, char *new_name,
uint order_num, ORDER *order,
enum enum_duplicates handle_duplicates,
bool ignore,
- ALTER_INFO *alter_info, bool do_send_ok=1);
+ ALTER_INFO *alter_info, bool do_send_ok);
bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list, bool do_send_ok);
bool mysql_create_like_table(THD *thd, TABLE_LIST *table,
HA_CREATE_INFO *create_info,
@@ -705,7 +706,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT* mem,
bool *refresh);
TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table);
TABLE *find_locked_table(THD *thd, const char *db,const char *table_name);
-bool reopen_table(TABLE *table,bool locked=0);
+bool reopen_table(TABLE *table,bool locked);
bool reopen_tables(THD *thd,bool get_locks,bool in_refresh);
void close_old_data_files(THD *thd, TABLE *table, bool abort_locks,
bool send_refresh);
@@ -769,7 +770,7 @@ void append_identifier(THD *thd, String *packet, const char *name,
uint length);
int get_quote_char_for_identifier(THD *thd, const char *name, uint length);
void mysqld_list_fields(THD *thd,TABLE_LIST *table, const char *wild);
-int mysqld_dump_create_info(THD *thd, TABLE_LIST *table_list, int fd = -1);
+int mysqld_dump_create_info(THD *thd, TABLE_LIST *table_list, int fd);
bool mysqld_show_create(THD *thd, TABLE_LIST *table_list);
bool mysqld_show_create_db(THD *thd, char *dbname, HA_CREATE_INFO *create);
@@ -790,7 +791,7 @@ void calc_sum_of_all_status(STATUS_VAR *to);
extern LEX_STRING information_schema_name;
LEX_STRING *make_lex_string(THD *thd, LEX_STRING *lex_str,
const char* str, uint length,
- bool allocate_lex_string= 0);
+ bool allocate_lex_string);
ST_SCHEMA_TABLE *find_schema_table(THD *thd, const char* table_name);
ST_SCHEMA_TABLE *get_schema_table(enum enum_schema_tables schema_table_idx);
int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
@@ -806,7 +807,7 @@ bool get_schema_tables_result(JOIN *join);
/* sql_prepare.cc */
bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length,
- LEX_STRING *name=NULL);
+ LEX_STRING *name);
void mysql_stmt_execute(THD *thd, char *packet, uint packet_length);
void mysql_sql_stmt_execute(THD *thd, LEX_STRING *stmt_name);
void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length);
@@ -821,11 +822,11 @@ MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level, uint
const char *msg);
void push_warning_printf(THD *thd, MYSQL_ERROR::enum_warning_level level,
uint code, const char *format, ...);
-void mysql_reset_errors(THD *thd, bool force= false);
+void mysql_reset_errors(THD *thd, bool force);
bool mysqld_show_warnings(THD *thd, ulong levels_to_show);
/* sql_handler.cc */
-bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen= 0);
+bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen);
bool mysql_ha_close(THD *thd, TABLE_LIST *tables);
bool mysql_ha_read(THD *, TABLE_LIST *,enum enum_ha_read_modes,char *,
List<Item> *,enum ha_rkey_function,Item *,ha_rows,ha_rows);
@@ -854,15 +855,15 @@ create_field * new_create_field(THD *thd, char *field_name, enum_field_types typ
List<String> *interval_list, CHARSET_INFO *cs,
uint uint_geom_type);
void store_position_for_column(const char *name);
-bool add_to_list(THD *thd, SQL_LIST &list,Item *group,bool asc=0);
+bool add_to_list(THD *thd, SQL_LIST &list,Item *group,bool asc);
void add_join_on(TABLE_LIST *b,Item *expr);
void add_join_natural(TABLE_LIST *a,TABLE_LIST *b);
bool add_proc_to_list(THD *thd, Item *item);
TABLE *unlink_open_table(THD *thd,TABLE *list,TABLE *find);
SQL_SELECT *make_select(TABLE *head, table_map const_tables,
- table_map read_tables, COND *conds, int *error,
- bool allow_null_cond= false);
+ table_map read_tables, COND *conds,
+ bool allow_null_cond, int *error);
extern Item **not_found_item;
Item ** find_item_in_list(Item *item, List<Item> &items, uint *counter,
find_item_error_report_type report_error,
@@ -905,13 +906,13 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table,
TABLE_LIST *unique_table(TABLE_LIST *table, TABLE_LIST *table_list);
TABLE **find_temporary_table(THD *thd, const char *db, const char *table_name);
bool close_temporary_table(THD *thd, const char *db, const char *table_name);
-void close_temporary(TABLE *table, bool delete_table=1);
+void close_temporary(TABLE *table, bool delete_table);
bool rename_temporary_table(THD* thd, TABLE *table, const char *new_db,
const char *table_name);
void remove_db_from_cache(const char *db);
void flush_tables();
bool remove_table_from_cache(THD *thd, const char *db, const char *table,
- bool return_if_owned_by_thd=0);
+ bool return_if_owned_by_thd);
bool close_cached_tables(THD *thd, bool wait_for_refresh, TABLE_LIST *tables);
void copy_field_from_tmp_record(Field *field,int offset);
bool fill_record(THD *thd, List<Item> &fields, List<Item> &values,
@@ -1172,7 +1173,7 @@ void unlock_table_name(THD *thd, TABLE_LIST *table_list);
bool wait_for_locked_table_names(THD *thd, TABLE_LIST *table_list);
bool lock_table_names(THD *thd, TABLE_LIST *table_list);
void unlock_table_names(THD *thd, TABLE_LIST *table_list,
- TABLE_LIST *last_table= 0);
+ TABLE_LIST *last_table);
/* old unireg functions */
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 812d5a41cbc..fe1780b92a7 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -650,8 +650,10 @@ int imerge_list_or_tree(PARAM *param,
*/
SQL_SELECT *make_select(TABLE *head, table_map const_tables,
- table_map read_tables, COND *conds, int *error,
- bool allow_null_cond)
+ table_map read_tables, COND *conds,
+ bool allow_null_cond,
+ int *error)
+
{
SQL_SELECT *select;
DBUG_ENTER("make_select");
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 2097e55d4e3..89c4b2dbaac 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -1016,23 +1016,31 @@ sp_head::restore_thd_mem_root(THD *thd)
}
-bool check_show_routine_acceess(THD *thd, sp_head *sp, bool *full_access)
+/*
+ Check if a user has access right to a routine
+
+ SYNOPSIS
+ check_show_routine_access()
+ thd Thread handler
+ sp SP
+ full_access Set to 1 if the user has SELECT right to the
+ 'mysql.proc' able or is the owner of the routine
+ RETURN
+ 0 ok
+ 1 error
+*/
+
+bool check_show_routine_access(THD *thd, sp_head *sp, bool *full_access)
{
TABLE_LIST tables;
bzero((char*) &tables,sizeof(tables));
tables.db= (char*) "mysql";
tables.table_name= tables.alias= (char*) "proc";
- *full_access= !check_table_access(thd, SELECT_ACL, &tables, 1);
- if (!(*full_access))
- *full_access= (!strcmp(sp->m_definer_user.str, thd->priv_user) &&
- !strcmp(sp->m_definer_host.str, thd->priv_host));
- if (!(*full_access))
- {
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
- return check_some_routine_access(thd, (char * )sp->m_db.str,
- (char * ) sp->m_name.str);
-#endif
- }
+ *full_access= (!check_table_access(thd, SELECT_ACL, &tables, 1) ||
+ (!strcmp(sp->m_definer_user.str, thd->priv_user) &&
+ !strcmp(sp->m_definer_host.str, thd->priv_host)));
+ if (!*full_access)
+ return check_some_routine_access(thd, sp->m_db.str, sp->m_name.str);
return 0;
}
@@ -1056,7 +1064,7 @@ sp_head::show_create_procedure(THD *thd)
LINT_INIT(sql_mode_str);
LINT_INIT(sql_mode_len);
- if (check_show_routine_acceess(thd, this, &full_access))
+ if (check_show_routine_access(thd, this, &full_access))
return 1;
old_sql_mode= thd->variables.sql_mode;
@@ -1129,7 +1137,7 @@ sp_head::show_create_function(THD *thd)
LINT_INIT(sql_mode_str);
LINT_INIT(sql_mode_len);
- if (check_show_routine_acceess(thd, this, &full_access))
+ if (check_show_routine_access(thd, this, &full_access))
return 1;
old_sql_mode= thd->variables.sql_mode;
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 3db219b5fdc..c51e5e00aa1 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -1642,17 +1642,6 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
}
else
{
- /*
- Check that the user isn't trying to change a password for another
- user if he doesn't have UPDATE privilege to the MySQL database
- */
- DBUG_ASSERT(combo.host.str != 0);
- if (thd->user && combo.password.str &&
- (strcmp(thd->user,combo.user.str) ||
- my_strcasecmp(system_charset_info,
- combo.host.str, thd->host_or_ip)) &&
- check_access(thd, UPDATE_ACL, "mysql",0,1,0))
- goto end;
old_row_exists = 1;
store_record(table,record[1]); // Save copy for update
if (combo.password.str) // If password given
@@ -2125,7 +2114,7 @@ static GRANT_NAME *name_hash_search(HASH *name_hash,
inline GRANT_NAME *
proc_hash_search(const char *host, const char *ip, const char *db,
- const char *user, const char *tname, bool exact)
+ const char *user, const char *tname, bool exact)
{
return (GRANT_TABLE*) name_hash_search(&proc_priv_hash, host, ip, db,
user, tname, exact);
@@ -3594,11 +3583,11 @@ err:
name Routine name
RETURN
- 1 error
0 Ok
+ 1 error
*/
-bool check_routine_level_acl(THD *thd, char *db, char *name)
+bool check_routine_level_acl(THD *thd, const char *db, const char *name)
{
bool no_routine_acl= 1;
if (grant_option)
@@ -5570,4 +5559,16 @@ void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant,
grant->privilege|= grant->grant_table->privs;
}
}
+
+#else /* NO_EMBEDDED_ACCESS_CHECKS */
+
+/****************************************************************************
+ Dummy wrappers when we don't have any access checks
+****************************************************************************/
+
+bool check_routine_level_acl(THD *thd, const char *db, const char *name)
+{
+ return FALSE;
+}
+
#endif
diff --git a/sql/sql_acl.h b/sql/sql_acl.h
index 30e335c7afd..24916fd4385 100644
--- a/sql/sql_acl.h
+++ b/sql/sql_acl.h
@@ -219,7 +219,7 @@ void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant,
const char *db, const char *table);
bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name);
bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name);
-bool check_routine_level_acl(THD *thd, char *db, char *name);
+bool check_routine_level_acl(THD *thd, const char *db, const char *name);
#ifdef NO_EMBEDDED_ACCESS_CHECKS
#define check_grant(A,B,C,D,E,F) 0
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 09640eb3f57..4750fe1386f 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -633,7 +633,7 @@ void close_temporary_tables(THD *thd)
table->s->table_name,"`,", NullS);
}
next=table->next;
- close_temporary(table);
+ close_temporary(table, 1);
}
if (query && found_user_tables && mysql_bin_log.is_open())
{
@@ -798,7 +798,7 @@ bool close_temporary_table(THD *thd, const char *db, const char *table_name)
return 1;
table= *prev;
*prev= table->next;
- close_temporary(table);
+ close_temporary(table, 1);
if (thd->slave_thread)
--slave_open_temp_tables;
return 0;
@@ -1606,7 +1606,7 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
if (ha_create_table_from_engine(thd, db, name, TRUE) != 0)
goto err;
- mysql_reset_errors(thd, true); // Clear warnings
+ mysql_reset_errors(thd, 1); // Clear warnings
thd->clear_error(); // Clear error message
continue;
}
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index d49d654cb87..642564f5d7a 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -96,7 +96,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
table->used_keys.clear_all();
table->quick_keys.clear_all(); // Can't use 'only index'
- select=make_select(table,0,0,conds,&error);
+ select=make_select(table, 0, 0, conds, 0, &error);
if (error)
DBUG_RETURN(TRUE);
if ((select && select->check_quick(thd, safe_update, limit)) || !limit)
diff --git a/sql/sql_error.cc b/sql/sql_error.cc
index 4420f2d16ad..281ac7169c0 100644
--- a/sql/sql_error.cc
+++ b/sql/sql_error.cc
@@ -80,7 +80,8 @@ void mysql_reset_errors(THD *thd, bool force)
thd->warn_id= thd->query_id;
free_root(&thd->warn_root,MYF(0));
bzero((char*) thd->warn_count, sizeof(thd->warn_count));
- if (force) thd->total_warn_count= 0;
+ if (force)
+ thd->total_warn_count= 0;
thd->warn_list.empty();
thd->row_count= 1; // by default point to row 1
}
@@ -113,7 +114,7 @@ MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level,
DBUG_RETURN(0);
if (thd->query_id != thd->warn_id)
- mysql_reset_errors(thd);
+ mysql_reset_errors(thd, 0);
thd->got_warning= 1;
if (thd->spcont &&
thd->spcont->find_handler(code,
diff --git a/sql/sql_help.cc b/sql/sql_help.cc
index f5490da7e85..fa3e2070a28 100644
--- a/sql/sql_help.cc
+++ b/sql/sql_help.cc
@@ -562,7 +562,7 @@ SQL_SELECT *prepare_simple_select(THD *thd, Item *cond, TABLE_LIST *tables,
/* Assume that no indexes cover all required fields */
table->used_keys.clear_all();
- SQL_SELECT *res= make_select(table,0,0,cond,error);
+ SQL_SELECT *res= make_select(table, 0, 0, cond, 0, error);
if (*error || (res && res->check_quick(thd, 0, HA_POS_ERROR)) ||
(res->quick && res->quick->reset()))
{
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 66b0e69452f..a39ccacfe00 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1623,7 +1623,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
}
case COM_PREPARE:
{
- mysql_stmt_prepare(thd, packet, packet_length);
+ mysql_stmt_prepare(thd, packet, packet_length, 0);
break;
}
case COM_CLOSE_STMT:
@@ -2261,7 +2261,7 @@ mysql_execute_command(THD *thd)
*/
if (all_tables || &lex->select_lex != lex->all_selects_list ||
lex->spfuns.records || lex->spprocs.records)
- mysql_reset_errors(thd);
+ mysql_reset_errors(thd, 0);
#ifdef HAVE_REPLICATION
if (thd->slave_thread)
@@ -2935,7 +2935,8 @@ unsent_create_error:
lex->key_list,
select_lex->order_list.elements,
(ORDER *) select_lex->order_list.first,
- lex->duplicates, lex->ignore, &lex->alter_info);
+ lex->duplicates, lex->ignore, &lex->alter_info,
+ 1);
}
break;
}
@@ -3625,6 +3626,24 @@ unsent_create_error:
first_table ? 0 : 1, 0))
goto error;
+ if (thd->user) // If not replication
+ {
+ LEX_USER *user;
+ List_iterator <LEX_USER> user_list(lex->users_list);
+ while ((user=user_list++))
+ {
+ if (user->password.str &&
+ strcmp(thd->user, user->user.str) ||
+ user->host.str &&
+ my_strcasecmp(system_charset_info,
+ user->host.str, thd->host_or_ip))
+ {
+ if (check_access(thd, UPDATE_ACL, "mysql", 0, 1, 0))
+ goto error;
+ break; // We are allowed to do changes
+ }
+ }
+ }
if (specialflag & SPECIAL_NO_RESOLVE)
{
LEX_USER *user;
@@ -3762,7 +3781,7 @@ unsent_create_error:
if (check_db_used(thd, all_tables) ||
check_table_access(thd, SELECT_ACL, all_tables, 0))
goto error;
- res= mysql_ha_open(thd, first_table);
+ res= mysql_ha_open(thd, first_table, 0);
break;
case SQLCOM_HA_CLOSE:
DBUG_ASSERT(first_table == all_tables && first_table != 0);
@@ -4107,7 +4126,7 @@ unsent_create_error:
sp= sp_find_procedure(thd, lex->spname);
else
sp= sp_find_function(thd, lex->spname);
- mysql_reset_errors(thd);
+ mysql_reset_errors(thd, 0);
if (! sp)
result= SP_KEY_NOT_FOUND;
else
@@ -4148,7 +4167,7 @@ unsent_create_error:
sp= sp_find_procedure(thd, lex->spname);
else
sp= sp_find_function(thd, lex->spname);
- mysql_reset_errors(thd);
+ mysql_reset_errors(thd, 0);
if (sp)
{
db= thd->strdup(sp->m_db.str);
@@ -4758,7 +4777,7 @@ check_procedure_access(THD *thd, ulong want_access,char *db, char *name,
1 error
*/
-bool check_some_routine_access(THD *thd, char *db, char *name)
+bool check_some_routine_access(THD *thd, const char *db, const char *name)
{
ulong save_priv;
if (thd->master_access & SHOW_PROC_ACLS)
@@ -4766,12 +4785,7 @@ bool check_some_routine_access(THD *thd, char *db, char *name)
if (!check_access(thd, SHOW_PROC_ACLS, db, &save_priv, 0, 1) ||
(save_priv & SHOW_PROC_ACLS))
return FALSE;
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
- if (grant_option)
- return check_routine_level_acl(thd, db, name);
-#endif
-
- return FALSE;
+ return check_routine_level_acl(thd, db, name);
}
@@ -5849,11 +5863,14 @@ bool st_select_lex::init_nested_join(THD *thd)
TABLE_LIST *st_select_lex::end_nested_join(THD *thd)
{
TABLE_LIST *ptr;
+ NESTED_JOIN *nested_join;
DBUG_ENTER("end_nested_join");
+
+ DBUG_ASSERT(embedding);
ptr= embedding;
join_list= ptr->join_list;
embedding= ptr->embedding;
- NESTED_JOIN *nested_join= ptr->nested_join;
+ nested_join= ptr->nested_join;
if (nested_join->join_list.elements == 1)
{
TABLE_LIST *embedded= nested_join->join_list.head();
@@ -5863,6 +5880,11 @@ TABLE_LIST *st_select_lex::end_nested_join(THD *thd)
join_list->push_front(embedded);
ptr= embedded;
}
+ else if (nested_join->join_list.elements == 0)
+ {
+ join_list->pop();
+ ptr= 0; // return value
+ }
DBUG_RETURN(ptr);
}
@@ -6494,7 +6516,7 @@ bool mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->table_name,
&create_info, table_list,
fields, keys, 0, (ORDER*)0,
- DUP_ERROR, 0, &alter_info));
+ DUP_ERROR, 0, &alter_info, 1));
}
@@ -6512,7 +6534,7 @@ bool mysql_drop_index(THD *thd, TABLE_LIST *table_list, ALTER_INFO *alter_info)
DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->table_name,
&create_info, table_list,
fields, keys, 0, (ORDER*)0,
- DUP_ERROR, 0, alter_info));
+ DUP_ERROR, 0, alter_info, 1));
}
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 5cd4753c229..7862717bb18 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1782,7 +1782,7 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length,
thd->current_arena= stmt;
mysql_init_query(thd, (uchar *) thd->query, thd->query_length);
/* Reset warnings from previous command */
- mysql_reset_errors(thd);
+ mysql_reset_errors(thd, 0);
lex= thd->lex;
lex->safe_to_cache_query= 0;
diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc
index 8bc1891ef1b..8fe17198cf0 100644
--- a/sql/sql_rename.cc
+++ b/sql/sql_rename.cc
@@ -90,7 +90,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list)
send_ok(thd);
}
- unlock_table_names(thd, table_list);
+ unlock_table_names(thd, table_list, (TABLE_LIST*) 0);
err:
pthread_mutex_unlock(&LOCK_open);
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 277c9970595..b970c184489 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -675,8 +675,8 @@ JOIN::optimize()
/* Handle the case where we have an OUTER JOIN without a WHERE */
conds=new Item_int((longlong) 1,1); // Always true
}
- select=make_select(*table, const_table_map,
- const_table_map, conds, &error, true);
+ select= make_select(*table, const_table_map,
+ const_table_map, conds, 1, &error);
if (error)
{ /* purecov: inspected */
error= -1; /* purecov: inspected */
@@ -2398,7 +2398,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
select= make_select(s->table, found_const_table_map,
found_const_table_map,
*s->on_expr_ref ? *s->on_expr_ref : conds,
- &error, true);
+ 1, &error);
if (!select)
DBUG_RETURN(1);
records= get_quick_record_count(join->thd, select, s->table,
@@ -4987,7 +4987,7 @@ bool
store_val_in_field(Field *field,Item *item)
{
bool error;
- THD *thd=current_thd;
+ THD *thd= field->table->in_use;
ha_rows cuted_fields=thd->cuted_fields;
/*
we should restore old value of count_cuted_fields because
@@ -5182,6 +5182,7 @@ make_outerjoin_info(JOIN *join)
static bool
make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
{
+ THD *thd= join->thd;
DBUG_ENTER("make_join_select");
if (select)
{
@@ -5191,8 +5192,8 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
if (join->tables > 1)
cond->update_used_tables(); // Tablenr may have changed
if (join->const_tables == join->tables &&
- join->thd->lex->current_select->master_unit() ==
- &join->thd->lex->unit) // not upper level SELECT
+ thd->lex->current_select->master_unit() ==
+ &thd->lex->unit) // not upper level SELECT
join->const_table_map|=RAND_TABLE_BIT;
{ // Check const tables
COND *const_cond=
@@ -5288,7 +5289,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
{
DBUG_EXECUTE("where",print_where(tmp,tab->table->alias););
SQL_SELECT *sel=tab->select=(SQL_SELECT*)
- join->thd->memdup((gptr) select, sizeof(SQL_SELECT));
+ thd->memdup((gptr) select, sizeof(SQL_SELECT));
if (!sel)
DBUG_RETURN(1); // End of memory
/*
@@ -5298,14 +5299,15 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
the first match for outer tables is encountered.
*/
if (cond)
- {/*
+ {
+ /*
Because of QUICK_GROUP_MIN_MAX_SELECT there may be a select without
a cond, so neutralize the hack above.
*/
if (!(tmp= add_found_match_trig_cond(first_inner_tab, tmp, 0)))
DBUG_RETURN(1);
tab->select_cond=sel->cond=tmp;
- if (join->thd->variables.engine_condition_pushdown)
+ if (thd->variables.engine_condition_pushdown)
{
tab->table->file->pushed_cond= NULL;
/* Push condition to handler */
@@ -5375,7 +5377,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
if (sel->cond && !sel->cond->fixed)
sel->cond->quick_fix_field();
- if (sel->test_quick_select(join->thd, tab->keys,
+ if (sel->test_quick_select(thd, tab->keys,
used_tables & ~ current_map,
(join->select_options &
OPTION_FOUND_ROWS ?
@@ -5388,7 +5390,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
*/
sel->cond=orig_cond;
if (!*tab->on_expr_ref ||
- sel->test_quick_select(join->thd, tab->keys,
+ sel->test_quick_select(thd, tab->keys,
used_tables & ~ current_map,
(join->select_options &
OPTION_FOUND_ROWS ?
@@ -5430,10 +5432,10 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
{
DBUG_EXECUTE("where",print_where(tmp,"cache"););
tab->cache.select=(SQL_SELECT*)
- join->thd->memdup((gptr) sel, sizeof(SQL_SELECT));
+ thd->memdup((gptr) sel, sizeof(SQL_SELECT));
tab->cache.select->cond=tmp;
tab->cache.select->read_tables=join->const_table_map;
- if (join->thd->variables.engine_condition_pushdown &&
+ if (thd->variables.engine_condition_pushdown &&
(!tab->table->file->pushed_cond))
{
/* Push condition to handler */
@@ -5443,7 +5445,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
}
}
}
- }
+ }
/*
Push down all predicates from on expressions.
@@ -11909,7 +11911,7 @@ calc_group_buffer(JOIN *join,ORDER *group)
{
/* This case should never be choosen */
DBUG_ASSERT(0);
- current_thd->fatal_error();
+ join->thd->fatal_error();
}
parts++;
if ((*group->item)->maybe_null)
@@ -12493,7 +12495,8 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab)
error=(int) cond->add(join_tab->select->cond);
join_tab->select_cond=join_tab->select->cond=cond;
}
- else if ((join_tab->select=make_select(join_tab->table, 0, 0, cond,&error)))
+ else if ((join_tab->select= make_select(join_tab->table, 0, 0, cond, 0,
+ &error)))
join_tab->select_cond=cond;
DBUG_RETURN(error ? TRUE : FALSE);
@@ -13237,6 +13240,7 @@ void st_table_list::print(THD *thd, String *str)
void st_select_lex::print(THD *thd, String *str)
{
+ /* QQ: thd may not be set for sub queries, but this should be fixed */
if (!thd)
thd= current_thd;
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index e0fc570015d..124ce1805db 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -704,14 +704,17 @@ static void append_directory(THD *thd, String *packet, const char *dir_type,
packet->append(dir_type);
packet->append(" DIRECTORY='", 12);
#ifdef __WIN__
- char *winfilename = thd->memdup(filename, length);
- for (uint i=0; i < length; i++)
- if (winfilename[i] == '\\')
- winfilename[i] = '/';
- packet->append(winfilename, length);
-#else
- packet->append(filename, length);
+ /* Convert \ to / to be able to create table on unix */
+ char *winfilename= (char*) thd->memdup(filename, length);
+ char *pos, *end;
+ for (pos= winfilename, end= pos+length ; pos < end ; pos++)
+ {
+ if (*pos == '\\')
+ *pos = '/';
+ }
+ filename= winfilename;
#endif
+ packet->append(filename, length);
packet->append('\'');
}
}
@@ -2489,13 +2492,8 @@ void store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
definer= get_field(thd->mem_root, proc_table->field[11]);
if (!full_access)
full_access= !strcmp(sp_user, definer);
- if (!full_access)
- {
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
- if (check_some_routine_access(thd, (char * )sp_db, (char * )sp_name))
- return;
-#endif
- }
+ if (!full_access && check_some_routine_access(thd, sp_db, sp_name))
+ return;
if (lex->orig_sql_command == SQLCOM_SHOW_STATUS_PROC &&
proc_table->field[2]->val_int() == TYPE_ENUM_PROCEDURE ||
@@ -2507,36 +2505,30 @@ void store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
if (!wild || !wild[0] || !wild_compare(sp_name, wild, 0))
{
table->field[3]->store(sp_name, strlen(sp_name), cs);
- tmp_string.length(0);
get_field(thd->mem_root, proc_table->field[3], &tmp_string);
table->field[0]->store(tmp_string.ptr(), tmp_string.length(), cs);
table->field[2]->store(sp_db, strlen(sp_db), cs);
- tmp_string.length(0);
get_field(thd->mem_root, proc_table->field[2], &tmp_string);
table->field[4]->store(tmp_string.ptr(), tmp_string.length(), cs);
if (proc_table->field[2]->val_int() == TYPE_ENUM_FUNCTION)
{
- tmp_string.length(0);
get_field(thd->mem_root, proc_table->field[9], &tmp_string);
table->field[5]->store(tmp_string.ptr(), tmp_string.length(), cs);
table->field[5]->set_notnull();
}
if (full_access)
{
- tmp_string.length(0);
get_field(thd->mem_root, proc_table->field[10], &tmp_string);
table->field[7]->store(tmp_string.ptr(), tmp_string.length(), cs);
}
table->field[6]->store("SQL", 3, cs);
table->field[10]->store("SQL", 3, cs);
- tmp_string.length(0);
get_field(thd->mem_root, proc_table->field[6], &tmp_string);
table->field[11]->store(tmp_string.ptr(), tmp_string.length(), cs);
if (proc_table->field[5]->val_int() == SP_CONTAINS_SQL)
{
table->field[12]->store("CONTAINS SQL", 12 , cs);
}
- tmp_string.length(0);
get_field(thd->mem_root, proc_table->field[7], &tmp_string);
table->field[14]->store(tmp_string.ptr(), tmp_string.length(), cs);
bzero((char *)&time, sizeof(time));
@@ -2545,10 +2537,8 @@ void store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
bzero((char *)&time, sizeof(time));
((Field_timestamp *) proc_table->field[13])->get_time(&time);
table->field[16]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
- tmp_string.length(0);
get_field(thd->mem_root, proc_table->field[14], &tmp_string);
table->field[17]->store(tmp_string.ptr(), tmp_string.length(), cs);
- tmp_string.length(0);
get_field(thd->mem_root, proc_table->field[15], &tmp_string);
table->field[18]->store(tmp_string.ptr(), tmp_string.length(), cs);
table->field[19]->store(definer, strlen(definer), cs);
diff --git a/sql/sql_string.cc b/sql/sql_string.cc
index 226a80201a1..0424723d97f 100644
--- a/sql/sql_string.cc
+++ b/sql/sql_string.cc
@@ -686,16 +686,16 @@ void String::qs_append(double *d)
void String::qs_append(int i)
{
- char *buff = Ptr + str_length;
- sprintf(buff,"%d", i);
- str_length += strlen(buff);
+ char *buff= Ptr + str_length;
+ char *end= int10_to_str(i, buff, -10);
+ str_length+= (int) (end-buff);
}
void String::qs_append(uint i)
{
- char *buff = Ptr + str_length;
- sprintf(buff,"%u", i);
- str_length += strlen(buff);
+ char *buff= Ptr + str_length;
+ char *end= int10_to_str(i, buff, 10);
+ str_length+= (int) (end-buff);
}
/*
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index c79f49afc64..8295e2f07ab 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -207,7 +207,8 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
if (!drop_temporary)
{
abort_locked_tables(thd,db,table->table_name);
- while (remove_table_from_cache(thd,db,table->table_name) && !thd->killed)
+ while (remove_table_from_cache(thd, db, table->table_name, 0) &&
+ !thd->killed)
{
dropping_tables++;
(void) pthread_cond_wait(&COND_refresh,&LOCK_open);
@@ -290,7 +291,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
}
}
- unlock_table_names(thd, tables);
+ unlock_table_names(thd, tables, (TABLE_LIST*) 0);
thd->no_warnings_for_error= 0;
DBUG_RETURN(error);
}
@@ -450,150 +451,151 @@ void calculate_interval_lengths(CHARSET_INFO *cs, TYPELIB *interval,
*/
int prepare_create_field(create_field *sql_field,
- uint &blob_columns,
- int &timestamps, int &timestamps_with_niladic,
+ uint *blob_columns,
+ int *timestamps, int *timestamps_with_niladic,
uint table_flags)
{
DBUG_ENTER("prepare_field");
- {
- /* This code came from mysql_prepare_table.
- Indent preserved to make patching easier */
- DBUG_ASSERT(sql_field->charset);
-
- switch (sql_field->sql_type) {
- case FIELD_TYPE_BLOB:
- case FIELD_TYPE_MEDIUM_BLOB:
- case FIELD_TYPE_TINY_BLOB:
- case FIELD_TYPE_LONG_BLOB:
- sql_field->pack_flag=FIELDFLAG_BLOB |
- pack_length_to_packflag(sql_field->pack_length -
- portable_sizeof_char_ptr);
- if (sql_field->charset->state & MY_CS_BINSORT)
- sql_field->pack_flag|=FIELDFLAG_BINARY;
- sql_field->length=8; // Unireg field length
- sql_field->unireg_check=Field::BLOB_FIELD;
- blob_columns++;
- break;
- case FIELD_TYPE_GEOMETRY:
+
+ /*
+ This code came from mysql_prepare_table.
+ Indent preserved to make patching easier
+ */
+ DBUG_ASSERT(sql_field->charset);
+
+ switch (sql_field->sql_type) {
+ case FIELD_TYPE_BLOB:
+ case FIELD_TYPE_MEDIUM_BLOB:
+ case FIELD_TYPE_TINY_BLOB:
+ case FIELD_TYPE_LONG_BLOB:
+ sql_field->pack_flag=FIELDFLAG_BLOB |
+ pack_length_to_packflag(sql_field->pack_length -
+ portable_sizeof_char_ptr);
+ if (sql_field->charset->state & MY_CS_BINSORT)
+ sql_field->pack_flag|=FIELDFLAG_BINARY;
+ sql_field->length=8; // Unireg field length
+ sql_field->unireg_check=Field::BLOB_FIELD;
+ (*blob_columns)++;
+ break;
+ case FIELD_TYPE_GEOMETRY:
#ifdef HAVE_SPATIAL
- if (!(table_flags & HA_CAN_GEOMETRY))
- {
- my_printf_error(ER_CHECK_NOT_IMPLEMENTED, ER(ER_CHECK_NOT_IMPLEMENTED),
- MYF(0), "GEOMETRY");
- DBUG_RETURN(1);
- }
- sql_field->pack_flag=FIELDFLAG_GEOM |
- pack_length_to_packflag(sql_field->pack_length -
- portable_sizeof_char_ptr);
- if (sql_field->charset->state & MY_CS_BINSORT)
- sql_field->pack_flag|=FIELDFLAG_BINARY;
- sql_field->length=8; // Unireg field length
- sql_field->unireg_check=Field::BLOB_FIELD;
- blob_columns++;
- break;
-#else
- my_printf_error(ER_FEATURE_DISABLED,ER(ER_FEATURE_DISABLED), MYF(0),
- sym_group_geom.name, sym_group_geom.needed_define);
+ if (!(table_flags & HA_CAN_GEOMETRY))
+ {
+ my_printf_error(ER_CHECK_NOT_IMPLEMENTED, ER(ER_CHECK_NOT_IMPLEMENTED),
+ MYF(0), "GEOMETRY");
DBUG_RETURN(1);
+ }
+ sql_field->pack_flag=FIELDFLAG_GEOM |
+ pack_length_to_packflag(sql_field->pack_length -
+ portable_sizeof_char_ptr);
+ if (sql_field->charset->state & MY_CS_BINSORT)
+ sql_field->pack_flag|=FIELDFLAG_BINARY;
+ sql_field->length=8; // Unireg field length
+ sql_field->unireg_check=Field::BLOB_FIELD;
+ (*blob_columns)++;
+ break;
+#else
+ my_printf_error(ER_FEATURE_DISABLED,ER(ER_FEATURE_DISABLED), MYF(0),
+ sym_group_geom.name, sym_group_geom.needed_define);
+ DBUG_RETURN(1);
#endif /*HAVE_SPATIAL*/
- case MYSQL_TYPE_VARCHAR:
+ case MYSQL_TYPE_VARCHAR:
#ifndef QQ_ALL_HANDLERS_SUPPORT_VARCHAR
- if (table_flags & HA_NO_VARCHAR)
- {
- /* convert VARCHAR to CHAR because handler is not yet up to date */
- sql_field->sql_type= MYSQL_TYPE_VAR_STRING;
- sql_field->pack_length= calc_pack_length(sql_field->sql_type,
- (uint) sql_field->length);
- if ((sql_field->length / sql_field->charset->mbmaxlen) >
- MAX_FIELD_CHARLENGTH)
- {
- my_printf_error(ER_TOO_BIG_FIELDLENGTH, ER(ER_TOO_BIG_FIELDLENGTH),
- MYF(0), sql_field->field_name, MAX_FIELD_CHARLENGTH);
- DBUG_RETURN(1);
- }
- }
-#endif
- /* fall through */
- case FIELD_TYPE_STRING:
- sql_field->pack_flag=0;
- if (sql_field->charset->state & MY_CS_BINSORT)
- sql_field->pack_flag|=FIELDFLAG_BINARY;
- break;
- case FIELD_TYPE_ENUM:
- sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
- FIELDFLAG_INTERVAL;
- if (sql_field->charset->state & MY_CS_BINSORT)
- sql_field->pack_flag|=FIELDFLAG_BINARY;
- sql_field->unireg_check=Field::INTERVAL_FIELD;
- check_duplicates_in_interval("ENUM",sql_field->field_name,
- sql_field->interval,
- sql_field->charset);
- break;
- case FIELD_TYPE_SET:
- sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
- FIELDFLAG_BITFIELD;
- if (sql_field->charset->state & MY_CS_BINSORT)
- sql_field->pack_flag|=FIELDFLAG_BINARY;
- sql_field->unireg_check=Field::BIT_FIELD;
- check_duplicates_in_interval("SET",sql_field->field_name,
- sql_field->interval,
- sql_field->charset);
- break;
- case FIELD_TYPE_DATE: // Rest of string types
- case FIELD_TYPE_NEWDATE:
- case FIELD_TYPE_TIME:
- case FIELD_TYPE_DATETIME:
- case FIELD_TYPE_NULL:
- sql_field->pack_flag=f_settype((uint) sql_field->sql_type);
- break;
- case FIELD_TYPE_BIT:
- if (!(table_flags & HA_CAN_BIT_FIELD))
+ if (table_flags & HA_NO_VARCHAR)
+ {
+ /* convert VARCHAR to CHAR because handler is not yet up to date */
+ sql_field->sql_type= MYSQL_TYPE_VAR_STRING;
+ sql_field->pack_length= calc_pack_length(sql_field->sql_type,
+ (uint) sql_field->length);
+ if ((sql_field->length / sql_field->charset->mbmaxlen) >
+ MAX_FIELD_CHARLENGTH)
{
- my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "BIT FIELD");
+ my_printf_error(ER_TOO_BIG_FIELDLENGTH, ER(ER_TOO_BIG_FIELDLENGTH),
+ MYF(0), sql_field->field_name, MAX_FIELD_CHARLENGTH);
DBUG_RETURN(1);
}
- sql_field->pack_flag= FIELDFLAG_NUMBER;
- break;
- case FIELD_TYPE_NEWDECIMAL:
- sql_field->pack_flag=(FIELDFLAG_NUMBER |
- (sql_field->flags & UNSIGNED_FLAG ? 0 :
- FIELDFLAG_DECIMAL) |
- (sql_field->flags & ZEROFILL_FLAG ?
- FIELDFLAG_ZEROFILL : 0) |
- (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
- break;
- case FIELD_TYPE_TIMESTAMP:
- /* We should replace old TIMESTAMP fields with their newer analogs */
- if (sql_field->unireg_check == Field::TIMESTAMP_OLD_FIELD)
+ }
+#endif
+ /* fall through */
+ case FIELD_TYPE_STRING:
+ sql_field->pack_flag=0;
+ if (sql_field->charset->state & MY_CS_BINSORT)
+ sql_field->pack_flag|=FIELDFLAG_BINARY;
+ break;
+ case FIELD_TYPE_ENUM:
+ sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
+ FIELDFLAG_INTERVAL;
+ if (sql_field->charset->state & MY_CS_BINSORT)
+ sql_field->pack_flag|=FIELDFLAG_BINARY;
+ sql_field->unireg_check=Field::INTERVAL_FIELD;
+ check_duplicates_in_interval("ENUM",sql_field->field_name,
+ sql_field->interval,
+ sql_field->charset);
+ break;
+ case FIELD_TYPE_SET:
+ sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
+ FIELDFLAG_BITFIELD;
+ if (sql_field->charset->state & MY_CS_BINSORT)
+ sql_field->pack_flag|=FIELDFLAG_BINARY;
+ sql_field->unireg_check=Field::BIT_FIELD;
+ check_duplicates_in_interval("SET",sql_field->field_name,
+ sql_field->interval,
+ sql_field->charset);
+ break;
+ case FIELD_TYPE_DATE: // Rest of string types
+ case FIELD_TYPE_NEWDATE:
+ case FIELD_TYPE_TIME:
+ case FIELD_TYPE_DATETIME:
+ case FIELD_TYPE_NULL:
+ sql_field->pack_flag=f_settype((uint) sql_field->sql_type);
+ break;
+ case FIELD_TYPE_BIT:
+ if (!(table_flags & HA_CAN_BIT_FIELD))
+ {
+ my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "BIT FIELD");
+ DBUG_RETURN(1);
+ }
+ sql_field->pack_flag= FIELDFLAG_NUMBER;
+ break;
+ case FIELD_TYPE_NEWDECIMAL:
+ sql_field->pack_flag=(FIELDFLAG_NUMBER |
+ (sql_field->flags & UNSIGNED_FLAG ? 0 :
+ FIELDFLAG_DECIMAL) |
+ (sql_field->flags & ZEROFILL_FLAG ?
+ FIELDFLAG_ZEROFILL : 0) |
+ (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
+ break;
+ case FIELD_TYPE_TIMESTAMP:
+ /* We should replace old TIMESTAMP fields with their newer analogs */
+ if (sql_field->unireg_check == Field::TIMESTAMP_OLD_FIELD)
+ {
+ if (!*timestamps)
{
- if (!timestamps)
- {
- sql_field->unireg_check= Field::TIMESTAMP_DNUN_FIELD;
- timestamps_with_niladic++;
- }
- else
- sql_field->unireg_check= Field::NONE;
+ sql_field->unireg_check= Field::TIMESTAMP_DNUN_FIELD;
+ (*timestamps_with_niladic)++;
}
- else if (sql_field->unireg_check != Field::NONE)
- timestamps_with_niladic++;
-
- timestamps++;
- /* fall-through */
- default:
- sql_field->pack_flag=(FIELDFLAG_NUMBER |
- (sql_field->flags & UNSIGNED_FLAG ? 0 :
- FIELDFLAG_DECIMAL) |
- (sql_field->flags & ZEROFILL_FLAG ?
- FIELDFLAG_ZEROFILL : 0) |
- f_settype((uint) sql_field->sql_type) |
- (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
- break;
- }
- if (!(sql_field->flags & NOT_NULL_FLAG))
- sql_field->pack_flag|= FIELDFLAG_MAYBE_NULL;
- if (sql_field->flags & NO_DEFAULT_VALUE_FLAG)
- sql_field->pack_flag|= FIELDFLAG_NO_DEFAULT;
- }
+ else
+ sql_field->unireg_check= Field::NONE;
+ }
+ else if (sql_field->unireg_check != Field::NONE)
+ (*timestamps_with_niladic)++;
+
+ (*timestamps)++;
+ /* fall-through */
+ default:
+ sql_field->pack_flag=(FIELDFLAG_NUMBER |
+ (sql_field->flags & UNSIGNED_FLAG ? 0 :
+ FIELDFLAG_DECIMAL) |
+ (sql_field->flags & ZEROFILL_FLAG ?
+ FIELDFLAG_ZEROFILL : 0) |
+ f_settype((uint) sql_field->sql_type) |
+ (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
+ break;
+ }
+ if (!(sql_field->flags & NOT_NULL_FLAG))
+ sql_field->pack_flag|= FIELDFLAG_MAYBE_NULL;
+ if (sql_field->flags & NO_DEFAULT_VALUE_FLAG)
+ sql_field->pack_flag|= FIELDFLAG_NO_DEFAULT;
DBUG_RETURN(0);
}
@@ -856,8 +858,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
{
DBUG_ASSERT(sql_field->charset != 0);
- if (prepare_create_field(sql_field, blob_columns,
- timestamps, timestamps_with_niladic,
+ if (prepare_create_field(sql_field, &blob_columns,
+ &timestamps, &timestamps_with_niladic,
file->table_flags()))
DBUG_RETURN(-1);
if (sql_field->sql_type == FIELD_TYPE_BLOB ||
@@ -1764,7 +1766,7 @@ static void wait_while_table_is_used(THD *thd,TABLE *table,
mysql_lock_abort(thd, table); // end threads waiting on lock
/* Wait until all there are no other threads that has this table open */
- while (remove_table_from_cache(thd, table->s->db, table->s->table_name))
+ while (remove_table_from_cache(thd, table->s->db, table->s->table_name, 0))
{
dropping_tables++;
(void) pthread_cond_wait(&COND_refresh,&LOCK_open);
@@ -2133,7 +2135,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
"Waiting to get writelock");
mysql_lock_abort(thd,table->table);
while (remove_table_from_cache(thd, table->table->s->db,
- table->table->s->table_name) &&
+ table->table->s->table_name, 0) &&
! thd->killed)
{
dropping_tables++;
@@ -2248,7 +2250,7 @@ send_result_message:
{
pthread_mutex_lock(&LOCK_open);
remove_table_from_cache(thd, table->table->s->db,
- table->table->s->table_name);
+ table->table->s->table_name, 0);
pthread_mutex_unlock(&LOCK_open);
/* May be something modified consequently we have to invalidate cache */
query_cache_invalidate3(thd, table->table, 0);
@@ -3557,7 +3559,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
if (table)
{
VOID(table->file->extra(HA_EXTRA_FORCE_REOPEN)); // Use new file
- remove_table_from_cache(thd,db,table_name); // Mark all in-use copies old
+ remove_table_from_cache(thd,db,table_name, 0); // Mark in-use copies old
mysql_lock_abort(thd,table); // end threads waiting on lock
}
VOID(quick_rm_table(old_db_type,db,old_name));
diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc
index 1d14d037c47..3340c46bb6b 100644
--- a/sql/sql_udf.cc
+++ b/sql/sql_udf.cc
@@ -110,15 +110,15 @@ static char *init_syms(udf_func *tmp, char *nm)
*/
if (!tmp->func_init && !tmp->func_deinit && tmp->type != UDFTYPE_AGGREGATE)
{
- if (opt_allow_suspicious_udfs)
- sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), nm);
- else
+ if (!opt_allow_suspicious_udfs)
return nm;
+ if (current_thd->variables.log_warnings)
+ sql_print_warning(ER(ER_CANT_FIND_DL_ENTRY), nm);
}
-
return 0;
}
+
extern "C" byte* get_hash_key(const byte *buff,uint *length,
my_bool not_used __attribute__((unused)))
{
@@ -127,9 +127,10 @@ extern "C" byte* get_hash_key(const byte *buff,uint *length,
return (byte*) udf->name.str;
}
+
/*
-** Read all predeclared functions from mysql.func and accept all that
-** can be used.
+ Read all predeclared functions from mysql.func and accept all that
+ can be used.
*/
void udf_init()
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 477a283448a..3ee656b00ce 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -219,7 +219,7 @@ int mysql_update(THD *thd,
#ifndef NO_EMBEDDED_ACCESS_CHECKS
/* Check values */
table_list->grant.want_privilege= table->grant.want_privilege=
- (SELECT_ACL & ~~table->grant.privilege);
+ (SELECT_ACL & ~table->grant.privilege);
#endif
if (setup_fields(thd, 0, table_list, values, 1, 0, 0))
{
@@ -229,7 +229,7 @@ int mysql_update(THD *thd,
// Don't count on usage of 'only index' when calculating which key to use
table->used_keys.clear_all();
- select=make_select(table,0,0,conds,&error);
+ select= make_select(table, 0, 0, conds, 0, &error);
if (error ||
(select && select->check_quick(thd, safe_update, limit)) || !limit)
{
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index ef5cbb3c79b..cc6eadf5fd5 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -52,6 +52,13 @@ const LEX_STRING null_lex_str={0,0};
ER_WARN_DEPRECATED_SYNTAX, \
ER(ER_WARN_DEPRECATED_SYNTAX), (A), (B));
+#define TEST_ASSERT(A) \
+ if (!(A)) \
+ { \
+ yyerror(ER(ER_SYNTAX_ERROR)); \
+ YYABORT; \
+ }
+
/* Helper for parsing "IS [NOT] truth_value" */
inline Item *is_truth_value(Item *A, bool v1, bool v2)
{
@@ -692,6 +699,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
opt_var_ident_type delete_option opt_temporary all_or_any opt_distinct
opt_ignore_leaves fulltext_options spatial_type union_option
start_transaction_opts opt_chain opt_release
+ union_opt select_derived_init
%type <ulong_num>
ULONG_NUM raid_types merge_insert_types
@@ -738,6 +746,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <table_list>
join_table_list join_table
table_factor table_ref
+ select_derived derived_table_list
%type <date_time_type> date_time_type;
%type <interval> interval
@@ -772,6 +781,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <variable> internal_variable_name
%type <select_lex> in_subselect in_subselect_init
+ get_select_lex
%type <boolfunc2creator> comp_op
@@ -1388,14 +1398,18 @@ create_function_tail:
uint unused1= 0;
int unused2= 0;
- if (!(new_field= new_create_field(YYTHD, "", (enum enum_field_types)$8,
- lex->length, lex->dec, lex->type,
- (Item *)0, (Item *) 0, &cmt, 0, &lex->interval_list,
- (lex->charset ? lex->charset : default_charset_info),
- lex->uint_geom_type)))
+ if (!(new_field= new_create_field(YYTHD, "",
+ (enum enum_field_types)$8,
+ lex->length, lex->dec, lex->type,
+ (Item *)0, (Item *) 0, &cmt, 0,
+ &lex->interval_list,
+ (lex->charset ? lex->charset :
+ default_charset_info),
+ lex->uint_geom_type)))
YYABORT;
- if (prepare_create_field(new_field, unused1, unused2, unused2, 0))
+ if (prepare_create_field(new_field, &unused1, &unused2, &unused2,
+ 0))
YYABORT;
sp->m_returns= new_field->sql_type;
@@ -4024,13 +4038,53 @@ optional_braces:
/* all possible expressions */
expr:
- expr or bool_term { $$= new Item_cond_or($1,$3); }
- | expr XOR bool_term { $$= new Item_cond_xor($1,$3); }
- | bool_term ;
+ bool_term { Select->expr_list.push_front(new List<Item>); }
+ bool_or_expr
+ {
+ List<Item> *list= Select->expr_list.pop();
+ if (list->elements)
+ {
+ list->push_front($1);
+ $$= new Item_cond_or(*list);
+ /* optimize construction of logical OR to reduce
+ amount of objects for complex expressions */
+ }
+ else
+ $$= $1;
+ delete list;
+ }
+ ;
+
+bool_or_expr:
+ /* empty */
+ | bool_or_expr or bool_term
+ { Select->expr_list.head()->push_back($3); }
+ ;
bool_term:
- bool_term and bool_factor { $$= new Item_cond_and($1,$3); }
- | bool_factor ;
+ bool_term XOR bool_term { $$= new Item_cond_xor($1,$3); }
+ | bool_factor { Select->expr_list.push_front(new List<Item>); }
+ bool_and_expr
+ {
+ List<Item> *list= Select->expr_list.pop();
+ if (list->elements)
+ {
+ list->push_front($1);
+ $$= new Item_cond_and(*list);
+ /* optimize construction of logical AND to reduce
+ amount of objects for complex expressions */
+ }
+ else
+ $$= $1;
+ delete list;
+ }
+ ;
+
+bool_and_expr:
+ /* empty */
+ | bool_and_expr and bool_factor
+ { Select->expr_list.head()->push_back($3); }
+ ;
bool_factor:
NOT_SYM bool_factor { $$= negate_expression(YYTHD, $2); }
@@ -4915,6 +4969,7 @@ when_list2:
sel->when_list.head()->push_back($5);
};
+/* Warning - may return NULL in case of incomplete SELECT */
table_ref:
table_factor { $$=$1; }
| join_table { $$=$1; }
@@ -4926,36 +4981,47 @@ table_ref:
;
join_table_list:
+ derived_table_list { TEST_ASSERT($$=$1); }
+ ;
+
+/* Warning - may return NULL in case of incomplete SELECT */
+derived_table_list:
table_ref { $$=$1; }
- | join_table_list ',' table_ref { $$=$3; }
+ | derived_table_list ',' table_ref
+ {
+ TEST_ASSERT($1 && ($$=$3));
+ }
;
join_table:
- table_ref normal_join table_ref { $$=$3; }
+ table_ref normal_join table_ref { TEST_ASSERT($1 && ($$=$3)); }
| table_ref STRAIGHT_JOIN table_factor
- { $3->straight=1; $$=$3 ; }
+ { TEST_ASSERT($1 && ($$=$3)); $3->straight=1; }
| table_ref normal_join table_ref ON expr
- { add_join_on($3,$5); $$=$3; }
+ { TEST_ASSERT($1 && ($$=$3)); add_join_on($3,$5); }
| table_ref normal_join table_ref
USING
{
SELECT_LEX *sel= Select;
+ TEST_ASSERT($1 && $3);
sel->save_names_for_using_list($1, $3);
}
'(' using_list ')'
{ add_join_on($3,$7); $$=$3; }
| table_ref LEFT opt_outer JOIN_SYM table_ref ON expr
- { add_join_on($5,$7); $5->outer_join|=JOIN_TYPE_LEFT; $$=$5; }
+ { TEST_ASSERT($1 && $5); add_join_on($5,$7); $5->outer_join|=JOIN_TYPE_LEFT; $$=$5; }
| table_ref LEFT opt_outer JOIN_SYM table_factor
{
SELECT_LEX *sel= Select;
+ TEST_ASSERT($1 && $5);
sel->save_names_for_using_list($1, $5);
}
USING '(' using_list ')'
{ add_join_on($5,$9); $5->outer_join|=JOIN_TYPE_LEFT; $$=$5; }
| table_ref NATURAL LEFT opt_outer JOIN_SYM table_factor
{
+ TEST_ASSERT($1 && $6);
add_join_natural($1,$6);
$6->outer_join|=JOIN_TYPE_LEFT;
$$=$6;
@@ -4963,6 +5029,7 @@ join_table:
| table_ref RIGHT opt_outer JOIN_SYM table_ref ON expr
{
LEX *lex= Lex;
+ TEST_ASSERT($1 && $5);
if (!($$= lex->current_select->convert_right_join()))
YYABORT;
add_join_on($$, $7);
@@ -4970,6 +5037,7 @@ join_table:
| table_ref RIGHT opt_outer JOIN_SYM table_factor
{
SELECT_LEX *sel= Select;
+ TEST_ASSERT($1 && $5);
sel->save_names_for_using_list($1, $5);
}
USING '(' using_list ')'
@@ -4981,13 +5049,14 @@ join_table:
}
| table_ref NATURAL RIGHT opt_outer JOIN_SYM table_factor
{
+ TEST_ASSERT($1 && $6);
add_join_natural($6,$1);
LEX *lex= Lex;
if (!($$= lex->current_select->convert_right_join()))
YYABORT;
}
| table_ref NATURAL JOIN_SYM table_factor
- { add_join_natural($1,$4); $$=$4; };
+ { TEST_ASSERT($1 && ($$=$4)); add_join_natural($1,$4); };
normal_join:
@@ -4996,6 +5065,7 @@ normal_join:
| CROSS JOIN_SYM {}
;
+/* Warning - may return NULL in case of incomplete SELECT */
table_factor:
{
SELECT_LEX *sel= Select;
@@ -5014,50 +5084,96 @@ table_factor:
YYABORT;
sel->add_joined_table($$);
}
- | '('
+ | '{' ident table_ref LEFT OUTER JOIN_SYM table_ref ON expr '}'
+ { TEST_ASSERT($3 && $7); add_join_on($7,$9); $7->outer_join|=JOIN_TYPE_LEFT; $$=$7; }
+ | select_derived_init get_select_lex select_derived2
{
LEX *lex= Lex;
- if (lex->current_select->init_nested_join(lex->thd))
- YYABORT;
+ SELECT_LEX *sel= lex->current_select;
+ if ($1)
+ {
+ if (sel->set_braces(1))
+ {
+ yyerror(ER(ER_SYNTAX_ERROR));
+ YYABORT;
+ }
+ /* select in braces, can't contain global parameters */
+ if (sel->master_unit()->fake_select_lex)
+ sel->master_unit()->global_parameters=
+ sel->master_unit()->fake_select_lex;
+ }
+ if ($2->init_nested_join(lex->thd))
+ YYABORT;
+ $$= 0;
+ /* incomplete derived tables return NULL, we must be
+ nested in select_derived rule to be here. */
}
- join_table_list ')'
+ | '(' get_select_lex select_derived union_opt ')' opt_table_alias
+ {
+ /* Use $2 instead of Lex->current_select as derived table will
+ alter value of Lex->current_select. */
+
+ if (!($3 || $6) && $2->embedding &&
+ !$2->embedding->nested_join->join_list.elements)
{
- LEX *lex= Lex;
- if (!($$= lex->current_select->end_nested_join(lex->thd)))
- YYABORT;
+ /* we have a derived table ($3 == NULL) but no alias,
+ Since we are nested in further parentheses so we
+ can pass NULL to the outer level parentheses
+ Permits parsing of "((((select ...))) as xyz)" */
+ $$= 0;
}
- | '{' ident table_ref LEFT OUTER JOIN_SYM table_ref ON expr '}'
- { add_join_on($7,$9); $7->outer_join|=JOIN_TYPE_LEFT; $$=$7; }
- | '(' select_derived union_opt ')' opt_table_alias
- {
- LEX *lex=Lex;
- SELECT_LEX_UNIT *unit= lex->current_select->master_unit();
- lex->current_select= unit->outer_select();
- if (!($$= lex->current_select->
- add_table_to_list(lex->thd, new Table_ident(unit), $5, 0,
- TL_READ,(List<String> *)0,
- (List<String> *)0)))
+ else
+ if (!$3)
+ {
+ /* Handle case of derived table, alias may be NULL if there
+ are no outer parentheses, add_table_to_list() will throw
+ error in this case */
+ LEX *lex=Lex;
+ SELECT_LEX *sel= lex->current_select;
+ SELECT_LEX_UNIT *unit= sel->master_unit();
+ lex->current_select= sel= unit->outer_select();
+ if (!($$= sel->
+ add_table_to_list(lex->thd, new Table_ident(unit), $6, 0,
+ TL_READ,(List<String> *)0,
+ (List<String> *)0)))
+ YYABORT;
+ sel->add_joined_table($$);
+ }
+ else
+ if ($4 || $6)
+ {
+ /* simple nested joins cannot have aliases or unions */
+ yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
- lex->current_select->add_joined_table($$);
- };
-
+ }
+ else
+ $$= $3;
+ }
+ ;
+/* handle contents of parentheses in join expression */
select_derived:
- SELECT_SYM select_derived2
- | '(' select_derived ')'
+ get_select_lex
{
- SELECT_LEX *sel= Select;
- if (sel->set_braces(1))
- {
+ LEX *lex= Lex;
+ if ($1->init_nested_join(lex->thd))
+ YYABORT;
+ }
+ derived_table_list
+ {
+ LEX *lex= Lex;
+ /* for normal joins, $3 != NULL and end_nested_join() != NULL,
+ for derived tables, both must equal NULL */
+
+ if (!($$= $1->end_nested_join(lex->thd)) && $3)
+ YYABORT;
+ if (!$3 && $$)
+ {
yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
- }
- /* select in braces, can't contain global parameters */
- if (sel->master_unit()->fake_select_lex)
- sel->master_unit()->global_parameters=
- sel->master_unit()->fake_select_lex;
- }
+ }
+ }
;
select_derived2:
@@ -5085,6 +5201,29 @@ select_derived2:
opt_select_from
;
+get_select_lex:
+ /* Empty */ { $$= Select; }
+ ;
+
+select_derived_init:
+ SELECT_SYM
+ {
+ LEX *lex= Lex;
+ SELECT_LEX *sel= lex->current_select;
+ TABLE_LIST *embedding;
+ if (!sel->embedding || sel->end_nested_join(lex->thd))
+ {
+ /* we are not in parentheses */
+ yyerror(ER(ER_SYNTAX_ERROR));
+ YYABORT;
+ }
+ embedding= Select->embedding;
+ $$= embedding &&
+ !embedding->nested_join->join_list.elements;
+ /* return true if we are deeply nested */
+ }
+ ;
+
opt_outer:
/* empty */ {}
| OUTER {};
@@ -8118,13 +8257,12 @@ union_list:
;
union_opt:
- union_list {}
- | optional_order_or_limit {}
+ /* Empty */ { $$= 0; }
+ | union_list { $$= 1; }
+ | union_order_or_limit { $$= 1; }
;
-optional_order_or_limit:
- /* Empty */ {}
- |
+union_order_or_limit:
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
diff --git a/sql/table.cc b/sql/table.cc
index 63da10c687a..939690395d4 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1390,8 +1390,12 @@ bool get_field(MEM_ROOT *mem, Field *field, String *res)
field->val_str(&str);
if (!(length= str.length()))
+ {
+ res->length(0);
return 1;
- to= strmake_root(mem, str.ptr(), length);
+ }
+ if (!(to= strmake_root(mem, str.ptr(), length)))
+ length= 0; // Safety fix
res->set(to, length, ((Field_str*)field)->charset());
return 0;
}