developers
Threads by month
- ----- 2025 -----
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- 5 participants
- 6819 discussions
[Maria-developers] Rev 2746: MWL#17: Table elimination in file:///home/psergey/dev/maria-5.1-table-elim-r11-gcov/
by Sergey Petrunya 25 Aug '09
by Sergey Petrunya 25 Aug '09
25 Aug '09
At file:///home/psergey/dev/maria-5.1-table-elim-r11-gcov/
------------------------------------------------------------
revno: 2746
revision-id: psergey(a)askmonty.org-20090825145915-rxwmfczgqe69r5ju
parent: psergey(a)askmonty.org-20090825103822-ldmjinfdh7ymc35r
committer: Sergey Petrunya <psergey(a)askmonty.org>
branch nick: maria-5.1-table-elim-r11-gcov
timestamp: Tue 2009-08-25 17:59:15 +0300
message:
MWL#17: Table elimination
- Mark gcov deadcode
=== modified file 'sql/opt_table_elimination.cc'
--- a/sql/opt_table_elimination.cc 2009-08-25 10:38:22 +0000
+++ b/sql/opt_table_elimination.cc 2009-08-25 14:59:15 +0000
@@ -197,7 +197,7 @@
public:
Value_dep(): bound(FALSE), next(NULL) {}
virtual void now_bound(Func_dep_analyzer *fda, Module_dep **bound_modules)=0;
- virtual ~Value_dep() {} /* only to shut up compiler warnings */
+ virtual ~Value_dep(){} /* purecov: inspected */ /* stop compiler warnings */
bool bound;
Value_dep *next;
@@ -264,7 +264,7 @@
{
public:
virtual bool now_bound(Func_dep_analyzer *fda, Value_dep **bound_modules)=0;
- virtual ~Module_dep(){}
+ virtual ~Module_dep(){} /* purecov: inspected */ /* stop compiler warnings */
/*
Used to make a linked list of elements that became bound and thus can
make elements that depend on them bound, too.
@@ -510,7 +510,7 @@
Item_equal *item_equal= (Item_equal*)cond;
List<Field_value> *fvl;
if (!(fvl= new List<Field_value>))
- break;
+ break; /* purecov: inspected */
Item_equal_iterator it(*item_equal);
Item_field *item;
@@ -802,6 +802,7 @@
We've filled the entire equality_mods array. Replace it with a bigger
one. We do it somewhat inefficiently but it doesn't matter.
*/
+ /* purecov: begin inspected */
Equality_module *new_arr;
if (!(new_arr= new Equality_module[fda->n_equality_mods_alloced *2]))
return;
@@ -811,6 +812,7 @@
fda->equality_mods= new_arr;
*eq_mod= new_arr + (*eq_mod - fda->equality_mods);
+ /* purecov: end */
}
(*eq_mod)->field= field_val;
@@ -828,7 +830,7 @@
{
Table_value *tbl_dep;
if (!(tbl_dep= new Table_value(table)))
- return NULL;
+ return NULL; /* purecov: inspected */
Key_module **key_list= &(tbl_dep->keys);
/* Add dependencies for unique keys */
@@ -972,7 +974,7 @@
if (!(buf= current_thd->alloc(bitmap_buffer_size(offset))) ||
bitmap_init(&fda->expr_deps, (my_bitmap_map*)buf, offset, FALSE))
{
- DBUG_RETURN(TRUE);
+ DBUG_RETURN(TRUE); /* purecov: inspected */
}
bitmap_clear_all(&fda->expr_deps);
@@ -1077,7 +1079,7 @@
#ifndef DBUG_OFF
if (!optimizer_flag(thd, OPTIMIZER_SWITCH_TABLE_ELIMINATION))
- DBUG_VOID_RETURN;
+ DBUG_VOID_RETURN; /* purecov: inspected */
#endif
/* Find the tables that are referred to from WHERE/HAVING */
@@ -1256,7 +1258,7 @@
join->thd->lex->current_select->between_count;
if (!(fda.equality_mods= new Equality_module[fda.n_equality_mods_alloced]))
- return FALSE;
+ return FALSE; /* purecov: inspected */
Equality_module* last_eq_mod= fda.equality_mods;
@@ -1264,7 +1266,7 @@
if (oj_tbl)
{
if (!get_table_value(&fda, oj_tbl->table))
- return FALSE;
+ return FALSE; /* purecov: inspected */
}
else
{
@@ -1274,7 +1276,7 @@
if (tbl->table && (tbl->table->map & dep_tables))
{
if (!get_table_value(&fda, tbl->table))
- return FALSE;
+ return FALSE; /* purecov: inspected */
}
}
}
@@ -1292,7 +1294,7 @@
if (!(fda.outer_join_dep= new Outer_join_module(my_count_bits(dep_tables))) ||
setup_equality_modules_deps(&fda, &bound_modules))
{
- return FALSE; /* OOM, default to non-dependent */
+ return FALSE; /* OOM, default to non-dependent */ /* purecov: inspected */
}
DBUG_EXECUTE("test", dbug_print_deps(&fda); );
1
0
[Maria-developers] Rev 2745: MWL#17: Table elimination in file:///home/psergey/dev/maria-5.1-table-elim-r11-gcov/
by Sergey Petrunya 25 Aug '09
by Sergey Petrunya 25 Aug '09
25 Aug '09
At file:///home/psergey/dev/maria-5.1-table-elim-r11-gcov/
------------------------------------------------------------
revno: 2745
revision-id: psergey(a)askmonty.org-20090825103822-ldmjinfdh7ymc35r
parent: psergey(a)askmonty.org-20090825092750-mnmatimn7cxm4rl8
committer: Sergey Petrunya <psergey(a)askmonty.org>
branch nick: maria-5.1-table-elim-r11-gcov
timestamp: Tue 2009-08-25 13:38:22 +0300
message:
MWL#17: Table elimination
- More test coverage
- Remove unused code
=== modified file 'mysql-test/r/table_elim.result'
--- a/mysql-test/r/table_elim.result 2009-08-25 09:27:50 +0000
+++ b/mysql-test/r/table_elim.result 2009-08-25 10:38:22 +0000
@@ -314,8 +314,8 @@
insert into t1 values (0,0,0,0),(1,1,1,1),(2,2,2,2),(3,3,3,3);
create table t2 (pk int primary key, b int)
as select a as pk, a as b from t1 where a in (1,2);
-create table t3 (pk int primary key, b int)
-as select a as pk, a as b from t1 where a in (1,3);
+create table t3 (pk1 int, pk2 int, b int, unique(pk1,pk2));
+insert into t3 select a as pk1, a as pk2, a as b from t1 where a in (1,3);
explain select t1.a from t1 left join t2 on t2.pk=t1.a and t2.b<t1.b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4
@@ -344,4 +344,11 @@
explain select t1.a from t1 left join t2 on t2.pk in (t1.a);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4
+explain select t1.a from t1 left join t2 on TRUE;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4
+1 SIMPLE t2 index NULL PRIMARY 4 NULL 2 Using index
+explain select t1.a from t1 left join t3 on t3.pk1=t1.a and t3.pk2 IS NULL;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4
drop table t1,t2,t3;
=== modified file 'mysql-test/t/table_elim.test'
--- a/mysql-test/t/table_elim.test 2009-08-25 09:27:50 +0000
+++ b/mysql-test/t/table_elim.test 2009-08-25 10:38:22 +0000
@@ -274,5 +274,7 @@
explain select t1.a from t1 left join t2 on TRUE;
+explain select t1.a from t1 left join t3 on t3.pk1=t1.a and t3.pk2 IS NULL;
+
drop table t1,t2,t3;
=== modified file 'sql/opt_table_elimination.cc'
--- a/sql/opt_table_elimination.cc 2009-08-25 09:27:50 +0000
+++ b/sql/opt_table_elimination.cc 2009-08-25 10:38:22 +0000
@@ -490,7 +490,7 @@
{
Item *tmp=new Item_null;
if (tmp)
- add_eq_mod(fda, eq_mod, *and_level, cond_func, args[0], args[1]);
+ add_eq_mod(fda, eq_mod, *and_level, cond_func, args[0], tmp);
break;
}
case Item_func::MULT_EQUAL_FUNC:
@@ -828,7 +828,7 @@
{
Table_value *tbl_dep;
if (!(tbl_dep= new Table_value(table)))
- return NULL; /* purecov: inspected */
+ return NULL;
Key_module **key_list= &(tbl_dep->keys);
/* Add dependencies for unique keys */
@@ -853,15 +853,8 @@
static Field_value *get_field_value(Func_dep_analyzer *fda, Field *field)
{
TABLE *table= field->table;
- Table_value *tbl_dep;
+ Table_value *tbl_dep= fda->table_deps[table->tablenr];
- /* First, get the table*/
- if (!(tbl_dep= fda->table_deps[table->tablenr]))
- {
- if (!(tbl_dep= get_table_value(fda, table)))
- return NULL;
- }
-
/* Try finding the field in field list */
Field_value **pfield= &(tbl_dep->fields);
while (*pfield && (*pfield)->field->field_index < field->field_index)
1
0
[Maria-developers] Rev 2744: MWL#17: Table elimination in file:///home/psergey/dev/maria-5.1-table-elim-r11-gcov/
by Sergey Petrunya 25 Aug '09
by Sergey Petrunya 25 Aug '09
25 Aug '09
At file:///home/psergey/dev/maria-5.1-table-elim-r11-gcov/
------------------------------------------------------------
revno: 2744
revision-id: psergey(a)askmonty.org-20090825092750-mnmatimn7cxm4rl8
parent: psergey(a)askmonty.org-20090824191048-xev0gm1miw6ezz2r
committer: Sergey Petrunya <psergey(a)askmonty.org>
branch nick: maria-5.1-table-elim-r11-gcov
timestamp: Tue 2009-08-25 12:27:50 +0300
message:
MWL#17: Table elimination
- Add more testcases.
- Fix trivial compile failure
- Remove handling of "column IN (one_element)". This is converted to equality
elsewhere
=== modified file 'mysql-test/r/table_elim.result'
--- a/mysql-test/r/table_elim.result 2009-08-24 08:12:42 +0000
+++ b/mysql-test/r/table_elim.result 2009-08-25 09:27:50 +0000
@@ -307,3 +307,41 @@
select * from t2;
a b
drop table t1, t2;
+#
+# Tests with various edge-case ON expressions
+#
+create table t1 (a int, b int, c int, d int);
+insert into t1 values (0,0,0,0),(1,1,1,1),(2,2,2,2),(3,3,3,3);
+create table t2 (pk int primary key, b int)
+as select a as pk, a as b from t1 where a in (1,2);
+create table t3 (pk int primary key, b int)
+as select a as pk, a as b from t1 where a in (1,3);
+explain select t1.a from t1 left join t2 on t2.pk=t1.a and t2.b<t1.b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4
+explain select t1.a from t1 left join t2 on t2.pk=t1.a or t2.b<t1.b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4
+1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 2
+explain select t1.a from t1 left join t2 on t2.b<t1.b or t2.pk=t1.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4
+1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 2
+explain select t1.a from t1 left join t2 on t2.pk between 10 and 20;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4
+1 SIMPLE t2 index PRIMARY PRIMARY 4 NULL 2 Using index
+explain select t1.a from t1 left join t2 on t2.pk between 0.5 and 1.5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4
+1 SIMPLE t2 index PRIMARY PRIMARY 4 NULL 2 Using index
+explain select t1.a from t1 left join t2 on t2.pk between 10 and 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4
+explain select t1.a from t1 left join t2 on t2.pk in (10);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4
+explain select t1.a from t1 left join t2 on t2.pk in (t1.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4
+drop table t1,t2,t3;
=== modified file 'mysql-test/t/table_elim.test'
--- a/mysql-test/t/table_elim.test 2009-08-24 08:12:42 +0000
+++ b/mysql-test/t/table_elim.test 2009-08-25 09:27:50 +0000
@@ -249,3 +249,30 @@
select * from t2;
drop table t1, t2;
+--echo #
+--echo # Tests with various edge-case ON expressions
+--echo #
+create table t1 (a int, b int, c int, d int);
+insert into t1 values (0,0,0,0),(1,1,1,1),(2,2,2,2),(3,3,3,3);
+
+create table t2 (pk int primary key, b int)
+ as select a as pk, a as b from t1 where a in (1,2);
+
+create table t3 (pk1 int, pk2 int, b int, unique(pk1,pk2));
+insert into t3 select a as pk1, a as pk2, a as b from t1 where a in (1,3);
+
+explain select t1.a from t1 left join t2 on t2.pk=t1.a and t2.b<t1.b;
+explain select t1.a from t1 left join t2 on t2.pk=t1.a or t2.b<t1.b;
+explain select t1.a from t1 left join t2 on t2.b<t1.b or t2.pk=t1.a;
+
+explain select t1.a from t1 left join t2 on t2.pk between 10 and 20;
+explain select t1.a from t1 left join t2 on t2.pk between 0.5 and 1.5;
+explain select t1.a from t1 left join t2 on t2.pk between 10 and 10;
+
+explain select t1.a from t1 left join t2 on t2.pk in (10);
+explain select t1.a from t1 left join t2 on t2.pk in (t1.a);
+
+explain select t1.a from t1 left join t2 on TRUE;
+
+drop table t1,t2,t3;
+
=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc 2009-08-24 19:10:48 +0000
+++ b/sql/mysqld.cc 2009-08-25 09:27:50 +0000
@@ -393,6 +393,8 @@
"index_merge_intersection=on"
#ifndef DBUG_OFF
",table_elimination=on";
+#else
+ ;
#endif
static char *mysqld_user, *mysqld_chroot, *log_error_file_ptr;
static char *opt_init_slave, *language_ptr, *opt_init_connect;
=== modified file 'sql/opt_table_elimination.cc'
--- a/sql/opt_table_elimination.cc 2009-08-24 19:10:48 +0000
+++ b/sql/opt_table_elimination.cc 2009-08-25 09:27:50 +0000
@@ -467,15 +467,6 @@
Item **args= cond_func->arguments();
switch (cond_func->functype()) {
- case Item_func::IN_FUNC:
- {
- if (cond_func->argument_count() == 2)
- {
- add_eq_mod(fda, eq_mod, *and_level, cond_func, args[0], args[1]);
- add_eq_mod(fda, eq_mod, *and_level, cond_func, args[1], args[0]);
- }
- break;
- }
case Item_func::BETWEEN:
{
Item *fld;
@@ -837,7 +828,7 @@
{
Table_value *tbl_dep;
if (!(tbl_dep= new Table_value(table)))
- return NULL;
+ return NULL; /* purecov: inspected */
Key_module **key_list= &(tbl_dep->keys);
/* Add dependencies for unique keys */
@@ -1499,6 +1490,7 @@
#ifndef DBUG_OFF
+/* purecov: begin inspected */
static
void dbug_print_deps(Func_dep_analyzer *fda)
{
@@ -1559,6 +1551,7 @@
DBUG_UNLOCK_FILE;
DBUG_VOID_RETURN;
}
+/* purecov: end */
#endif
/**
1
0
[Maria-developers] Rev 2743: MWL#17: Table elimination: last fixes in file:///home/psergey/dev/maria-5.1-table-elim-r11/
by Sergey Petrunya 24 Aug '09
by Sergey Petrunya 24 Aug '09
24 Aug '09
At file:///home/psergey/dev/maria-5.1-table-elim-r11/
------------------------------------------------------------
revno: 2743
revision-id: psergey(a)askmonty.org-20090824191048-xev0gm1miw6ezz2r
parent: psergey(a)askmonty.org-20090824081242-32o90vv8awk27sut
committer: Sergey Petrunya <psergey(a)askmonty.org>
branch nick: maria-5.1-table-elim-r11
timestamp: Mon 2009-08-24 22:10:48 +0300
message:
MWL#17: Table elimination: last fixes
- Add an @@optimizer_switch flag for table_elimination for debug build
- Better comments
=== modified file 'mysql-test/t/index_merge_myisam.test'
--- a/mysql-test/t/index_merge_myisam.test 2009-03-14 18:58:23 +0000
+++ b/mysql-test/t/index_merge_myisam.test 2009-08-24 19:10:48 +0000
@@ -25,15 +25,19 @@
--echo # we get another @@optimizer_switch user)
--echo #
+--replace_regex /,table_elimination=on//
select @@optimizer_switch;
set optimizer_switch='index_merge=off,index_merge_union=off';
+--replace_regex /,table_elimination=on//
select @@optimizer_switch;
set optimizer_switch='index_merge_union=on';
+--replace_regex /,table_elimination=on//
select @@optimizer_switch;
set optimizer_switch='default,index_merge_sort_union=off';
+--replace_regex /,table_elimination=on//
select @@optimizer_switch;
--error ER_WRONG_VALUE_FOR_VAR
@@ -71,17 +75,21 @@
set optimizer_switch=default;
set optimizer_switch='index_merge=off,index_merge_union=off,default';
+--replace_regex /,table_elimination=on//
select @@optimizer_switch;
set optimizer_switch=default;
# Check setting defaults for global vars
+--replace_regex /,table_elimination=on//
select @@global.optimizer_switch;
set @@global.optimizer_switch=default;
+--replace_regex /,table_elimination=on//
select @@global.optimizer_switch;
--echo #
--echo # Check index_merge's @@optimizer_switch flags
--echo #
+--replace_regex /,table_elimination.on//
select @@optimizer_switch;
create table t0 (a int);
@@ -182,6 +190,7 @@
explain select * from t1 where a=10 and b=10 or c=10;
set optimizer_switch=default;
+--replace_regex /,table_elimination.on//
show variables like 'optimizer_switch';
drop table t0, t1;
=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h 2009-04-25 10:05:32 +0000
+++ b/sql/mysql_priv.h 2009-08-24 19:10:48 +0000
@@ -528,14 +528,27 @@
#define OPTIMIZER_SWITCH_INDEX_MERGE_UNION 2
#define OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION 4
#define OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT 8
-#define OPTIMIZER_SWITCH_LAST 16
-
+
+#ifdef DBUG_OFF
+# define OPTIMIZER_SWITCH_LAST 16
+#else
+# define OPTIMIZER_SWITCH_TABLE_ELIMINATION 16
+# define OPTIMIZER_SWITCH_LAST 32
+#endif
+
+#ifdef DBUG_OFF
/* The following must be kept in sync with optimizer_switch_str in mysqld.cc */
-#define OPTIMIZER_SWITCH_DEFAULT (OPTIMIZER_SWITCH_INDEX_MERGE | \
- OPTIMIZER_SWITCH_INDEX_MERGE_UNION | \
- OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION | \
- OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT)
-
+# define OPTIMIZER_SWITCH_DEFAULT (OPTIMIZER_SWITCH_INDEX_MERGE | \
+ OPTIMIZER_SWITCH_INDEX_MERGE_UNION | \
+ OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION | \
+ OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT)
+#else
+# define OPTIMIZER_SWITCH_DEFAULT (OPTIMIZER_SWITCH_INDEX_MERGE | \
+ OPTIMIZER_SWITCH_INDEX_MERGE_UNION | \
+ OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION | \
+ OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT | \
+ OPTIMIZER_SWITCH_TABLE_ELIMINATION)
+#endif
/*
Replication uses 8 bytes to store SQL_MODE in the binary log. The day you
=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc 2009-05-19 09:28:05 +0000
+++ b/sql/mysqld.cc 2009-08-24 19:10:48 +0000
@@ -297,9 +297,14 @@
static const char *optimizer_switch_names[]=
{
- "index_merge","index_merge_union","index_merge_sort_union",
- "index_merge_intersection", "default", NullS
+ "index_merge","index_merge_union","index_merge_sort_union",
+ "index_merge_intersection",
+#ifndef DBUG_OFF
+ "table_elimination",
+#endif
+ "default", NullS
};
+
/* Corresponding defines are named OPTIMIZER_SWITCH_XXX */
static const unsigned int optimizer_switch_names_len[]=
{
@@ -307,6 +312,9 @@
sizeof("index_merge_union") - 1,
sizeof("index_merge_sort_union") - 1,
sizeof("index_merge_intersection") - 1,
+#ifndef DBUG_OFF
+ sizeof("table_elimination") - 1,
+#endif
sizeof("default") - 1
};
TYPELIB optimizer_switch_typelib= { array_elements(optimizer_switch_names)-1,"",
@@ -382,7 +390,10 @@
/* Text representation for OPTIMIZER_SWITCH_DEFAULT */
static const char *optimizer_switch_str="index_merge=on,index_merge_union=on,"
"index_merge_sort_union=on,"
- "index_merge_intersection=on";
+ "index_merge_intersection=on"
+#ifndef DBUG_OFF
+ ",table_elimination=on";
+#endif
static char *mysqld_user, *mysqld_chroot, *log_error_file_ptr;
static char *opt_init_slave, *language_ptr, *opt_init_connect;
static char *default_character_set_name;
@@ -6929,8 +6940,11 @@
0, GET_ULONG, OPT_ARG, MAX_TABLES+1, 0, MAX_TABLES+2, 0, 1, 0},
{"optimizer_switch", OPT_OPTIMIZER_SWITCH,
"optimizer_switch=option=val[,option=val...], where option={index_merge, "
- "index_merge_union, index_merge_sort_union, index_merge_intersection} and "
- "val={on, off, default}.",
+ "index_merge_union, index_merge_sort_union, index_merge_intersection"
+#ifndef DBUG_OFF
+ ", table_elimination"
+#endif
+ "} and val={on, off, default}.",
(uchar**) &optimizer_switch_str, (uchar**) &optimizer_switch_str, 0, GET_STR, REQUIRED_ARG,
/*OPTIMIZER_SWITCH_DEFAULT*/0,
0, 0, 0, 0, 0},
=== modified file 'sql/opt_table_elimination.cc'
--- a/sql/opt_table_elimination.cc 2009-08-24 08:12:42 +0000
+++ b/sql/opt_table_elimination.cc 2009-08-24 19:10:48 +0000
@@ -18,6 +18,7 @@
/*
OVERVIEW
+ ========
This file contains table elimination module. The idea behind table
elimination is as follows: suppose we have a left join
@@ -36,7 +37,9 @@
null-complemented one) and we don't care about what that record combination
is.
+
MODULE INTERFACE
+ ================
The module has one entry point - eliminate_tables() function, which one
needs to call (once) at some point before the join optimization.
@@ -58,23 +61,25 @@
Table elimination is redone on every PS re-execution.
+
TABLE ELIMINATION ALGORITHM FOR ONE OUTER JOIN
+ ==============================================
- As said above, we can remove inner side of an outer join if it is
+ As described above, we can remove inner side of an outer join if it is
1. not referred to from any other parts of the query
2. always produces one matching record combination.
- We check #1 by doing a recursive descent down the join->join_list while
- maintaining a union of used_tables() attribute of all expressions we've seen
- "elsewhere". When we encounter an outer join, we check if the bitmap of
- tables on its inner side has an intersection with tables that are used
+ We check #1 by doing a recursive descent down the join->join_list while
+ maintaining a union of used_tables() attribute of all Item expressions in
+ other parts of the query. When we encounter an outer join, we check if the
+ bitmap of tables on its inner side has intersection with tables that are used
elsewhere. No intersection means that inner side of the outer join could
potentially be eliminated.
In order to check #2, one needs to prove that inner side of an outer join
- is functionally dependent on the outside. We prove dependency by proving
- functional dependency of intermediate objects:
+ is functionally dependent on the outside. The proof is constructed from
+ functional dependencies of intermediate objects:
- Inner side of outer join is functionally dependent when each of its tables
are functionally dependent. (We assume a table is functionally dependent
@@ -91,14 +96,15 @@
where expr is functionally-depdendent.
- Apparently the above rules can be applied recursively. Also, certain entities
- depend on multiple other entities. We model this by a bipartite graph which
- has two kinds of nodes:
+ These relationships are modeled as a bipartite directed graph that has
+ dependencies as edges and two kinds of nodes:
Value nodes:
- Table column values (each is a value of tblX.columnY)
- - Table nodes (each node represents a table inside an eliminable join nest).
- each value is either bound (i.e. functionally dependent) or not.
+ - Table values (each node represents a table inside the join nest we're
+ trying to eliminate).
+ A value has one attribute, it is either bound (i.e. functionally dependent)
+ or not.
Module nodes:
- Modules representing tblX.colY=expr equalities. Equality module has
@@ -118,11 +124,54 @@
(their expressions are either constant or depend only on tables that are
outside of the outer join in question) and performns a breadth-first
traversal. If we reach the outer join nest node, it means outer join is
- functionally-dependant and can be eliminated. Otherwise it cannot.
+ functionally-dependant and can be eliminated. Otherwise it cannot be.
- HANDLING MULTIPLE NESTED OUTER JOINS
- (TODO : explanations why 'local bottom up is sufficient')
-
+ HANDLING MULTIPLE NESTED OUTER JOINS
+ ====================================
+
+ Outer joins that are not nested one within another are eliminated
+ independently. For nested outer joins we have the following considerations:
+
+ 1. ON expressions from children outer joins must be taken into account
+
+ Consider this example:
+
+ SELECT t0.*
+ FROM
+ t0
+ LEFT JOIN
+ (t1 LEFT JOIN t2 ON t2.primary_key=t1.col1)
+ ON
+ t1.primary_key=t0.col AND t2.col1=t1.col2
+
+ Here we cannot eliminate the "... LEFT JOIN t2 ON ..." part alone because the
+ ON clause of top level outer join has references to table t2.
+ We can eliminate the entire "... LEFT JOIN (t1 LEFT JOIN t2) ON .." part,
+ but in order to do that, we must look at both ON expressions.
+
+ 2. ON expressions of parent outer joins are useless.
+ Consider an example:
+
+ SELECT t0.*
+ FROM
+ t0
+ LEFT JOIN
+ (t1 LEFT JOIN t2 ON some_expr)
+ ON
+ t2.primary_key=t1.col -- (*)
+
+ Here the uppermost ON expression has a clause that gives us functional
+ dependency of table t2 on t1 and hence could be used to eliminate the
+ "... LEFT JOIN t2 ON..." part.
+ However, we would not actually encounter this situation, because before the
+ table elimination we run simplify_joins(), which, among other things, upon
+ seeing a functional dependency condition like (*) will convert the outer join
+ of
+
+ "... LEFT JOIN t2 ON ..."
+
+ into inner join and thus make table elimination not to consider eliminating
+ table t2.
*/
class Value_dep;
@@ -157,7 +206,7 @@
/*
A table field value. There is exactly only one such object for any tblX.fieldY
- - the field epends on its table and equalities
+ - the field depends on its table and equalities
- expressions that use the field are its dependencies
*/
class Field_value : public Value_dep
@@ -175,26 +224,23 @@
field_index
*/
Field_value *next_table_field;
- /*
- Offset of our part of the bitmap psergey-todo: better comment!
+ /*
+ Offset to bits in Func_dep_analyzer::expr_deps
*/
uint bitmap_offset;
- /*
- Field became known. Check out
- - unique keys we belong to
- - expressions that depend on us.
- */
void now_bound(Func_dep_analyzer *fda, Module_dep **bound_modules);
void signal_from_field_to_exprs(Func_dep_analyzer* fda,
Module_dep **bound_modules);
};
+
/*
A table value. There is one Table_value object for every table that can
potentially be eliminated.
+ Dependencies:
- table depends on any of its unique keys
- - has its fields and embedding outer join as dependency.
+ - has its fields and embedding outer join as dependency
*/
class Table_value : public Value_dep
{
@@ -205,13 +251,13 @@
TABLE *table;
Field_value *fields; /* Ordered list of fields that belong to this table */
Key_module *keys; /* Ordered list of Unique keys in this table */
- //Outer_join_module *outer_join_dep;
void now_bound(Func_dep_analyzer *fda, Module_dep **bound_modules);
};
/*
- A 'module'. Module has dependencies
+ A 'module'. Module has unsatisfied dependencies, number of whose is stored in
+ unknown_args. Modules also can be linked together in a list.
*/
class Module_dep : public Sql_alloc
@@ -232,10 +278,11 @@
/*
This represents either
- - "tbl.column= expr" equality dependency, i.e. tbl.column depends on fields
+ - "tbl.column= expr" equality dependency, i.e. tbl.column depends on fields
used in the expression, or
- tbl1.col1=tbl2.col2=... multi-equality.
*/
+
class Equality_module : public Module_dep
{
public:
@@ -314,7 +361,11 @@
/* Element for the outer join we're attempting to eliminate */
Outer_join_module *outer_join_dep;
- /* Bitmap of how expressions depend on bits */
+ /*
+ Bitmap of how expressions depend on bits. Given a Field_value object,
+ one can check bitmap_is_set(expr_deps, field_val->bitmap_offset + expr_no)
+ to see if expression equality_mods[expr_no] depends on the given field.
+ */
MY_BITMAP expr_deps;
};
@@ -453,11 +504,23 @@
}
case Item_func::MULT_EQUAL_FUNC:
{
+ /*
+ The condition is a
+
+ tbl1.field1 = tbl2.field2 = tbl3.field3 [= const_expr]
+
+ multiple-equality. Do two things:
+ - Collect an ordered List<Field_value> of tblX.colY where tblX is one
+ of those that we're trying to eliminate.
+ - rembember if there was a const_expr or tblY.colZ that we can consider
+ bound.
+ Store all collected information in a Equality_module object.
+ */
Item_equal *item_equal= (Item_equal*)cond;
List<Field_value> *fvl;
if (!(fvl= new List<Field_value>))
break;
-
+
Item_equal_iterator it(*item_equal);
Item_field *item;
Item *bound_item= item_equal->get_const();
@@ -554,9 +617,9 @@
Equality_module *end, uint and_level)
{
if (start == new_fields)
- return start; // Impossible or
+ return start; /* (nothing) OR (...) -> (nothing) */
if (new_fields == end)
- return start; // No new fields, skip all
+ return start; /* (...) OR (nothing) -> (nothing) */
Equality_module *first_free=new_fields;
@@ -564,28 +627,6 @@
{
for (Equality_module *old=start ; old != first_free ; old++)
{
- /*
- Merge multiple-equalities:
- A: YES.
- (a=b=c) OR (a=b=d) produce "a=b".
-
- TODO:
- sort by (table_ptr, column_index)
- then run along the two and produce an intersection
-
- Q: What about constants?
- a=b=3 OR a=b=5 -> a=b= (either 3 or 5)
-
- a=b OR a=b=5 -> a=b= (any constant)
- A: keep the constant iff it is present in both sides and is the same.
-
- class Multi_equality
- {
- Item *const_item;
- List<...) list;
- };
-
- */
if (old->field == new_fields->field)
{
if (!old->field)
@@ -616,7 +657,7 @@
}
else
{
- // no single constant/bound item.
+ /* no single constant/bound item. */
old->expression= NULL;
}
@@ -975,7 +1016,7 @@
}
else
{
- /* It's a multi-equality*/
+ /* It's a multi-equality */
eq_mod->unknown_args= !test(eq_mod->expression);
List_iterator<Field_value> it(*eq_mod->mult_equal_fields);
Field_value* field_val;
@@ -1050,6 +1091,11 @@
if (!join->outer_join)
DBUG_VOID_RETURN;
+#ifndef DBUG_OFF
+ if (!optimizer_flag(thd, OPTIMIZER_SWITCH_TABLE_ELIMINATION))
+ DBUG_VOID_RETURN;
+#endif
+
/* Find the tables that are referred to from WHERE/HAVING */
used_tables= (join->conds? join->conds->used_tables() : 0) |
(join->having? join->having->used_tables() : 0);
@@ -1188,7 +1234,7 @@
/*
- Check if condition makes the a set of tables functionally-dependent
+ Check if given condition makes given set of tables functionally-dependent
SYNOPSIS
check_func_dependency()
@@ -1197,8 +1243,8 @@
cond Condition to use
DESCRIPTION
- Check if condition allows to conclude that the table set is functionally
- dependent on everything else.
+ Check if we can use given condition to infer that the set of given tables
+ is functionally-dependent on everything else.
RETURN
TRUE - Yes, functionally dependent
@@ -1216,7 +1262,10 @@
Func_dep_analyzer fda(join);
- /* Start value */
+ /*
+ Pre-alloc some Equality_module structures. We don't need this to be
+ guaranteed upper bound.
+ */
fda.n_equality_mods_alloced=
join->thd->lex->current_select->max_equal_elems +
(join->thd->lex->current_select->cond_count+1)*2 +
@@ -1249,7 +1298,7 @@
fda.usable_tables= dep_tables;
/*
Analyze the the ON expression and create Equality_module objects and
- Field_value objects for their left parts.
+ Field_value objects for the used fields.
*/
uint and_level=0;
build_eq_mods_for_cond(&fda, &last_eq_mod, &and_level, cond);
@@ -1264,14 +1313,14 @@
DBUG_EXECUTE("test", dbug_print_deps(&fda); );
- /* The running wave algorithm itself: */
+ /* The forward running wave algorithm: */
Value_dep *bound_values= NULL;
while (bound_modules)
{
for (;bound_modules; bound_modules= bound_modules->next)
{
if (bound_modules->now_bound(&fda, &bound_values))
- return TRUE; /* Dependent! */
+ return TRUE; /* Dependent */
}
for (;bound_values; bound_values=bound_values->next)
bound_values->now_bound(&fda, &bound_modules);
@@ -1280,17 +1329,12 @@
}
-/*
- Table is known means that
- - one more element in outer join nest is known
- - all its fields are known
-*/
-
void Table_value::now_bound(Func_dep_analyzer *fda,
Module_dep **bound_modules)
{
DBUG_PRINT("info", ("table %s is now bound", table->alias));
-
+
+ /* Signal to all fields that they are now bound */
for (Field_value *field_dep= fields; field_dep;
field_dep= field_dep->next_table_field)
{
@@ -1302,6 +1346,7 @@
}
}
+ /* Signal to outer join that one more table is known */
if (fda->outer_join_dep->unknown_args &&
!--fda->outer_join_dep->unknown_args)
{
@@ -1318,6 +1363,7 @@
DBUG_PRINT("info", ("field %s.%s is now bound", field->table->alias,
field->field_name));
+ /* Signal to unique keys and expressions that use this field*/
for (Key_module *key_dep= table->keys; key_dep;
key_dep= key_dep->next_table_key)
{
@@ -1337,8 +1383,8 @@
/*
- Walk through expressions that depend on this field and 'notify' them
- that this field is no longer unknown.
+ Walk through expressions that depend on this field and notify them
+ that this field is now known.
*/
void Field_value::signal_from_field_to_exprs(Func_dep_analyzer* fda,
Module_dep **bound_modules)
@@ -1362,16 +1408,16 @@
Value_dep **bound_values)
{
DBUG_PRINT("info", ("Outer join eliminated"));
- return TRUE; /* Signal to finish the process */
+ return TRUE; /* Signal out that the search is finished */
}
bool Equality_module::now_bound(Func_dep_analyzer *fda,
Value_dep **bound_values)
{
- /* For field=expr and we got to know the expr, so we know the field */
if (mult_equal_fields)
{
+ /* It's a=b=c=... multiple equality. Mark all equality members as known. */
List_iterator<Field_value> it(*mult_equal_fields);
Field_value *fv;
while ((fv= it++))
@@ -1387,6 +1433,7 @@
}
else
{
+ /* It's a fieldX=exprY equality. Mark exprY as known */
if (!field->bound)
{
/* Mark as bound and add to the list */
@@ -1398,7 +1445,9 @@
return FALSE;
}
+
/* Unique key is known means its table is known */
+
bool Key_module::now_bound(Func_dep_analyzer *fda, Value_dep **bound_values)
{
if (!table->bound)
1
0
[Maria-developers] bzr commit into MariaDB 5.1, with Maria 1.5:maria branch (knielsen:2720)
by knielsenï¼ knielsen-hq.org 24 Aug '09
by knielsenï¼ knielsen-hq.org 24 Aug '09
24 Aug '09
#At lp:maria
2720 knielsen(a)knielsen-hq.org 2009-08-24
Fix most Compiler warnings seen in buildbot.
This includes fixing a bug in option parsing; test case for this bug added.
Also add suppressions for a few warnings that cannot be meaningfully fixed by
MariaDB developers.
added:
mysql-test/r/plugin_load2.result
mysql-test/t/plugin_load2-master.opt
mysql-test/t/plugin_load2.test
support-files/ccfilter
modified:
mysys/my_compress.c
mysys/my_getopt.c
sql/mysqld.cc
storage/xtradb/fil/fil0fil.c
storage/xtradb/mtr/mtr0mtr.c
storage/xtradb/srv/srv0srv.c
storage/xtradb/srv/srv0start.c
support-files/compiler_warnings.supp
=== added file 'mysql-test/r/plugin_load2.result'
--- a/mysql-test/r/plugin_load2.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/plugin_load2.result 2009-08-24 13:56:18 +0000
@@ -0,0 +1,2 @@
+SELECT @@global.example_enum_var = 'e2';
+ERROR HY000: Unknown system variable 'example_enum_var'
=== added file 'mysql-test/t/plugin_load2-master.opt'
--- a/mysql-test/t/plugin_load2-master.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/plugin_load2-master.opt 2009-08-24 13:56:18 +0000
@@ -0,0 +1,3 @@
+$EXAMPLE_PLUGIN_OPT
+"--plugin-load=;EXAMPLE=ha_example.so;"
+--loose-plugin-example-enum-var=nonexistientvalue
=== added file 'mysql-test/t/plugin_load2.test'
--- a/mysql-test/t/plugin_load2.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/plugin_load2.test 2009-08-24 13:56:18 +0000
@@ -0,0 +1,12 @@
+--source include/have_example_plugin.inc
+
+# Test for bug in parsing plugin enum option.
+# The bug was that the error from parsing a non-existent value was not properly
+# handled, so the variable was assigned some arbitrary wrong value.
+#
+# We test this by passing --loose-plugin-example-enum-var=nonexistientvalue in
+# the .opt file of the test case, and check that the variable is not wrongly
+# set to a value in this case.
+
+--error 1193
+SELECT @@global.example_enum_var = 'e2';
=== modified file 'mysys/my_compress.c'
--- a/mysys/my_compress.c 2009-05-22 12:38:50 +0000
+++ b/mysys/my_compress.c 2009-08-24 13:56:18 +0000
@@ -81,12 +81,13 @@ my_bool my_compress(uchar *packet, size_
This fix is safe, since such memory is only used internally by zlib, so we
will not hide any bugs in mysql this way.
*/
-void *my_az_allocator(void *dummy, unsigned int items, unsigned int size)
+void *my_az_allocator(void *dummy __attribute__((unused)), unsigned int items,
+ unsigned int size)
{
return my_malloc((size_t)items*(size_t)size, IF_VALGRIND(MY_ZEROFILL, MYF(0)));
}
-void my_az_free(void *dummy, void *address)
+void my_az_free(void *dummy __attribute__((unused)), void *address)
{
my_free(address, MYF(MY_ALLOW_ZERO_PTR));
}
=== modified file 'mysys/my_getopt.c'
--- a/mysys/my_getopt.c 2009-05-20 15:34:34 +0000
+++ b/mysys/my_getopt.c 2009-08-24 13:56:18 +0000
@@ -603,6 +603,7 @@ static int setval(const struct my_option
my_bool set_maximum_value)
{
int err= 0;
+ int pos;
if (value && argument)
{
@@ -647,7 +648,9 @@ static int setval(const struct my_option
return EXIT_OUT_OF_MEMORY;
break;
case GET_ENUM:
- if (((*(ulong *)result_pos)= find_type(argument, opts->typelib, 2) - 1) < 0)
+ pos = find_type(argument, opts->typelib, 2) - 1;
+ (*(ulong *)result_pos)= pos;
+ if (pos < 0)
return EXIT_ARGUMENT_INVALID;
break;
case GET_SET:
=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc 2009-05-19 09:28:05 +0000
+++ b/sql/mysqld.cc 2009-08-24 13:56:18 +0000
@@ -1002,6 +1002,7 @@ static void close_connections(void)
}
+#ifdef HAVE_CLOSE_SERVER_SOCK
static void close_socket(my_socket sock, const char *info)
{
DBUG_ENTER("close_socket");
@@ -1021,6 +1022,7 @@ static void close_socket(my_socket sock,
}
DBUG_VOID_RETURN;
}
+#endif
static void close_server_sock()
=== modified file 'storage/xtradb/fil/fil0fil.c'
--- a/storage/xtradb/fil/fil0fil.c 2009-06-25 01:43:25 +0000
+++ b/storage/xtradb/fil/fil0fil.c 2009-08-24 13:56:18 +0000
@@ -45,7 +45,9 @@ Created 10/25/1995 Heikki Tuuri
#include "trx0trx.h"
#include "trx0sys.h"
#include "pars0pars.h"
+#include "row0row.h"
#include "row0mysql.h"
+#include "que0que.h"
/*
@@ -3134,7 +3136,7 @@ skip_info:
rec_offs_init(offsets_);
- fprintf(stderr, "InnoDB: Progress in %:");
+ fprintf(stderr, "%s", "InnoDB: Progress in %:");
for (offset = 0; offset < size_bytes; offset += UNIV_PAGE_SIZE) {
success = os_file_read(file, page,
=== modified file 'storage/xtradb/mtr/mtr0mtr.c'
--- a/storage/xtradb/mtr/mtr0mtr.c 2009-06-25 01:43:25 +0000
+++ b/storage/xtradb/mtr/mtr0mtr.c 2009-08-24 13:56:18 +0000
@@ -32,6 +32,7 @@ Created 11/26/1995 Heikki Tuuri
#include "page0types.h"
#include "mtr0log.h"
#include "log0log.h"
+#include "buf0flu.h"
/*********************************************************************
Releases the item in the slot given. */
=== modified file 'storage/xtradb/srv/srv0srv.c'
--- a/storage/xtradb/srv/srv0srv.c 2009-07-06 05:47:15 +0000
+++ b/storage/xtradb/srv/srv0srv.c 2009-08-24 13:56:18 +0000
@@ -1815,7 +1815,6 @@ srv_printf_innodb_monitor(
ulint btr_search_sys_subtotal;
ulint lock_sys_subtotal;
ulint recv_sys_subtotal;
- ulint io_counter_subtotal;
ulint i;
trx_t* trx;
=== modified file 'storage/xtradb/srv/srv0start.c'
--- a/storage/xtradb/srv/srv0start.c 2009-08-03 20:09:53 +0000
+++ b/storage/xtradb/srv/srv0start.c 2009-08-24 13:56:18 +0000
@@ -122,20 +122,6 @@ static char* srv_monitor_file_name;
#define SRV_MAX_N_PENDING_SYNC_IOS 100
-/* Avoid warnings when using purify */
-
-#ifdef HAVE_valgrind
-static int inno_bcmp(register const char *s1, register const char *s2,
- register uint len)
-{
- while ((len-- != 0) && (*s1++ == *s2++))
- ;
-
- return(len + 1);
-}
-#define memcmp(A,B,C) inno_bcmp((A),(B),(C))
-#endif
-
static
char*
srv_parse_megabytes(
=== added file 'support-files/ccfilter'
--- a/support-files/ccfilter 1970-01-01 00:00:00 +0000
+++ b/support-files/ccfilter 2009-08-24 13:56:18 +0000
@@ -0,0 +1,104 @@
+#! /usr/bin/perl
+
+# Post-processor for compiler output to filter out warnings matched in
+# support-files/compiler_warnings.supp. This makes it easier to check
+# that no new warnings are introduced without needing to submit a build
+# for Buildbot.
+#
+# Use by setting CC="ccfilter gcc" CXX="ccfilter gcc" before ./configure.
+#
+# By default, just filters the output for suppressed warnings. If the
+# FAILONWARNING environment variable is set, then instead will fail the
+# compile on encountering a non-suppressed warnings.
+
+use strict;
+use warnings;
+
+my $suppressions;
+
+open STDOUT_COPY, ">&STDOUT"
+ or die "Failed to dup stdout: $!]n";
+
+my $pid= open(PIPE, '-|');
+
+if (!defined($pid)) {
+ die "Error: Cannot fork(): $!\n";
+} elsif (!$pid) {
+ # Child.
+ # actually want to send the STDERR to the parent, not the STDOUT.
+ # So shuffle things around a bit.
+ open STDERR, ">&STDOUT"
+ or die "Child: Failed to dup pipe to parent: $!\n";
+ open STDOUT, ">&STDOUT_COPY"
+ or die "Child: Failed to dup parent stdout: $!\n";
+ close STDOUT_COPY;
+ exec { $ARGV[0] } @ARGV;
+ die "Child: exec() failed: $!\n";
+} else {
+ # Parent.
+ close STDOUT_COPY;
+ my $cwd= qx(pwd);
+ chomp($cwd);
+ while (<PIPE>) {
+ my $line= $_;
+ if (/^(.*?):([0-9]+): [Ww]arning: (.*)$/) {
+ my ($file, $lineno, $msg)= ($1, $2, $3);
+ $file= "$cwd/$file";
+
+ next
+ if check_if_suppressed($file, $lineno, $msg);
+ die "$line\nGot warning, terminating.\n"
+ if $ENV{FAILONWARNING};
+ print STDERR $line;
+ next;
+ }
+
+ print STDERR $line;
+ }
+ close(PIPE);
+}
+
+exit 0;
+
+sub check_if_suppressed {
+ my ($file, $lineno, $msg)= @_;
+ load_suppressions() unless defined($suppressions);
+ for my $s (@$suppressions) {
+ my ($file_re, $msg_re, $start, $end)= @$s;
+ if ($file =~ /$file_re/ &&
+ $msg =~ /$msg_re/ &&
+ (!defined($start) || $start <= $lineno) &&
+ (!defined($end) || $end >= $lineno)) {
+ return 1;
+ }
+ }
+ return undef;
+}
+
+sub load_suppressions {
+ # First find the suppressions file, might be we need to move up to
+ # the base directory.
+ my $path = "support-files/compiler_warnings.supp";
+ my $exists;
+ for (1..10) {
+ $exists= -f $path;
+ last if $exists;
+ $path= '../'. $path;
+ }
+ die "Error: Could not find suppression file (out of source dir?).\n"
+ unless $exists;
+
+ $suppressions= [];
+ open "F", "<", $path
+ or die "Error: Could not read suppression file '$path': $!\n";
+ while (<F>) {
+ # Skip comment and empty lines.
+ next if /^\s*(\#.*)?$/;
+ die "Invalid syntax in suppression file '$path', line $.:\n$_"
+ unless /^\s*(.+?)\s*:\s*(.+?)\s*(?:[:]\s*([0-9]+)(?:-([0-9]+))?\s*)?$/;
+ my ($file_re, $line_re, $start, $end)= ($1, $2, $3, $4);
+ $end = $start
+ if defined($start) && !defined($end);
+ push @$suppressions, [$file_re, $line_re, $start, $end];
+ }
+}
=== modified file 'support-files/compiler_warnings.supp'
--- a/support-files/compiler_warnings.supp 2008-01-11 17:39:43 +0000
+++ b/support-files/compiler_warnings.supp 2009-08-24 13:56:18 +0000
@@ -25,6 +25,9 @@ sql_yacc.cc : .*switch statement contain
pars0grm.tab.c: .*'yyerrorlab' : unreferenced label.*
_flex_tmp.c: .*not enough actual parameters for macro 'yywrap'.*
pars0lex.l: .*conversion from 'ulint' to 'int', possible loss of data.*
+btr/btr0cur\.c: .*value computed is not used.*: 3175-3375
+include/buf0buf\.ic: unused parameter ‘mtr’
+fil/fil0fil\.c: comparison between signed and unsigned : 3100-3199
#
# bdb is not critical to keep up to date
@@ -41,6 +44,12 @@ db_vrfy.c : .*comparison is always false
.*/cmd-line-utils/readline/.* : .*
#
+# Ignore some warnings in libevent, which is not maintained by us.
+#
+.*/extra/libevent/.* : .*unused parameter.*
+.*/extra/libevent/select\.c : .*comparison between signed and unsigned.* : 270-280
+
+#
# Ignore all conversion warnings on windows 64
# (Is safe as we are not yet supporting strings >= 2G)
#
1
0
[Maria-developers] Rev 2742: MWL#17: Table elimination in file:///home/psergey/dev/maria-5.1-table-elim-r11/
by Sergey Petrunya 24 Aug '09
by Sergey Petrunya 24 Aug '09
24 Aug '09
At file:///home/psergey/dev/maria-5.1-table-elim-r11/
------------------------------------------------------------
revno: 2742
revision-id: psergey(a)askmonty.org-20090824081242-32o90vv8awk27sut
parent: psergey(a)askmonty.org-20090821133606-2t7hib7wuctqller
committer: Sergey Petrunya <psergey(a)askmonty.org>
branch nick: maria-5.1-table-elim-r11
timestamp: Mon 2009-08-24 10:12:42 +0200
message:
MWL#17: Table elimination
- Correctly handle the case where we have multi-table DELETE and a table
that we're deleting from looks like it could be eliminated.
=== modified file 'mysql-test/r/table_elim.result'
--- a/mysql-test/r/table_elim.result 2009-08-21 07:48:22 +0000
+++ b/mysql-test/r/table_elim.result 2009-08-24 08:12:42 +0000
@@ -278,3 +278,32 @@
1 SIMPLE t1 index NULL PRIMARY 10 NULL 2 Using index
1 SIMPLE t2 ref a a 3 test.t1.a 2
drop table t1, t2;
+#
+# check UPDATE/DELETE that look like they could be eliminated
+#
+create table t1 (a int primary key, b int);
+insert into t1 values (1,1),(2,2),(3,3);
+create table t2 like t1;
+insert into t2 select * from t1;
+update t1 left join t2 using (a) set t2.a=t2.a+100;
+select * from t1;
+a b
+1 1
+2 2
+3 3
+select * from t2;
+a b
+101 1
+102 2
+103 3
+delete from t2;
+insert into t2 select * from t1;
+delete t2 from t1 left join t2 using (a);
+select * from t1;
+a b
+1 1
+2 2
+3 3
+select * from t2;
+a b
+drop table t1, t2;
=== modified file 'mysql-test/t/table_elim.test'
--- a/mysql-test/t/table_elim.test 2009-08-21 07:48:22 +0000
+++ b/mysql-test/t/table_elim.test 2009-08-24 08:12:42 +0000
@@ -229,3 +229,23 @@
drop table t1, t2;
+--echo #
+--echo # check UPDATE/DELETE that look like they could be eliminated
+--echo #
+create table t1 (a int primary key, b int);
+insert into t1 values (1,1),(2,2),(3,3);
+
+create table t2 like t1;
+insert into t2 select * from t1;
+update t1 left join t2 using (a) set t2.a=t2.a+100;
+select * from t1;
+select * from t2;
+
+delete from t2;
+insert into t2 select * from t1;
+
+delete t2 from t1 left join t2 using (a);
+select * from t1;
+select * from t2;
+drop table t1, t2;
+
=== modified file 'sql/opt_table_elimination.cc'
--- a/sql/opt_table_elimination.cc 2009-08-21 13:36:06 +0000
+++ b/sql/opt_table_elimination.cc 2009-08-24 08:12:42 +0000
@@ -1069,16 +1069,26 @@
if (join->select_lex == &thd->lex->select_lex)
{
- /* Multi-table UPDATE and DELETE: don't eliminate the tables we modify: */
- used_tables |= thd->table_map_for_update;
/* Multi-table UPDATE: don't eliminate tables referred from SET statement */
if (thd->lex->sql_command == SQLCOM_UPDATE_MULTI)
{
+ /* Multi-table UPDATE and DELETE: don't eliminate the tables we modify: */
+ used_tables |= thd->table_map_for_update;
List_iterator<Item> it2(thd->lex->value_list);
while ((item= it2++))
used_tables |= item->used_tables();
}
+
+ if (thd->lex->sql_command == SQLCOM_DELETE_MULTI)
+ {
+ TABLE_LIST *tbl;
+ for (tbl= (TABLE_LIST*)thd->lex->auxiliary_table_list.first;
+ tbl; tbl= tbl->next_local)
+ {
+ used_tables |= tbl->table->map;
+ }
+ }
}
table_map all_tables= join->all_tables_map();
1
0
[Maria-developers] Rev 2741: MWL#17: Table elimination in file:///home/psergey/dev/maria-5.1-table-elim-r11/
by Sergey Petrunya 21 Aug '09
by Sergey Petrunya 21 Aug '09
21 Aug '09
At file:///home/psergey/dev/maria-5.1-table-elim-r11/
------------------------------------------------------------
revno: 2741
revision-id: psergey(a)askmonty.org-20090821133606-2t7hib7wuctqller
parent: psergey(a)askmonty.org-20090821074822-6x2gv01r9ltt2bhc
committer: Sergey Petrunya <psergey(a)askmonty.org>
branch nick: maria-5.1-table-elim-r11
timestamp: Fri 2009-08-21 15:36:06 +0200
message:
MWL#17: Table elimination
- Remove a piece of code that's not needed anymore.
=== modified file 'sql/opt_table_elimination.cc'
--- a/sql/opt_table_elimination.cc 2009-08-21 07:48:22 +0000
+++ b/sql/opt_table_elimination.cc 2009-08-21 13:36:06 +0000
@@ -505,39 +505,6 @@
/*
- The only requirement of this function is to order fields in some
- deterministic way.
-*/
-
-int cmp_equal_fields(Item_field *field1, Item_field *field2, void *arg)
-{
- int cmp= 0;
- bool outer_ref= 0;
- if (field2->used_tables() & OUTER_REF_TABLE_BIT)
- {
- outer_ref= 1;
- cmp= -1;
- }
- if (field2->used_tables() & OUTER_REF_TABLE_BIT)
- {
- outer_ref= 1;
- cmp++;
- }
- if (outer_ref)
- return cmp;
- cmp= (int)field2->field->table->tablenr -
- (int)field1->field->table->tablenr;
- if (cmp)
- return cmp < 0 ? -1 : 1;
- cmp= (int)field2->field->field_index -
- (int)field1->field->field_index;
-
- return cmp < 0 ? -1 : (cmp ? 1 : 0);
-
-}
-
-
-/*
Perform an OR operation on two (adjacent) Equality_module arrays.
SYNOPSIS
1
0
[Maria-developers] Rev 2740: MWL#17: Table elimination in file:///home/psergey/dev/maria-5.1-table-elim-r11/
by Sergey Petrunya 21 Aug '09
by Sergey Petrunya 21 Aug '09
21 Aug '09
At file:///home/psergey/dev/maria-5.1-table-elim-r11/
------------------------------------------------------------
revno: 2740
revision-id: psergey(a)askmonty.org-20090821074822-6x2gv01r9ltt2bhc
parent: psergey(a)askmonty.org-20090820155102-5zvm1m6idmie9mmv
committer: Sergey Petrunya <psergey(a)askmonty.org>
branch nick: maria-5.1-table-elim-r11
timestamp: Fri 2009-08-21 09:48:22 +0200
message:
MWL#17: Table elimination
- More testcases
- Set correct dependencies for non-bound multi-equalities.
=== modified file 'mysql-test/r/table_elim.result'
--- a/mysql-test/r/table_elim.result 2009-08-17 16:07:24 +0000
+++ b/mysql-test/r/table_elim.result 2009-08-21 07:48:22 +0000
@@ -218,6 +218,21 @@
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.col 1
+explain select t1.*
+from
+t1 left join ( t2 left join t3 on t3.pk=t2.col or t3.pk=t2.col)
+on t2.col=t1.col or t2.col=t1.col;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2
+explain select t1.*, t2.*
+from
+t1 left join
+(t2 left join t3 on t3.pk=t2.col or t3.pk=t2.col)
+on t2.pk=t1.col or t2.pk=t1.col;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.col 1
drop table t1, t2, t3;
#
# Check things that look like functional dependencies but really are not
=== modified file 'mysql-test/t/table_elim.test'
--- a/mysql-test/t/table_elim.test 2009-08-17 16:07:24 +0000
+++ b/mysql-test/t/table_elim.test 2009-08-21 07:48:22 +0000
@@ -175,6 +175,17 @@
explain
select t1.*, t2.* from t1 left join (t2 left join t3 on t3.pk=t2.col) on t2.pk=t1.col;
+explain select t1.*
+from
+ t1 left join ( t2 left join t3 on t3.pk=t2.col or t3.pk=t2.col)
+ on t2.col=t1.col or t2.col=t1.col;
+
+explain select t1.*, t2.*
+from
+ t1 left join
+ (t2 left join t3 on t3.pk=t2.col or t3.pk=t2.col)
+ on t2.pk=t1.col or t2.pk=t1.col;
+
drop table t1, t2, t3;
--echo #
=== modified file 'sql/opt_table_elimination.cc'
--- a/sql/opt_table_elimination.cc 2009-08-20 15:51:02 +0000
+++ b/sql/opt_table_elimination.cc 2009-08-21 07:48:22 +0000
@@ -454,8 +454,6 @@
case Item_func::MULT_EQUAL_FUNC:
{
Item_equal *item_equal= (Item_equal*)cond;
- // const item is 'item', field -> NULL. mult_equal_fields <-- an ordered
- // list of
List<Field_value> *fvl;
if (!(fvl= new List<Field_value>))
break;
@@ -1001,17 +999,24 @@
deps_recorder.expr_offset= eq_mod - fda->equality_mods;
deps_recorder.saw_other_tbl= FALSE;
eq_mod->unknown_args= 0;
-
+
+ if (eq_mod->field)
+ {
/* Regular tbl.col=expr(tblX1.col1, tblY1.col2, ...) */
- eq_mod->expression->walk(&Item::check_column_usage_processor, FALSE,
- (uchar*)&deps_recorder);
-
- if (!eq_mod->field)
+ eq_mod->expression->walk(&Item::check_column_usage_processor, FALSE,
+ (uchar*)&deps_recorder);
+ }
+ else
{
- if (eq_mod->unknown_args)
- eq_mod->unknown_args= 1;
- if (deps_recorder.saw_other_tbl)
- eq_mod->unknown_args= 0;
+ /* It's a multi-equality*/
+ eq_mod->unknown_args= !test(eq_mod->expression);
+ List_iterator<Field_value> it(*eq_mod->mult_equal_fields);
+ Field_value* field_val;
+ while ((field_val= it++))
+ {
+ uint offs= field_val->bitmap_offset + eq_mod - fda->equality_mods;
+ bitmap_set_bit(&fda->expr_deps, offs);
+ }
}
if (!eq_mod->unknown_args)
1
0
[Maria-developers] Rev 2739: MWL#17: Table elimination in file:///home/psergey/dev/maria-5.1-table-elim-r11/
by Sergey Petrunya 20 Aug '09
by Sergey Petrunya 20 Aug '09
20 Aug '09
At file:///home/psergey/dev/maria-5.1-table-elim-r11/
------------------------------------------------------------
revno: 2739
revision-id: psergey(a)askmonty.org-20090820155102-5zvm1m6idmie9mmv
parent: psergey(a)askmonty.org-20090819120659-0ndd6mqxeetgee2n
committer: Sergey Petrunya <psergey(a)askmonty.org>
branch nick: maria-5.1-table-elim-r11
timestamp: Thu 2009-08-20 17:51:02 +0200
message:
MWL#17: Table elimination
- Multiple-equality handling
=== modified file 'sql/item_cmpfunc.h'
--- a/sql/item_cmpfunc.h 2008-12-12 11:13:11 +0000
+++ b/sql/item_cmpfunc.h 2009-08-20 15:51:02 +0000
@@ -1578,6 +1578,7 @@
uint members();
bool contains(Field *field);
Item_field* get_first() { return fields.head(); }
+ uint n_fields() { return fields.elements; }
void merge(Item_equal *item);
void update_const();
enum Functype functype() const { return MULT_EQUAL_FUNC; }
=== modified file 'sql/opt_table_elimination.cc'
--- a/sql/opt_table_elimination.cc 2009-08-19 12:06:59 +0000
+++ b/sql/opt_table_elimination.cc 2009-08-20 15:51:02 +0000
@@ -175,7 +175,10 @@
field_index
*/
Field_value *next_table_field;
- uint bitmap_offset; /* Offset of our part of the bitmap */
+ /*
+ Offset of our part of the bitmap psergey-todo: better comment!
+ */
+ uint bitmap_offset;
/*
Field became known. Check out
@@ -214,10 +217,6 @@
class Module_dep : public Sql_alloc
{
public:
- enum {
- MODULE_OUTER_JOIN
- } type; /* Type of the object */
-
virtual bool now_bound(Func_dep_analyzer *fda, Value_dep **bound_modules)=0;
virtual ~Module_dep(){}
/*
@@ -232,8 +231,10 @@
/*
- A "tbl.column= expr" equality dependency. tbl.column depends on fields
- used in expr.
+ This represents either
+ - "tbl.column= expr" equality dependency, i.e. tbl.column depends on fields
+ used in the expression, or
+ - tbl1.col1=tbl2.col2=... multi-equality.
*/
class Equality_module : public Module_dep
{
@@ -241,6 +242,8 @@
Field_value *field;
Item *expression;
+ List<Field_value> *mult_equal_fields;
+
/* Used during condition analysis only, similar to KEYUSE::level */
uint level;
bool now_bound(Func_dep_analyzer *fda, Value_dep **bound_values);
@@ -331,7 +334,7 @@
Item* cond);
static
-void build_eq_mods_for_cond(Func_dep_analyzer *fda, Equality_module **fdeps,
+void build_eq_mods_for_cond(Func_dep_analyzer *fda, Equality_module **eq_mod,
uint *and_level, Item *cond);
static
void add_eq_mod(Func_dep_analyzer *fda, Equality_module **eq_mod,
@@ -346,6 +349,9 @@
static Field_value *get_field_value(Func_dep_analyzer *fda, Field *field);
static void mark_as_eliminated(JOIN *join, TABLE_LIST *tbl);
+static void add_eq_mod2(Func_dep_analyzer *fda, Equality_module **eq_mod,
+ uint and_level, Field_value *field_val, Item *right,
+ List<Field_value>* mult_equal_fields);
#ifndef DBUG_OFF
@@ -360,7 +366,7 @@
SYNOPSIS
build_eq_mods_for_cond()
fda Table elimination context
- fdeps INOUT Put produced equality conditions here
+ eq_mod INOUT Put produced equality conditions here
and_level INOUT AND-level (like in add_key_fields)
cond Condition to process
@@ -369,34 +375,34 @@
*/
static
-void build_eq_mods_for_cond(Func_dep_analyzer *fda, Equality_module **fdeps,
+void build_eq_mods_for_cond(Func_dep_analyzer *fda, Equality_module **eq_mod,
uint *and_level, Item *cond)
{
if (cond->type() == Item_func::COND_ITEM)
{
List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
- Equality_module *org_key_fields= *fdeps;
+ Equality_module *org_key_fields= *eq_mod;
/* AND/OR */
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
{
Item *item;
while ((item=li++))
- build_eq_mods_for_cond(fda, fdeps, and_level, item);
- for (; org_key_fields != *fdeps ; org_key_fields++)
+ build_eq_mods_for_cond(fda, eq_mod, and_level, item);
+ for (; org_key_fields != *eq_mod ; org_key_fields++)
org_key_fields->level= *and_level;
}
else
{
Item *item;
(*and_level)++;
- build_eq_mods_for_cond(fda, fdeps, and_level, li++);
+ build_eq_mods_for_cond(fda, eq_mod, and_level, li++);
while ((item=li++))
{
- Equality_module *start_key_fields= *fdeps;
+ Equality_module *start_key_fields= *eq_mod;
(*and_level)++;
- build_eq_mods_for_cond(fda, fdeps, and_level, item);
- *fdeps= merge_func_deps(org_key_fields, start_key_fields, *fdeps,
+ build_eq_mods_for_cond(fda, eq_mod, and_level, item);
+ *eq_mod= merge_func_deps(org_key_fields, start_key_fields, *eq_mod,
++(*and_level));
}
}
@@ -414,8 +420,8 @@
{
if (cond_func->argument_count() == 2)
{
- add_eq_mod(fda, fdeps, *and_level, cond_func, args[0], args[1]);
- add_eq_mod(fda, fdeps, *and_level, cond_func, args[1], args[0]);
+ add_eq_mod(fda, eq_mod, *and_level, cond_func, args[0], args[1]);
+ add_eq_mod(fda, eq_mod, *and_level, cond_func, args[1], args[0]);
}
break;
}
@@ -426,62 +432,72 @@
(fld= args[0]->real_item())->type() == Item::FIELD_ITEM &&
args[1]->eq(args[2], ((Item_field*)fld)->field->binary()))
{
- add_eq_mod(fda, fdeps, *and_level, cond_func, args[0], args[1]);
- add_eq_mod(fda, fdeps, *and_level, cond_func, args[1], args[0]);
+ add_eq_mod(fda, eq_mod, *and_level, cond_func, args[0], args[1]);
+ add_eq_mod(fda, eq_mod, *and_level, cond_func, args[1], args[0]);
}
break;
}
case Item_func::EQ_FUNC:
case Item_func::EQUAL_FUNC:
{
- add_eq_mod(fda, fdeps, *and_level, cond_func, args[0], args[1]);
- add_eq_mod(fda, fdeps, *and_level, cond_func, args[1], args[0]);
+ add_eq_mod(fda, eq_mod, *and_level, cond_func, args[0], args[1]);
+ add_eq_mod(fda, eq_mod, *and_level, cond_func, args[1], args[0]);
break;
}
case Item_func::ISNULL_FUNC:
{
Item *tmp=new Item_null;
if (tmp)
- add_eq_mod(fda, fdeps, *and_level, cond_func, args[0], args[1]);
+ add_eq_mod(fda, eq_mod, *and_level, cond_func, args[0], args[1]);
break;
}
case Item_func::MULT_EQUAL_FUNC:
{
- Item_equal *item_equal= (Item_equal *) cond;
- Item *const_item= item_equal->get_const();
+ Item_equal *item_equal= (Item_equal*)cond;
+ // const item is 'item', field -> NULL. mult_equal_fields <-- an ordered
+ // list of
+ List<Field_value> *fvl;
+ if (!(fvl= new List<Field_value>))
+ break;
+
Item_equal_iterator it(*item_equal);
Item_field *item;
- if (const_item)
- {
- /*
- For each field field1 from item_equal consider the equality
- field1=const_item as a condition allowing an index access of the table
- with field1 by the keys value of field1.
- */
- while ((item= it++))
- add_eq_mod(fda, fdeps, *and_level, cond_func, item, const_item);
- }
- else
- {
- /*
- Consider all pairs of different fields included into item_equal.
- For each of them (field1, field1) consider the equality
- field1=field2 as a condition allowing an index access of the table
- with field1 by the keys value of field2.
- */
- Item_equal_iterator fi(*item_equal);
- while ((item= fi++))
+ Item *bound_item= item_equal->get_const();
+ while ((item= it++))
+ {
+ if ((item->used_tables() & fda->usable_tables))
{
- Field *field= item->field;
- Item_field *item2;
- while ((item2= it++))
+ Field_value *field_val;
+ if ((field_val= get_field_value(fda, item->field)))
{
- if (!field->eq(item2->field))
- add_eq_mod(fda, fdeps, *and_level, cond_func, item, item2);
+ List_iterator<Field_value> it2(*fvl);
+ Field_value *other_f;
+ uint field_val_ratio= field_val->field->table->tablenr*MAX_FIELDS +
+ field_val->field->field_index;
+ bool added= FALSE;
+ while ((other_f= it2++))
+ {
+ uint other_f_ratio= other_f->field->table->tablenr*MAX_FIELDS +
+ other_f->field->field_index;
+ if (other_f_ratio > field_val_ratio)
+ {
+ *(it2.ref())= field_val;
+ it2.after(other_f);
+ added= TRUE;
+ break;
+ }
+ }
+ if (!added)
+ fvl->push_back(field_val);
}
- it.rewind();
+ }
+ else
+ {
+ if (!bound_item)
+ bound_item= item;
}
}
+ add_eq_mod2(fda, eq_mod, *and_level, NULL, bound_item, fvl);
break;
}
default:
@@ -491,6 +507,39 @@
/*
+ The only requirement of this function is to order fields in some
+ deterministic way.
+*/
+
+int cmp_equal_fields(Item_field *field1, Item_field *field2, void *arg)
+{
+ int cmp= 0;
+ bool outer_ref= 0;
+ if (field2->used_tables() & OUTER_REF_TABLE_BIT)
+ {
+ outer_ref= 1;
+ cmp= -1;
+ }
+ if (field2->used_tables() & OUTER_REF_TABLE_BIT)
+ {
+ outer_ref= 1;
+ cmp++;
+ }
+ if (outer_ref)
+ return cmp;
+ cmp= (int)field2->field->table->tablenr -
+ (int)field1->field->table->tablenr;
+ if (cmp)
+ return cmp < 0 ? -1 : 1;
+ cmp= (int)field2->field->field_index -
+ (int)field1->field->field_index;
+
+ return cmp < 0 ? -1 : (cmp ? 1 : 0);
+
+}
+
+
+/*
Perform an OR operation on two (adjacent) Equality_module arrays.
SYNOPSIS
@@ -540,9 +589,9 @@
Equality_module *end, uint and_level)
{
if (start == new_fields)
- return start; // Impossible or
+ return start; // Impossible or
if (new_fields == end)
- return start; // No new fields, skip all
+ return start; // No new fields, skip all
Equality_module *first_free=new_fields;
@@ -551,40 +600,119 @@
for (Equality_module *old=start ; old != first_free ; old++)
{
/*
- TODO: does it make sense to attempt to merging multiple-equalities?
- A: YES.
- (a=b=c) OR (a=b=d) produce "a=b".
- QQ:
- What to use for merging? Trivial N*M algorithm or pre-sort and then
- merge ordered sequences?
+ Merge multiple-equalities:
+ A: YES.
+ (a=b=c) OR (a=b=d) produce "a=b".
+
+ TODO:
+ sort by (table_ptr, column_index)
+ then run along the two and produce an intersection
+
+ Q: What about constants?
+ a=b=3 OR a=b=5 -> a=b= (either 3 or 5)
+
+ a=b OR a=b=5 -> a=b= (any constant)
+ A: keep the constant iff it is present in both sides and is the same.
+
+ class Multi_equality
+ {
+ Item *const_item;
+ List<...) list;
+ };
+
*/
if (old->field == new_fields->field)
{
- if (!new_fields->expression->const_item())
- {
- /*
- If the value matches, we can use the key reference.
- If not, we keep it until we have examined all new values
- */
- if (old->expression->eq(new_fields->expression, old->field->field->binary()))
- {
- old->level= and_level;
- }
- }
- else if (old->expression->eq_by_collation(new_fields->expression,
- old->field->field->binary(),
- old->field->field->charset()))
- {
- old->level= and_level;
- }
- else
- {
+ if (!old->field)
+ {
+ /*
+ OR-ing two multiple equalities. We must compute an intersection of
+ used fields, and check the constants according to these rules:
+
+ a=b=c=d OR a=c=e=f -> a=c (compute intersection)
+ a=const1 OR a=b -> (nothing)
+ a=const1 OR a=const1 -> a=const1
+ a=const1 OR a=const2 -> (nothing)
+
+ If we're performing an OR operation over multiple equalities, e.g.
+
+ (a=b=c AND p=q) OR (a=b AND v=z)
+
+ then we'll need to try combining each equality with each. ANDed
+ equalities are guaranteed to be disjoint, so we'll only get one
+ hit.
+ */
+ if (old->expression && new_fields->expression &&
+ old->expression->eq_by_collation(new_fields->expression,
+ old->mult_equal_fields->head()->field->binary(),
+ old->mult_equal_fields->head()->field->charset()))
+ {
+ /* Ok, keep */
+ }
+ else
+ {
+ // no single constant/bound item.
+ old->expression= NULL;
+ }
+
+ List <Field_value> *fv;
+ if (!(fv= new List<Field_value>))
+ break;
+
+ List_iterator<Field_value> it1(*old->mult_equal_fields);
+ List_iterator<Field_value> it2(*new_fields->mult_equal_fields);
+ Field_value *lfield= it1++;
+ Field_value *rfield= it2++;
+ // Merge
+ while (lfield && rfield)
+ {
+ if (lfield == rfield)
+ fv->push_back(lfield);
+ else
+ {
+ uint left_ratio= lfield->field->table->tablenr*MAX_FIELDS +
+ lfield->field->field_index;
+ uint right_ratio= rfield->field->table->tablenr*MAX_FIELDS +
+ rfield->field->field_index;
+ if (left_ratio < right_ratio)
+ lfield=it1++;
+ else
+ rfield=it2++;
+ }
+ }
+
+ if (fv->elements + test(old->expression) > 1)
+ {
+ old->mult_equal_fields= fv;
+ old->level= and_level;
+ }
+ }
+ else if (!new_fields->expression->const_item())
+ {
+ /*
+ If the value matches, we can use the key reference.
+ If not, we keep it until we have examined all new values
+ */
+ if (old->expression->eq(new_fields->expression,
+ old->field->field->binary()))
+ {
+ old->level= and_level;
+ }
+ }
+ else if (old->expression->eq_by_collation(new_fields->expression,
+ old->field->field->binary(),
+ old->field->field->charset()))
+ {
+ old->level= and_level;
+ }
+ else
+ {
/* The expressions are different. */
- if (old == --first_free) // If last item
- break;
- *old= *first_free; // Remove old value
- old--; // Retry this value
- }
+ if (old == --first_free) // If last item
+ break;
+ *old= *first_free; // Remove old value
+ old--; // Retry this value
+ }
}
}
}
@@ -596,10 +724,10 @@
for (Equality_module *old=start ; old != first_free ;)
{
if (old->level != and_level)
- { // Not used in all levels
+ { // Not used in all levels
if (old == --first_free)
- break;
- *old= *first_free; // Remove old value
+ break;
+ *old= *first_free; // Remove old value
continue;
}
old++;
@@ -659,33 +787,42 @@
return;
}
}
-
- if (*eq_mod == fda->equality_mods + fda->n_equality_mods_alloced)
- {
- /*
- We've filled the entire equality_mods array. Replace it with a bigger
- one. We do it somewhat inefficiently but it doesn't matter.
- */
- Equality_module *new_arr;
- if (!(new_arr= new Equality_module[fda->n_equality_mods_alloced *2]))
- return;
- fda->n_equality_mods_alloced *= 2;
- for (int i= 0; i < *eq_mod - fda->equality_mods; i++)
- new_arr[i]= fda->equality_mods[i];
-
- fda->equality_mods= new_arr;
- *eq_mod= new_arr + (*eq_mod - fda->equality_mods);
- }
-
- if (!((*eq_mod)->field= get_field_value(fda, field)))
+ Field_value *field_val;
+ if ((field_val= get_field_value(fda, field)))
+ add_eq_mod2(fda, eq_mod, and_level, field_val, right, NULL);
+ }
+}
+
+
+/* Just add eq_mod w/o any checks */
+static void add_eq_mod2(Func_dep_analyzer *fda, Equality_module **eq_mod,
+ uint and_level, Field_value *field_val, Item *right,
+ List<Field_value>* mult_equal_fields)
+{
+ if (*eq_mod == fda->equality_mods + fda->n_equality_mods_alloced)
+ {
+ /*
+ We've filled the entire equality_mods array. Replace it with a bigger
+ one. We do it somewhat inefficiently but it doesn't matter.
+ */
+ Equality_module *new_arr;
+ if (!(new_arr= new Equality_module[fda->n_equality_mods_alloced *2]))
return;
- (*eq_mod)->expression= right;
- (*eq_mod)->level= and_level;
- (*eq_mod)++;
+ fda->n_equality_mods_alloced *= 2;
+ for (int i= 0; i < *eq_mod - fda->equality_mods; i++)
+ new_arr[i]= fda->equality_mods[i];
+
+ fda->equality_mods= new_arr;
+ *eq_mod= new_arr + (*eq_mod - fda->equality_mods);
}
+
+ (*eq_mod)->field= field_val;
+ (*eq_mod)->expression= right;
+ (*eq_mod)->level= and_level;
+ (*eq_mod)->mult_equal_fields= mult_equal_fields;
+ (*eq_mod)++;
}
-
/*
Get a Table_value object for the given table, creating it if necessary.
*/
@@ -782,11 +919,15 @@
*/
fda->equality_mods[expr_offset].unknown_args++;
}
+ else
+ saw_other_tbl= TRUE;
}
Func_dep_analyzer *fda;
/* Offset of the expression we're processing in the dependency bitmap */
- uint expr_offset;
+ uint expr_offset;
+
+ bool saw_other_tbl;
};
@@ -858,9 +999,21 @@
eq_mod++)
{
deps_recorder.expr_offset= eq_mod - fda->equality_mods;
+ deps_recorder.saw_other_tbl= FALSE;
eq_mod->unknown_args= 0;
+
+ /* Regular tbl.col=expr(tblX1.col1, tblY1.col2, ...) */
eq_mod->expression->walk(&Item::check_column_usage_processor, FALSE,
(uchar*)&deps_recorder);
+
+ if (!eq_mod->field)
+ {
+ if (eq_mod->unknown_args)
+ eq_mod->unknown_args= 1;
+ if (deps_recorder.saw_other_tbl)
+ eq_mod->unknown_args= 0;
+ }
+
if (!eq_mod->unknown_args)
{
eq_mod->next= bound_dep;
@@ -1235,12 +1388,30 @@
Value_dep **bound_values)
{
/* For field=expr and we got to know the expr, so we know the field */
- if (!field->bound)
- {
- /* Mark as bound and add to the list */
- field->bound= TRUE;
- field->next= *bound_values;
- *bound_values= field;
+ if (mult_equal_fields)
+ {
+ List_iterator<Field_value> it(*mult_equal_fields);
+ Field_value *fv;
+ while ((fv= it++))
+ {
+ if (!fv->bound)
+ {
+ /* Mark as bound and add to the list */
+ fv->bound= TRUE;
+ fv->next= *bound_values;
+ *bound_values= fv;
+ }
+ }
+ }
+ else
+ {
+ if (!field->bound)
+ {
+ /* Mark as bound and add to the list */
+ field->bound= TRUE;
+ field->next= *bound_values;
+ *bound_values= field;
+ }
}
return FALSE;
}
@@ -1313,11 +1484,19 @@
String str(buf, sizeof(buf), &my_charset_bin);
str.length(0);
eq_mod->expression->print(&str, QT_ORDINARY);
- fprintf(DBUG_FILE, " equality%d: %s -> %s.%s\n",
- eq_mod - fda->equality_mods,
- str.c_ptr(),
- eq_mod->field->table->table->alias,
- eq_mod->field->field->field_name);
+ if (eq_mod->field)
+ {
+ fprintf(DBUG_FILE, " equality%d: %s -> %s.%s\n",
+ eq_mod - fda->equality_mods,
+ str.c_ptr(),
+ eq_mod->field->table->table->alias,
+ eq_mod->field->field->field_name);
+ }
+ else
+ {
+ fprintf(DBUG_FILE, " equality%d: multi-equality",
+ eq_mod - fda->equality_mods);
+ }
}
fprintf(DBUG_FILE,"\n");
1
0
[Maria-developers] Rev 2738: Variable/function renames in file:///home/psergey/dev/maria-5.1-table-elim-r11/
by Sergey Petrunya 19 Aug '09
by Sergey Petrunya 19 Aug '09
19 Aug '09
At file:///home/psergey/dev/maria-5.1-table-elim-r11/
------------------------------------------------------------
revno: 2738
revision-id: psergey(a)askmonty.org-20090819120659-0ndd6mqxeetgee2n
parent: psergey(a)askmonty.org-20090819101838-55ys0h923olqz4q9
committer: Sergey Petrunya <psergey(a)askmonty.org>
branch nick: maria-5.1-table-elim-r11
timestamp: Wed 2009-08-19 15:06:59 +0300
message:
Variable/function renames
=== modified file 'sql/opt_table_elimination.cc'
--- a/sql/opt_table_elimination.cc 2009-08-19 10:18:38 +0000
+++ b/sql/opt_table_elimination.cc 2009-08-19 12:06:59 +0000
@@ -147,7 +147,7 @@
{
public:
Value_dep(): bound(FALSE), next(NULL) {}
- virtual void now_bound(Func_dep_analyzer *te, Module_dep **bound_modules)=0;
+ virtual void now_bound(Func_dep_analyzer *fda, Module_dep **bound_modules)=0;
virtual ~Value_dep() {} /* only to shut up compiler warnings */
bool bound;
@@ -182,8 +182,8 @@
- unique keys we belong to
- expressions that depend on us.
*/
- void now_bound(Func_dep_analyzer *te, Module_dep **bound_modules);
- void signal_from_field_to_exprs(Func_dep_analyzer* te,
+ void now_bound(Func_dep_analyzer *fda, Module_dep **bound_modules);
+ void signal_from_field_to_exprs(Func_dep_analyzer* fda,
Module_dep **bound_modules);
};
@@ -203,7 +203,7 @@
Field_value *fields; /* Ordered list of fields that belong to this table */
Key_module *keys; /* Ordered list of Unique keys in this table */
//Outer_join_module *outer_join_dep;
- void now_bound(Func_dep_analyzer *te, Module_dep **bound_modules);
+ void now_bound(Func_dep_analyzer *fda, Module_dep **bound_modules);
};
@@ -218,7 +218,7 @@
MODULE_OUTER_JOIN
} type; /* Type of the object */
- virtual bool now_bound(Func_dep_analyzer *te, Value_dep **bound_modules)=0;
+ virtual bool now_bound(Func_dep_analyzer *fda, Value_dep **bound_modules)=0;
virtual ~Module_dep(){}
/*
Used to make a linked list of elements that became bound and thus can
@@ -243,7 +243,7 @@
/* Used during condition analysis only, similar to KEYUSE::level */
uint level;
- bool now_bound(Func_dep_analyzer *te, Value_dep **bound_values);
+ bool now_bound(Func_dep_analyzer *fda, Value_dep **bound_values);
};
@@ -264,7 +264,7 @@
uint keyno;
/* Unique keys form a linked list, ordered by keyno */
Key_module *next_table_key;
- bool now_bound(Func_dep_analyzer *te, Value_dep **bound_values);
+ bool now_bound(Func_dep_analyzer *fda, Value_dep **bound_values);
};
@@ -280,7 +280,7 @@
{
unknown_args= n_children;
}
- bool now_bound(Func_dep_analyzer *te, Value_dep **bound_values);
+ bool now_bound(Func_dep_analyzer *fda, Value_dep **bound_values);
};
@@ -301,9 +301,9 @@
table_map usable_tables;
/* Array of equality dependencies */
- Equality_module *equality_deps;
- uint n_equality_deps; /* Number of elements in the array */
- uint n_equality_deps_alloced;
+ Equality_module *equality_mods;
+ uint n_equality_mods; /* Number of elements in the array */
+ uint n_equality_mods_alloced;
/* tablenr -> Table_value* mapping. */
Table_value *table_deps[MAX_KEY];
@@ -331,10 +331,10 @@
Item* cond);
static
-bool build_eq_deps_for_cond(Func_dep_analyzer *te, Equality_module **fdeps,
+void build_eq_mods_for_cond(Func_dep_analyzer *fda, Equality_module **fdeps,
uint *and_level, Item *cond);
static
-bool add_eq_dep(Func_dep_analyzer *te, Equality_module **eq_dep,
+void add_eq_mod(Func_dep_analyzer *fda, Equality_module **eq_mod,
uint and_level,
Item_func *cond, Item *left, Item *right);
static
@@ -342,14 +342,14 @@
Equality_module *new_fields,
Equality_module *end, uint and_level);
-static Table_value *get_table_value(Func_dep_analyzer *te, TABLE *table);
-static Field_value *get_field_value(Func_dep_analyzer *te, Field *field);
+static Table_value *get_table_value(Func_dep_analyzer *fda, TABLE *table);
+static Field_value *get_field_value(Func_dep_analyzer *fda, Field *field);
static void mark_as_eliminated(JOIN *join, TABLE_LIST *tbl);
#ifndef DBUG_OFF
-static void dbug_print_deps(Func_dep_analyzer *te);
+static void dbug_print_deps(Func_dep_analyzer *fda);
#endif
/*******************************************************************************************/
@@ -358,17 +358,18 @@
Produce Eq_dep elements for given condition.
SYNOPSIS
- build_eq_deps_for_cond()
- te Table elimination context
+ build_eq_mods_for_cond()
+ fda Table elimination context
fdeps INOUT Put produced equality conditions here
and_level INOUT AND-level (like in add_key_fields)
cond Condition to process
+
DESCRIPTION
This function is modeled after add_key_fields()
*/
static
-bool build_eq_deps_for_cond(Func_dep_analyzer *te, Equality_module **fdeps,
+void build_eq_mods_for_cond(Func_dep_analyzer *fda, Equality_module **fdeps,
uint *and_level, Item *cond)
{
if (cond->type() == Item_func::COND_ITEM)
@@ -381,34 +382,29 @@
{
Item *item;
while ((item=li++))
- {
- if (build_eq_deps_for_cond(te, fdeps, and_level, item))
- return TRUE;
- }
+ build_eq_mods_for_cond(fda, fdeps, and_level, item);
for (; org_key_fields != *fdeps ; org_key_fields++)
org_key_fields->level= *and_level;
}
else
{
+ Item *item;
(*and_level)++;
- if (build_eq_deps_for_cond(te, fdeps, and_level, li++))
- return TRUE;
- Item *item;
+ build_eq_mods_for_cond(fda, fdeps, and_level, li++);
while ((item=li++))
{
Equality_module *start_key_fields= *fdeps;
(*and_level)++;
- if (build_eq_deps_for_cond(te, fdeps, and_level, item))
- return TRUE;
+ build_eq_mods_for_cond(fda, fdeps, and_level, item);
*fdeps= merge_func_deps(org_key_fields, start_key_fields, *fdeps,
++(*and_level));
}
}
- return FALSE;
+ return;
}
if (cond->type() != Item::FUNC_ITEM)
- return FALSE;
+ return;
Item_func *cond_func= (Item_func*) cond;
Item **args= cond_func->arguments();
@@ -418,10 +414,10 @@
{
if (cond_func->argument_count() == 2)
{
- if (add_eq_dep(te, fdeps, *and_level, cond_func, args[0], args[1]) ||
- add_eq_dep(te, fdeps, *and_level, cond_func, args[1], args[0]))
- return TRUE;
+ add_eq_mod(fda, fdeps, *and_level, cond_func, args[0], args[1]);
+ add_eq_mod(fda, fdeps, *and_level, cond_func, args[1], args[0]);
}
+ break;
}
case Item_func::BETWEEN:
{
@@ -430,24 +426,23 @@
(fld= args[0]->real_item())->type() == Item::FIELD_ITEM &&
args[1]->eq(args[2], ((Item_field*)fld)->field->binary()))
{
- if (add_eq_dep(te, fdeps, *and_level, cond_func, args[0], args[1]) ||
- add_eq_dep(te, fdeps, *and_level, cond_func, args[1], args[0]))
- return TRUE;
+ add_eq_mod(fda, fdeps, *and_level, cond_func, args[0], args[1]);
+ add_eq_mod(fda, fdeps, *and_level, cond_func, args[1], args[0]);
}
break;
}
case Item_func::EQ_FUNC:
case Item_func::EQUAL_FUNC:
{
- add_eq_dep(te, fdeps, *and_level, cond_func, args[0], args[1]);
- add_eq_dep(te, fdeps, *and_level, cond_func, args[1], args[0]);
+ add_eq_mod(fda, fdeps, *and_level, cond_func, args[0], args[1]);
+ add_eq_mod(fda, fdeps, *and_level, cond_func, args[1], args[0]);
break;
}
case Item_func::ISNULL_FUNC:
{
Item *tmp=new Item_null;
- if (!tmp || add_eq_dep(te, fdeps, *and_level, cond_func, args[0], args[1]))
- return TRUE;
+ if (tmp)
+ add_eq_mod(fda, fdeps, *and_level, cond_func, args[0], args[1]);
break;
}
case Item_func::MULT_EQUAL_FUNC:
@@ -462,12 +457,9 @@
For each field field1 from item_equal consider the equality
field1=const_item as a condition allowing an index access of the table
with field1 by the keys value of field1.
- */
+ */
while ((item= it++))
- {
- if (add_eq_dep(te, fdeps, *and_level, cond_func, item, const_item))
- return TRUE;
- }
+ add_eq_mod(fda, fdeps, *and_level, cond_func, item, const_item);
}
else
{
@@ -485,10 +477,7 @@
while ((item2= it++))
{
if (!field->eq(item2->field))
- {
- if (add_eq_dep(te, fdeps, *and_level, cond_func, item, item2))
- return TRUE;
- }
+ add_eq_mod(fda, fdeps, *and_level, cond_func, item, item2);
}
it.rewind();
}
@@ -498,7 +487,6 @@
default:
break;
}
- return FALSE;
}
@@ -624,8 +612,8 @@
Add an Equality_module element for left=right condition
SYNOPSIS
- add_eq_dep()
- te Table elimination context
+ add_eq_mod()
+ fda Table elimination context
eq_mod INOUT Store created Equality_module here and increment ptr if
you do so
and_level AND-level ()
@@ -645,10 +633,10 @@
*/
static
-bool add_eq_dep(Func_dep_analyzer *te, Equality_module **eq_mod,
+void add_eq_mod(Func_dep_analyzer *fda, Equality_module **eq_mod,
uint and_level, Item_func *cond, Item *left, Item *right)
{
- if ((left->used_tables() & te->usable_tables) &&
+ if ((left->used_tables() & fda->usable_tables) &&
!(right->used_tables() & RAND_TABLE_BIT) &&
left->real_item()->type() == Item::FIELD_ITEM)
{
@@ -658,7 +646,7 @@
if (right->result_type() != STRING_RESULT)
{
if (field->cmp_type() != right->result_type())
- return FALSE;
+ return;
}
else
{
@@ -668,17 +656,33 @@
*/
if (field->cmp_type() == STRING_RESULT &&
((Field_str*)field)->charset() != cond->compare_collation())
- return FALSE;
+ return;
}
}
-
- if (!((*eq_mod)->field= get_field_value(te, field)))
- return TRUE;
+
+ if (*eq_mod == fda->equality_mods + fda->n_equality_mods_alloced)
+ {
+ /*
+ We've filled the entire equality_mods array. Replace it with a bigger
+ one. We do it somewhat inefficiently but it doesn't matter.
+ */
+ Equality_module *new_arr;
+ if (!(new_arr= new Equality_module[fda->n_equality_mods_alloced *2]))
+ return;
+ fda->n_equality_mods_alloced *= 2;
+ for (int i= 0; i < *eq_mod - fda->equality_mods; i++)
+ new_arr[i]= fda->equality_mods[i];
+
+ fda->equality_mods= new_arr;
+ *eq_mod= new_arr + (*eq_mod - fda->equality_mods);
+ }
+
+ if (!((*eq_mod)->field= get_field_value(fda, field)))
+ return;
(*eq_mod)->expression= right;
(*eq_mod)->level= and_level;
(*eq_mod)++;
}
- return FALSE;
}
@@ -686,7 +690,7 @@
Get a Table_value object for the given table, creating it if necessary.
*/
-static Table_value *get_table_value(Func_dep_analyzer *te, TABLE *table)
+static Table_value *get_table_value(Func_dep_analyzer *fda, TABLE *table)
{
Table_value *tbl_dep;
if (!(tbl_dep= new Table_value(table)))
@@ -704,7 +708,7 @@
key_list= &(key_dep->next_table_key);
}
}
- return te->table_deps[table->tablenr]= tbl_dep;
+ return fda->table_deps[table->tablenr]= tbl_dep;
}
@@ -712,15 +716,15 @@
Get a Field_value object for the given field, creating it if necessary
*/
-static Field_value *get_field_value(Func_dep_analyzer *te, Field *field)
+static Field_value *get_field_value(Func_dep_analyzer *fda, Field *field)
{
TABLE *table= field->table;
Table_value *tbl_dep;
/* First, get the table*/
- if (!(tbl_dep= te->table_deps[table->tablenr]))
+ if (!(tbl_dep= fda->table_deps[table->tablenr]))
{
- if (!(tbl_dep= get_table_value(te, table)))
+ if (!(tbl_dep= get_table_value(fda, table)))
return NULL;
}
@@ -750,13 +754,13 @@
class Field_dependency_recorder : public Field_enumerator
{
public:
- Field_dependency_recorder(Func_dep_analyzer *te_arg): te(te_arg)
+ Field_dependency_recorder(Func_dep_analyzer *te_arg): fda(te_arg)
{}
void see_field(Field *field)
{
Table_value *tbl_dep;
- if ((tbl_dep= te->table_deps[field->table->tablenr]))
+ if ((tbl_dep= fda->table_deps[field->table->tablenr]))
{
for (Field_value *field_dep= tbl_dep->fields; field_dep;
field_dep= field_dep->next_table_field)
@@ -764,9 +768,9 @@
if (field->field_index == field_dep->field->field_index)
{
uint offs= field_dep->bitmap_offset + expr_offset;
- if (!bitmap_is_set(&te->expr_deps, offs))
- te->equality_deps[expr_offset].unknown_args++;
- bitmap_set_bit(&te->expr_deps, offs);
+ if (!bitmap_is_set(&fda->expr_deps, offs))
+ fda->equality_mods[expr_offset].unknown_args++;
+ bitmap_set_bit(&fda->expr_deps, offs);
return;
}
}
@@ -776,11 +780,11 @@
Bump the dependency anyway, this will signal that this dependency
cannot be satisfied.
*/
- te->equality_deps[expr_offset].unknown_args++;
+ fda->equality_mods[expr_offset].unknown_args++;
}
}
- Func_dep_analyzer *te;
+ Func_dep_analyzer *fda;
/* Offset of the expression we're processing in the dependency bitmap */
uint expr_offset;
};
@@ -791,7 +795,7 @@
SYNOPSIS
setup_equality_modules_deps()
- te Table elimination context
+ fda Table elimination context
bound_deps_list OUT Start of linked list of elements that were found to
be bound (caller will use this to see if that
allows to declare further elements bound)
@@ -807,7 +811,7 @@
*/
static
-bool setup_equality_modules_deps(Func_dep_analyzer *te,
+bool setup_equality_modules_deps(Func_dep_analyzer *fda,
Module_dep **bound_deps_list)
{
DBUG_ENTER("setup_equality_modules_deps");
@@ -817,8 +821,8 @@
value.
*/
uint offset= 0;
- for (Table_value **tbl_dep=te->table_deps;
- tbl_dep < te->table_deps + MAX_TABLES;
+ for (Table_value **tbl_dep=fda->table_deps;
+ tbl_dep < fda->table_deps + MAX_TABLES;
tbl_dep++)
{
if (*tbl_dep)
@@ -828,39 +832,39 @@
field_dep= field_dep->next_table_field)
{
field_dep->bitmap_offset= offset;
- offset += te->n_equality_deps;
+ offset += fda->n_equality_mods;
}
}
}
void *buf;
if (!(buf= current_thd->alloc(bitmap_buffer_size(offset))) ||
- bitmap_init(&te->expr_deps, (my_bitmap_map*)buf, offset, FALSE))
+ bitmap_init(&fda->expr_deps, (my_bitmap_map*)buf, offset, FALSE))
{
DBUG_RETURN(TRUE);
}
- bitmap_clear_all(&te->expr_deps);
+ bitmap_clear_all(&fda->expr_deps);
/*
- Analyze all "field=expr" dependencies, and have te->expr_deps encode
+ Analyze all "field=expr" dependencies, and have fda->expr_deps encode
dependencies of expressions from fields.
Also collect a linked list of equalities that are bound.
*/
Module_dep *bound_dep= NULL;
- Field_dependency_recorder deps_recorder(te);
- for (Equality_module *eq_dep= te->equality_deps;
- eq_dep < te->equality_deps + te->n_equality_deps;
- eq_dep++)
+ Field_dependency_recorder deps_recorder(fda);
+ for (Equality_module *eq_mod= fda->equality_mods;
+ eq_mod < fda->equality_mods + fda->n_equality_mods;
+ eq_mod++)
{
- deps_recorder.expr_offset= eq_dep - te->equality_deps;
- eq_dep->unknown_args= 0;
- eq_dep->expression->walk(&Item::check_column_usage_processor, FALSE,
+ deps_recorder.expr_offset= eq_mod - fda->equality_mods;
+ eq_mod->unknown_args= 0;
+ eq_mod->expression->walk(&Item::check_column_usage_processor, FALSE,
(uchar*)&deps_recorder);
- if (!eq_dep->unknown_args)
+ if (!eq_mod->unknown_args)
{
- eq_dep->next= bound_dep;
- bound_dep= eq_dep;
+ eq_mod->next= bound_dep;
+ bound_dep= eq_mod;
}
}
*bound_deps_list= bound_dep;
@@ -968,7 +972,7 @@
SYNOPSIS
eliminate_tables_for_list()
- te Table elimination context
+ fda Table elimination context
join_list Join list to work on
list_tables Bitmap of tables embedded in the join_list.
on_expr ON expression, if the join list is the inner side
@@ -1053,7 +1057,7 @@
SYNOPSIS
check_func_dependency()
- te Table elimination context
+ fda Table elimination context
tables Set of tables we want to be functionally dependent
cond Condition to use
@@ -1073,24 +1077,25 @@
TABLE_LIST *oj_tbl,
Item* cond)
{
- uint and_level=0;
Module_dep *bound_modules;
- //psergey-todo: move allocs to somewhere else.
- Func_dep_analyzer pte(join);
- Func_dep_analyzer *te= &pte;
- uint m= max(join->thd->lex->current_select->max_equal_elems,1);
- uint max_elems= ((join->thd->lex->current_select->cond_count+1)*2 +
- join->thd->lex->current_select->between_count)*m + 1 + 10;
- if (!(te->equality_deps= new Equality_module[max_elems]))
+ Func_dep_analyzer fda(join);
+
+ /* Start value */
+ fda.n_equality_mods_alloced=
+ join->thd->lex->current_select->max_equal_elems +
+ (join->thd->lex->current_select->cond_count+1)*2 +
+ join->thd->lex->current_select->between_count;
+
+ if (!(fda.equality_mods= new Equality_module[fda.n_equality_mods_alloced]))
return FALSE;
- Equality_module* eq_dep= te->equality_deps;
+ Equality_module* last_eq_mod= fda.equality_mods;
/* Create Table_value objects for all tables we're trying to eliminate */
if (oj_tbl)
{
- if (!get_table_value(te, oj_tbl->table))
+ if (!get_table_value(&fda, oj_tbl->table))
return FALSE;
}
else
@@ -1100,30 +1105,29 @@
{
if (tbl->table && (tbl->table->map & dep_tables))
{
- if (!get_table_value(te, tbl->table))
+ if (!get_table_value(&fda, tbl->table))
return FALSE;
}
}
}
- te->usable_tables= dep_tables;
+ fda.usable_tables= dep_tables;
/*
Analyze the the ON expression and create Equality_module objects and
Field_value objects for their left parts.
*/
- if (build_eq_deps_for_cond(te, &eq_dep, &and_level, cond) ||
- eq_dep == te->equality_deps)
- return FALSE;
-
- te->n_equality_deps= eq_dep - te->equality_deps;
+ uint and_level=0;
+ build_eq_mods_for_cond(&fda, &last_eq_mod, &and_level, cond);
+ if (!(fda.n_equality_mods= last_eq_mod - fda.equality_mods))
+ return FALSE; /* No useful conditions */
- if (!(te->outer_join_dep= new Outer_join_module(my_count_bits(dep_tables))) ||
- setup_equality_modules_deps(te, &bound_modules))
+ if (!(fda.outer_join_dep= new Outer_join_module(my_count_bits(dep_tables))) ||
+ setup_equality_modules_deps(&fda, &bound_modules))
{
return FALSE; /* OOM, default to non-dependent */
}
- DBUG_EXECUTE("test", dbug_print_deps(te); );
+ DBUG_EXECUTE("test", dbug_print_deps(&fda); );
/* The running wave algorithm itself: */
Value_dep *bound_values= NULL;
@@ -1131,11 +1135,11 @@
{
for (;bound_modules; bound_modules= bound_modules->next)
{
- if (bound_modules->now_bound(te, &bound_values))
+ if (bound_modules->now_bound(&fda, &bound_values))
return TRUE; /* Dependent! */
}
for (;bound_values; bound_values=bound_values->next)
- bound_values->now_bound(te, &bound_modules);
+ bound_values->now_bound(&fda, &bound_modules);
}
return FALSE; /* Not dependent */
}
@@ -1147,7 +1151,7 @@
- all its fields are known
*/
-void Table_value::now_bound(Func_dep_analyzer *te,
+void Table_value::now_bound(Func_dep_analyzer *fda,
Module_dep **bound_modules)
{
DBUG_PRINT("info", ("table %s is now bound", table->alias));
@@ -1159,21 +1163,21 @@
{
/* Mark as bound and add to the list */
field_dep->bound= TRUE;
- field_dep->signal_from_field_to_exprs(te, bound_modules);
+ field_dep->signal_from_field_to_exprs(fda, bound_modules);
}
}
- if (te->outer_join_dep->unknown_args &&
- !--te->outer_join_dep->unknown_args)
+ if (fda->outer_join_dep->unknown_args &&
+ !--fda->outer_join_dep->unknown_args)
{
/* Mark as bound and add to the list */
- te->outer_join_dep->next= *bound_modules;
- *bound_modules= te->outer_join_dep;
+ fda->outer_join_dep->next= *bound_modules;
+ *bound_modules= fda->outer_join_dep;
}
}
-void Field_value::now_bound(Func_dep_analyzer *te,
+void Field_value::now_bound(Func_dep_analyzer *fda,
Module_dep **bound_modules)
{
DBUG_PRINT("info", ("field %s.%s is now bound", field->table->alias,
@@ -1193,7 +1197,7 @@
*bound_modules= key_dep;
}
}
- signal_from_field_to_exprs(te, bound_modules);
+ signal_from_field_to_exprs(fda, bound_modules);
}
@@ -1201,25 +1205,25 @@
Walk through expressions that depend on this field and 'notify' them
that this field is no longer unknown.
*/
-void Field_value::signal_from_field_to_exprs(Func_dep_analyzer* te,
+void Field_value::signal_from_field_to_exprs(Func_dep_analyzer* fda,
Module_dep **bound_modules)
{
- for (uint i=0; i < te->n_equality_deps; i++)
+ for (uint i=0; i < fda->n_equality_mods; i++)
{
- if (bitmap_is_set(&te->expr_deps, bitmap_offset + i) &&
- te->equality_deps[i].unknown_args &&
- !--te->equality_deps[i].unknown_args)
+ if (bitmap_is_set(&fda->expr_deps, bitmap_offset + i) &&
+ fda->equality_mods[i].unknown_args &&
+ !--fda->equality_mods[i].unknown_args)
{
/* Mark as bound and add to the list */
- Equality_module* eq_dep= &te->equality_deps[i];
- eq_dep->next= *bound_modules;
- *bound_modules= eq_dep;
+ Equality_module* eq_mod= &fda->equality_mods[i];
+ eq_mod->next= *bound_modules;
+ *bound_modules= eq_mod;
}
}
}
-bool Outer_join_module::now_bound(Func_dep_analyzer *te,
+bool Outer_join_module::now_bound(Func_dep_analyzer *fda,
Value_dep **bound_values)
{
DBUG_PRINT("info", ("Outer join eliminated"));
@@ -1227,7 +1231,7 @@
}
-bool Equality_module::now_bound(Func_dep_analyzer *te,
+bool Equality_module::now_bound(Func_dep_analyzer *fda,
Value_dep **bound_values)
{
/* For field=expr and we got to know the expr, so we know the field */
@@ -1242,7 +1246,7 @@
}
/* Unique key is known means its table is known */
-bool Key_module::now_bound(Func_dep_analyzer *te, Value_dep **bound_values)
+bool Key_module::now_bound(Func_dep_analyzer *fda, Value_dep **bound_values)
{
if (!table->bound)
{
@@ -1294,7 +1298,7 @@
#ifndef DBUG_OFF
static
-void dbug_print_deps(Func_dep_analyzer *te)
+void dbug_print_deps(Func_dep_analyzer *fda)
{
DBUG_ENTER("dbug_print_deps");
DBUG_LOCK_FILE;
@@ -1302,18 +1306,18 @@
fprintf(DBUG_FILE,"deps {\n");
/* Start with printing equalities */
- for (Equality_module *eq_dep= te->equality_deps;
- eq_dep != te->equality_deps + te->n_equality_deps; eq_dep++)
+ for (Equality_module *eq_mod= fda->equality_mods;
+ eq_mod != fda->equality_mods + fda->n_equality_mods; eq_mod++)
{
char buf[128];
String str(buf, sizeof(buf), &my_charset_bin);
str.length(0);
- eq_dep->expression->print(&str, QT_ORDINARY);
+ eq_mod->expression->print(&str, QT_ORDINARY);
fprintf(DBUG_FILE, " equality%d: %s -> %s.%s\n",
- eq_dep - te->equality_deps,
+ eq_mod - fda->equality_mods,
str.c_ptr(),
- eq_dep->field->table->table->alias,
- eq_dep->field->field->field_name);
+ eq_mod->field->table->table->alias,
+ eq_mod->field->field->field_name);
}
fprintf(DBUG_FILE,"\n");
@@ -1321,7 +1325,7 @@
for (uint i=0; i < MAX_TABLES; i++)
{
Table_value *table_dep;
- if ((table_dep= te->table_deps[i]))
+ if ((table_dep= fda->table_deps[i]))
{
/* Print table */
fprintf(DBUG_FILE, " table %s\n", table_dep->table->alias);
@@ -1332,9 +1336,9 @@
fprintf(DBUG_FILE, " field %s.%s ->", table_dep->table->alias,
field_dep->field->field_name);
uint ofs= field_dep->bitmap_offset;
- for (uint bit= ofs; bit < ofs + te->n_equality_deps; bit++)
+ for (uint bit= ofs; bit < ofs + fda->n_equality_mods; bit++)
{
- if (bitmap_is_set(&te->expr_deps, bit))
+ if (bitmap_is_set(&fda->expr_deps, bit))
fprintf(DBUG_FILE, " equality%d ", bit - ofs);
}
fprintf(DBUG_FILE, "\n");
1
0