merge
sql/sql_lex.cc: Auto merged sql/sql_parse.cc: Auto merged sql/sql_update.cc: Auto merged sql/sql_yacc.yy: Auto merged sql/table.cc: Auto merged sql/table.h: Auto merged
This commit is contained in:
commit
5b82bc6644
@ -261,7 +261,7 @@ public:
|
||||
Returns strcat('*', octet2hex(sha1(sha1(password)))). '*' stands for new
|
||||
password format, sha1(sha1(password) is so-called hash_stage2 value.
|
||||
Length of returned string is always 41 byte. To find out how entire
|
||||
authentification procedure works, see comments in password.c.
|
||||
authentication procedure works, see comments in password.c.
|
||||
*/
|
||||
|
||||
class Item_func_password :public Item_str_func
|
||||
|
@ -57,11 +57,11 @@ write_escaped_string(IO_CACHE *file, LEX_STRING *val_s)
|
||||
if (my_b_append(file, (const byte *)"\\n", 2))
|
||||
return TRUE;
|
||||
break;
|
||||
case '\0': // problem for some string processing utilites
|
||||
case '\0': // problem for some string processing utilities
|
||||
if (my_b_append(file, (const byte *)"\\0", 2))
|
||||
return TRUE;
|
||||
break;
|
||||
case 26: // problem for windows utilites (Ctrl-Z)
|
||||
case 26: // problem for windows utilities (Ctrl-Z)
|
||||
if (my_b_append(file, (const byte *)"\\z", 2))
|
||||
return TRUE;
|
||||
break;
|
||||
@ -253,7 +253,7 @@ sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name,
|
||||
{
|
||||
if (old_version != ULONGLONG_MAX && max_versions != 0)
|
||||
{
|
||||
// save buckup
|
||||
// save backup
|
||||
char path_arc[FN_REFLEN];
|
||||
// backup old version
|
||||
char path_to[FN_REFLEN];
|
||||
@ -383,9 +383,9 @@ sql_parse_prepare(const LEX_STRING *file_name, MEM_ROOT *mem_root,
|
||||
}
|
||||
|
||||
end= parser->end= parser->buff + len;
|
||||
*end= '\0'; // barriaer for more simple parsing
|
||||
*end= '\0'; // barrier for more simple parsing
|
||||
|
||||
// 7 = 5 (TYPE=) + 1 (leter at least of type name) + 1 ('\n')
|
||||
// 7 = 5 (TYPE=) + 1 (letter at least of type name) + 1 ('\n')
|
||||
if (len < 7 ||
|
||||
parser->buff[0] != 'T' ||
|
||||
parser->buff[1] != 'Y' ||
|
||||
|
@ -23,7 +23,7 @@
|
||||
enum file_opt_type {
|
||||
FILE_OPTIONS_STRING, /* String (LEX_STRING) */
|
||||
FILE_OPTIONS_ESTRING, /* Escaped string (LEX_STRING) */
|
||||
FILE_OPTIONS_ULONGLONG, /* ulonglong parapeter (ulonglong) */
|
||||
FILE_OPTIONS_ULONGLONG, /* ulonglong parameter (ulonglong) */
|
||||
FILE_OPTIONS_REV, /* Revision version number (ulonglong) */
|
||||
FILE_OPTIONS_TIMESTAMP, /* timestamp (LEX_STRING have to be
|
||||
allocated with length 20 (19+1) */
|
||||
|
@ -65,7 +65,7 @@
|
||||
#include <sha1.h>
|
||||
#include "mysql.h"
|
||||
|
||||
/************ MySQL 3.23-4.0 authentification routines: untouched ***********/
|
||||
/************ MySQL 3.23-4.0 authentication routines: untouched ***********/
|
||||
|
||||
/*
|
||||
New (MySQL 3.21+) random generation structure initialization
|
||||
@ -280,7 +280,7 @@ void make_password_from_salt_323(char *to, const ulong *salt)
|
||||
|
||||
|
||||
/*
|
||||
**************** MySQL 4.1.1 authentification routines *************
|
||||
**************** MySQL 4.1.1 authentication routines *************
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -17,8 +17,8 @@
|
||||
|
||||
/*
|
||||
The privileges are saved in the following tables:
|
||||
mysql/user ; super user who are allowed to do almoust anything
|
||||
mysql/host ; host priviliges. This is used if host is empty in mysql/db.
|
||||
mysql/user ; super user who are allowed to do almost anything
|
||||
mysql/host ; host privileges. This is used if host is empty in mysql/db.
|
||||
mysql/db ; database privileges / user
|
||||
|
||||
data in tables is sorted according to how many not-wild-cards there is
|
||||
@ -597,7 +597,7 @@ static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b)
|
||||
thd->host, thd->ip, thd->user are used for checks.
|
||||
mqh user resources; on success mqh is reset, else
|
||||
unchanged
|
||||
passwd scrambled & crypted password, recieved from client
|
||||
passwd scrambled & crypted password, received from client
|
||||
(to check): thd->scramble or thd->scramble_323 is
|
||||
used to decrypt passwd, so they must contain
|
||||
original random string,
|
||||
@ -608,7 +608,7 @@ static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b)
|
||||
RETURN VALUE
|
||||
0 success: thd->priv_user, thd->priv_host, thd->master_access, mqh are
|
||||
updated
|
||||
1 user not found or authentification failure
|
||||
1 user not found or authentication failure
|
||||
2 user found, has long (4.1.1) salt, but passwd is in old (3.23) format.
|
||||
-1 user found, has short (3.23) salt, but passwd is in new (4.1.1) format.
|
||||
*/
|
||||
@ -748,7 +748,7 @@ int acl_getroot(THD *thd, USER_RESOURCES *mqh,
|
||||
break;
|
||||
}
|
||||
DBUG_PRINT("info",("checkpoint 2"));
|
||||
/* If X509 issuer is speified, we check it... */
|
||||
/* If X509 issuer is specified, we check it... */
|
||||
if (acl_user->x509_issuer)
|
||||
{
|
||||
DBUG_PRINT("info",("checkpoint 3"));
|
||||
@ -810,7 +810,7 @@ int acl_getroot(THD *thd, USER_RESOURCES *mqh,
|
||||
/*
|
||||
* This is like acl_getroot() above, but it doesn't check password,
|
||||
* and we don't care about the user resources.
|
||||
* Used to get access rights for SQL SECURITY DEFINER invokation of
|
||||
* Used to get access rights for SQL SECURITY DEFINER invocation of
|
||||
* stored procedures.
|
||||
*/
|
||||
int acl_getroot_no_password(THD *thd)
|
||||
@ -1831,7 +1831,7 @@ GRANT_TABLE::GRANT_TABLE(const char *h, const char *d,const char *u,
|
||||
{
|
||||
/* Host given by user */
|
||||
orig_host= strdup_root(&memex,h);
|
||||
/* Convert empty hostname to '%' for easy comparision */
|
||||
/* Convert empty hostname to '%' for easy comparison */
|
||||
host= orig_host[0] ? orig_host : (char*) "%";
|
||||
db = strdup_root(&memex,d);
|
||||
user = strdup_root(&memex,u);
|
||||
@ -2778,7 +2778,7 @@ void grant_reload(THD *thd)
|
||||
/****************************************************************************
|
||||
Check table level grants
|
||||
|
||||
SYNPOSIS
|
||||
SYNOPSIS
|
||||
bool check_grant()
|
||||
thd Thread handler
|
||||
want_access Bits of privileges user needs to have
|
||||
@ -2792,7 +2792,7 @@ void grant_reload(THD *thd)
|
||||
|
||||
RETURN
|
||||
0 ok
|
||||
1 Error: User did not have the requested privielges
|
||||
1 Error: User did not have the requested privileges
|
||||
****************************************************************************/
|
||||
|
||||
bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
|
||||
@ -3870,8 +3870,8 @@ int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr)
|
||||
fill effective privileges for table
|
||||
|
||||
SYNOPSIS
|
||||
get_effectlige_privileges()
|
||||
thd thread handleg
|
||||
fill_effective_table_privileges()
|
||||
thd thread handler
|
||||
grant grants table descriptor
|
||||
db db name
|
||||
table table name
|
||||
|
@ -1537,11 +1537,17 @@ void st_select_lex::print_limit(THD *thd, String *str)
|
||||
|
||||
|
||||
/*
|
||||
Check is merging algorithm can be used on this VIEW
|
||||
Check whether the merging algorithm can be used on this VIEW
|
||||
|
||||
SYNOPSIS
|
||||
st_lex::can_be_merged()
|
||||
|
||||
DESCRIPTION
|
||||
We can apply merge algorithm if it is single SELECT view (we do not
|
||||
count SELECTs of underlying views) and we have not grpouping, ordering,
|
||||
HAVING clause, aggregate functions, DISTINCT clause, LIMIT clause and
|
||||
several underlying tables.
|
||||
|
||||
RETURN
|
||||
FALSE - only temporary table algorithm can be used
|
||||
TRUE - merge algorithm can be used
|
||||
@ -1569,12 +1575,18 @@ bool st_lex::can_be_merged()
|
||||
select_lex.select_limit == HA_POS_ERROR);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
check if command can use VIEW with MERGE algorithm (for top VIEWs)
|
||||
|
||||
SYNOPSIS
|
||||
st_lex::can_use_merged()
|
||||
|
||||
DESCRIPTION
|
||||
Only listed here commands can use merge algorithm in top level
|
||||
SELECT_LEX (for subqueries will be used merge algorithm if
|
||||
st_lex::can_not_use_merged() is not TRUE).
|
||||
|
||||
RETURN
|
||||
FALSE - command can't use merged VIEWs
|
||||
TRUE - VIEWs with MERGE algorithms can be used
|
||||
@ -1601,11 +1613,15 @@ bool st_lex::can_use_merged()
|
||||
}
|
||||
|
||||
/*
|
||||
check if command can't use merged views in any part of command
|
||||
Check if command can't use merged views in any part of command
|
||||
|
||||
SYNOPSIS
|
||||
st_lex::can_not_use_merged()
|
||||
|
||||
DESCRIPTION
|
||||
Temporary table algorithm will be used on all SELECT levels for queries
|
||||
listed here (see also st_lex::can_use_merged()).
|
||||
|
||||
RETURN
|
||||
FALSE - command can't use merged VIEWs
|
||||
TRUE - VIEWs with MERGE algorithms can be used
|
||||
@ -1673,16 +1689,16 @@ void st_select_lex_unit::set_limit(SELECT_LEX *values,
|
||||
|
||||
|
||||
/*
|
||||
Unlink first table from global table list and first table from outer select
|
||||
list (lex->select_lex)
|
||||
Unlink the first table from the global table list and the first table from
|
||||
outer select (lex->select_lex) local list
|
||||
|
||||
SYNOPSIS
|
||||
unlink_first_table()
|
||||
link_to_local Set to 1 if caller should link this table to local
|
||||
link_to_local Set to 1 if caller should link this table to local list
|
||||
|
||||
NOTES
|
||||
We rely on fact that first table in both list are same or local list
|
||||
is empty
|
||||
We assume that first tables in both lists is the same table or the local
|
||||
list is empty.
|
||||
|
||||
RETURN
|
||||
0 If 'query_tables' == 0
|
||||
@ -1711,8 +1727,8 @@ TABLE_LIST *st_lex::unlink_first_table(bool *link_to_local)
|
||||
select_lex.table_list.elements--; //safety
|
||||
first->next_local= 0;
|
||||
/*
|
||||
reorder global list to keep first tables the same in both lists
|
||||
(if it is need)
|
||||
Ensure that the global list has the same first table as the local
|
||||
list.
|
||||
*/
|
||||
first_lists_tables_same();
|
||||
}
|
||||
@ -1729,11 +1745,12 @@ TABLE_LIST *st_lex::unlink_first_table(bool *link_to_local)
|
||||
st_lex::first_lists_tables_same()
|
||||
|
||||
NOTES
|
||||
In many cases first table of main SELECT_LEX have special meaning =>
|
||||
check that it is first table in global list and relink it first in
|
||||
queries_tables list if it is necessary (we need such relinking only
|
||||
for queries with subqueries in select list, in this case tables of
|
||||
subqueries will go to global list first)
|
||||
In many cases (for example, usual INSERT/DELETE/...) the first table of
|
||||
main SELECT_LEX have special meaning => check that it is the first table
|
||||
in global list and re-link to be first in the global list if it is
|
||||
necessary. We need such re-linking only for queries with sub-queries in
|
||||
the select list, as only in this case tables of sub-queries will go to
|
||||
the global list first.
|
||||
*/
|
||||
|
||||
void st_lex::first_lists_tables_same()
|
||||
@ -1744,14 +1761,15 @@ void st_lex::first_lists_tables_same()
|
||||
TABLE_LIST *next;
|
||||
if (query_tables_last == &first_table->next_global)
|
||||
query_tables_last= first_table->prev_global;
|
||||
|
||||
|
||||
if ((next= *first_table->prev_global= first_table->next_global))
|
||||
next->prev_global= first_table->prev_global;
|
||||
/* include in new place */
|
||||
first_table->next_global= query_tables;
|
||||
/*
|
||||
we are sure that above is not 0, because first_table was not
|
||||
first table in global list => we can do following without check
|
||||
We are sure that query_tables is not 0, because first_table was not
|
||||
first table in the global list => we can use
|
||||
query_tables->prev_global without check of query_tables
|
||||
*/
|
||||
query_tables->prev_global= &first_table->next_global;
|
||||
first_table->prev_global= &query_tables;
|
||||
|
@ -108,7 +108,7 @@ static void unlock_locked_tables(THD *thd)
|
||||
if (thd->locked_tables)
|
||||
{
|
||||
thd->lock=thd->locked_tables;
|
||||
thd->locked_tables=0; // Will be automaticly closed
|
||||
thd->locked_tables=0; // Will be automatically closed
|
||||
close_thread_tables(thd); // Free tables
|
||||
}
|
||||
}
|
||||
@ -205,13 +205,13 @@ end:
|
||||
command originator of the check: now check_user is called
|
||||
during connect and change user procedures; used for
|
||||
logging.
|
||||
passwd scrambled password recieved from client
|
||||
passwd scrambled password received from client
|
||||
passwd_len length of scrambled password
|
||||
db database name to connect to, may be NULL
|
||||
check_count dont know exactly
|
||||
|
||||
Note, that host, user and passwd may point to communication buffer.
|
||||
Current implementation does not depened on that, but future changes
|
||||
Current implementation does not depend on that, but future changes
|
||||
should be done with this in mind; 'thd' is INOUT, all other params
|
||||
are 'IN'.
|
||||
|
||||
@ -269,7 +269,7 @@ int check_user(THD *thd, enum enum_server_command command,
|
||||
|
||||
/*
|
||||
Clear thd->db as it points to something, that will be freed when
|
||||
connection is closed. We don't want to accidently free a wrong pointer
|
||||
connection is closed. We don't want to accidentally free a wrong pointer
|
||||
if connect failed. Also in case of 'CHANGE USER' failure, current
|
||||
database will be switched to 'no database selected'.
|
||||
*/
|
||||
@ -311,7 +311,7 @@ int check_user(THD *thd, enum enum_server_command command,
|
||||
/* here res is always >= 0 */
|
||||
if (res == 0)
|
||||
{
|
||||
if (!(thd->master_access & NO_ACCESS)) // authentification is OK
|
||||
if (!(thd->master_access & NO_ACCESS)) // authentication is OK
|
||||
{
|
||||
DBUG_PRINT("info",
|
||||
("Capabilities: %d packet_length: %ld Host: '%s' "
|
||||
@ -731,7 +731,7 @@ static int check_connection(THD *thd)
|
||||
#endif /* HAVE_COMPRESS */
|
||||
#ifdef HAVE_OPENSSL
|
||||
if (ssl_acceptor_fd)
|
||||
client_flags |= CLIENT_SSL; /* Wow, SSL is avalaible! */
|
||||
client_flags |= CLIENT_SSL; /* Wow, SSL is available! */
|
||||
#endif /* HAVE_OPENSSL */
|
||||
|
||||
end= strnmov(buff, server_version, SERVER_VERSION_LENGTH) + 1;
|
||||
@ -1393,7 +1393,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
*passwd++ : strlen(passwd);
|
||||
db+= passwd_len + 1;
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
/* Small check for incomming packet */
|
||||
/* Small check for incoming packet */
|
||||
if ((uint) ((uchar*) db - net->read_pos) > packet_length)
|
||||
{
|
||||
send_error(thd, ER_UNKNOWN_COM_ERROR);
|
||||
@ -1428,7 +1428,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
|
||||
if (res)
|
||||
{
|
||||
/* authentification failure, we shall restore old user */
|
||||
/* authentication failure, we shall restore old user */
|
||||
if (res > 0)
|
||||
send_error(thd, ER_UNKNOWN_COM_ERROR);
|
||||
x_free(thd->user);
|
||||
@ -2397,7 +2397,7 @@ mysql_execute_command(THD *thd)
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
If we are using SET CHARSET without DEFAULT, add an implicite
|
||||
If we are using SET CHARSET without DEFAULT, add an implicit
|
||||
DEFAULT to not confuse old users. (This may change).
|
||||
*/
|
||||
if ((lex->create_info.used_fields &
|
||||
@ -3551,7 +3551,7 @@ purposes internal to the MySQL server", MYF(0));
|
||||
if (thd->locked_tables)
|
||||
{
|
||||
thd->lock=thd->locked_tables;
|
||||
thd->locked_tables=0; // Will be automaticly closed
|
||||
thd->locked_tables=0; // Will be automatically closed
|
||||
close_thread_tables(thd); // Free tables
|
||||
}
|
||||
if (end_active_trans(thd))
|
||||
@ -3998,7 +3998,7 @@ error:
|
||||
SYNOPSIS
|
||||
check_one_table_access()
|
||||
thd Thread handler
|
||||
privilege requested privelage
|
||||
privilege requested privilege
|
||||
all_tables global table list of query
|
||||
|
||||
RETURN
|
||||
@ -4140,7 +4140,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
|
||||
want_access Use should have any of these global rights
|
||||
|
||||
WARNING
|
||||
One gets access rigth if one has ANY of the rights in want_access
|
||||
One gets access right if one has ANY of the rights in want_access
|
||||
This is useful as one in most cases only need one global right,
|
||||
but in some case we want to check if the user has SUPER or
|
||||
REPL_CLIENT_ACL rights.
|
||||
@ -4902,7 +4902,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
|
||||
/*
|
||||
We are setting TIMESTAMP_OLD_FIELD here only temporary, we will
|
||||
replace this value by TIMESTAMP_DNUN_FIELD or NONE later when
|
||||
information about all TIMESTAMP fields in table will be availiable.
|
||||
information about all TIMESTAMP fields in table will be available.
|
||||
*/
|
||||
new_field->unireg_check= on_update_value?Field::TIMESTAMP_UN_FIELD:
|
||||
Field::TIMESTAMP_OLD_FIELD;
|
||||
@ -5329,7 +5329,7 @@ TABLE_LIST *st_select_lex::nest_last_join(THD *thd)
|
||||
|
||||
|
||||
/*
|
||||
Save names for a join with using clase
|
||||
Save names for a join with using clause
|
||||
|
||||
SYNOPSIS
|
||||
save_names_for_using_list
|
||||
@ -6182,7 +6182,7 @@ int create_table_precheck(THD *thd, TABLE_LIST *tables,
|
||||
|
||||
SYNOPSIS
|
||||
negate_expression()
|
||||
thd therad handler
|
||||
thd thread handler
|
||||
expr expression for negation
|
||||
|
||||
RETURN
|
||||
|
@ -762,7 +762,7 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild,
|
||||
protocol->store(field->has_charset() ? field->charset()->name : "NULL",
|
||||
system_charset_info);
|
||||
/*
|
||||
Altough TIMESTAMP fields can't contain NULL as its value they
|
||||
Although TIMESTAMP fields can't contain NULL as its value they
|
||||
will accept NULL if you will try to insert such value and will
|
||||
convert it to current TIMESTAMP. So YES here means that NULL
|
||||
is allowed for assignment but can't be returned.
|
||||
@ -781,7 +781,7 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild,
|
||||
{
|
||||
/*
|
||||
We have NOW() as default value but we use CURRENT_TIMESTAMP form
|
||||
because it is more SQL standard comatible
|
||||
because it is more SQL standard compatible
|
||||
*/
|
||||
protocol->store("CURRENT_TIMESTAMP", system_charset_info);
|
||||
}
|
||||
@ -1213,7 +1213,7 @@ mysqld_dump_create_info(THD *thd, TABLE *table, int fd)
|
||||
|
||||
/*
|
||||
Go through all character combinations and ensure that sql_lex.cc can
|
||||
parse it as an identifer.
|
||||
parse it as an identifier.
|
||||
|
||||
SYNOPSIS
|
||||
require_quotes()
|
||||
|
@ -72,7 +72,7 @@ static bool check_fields(THD *thd, List<Item> &items)
|
||||
{
|
||||
if (!(field= item->filed_for_view_update()))
|
||||
{
|
||||
/* as far as item comes from VIEW select list it has name */
|
||||
/* item has name, because it comes from VIEW SELECT list */
|
||||
my_error(ER_NONUPDATEABLE_COLUMN, MYF(0), item->name);
|
||||
return TRUE;
|
||||
}
|
||||
@ -626,8 +626,9 @@ int mysql_multi_update_prepare(THD *thd)
|
||||
}
|
||||
|
||||
/*
|
||||
setup_tables() need for VIEWs. JOIN::prepare() will not do it second
|
||||
time.
|
||||
setup_tables() need for VIEWs. JOIN::prepare() will call setup_tables()
|
||||
second time, but this call will do nothing (there are check for second
|
||||
call in setup_tables()).
|
||||
*/
|
||||
if ((thd->lex->select_lex.no_wrap_view_item= 1,
|
||||
res= setup_fields(thd, 0, table_list, *fields, 1, 0, 0),
|
||||
|
@ -80,6 +80,18 @@ int mysql_create_view(THD *thd,
|
||||
}
|
||||
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
/*
|
||||
Privilege check for view creation:
|
||||
- user have CREATE VIEW privilege on view table
|
||||
- have some (SELECT/UPDATE/INSERT/DELETE) privileges on columns of
|
||||
underlying tables used on top of SELECT list (because it can be
|
||||
(theoretically) updated, so it is enough to have UPDATE privilege on
|
||||
them, for example)
|
||||
- have SELECT privilege on columns used in expressions of VIEW select
|
||||
- for columns of underly tables used on top of SELECT list also will be
|
||||
checked that we have not more privileges on correspondent column of view
|
||||
table (i.e. user will not get some privileges by view creation)
|
||||
*/
|
||||
if (check_access(thd, CREATE_VIEW_ACL, view->db, &view->grant.privilege,
|
||||
0, 0) ||
|
||||
grant_option && check_grant(thd, CREATE_VIEW_ACL, view, 0, 1, 0))
|
||||
@ -89,7 +101,7 @@ int mysql_create_view(THD *thd,
|
||||
for (tbl= sl->get_table_list(); tbl; tbl= tbl->next_local)
|
||||
{
|
||||
/*
|
||||
Ensure that we have some privilage on this table, more strict check
|
||||
Ensure that we have some privileges on this table, more strict check
|
||||
will be done on column level after preparation,
|
||||
*/
|
||||
if (check_some_access(thd, VIEW_ANY_ACL, tbl))
|
||||
@ -103,16 +115,20 @@ int mysql_create_view(THD *thd,
|
||||
tbl->real_name);
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
/* mark this table as table which will be checked after preparation */
|
||||
/*
|
||||
Mark this table as a table which will be checked after the prepare
|
||||
phase
|
||||
*/
|
||||
tbl->table_in_first_from_clause= 1;
|
||||
|
||||
/*
|
||||
We need to check only SELECT_ACL for all normal fields, fields
|
||||
where we need any privilege will be marked later
|
||||
We need to check only SELECT_ACL for all normal fields, fields for
|
||||
which we need "any" (SELECT/UPDATE/INSERT/DELETE) privilege will be
|
||||
checked later
|
||||
*/
|
||||
tbl->grant.want_privilege= SELECT_ACL;
|
||||
/*
|
||||
Make sure that all rights are loaded to table 'grant' field.
|
||||
Make sure that all rights are loaded to the TABLE::grant field.
|
||||
|
||||
tbl->real_name will be correct name of table because VIEWs are
|
||||
not opened yet.
|
||||
@ -140,7 +156,7 @@ int mysql_create_view(THD *thd,
|
||||
}
|
||||
}
|
||||
/*
|
||||
Mark fields for special privilege check (any privilege)
|
||||
Mark fields for special privilege check ("any" privilege)
|
||||
*/
|
||||
for (sl= select_lex; sl; sl= sl->next_select())
|
||||
{
|
||||
@ -169,14 +185,14 @@ int mysql_create_view(THD *thd,
|
||||
}
|
||||
|
||||
/*
|
||||
Copy privileges of underlaying VIEWs which was filled by
|
||||
Copy the privileges of the underlying VIEWs which were filled by
|
||||
fill_effective_table_privileges
|
||||
(they was not copied in derived tables processing)
|
||||
(they were not copied at derived tables processing)
|
||||
*/
|
||||
tbl->table->grant.privilege= tbl->grant.privilege;
|
||||
}
|
||||
|
||||
// prepare select to resolve all fields
|
||||
/* prepare select to resolve all fields */
|
||||
lex->view_prepare_mode= 1;
|
||||
if (unit->prepare(thd, 0, 0))
|
||||
{
|
||||
@ -227,7 +243,7 @@ int mysql_create_view(THD *thd,
|
||||
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
/*
|
||||
Compare/check grants on view with grants of underlaying tables
|
||||
Compare/check grants on view with grants of underlying tables
|
||||
*/
|
||||
for (sl= select_lex; sl; sl= sl->next_select())
|
||||
{
|
||||
@ -245,7 +261,7 @@ int mysql_create_view(THD *thd,
|
||||
if ((fld= item->filed_for_view_update()))
|
||||
{
|
||||
/*
|
||||
Do we have more privilegeson view field then underlying table field
|
||||
Do we have more privileges on view field then underlying table field?
|
||||
*/
|
||||
if ((~fld->have_privileges & priv))
|
||||
{
|
||||
@ -354,7 +370,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
|
||||
LEX_STRING dir, file;
|
||||
DBUG_ENTER("mysql_register_view");
|
||||
|
||||
// print query
|
||||
/* print query */
|
||||
str.length(0);
|
||||
{
|
||||
ulong sql_mode= thd->variables.sql_mode & MODE_ANSI_QUOTES;
|
||||
@ -365,7 +381,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
|
||||
str.append('\0');
|
||||
DBUG_PRINT("VIEW", ("View: %s", str.ptr()));
|
||||
|
||||
// print file name
|
||||
/* print file name */
|
||||
(void) my_snprintf(dir_buff, FN_REFLEN, "%s/%s/",
|
||||
mysql_data_home, view->db);
|
||||
unpack_filename(dir_buff, dir_buff);
|
||||
@ -379,7 +395,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
|
||||
if (!view->timestamp.str)
|
||||
view->timestamp.str= view->timestamp_buffer;
|
||||
|
||||
// check old .frm
|
||||
/* check old .frm */
|
||||
{
|
||||
char path_buff[FN_REFLEN];
|
||||
LEX_STRING path;
|
||||
@ -411,7 +427,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
|
||||
/*
|
||||
read revision number
|
||||
|
||||
TODO: read dependense list, too, to process cascade/restrict
|
||||
TODO: read dependence list, too, to process cascade/restrict
|
||||
TODO: special cascade/restrict procedure for alter?
|
||||
*/
|
||||
if (parser->parse((gptr)view, &thd->mem_root,
|
||||
@ -429,7 +445,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
|
||||
}
|
||||
}
|
||||
}
|
||||
// fill structure
|
||||
/* fill structure */
|
||||
view->query.str= (char*)str.ptr();
|
||||
view->query.length= str.length()-1; // we do not need last \0
|
||||
view->source.str= thd->query;
|
||||
@ -451,7 +467,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
|
||||
if ((view->updatable_view= (can_be_merged &&
|
||||
view->algorithm != VIEW_ALGORITHM_TMPTABLE)))
|
||||
{
|
||||
// TODO: change here when we will support UNIONs
|
||||
/* TODO: change here when we will support UNIONs */
|
||||
for (TABLE_LIST *tbl= (TABLE_LIST *)thd->lex->select_lex.table_list.first;
|
||||
tbl;
|
||||
tbl= tbl->next_local)
|
||||
@ -500,7 +516,6 @@ loop_out:
|
||||
RETURN
|
||||
0 ok
|
||||
1 error
|
||||
|
||||
*/
|
||||
|
||||
my_bool
|
||||
@ -644,7 +659,7 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)
|
||||
|
||||
/*
|
||||
check rights to run commands (EXPLAIN SELECT & SHOW CREATE) which show
|
||||
underlaying tables
|
||||
underlying tables
|
||||
*/
|
||||
if ((old_lex->sql_command == SQLCOM_SELECT && old_lex->describe))
|
||||
{
|
||||
@ -694,7 +709,7 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)
|
||||
/*
|
||||
check MERGE algorithm ability
|
||||
- algorithm is not explicit TEMPORARY TABLE
|
||||
- VIEW SELECT allow marging
|
||||
- VIEW SELECT allow merging
|
||||
- VIEW used in subquery or command support MERGE algorithm
|
||||
*/
|
||||
if (table->algorithm != VIEW_ALGORITHM_TMPTABLE &&
|
||||
@ -712,9 +727,7 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)
|
||||
|
||||
table->ancestor= view_tables;
|
||||
|
||||
/*
|
||||
next table should include SELECT_LEX under this table SELECT_LEX
|
||||
*/
|
||||
/* next table should include SELECT_LEX under this table SELECT_LEX */
|
||||
table->ancestor->select_lex= table->select_lex;
|
||||
|
||||
/*
|
||||
@ -753,7 +766,7 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)
|
||||
}
|
||||
}
|
||||
|
||||
/* Store WHERE clause for postprocessing in setup_ancestor */
|
||||
/* Store WHERE clause for post-processing in setup_ancestor */
|
||||
table->where= view_select->where;
|
||||
|
||||
/*
|
||||
@ -905,6 +918,13 @@ frm_type_enum mysql_frm_type(char *path)
|
||||
thd thread handler
|
||||
view view for check with opened table
|
||||
|
||||
DESCRIPTION
|
||||
check that undertlaying table of viey contain one of following:
|
||||
1) primary key of underlying table
|
||||
2) unique key underlying table with fields for which NULL value is
|
||||
impossible
|
||||
3) all fields of underlying table
|
||||
|
||||
RETURN
|
||||
FALSE OK
|
||||
TRUE view do not contain key or all fields
|
||||
@ -976,7 +996,7 @@ bool check_key_in_view(THD *thd, TABLE_LIST *view)
|
||||
0 == NO ; Don't give any errors
|
||||
1 == YES ; Give always an error
|
||||
2 == LIMIT1 ; Give an error if this is used with LIMIT 1
|
||||
This is used to protect against gui programs that
|
||||
This is used to protect against GUI programs that
|
||||
uses LIMIT 1 to update just the current row. This
|
||||
doesn't work reliable if the view doesn't have a
|
||||
unique key or if the view doesn't use all fields in
|
||||
|
@ -2423,8 +2423,8 @@ create_select:
|
||||
else if (lex->sql_command == SQLCOM_REPLACE)
|
||||
lex->sql_command= SQLCOM_REPLACE_SELECT;
|
||||
/*
|
||||
following work only with local list, global list is
|
||||
created correctly in this case
|
||||
The following work only with the local list, the global list
|
||||
is created correctly in this case
|
||||
*/
|
||||
lex->current_select->table_list.save_and_clear(&lex->save_list);
|
||||
mysql_init_select(lex);
|
||||
@ -2437,8 +2437,8 @@ create_select:
|
||||
opt_select_from
|
||||
{
|
||||
/*
|
||||
following work only with local list, global list is
|
||||
created correctly in this case
|
||||
The following work only with the local list, the global list
|
||||
is created correctly in this case
|
||||
*/
|
||||
Lex->current_select->table_list.push_front(&Lex->save_list);
|
||||
}
|
||||
|
32
sql/table.cc
32
sql/table.cc
@ -169,7 +169,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
|
||||
outparam->db_record_offset=1;
|
||||
if (db_create_options & HA_OPTION_LONG_BLOB_PTR)
|
||||
outparam->blob_ptr_size=portable_sizeof_char_ptr;
|
||||
/* Set temporaryly a good value for db_low_byte_first */
|
||||
/* Set temporarily a good value for db_low_byte_first */
|
||||
outparam->db_low_byte_first=test(outparam->db_type != DB_TYPE_ISAM);
|
||||
error=4;
|
||||
outparam->max_rows=uint4korr(head+18);
|
||||
@ -710,7 +710,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
|
||||
outparam->blob_field=
|
||||
(Field_blob**) (outparam->field+outparam->fields); // Point at null ptr
|
||||
|
||||
/* The table struct is now initialzed; Open the table */
|
||||
/* The table struct is now initialized; Open the table */
|
||||
error=2;
|
||||
if (db_stat)
|
||||
{
|
||||
@ -759,7 +759,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
|
||||
my_pthread_setspecific_ptr(THR_MALLOC,old_root);
|
||||
frm_error(error,outparam,name,ME_ERROR+ME_WAITTANG);
|
||||
delete outparam->file;
|
||||
outparam->file=0; // For easyer errorchecking
|
||||
outparam->file=0; // For easier errorchecking
|
||||
outparam->db_stat=0;
|
||||
hash_free(&outparam->name_hash);
|
||||
free_root(&outparam->mem_root,MYF(0));
|
||||
@ -788,7 +788,7 @@ int closefrm(register TABLE *table)
|
||||
table->fields=0;
|
||||
}
|
||||
delete table->file;
|
||||
table->file=0; /* For easyer errorchecking */
|
||||
table->file=0; /* For easier errorchecking */
|
||||
hash_free(&table->name_hash);
|
||||
free_root(&table->mem_root,MYF(0));
|
||||
DBUG_RETURN(error);
|
||||
@ -985,7 +985,7 @@ static void frm_error(int error, TABLE *form, const char *name, myf errortype)
|
||||
|
||||
/*
|
||||
** fix a str_type to a array type
|
||||
** typeparts sepearated with some char. differents types are separated
|
||||
** typeparts separated with some char. differents types are separated
|
||||
** with a '\0'
|
||||
*/
|
||||
|
||||
@ -1072,7 +1072,7 @@ static uint find_field(TABLE *form,uint start,uint length)
|
||||
}
|
||||
|
||||
|
||||
/* Check that the integer is in the internvall */
|
||||
/* Check that the integer is in the internal */
|
||||
|
||||
int set_zone(register int nr, int min_zone, int max_zone)
|
||||
{
|
||||
@ -1136,7 +1136,7 @@ void append_unescaped(String *res, const char *pos, uint length)
|
||||
res->append('n');
|
||||
break;
|
||||
case '\r':
|
||||
res->append('\\'); /* This gives better readbility */
|
||||
res->append('\\'); /* This gives better readability */
|
||||
res->append('r');
|
||||
break;
|
||||
case '\\':
|
||||
@ -1555,15 +1555,17 @@ void st_table_list::restore_want_privilege()
|
||||
thd - thread handler
|
||||
conds - condition of this JOIN
|
||||
|
||||
DESCRIPTION
|
||||
It is:
|
||||
- preparing translation table for view columns (fix_fields() for every
|
||||
call and creation for first call)
|
||||
- preparing WHERE, ON and CHECK OPTION condition (fix_fields() for every
|
||||
call and merging for first call).
|
||||
If there are underlying view(s) procedure first will be called for them.
|
||||
|
||||
RETURN
|
||||
0 - OK
|
||||
1 - error
|
||||
|
||||
TODO: for several substituted table last set up table (or maybe subtree,
|
||||
it depends on future join implementation) will contain all fields of VIEW
|
||||
(to be able call fix_fields() for them. All other will looks like empty
|
||||
(without fields) for name resolving, but substituted expressions will
|
||||
return correct used tables mask.
|
||||
*/
|
||||
|
||||
bool st_table_list::setup_ancestor(THD *thd, Item **conds)
|
||||
@ -1700,7 +1702,7 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds)
|
||||
{
|
||||
/*
|
||||
Store WHERE condition to ON expression for outer join, because
|
||||
we can't use WHERE to correctly execute jeft joins on VIEWs and
|
||||
we can't use WHERE to correctly execute left joins on VIEWs and
|
||||
this expression will not be moved to WHERE condition (i.e. will
|
||||
be clean correctly for PS/SP)
|
||||
*/
|
||||
@ -1714,7 +1716,7 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds)
|
||||
{
|
||||
/*
|
||||
Store WHERE condition to ON expression for outer join, because
|
||||
we can't use WHERE to correctly execute jeft joins on VIEWs and
|
||||
we can't use WHERE to correctly execute left joins on VIEWs and
|
||||
this expression will not be moved to WHERE condition (i.e. will
|
||||
be clean correctly for PS/SP)
|
||||
*/
|
||||
|
14
sql/table.h
14
sql/table.h
@ -34,7 +34,7 @@ typedef struct st_order {
|
||||
bool asc; /* true if ascending */
|
||||
bool free_me; /* true if item isn't shared */
|
||||
bool in_field_list; /* true if in select field list */
|
||||
bool counter_used; /* parapeter was counter of columns */
|
||||
bool counter_used; /* parameter was counter of columns */
|
||||
Field *field; /* If tmp-table group */
|
||||
char *buff; /* If tmp-table group */
|
||||
table_map used,depend_map;
|
||||
@ -116,7 +116,7 @@ struct st_table {
|
||||
These two members hold offset in record + 1 for TIMESTAMP field
|
||||
with NOW() as default value or/and with ON UPDATE NOW() option.
|
||||
If 0 then such field is absent in this table or auto-set for default
|
||||
or/and on update should be temporaly disabled for some reason.
|
||||
or/and on update should be temporally disabled for some reason.
|
||||
These values is setup to offset value for each statement in open_table()
|
||||
and turned off in statement processing code (see mysql_update as example).
|
||||
*/
|
||||
@ -244,10 +244,10 @@ typedef struct st_table_list
|
||||
Item *where; /* VIEW WHERE clause condition */
|
||||
Item *check_option; /* WITH CHECK OPTION condition */
|
||||
LEX_STRING query; /* text of (CRETE/SELECT) statement */
|
||||
LEX_STRING md5; /* md5 of query tesxt */
|
||||
LEX_STRING md5; /* md5 of query text */
|
||||
LEX_STRING source; /* source of CREATE VIEW */
|
||||
LEX_STRING view_db; /* save view database */
|
||||
LEX_STRING view_name; /* save view name */
|
||||
LEX_STRING view_db; /* saved view database */
|
||||
LEX_STRING view_name; /* saved view name */
|
||||
LEX_STRING timestamp; /* GMT time stamp of last operation */
|
||||
ulonglong file_version; /* version of file's field set */
|
||||
ulonglong updatable_view; /* VIEW can be updated */
|
||||
@ -273,11 +273,11 @@ typedef struct st_table_list
|
||||
st_table_list *embedding; /* nested join containing the table */
|
||||
List<struct st_table_list> *join_list;/* join list the table belongs to */
|
||||
bool cacheable_table; /* stop PS caching */
|
||||
/* used in multi-upd/views privelege check */
|
||||
/* used in multi-upd/views privilege check */
|
||||
bool table_in_first_from_clause;
|
||||
bool skip_temporary; /* this table shouldn't be temporary */
|
||||
bool setup_is_done; /* setup_tables() is done */
|
||||
/* do view contain auto_increment field */
|
||||
/* TRUE if this merged view contain auto_increment field */
|
||||
bool contain_auto_increment;
|
||||
/* FRMTYPE_ERROR if any type is acceptable */
|
||||
enum frm_type_enum required_type;
|
||||
|
Loading…
x
Reference in New Issue
Block a user