Commit e66c75ef authored by unknown's avatar unknown

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

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

parents ac06195c 367d882b
...@@ -32,10 +32,10 @@ c ...@@ -32,10 +32,10 @@ c
11 11
show create table v1; show create table v1;
Table Create Table Table Create Table
v1 CREATE VIEW test.v1 AS select (`test`.`t1`.`b` + 1) AS `c` from `test`.`t1` v1 CREATE VIEW `test`.`v1` AS select (`test`.`t1`.`b` + 1) AS `c` from `test`.`t1`
show create view v1; show create view v1;
Table Create Table Table Create Table
v1 CREATE VIEW test.v1 AS select (`test`.`t1`.`b` + 1) AS `c` from `test`.`t1` v1 CREATE VIEW `test`.`v1` AS select (`test`.`t1`.`b` + 1) AS `c` from `test`.`t1`
show create view t1; show create view t1;
ERROR HY000: 'test.t1' is not VIEW ERROR HY000: 'test.t1' is not VIEW
drop table t1; drop table t1;
...@@ -55,7 +55,7 @@ Note 1003 select (`test`.`t1`.`b` + 1) AS `c` from `test`.`v1` ...@@ -55,7 +55,7 @@ Note 1003 select (`test`.`t1`.`b` + 1) AS `c` from `test`.`v1`
create algorithm=temptable view v2 (c) as select b+1 from t1; create algorithm=temptable view v2 (c) as select b+1 from t1;
show create table v2; show create table v2;
Table Create Table Table Create Table
v2 CREATE ALGORITHM=TMPTABLE VIEW test.v2 AS select (`test`.`t1`.`b` + 1) AS `c` from `test`.`t1` v2 CREATE ALGORITHM=TMPTABLE VIEW `test`.`v2` AS select (`test`.`t1`.`b` + 1) AS `c` from `test`.`t1`
select c from v2; select c from v2;
c c
3 3
...@@ -306,14 +306,14 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -306,14 +306,14 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found 1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
show create table mysqltest.v1; show create table mysqltest.v1;
Table Create Table Table Create Table
v1 CREATE VIEW mysqltest.v1 AS select (`mysqltest`.`t1`.`a` + 1) AS `c`,(`mysqltest`.`t1`.`b` + 1) AS `d` from `mysqltest`.`t1` v1 CREATE VIEW `mysqltest`.`v1` AS select (`mysqltest`.`t1`.`a` + 1) AS `c`,(`mysqltest`.`t1`.`b` + 1) AS `d` from `mysqltest`.`t1`
explain select c from mysqltest.v2; explain select c from mysqltest.v2;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> system NULL NULL NULL NULL 0 const row not found 1 PRIMARY <derived2> system NULL NULL NULL NULL 0 const row not found
2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table 2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
show create table mysqltest.v2; show create table mysqltest.v2;
Table Create Table Table Create Table
v2 CREATE ALGORITHM=TMPTABLE VIEW mysqltest.v2 AS select (`mysqltest`.`t1`.`a` + 1) AS `c`,(`mysqltest`.`t1`.`b` + 1) AS `d` from `mysqltest`.`t1` v2 CREATE ALGORITHM=TMPTABLE VIEW `mysqltest`.`v2` AS select (`mysqltest`.`t1`.`a` + 1) AS `c`,(`mysqltest`.`t1`.`b` + 1) AS `d` from `mysqltest`.`t1`
explain select c from mysqltest.v3; explain select c from mysqltest.v3;
ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
show create table mysqltest.v3; show create table mysqltest.v3;
...@@ -328,27 +328,27 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -328,27 +328,27 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found 1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
show create table mysqltest.v1; show create table mysqltest.v1;
Table Create Table Table Create Table
v1 CREATE VIEW mysqltest.v1 AS select (`mysqltest`.`t1`.`a` + 1) AS `c`,(`mysqltest`.`t1`.`b` + 1) AS `d` from `mysqltest`.`t1` v1 CREATE VIEW `mysqltest`.`v1` AS select (`mysqltest`.`t1`.`a` + 1) AS `c`,(`mysqltest`.`t1`.`b` + 1) AS `d` from `mysqltest`.`t1`
explain select c from mysqltest.v2; explain select c from mysqltest.v2;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> system NULL NULL NULL NULL 0 const row not found 1 PRIMARY <derived2> system NULL NULL NULL NULL 0 const row not found
2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table 2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
show create table mysqltest.v2; show create table mysqltest.v2;
Table Create Table Table Create Table
v2 CREATE ALGORITHM=TMPTABLE VIEW mysqltest.v2 AS select (`mysqltest`.`t1`.`a` + 1) AS `c`,(`mysqltest`.`t1`.`b` + 1) AS `d` from `mysqltest`.`t1` v2 CREATE ALGORITHM=TMPTABLE VIEW `mysqltest`.`v2` AS select (`mysqltest`.`t1`.`a` + 1) AS `c`,(`mysqltest`.`t1`.`b` + 1) AS `d` from `mysqltest`.`t1`
explain select c from mysqltest.v3; explain select c from mysqltest.v3;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 system NULL NULL NULL NULL 0 const row not found 1 PRIMARY t2 system NULL NULL NULL NULL 0 const row not found
show create table mysqltest.v3; show create table mysqltest.v3;
Table Create Table Table Create Table
v3 CREATE VIEW mysqltest.v3 AS select (`mysqltest`.`t2`.`a` + 1) AS `c`,(`mysqltest`.`t2`.`b` + 1) AS `d` from `mysqltest`.`t2` v3 CREATE VIEW `mysqltest`.`v3` AS select (`mysqltest`.`t2`.`a` + 1) AS `c`,(`mysqltest`.`t2`.`b` + 1) AS `d` from `mysqltest`.`t2`
explain select c from mysqltest.v4; explain select c from mysqltest.v4;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> system NULL NULL NULL NULL 0 const row not found 1 PRIMARY <derived2> system NULL NULL NULL NULL 0 const row not found
2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table 2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
show create table mysqltest.v4; show create table mysqltest.v4;
Table Create Table Table Create Table
v4 CREATE ALGORITHM=TMPTABLE VIEW mysqltest.v4 AS select (`mysqltest`.`t2`.`a` + 1) AS `c`,(`mysqltest`.`t2`.`b` + 1) AS `d` from `mysqltest`.`t2` v4 CREATE ALGORITHM=TMPTABLE VIEW `mysqltest`.`v4` AS select (`mysqltest`.`t2`.`a` + 1) AS `c`,(`mysqltest`.`t2`.`b` + 1) AS `d` from `mysqltest`.`t2`
revoke all privileges on mysqltest.* from mysqltest_1@localhost; revoke all privileges on mysqltest.* from mysqltest_1@localhost;
delete from mysql.user where user='mysqltest_1'; delete from mysql.user where user='mysqltest_1';
drop database mysqltest; drop database mysqltest;
...@@ -830,7 +830,7 @@ a b c ...@@ -830,7 +830,7 @@ a b c
30 4 -60 30 4 -60
50 6 -100 50 6 -100
40 5 NULL 40 5 NULL
drop table t1; drop table t1, t2;
drop view v1,v2,v3,v4,v5; drop view v1,v2,v3,v4,v5;
create database mysqltest; create database mysqltest;
create table mysqltest.t1 (a int, b int, primary key(a)); create table mysqltest.t1 (a int, b int, primary key(a));
...@@ -946,7 +946,7 @@ create table t1 ("a*b" int); ...@@ -946,7 +946,7 @@ create table t1 ("a*b" int);
create view v1 as select "a*b" from t1; create view v1 as select "a*b" from t1;
show create view v1; show create view v1;
Table Create Table Table Create Table
v1 CREATE VIEW test.v1 AS select `test`.`t1`.`a*b` AS `a*b` from `test`.`t1` v1 CREATE VIEW "test"."v1" AS select `test`.`t1`.`a*b` AS `a*b` from `test`.`t1`
drop view v1; drop view v1;
drop table t1; drop table t1;
set sql_mode=default; set sql_mode=default;
...@@ -1040,10 +1040,60 @@ CREATE VIEW v02 AS SELECT * FROM DUAL; ...@@ -1040,10 +1040,60 @@ CREATE VIEW v02 AS SELECT * FROM DUAL;
ERROR HY000: No tables used ERROR HY000: No tables used
SHOW TABLES; SHOW TABLES;
Tables_in_test table_type Tables_in_test table_type
t2 BASE TABLE
v4 VIEW v4 VIEW
CREATE VIEW v1 AS SELECT EXISTS (SELECT 1 UNION SELECT 2); CREATE VIEW v1 AS SELECT EXISTS (SELECT 1 UNION SELECT 2);
select * from v1; select * from v1;
EXISTS (SELECT 1 UNION SELECT 2) EXISTS (SELECT 1 UNION SELECT 2)
1 1
drop view v1; drop view v1;
create table t1 (col1 int,col2 char(22));
create view v1 as select * from t1;
create index i1 on v1 (col1);
ERROR HY000: 'test.v1' is not BASE TABLE
drop view v1;
drop table t1;
CREATE VIEW v1 (f1,f2,f3,f4) AS SELECT connection_id(), pi(), current_user(), version();
SHOW CREATE VIEW v1;
Table Create Table
v1 CREATE VIEW `test`.`v1` AS select sql_no_cache connection_id() AS `f1`,pi() AS `f2`,current_user() AS `f3`,version() AS `f4`
drop view v1;
create table t1 (s1 int);
create table t2 (s2 int);
insert into t1 values (1), (2);
insert into t2 values (2), (3);
create view v1 as select * from t1,t2 union all select * from t1,t2;
select * from v1;
s1 s2
1 2
2 2
1 3
2 3
1 2
2 2
1 3
2 3
drop view v1;
drop tables t1, t2;
create table t1 (col1 int);
insert into t1 values (1);
create view v1 as select count(*) from t1;
insert into t1 values (null);
select * from v1;
count(*)
2
drop view v1;
drop table t1;
create table t1 (a int);
create table t2 (a int);
create view v1 as select a from t1;
create view v2 as select a from t2 where a in (select a from v1);
show create view v2;
Table Create Table
v2 CREATE VIEW `test`.`v2` AS select `test`.`t2`.`a` AS `a` from `test`.`t2` where `a` in (select `v1`.`a` AS `a` from `test`.`v1`)
drop view v2, v1;
drop table t1, t2;
CREATE VIEW `v 1` AS select 5 AS `5`;
show create view `v 1`;
Table Create Table
v 1 CREATE VIEW `test`.`v 1` AS select 5 AS `5`
drop view `v 1`;
...@@ -693,7 +693,7 @@ insert into v1 select c, b, a from t2; ...@@ -693,7 +693,7 @@ insert into v1 select c, b, a from t2;
insert into v1 (z,y,x) select a+20,b+2,-100 from t2; insert into v1 (z,y,x) select a+20,b+2,-100 from t2;
insert into v2 select b+1, a+10 from t2; insert into v2 select b+1, a+10 from t2;
select * from t1; select * from t1;
drop table t1; drop table t1, t2;
drop view v1,v2,v3,v4,v5; drop view v1,v2,v3,v4,v5;
# #
...@@ -987,3 +987,61 @@ SHOW TABLES; ...@@ -987,3 +987,61 @@ SHOW TABLES;
CREATE VIEW v1 AS SELECT EXISTS (SELECT 1 UNION SELECT 2); CREATE VIEW v1 AS SELECT EXISTS (SELECT 1 UNION SELECT 2);
select * from v1; select * from v1;
drop view v1; drop view v1;
#
# using VIEW where table is required
#
create table t1 (col1 int,col2 char(22));
create view v1 as select * from t1;
-- error 1346
create index i1 on v1 (col1);
drop view v1;
drop table t1;
#
# connection_id(), pi(), current_user(), version() representation test
#
CREATE VIEW v1 (f1,f2,f3,f4) AS SELECT connection_id(), pi(), current_user(), version();
SHOW CREATE VIEW v1;
drop view v1;
#
# VIEW built over UNION
#
create table t1 (s1 int);
create table t2 (s2 int);
insert into t1 values (1), (2);
insert into t2 values (2), (3);
create view v1 as select * from t1,t2 union all select * from t1,t2;
select * from v1;
drop view v1;
drop tables t1, t2;
#
# Aggregate functions in view list
#
create table t1 (col1 int);
insert into t1 values (1);
create view v1 as select count(*) from t1;
insert into t1 values (null);
select * from v1;
drop view v1;
drop table t1;
#
# Showing VIEW with VIEWs in subquery
#
create table t1 (a int);
create table t2 (a int);
create view v1 as select a from t1;
create view v2 as select a from t2 where a in (select a from v1);
show create view v2;
drop view v2, v1;
drop table t1, t2;
#
# SHOW VIEW view with name with spaces
#
CREATE VIEW `v 1` AS select 5 AS `5`;
show create view `v 1`;
drop view `v 1`;
...@@ -669,6 +669,17 @@ class Item_int :public Item_num ...@@ -669,6 +669,17 @@ class Item_int :public Item_num
}; };
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 class Item_uint :public Item_int
{ {
public: public:
...@@ -724,6 +735,18 @@ class Item_real :public Item_num ...@@ -724,6 +735,18 @@ class Item_real :public Item_num
}; };
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 class Item_float :public Item_real
{ {
public: public:
...@@ -803,6 +826,20 @@ class Item_string :public Item ...@@ -803,6 +826,20 @@ class Item_string :public Item
void cleanup() {} 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 */ /* for show tables */
class Item_datetime :public Item_string class Item_datetime :public Item_string
......
...@@ -73,7 +73,8 @@ Item *create_func_connection_id(void) ...@@ -73,7 +73,8 @@ Item *create_func_connection_id(void)
{ {
THD *thd=current_thd; THD *thd=current_thd;
thd->lex->safe_to_cache_query= 0; thd->lex->safe_to_cache_query= 0;
return new Item_int(NullS,(longlong) return new Item_static_int_func("connection_id()",
(longlong)
((thd->slave_thread) ? ((thd->slave_thread) ?
thd->variables.pseudo_thread_id : thd->variables.pseudo_thread_id :
thd->thread_id), thd->thread_id),
...@@ -293,7 +294,7 @@ Item *create_func_period_diff(Item* a, Item *b) ...@@ -293,7 +294,7 @@ Item *create_func_period_diff(Item* a, Item *b)
Item *create_func_pi(void) 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) Item *create_func_pow(Item* a, Item *b)
...@@ -309,7 +310,8 @@ Item *create_func_current_user() ...@@ -309,7 +310,8 @@ Item *create_func_current_user()
length= (uint) (strxmov(buff, thd->priv_user, "@", thd->priv_host, NullS) - length= (uint) (strxmov(buff, thd->priv_user, "@", thd->priv_host, NullS) -
buff); buff);
return new Item_string(NullS, thd->memdup(buff, length), length, return new Item_static_string_func("current_user()",
thd->memdup(buff, length), length,
system_charset_info); system_charset_info);
} }
...@@ -434,7 +436,7 @@ Item *create_func_uuid(void) ...@@ -434,7 +436,7 @@ Item *create_func_uuid(void)
Item *create_func_version(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), (uint) strlen(server_version),
system_charset_info, DERIVATION_IMPLICIT); system_charset_info, DERIVATION_IMPLICIT);
} }
......
...@@ -38,6 +38,7 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db, ...@@ -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 free_cache_entry(TABLE *entry);
static void mysql_rm_tmp_tables(void); static void mysql_rm_tmp_tables(void);
static my_bool open_new_frm(const char *path, const char *alias, 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 db_stat, uint prgflag,
uint ha_open_flags, TABLE *outparam, uint ha_open_flags, TABLE *outparam,
TABLE_LIST *table_desc, MEM_ROOT *mem_root); TABLE_LIST *table_desc, MEM_ROOT *mem_root);
...@@ -1379,8 +1380,6 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db, ...@@ -1379,8 +1380,6 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
{ {
char path[FN_REFLEN]; char path[FN_REFLEN];
int error; 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; uint discover_retry_count= 0;
DBUG_ENTER("open_unireg_entry"); DBUG_ENTER("open_unireg_entry");
...@@ -1388,12 +1387,12 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db, ...@@ -1388,12 +1387,12 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
while ((error= openfrm(path, alias, while ((error= openfrm(path, alias,
(uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
HA_GET_INDEX | HA_TRY_READ_ONLY | HA_GET_INDEX | HA_TRY_READ_ONLY |
new_frm_flag), NO_ERR_ON_NEW_FRM),
READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD, READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD,
thd->open_options, entry)) && thd->open_options, entry)) &&
(error != 5 || (error != 5 ||
fn_format(path, path, 0, reg_ext, MY_UNPACK_FILENAME), 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 | (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
HA_GET_INDEX | HA_TRY_READ_ONLY), HA_GET_INDEX | HA_TRY_READ_ONLY),
READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD, READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD,
...@@ -1679,6 +1678,8 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type) ...@@ -1679,6 +1678,8 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type)
thd->proc_info="Opening table"; thd->proc_info="Opening table";
thd->current_tablenr= 0; 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) ; while (!(table= open_table(thd, table_list, 0, &refresh)) && refresh) ;
if (table) if (table)
...@@ -3209,6 +3210,8 @@ int init_ftfuncs(THD *thd, SELECT_LEX *select_lex, bool no_order) ...@@ -3209,6 +3210,8 @@ int init_ftfuncs(THD *thd, SELECT_LEX *select_lex, bool no_order)
open_new_frm() open_new_frm()
path path to .frm path path to .frm
alias alias for table alias alias for table
db database
table_name name of table
db_stat open flags (for example HA_OPEN_KEYFILE|HA_OPEN_RNDFILE..) db_stat open flags (for example HA_OPEN_KEYFILE|HA_OPEN_RNDFILE..)
can be 0 (example in ha_example_table) can be 0 (example in ha_example_table)
prgflag READ_ALL etc.. prgflag READ_ALL etc..
...@@ -3218,7 +3221,9 @@ int init_ftfuncs(THD *thd, SELECT_LEX *select_lex, bool no_order) ...@@ -3218,7 +3221,9 @@ int init_ftfuncs(THD *thd, SELECT_LEX *select_lex, bool no_order)
mem_root temporary MEM_ROOT for parsing mem_root temporary MEM_ROOT for parsing
*/ */
static my_bool 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, uint ha_open_flags, TABLE *outparam, TABLE_LIST *table_desc,
MEM_ROOT *mem_root) MEM_ROOT *mem_root)
{ {
...@@ -3226,28 +3231,36 @@ open_new_frm(const char *path, const char *alias, uint db_stat, uint prgflag, ...@@ -3226,28 +3231,36 @@ open_new_frm(const char *path, const char *alias, uint db_stat, uint prgflag,
LEX_STRING pathstr; LEX_STRING pathstr;
pathstr.str= (char *)path; pathstr.str= (char *)path;
pathstr.length= strlen(path); pathstr.length= strlen(path);
if (!mem_root)
mem_root= &current_thd->mem_root;
File_parser *parser= sql_parse_prepare(&pathstr, mem_root, 1); File_parser *parser= sql_parse_prepare(&pathstr, mem_root, 1);
if (parser) if (parser)
{ {
if (!strncmp("VIEW", parser->type()->str, parser->type()->length)) 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 my_error(ER_WRONG_OBJECT, MYF(0), db, table_name, "BASE TABLE");
DBUG_RETURN(1); goto err;
} }
if (mysql_make_view(parser, table_desc))
goto err;
} }
else else
{ {
/* only VIEWs are supported now */ /* only VIEWs are supported now */
my_error(ER_FRM_UNKNOWN_TYPE, MYF(0), path, parser->type()->str); my_error(ER_FRM_UNKNOWN_TYPE, MYF(0), path, parser->type()->str);
bzero(outparam, sizeof(outparam)); // do not run repair goto err;
DBUG_RETURN(1);
} }
} }
else else
{ goto err;
DBUG_RETURN(1);
}
DBUG_RETURN(0); DBUG_RETURN(0);
err:
bzero(outparam, sizeof(TABLE)); // do not run repair
DBUG_RETURN(1);
} }
...@@ -1546,7 +1546,7 @@ bool st_lex::can_be_merged() ...@@ -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 SYNOPSIS
st_lex::can_use_merged() st_lex::can_use_merged()
...@@ -1576,6 +1576,29 @@ bool 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 Detect that we need only table structure of derived table/view
......
...@@ -749,6 +749,7 @@ typedef struct st_lex ...@@ -749,6 +749,7 @@ typedef struct st_lex
bool can_be_merged(); bool can_be_merged();
bool can_use_merged(); bool can_use_merged();
bool can_not_use_merged();
bool only_view_structure(); bool only_view_structure();
} LEX; } LEX;
......
...@@ -1575,9 +1575,9 @@ view_store_create_info(THD *thd, TABLE_LIST *table, String *buff) ...@@ -1575,9 +1575,9 @@ view_store_create_info(THD *thd, TABLE_LIST *table, String *buff)
buff->append("MERGE ", 6); buff->append("MERGE ", 6);
} }
buff->append("VIEW ", 5); 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('.');
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(" AS ", 4);
buff->append(table->query.str, table->query.length); buff->append(table->query.str, table->query.length);
return 0; return 0;
......
...@@ -54,7 +54,7 @@ int mysql_create_view(THD *thd, ...@@ -54,7 +54,7 @@ int mysql_create_view(THD *thd,
TABLE_LIST *view= lex->unlink_first_table(&link_to_local); TABLE_LIST *view= lex->unlink_first_table(&link_to_local);
TABLE_LIST *tables= lex->query_tables; TABLE_LIST *tables= lex->query_tables;
TABLE_LIST *tbl; TABLE_LIST *tbl;
SELECT_LEX *select_lex= &lex->select_lex; SELECT_LEX *select_lex= &lex->select_lex, *sl;
SELECT_LEX_UNIT *unit= &lex->unit; SELECT_LEX_UNIT *unit= &lex->unit;
int res= 0; int res= 0;
DBUG_ENTER("mysql_create_view"); DBUG_ENTER("mysql_create_view");
...@@ -74,7 +74,9 @@ int mysql_create_view(THD *thd, ...@@ -74,7 +74,9 @@ int mysql_create_view(THD *thd,
0, 0) || 0, 0) ||
grant_option && check_grant(thd, CREATE_VIEW_ACL, view, 0, 1, 0)) grant_option && check_grant(thd, CREATE_VIEW_ACL, view, 0, 1, 0))
DBUG_RETURN(1); DBUG_RETURN(1);
for (tbl= tables; tbl; tbl= tbl->next_local) for (sl= select_lex; sl; sl= sl->next_select())
{
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 privilage on this table, more strict check
...@@ -125,6 +127,7 @@ int mysql_create_view(THD *thd, ...@@ -125,6 +127,7 @@ int mysql_create_view(THD *thd,
fill_effective_table_privileges(thd, &tbl->grant, tbl->db, fill_effective_table_privileges(thd, &tbl->grant, tbl->db,
tbl->real_name); tbl->real_name);
} }
}
if (&lex->select_lex != lex->all_selects_list) if (&lex->select_lex != lex->all_selects_list)
{ {
...@@ -145,12 +148,10 @@ int mysql_create_view(THD *thd, ...@@ -145,12 +148,10 @@ int mysql_create_view(THD *thd,
} }
/* /*
Mark fields for special privilege check (any privilege) 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; Item *item;
while ((item= it++)) while ((item= it++))
{ {
...@@ -235,9 +236,10 @@ int mysql_create_view(THD *thd, ...@@ -235,9 +236,10 @@ int mysql_create_view(THD *thd,
/* /*
Compare/check grants on view with grants of underlaying tables 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; 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; Item *item;
fill_effective_table_privileges(thd, &view->grant, db, fill_effective_table_privileges(thd, &view->grant, db,
view->real_name); view->real_name);
...@@ -657,7 +659,8 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table) ...@@ -657,7 +659,8 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)
if (table->algorithm != VIEW_ALGORITHM_TMEPTABLE && if (table->algorithm != VIEW_ALGORITHM_TMEPTABLE &&
lex->can_be_merged() && lex->can_be_merged() &&
(table->select_lex->master_unit() != &old_lex->unit || (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 TODO: support multi tables substitutions
...@@ -670,6 +673,7 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table) ...@@ -670,6 +673,7 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)
DBUG_ASSERT(view_table != 0); DBUG_ASSERT(view_table != 0);
table->effective_algorithm= VIEW_ALGORITHM_MERGE; table->effective_algorithm= VIEW_ALGORITHM_MERGE;
DBUG_PRINT("info", ("algorithm: MERGE"));
table->updatable= (table->updatable_view != 0); table->updatable= (table->updatable_view != 0);
if (old_next) if (old_next)
...@@ -699,6 +703,7 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table) ...@@ -699,6 +703,7 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)
} }
table->effective_algorithm= VIEW_ALGORITHM_TMEPTABLE; table->effective_algorithm= VIEW_ALGORITHM_TMEPTABLE;
DBUG_PRINT("info", ("algorithm: TEMPORARY TABLE"));
lex->select_lex.linkage= DERIVED_TABLE_TYPE; lex->select_lex.linkage= DERIVED_TABLE_TYPE;
table->updatable= 0; table->updatable= 0;
......
...@@ -27,13 +27,6 @@ bool check_key_in_view(THD *thd, TABLE_LIST * view); ...@@ -27,13 +27,6 @@ bool check_key_in_view(THD *thd, TABLE_LIST * view);
void insert_view_fields(List<Item> *list, 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); frm_type_enum mysql_frm_type(char *path);
extern TYPELIB sql_updatable_view_key_typelib; extern TYPELIB sql_updatable_view_key_typelib;
......
...@@ -1506,6 +1506,7 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds) ...@@ -1506,6 +1506,7 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds)
uint i= 0; uint i= 0;
bool save_set_query_id= thd->set_query_id; bool save_set_query_id= thd->set_query_id;
bool save_wrapper= thd->lex->select_lex.no_wrap_view_item; 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"); DBUG_ENTER("st_table_list::setup_ancestor");
if (ancestor->ancestor && if (ancestor->ancestor &&
...@@ -1525,6 +1526,8 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds) ...@@ -1525,6 +1526,8 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds)
uint want_privilege= ancestor->table->grant.want_privilege; uint want_privilege= ancestor->table->grant.want_privilege;
/* real rights will be checked in VIEW field */ /* real rights will be checked in VIEW field */
ancestor->table->grant.want_privilege= 0; ancestor->table->grant.want_privilege= 0;
/* aggregate function are allowed */
thd->allow_sum_func= 1;
if (!(*i)->fixed && (*i)->fix_fields(thd, ancestor, i)) if (!(*i)->fixed && (*i)->fix_fields(thd, ancestor, i))
goto err; goto err;
ancestor->table->grant.want_privilege= want_privilege; ancestor->table->grant.want_privilege= want_privilege;
...@@ -1558,6 +1561,8 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds) ...@@ -1558,6 +1561,8 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds)
uint want_privilege= ancestor->table->grant.want_privilege; uint want_privilege= ancestor->table->grant.want_privilege;
/* real rights will be checked in VIEW field */ /* real rights will be checked in VIEW field */
ancestor->table->grant.want_privilege= 0; ancestor->table->grant.want_privilege= 0;
/* aggregate function are allowed */
thd->allow_sum_func= 1;
if (!item->fixed && item->fix_fields(thd, ancestor, &item)) if (!item->fixed && item->fix_fields(thd, ancestor, &item))
{ {
goto err; goto err;
...@@ -1602,6 +1607,7 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds) ...@@ -1602,6 +1607,7 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds)
thd->lex->select_lex.no_wrap_view_item= save_wrapper; thd->lex->select_lex.no_wrap_view_item= save_wrapper;
thd->lex->current_select= current_select_save; thd->lex->current_select= current_select_save;
thd->set_query_id= save_set_query_id; thd->set_query_id= save_set_query_id;
thd->allow_sum_func= save_allow_sum_func;
DBUG_RETURN(0); DBUG_RETURN(0);
err: err:
...@@ -1614,6 +1620,7 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds) ...@@ -1614,6 +1620,7 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds)
thd->lex->select_lex.no_wrap_view_item= save_wrapper; thd->lex->select_lex.no_wrap_view_item= save_wrapper;
thd->lex->current_select= current_select_save; thd->lex->current_select= current_select_save;
thd->set_query_id= save_set_query_id; thd->set_query_id= save_set_query_id;
thd->allow_sum_func= save_allow_sum_func;
DBUG_RETURN(1); DBUG_RETURN(1);
} }
......
...@@ -47,6 +47,13 @@ typedef struct st_grant_info ...@@ -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 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 typedef struct st_filesort_info
{ {
IO_CACHE *io_cache; /* If sorted through filebyte */ IO_CACHE *io_cache; /* If sorted through filebyte */
...@@ -241,6 +248,8 @@ typedef struct st_table_list ...@@ -241,6 +248,8 @@ typedef struct st_table_list
bool setup_is_done; /* setup_tables() is done */ bool setup_is_done; /* setup_tables() is done */
/* do view contain auto_increment field */ /* do view contain auto_increment field */
bool contain_auto_increment; 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) */ char timestamp_buffer[20]; /* buffer for timestamp (19+1) */
void calc_md5(char *buffer); void calc_md5(char *buffer);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment