1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-27 18:02:13 +03:00

Merge bk-internal.mysql.com:/home/bk/mysql-5.1-maint

into  janus.mylan:/usr/home/serg/Abk/mysql-5.1


configure.in:
  Auto merged
libmysql/CMakeLists.txt:
  Auto merged
libmysqld/lib_sql.cc:
  Auto merged
mysql-test/mysql-test-run.pl:
  Auto merged
mysql-test/r/information_schema.result:
  Auto merged
mysql-test/t/information_schema.test:
  Auto merged
sql/Makefile.am:
  Auto merged
sql/field.cc:
  Auto merged
sql/handler.cc:
  Auto merged
sql/item.cc:
  Auto merged
sql/item_func.cc:
  Auto merged
sql/item_geofunc.cc:
  Auto merged
sql/item_subselect.cc:
  Auto merged
sql/key.cc:
  Auto merged
sql/lock.cc:
  Auto merged
sql/log.cc:
  Auto merged
sql/log_event.cc:
  Auto merged
sql/mysql_priv.h:
  Auto merged
sql/mysqld.cc:
  Auto merged
sql/net_serv.cc:
  Auto merged
sql/opt_sum.cc:
  Auto merged
sql/protocol.h:
  Auto merged
sql/repl_failsafe.cc:
  Auto merged
sql/set_var.cc:
  Auto merged
sql/set_var.h:
  Auto merged
sql/sp_head.cc:
  Auto merged
sql/sql_base.cc:
  Auto merged
sql/sql_cache.cc:
  Auto merged
sql/sql_class.cc:
  Auto merged
sql/sql_delete.cc:
  Auto merged
sql/sql_insert.cc:
  Auto merged
sql/sql_lex.cc:
  Auto merged
sql/sql_prepare.cc:
  Auto merged
sql/sql_select.cc:
  Auto merged
sql/sql_select.h:
  Auto merged
sql/sql_show.cc:
  Auto merged
sql/sql_table.cc:
  Auto merged
sql/sql_update.cc:
  Auto merged
sql/sql_yacc.yy:
  Auto merged
sql/table.h:
  Auto merged
storage/archive/ha_archive.cc:
  Auto merged
storage/innobase/buf/buf0buf.c:
  Auto merged
storage/innobase/buf/buf0flu.c:
  Auto merged
storage/innobase/buf/buf0lru.c:
  Auto merged
storage/innobase/include/buf0buf.h:
  Auto merged
storage/innobase/include/buf0buf.ic:
  Auto merged
storage/innobase/include/sync0arr.h:
  Auto merged
storage/innobase/include/sync0rw.h:
  Auto merged
storage/innobase/include/sync0rw.ic:
  Auto merged
storage/innobase/include/sync0sync.h:
  Auto merged
storage/innobase/os/os0sync.c:
  Auto merged
storage/innobase/sync/sync0arr.c:
  Auto merged
storage/innobase/sync/sync0rw.c:
  Auto merged
storage/innobase/sync/sync0sync.c:
  Auto merged
storage/myisam/ha_myisam.cc:
  Auto merged
storage/myisam/mi_open.c:
  Auto merged
storage/myisammrg/ha_myisammrg.cc:
  Auto merged
sql/ha_ndbcluster.cc:
  merged
sql/item_cmpfunc.cc:
  merged
sql/protocol.cc:
  merged
sql/slave.cc:
  merged
sql/sql_class.h:
  merged
sql/sql_parse.cc:
  merged
This commit is contained in:
unknown
2007-12-20 22:11:37 +01:00
306 changed files with 11710 additions and 2869 deletions

View File

