mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
VIEW
two TABLE_LIST copy eliminated include/mysqld_error.h: errors of view libmysqld/Makefile.am: new view file mysql-test/r/connect.result: SHOW TABLE show type of table mysql-test/r/ctype_recoding.result: SHOW TABLE show type of table mysql-test/r/drop.result: SHOW TABLE show type of table mysql-test/r/grant.result: new two privileges (CRETEA|SHOW VIEW) mysql-test/r/lowercase_table.result: SHOW TABLE show type of table mysql-test/r/ps_1general.result: SHOW TABLE show type of table mysql-test/r/rename.result: SHOW TABLE show type of table mysql-test/r/rpl000009.result: SHOW TABLE show type of table mysql-test/r/rpl_error_ignored_table.result: SHOW TABLE show type of table mysql-test/r/select.result: SHOW TABLE show type of table mysql-test/r/system_mysql_db.result: SHOW TABLE show type of table new two privileges (CRETEA|SHOW VIEW) mysql-test/t/system_mysql_db_fix.test: removing all system tables scripts/mysql_fix_privilege_tables.sql: new two privileges (CRETEA|SHOW VIEW) sql/Makefile.am: new VIEW related file sql/ha_myisammrg.cc: two TABLE_LIST copy eliminated sql/item.cc: VIEW sql/item.h: VIEW sql/item_subselect.cc: VIEW sql/item_subselect.h: VIEW sql/lex.h: VIEW sql/lock.cc: VIEW sql/mysql_priv.h: VIEW sql/mysqld.cc: VIEW new parameter - sql_updatable_view_key sql/opt_sum.cc: two TABLE_LIST copy eliminated sql/set_var.cc: new parameter - sql_updatable_view_key sql/share/czech/errmsg.txt: errors messages of views sql/share/danish/errmsg.txt: errors messages of views sql/share/dutch/errmsg.txt: errors messages of views sql/share/english/errmsg.txt: errors messages of views sql/share/estonian/errmsg.txt: errors messages of views sql/share/french/errmsg.txt: errors messages of views sql/share/german/errmsg.txt: errors messages of views sql/share/greek/errmsg.txt: errors messages of views sql/share/hungarian/errmsg.txt: errors messages of views sql/share/italian/errmsg.txt: errors messages of views sql/share/japanese/errmsg.txt: errors messages of views sql/share/korean/errmsg.txt: errors messages of views sql/share/norwegian-ny/errmsg.txt: errors messages of views sql/share/norwegian/errmsg.txt: errors messages of views sql/share/polish/errmsg.txt: errors messages of views sql/share/portuguese/errmsg.txt: errors messages of views sql/share/romanian/errmsg.txt: errors messages of views sql/share/russian/errmsg.txt: errors messages of views sql/share/serbian/errmsg.txt: errors messages of views sql/share/slovak/errmsg.txt: errors messages of views sql/share/spanish/errmsg.txt: errors messages of views sql/share/swedish/errmsg.txt: errors messages of views sql/share/ukrainian/errmsg.txt: errors messages of views sql/slave.cc: two TABLE_LIST copy eliminated sql/sp.cc: VIEW sql/sql_acl.cc: VIEW sql/sql_acl.h: VIEW sql/sql_base.cc: VIEW sql/sql_cache.cc: two TABLE_LIST copy eliminated sql/sql_class.h: VIEW sql/sql_db.cc: two TABLE_LIST copy eliminated sql/sql_delete.cc: VIEW sql/sql_derived.cc: VIEW sql/sql_handler.cc: two TABLE_LIST copy eliminated sql/sql_help.cc: two TABLE_LIST copy eliminated sql/sql_insert.cc: VIEW sql/sql_lex.cc: VIEW sql/sql_lex.h: VIEW sql/sql_load.cc: VIEW sql/sql_olap.cc: VIEW sql/sql_parse.cc: two TABLE_LIST copy eliminated VIEW sql/sql_prepare.cc: VIEW sql/sql_rename.cc: two TABLE_LIST copy eliminated sql/sql_select.cc: VIEW sql/sql_show.cc: VIEW sql/sql_table.cc: VIEW sql/sql_union.cc: VIEW sql/sql_update.cc: VIEW sql/sql_yacc.yy: VIEW sql/table.cc: VIEW sql/table.h: VIEW sql/tztime.cc: two TABLE_LIST copy eliminated sql/unireg.h: VIEW tests/client_test.c: VIEW
This commit is contained in:
236
sql/table.cc
236
sql/table.cc
@ -20,7 +20,8 @@
|
||||
#include "mysql_priv.h"
|
||||
#include <errno.h>
|
||||
#include <m_ctype.h>
|
||||
|
||||
#include "md5.h"
|
||||
#include "sql_acl.h"
|
||||
|
||||
/* Functions defined in this file */
|
||||
|
||||
@ -57,6 +58,7 @@ static byte* get_field_name(Field **buff,uint *length,
|
||||
2 Error (see frm_error)
|
||||
3 Wrong data in .frm file
|
||||
4 Error (see frm_error)
|
||||
5 It is new format of .frm file
|
||||
*/
|
||||
|
||||
int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
|
||||
@ -81,17 +83,46 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
|
||||
uchar *null_pos;
|
||||
uint null_bit, new_frm_ver, field_pack_length;
|
||||
SQL_CRYPT *crypted=0;
|
||||
MEM_ROOT *old_root;
|
||||
DBUG_ENTER("openfrm");
|
||||
DBUG_PRINT("enter",("name: '%s' form: %lx",name,outparam));
|
||||
|
||||
error=1;
|
||||
|
||||
if ((file=my_open(fn_format(index_file, name, "", reg_ext,
|
||||
MY_UNPACK_FILENAME),
|
||||
O_RDONLY | O_SHARE,
|
||||
MYF(0)))
|
||||
< 0)
|
||||
{
|
||||
goto err_w_init;
|
||||
}
|
||||
|
||||
if (my_read(file,(byte*) head,64,MYF(MY_NABP)))
|
||||
{
|
||||
goto err_w_init;
|
||||
}
|
||||
|
||||
if (memcmp(head, "TYPE=", 5) == 0)
|
||||
{
|
||||
// new .frm
|
||||
my_close(file,MYF(MY_WME));
|
||||
|
||||
if (db_stat & NO_ERR_ON_NEW_FRM)
|
||||
DBUG_RETURN(5);
|
||||
|
||||
// caller can't process new .frm
|
||||
error= 4;
|
||||
goto err_w_init;
|
||||
}
|
||||
|
||||
bzero((char*) outparam,sizeof(*outparam));
|
||||
outparam->blob_ptr_size=sizeof(char*);
|
||||
disk_buff=NULL; record= NULL; keynames=NullS;
|
||||
outparam->db_stat = db_stat;
|
||||
error=1;
|
||||
|
||||
init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
|
||||
MEM_ROOT *old_root=my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC);
|
||||
old_root= my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC);
|
||||
my_pthread_setspecific_ptr(THR_MALLOC,&outparam->mem_root);
|
||||
|
||||
outparam->real_name=strdup_root(&outparam->mem_root,
|
||||
@ -101,19 +132,11 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
|
||||
if (!outparam->real_name || !outparam->table_name)
|
||||
goto err_end;
|
||||
|
||||
if ((file=my_open(fn_format(index_file,name,"",reg_ext,MY_UNPACK_FILENAME),
|
||||
O_RDONLY | O_SHARE,
|
||||
MYF(0)))
|
||||
< 0)
|
||||
{
|
||||
goto err_end; /* purecov: inspected */
|
||||
}
|
||||
error=4;
|
||||
if (!(outparam->path= strdup_root(&outparam->mem_root,name)))
|
||||
goto err_not_open;
|
||||
*fn_ext(outparam->path)='\0'; // Remove extension
|
||||
|
||||
if (my_read(file,(byte*) head,64,MYF(MY_NABP))) goto err_not_open;
|
||||
if (head[0] != (uchar) 254 || head[1] != 1 ||
|
||||
(head[2] != FRM_VER && head[2] != FRM_VER+1 && head[2] != FRM_VER+3))
|
||||
goto err_not_open; /* purecov: inspected */
|
||||
@ -718,6 +741,13 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
|
||||
#endif
|
||||
DBUG_RETURN (0);
|
||||
|
||||
err_w_init:
|
||||
//awoid problem with uninitialized data
|
||||
bzero((char*) outparam,sizeof(*outparam));
|
||||
outparam->real_name= (char*)name+dirname_length(name);
|
||||
old_root= my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC);
|
||||
disk_buff= 0;
|
||||
|
||||
err_not_open:
|
||||
x_free((gptr) disk_buff);
|
||||
if (file > 0)
|
||||
@ -1410,6 +1440,190 @@ db_type get_table_type(const char *name)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
calculate md5 of query
|
||||
|
||||
SYNOPSIS
|
||||
st_table_list::calc_md5()
|
||||
buffer buffer for md5 writing
|
||||
*/
|
||||
void st_table_list::calc_md5(char *buffer)
|
||||
{
|
||||
my_MD5_CTX context;
|
||||
unsigned char digest[16];
|
||||
my_MD5Init (&context);
|
||||
my_MD5Update (&context,(unsigned char *) query.str, query.length);
|
||||
my_MD5Final (digest, &context);
|
||||
sprintf((char *) buffer,
|
||||
"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
|
||||
digest[0], digest[1], digest[2], digest[3],
|
||||
digest[4], digest[5], digest[6], digest[7],
|
||||
digest[8], digest[9], digest[10], digest[11],
|
||||
digest[12], digest[13], digest[14], digest[15]);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
set ancestor TABLE for table place holder of VIEW
|
||||
|
||||
SYNOPSIS
|
||||
st_table_list::set_ancestor()
|
||||
*/
|
||||
void st_table_list::set_ancestor()
|
||||
{
|
||||
if (ancestor->ancestor)
|
||||
ancestor->set_ancestor();
|
||||
table= ancestor->table;
|
||||
ancestor->table->grant= grant;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
setup fields of placeholder of merged VIEW
|
||||
|
||||
SYNOPSIS
|
||||
st_table_list::setup_ancestor()
|
||||
thd - thread handler
|
||||
conds - condition of this JOIN
|
||||
|
||||
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)
|
||||
{
|
||||
Item **transl;
|
||||
SELECT_LEX *select= &view->select_lex;
|
||||
Item *item;
|
||||
List_iterator_fast<Item> it(select->item_list);
|
||||
uint i= 0;
|
||||
bool save_set_query_id= thd->set_query_id;
|
||||
DBUG_ENTER("st_table_list::setup_ancestor");
|
||||
|
||||
if (ancestor->ancestor &&
|
||||
ancestor->setup_ancestor(thd, conds))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
if (field_translation)
|
||||
{
|
||||
thd->set_query_id= 1;
|
||||
/* this view was prepared already on previous PS/SP execution */
|
||||
Item **end= field_translation + select->item_list.elements;
|
||||
for (Item **i= field_translation; i < end; i++)
|
||||
{
|
||||
//TODO: fix for several tables in VIEW
|
||||
uint want_privilege= ancestor->table->grant.want_privilege;
|
||||
/* real rights will be checked in VIEW field */
|
||||
ancestor->table->grant.want_privilege= 0;
|
||||
if (!(*i)->fixed && (*i)->fix_fields(thd, ancestor, i))
|
||||
goto err;
|
||||
ancestor->table->grant.want_privilege= want_privilege;
|
||||
}
|
||||
goto ok;
|
||||
}
|
||||
|
||||
/* view fields translation table */
|
||||
if (!(transl=
|
||||
(Item**)(thd->current_arena ?
|
||||
thd->current_arena :
|
||||
thd)->alloc(select->item_list.elements * sizeof(Item*))))
|
||||
{
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
/*
|
||||
Resolve all view items against ancestor table.
|
||||
|
||||
TODO: do it only for real used fields "on demand" to mark really
|
||||
used fields correctly.
|
||||
*/
|
||||
thd->set_query_id= 1;
|
||||
while ((item= it++))
|
||||
{
|
||||
//TODO: fix for several tables in VIEW
|
||||
uint want_privilege= ancestor->table->grant.want_privilege;
|
||||
/* real rights will be checked in VIEW field */
|
||||
ancestor->table->grant.want_privilege= 0;
|
||||
if (!item->fixed && item->fix_fields(thd, ancestor, &item))
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
ancestor->table->grant.want_privilege= want_privilege;
|
||||
transl[i++]= item;
|
||||
}
|
||||
field_translation= transl;
|
||||
//TODO: sort this list? Use hash for big number of fields
|
||||
|
||||
if (where)
|
||||
{
|
||||
Item_arena *arena= thd->current_arena, backup;
|
||||
if (!where->fixed && where->fix_fields(thd, ancestor, &where))
|
||||
goto err;
|
||||
|
||||
if (arena)
|
||||
thd->set_n_backup_item_arena(arena, &backup);
|
||||
if (outer_join)
|
||||
{
|
||||
/*
|
||||
Store WHERE condition to ON expression for outer join, because we
|
||||
can't use WHERE to correctly execute jeft joins on VIEWs and this
|
||||
expression will not be moved to WHERE condition (i.e. will be clean
|
||||
correctly for PS/SP)
|
||||
*/
|
||||
on_expr= and_conds(on_expr, where);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
It is conds of JOIN, but it will be stored in st_select_lex::prep_where
|
||||
for next reexecution
|
||||
*/
|
||||
*conds= and_conds(*conds, where);
|
||||
}
|
||||
if (arena)
|
||||
thd->restore_backup_item_arena(arena, &backup);
|
||||
}
|
||||
|
||||
ok:
|
||||
thd->set_query_id= save_set_query_id;
|
||||
DBUG_RETURN(0);
|
||||
|
||||
err:
|
||||
thd->set_query_id= save_set_query_id;
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
|
||||
void Field_iterator_view::set(TABLE_LIST *table)
|
||||
{
|
||||
ptr= table->field_translation;
|
||||
array_end= ptr + table->view->select_lex.item_list.elements;
|
||||
}
|
||||
|
||||
|
||||
const char *Field_iterator_table::name()
|
||||
{
|
||||
return (*ptr)->field_name;
|
||||
}
|
||||
|
||||
|
||||
Item *Field_iterator_table::item(THD *thd)
|
||||
{
|
||||
return new Item_field(thd, *ptr);
|
||||
}
|
||||
|
||||
|
||||
const char *Field_iterator_view::name()
|
||||
{
|
||||
return (*ptr)->name;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Instansiate templates
|
||||
*****************************************************************************/
|
||||
|
Reference in New Issue
Block a user