summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/opt_range.cc3
-rw-r--r--sql/set_var.cc70
-rw-r--r--sql/set_var.h18
-rw-r--r--sql/sp.cc204
-rw-r--r--sql/sp.h3
-rw-r--r--sql/sql_acl.cc7
-rw-r--r--sql/sql_base.cc84
-rw-r--r--sql/sql_parse.cc15
-rw-r--r--sql/sql_prepare.cc73
-rw-r--r--sql/sql_update.cc6
10 files changed, 116 insertions, 367 deletions
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index e5709f418f7..b428909d9b7 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -2314,9 +2314,6 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
table deletes.
*/
if ((thd->lex->sql_command != SQLCOM_DELETE))
-#ifdef NOT_USED
- if ((thd->lex->sql_command != SQLCOM_UPDATE))
-#endif
{
/*
Get best non-covering ROR-intersection plan and prepare data for
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 99931d7bafc..fac67799ec3 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -1664,6 +1664,14 @@ bool sys_var::check_set(THD *thd, set_var *var, TYPELIB *enum_names)
strmov(buff, "NULL");
goto err;
}
+
+ if (!m_allow_empty_value &&
+ res->length() == 0)
+ {
+ buff[0]= 0;
+ goto err;
+ }
+
var->save_result.ulong_value= ((ulong)
find_set(enum_names, res->c_ptr(),
res->length(),
@@ -1679,10 +1687,19 @@ bool sys_var::check_set(THD *thd, set_var *var, TYPELIB *enum_names)
else
{
ulonglong tmp= var->value->val_int();
- /*
- For when the enum is made to contain 64 elements, as 1ULL<<64 is
- undefined, we guard with a "count<64" test.
- */
+
+ if (!m_allow_empty_value &&
+ tmp == 0)
+ {
+ buff[0]= '0';
+ buff[1]= 0;
+ goto err;
+ }
+
+ /*
+ For when the enum is made to contain 64 elements, as 1ULL<<64 is
+ undefined, we guard with a "count<64" test.
+ */
if (unlikely((tmp >= ((ULL(1)) << enum_names->count)) &&
(enum_names->count < 64)))
{
@@ -2382,32 +2399,51 @@ static int sys_check_log_path(THD *thd, set_var *var)
MY_STAT f_stat;
String str(buff, sizeof(buff), system_charset_info), *res;
const char *log_file_str;
-
+ size_t path_length;
+
if (!(res= var->value->val_str(&str)))
goto err;
log_file_str= res->c_ptr();
bzero(&f_stat, sizeof(MY_STAT));
- (void) unpack_filename(path, log_file_str);
- if (my_stat(path, &f_stat, MYF(0)))
+ path_length= unpack_filename(path, log_file_str);
+
+ if (!path_length)
{
- /* Check if argument is a file and we have 'write' permission */
- if (!MY_S_ISREG(f_stat.st_mode) ||
- !(f_stat.st_mode & MY_S_IWRITE))
- goto err;
+ /* File name is empty. */
+
+ goto err;
}
- else
+
+ if (my_stat(path, &f_stat, MYF(0)))
{
- size_t path_length;
/*
- Check if directory exists and
- we have permission to create file & write to file
+ A file system object exists. Check if argument is a file and we have
+ 'write' permission.
*/
- (void) dirname_part(path, log_file_str, &path_length);
- if (my_access(path, (F_OK|W_OK)))
+
+ if (!MY_S_ISREG(f_stat.st_mode) ||
+ !(f_stat.st_mode & MY_S_IWRITE))
goto err;
+
+ return 0;
}
+
+ /* Get dirname of the file path. */
+ (void) dirname_part(path, log_file_str, &path_length);
+
+ /* Dirname is empty if file path is relative. */
+ if (!path_length)
+ return 0;
+
+ /*
+ Check if directory exists and we have permission to create file and
+ write to file.
+ */
+ if (my_access(path, (F_OK|W_OK)))
+ goto err;
+
return 0;
err:
diff --git a/sql/set_var.h b/sql/set_var.h
index b33a3a968bb..c4fc13f1321 100644
--- a/sql/set_var.h
+++ b/sql/set_var.h
@@ -74,7 +74,8 @@ public:
sys_var(const char *name_arg, sys_after_update_func func= NULL,
Binlog_status_enum binlog_status_arg= NOT_IN_BINLOG)
:name(name_arg), after_update(func), no_support_one_shot(1),
- binlog_status(binlog_status_arg)
+ binlog_status(binlog_status_arg),
+ m_allow_empty_value(TRUE)
{}
virtual ~sys_var() {}
void chain_sys_var(sys_var_chain *chain_arg)
@@ -109,8 +110,16 @@ public:
virtual bool is_readonly() const { return 0; }
virtual sys_var_pluginvar *cast_pluginvar() { return 0; }
+protected:
+ void set_allow_empty_value(bool allow_empty_value)
+ {
+ m_allow_empty_value= allow_empty_value;
+ }
+
private:
const Binlog_status_enum binlog_status;
+
+ bool m_allow_empty_value;
};
@@ -878,8 +887,11 @@ public:
sys_var_log_output(sys_var_chain *chain, const char *name_arg, ulong *value_arg,
TYPELIB *typelib, sys_after_update_func func)
:sys_var(name_arg,func), value(value_arg), enum_names(typelib)
- { chain_sys_var(chain); }
- bool check(THD *thd, set_var *var)
+ {
+ chain_sys_var(chain);
+ set_allow_empty_value(FALSE);
+ }
+ virtual bool check(THD *thd, set_var *var)
{
return check_set(thd, var, enum_names);
}
diff --git a/sql/sp.cc b/sql/sp.cc
index 69eae8de207..3fe0841e879 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -1070,210 +1070,6 @@ sp_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics)
}
-struct st_used_field
-{
- const char *field_name;
- uint field_length;
- enum enum_field_types field_type;
- Field *field;
-};
-
-static struct st_used_field init_fields[]=
-{
- { "Db", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0},
- { "Name", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0},
- { "Type", 9, MYSQL_TYPE_STRING, 0},
- { "Definer", USER_HOST_BUFF_SIZE, MYSQL_TYPE_STRING, 0},
- { "Modified", 0, MYSQL_TYPE_TIMESTAMP, 0},
- { "Created", 0, MYSQL_TYPE_TIMESTAMP, 0},
- { "Security_type", 1, MYSQL_TYPE_STRING, 0},
- { "Comment", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0},
- { "character_set_client", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0},
- { "collation_connection", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0},
- { "Database Collation", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0},
- { 0, 0, MYSQL_TYPE_STRING, 0}
-};
-
-
-static int
-print_field_values(THD *thd, TABLE *table,
- struct st_used_field *used_fields,
- int type, const char *wild)
-{
- Protocol *protocol= thd->protocol;
-
- if (table->field[MYSQL_PROC_MYSQL_TYPE]->val_int() == type)
- {
- String db_string;
- String name_string;
- struct st_used_field *used_field= used_fields;
-
- if (get_field(thd->mem_root, used_field->field, &db_string))
- db_string.set_ascii("", 0);
- used_field+= 1;
- get_field(thd->mem_root, used_field->field, &name_string);
-
- if (!wild || !wild[0] || !wild_compare(name_string.ptr(), wild, 0))
- {
- protocol->prepare_for_resend();
- protocol->store(&db_string);
- protocol->store(&name_string);
- for (used_field++;
- used_field->field_name;
- used_field++)
- {
- switch (used_field->field_type) {
- case MYSQL_TYPE_TIMESTAMP:
- {
- MYSQL_TIME tmp_time;
-
- bzero((char *)&tmp_time, sizeof(tmp_time));
- ((Field_timestamp *) used_field->field)->get_time(&tmp_time);
- protocol->store(&tmp_time);
- }
- break;
- default:
- {
- String tmp_string;
-
- get_field(thd->mem_root, used_field->field, &tmp_string);
- protocol->store(&tmp_string);
- }
- break;
- }
- }
- if (protocol->write())
- return SP_INTERNAL_ERROR;
- }
- }
-
- return SP_OK;
-}
-
-
-/**
- Implement SHOW STATUS statement for stored routines.
-
- @param thd Thread context.
- @param type Stored routine type
- (TYPE_ENUM_PROCEDURE or TYPE_ENUM_FUNCTION)
- @param name_pattern Stored routine name pattern.
-
- @return Error code. SP_OK is returned on success. Other SP_ constants are
- used to indicate about errors.
-*/
-
-int
-sp_show_status_routine(THD *thd, int type, const char *name_pattern)
-{
- TABLE *table;
- TABLE_LIST tables;
- int res;
- DBUG_ENTER("sp_show_status_routine");
-
- DBUG_ASSERT(type == TYPE_ENUM_PROCEDURE ||
- type == TYPE_ENUM_FUNCTION);
-
- memset(&tables, 0, sizeof(tables));
- tables.db= (char*)"mysql";
- tables.table_name= tables.alias= (char*)"proc";
-
- if (! (table= open_ltable(thd, &tables, TL_READ, 0)))
- {
- res= SP_OPEN_TABLE_FAILED;
- goto done;
- }
- else
- {
- Item *item;
- List<Item> field_list;
- struct st_used_field *used_field;
- TABLE_LIST *leaves= 0;
- st_used_field used_fields[array_elements(init_fields)];
-
- table->use_all_columns();
- memcpy((char*) used_fields, (char*) init_fields, sizeof(used_fields));
- /* Init header */
- for (used_field= &used_fields[0];
- used_field->field_name;
- used_field++)
- {
- switch (used_field->field_type) {
- case MYSQL_TYPE_TIMESTAMP:
- item= new Item_return_date_time(used_field->field_name,
- MYSQL_TYPE_DATETIME);
- field_list.push_back(item);
- break;
- default:
- item= new Item_empty_string(used_field->field_name,
- used_field->field_length);
- field_list.push_back(item);
- break;
- }
- }
- /* Print header */
- if (thd->protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS |
- Protocol::SEND_EOF))
- {
- res= SP_INTERNAL_ERROR;
- goto err_case;
- }
-
- /*
- Init fields
-
- tables is not VIEW for sure => we can pass 0 as condition
- */
- thd->lex->select_lex.context.resolve_in_table_list_only(&tables);
- setup_tables(thd, &thd->lex->select_lex.context,
- &thd->lex->select_lex.top_join_list,
- &tables, &leaves, FALSE);
- for (used_field= &used_fields[0];
- used_field->field_name;
- used_field++)
- {
- Item_field *field= new Item_field(&thd->lex->select_lex.context,
- "mysql", "proc",
- used_field->field_name);
- if (!field ||
- !(used_field->field= find_field_in_tables(thd, field, &tables, NULL,
- 0, REPORT_ALL_ERRORS, 1,
- TRUE)))
- {
- res= SP_INTERNAL_ERROR;
- goto err_case1;
- }
- }
-
- table->file->ha_index_init(0, 1);
- if ((res= table->file->index_first(table->record[0])))
- {
- res= (res == HA_ERR_END_OF_FILE) ? 0 : SP_INTERNAL_ERROR;
- goto err_case1;
- }
-
- do
- {
- res= print_field_values(thd, table, used_fields, type, name_pattern);
-
- if (res)
- goto err_case1;
- }
- while (!table->file->index_next(table->record[0]));
-
- res= SP_OK;
- }
-
-err_case1:
- my_eof(thd);
-err_case:
- table->file->ha_index_end();
- close_thread_tables(thd);
-done:
- DBUG_RETURN(res);
-}
-
-
/**
Drop all routines in database 'db'
diff --git a/sql/sp.h b/sql/sp.h
index 31173e1f90c..75088ea0b83 100644
--- a/sql/sp.h
+++ b/sql/sp.h
@@ -49,9 +49,6 @@ bool
sp_show_create_routine(THD *thd, int type, sp_name *name);
int
-sp_show_status_routine(THD *thd, int type, const char *wild);
-
-int
sp_create_routine(THD *thd, int type, sp_head *sp);
int
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 92eb68dc2fa..0b33abcfba2 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -695,6 +695,8 @@ my_bool acl_reload(THD *thd)
tables[0].next_local= tables[0].next_global= tables+1;
tables[1].next_local= tables[1].next_global= tables+2;
tables[0].lock_type=tables[1].lock_type=tables[2].lock_type=TL_READ;
+ tables[0].skip_temporary= tables[1].skip_temporary=
+ tables[2].skip_temporary= TRUE;
if (simple_open_n_lock_tables(thd, tables))
{
@@ -3537,7 +3539,7 @@ static my_bool grant_load_procs_priv(TABLE *p_table)
bool check_no_resolve= specialflag & SPECIAL_NO_RESOLVE;
MEM_ROOT **save_mem_root_ptr= my_pthread_getspecific_ptr(MEM_ROOT**,
THR_MALLOC);
- DBUG_ENTER("grant_load");
+ DBUG_ENTER("grant_load_procs_priv");
(void) hash_init(&proc_priv_hash,system_charset_info,
0,0,0, (hash_get_key) get_grant_table,
0,0);
@@ -3721,6 +3723,7 @@ static my_bool grant_reload_procs_priv(THD *thd)
table.alias= table.table_name= (char*) "procs_priv";
table.db= (char *) "mysql";
table.lock_type= TL_READ;
+ table.skip_temporary= 1;
if (simple_open_n_lock_tables(thd, &table))
{
@@ -3786,7 +3789,7 @@ my_bool grant_reload(THD *thd)
tables[0].db= tables[1].db= (char *) "mysql";
tables[0].next_local= tables[0].next_global= tables+1;
tables[0].lock_type= tables[1].lock_type= TL_READ;
-
+ tables[0].skip_temporary= tables[1].skip_temporary= TRUE;
/*
To avoid deadlocks we should obtain table locks before
obtaining LOCK_grant rwlock.
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 3f0c1ee8a80..f0faf034027 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -345,26 +345,9 @@ TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key,
if (!(share= alloc_table_share(table_list, key, key_length)))
{
-#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3
- pthread_mutex_unlock(&LOCK_open);
-#endif
DBUG_RETURN(0);
}
-#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3
- // We need a write lock to be able to add a new entry
- pthread_mutex_unlock(&LOCK_open);
- pthread_mutex_lock(&LOCK_open);
- /* Check that another thread didn't insert the same table in between */
- if ((old_share= hash_search(&table_def_cache, (uchar*) key, key_length)))
- {
- (void) pthread_mutex_lock(&share->mutex);
- free_table_share(share);
- share= old_share;
- goto found;
- }
-#endif
-
/*
Lock mutex to be able to read table definition from file without
conflicts
@@ -388,29 +371,11 @@ TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key,
if (my_hash_insert(&table_def_cache, (uchar*) share))
{
-#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3
- pthread_mutex_unlock(&LOCK_open);
- (void) pthread_mutex_unlock(&share->mutex);
-#endif
free_table_share(share);
DBUG_RETURN(0); // return error
}
-#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3
- pthread_mutex_unlock(&LOCK_open);
-#endif
if (open_table_def(thd, share, db_flags))
{
-#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3
- /*
- No such table or wrong table definition file
- Lock first the table cache and then the mutex.
- This will ensure that no other thread is using the share
- structure.
- */
- (void) pthread_mutex_unlock(&share->mutex);
- (void) pthread_mutex_lock(&LOCK_open);
- (void) pthread_mutex_lock(&share->mutex);
-#endif
*error= share->error;
(void) hash_delete(&table_def_cache, (uchar*) share);
DBUG_RETURN(0);
@@ -429,9 +394,6 @@ found:
/* We must do a lock to ensure that the structure is initialized */
(void) pthread_mutex_lock(&share->mutex);
-#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3
- pthread_mutex_unlock(&LOCK_open);
-#endif
if (share->error)
{
/* Table definition contained an error */
@@ -618,52 +580,6 @@ void release_table_share(TABLE_SHARE *share, enum release_type type)
}
pthread_mutex_unlock(&share->mutex);
DBUG_VOID_RETURN;
-
-
-#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3
- if (to_be_deleted)
- {
- /*
- We must try again with new locks as we must get LOCK_open
- before share->mutex
- */
- pthread_mutex_unlock(&share->mutex);
- pthread_mutex_lock(&LOCK_open);
- pthread_mutex_lock(&share->mutex);
- if (!share->ref_count)
- { // No one is using this now
- TABLE_SHARE *name_lock;
- if (share->replace_with_name_lock && (name_lock=get_name_lock(share)))
- {
- /*
- This code is execured when someone does FLUSH TABLES while on has
- locked tables.
- */
- (void) hash_search(&def_cache,(uchar*) key,key_length);
- hash_replace(&def_cache, def_cache.current_record,(uchar*) name_lock);
- }
- else
- {
- /* Remove table definition */
- hash_delete(&def_cache,(uchar*) share);
- }
- pthread_mutex_unlock(&LOCK_open);
- free_table_share(share);
- }
- else
- {
- pthread_mutex_unlock(&LOCK_open);
- if (type == RELEASE_WAIT_FOR_DROP)
- wait_for_table(share, "Waiting for close");
- else
- pthread_mutex_unlock(&share->mutex);
- }
- }
- else if (type == RELEASE_WAIT_FOR_DROP)
- wait_for_table(share, "Waiting for close");
- else
- pthread_mutex_unlock(&share->mutex);
-#endif
}
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 2b57071d497..a5a1f9401cf 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -3301,6 +3301,7 @@ end_with_restore_list:
can free its locks if LOCK TABLES locked some tables before finding
that it can't lock a table in its list
*/
+ ha_autocommit_or_rollback(thd, 1);
end_active_trans(thd);
thd->options&= ~(OPTION_TABLE_LOCK);
}
@@ -4304,20 +4305,6 @@ create_sp_error:
}
break;
}
-#ifdef NOT_USED
- case SQLCOM_SHOW_STATUS_PROC:
- {
- res= sp_show_status_routine(thd, TYPE_ENUM_PROCEDURE,
- (lex->wild ? lex->wild->ptr() : NullS));
- break;
- }
- case SQLCOM_SHOW_STATUS_FUNC:
- {
- res= sp_show_status_routine(thd, TYPE_ENUM_FUNCTION,
- (lex->wild ? lex->wild->ptr() : NullS));
- break;
- }
-#endif
#ifndef DBUG_OFF
case SQLCOM_SHOW_PROC_CODE:
case SQLCOM_SHOW_FUNC_CODE:
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 091cc18114b..c221e29e1d0 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -155,11 +155,11 @@ public:
virtual void cleanup_stmt();
bool set_name(LEX_STRING *name);
inline void close_cursor() { delete cursor; cursor= 0; }
-
+ inline bool is_in_use() { return flags & (uint) IS_IN_USE; }
bool prepare(const char *packet, uint packet_length);
bool execute(String *expanded_query, bool open_cursor);
/* Destroy this statement */
- bool deallocate();
+ void deallocate();
private:
/**
Store the parsed tree of a prepared statement here.
@@ -198,7 +198,7 @@ inline bool is_param_null(const uchar *pos, ulong param_no)
*/
static Prepared_statement *
-find_prepared_statement(THD *thd, ulong id, const char *where)
+find_prepared_statement(THD *thd, ulong id)
{
/*
To strictly separate namespaces of SQL prepared statements and C API
@@ -208,12 +208,8 @@ find_prepared_statement(THD *thd, ulong id, const char *where)
Statement *stmt= thd->stmt_map.find(id);
if (stmt == 0 || stmt->type() != Query_arena::PREPARED_STATEMENT)
- {
- char llbuf[22];
- my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), sizeof(llbuf), llstr(id, llbuf),
- where);
- return 0;
- }
+ return NULL;
+
return (Prepared_statement *) stmt;
}
@@ -2121,8 +2117,13 @@ void mysql_sql_stmt_prepare(THD *thd)
If there is a statement with the same name, remove it. It is ok to
remove old and fail to insert a new one at the same time.
*/
- if (stmt->deallocate())
+ if (stmt->is_in_use())
+ {
+ my_error(ER_PS_NO_RECURSION, MYF(0));
DBUG_VOID_RETURN;
+ }
+
+ stmt->deallocate();
}
if (! (query= get_dynamic_sql_string(lex, &query_len)) ||
@@ -2320,8 +2321,13 @@ void mysql_stmt_execute(THD *thd, char *packet_arg, uint packet_length)
/* First of all clear possible warnings from the previous command */
mysql_reset_thd_for_next_command(thd);
- if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_execute")))
+ if (!(stmt= find_prepared_statement(thd, stmt_id)))
+ {
+ char llbuf[22];
+ my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), sizeof(llbuf),
+ llstr(stmt_id, llbuf), "mysql_stmt_execute");
DBUG_VOID_RETURN;
+ }
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
thd->profiling.set_query_source(stmt->query, stmt->query_length);
@@ -2458,8 +2464,13 @@ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length)
/* First of all clear possible warnings from the previous command */
mysql_reset_thd_for_next_command(thd);
status_var_increment(thd->status_var.com_stmt_fetch);
- if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_fetch")))
+ if (!(stmt= find_prepared_statement(thd, stmt_id)))
+ {
+ char llbuf[22];
+ my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), sizeof(llbuf),
+ llstr(stmt_id, llbuf), "mysql_stmt_fetch");
DBUG_VOID_RETURN;
+ }
cursor= stmt->cursor;
if (!cursor)
@@ -2520,8 +2531,13 @@ void mysql_stmt_reset(THD *thd, char *packet)
mysql_reset_thd_for_next_command(thd);
status_var_increment(thd->status_var.com_stmt_reset);
- if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_reset")))
+ if (!(stmt= find_prepared_statement(thd, stmt_id)))
+ {
+ char llbuf[22];
+ my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), sizeof(llbuf),
+ llstr(stmt_id, llbuf), "mysql_stmt_reset");
DBUG_VOID_RETURN;
+ }
stmt->close_cursor();
@@ -2557,15 +2573,15 @@ void mysql_stmt_close(THD *thd, char *packet)
thd->main_da.disable_status();
- if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_close")))
+ if (!(stmt= find_prepared_statement(thd, stmt_id)))
DBUG_VOID_RETURN;
/*
The only way currently a statement can be deallocated when it's
in use is from within Dynamic SQL.
*/
- DBUG_ASSERT(! (stmt->flags & (uint) Prepared_statement::IS_IN_USE));
- (void) stmt->deallocate();
+ DBUG_ASSERT(! stmt->is_in_use());
+ stmt->deallocate();
general_log_print(thd, thd->command, NullS);
DBUG_VOID_RETURN;
@@ -2592,14 +2608,15 @@ void mysql_sql_stmt_close(THD *thd)
name->str));
if (! (stmt= (Prepared_statement*) thd->stmt_map.find_by_name(name)))
- {
my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0),
name->length, name->str, "DEALLOCATE PREPARE");
- return;
- }
-
- if (stmt->deallocate() == 0)
+ else if (stmt->is_in_use())
+ my_error(ER_PS_NO_RECURSION, MYF(0));
+ else
+ {
+ stmt->deallocate();
my_ok(thd);
+ }
}
/**
@@ -2633,17 +2650,13 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length)
#ifndef EMBEDDED_LIBRARY
/* Minimal size of long data packet is 6 bytes */
if (packet_length < MYSQL_LONG_DATA_HEADER)
- {
- my_error(ER_WRONG_ARGUMENTS, MYF(0), "mysql_stmt_send_long_data");
DBUG_VOID_RETURN;
- }
#endif
stmt_id= uint4korr(packet);
packet+= 4;
- if (!(stmt=find_prepared_statement(thd, stmt_id,
- "mysql_stmt_send_long_data")))
+ if (!(stmt=find_prepared_statement(thd, stmt_id)))
DBUG_VOID_RETURN;
param_number= uint2korr(packet);
@@ -3186,16 +3199,10 @@ error:
/** Common part of DEALLOCATE PREPARE and mysql_stmt_close. */
-bool Prepared_statement::deallocate()
+void Prepared_statement::deallocate()
{
/* We account deallocate in the same manner as mysql_stmt_close */
status_var_increment(thd->status_var.com_stmt_close);
- if (flags & (uint) IS_IN_USE)
- {
- my_error(ER_PS_NO_RECURSION, MYF(0));
- return TRUE;
- }
/* Statement map calls delete stmt on erase */
thd->stmt_map.erase(this);
- return FALSE;
}
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 23ad5ce9385..103ac17a821 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -853,8 +853,9 @@ bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
Item **conds, uint order_num, ORDER *order)
{
Item *fake_conds= 0;
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
TABLE *table= table_list->table;
- TABLE_LIST tables;
+#endif
List<Item> all_fields;
SELECT_LEX *select_lex= &thd->lex->select_lex;
DBUG_ENTER("mysql_prepare_update");
@@ -878,9 +879,6 @@ bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
table_list->register_want_access(SELECT_ACL);
#endif
- bzero((char*) &tables,sizeof(tables)); // For ORDER BY
- tables.table= table;
- tables.alias= table_list->alias;
thd->lex->allow_sum_func= 0;
if (setup_tables_and_check_access(thd, &select_lex->context,