1
0
mirror of https://github.com/MariaDB/server.git synced 2025-12-04 17:23:46 +03:00

Merge sanja.is.com.ua:/home/bell/mysql/bk/mysql-5.0

into sanja.is.com.ua:/home/bell/mysql/bk/work-5.0
This commit is contained in:
unknown
2004-08-25 09:04:06 +03:00
12 changed files with 298 additions and 100 deletions

View File

@@ -669,6 +669,17 @@ public:
};
class Item_static_int_func :public Item_int
{
const char *func_name;
public:
Item_static_int_func(const char *str_arg, longlong i, uint length)
:Item_int(NullS, i, length), func_name(str_arg)
{}
void print(String *str) { str->append(func_name); }
};
class Item_uint :public Item_int
{
public:
@@ -724,6 +735,18 @@ public:
};
class Item_static_real_func :public Item_real
{
const char *func_name;
public:
Item_static_real_func(const char *str, double val_arg, uint decimal_par,
uint length)
:Item_real(NullS, val_arg, decimal_par, length), func_name(str)
{}
void print(String *str) { str->append(func_name); }
};
class Item_float :public Item_real
{
public:
@@ -803,6 +826,20 @@ public:
void cleanup() {}
};
class Item_static_string_func :public Item_string
{
const char *func_name;
public:
Item_static_string_func(const char *name_par, const char *str, uint length,
CHARSET_INFO *cs,
Derivation dv= DERIVATION_COERCIBLE)
:Item_string(NullS, str, length, cs, dv), func_name(name_par)
{}
void print(String *str) { str->append(func_name); }
};
/* for show tables */
class Item_datetime :public Item_string

View File

