1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

Merge mysql.com:/home/mysql_src/mysql-5.0

into  mysql.com:/home/mysql_src/mysql-5.1-merge-of-5.0 (not all files are good,
I'll fix; I'll ask some devs to check their part)
This commit is contained in:
guilhem@mysql.com
2005-11-18 16:38:01 +01:00
101 changed files with 4429 additions and 791 deletions

View File

@ -188,6 +188,18 @@ inline bool all_tables_not_ok(THD *thd, TABLE_LIST *tables)
#endif
static bool some_non_temp_table_to_be_updated(THD *thd, TABLE_LIST *tables)
{
for (TABLE_LIST *table= tables; table; table= table->next_global)
{
DBUG_ASSERT(table->db && table->table_name);
if (table->updating &&
!find_temporary_table(thd, table->db, table->table_name))
return 1;
}
return 0;
}
static HASH hash_user_connections;
static int get_or_create_user_conn(THD *thd, const char *user,
@ -2360,7 +2372,7 @@ mysql_execute_command(THD *thd)
mysql_reset_errors(thd, 0);
#ifdef HAVE_REPLICATION
if (thd->slave_thread)
if (unlikely(thd->slave_thread))
{
/*
Check if statment should be skipped because of slave filtering
@ -2399,16 +2411,20 @@ mysql_execute_command(THD *thd)
}
#endif
}
else
#endif /* HAVE_REPLICATION */
/*
When option readonly is set deny operations which change tables.
Except for the replication thread and the 'super' users.
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->slave_thread ||
(thd->security_ctx->master_access & SUPER_ACL)) &&
uc_update_queries[lex->sql_command])
!(thd->security_ctx->master_access & SUPER_ACL) &&
uc_update_queries[lex->sql_command] &&
!((lex->sql_command == SQLCOM_CREATE_TABLE) &&
(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)) &&
((lex->sql_command != SQLCOM_UPDATE_MULTI) &&
some_non_temp_table_to_be_updated(thd, all_tables)))
{
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
DBUG_RETURN(-1);
@ -3198,13 +3214,24 @@ end_with_restore_list:
#ifdef HAVE_REPLICATION
/* Check slave filtering rules */
if (thd->slave_thread && all_tables_not_ok(thd, all_tables))
if (unlikely(thd->slave_thread))
{
/* we warn the slave SQL thread */
my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
if (all_tables_not_ok(thd, all_tables))
{
/* we warn the slave SQL thread */
my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
break;
}
}
else
#endif /* HAVE_REPLICATION */
if (opt_readonly &&
!(thd->security_ctx->master_access & SUPER_ACL) &&
some_non_temp_table_to_be_updated(thd, all_tables))
{
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
break;
}
#endif /* HAVE_REPLICATION */
res= mysql_multi_update(thd, all_tables,
&select_lex->item_list,
@ -4061,7 +4088,7 @@ end_with_restore_list:
if (!lex->sphead->m_db.str || !lex->sphead->m_db.str[0])
{
if (! thd->db)
if (!thd->db)
{
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
delete lex->sphead;
@ -4280,18 +4307,6 @@ end_with_restore_list:
So just execute the statement.
*/
res= sp->execute_procedure(thd, &lex->value_list);
if (mysql_bin_log.is_open() &&
(sp->m_chistics->daccess == SP_CONTAINS_SQL ||
sp->m_chistics->daccess == SP_MODIFIES_SQL_DATA))
{
if (res)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_FAILED_ROUTINE_BREAK_BINLOG,
ER(ER_FAILED_ROUTINE_BREAK_BINLOG));
else
thd->clear_error();
}
/*
If warnings have been cleared, we have to clear total_warn_count
too, otherwise the clients get confused.
@ -4350,7 +4365,8 @@ end_with_restore_list:
if (end_active_trans(thd))
goto error;
memcpy(&lex->sp_chistics, &chistics, sizeof(lex->sp_chistics));
if (!trust_routine_creators && mysql_bin_log.is_open() &&
if ((sp->m_type == TYPE_ENUM_FUNCTION) &&
!trust_function_creators && mysql_bin_log.is_open() &&
!sp->m_chistics->detistic &&
(chistics.daccess == SP_CONTAINS_SQL ||
chistics.daccess == SP_MODIFIES_SQL_DATA))
@ -4361,6 +4377,12 @@ end_with_restore_list:
}
else
{
/*
Note that if you implement the capability of ALTER FUNCTION to
alter the body of the function, this command should be made to
follow the restrictions that log-bin-trust-function-creators=0
already puts on CREATE FUNCTION.
*/
if (lex->sql_command == SQLCOM_ALTER_PROCEDURE)
result= sp_update_procedure(thd, lex->spname, &lex->sp_chistics);
else
@ -5033,7 +5055,7 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
the given table list refers to the list for prelocking (contains tables
of other queries). For simple queries first_not_own_table is 0.
*/
for (; tables != first_not_own_table; tables= tables->next_global)
for (; tables && tables != first_not_own_table; tables= tables->next_global)
{
if (tables->schema_table &&
(want_access & ~(SELECT_ACL | EXTRA_ACL | FILE_ACL)))
@ -7437,32 +7459,81 @@ Item *negate_expression(THD *thd, Item *expr)
return new Item_func_not(expr);
}
/*
Assign as view definer current user
Set the specified definer to the default value, which is the current user in
the thread. Also check that the current user satisfies to the definers
requirements.
SYNOPSIS
default_view_definer()
sctx current security context
definer structure where it should be assigned
get_default_definer()
thd [in] thread handler
definer [out] definer
RETURN
FALSE OK
TRUE Error
error status, that is:
- FALSE -- on success;
- TRUE -- on error (current user can not be a definer).
*/
bool default_view_definer(Security_context *sctx, st_lex_user *definer)
bool get_default_definer(THD *thd, LEX_USER *definer)
{
definer->user.str= sctx->priv_user;
definer->user.length= strlen(sctx->priv_user);
/* Check that current user has non-empty host name. */
if (!*sctx->priv_host)
const Security_context *sctx= thd->security_ctx;
if (sctx->priv_host[0] == 0)
{
my_error(ER_NO_VIEW_USER, MYF(0));
my_error(ER_MALFORMED_DEFINER, MYF(0));
return TRUE;
}
definer->host.str= sctx->priv_host;
definer->host.length= strlen(sctx->priv_host);
/* Fill in. */
definer->user.str= (char *) sctx->priv_user;
definer->user.length= strlen(definer->user.str);
definer->host.str= (char *) sctx->priv_host;
definer->host.length= strlen(definer->host.str);
return FALSE;
}
/*
Create definer with the given user and host names. Also check that the user
and host names satisfy definers requirements.
SYNOPSIS
create_definer()
thd [in] thread handler
user_name [in] user name
host_name [in] host name
RETURN
On success, return a valid pointer to the created and initialized
LEX_STRING, which contains definer information.
On error, return 0.
*/
LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name)
{
LEX_USER *definer;
/* Check that specified host name is valid. */
if (host_name->length == 0)
{
my_error(ER_MALFORMED_DEFINER, MYF(0));
return 0;
}
/* Create and initialize. */
if (! (definer= (LEX_USER*) thd->alloc(sizeof (LEX_USER))))
return 0;
definer->user= *user_name;
definer->host= *host_name;
return definer;
}