@ -331,7 +331,6 @@ void execute_init_command(THD *thd, sys_var_str *init_command_var,
*/
save_vio= thd->net.vio;
thd->net.vio= 0;
thd->net.no_send_error= 0;
dispatch_command(COM_QUERY, thd,
init_command_var->value,
init_command_var->value_length);
@ -401,8 +400,8 @@ pthread_handler_t handle_bootstrap(void *arg)
/* purecov: begin tested */
if (net_realloc(&(thd->net), 2 * thd->net.max_packet))
{
net_send_error(thd, ER_NET_PACKET_TOO_LARGE, NullS);
thd->fatal_error();
net_end_statement(thd);
bootstrap_error= 1;
break;
}
buff= (char*) thd->net.buff;
@ -410,7 +409,7 @@ pthread_handler_t handle_bootstrap(void *arg)
length+= (ulong) strlen(buff + length);
/* purecov: end */
}
if (thd->is_fatal_error)
if (bootstrap_error)
break; /* purecov: inspected */
while (length && (my_isspace(thd->charset(), buff[length-1]) ||
@ -441,16 +440,11 @@ pthread_handler_t handle_bootstrap(void *arg)
mysql_parse(thd, thd->query, length, & found_semicolon);
close_thread_tables(thd); // Free tables
if (thd->is_fatal_error)
break;
bootstrap_error= thd->is_error();
net_end_statement(thd);
if (thd->is_error())
{
/* The query failed, send error to log and abort bootstrap */
net_send_error(thd);
thd->fatal_error();
if (bootstrap_error)
break;
}
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
#ifdef USING_TRANSACTIONS
@ -459,9 +453,6 @@ pthread_handler_t handle_bootstrap(void *arg)
}
end:
/* Remember the exit code of bootstrap */
bootstrap_error= thd->is_fatal_error;
net_end(&thd->net);
thd->cleanup();
delete thd;
@ -495,7 +486,7 @@ end:
(CREATE TABLE, ALTER TABLE ... UNION=(...)). Set TL_WRITE for
every child. Set 'db' for every child if not present.
*/
#ifndef NO_EMBEDDED_ACCESS_CHECKS
static bool check_merge_table_access(THD *thd, char *db,
TABLE_LIST *table_list)
{
@ -516,7 +507,7 @@ static bool check_merge_table_access(THD *thd, char *db,
}
return error;
}
#endif
/* This works because items are allocated with sql_alloc() */
@ -720,7 +711,12 @@ bool do_command(THD *thd)
*/
my_net_set_read_timeout(net, thd->variables.net_wait_timeout);
/*
XXX: this code is here only to clear possible errors of init_connect.
Consider moving to init_connect() instead.
*/
thd->clear_error(); // Clear error message
thd->main_da.reset_diagnostics_area();
net_new_transaction(net);
@ -736,13 +732,16 @@ bool do_command(THD *thd)
/* Check if we can continue without closing the connection */
/* The error must be set. */
DBUG_ASSERT(thd->is_error());
net_end_statement(thd);
if (net->error != 3)
{
return_value= TRUE; // We have to close it.
return_value= TRUE; // We have to close it.
goto out;
}
net_send_error(thd, net->last_errno, NullS);
net->error= 0;
return_value= FALSE;
goto out;
@ -789,6 +788,73 @@ out:
}
#endif /* EMBEDDED_LIBRARY */
/**
@brief Determine if an attempt to update a non-temporary table while the
read-only option was enabled has been made.
This is a helper function to mysql_execute_command.
@note SQLCOM_MULTI_UPDATE is an exception and delt with elsewhere.
@see mysql_execute_command
@returns Status code
@retval TRUE The statement should be denied.
@retval FALSE The statement isn't updating any relevant tables.
*/
static my_bool deny_updates_if_read_only_option(THD *thd,
TABLE_LIST *all_tables)
{
DBUG_ENTER("deny_updates_if_read_only_option");
if (!opt_readonly)
DBUG_RETURN(FALSE);
LEX *lex= thd->lex;
const my_bool user_is_super=
((ulong)(thd->security_ctx->master_access & SUPER_ACL) ==
(ulong)SUPER_ACL);
if (user_is_super)
DBUG_RETURN(FALSE);
if (!(sql_command_flags[lex->sql_command] & CF_CHANGES_DATA))
DBUG_RETURN(FALSE);
/* Multi update is an exception and is dealt with later. */
if (lex->sql_command == SQLCOM_UPDATE_MULTI)
DBUG_RETURN(FALSE);
const my_bool create_temp_tables=
(lex->sql_command == SQLCOM_CREATE_TABLE) &&
(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE);
const my_bool drop_temp_tables=
(lex->sql_command == SQLCOM_DROP_TABLE) &&
lex->drop_temporary;
const my_bool update_real_tables=
some_non_temp_table_to_be_updated(thd, all_tables) &&
!(create_temp_tables || drop_temp_tables);
const my_bool create_or_drop_databases=
(lex->sql_command == SQLCOM_CREATE_DB) ||
(lex->sql_command == SQLCOM_DROP_DB);
if (update_real_tables || create_or_drop_databases)
{
/*
An attempt was made to modify one or more non-temporary tables.
*/
DBUG_RETURN(TRUE);
}
/* Assuming that only temporary tables are modified. */
DBUG_RETURN(FALSE);
}
/**
Perform one connection-level (COM_XXXX) command.
@ -809,9 +875,8 @@ out:
0 ok
@retval
1 request of thread shutdown, i. e. if command is
COM_QUIT/COM_SHUTDOWN
COM_QUIT/COM_SHUTDOWN
*/
bool dispatch_command(enum enum_server_command command, THD *thd,
char* packet, uint packet_length)
{
@ -890,7 +955,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
db.length= db_len;
tbl_name= strmake(db.str, packet + 1, db_len)+1;
strmake(tbl_name, packet + db_len + 2, tbl_len);
mysql_table_dump(thd, &db, tbl_name);
if (mysql_table_dump(thd, &db, tbl_name) == 0)
thd->main_da.disable_status();
break;
}
case COM_CHANGE_USER:
@ -1057,7 +1123,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
while (!thd->killed && (end_of_stmt != NULL) && ! thd->is_error())
{
char *beginning_of_next_stmt= (char*) end_of_stmt;
net->no_send_error= 0;
net_end_statement(thd);
query_cache_end_of_result(thd);
/*
Multiple queries exits, execute them individually
*/
@ -1165,6 +1233,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
/* We don't calculate statistics for this command */
general_log_print(thd, command, NullS);
net->error=0; // Don't give 'abort' message
thd->main_da.disable_status(); // Don't send anything back
error=TRUE; // End server
break;
@ -1281,16 +1350,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
DBUG_PRINT("quit",("Got shutdown command for level %u", level));
general_log_print(thd, command, NullS);
send_eof(thd);
#ifdef __WIN__
sleep(1); // must wait after eof()
#endif
/*
The client is next going to send a COM_QUIT request (as part of
mysql_close()). Make the life simpler for the client by sending
the response for the coming COM_QUIT in advance
*/
send_eof(thd);
close_connection(thd, 0, 1);
close_thread_tables(thd); // Free before kill
kill_mysql();
error=TRUE;
@ -1303,13 +1362,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
ulong uptime;
uint length;
ulonglong queries_per_second1000;
#ifndef EMBEDDED_LIBRARY
char buff[250];
uint buff_len= sizeof(buff);
#else
char *buff= thd->net.last_error;
uint buff_len= sizeof(thd->net.last_error);
#endif
general_log_print(thd, command, NullS);
status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_STATUS]);
@ -1331,6 +1385,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
cached_open_tables(),
(uint) (queries_per_second1000 / 1000),
(uint) (queries_per_second1000 % 1000));
#ifdef EMBEDDED_LIBRARY
/* Store the buffer in permanent memory */
send_ok(thd, 0, 0, buff);
#endif
#ifdef SAFEMALLOC
if (sf_malloc_cur_memory) // Using SAFEMALLOC
{
@ -1343,7 +1401,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
#endif
#ifndef EMBEDDED_LIBRARY
VOID(my_net_write(net, (uchar*) buff, length));
VOID(net_flush(net));
VOID(net_flush(net));
thd->main_da.disable_status();
#endif
break;
}
@ -1423,10 +1482,19 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd->transaction.xid_state.xid.null();
/* report error issued during command execution */
if (thd->killed_errno() && ! thd->is_error())
thd->send_kill_message();
if (thd->is_error())
net_send_error(thd);
if (thd->killed_errno())
{
if (! thd->main_da.is_set())
thd->send_kill_message();
}
if (thd->killed == THD::KILL_QUERY || thd->killed == THD::KILL_BAD_DATA)
{
thd->killed= THD::NOT_KILLED;
thd->mysys_var->abort= 0;
}
net_end_statement(thd);
query_cache_end_of_result(thd);
log_slow_statement(thd);
@ -1505,7 +1573,7 @@ void log_slow_statement(THD *thd)
0 success
@retval
1 out of memory or SHOW commands are not allowed
in this version of the server.
in this version of the server.
*/
int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
@ -1618,7 +1686,7 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
Read query from packet and store in thd->query.
Used in COM_QUERY and COM_STMT_PREPARE.
Sets the following THD variables:
Sets the following THD variables:
- query
- query_length
@ -1810,7 +1878,6 @@ mysql_execute_command(THD *thd)
SELECT_LEX_UNIT *unit= &lex->unit;
/* Saved variable value */
DBUG_ENTER("mysql_execute_command");
thd->net.no_send_error= 0;
#ifdef WITH_PARTITION_STORAGE_ENGINE
thd->work_part_info= 0;
#endif
@ -1923,14 +1990,7 @@ mysql_execute_command(THD *thd)
When option readonly is set deny operations which change non-temporary
tables. Except for the replication thread and the 'super' users.
*/
if (opt_readonly &&
!(thd->security_ctx->master_access & SUPER_ACL) &&
(sql_command_flags[lex->sql_command] & CF_CHANGES_DATA) &&
!((lex->sql_command == SQLCOM_CREATE_TABLE) &&
(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)) &&
!((lex->sql_command == SQLCOM_DROP_TABLE) && lex->drop_temporary) &&
((lex->sql_command != SQLCOM_UPDATE_MULTI) &&
some_non_temp_table_to_be_updated(thd, all_tables)))
if (deny_updates_if_read_only_option(thd, all_tables))
{
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
DBUG_RETURN(-1);
@ -1944,10 +2004,6 @@ mysql_execute_command(THD *thd)
switch (lex->sql_command) {
case SQLCOM_SHOW_EVENTS:
if ((res= check_access(thd, EVENT_ACL, thd->lex->select_lex.db, 0, 0, 0,
is_schema_db(thd->lex->select_lex.db))))
break;
/* fall through */
case SQLCOM_SHOW_STATUS_PROC:
case SQLCOM_SHOW_STATUS_FUNC:
res= execute_sqlcom_select(thd, all_tables);
@ -3060,13 +3116,9 @@ end_with_restore_list:
SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
OPTION_SETUP_TABLES_DONE,
del_result, unit, select_lex);
res|= thd->net.report_error;
if (unlikely(res))
{
/* If we had a another error reported earlier then this will be ignored */
del_result->send_error(ER_UNKNOWN_ERROR, "Execution of the query failed");
res|= thd->is_error();
if (res)
del_result->abort();
}
delete del_result;
}
else
@ -3999,8 +4051,6 @@ create_sp_error:
goto error;
}
my_bool save_no_send_ok= thd->net.no_send_ok;
thd->net.no_send_ok= TRUE;
if (sp->m_flags & sp_head::MULTI_RESULTS)
{
if (! (thd->client_capabilities & CLIENT_MULTI_RESULTS))
@ -4010,7 +4060,6 @@ create_sp_error:
back
*/
my_error(ER_SP_BADSELECT, MYF(0), sp->m_qname.str);
thd->net.no_send_ok= save_no_send_ok;
goto error;
}
/*
@ -4022,14 +4071,11 @@ create_sp_error:
thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (check_routine_access(thd, EXECUTE_ACL,
sp->m_db.str, sp->m_name.str, TRUE, FALSE))
{
thd->net.no_send_ok= save_no_send_ok;
goto error;
}
#endif
select_limit= thd->variables.select_limit;
thd->variables.select_limit= HA_POS_ERROR;
@ -4051,7 +4097,6 @@ create_sp_error:
thd->variables.select_limit= select_limit;
thd->net.no_send_ok= save_no_send_ok;
thd->server_status&= ~bits_to_be_cleared;
if (!res)
@ -4691,7 +4736,10 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_YES, str.ptr());
}
result->send_eof();
if (res)
result->abort();
else
result->send_eof();
delete result;
}
else
@ -4708,14 +4756,15 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
/**
Check grants for commands which work only with one table.
@param thd Thread handler
@param privilege requested privilege
@param all_tables global table list of query
@param thd Thread handler
@param privilege requested privilege
@param all_tables global table list of query
@param no_errors FALSE/TRUE - report/don't report error to
the client (using my_error() call).
the client (using my_error() call).
@retval
0 OK
@ -4824,7 +4873,6 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
bool dont_check_global_grants, bool no_errors, bool schema_db)
{
Security_context *sctx= thd->security_ctx;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
ulong db_access;
/*
GRANT command:
@ -4837,7 +4885,6 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
*/
bool db_is_pattern= (test(want_access & GRANT_ACL) &&
dont_check_global_grants);
#endif
ulong dummy;
DBUG_ENTER("check_access");
DBUG_PRINT("enter",("db: %s want_access: %lu master_access: %lu",
@ -4877,9 +4924,6 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
}
}
#ifdef NO_EMBEDDED_ACCESS_CHECKS
DBUG_RETURN(0);
#else
if ((sctx->master_access & want_access) == want_access)
{
/*
@ -4937,7 +4981,6 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
thd->db :
"unknown"))); /* purecov: tested */
DBUG_RETURN(TRUE); /* purecov: tested */
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
}
@ -4961,16 +5004,12 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
bool check_global_access(THD *thd, ulong want_access)
{
#ifdef NO_EMBEDDED_ACCESS_CHECKS
return 0;
#else
char command[128];
if ((thd->security_ctx->master_access & want_access))
return 0;
get_privilege_desc(command, sizeof(command), want_access);
my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), command);
return 1;
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
}
@ -5040,7 +5079,7 @@ static bool check_show_access(THD *thd, TABLE_LIST *table)
@param want_access Privileges requested
@param tables List of tables to be checked
@param no_errors FALSE/TRUE - report/don't report error to
the client (using my_error() call).
the client (using my_error() call).
@note
Table privileges are cached in the table list for GRANT checking.
@ -5059,9 +5098,7 @@ bool
check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
bool no_errors)
{
#ifndef NO_EMBEDDED_ACCESS_CHECKS
TABLE_LIST *org_tables= tables;
#endif
TABLE_LIST *first_not_own_table= thd->lex->first_not_own_table();
Security_context *sctx= thd->security_ctx, *backup_ctx= thd->security_ctx;
/*
@ -5148,11 +5185,7 @@ check_routine_access(THD *thd, ulong want_access,char *db, char *name,
0, no_errors, 0))
return TRUE;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
return check_grant_routine(thd, want_access, tables, is_proc, no_errors);
#else
return FALSE;
#endif
}
@ -5219,6 +5252,7 @@ bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table)
DBUG_RETURN(1);
}
#endif /*NO_EMBEDDED_ACCESS_CHECKS*/
/****************************************************************************
Check stack size; Send error if there isn't enough stack to continue
@ -5297,11 +5331,11 @@ bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, ulong *yystacksize)
/**
Reset THD part responsible for command processing state.
Reset THD part responsible for command processing state.
This needs to be called before execution of every statement
(prepared or conventional).
It is not called by substatements of routines.
This needs to be called before execution of every statement
(prepared or conventional).
It is not called by substatements of routines.
@todo
Make it a method of THD and align its name with the rest of
@ -5314,6 +5348,7 @@ void mysql_reset_thd_for_next_command(THD *thd)
{
DBUG_ENTER("mysql_reset_thd_for_next_command");
DBUG_ASSERT(!thd->spcont); /* not for substatements of routines */
DBUG_ASSERT(! thd->in_sub_stmt);
thd->free_list= 0;
thd->select_number= 1;
/*
@ -5340,18 +5375,18 @@ void mysql_reset_thd_for_next_command(THD *thd)
}
DBUG_ASSERT(thd->security_ctx== &thd->main_security_ctx);
thd->thread_specific_used= FALSE;
if (!thd->in_sub_stmt)
if (opt_bin_log)
{
if (opt_bin_log)
{
reset_dynamic(&thd->user_var_events);
thd->user_var_events_alloc= thd->mem_root;
}
thd->clear_error();
thd->total_warn_count=0; // Warnings for this query
thd->rand_used= 0;
thd->sent_row_count= thd->examined_row_count= 0;
reset_dynamic(&thd->user_var_events);
thd->user_var_events_alloc= thd->mem_root;
}
thd->clear_error();
thd->main_da.reset_diagnostics_area();
thd->total_warn_count=0; // Warnings for this query
thd->rand_used= 0;
thd->sent_row_count= thd->examined_row_count= 0;
/*
Because we come here only for start of top-statements, binlog format is
constant inside a complex statement (using stored functions) etc.
@ -5586,7 +5621,6 @@ void mysql_parse(THD *thd, const char *inBuf, uint length,
/* Actually execute the query */
lex->set_trg_event_type_for_tables();
mysql_execute_command(thd);
query_cache_end_of_result(thd);
}
}
}
@ -5819,7 +5853,7 @@ bool add_to_list(THD *thd, SQL_LIST &list,Item *item,bool asc)
@param ignore_index List of indexed used in IGNORE INDEX
@retval
0 Error
0 Error
@retval
\# Pointer to TABLE_LIST element added to the total table list
*/
@ -6052,7 +6086,7 @@ TABLE_LIST *st_select_lex::end_nested_join(THD *thd)
/**
Nest last join operation.
The function nest last join operation as if it was enclosed in braces.
The function nest last join operation as if it was enclosed in braces.
@param thd current thread
@ -6139,17 +6173,17 @@ void st_select_lex::add_joined_table(TABLE_LIST *table)
EXAMPLES
@verbatim
SELECT * FROM t1 RIGHT JOIN t2 ON on_expr =>
SELECT * FROM t2 LEFT JOIN t1 ON on_expr
SELECT * FROM t1 RIGHT JOIN t2 ON on_expr =>
SELECT * FROM t2 LEFT JOIN t1 ON on_expr
SELECT * FROM t1,t2 RIGHT JOIN t3 ON on_expr =>
SELECT * FROM t1,t3 LEFT JOIN t2 ON on_expr
SELECT * FROM t1,t2 RIGHT JOIN t3 ON on_expr =>
SELECT * FROM t1,t3 LEFT JOIN t2 ON on_expr
SELECT * FROM t1,t2 RIGHT JOIN (t3,t4) ON on_expr =>
SELECT * FROM t1,(t3,t4) LEFT JOIN t2 ON on_expr
SELECT * FROM t1,t2 RIGHT JOIN (t3,t4) ON on_expr =>
SELECT * FROM t1,(t3,t4) LEFT JOIN t2 ON on_expr
SELECT * FROM t1 LEFT JOIN t2 ON on_expr1 RIGHT JOIN t3 ON on_expr2 =>
SELECT * FROM t3 LEFT JOIN (t1 LEFT JOIN t2 ON on_expr2) ON on_expr1
SELECT * FROM t1 LEFT JOIN t2 ON on_expr1 RIGHT JOIN t3 ON on_expr2 =>
SELECT * FROM t3 LEFT JOIN (t1 LEFT JOIN t2 ON on_expr2) ON on_expr1
@endverbatim
@param thd current thread
@ -6214,7 +6248,7 @@ void st_select_lex::set_lock_for_tables(thr_lock_type lock_type)
@varbatim
(SELECT ... ORDER BY LIMIT n) ORDER BY ...
@endvarbatim
@param thd_arg thread handle
@note
@ -6303,7 +6337,7 @@ push_new_name_resolution_context(THD *thd,
/**
Add an ON condition to the second operand of a JOIN ... ON.
Add an ON condition to the right operand of a JOIN ... ON clause.
Add an ON condition to the right operand of a JOIN ... ON clause.
@param b the second operand of a JOIN ... ON
@param expr the condition to be added to the ON clause
@ -6349,17 +6383,17 @@ void add_join_on(TABLE_LIST *b, Item *expr)
EXAMPLE
@verbatim
SELECT * FROM t1 NATURAL LEFT JOIN t2
<=>
SELECT * FROM t1 LEFT JOIN t2 ON (t1.i=t2.i and t1.j=t2.j ... )
SELECT * FROM t1 NATURAL LEFT JOIN t2
<=>
SELECT * FROM t1 LEFT JOIN t2 ON (t1.i=t2.i and t1.j=t2.j ... )
SELECT * FROM t1 NATURAL JOIN t2 WHERE <some_cond>
<=>
SELECT * FROM t1, t2 WHERE (t1.i=t2.i and t1.j=t2.j and <some_cond>)
SELECT * FROM t1 NATURAL JOIN t2 WHERE <some_cond>
<=>
SELECT * FROM t1, t2 WHERE (t1.i=t2.i and t1.j=t2.j and <some_cond>)
SELECT * FROM t1 JOIN t2 USING(j) WHERE <some_cond>
<=>
SELECT * FROM t1, t2 WHERE (t1.j=t2.j and <some_cond>)
SELECT * FROM t1 JOIN t2 USING(j) WHERE <some_cond>
<=>
SELECT * FROM t1, t2 WHERE (t1.j=t2.j and <some_cond>)
@endverbatim
@param a Left join argument
@ -6418,8 +6452,10 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
}
if (thd)
{
(void)acl_reload(thd);
(void)grant_reload(thd);
if (acl_reload(thd))
result= 1;
if (grant_reload(thd))
result= 1;
}
if (tmp_thd)
{
@ -6509,8 +6545,8 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
tmp_write_to_binlog= 0;
if (lock_global_read_lock(thd))
return 1; // Killed
result=close_cached_tables(thd,(options & REFRESH_FAST) ? 0 : 1,
tables);
result= close_cached_tables(thd, tables, FALSE, (options & REFRESH_FAST) ?
FALSE : TRUE, TRUE);
if (make_global_read_lock_block_commit(thd)) // Killed
{
/* Don't leave things in a half-locked state */
@ -6519,7 +6555,8 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
}
}
else
result=close_cached_tables(thd,(options & REFRESH_FAST) ? 0 : 1, tables);
result= close_cached_tables(thd, tables, FALSE, (options & REFRESH_FAST) ?
FALSE : TRUE, FALSE);
my_dbopt_cleanup();
}
if (options & REFRESH_HOSTS)
@ -6536,7 +6573,6 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
if (reset_master(thd))
{
result=1;
thd->fatal_error(); // Ensure client get error
}
}
#endif
@ -7148,7 +7184,7 @@ Item *negate_expression(THD *thd, Item *expr)
/**
Set the specified definer to the default value, which is the
current user in the thread.
@param[in] thd thread handler
@param[out] definer definer
*/