@@ -73,12 +73,13 @@ Item *create_func_connection_id(void)
{
THD *thd=current_thd;
thd->lex->safe_to_cache_query= 0;
return new Item_int(NullS,(longlong)
((thd->slave_thread) ?
thd->variables.pseudo_thread_id :
thd->thread_id),
10);
}
return new Item_static_int_func("connection_id()",
(longlong)
((thd->slave_thread) ?
thd->variables.pseudo_thread_id :
thd->thread_id),
10);
}
Item *create_func_conv(Item* a, Item *b, Item *c)
{
@@ -293,7 +294,7 @@ Item *create_func_period_diff(Item* a, Item *b)
Item *create_func_pi(void)
{
return new Item_real("pi()",M_PI,6,8);
return new Item_static_real_func("pi()", M_PI, 6, 8);
}
Item *create_func_pow(Item* a, Item *b)
@@ -309,8 +310,9 @@ Item *create_func_current_user()
length= (uint) (strxmov(buff, thd->priv_user, "@", thd->priv_host, NullS) -
buff);
return new Item_string(NullS, thd->memdup(buff, length), length,
system_charset_info);
return new Item_static_string_func("current_user()",
thd->memdup(buff, length), length,
system_charset_info);
}
Item *create_func_radians(Item *a)
@@ -434,7 +436,7 @@ Item *create_func_uuid(void)
Item *create_func_version(void)
{
return new Item_string(NullS,server_version,
return new Item_static_string_func("version()", server_version,
(uint) strlen(server_version),
system_charset_info, DERIVATION_IMPLICIT);
}

View File

@@ -38,6 +38,7 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
static void free_cache_entry(TABLE *entry);
static void mysql_rm_tmp_tables(void);
static my_bool open_new_frm(const char *path, const char *alias,
const char *db, const char *table_name,
uint db_stat, uint prgflag,
uint ha_open_flags, TABLE *outparam,
TABLE_LIST *table_desc, MEM_ROOT *mem_root);
@@ -1379,8 +1380,6 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
{
char path[FN_REFLEN];
int error;
// we support new format only is have all parameters for it
uint new_frm_flag= (table_desc && mem_root) ? NO_ERR_ON_NEW_FRM : 0;
uint discover_retry_count= 0;
DBUG_ENTER("open_unireg_entry");
@@ -1388,12 +1387,12 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
while ((error= openfrm(path, alias,
(uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
HA_GET_INDEX | HA_TRY_READ_ONLY |
new_frm_flag),
NO_ERR_ON_NEW_FRM),
READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD,
thd->open_options, entry)) &&
(error != 5 ||
fn_format(path, path, 0, reg_ext, MY_UNPACK_FILENAME),
open_new_frm(path, alias,
open_new_frm(path, alias, db, name,
(uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
HA_GET_INDEX | HA_TRY_READ_ONLY),
READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD,
@@ -1679,6 +1678,8 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type)
thd->proc_info="Opening table";
thd->current_tablenr= 0;
/* open_ltable can be used only for BASIC TABLEs */
table_list->required_type= FRMTYPE_TABLE;
while (!(table= open_table(thd, table_list, 0, &refresh)) && refresh) ;
if (table)
@@ -3209,6 +3210,8 @@ int init_ftfuncs(THD *thd, SELECT_LEX *select_lex, bool no_order)
open_new_frm()
path path to .frm
alias alias for table
db database
table_name name of table
db_stat open flags (for example HA_OPEN_KEYFILE|HA_OPEN_RNDFILE..)
can be 0 (example in ha_example_table)
prgflag READ_ALL etc..
@@ -3218,7 +3221,9 @@ int init_ftfuncs(THD *thd, SELECT_LEX *select_lex, bool no_order)
mem_root temporary MEM_ROOT for parsing
*/
static my_bool
open_new_frm(const char *path, const char *alias, uint db_stat, uint prgflag,
open_new_frm(const char *path, const char *alias,
const char *db, const char *table_name,
uint db_stat, uint prgflag,
uint ha_open_flags, TABLE *outparam, TABLE_LIST *table_desc,
MEM_ROOT *mem_root)
{
@@ -3226,28 +3231,36 @@ open_new_frm(const char *path, const char *alias, uint db_stat, uint prgflag,
LEX_STRING pathstr;
pathstr.str= (char *)path;
pathstr.length= strlen(path);
if (!mem_root)
mem_root= &current_thd->mem_root;
File_parser *parser= sql_parse_prepare(&pathstr, mem_root, 1);
if (parser)
{
if (!strncmp("VIEW", parser->type()->str, parser->type()->length))
{
if (mysql_make_view(parser, table_desc))
if (table_desc == 0 || table_desc->required_type == FRMTYPE_TABLE)
{
bzero(outparam, sizeof(*outparam)); // do not run repair
DBUG_RETURN(1);
my_error(ER_WRONG_OBJECT, MYF(0), db, table_name, "BASE TABLE");
goto err;
}
if (mysql_make_view(parser, table_desc))
goto err;
}
else
{
/* only VIEWs are supported now */
my_error(ER_FRM_UNKNOWN_TYPE, MYF(0), path, parser->type()->str);
bzero(outparam, sizeof(outparam)); // do not run repair
DBUG_RETURN(1);
goto err;
}
}
else
{
DBUG_RETURN(1);
}
goto err;
DBUG_RETURN(0);
err:
bzero(outparam, sizeof(TABLE)); // do not run repair
DBUG_RETURN(1);
}

View File

@@ -1546,7 +1546,7 @@ bool st_lex::can_be_merged()
}
/*
check if command can use VIEW with MERGE algorithm
check if command can use VIEW with MERGE algorithm (for top VIEWs)
SYNOPSIS
st_lex::can_use_merged()
@@ -1576,6 +1576,29 @@ bool st_lex::can_use_merged()
}
}
/*
check if command can't use merged views in any part of command
SYNOPSIS
st_lex::can_not_use_merged()
RETURN
FALSE - command can't use merged VIEWs
TRUE - VIEWs with MERGE algorithms can be used
*/
bool st_lex::can_not_use_merged()
{
switch (sql_command)
{
case SQLCOM_CREATE_VIEW:
case SQLCOM_SHOW_CREATE:
return TRUE;
default:
return FALSE;
}
}
/*
Detect that we need only table structure of derived table/view

View File

@@ -749,6 +749,7 @@ typedef struct st_lex
bool can_be_merged();
bool can_use_merged();
bool can_not_use_merged();
bool only_view_structure();
} LEX;

View File

@@ -1575,9 +1575,9 @@ view_store_create_info(THD *thd, TABLE_LIST *table, String *buff)
buff->append("MERGE ", 6);
}
buff->append("VIEW ", 5);
buff->append(table->view_db.str, table->view_db.length);
append_identifier(thd, buff, table->view_db.str, table->view_db.length);
buff->append('.');
buff->append(table->view_name.str, table->view_name.length);
append_identifier(thd, buff, table->view_name.str, table->view_name.length);
buff->append(" AS ", 4);
buff->append(table->query.str, table->query.length);
return 0;

View File

@@ -54,7 +54,7 @@ int mysql_create_view(THD *thd,
TABLE_LIST *view= lex->unlink_first_table(&link_to_local);
TABLE_LIST *tables= lex->query_tables;
TABLE_LIST *tbl;
SELECT_LEX *select_lex= &lex->select_lex;
SELECT_LEX *select_lex= &lex->select_lex, *sl;
SELECT_LEX_UNIT *unit= &lex->unit;
int res= 0;
DBUG_ENTER("mysql_create_view");
@@ -74,56 +74,59 @@ int mysql_create_view(THD *thd,
0, 0) ||
grant_option && check_grant(thd, CREATE_VIEW_ACL, view, 0, 1, 0))
DBUG_RETURN(1);
for (tbl= tables; tbl; tbl= tbl->next_local)
for (sl= select_lex; sl; sl= sl->next_select())
{
/*
Ensure that we have some privilage on this table, more strict check
will be done on column level after preparation,
SELECT_ACL will be checked for sure for all fields because it is
listed first (if we have not rights to SELECT from whole table this
right will be written as tbl->grant.want_privilege and will be checked
later (except fields which need any privilege and can be updated).
*/
if ((check_access(thd, SELECT_ACL, tbl->db,
&tbl->grant.privilege, 0, 1) ||
grant_option && check_grant(thd, SELECT_ACL, tbl, 0, 1, 1)) &&
(check_access(thd, INSERT_ACL, tbl->db,
&tbl->grant.privilege, 0, 1) ||
grant_option && check_grant(thd, INSERT_ACL, tbl, 0, 1, 1)) &&
(check_access(thd, DELETE_ACL, tbl->db,
&tbl->grant.privilege, 0, 1) ||
grant_option && check_grant(thd, DELETE_ACL, tbl, 0, 1, 1)) &&
(check_access(thd, UPDATE_ACL, tbl->db,
&tbl->grant.privilege, 0, 1) ||
grant_option && check_grant(thd, UPDATE_ACL, tbl, 0, 1, 1))
)
for (tbl= sl->get_table_list(); tbl; tbl= tbl->next_local)
{
my_printf_error(ER_TABLEACCESS_DENIED_ERROR,
ER(ER_TABLEACCESS_DENIED_ERROR),
MYF(0),
"ANY",
thd->priv_user,
thd->host_or_ip,
tbl->real_name);
DBUG_RETURN(-1);
/*
Ensure that we have some privilage on this table, more strict check
will be done on column level after preparation,
SELECT_ACL will be checked for sure for all fields because it is
listed first (if we have not rights to SELECT from whole table this
right will be written as tbl->grant.want_privilege and will be checked
later (except fields which need any privilege and can be updated).
*/
if ((check_access(thd, SELECT_ACL, tbl->db,
&tbl->grant.privilege, 0, 1) ||
grant_option && check_grant(thd, SELECT_ACL, tbl, 0, 1, 1)) &&
(check_access(thd, INSERT_ACL, tbl->db,
&tbl->grant.privilege, 0, 1) ||
grant_option && check_grant(thd, INSERT_ACL, tbl, 0, 1, 1)) &&
(check_access(thd, DELETE_ACL, tbl->db,
&tbl->grant.privilege, 0, 1) ||
grant_option && check_grant(thd, DELETE_ACL, tbl, 0, 1, 1)) &&
(check_access(thd, UPDATE_ACL, tbl->db,
&tbl->grant.privilege, 0, 1) ||
grant_option && check_grant(thd, UPDATE_ACL, tbl, 0, 1, 1))
)
{
my_printf_error(ER_TABLEACCESS_DENIED_ERROR,
ER(ER_TABLEACCESS_DENIED_ERROR),
MYF(0),
"ANY",
thd->priv_user,
thd->host_or_ip,
tbl->real_name);
DBUG_RETURN(-1);
}
/* mark this table as table which will be checked after preparation */
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 pmarked later
*/
tbl->grant.want_privilege= SELECT_ACL;
/*
Make sure that all rights are loaded to table 'grant' field.
tbl->real_name will be correct name of table because VIEWs are
not opened yet.
*/
fill_effective_table_privileges(thd, &tbl->grant, tbl->db,
tbl->real_name);
}
/* mark this table as table which will be checked after preparation */
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 pmarked later
*/
tbl->grant.want_privilege= SELECT_ACL;
/*
Make sure that all rights are loaded to table 'grant' field.
tbl->real_name will be correct name of table because VIEWs are
not opened yet.
*/
fill_effective_table_privileges(thd, &tbl->grant, tbl->db,
tbl->real_name);
}
if (&lex->select_lex != lex->all_selects_list)
@@ -145,12 +148,10 @@ int mysql_create_view(THD *thd,
}
/*
Mark fields for special privilege check (any privilege)
'if' should be changed if we made updateable UNION.
*/
if (lex->select_lex.next_select() == 0)
for (sl= select_lex; sl; sl= sl->next_select())
{
List_iterator_fast<Item> it(lex->select_lex.item_list);
List_iterator_fast<Item> it(sl->item_list);
Item *item;
while ((item= it++))
{
@@ -235,9 +236,10 @@ int mysql_create_view(THD *thd,
/*
Compare/check grants on view with grants of underlaying tables
*/
for (sl= select_lex; sl; sl= sl->next_select())
{
char *db= view->db ? view->db : thd->db;
List_iterator_fast<Item> it(select_lex->item_list);
List_iterator_fast<Item> it(sl->item_list);
Item *item;
fill_effective_table_privileges(thd, &view->grant, db,
view->real_name);
@@ -657,7 +659,8 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)
if (table->algorithm != VIEW_ALGORITHM_TMEPTABLE &&
lex->can_be_merged() &&
(table->select_lex->master_unit() != &old_lex->unit ||
old_lex->can_use_merged()))
old_lex->can_use_merged()) &&
!old_lex->can_not_use_merged())
{
/*
TODO: support multi tables substitutions
@@ -670,6 +673,7 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)
DBUG_ASSERT(view_table != 0);
table->effective_algorithm= VIEW_ALGORITHM_MERGE;
DBUG_PRINT("info", ("algorithm: MERGE"));
table->updatable= (table->updatable_view != 0);
if (old_next)
@@ -699,6 +703,7 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)
}
table->effective_algorithm= VIEW_ALGORITHM_TMEPTABLE;
DBUG_PRINT("info", ("algorithm: TEMPORARY TABLE"));
lex->select_lex.linkage= DERIVED_TABLE_TYPE;
table->updatable= 0;

View File

@@ -27,13 +27,6 @@ bool check_key_in_view(THD *thd, TABLE_LIST * view);
void insert_view_fields(List<Item> *list, TABLE_LIST *view);
enum frm_type_enum
{
FRMTYPE_ERROR,
FRMTYPE_TABLE,
FRMTYPE_VIEW
};
frm_type_enum mysql_frm_type(char *path);
extern TYPELIB sql_updatable_view_key_typelib;

View File

@@ -1506,6 +1506,7 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds)
uint i= 0;
bool save_set_query_id= thd->set_query_id;
bool save_wrapper= thd->lex->select_lex.no_wrap_view_item;
bool save_allow_sum_func= thd->allow_sum_func;
DBUG_ENTER("st_table_list::setup_ancestor");
if (ancestor->ancestor &&
@@ -1525,6 +1526,8 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds)
uint want_privilege= ancestor->table->grant.want_privilege;
/* real rights will be checked in VIEW field */
ancestor->table->grant.want_privilege= 0;
/* aggregate function are allowed */
thd->allow_sum_func= 1;
if (!(*i)->fixed && (*i)->fix_fields(thd, ancestor, i))
goto err;
ancestor->table->grant.want_privilege= want_privilege;
@@ -1558,6 +1561,8 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds)
uint want_privilege= ancestor->table->grant.want_privilege;
/* real rights will be checked in VIEW field */
ancestor->table->grant.want_privilege= 0;
/* aggregate function are allowed */
thd->allow_sum_func= 1;
if (!item->fixed && item->fix_fields(thd, ancestor, &item))
{
goto err;
@@ -1602,6 +1607,7 @@ ok:
thd->lex->select_lex.no_wrap_view_item= save_wrapper;
thd->lex->current_select= current_select_save;
thd->set_query_id= save_set_query_id;
thd->allow_sum_func= save_allow_sum_func;
DBUG_RETURN(0);
err:
@@ -1614,6 +1620,7 @@ err:
thd->lex->select_lex.no_wrap_view_item= save_wrapper;
thd->lex->current_select= current_select_save;
thd->set_query_id= save_set_query_id;
thd->allow_sum_func= save_allow_sum_func;
DBUG_RETURN(1);
}

View File

@@ -47,6 +47,13 @@ typedef struct st_grant_info
enum tmp_table_type {NO_TMP_TABLE=0, TMP_TABLE=1, TRANSACTIONAL_TMP_TABLE=2};
enum frm_type_enum
{
FRMTYPE_ERROR= 0,
FRMTYPE_TABLE,
FRMTYPE_VIEW
};
typedef struct st_filesort_info
{
IO_CACHE *io_cache; /* If sorted through filebyte */
@@ -241,6 +248,8 @@ typedef struct st_table_list
bool setup_is_done; /* setup_tables() is done */
/* do view contain auto_increment field */
bool contain_auto_increment;
/* FRMTYPE_ERROR if any type is acceptable */
enum frm_type_enum required_type;
char timestamp_buffer[20]; /* buffer for timestamp (19+1) */
void calc_md5(char *buffer);