Below is the list of changes that have just been committed into a local
5.1 repository of uchum. When uchum does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2007-06-01 03:05:25+05:00, gshchepa@stripped +9 -0
Merge gleb.loc:/home/uchum/work/bk/mysql-5.0-opt
into gleb.loc:/home/uchum/work/bk/mysql-5.1-opt
MERGE: 1.1810.2942.39
mysql-test/r/user_var.result@stripped, 2007-06-01 03:02:02+05:00, gshchepa@stripped +0 -0
Auto merged
MERGE: 1.37.1.8
mysql-test/r/view.result@stripped, 2007-06-01 03:02:03+05:00, gshchepa@stripped +0 -0
Auto merged
MERGE: 1.138.1.67
mysql-test/t/user_var.test@stripped, 2007-06-01 03:02:03+05:00, gshchepa@stripped +0 -0
Auto merged
MERGE: 1.35.1.5
mysql-test/t/view.test@stripped, 2007-06-01 03:05:21+05:00, gshchepa@stripped +52 -86
Merge with 5.0-opt.
MERGE: 1.126.1.60
sql/item_func.cc@stripped, 2007-06-01 03:02:03+05:00, gshchepa@stripped +0 -0
Auto merged
MERGE: 1.270.1.74
sql/item_func.h@stripped, 2007-06-01 03:02:03+05:00, gshchepa@stripped +0 -0
Auto merged
MERGE: 1.136.2.33
sql/sql_view.cc@stripped, 2007-06-01 03:02:03+05:00, gshchepa@stripped +0 -0
Auto merged
MERGE: 1.78.1.35
sql/table.cc@stripped, 2007-06-01 03:02:03+05:00, gshchepa@stripped +0 -0
Auto merged
MERGE: 1.160.1.91
sql/table.h@stripped, 2007-06-01 03:02:03+05:00, gshchepa@stripped +0 -0
Auto merged
MERGE: 1.102.1.42
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: gshchepa
# Host: gleb.loc
# Root: /home/uchum/work/bk/mysql-5.1-opt/RESYNC
--- 1.401/sql/item_func.cc 2007-05-31 14:19:11 +05:00
+++ 1.402/sql/item_func.cc 2007-06-01 03:02:03 +05:00
@@ -4259,9 +4259,11 @@ void Item_func_set_user_var::make_field(
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;
/* Update the value of the user variable */
--- 1.175/sql/item_func.h 2007-05-18 01:27:07 +05:00
+++ 1.176/sql/item_func.h 2007-06-01 03:02:03 +05:00
@@ -1248,7 +1248,13 @@ public:
void print(String *str);
void print_as_stmt(String *str);
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); }
};
--- 1.288/sql/table.cc 2007-05-05 11:20:34 +05:00
+++ 1.289/sql/table.cc 2007-06-01 03:02:03 +05:00
@@ -2903,6 +2903,47 @@ bool st_table_list::prep_where(THD *thd,
/*
+ 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
SYNOPSIS
@@ -2918,8 +2959,8 @@ bool st_table_list::prep_where(THD *thd,
VIEW_CHECK_LOCAL option.
NOTE
- This method build check options for every call
- (usual execution or every SP/PS call)
+ This method builds check option condition to use it later on
+ every call (usual execution or every SP/PS call).
This method have to be called after WHERE preparation
(st_table_list::prep_where)
@@ -2931,38 +2972,42 @@ bool st_table_list::prep_where(THD *thd,
bool st_table_list::prep_check_option(THD *thd, uint8 check_opt_type)
{
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)
{
/* see comment of check_opt_type parameter */
- if (tbl->view &&
- tbl->prep_check_option(thd,
- ((check_opt_type == VIEW_CHECK_CASCADED) ?
- VIEW_CHECK_CASCADED :
- VIEW_CHECK_NONE)))
- {
+ if (tbl->view && tbl->prep_check_option(thd, (is_cascaded ?
+ VIEW_CHECK_CASCADED :
+ VIEW_CHECK_NONE)))
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)
{
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)
{
if (tbl->check_option)
- item= and_conds(item, tbl->check_option);
+ check_option= and_conds(check_option, tbl->check_option);
}
}
- if (item)
- thd->change_item_tree(&check_option, item);
+ check_option= and_conds(check_option,
+ merge_on_conds(thd, this, is_cascaded));
+
+ if (arena)
+ thd->restore_active_arena(arena, &backup);
+ check_option_processed= TRUE;
+
}
if (check_option)
@@ -3067,7 +3112,7 @@ void st_table_list::cleanup_items()
check CHECK OPTION condition
SYNOPSIS
- check_option()
+ st_table_list::view_check_option()
ignore_failure ignore check option fail
RETURN
--- 1.171/sql/table.h 2007-05-23 14:39:37 +05:00
+++ 1.172/sql/table.h 2007-06-01 03:02:03 +05:00
@@ -909,6 +909,8 @@ typedef struct st_table_list
bool compact_view_format; /* Use compact format for SHOW CREATE VIEW */
/* view where processed */
bool where_processed;
+ /* TRUE <=> VIEW CHECK OPTION expression has been processed */
+ bool check_option_processed;
/* FRMTYPE_ERROR if any type is acceptable */
enum frm_type_enum required_type;
handlerton *db_type; /* table_type for handler */
--- 1.230/mysql-test/r/view.result 2007-05-31 14:19:11 +05:00
+++ 1.231/mysql-test/r/view.result 2007-06-01 03:02:03 +05:00
@@ -3386,6 +3386,67 @@ WHERE t1.id=t2.id AND 1 IN (SELECT id FR
UPDATE v1 SET c=1;
DROP VIEW v1;
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.
DROP DATABASE IF EXISTS `d-1`;
CREATE DATABASE `d-1`;
--- 1.201/mysql-test/t/view.test 2007-05-31 14:02:48 +05:00
+++ 1.202/mysql-test/t/view.test 2007-06-01 03:05:21 +05:00
@@ -3260,6 +3260,58 @@ UPDATE v1 SET c=1;
DROP VIEW v1;
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.
#
--- 1.134/sql/sql_view.cc 2007-05-31 21:10:26 +05:00
+++ 1.135/sql/sql_view.cc 2007-06-01 03:02:03 +05:00
@@ -706,7 +706,7 @@ static int mysql_register_view(THD *thd,
DBUG_PRINT("info", ("View: %s", str.ptr()));
/* fill structure */
- view->query.str= str.c_ptr();
+ view->query.str= str.c_ptr_safe();
view->query.length= str.length();
view->source.str= thd->query + thd->lex->create_view_select_start;
endp= view->source.str;
--- 1.46/mysql-test/r/user_var.result 2007-01-10 14:06:17 +04:00
+++ 1.47/mysql-test/r/user_var.result 2007-06-01 03:02:02 +05:00
@@ -317,3 +317,10 @@ SHOW COUNT(*) WARNINGS;
SHOW COUNT(*) ERRORS;
@@session.error_count
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;
--- 1.40/mysql-test/t/user_var.test 2007-01-10 14:06:17 +04:00
+++ 1.41/mysql-test/t/user_var.test 2007-06-01 03:02:03 +05:00
@@ -222,3 +222,11 @@ drop table t1,t2;
insert into city 'blah';
SHOW COUNT(*) WARNINGS;
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;
| Thread |
|---|
| • bk commit into 5.1 tree (gshchepa:1.2527) | gshchepa | 31 May |