mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Merge gleb.loc:/home/uchum/work/bk/mysql-5.0-opt
into gleb.loc:/home/uchum/work/bk/mysql-5.1-opt
This commit is contained in:
@ -317,3 +317,10 @@ SHOW COUNT(*) WARNINGS;
|
|||||||
SHOW COUNT(*) ERRORS;
|
SHOW COUNT(*) ERRORS;
|
||||||
@@session.error_count
|
@@session.error_count
|
||||||
1
|
1
|
||||||
|
create table t1(f1 int);
|
||||||
|
insert into t1 values(1),(1),(2);
|
||||||
|
select @a:=f1, count(f1) from t1 group by 1;
|
||||||
|
@a:=f1 count(f1)
|
||||||
|
1 2
|
||||||
|
2 1
|
||||||
|
drop table t1;
|
||||||
|
@ -3386,6 +3386,67 @@ WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
|
|||||||
UPDATE v1 SET c=1;
|
UPDATE v1 SET c=1;
|
||||||
DROP VIEW v1;
|
DROP VIEW v1;
|
||||||
DROP TABLE t1,t2;
|
DROP TABLE t1,t2;
|
||||||
|
CREATE TABLE t1 (a1 INT, c INT DEFAULT 0);
|
||||||
|
CREATE TABLE t2 (a2 INT);
|
||||||
|
CREATE TABLE t3 (a3 INT);
|
||||||
|
CREATE TABLE t4 (a4 INT);
|
||||||
|
INSERT INTO t1 (a1) VALUES (1),(2);
|
||||||
|
INSERT INTO t2 (a2) VALUES (1),(2);
|
||||||
|
INSERT INTO t3 (a3) VALUES (1),(2);
|
||||||
|
INSERT INTO t4 (a4) VALUES (1),(2);
|
||||||
|
CREATE VIEW v1 AS
|
||||||
|
SELECT t1.a1, t1.c FROM t1 JOIN t2 ON t1.a1=t2.a2 AND t1.c < 3
|
||||||
|
WITH CHECK OPTION;
|
||||||
|
SELECT * FROM v1;
|
||||||
|
a1 c
|
||||||
|
1 0
|
||||||
|
2 0
|
||||||
|
UPDATE v1 SET c=3;
|
||||||
|
ERROR HY000: CHECK OPTION failed 'test.v1'
|
||||||
|
PREPARE t FROM 'UPDATE v1 SET c=3';
|
||||||
|
EXECUTE t;
|
||||||
|
ERROR HY000: CHECK OPTION failed 'test.v1'
|
||||||
|
EXECUTE t;
|
||||||
|
ERROR HY000: CHECK OPTION failed 'test.v1'
|
||||||
|
INSERT INTO v1(a1, c) VALUES (3, 3);
|
||||||
|
ERROR HY000: CHECK OPTION failed 'test.v1'
|
||||||
|
UPDATE v1 SET c=1 WHERE a1=1;
|
||||||
|
SELECT * FROM v1;
|
||||||
|
a1 c
|
||||||
|
1 1
|
||||||
|
2 0
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a1 c
|
||||||
|
1 1
|
||||||
|
2 0
|
||||||
|
CREATE VIEW v2 AS SELECT t1.a1, t1.c
|
||||||
|
FROM (t1 JOIN t2 ON t1.a1=t2.a2 AND t1.c < 3)
|
||||||
|
JOIN (t3 JOIN t4 ON t3.a3=t4.a4)
|
||||||
|
ON t2.a2=t3.a3 WITH CHECK OPTION;
|
||||||
|
SELECT * FROM v2;
|
||||||
|
a1 c
|
||||||
|
1 1
|
||||||
|
2 0
|
||||||
|
UPDATE v2 SET c=3;
|
||||||
|
ERROR HY000: CHECK OPTION failed 'test.v2'
|
||||||
|
PREPARE t FROM 'UPDATE v2 SET c=3';
|
||||||
|
EXECUTE t;
|
||||||
|
ERROR HY000: CHECK OPTION failed 'test.v2'
|
||||||
|
EXECUTE t;
|
||||||
|
ERROR HY000: CHECK OPTION failed 'test.v2'
|
||||||
|
INSERT INTO v2(a1, c) VALUES (3, 3);
|
||||||
|
ERROR HY000: CHECK OPTION failed 'test.v2'
|
||||||
|
UPDATE v2 SET c=2 WHERE a1=1;
|
||||||
|
SELECT * FROM v2;
|
||||||
|
a1 c
|
||||||
|
1 2
|
||||||
|
2 0
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a1 c
|
||||||
|
1 2
|
||||||
|
2 0
|
||||||
|
DROP VIEW v1,v2;
|
||||||
|
DROP TABLE t1,t2,t3,t4;
|
||||||
End of 5.0 tests.
|
End of 5.0 tests.
|
||||||
DROP DATABASE IF EXISTS `d-1`;
|
DROP DATABASE IF EXISTS `d-1`;
|
||||||
CREATE DATABASE `d-1`;
|
CREATE DATABASE `d-1`;
|
||||||
|
@ -222,3 +222,11 @@ drop table t1,t2;
|
|||||||
insert into city 'blah';
|
insert into city 'blah';
|
||||||
SHOW COUNT(*) WARNINGS;
|
SHOW COUNT(*) WARNINGS;
|
||||||
SHOW COUNT(*) ERRORS;
|
SHOW COUNT(*) ERRORS;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#28494: Grouping by Item_func_set_user_var produces incorrect result.
|
||||||
|
#
|
||||||
|
create table t1(f1 int);
|
||||||
|
insert into t1 values(1),(1),(2);
|
||||||
|
select @a:=f1, count(f1) from t1 group by 1;
|
||||||
|
drop table t1;
|
||||||
|
@ -3260,6 +3260,58 @@ UPDATE v1 SET c=1;
|
|||||||
DROP VIEW v1;
|
DROP VIEW v1;
|
||||||
DROP TABLE t1,t2;
|
DROP TABLE t1,t2;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #27827: CHECK OPTION ignores ON conditions when updating
|
||||||
|
# a multi-table view with CHECK OPTION.
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a1 INT, c INT DEFAULT 0);
|
||||||
|
CREATE TABLE t2 (a2 INT);
|
||||||
|
CREATE TABLE t3 (a3 INT);
|
||||||
|
CREATE TABLE t4 (a4 INT);
|
||||||
|
INSERT INTO t1 (a1) VALUES (1),(2);
|
||||||
|
INSERT INTO t2 (a2) VALUES (1),(2);
|
||||||
|
INSERT INTO t3 (a3) VALUES (1),(2);
|
||||||
|
INSERT INTO t4 (a4) VALUES (1),(2);
|
||||||
|
|
||||||
|
CREATE VIEW v1 AS
|
||||||
|
SELECT t1.a1, t1.c FROM t1 JOIN t2 ON t1.a1=t2.a2 AND t1.c < 3
|
||||||
|
WITH CHECK OPTION;
|
||||||
|
SELECT * FROM v1;
|
||||||
|
--error 1369
|
||||||
|
UPDATE v1 SET c=3;
|
||||||
|
PREPARE t FROM 'UPDATE v1 SET c=3';
|
||||||
|
--error 1369
|
||||||
|
EXECUTE t;
|
||||||
|
--error 1369
|
||||||
|
EXECUTE t;
|
||||||
|
--error 1369
|
||||||
|
INSERT INTO v1(a1, c) VALUES (3, 3);
|
||||||
|
UPDATE v1 SET c=1 WHERE a1=1;
|
||||||
|
SELECT * FROM v1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
|
||||||
|
CREATE VIEW v2 AS SELECT t1.a1, t1.c
|
||||||
|
FROM (t1 JOIN t2 ON t1.a1=t2.a2 AND t1.c < 3)
|
||||||
|
JOIN (t3 JOIN t4 ON t3.a3=t4.a4)
|
||||||
|
ON t2.a2=t3.a3 WITH CHECK OPTION;
|
||||||
|
SELECT * FROM v2;
|
||||||
|
--error 1369
|
||||||
|
UPDATE v2 SET c=3;
|
||||||
|
PREPARE t FROM 'UPDATE v2 SET c=3';
|
||||||
|
--error 1369
|
||||||
|
EXECUTE t;
|
||||||
|
--error 1369
|
||||||
|
EXECUTE t;
|
||||||
|
--error 1369
|
||||||
|
INSERT INTO v2(a1, c) VALUES (3, 3);
|
||||||
|
UPDATE v2 SET c=2 WHERE a1=1;
|
||||||
|
SELECT * FROM v2;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
|
||||||
|
DROP VIEW v1,v2;
|
||||||
|
DROP TABLE t1,t2,t3,t4;
|
||||||
|
|
||||||
--echo End of 5.0 tests.
|
--echo End of 5.0 tests.
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -4259,9 +4259,11 @@ void Item_func_set_user_var::make_field(Send_field *tmp_field)
|
|||||||
TRUE Error
|
TRUE Error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int Item_func_set_user_var::save_in_field(Field *field, bool no_conversions)
|
int Item_func_set_user_var::save_in_field(Field *field, bool no_conversions,
|
||||||
|
bool can_use_result_field)
|
||||||
{
|
{
|
||||||
bool use_result_field= (result_field && result_field != field);
|
bool use_result_field= (!can_use_result_field ? 0 :
|
||||||
|
(result_field && result_field != field));
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
/* Update the value of the user variable */
|
/* Update the value of the user variable */
|
||||||
|
@ -1248,7 +1248,13 @@ public:
|
|||||||
void print(String *str);
|
void print(String *str);
|
||||||
void print_as_stmt(String *str);
|
void print_as_stmt(String *str);
|
||||||
const char *func_name() const { return "set_user_var"; }
|
const char *func_name() const { return "set_user_var"; }
|
||||||
int save_in_field(Field *field, bool no_conversions);
|
int save_in_field(Field *field, bool no_conversions,
|
||||||
|
bool can_use_result_field);
|
||||||
|
int save_in_field(Field *field, bool no_conversions)
|
||||||
|
{
|
||||||
|
return save_in_field(field, no_conversions, 1);
|
||||||
|
}
|
||||||
|
void save_org_in_field(Field *field) { (void)save_in_field(field, 1, 0); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -706,7 +706,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
|
|||||||
DBUG_PRINT("info", ("View: %s", str.ptr()));
|
DBUG_PRINT("info", ("View: %s", str.ptr()));
|
||||||
|
|
||||||
/* fill structure */
|
/* fill structure */
|
||||||
view->query.str= str.c_ptr();
|
view->query.str= str.c_ptr_safe();
|
||||||
view->query.length= str.length();
|
view->query.length= str.length();
|
||||||
view->source.str= thd->query + thd->lex->create_view_select_start;
|
view->source.str= thd->query + thd->lex->create_view_select_start;
|
||||||
endp= view->source.str;
|
endp= view->source.str;
|
||||||
|
79
sql/table.cc
79
sql/table.cc
@ -2902,6 +2902,47 @@ bool st_table_list::prep_where(THD *thd, Item **conds,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Merge ON expressions for a view
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
merge_on_conds()
|
||||||
|
thd thread handle
|
||||||
|
table table for the VIEW
|
||||||
|
is_cascaded TRUE <=> merge ON expressions from underlying views
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
This function returns the result of ANDing the ON expressions
|
||||||
|
of the given view and all underlying views. The ON expressions
|
||||||
|
of the underlying views are added only if is_cascaded is TRUE.
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
Pointer to the built expression if there is any.
|
||||||
|
Otherwise and in the case of a failure NULL is returned.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static Item *
|
||||||
|
merge_on_conds(THD *thd, TABLE_LIST *table, bool is_cascaded)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("merge_on_conds");
|
||||||
|
|
||||||
|
Item *cond= NULL;
|
||||||
|
DBUG_PRINT("info", ("alias: %s", table->alias));
|
||||||
|
if (table->on_expr)
|
||||||
|
cond= table->on_expr->copy_andor_structure(thd);
|
||||||
|
if (!table->nested_join)
|
||||||
|
DBUG_RETURN(cond);
|
||||||
|
List_iterator<TABLE_LIST> li(table->nested_join->join_list);
|
||||||
|
while (TABLE_LIST *tbl= li++)
|
||||||
|
{
|
||||||
|
if (tbl->view && !is_cascaded)
|
||||||
|
continue;
|
||||||
|
cond= and_conds(cond, merge_on_conds(thd, tbl, is_cascaded));
|
||||||
|
}
|
||||||
|
DBUG_RETURN(cond);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Prepare check option expression of table
|
Prepare check option expression of table
|
||||||
|
|
||||||
@ -2918,8 +2959,8 @@ bool st_table_list::prep_where(THD *thd, Item **conds,
|
|||||||
VIEW_CHECK_LOCAL option.
|
VIEW_CHECK_LOCAL option.
|
||||||
|
|
||||||
NOTE
|
NOTE
|
||||||
This method build check options for every call
|
This method builds check option condition to use it later on
|
||||||
(usual execution or every SP/PS call)
|
every call (usual execution or every SP/PS call).
|
||||||
This method have to be called after WHERE preparation
|
This method have to be called after WHERE preparation
|
||||||
(st_table_list::prep_where)
|
(st_table_list::prep_where)
|
||||||
|
|
||||||
@ -2931,38 +2972,42 @@ bool st_table_list::prep_where(THD *thd, Item **conds,
|
|||||||
bool st_table_list::prep_check_option(THD *thd, uint8 check_opt_type)
|
bool st_table_list::prep_check_option(THD *thd, uint8 check_opt_type)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("st_table_list::prep_check_option");
|
DBUG_ENTER("st_table_list::prep_check_option");
|
||||||
|
bool is_cascaded= check_opt_type == VIEW_CHECK_CASCADED;
|
||||||
|
|
||||||
for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
|
for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
|
||||||
{
|
{
|
||||||
/* see comment of check_opt_type parameter */
|
/* see comment of check_opt_type parameter */
|
||||||
if (tbl->view &&
|
if (tbl->view && tbl->prep_check_option(thd, (is_cascaded ?
|
||||||
tbl->prep_check_option(thd,
|
VIEW_CHECK_CASCADED :
|
||||||
((check_opt_type == VIEW_CHECK_CASCADED) ?
|
VIEW_CHECK_NONE)))
|
||||||
VIEW_CHECK_CASCADED :
|
|
||||||
VIEW_CHECK_NONE)))
|
|
||||||
{
|
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (check_opt_type)
|
if (check_opt_type && !check_option_processed)
|
||||||
{
|
{
|
||||||
Item *item= 0;
|
Query_arena *arena= thd->stmt_arena, backup;
|
||||||
|
arena= thd->activate_stmt_arena_if_needed(&backup); // For easier test
|
||||||
|
|
||||||
if (where)
|
if (where)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(where->fixed);
|
DBUG_ASSERT(where->fixed);
|
||||||
item= where->copy_andor_structure(thd);
|
check_option= where->copy_andor_structure(thd);
|
||||||
}
|
}
|
||||||
if (check_opt_type == VIEW_CHECK_CASCADED)
|
if (is_cascaded)
|
||||||
{
|
{
|
||||||
for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
|
for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
|
||||||
{
|
{
|
||||||
if (tbl->check_option)
|
if (tbl->check_option)
|
||||||
item= and_conds(item, tbl->check_option);
|
check_option= and_conds(check_option, tbl->check_option);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (item)
|
check_option= and_conds(check_option,
|
||||||
thd->change_item_tree(&check_option, item);
|
merge_on_conds(thd, this, is_cascaded));
|
||||||
|
|
||||||
|
if (arena)
|
||||||
|
thd->restore_active_arena(arena, &backup);
|
||||||
|
check_option_processed= TRUE;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (check_option)
|
if (check_option)
|
||||||
@ -3067,7 +3112,7 @@ void st_table_list::cleanup_items()
|
|||||||
check CHECK OPTION condition
|
check CHECK OPTION condition
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
check_option()
|
st_table_list::view_check_option()
|
||||||
ignore_failure ignore check option fail
|
ignore_failure ignore check option fail
|
||||||
|
|
||||||
RETURN
|
RETURN
|
||||||
|
@ -909,6 +909,8 @@ typedef struct st_table_list
|
|||||||
bool compact_view_format; /* Use compact format for SHOW CREATE VIEW */
|
bool compact_view_format; /* Use compact format for SHOW CREATE VIEW */
|
||||||
/* view where processed */
|
/* view where processed */
|
||||||
bool where_processed;
|
bool where_processed;
|
||||||
|
/* TRUE <=> VIEW CHECK OPTION expression has been processed */
|
||||||
|
bool check_option_processed;
|
||||||
/* FRMTYPE_ERROR if any type is acceptable */
|
/* FRMTYPE_ERROR if any type is acceptable */
|
||||||
enum frm_type_enum required_type;
|
enum frm_type_enum required_type;
|
||||||
handlerton *db_type; /* table_type for handler */
|
handlerton *db_type; /* table_type for handler */
|
||||||
|
Reference in New Issue
Block a user