Below is the list of changes that have just been committed into a local
5.0 repository of schwenke. When schwenke 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
1.1913 05/07/28 17:12:59 schwenke@stripped +2 -0
fixed issues that break Windows builds
sql/sql_select.cc
1.345 05/07/28 17:11:23 schwenke@stripped +300 -299
pulled variable out of for() scope
libmysql/libmysql.def
1.43 05/07/28 17:11:23 schwenke@stripped +0 -1
Symbol was renamed to get_defaults_options
# 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: schwenke
# Host: alpha.xl.local
# Root: /home/schwenke/Work/MySQL/BK-internal-tree/mysql-5.0
--- 1.344/sql/sql_select.cc 2005-07-25 21:51:44 +02:00
+++ 1.345/sql/sql_select.cc 2005-07-28 17:11:23 +02:00
@@ -101,7 +101,7 @@
List<TABLE_LIST> *join_list,
Item::cond_result *cond_value);
static bool resolve_nested_join (TABLE_LIST *table);
-static COND *remove_eq_conds(THD *thd, COND *cond,
+static COND *remove_eq_conds(THD *thd, COND *cond,
Item::cond_result *cond_value);
static bool const_expression_in_where(COND *conds,Item *item, Item **comp_item);
static bool open_tmp_table(TABLE *table);
@@ -232,7 +232,7 @@
unit->set_limit(unit->global_parameters);
/*
'options' of mysql_select will be set in JOIN, as far as JOIN for
- every PS/SP execution new, we will not need reset this flag if
+ every PS/SP execution new, we will not need reset this flag if
setup_tables_done_option changed for next rexecution
*/
res= mysql_select(thd, &select_lex->ref_pointer_array,
@@ -352,7 +352,7 @@
DBUG_RETURN(-1); /* purecov: inspected */
ref_pointer_array= *rref_pointer_array;
-
+
if (having)
{
thd->where="having clause";
@@ -386,7 +386,7 @@
if (setup_ftfuncs(select_lex)) /* should be after having->fix_fields */
DBUG_RETURN(-1);
-
+
/*
Check if one one uses a not constant column with group functions
@@ -426,7 +426,7 @@
for (ORDER *group_tmp= group_list ; group_tmp ; group_tmp= group_tmp->next)
send_group_parts++;
}
-
+
procedure= setup_procedure(thd, proc_param, result, fields_list, &error);
if (error)
goto err; /* purecov: inspected */
@@ -598,7 +598,7 @@
thd->restore_backup_item_arena(arena, &backup);
}
- conds= optimize_cond(this, conds, join_list, &cond_value);
+ conds= optimize_cond(this, conds, join_list, &cond_value);
if (thd->net.report_error)
{
error= 1;
@@ -721,7 +721,7 @@
/*
Permorm the the optimization on fields evaluation mentioned above
for all on expressions.
- */
+ */
for (JOIN_TAB *tab= join_tab + const_tables; tab < join_tab + tables ; tab++)
{
if (*tab->on_expr_ref)
@@ -978,7 +978,7 @@
if (add_ref_to_table_cond(thd,&join_tab[const_tables]))
DBUG_RETURN(1);
}
-
+
if (!(select_options & SELECT_BIG_RESULT) &&
((group_list &&
(!simple_group ||
@@ -1028,11 +1028,11 @@
temp table.
- We are using DISTINCT without resolving the distinct as a GROUP BY
on all columns.
-
+
If having is not handled here, it will be checked before the row
is sent to the client.
- */
- if (tmp_having &&
+ */
+ if (tmp_having &&
(sort_and_group || (exec_tmp_table1->distinct && !group_list)))
having= tmp_having;
@@ -1064,7 +1064,7 @@
order=0;
}
}
-
+
/*
Optimize distinct when used on some of the tables
SELECT DISTINCT t1.a FROM t1,t2 WHERE t1.b=t2.b
@@ -1090,7 +1090,7 @@
order=0;
}
}
-
+
if (thd->lex->subqueries)
{
if (!(tmp_join= (JOIN*)thd->alloc(sizeof(JOIN))))
@@ -1291,10 +1291,10 @@
DBUG_VOID_RETURN;
}
curr_tmp_table->file->info(HA_STATUS_VARIABLE);
-
+
if (curr_join->having)
curr_join->having= curr_join->tmp_having= 0; // Allready done
-
+
/* Change sum_fields reference to calculated fields in tmp_table */
curr_join->all_fields= *curr_all_fields;
if (!items1)
@@ -1321,33 +1321,33 @@
curr_all_fields= &tmp_all_fields1;
curr_fields_list= &tmp_fields_list1;
curr_join->set_items_ref_array(items1);
-
+
if (sort_and_group || curr_tmp_table->group)
{
- curr_join->tmp_table_param.field_count+=
+ curr_join->tmp_table_param.field_count+=
curr_join->tmp_table_param.sum_func_count+
curr_join->tmp_table_param.func_count;
- curr_join->tmp_table_param.sum_func_count=
+ curr_join->tmp_table_param.sum_func_count=
curr_join->tmp_table_param.func_count= 0;
}
else
{
- curr_join->tmp_table_param.field_count+=
+ curr_join->tmp_table_param.field_count+=
curr_join->tmp_table_param.func_count;
curr_join->tmp_table_param.func_count= 0;
}
-
+
// procedure can't be used inside subselect => we do nothing special for it
if (procedure)
procedure->update_refs();
-
+
if (curr_tmp_table->group)
{ // Already grouped
if (!curr_join->order && !curr_join->no_order && !skip_sort_order)
curr_join->order= curr_join->group_list; /* order by group */
curr_join->group_list= 0;
}
-
+
/*
If we have different sort & group then we must sort the data by group
and copy it to another tmp table
@@ -1357,13 +1357,13 @@
*/
if (curr_join->group_list && (!test_if_subpart(curr_join->group_list,
- curr_join->order) ||
+ curr_join->order) ||
curr_join->select_distinct) ||
(curr_join->select_distinct &&
curr_join->tmp_table_param.using_indirect_summary_function))
{ /* Must copy to another table */
DBUG_PRINT("info",("Creating group table"));
-
+
/* Free first data from old join */
curr_join->join_free(0);
if (make_simple_join(curr_join, curr_tmp_table))
@@ -1372,11 +1372,11 @@
count_field_types(&curr_join->tmp_table_param,
curr_join->tmp_all_fields1,
curr_join->select_distinct && !curr_join->group_list);
- curr_join->tmp_table_param.hidden_field_count=
+ curr_join->tmp_table_param.hidden_field_count=
(curr_join->tmp_all_fields1.elements-
curr_join->tmp_fields_list1.elements);
-
-
+
+
if (exec_tmp_table2)
curr_tmp_table= exec_tmp_table2;
else
@@ -1387,7 +1387,7 @@
&curr_join->tmp_table_param,
*curr_all_fields,
(ORDER*) 0,
- curr_join->select_distinct &&
+ curr_join->select_distinct &&
!curr_join->group_list,
1, curr_join->select_options,
HA_POS_ERROR,
@@ -1409,7 +1409,7 @@
DBUG_VOID_RETURN;
}
}
-
+
thd->proc_info="Copying to group table";
DBUG_PRINT("info", ("%s", thd->proc_info));
tmp_error= -1;
@@ -1418,7 +1418,7 @@
if (sum_funcs2)
{
curr_join->sum_funcs= sum_funcs2;
- curr_join->sum_funcs_end= sum_funcs_end2;
+ curr_join->sum_funcs_end= sum_funcs_end2;
}
else
{
@@ -1441,13 +1441,13 @@
end_read_record(&curr_join->join_tab->read_record);
curr_join->const_tables= curr_join->tables; // Mark free for cleanup()
curr_join->join_tab[0].table= 0; // Table is freed
-
+
// No sum funcs anymore
if (!items2)
{
items2= items1 + all_fields.elements;
if (change_to_use_tmp_fields(thd, items2,
- tmp_fields_list2, tmp_all_fields2,
+ tmp_fields_list2, tmp_all_fields2,
fields_list.elements, tmp_all_fields1))
DBUG_VOID_RETURN;
curr_join->tmp_fields_list2= tmp_fields_list2;
@@ -1456,13 +1456,13 @@
curr_fields_list= &curr_join->tmp_fields_list2;
curr_all_fields= &curr_join->tmp_all_fields2;
curr_join->set_items_ref_array(items2);
- curr_join->tmp_table_param.field_count+=
+ curr_join->tmp_table_param.field_count+=
curr_join->tmp_table_param.sum_func_count;
curr_join->tmp_table_param.sum_func_count= 0;
}
if (curr_tmp_table->distinct)
curr_join->select_distinct=0; /* Each row is unique */
-
+
curr_join->join_free(0); /* Free quick selects */
if (curr_join->select_distinct && ! curr_join->group_list)
{
@@ -1480,11 +1480,11 @@
DBUG_VOID_RETURN;
calc_group_buffer(curr_join, curr_join->group_list);
count_field_types(&curr_join->tmp_table_param, *curr_all_fields, 0);
-
+
}
if (procedure)
count_field_types(&curr_join->tmp_table_param, *curr_all_fields, 0);
-
+
if (curr_join->group || curr_join->tmp_table_param.sum_func_count ||
(procedure && (procedure->flags & PROC_GROUP)))
{
@@ -1519,7 +1519,7 @@
curr_join->set_items_ref_array(items3);
if (curr_join->make_sum_func_list(*curr_all_fields, *curr_fields_list,
- 1, TRUE) ||
+ 1, TRUE) ||
setup_sum_funcs(curr_join->thd, curr_join->sum_funcs) ||
thd->is_fatal_error)
DBUG_VOID_RETURN;
@@ -1529,7 +1529,7 @@
DBUG_PRINT("info",("Sorting for send_fields"));
thd->proc_info="Sorting result";
/* If we have already done the group, add HAVING to sorted table */
- if (curr_join->tmp_having && ! curr_join->group_list &&
+ if (curr_join->tmp_having && ! curr_join->group_list &&
! curr_join->sort_and_group)
{
// Some tables may have been const
@@ -1602,7 +1602,7 @@
}
/*
Here we sort rows for ORDER BY/GROUP BY clause, if the optimiser
- chose FILESORT to be faster than INDEX SCAN or there is no
+ chose FILESORT to be faster than INDEX SCAN or there is no
suitable index present.
Note, that create_sort_index calls test_if_skip_sort_order and may
finally replace sorting with index scan if there is a LIMIT clause in
@@ -1610,7 +1610,7 @@
OPTION_FOUND_ROWS supersedes LIMIT and is taken into account.
*/
if (create_sort_index(thd, curr_join,
- curr_join->group_list ?
+ curr_join->group_list ?
curr_join->group_list : curr_join->order,
curr_join->select_limit,
(select_options & OPTION_FOUND_ROWS ?
@@ -1641,7 +1641,7 @@
*/
DBUG_ASSERT(error == 0);
/*
- curr_join is used only for reusable joins - that is,
+ curr_join is used only for reusable joins - that is,
to perform SELECT for each outer row (like in subselects).
This join is main, so we know for sure that curr_join == join.
*/
@@ -1842,6 +1842,7 @@
JOIN_TAB *join_tab= join->join_tab + join->const_tables;
enum_nested_loop_state error= NESTED_LOOP_OK;
Query_arena backup_arena;
+ Engine_info *info;
DBUG_ENTER("Cursor::fetch");
DBUG_PRINT("enter",("rows: %lu", num_rows));
@@ -1856,7 +1857,7 @@
/* save references to memory, allocated during fetch */
thd->set_n_backup_item_arena(this, &backup_arena);
- for (Engine_info *info= ht_info; info->read_view ; info++)
+ for (info= ht_info; info->read_view ; info++)
(info->ht->set_cursor_read_view)(info->read_view);
join->fetch_limit+= num_rows;
@@ -1875,7 +1876,7 @@
/* Grab free_list here to correctly free it in close */
thd->restore_backup_item_arena(this, &backup_arena);
- for (Engine_info *info= ht_info; info->read_view; info++)
+ for (info= ht_info; info->read_view; info++)
(info->ht->set_cursor_read_view)(0);
if (error == NESTED_LOOP_CURSOR_LIMIT)
@@ -1966,7 +1967,7 @@
the top-level select_lex for this query
tables list of all tables used in this query.
The tables have been pre-opened.
- wild_num number of wildcards used in the top level
+ wild_num number of wildcards used in the top level
select of this query.
For example statement
SELECT *, t1.*, catalog.t2.* FROM t0, t1, t2;
@@ -2232,13 +2233,13 @@
if (join->outer_join)
{
- /*
+ /*
Build transitive closure for relation 'to be dependent on'.
This will speed up the plan search for many cases with outer joins,
as well as allow us to catch illegal cross references/
Warshall's algorithm is used to build the transitive closure.
As we use bitmaps to represent the relation the complexity
- of the algorithm is O((number of tables)^2).
+ of the algorithm is O((number of tables)^2).
*/
for (i= 0, s= stat ; i < table_count ; i++, s++)
{
@@ -2503,7 +2504,7 @@
If true, the condition this struct represents will not be satisfied
when val IS NULL.
*/
- bool null_rejecting;
+ bool null_rejecting;
} KEY_FIELD;
/* Values in optimize */
@@ -2519,7 +2520,7 @@
and 'column IS NULL' to one test. This is useful for sub select queries
that are internally transformed to something like:
- SELECT * FROM t1 WHERE t1.key=outer_ref_field or t1.key IS NULL
+ SELECT * FROM t1 WHERE t1.key=outer_ref_field or t1.key IS NULL
KEY_FIELD::null_rejecting is processed as follows:
result has null_rejecting=true if it is set for both ORed references.
@@ -2584,7 +2585,7 @@
/* Remember the NOT NULL value */
if (old->val->is_null())
old->val= new_fields->val;
- /* The referred expression can be NULL: */
+ /* The referred expression can be NULL: */
old->null_rejecting= 0;
}
else
@@ -2744,8 +2745,8 @@
(*key_fields)->level= and_level;
(*key_fields)->optimize= exists_optimize;
/*
- If the condition has form "tbl.keypart = othertbl.field" and
- othertbl.field can be NULL, there will be no matches if othertbl.field
+ If the condition has form "tbl.keypart = othertbl.field" and
+ othertbl.field can be NULL, there will be no matches if othertbl.field
has NULL value.
We use null_rejecting in add_not_null_conds() to add
'othertbl.field IS NOT NULL' to tab->select_cond.
@@ -2767,7 +2768,7 @@
field Field used in comparision
eq_func True if we used =, <=> or IS NULL
value Value used for comparison with field
- Is NULL for BETWEEN and IN
+ Is NULL for BETWEEN and IN
usable_tables Tables which can be used for key optimization
NOTES
@@ -2789,7 +2790,7 @@
eq_func, val, num_values, usable_tables);
Item_equal *item_equal= field_item->item_equal;
if (item_equal)
- {
+ {
/*
Add to the set of possible key values every substitution of
the field for an equal field included into item_equal
@@ -2899,7 +2900,7 @@
cond_func->functype() != Item_func::LIKE_FUNC &&
!(cond_func->arguments()[1]->used_tables() & OUTER_REF_TABLE_BIT))
{
- add_key_equal_fields(key_fields, *and_level, cond_func,
+ add_key_equal_fields(key_fields, *and_level, cond_func,
(Item_field*) (cond_func->arguments()[1])->real_item(),
equal_func,
cond_func->arguments(),1,usable_tables);
@@ -2928,24 +2929,24 @@
if (const_item)
{
/*
- For each field field1 from item_equal consider the equality
+ 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_key_field(key_fields, *and_level, cond_func, item->field,
TRUE, &const_item, 1, usable_tables);
}
}
- else
+ else
{
/*
Consider all pairs of different fields included into item_equal.
- For each of them (field1, field1) consider the equality
+ 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++))
{
@@ -3100,20 +3101,20 @@
/*
Update keyuse array with all possible keys we can use to fetch rows
-
+
SYNOPSIS
update_ref_and_keys()
- thd
+ thd
keyuse OUT Put here ordered array of KEYUSE structures
join_tab Array in tablenr_order
tables Number of tables in join
- cond WHERE condition (note that the function analyzes
+ cond WHERE condition (note that the function analyzes
join_tab[i]->on_expr too)
normal_tables tables not inner w.r.t some outer join (ones for which
we can make ref access based the WHERE clause)
select_lex current SELECT
-
- RETURN
+
+ RETURN
0 - OK
1 - Out of memory.
*/
@@ -3126,7 +3127,7 @@
uint and_level,i,found_eq_constant;
KEY_FIELD *key_fields, *end, *field;
uint m= 1;
-
+
if (cond_equal && cond_equal->max_members)
m= cond_equal->max_members;
@@ -3160,13 +3161,13 @@
In the future when we introduce conditional accesses
for inner tables in outer joins these keys will be taken
into account as well.
- */
+ */
if (*join_tab[i].on_expr_ref)
{
add_key_fields(&end,&and_level,*join_tab[i].on_expr_ref,
join_tab[i].table->map);
}
- else
+ else
{
TABLE_LIST *tab= join_tab[i].table->pos_in_table_list;
TABLE_LIST *embedding= tab->embedding;
@@ -3693,7 +3694,7 @@
{
/*
For each record we have to:
- - read the whole table record
+ - read the whole table record
- skip rows which does not satisfy join condition
*/
tmp= record_count *
@@ -3706,10 +3707,10 @@
tmp*= (1.0 + floor((double) cache_record_length(join,idx) *
record_count /
(double) thd->variables.join_buff_size));
- /*
+ /*
We don't make full cartesian product between rows in the scanned
table and existing records because we skip all rows from the
- scanned table, which does not satisfy join condition when
+ scanned table, which does not satisfy join condition when
we read the table (see flush_cached_records for details). Here we
take into account cost to read and skip these records.
*/
@@ -3782,15 +3783,15 @@
/*
if (SELECT_STRAIGHT_JOIN option is set)
- reorder tables so dependent tables come after tables they depend
- on, otherwise keep tables in the order they were specified in the query
+ reorder tables so dependent tables come after tables they depend
+ on, otherwise keep tables in the order they were specified in the query
else
Apply heuristic: pre-sort all access plans with respect to the number of
records accessed.
*/
qsort(join->best_ref + join->const_tables, join->tables - join->const_tables,
sizeof(JOIN_TAB*), straight_join?join_tab_cmp_straight:join_tab_cmp);
-
+
if (straight_join)
{
optimize_straight_join(join, join_tables);
@@ -3804,7 +3805,7 @@
*/
join->best_read= DBL_MAX;
find_best(join, join_tables, join->const_tables, 1.0, 0.0);
- }
+ }
else
{
if (search_depth == 0)
@@ -3814,7 +3815,7 @@
}
}
- /*
+ /*
Store the cost of this query into a user variable
Don't update last_query_cost for 'show status' command
*/
@@ -3847,16 +3848,16 @@
if (jt1->dependent & jt2->table->map)
return 1;
if (jt2->dependent & jt1->table->map)
- return -1;
+ return -1;
if (jt1->found_records > jt2->found_records)
return 1;
if (jt1->found_records < jt2->found_records)
- return -1;
+ return -1;
return jt1 > jt2 ? 1 : (jt1 < jt2 ? -1 : 0);
}
-/*
+/*
Same as join_tab_cmp, but for use with SELECT_STRAIGHT_JOIN.
*/
@@ -3955,7 +3956,7 @@
uint idx= join->const_tables;
double record_count= 1.0;
double read_time= 0.0;
-
+
for (JOIN_TAB **pos= join->best_ref + idx ; (s= *pos) ; pos++)
{
/* Find the best access method from 's' to the current partial plan */
@@ -4147,7 +4148,7 @@
table. The choice of a table order and an access path for each table
constitutes a query execution plan (QEP) that fully specifies how to
execute the query.
-
+
The maximal size of the found plan is controlled by the parameter
'search_depth'. When search_depth == N, the resulting plan is complete and
can be used directly as a QEP. If search_depth < N, the found plan consists
@@ -4246,7 +4247,7 @@
DBUG_ENTER("best_extension_by_limited_search");
- /*
+ /*
'join' is a partial plan with lower cost than the best plan so far,
so continue expanding it further with the tables in 'remaining_tables'.
*/
@@ -4565,7 +4566,7 @@
double rec_per_key;
rec_per_key= keyinfo->rec_per_key[keyinfo->key_parts-1] ?
(double) keyinfo->rec_per_key[keyinfo->key_parts-1] :
- (double) s->records/rec+1;
+ (double) s->records/rec+1;
if (!s->records)
tmp=0;
else if (rec_per_key/(double) s->records >= 0.01)
@@ -4673,11 +4674,11 @@
{
/*
For each record we have to:
- - read the whole table record
+ - read the whole table record
- skip rows which does not satisfy join condition
*/
tmp= record_count *
- (tmp +
+ (tmp +
(s->records - rnd_records)/(double) TIME_FOR_COMPARE);
}
else
@@ -4686,10 +4687,10 @@
tmp*= (1.0 + floor((double) cache_record_length(join,idx) *
record_count /
(double) thd->variables.join_buff_size));
- /*
+ /*
We don't make full cartesian product between rows in the scanned
table and existing records because we skip all rows from the
- scanned table, which does not satisfy join condition when
+ scanned table, which does not satisfy join condition when
we read the table (see flush_cached_records for details). Here we
take into account cost to read and skip these records.
*/
@@ -4976,7 +4977,7 @@
uint maybe_null= test(keyinfo->key_part[i].null_bit);
j->ref.items[i]=keyuse->val; // Save for cond removal
- if (keyuse->null_rejecting)
+ if (keyuse->null_rejecting)
j->ref.null_rejecting |= 1 << i;
keyuse_uses_no_tables= keyuse_uses_no_tables && !keyuse->used_tables;
if (!keyuse->used_tables &&
@@ -5078,7 +5079,7 @@
ha_rows cuted_fields=thd->cuted_fields;
/*
we should restore old value of count_cuted_fields because
- store_val_in_field can be called from mysql_insert
+ store_val_in_field can be called from mysql_insert
with select_insert, which make count_cuted_fields= 1
*/
enum_check_fields old_count_cuted_fields= thd->count_cuted_fields;
@@ -5170,7 +5171,7 @@
and plan " any-access(t1), ref(t2.key=t1.field) "
add "t1.field IS NOT NULL" to t1's table condition.
Description of the optimization:
-
+
We look through equalities choosen to perform ref/eq_ref access,
pick equalities that have form "tbl.part_of_key = othertbl.field"
(where othertbl is a non-const table and othertbl.field may be NULL)
@@ -5196,7 +5197,7 @@
This optimization doesn't affect the choices that ref, range, or join
optimizer make. This was intentional because this was added after 4.1
was GA.
-
+
Implementation overview
1. update_ref_and_keys() accumulates info about null-rejecting
predicates in in KEY_FIELD::null_rejecting
@@ -5235,8 +5236,8 @@
DBUG_VOID_RETURN;
/*
We need to do full fix_fields() call here in order to have correct
- notnull->const_item(). This is needed e.g. by test_quick_select
- when it is called from make_join_select after this function is
+ notnull->const_item(). This is needed e.g. by test_quick_select
+ when it is called from make_join_select after this function is
called.
*/
if (notnull->fix_fields(join->thd, ¬null))
@@ -5269,7 +5270,7 @@
RETURN VALUE
pointer to the guarded predicate, if success
0, otherwise
-*/
+*/
static COND*
add_found_match_trig_cond(JOIN_TAB *tab, COND *cond, JOIN_TAB *root_tab)
@@ -5313,7 +5314,7 @@
Here ti are structures of the JOIN_TAB type.
EXAMPLE
- For the query:
+ For the query:
SELECT * FROM t1
LEFT JOIN
(t2, t3 LEFT JOIN t4 ON t3.a=t4.a)
@@ -5323,16 +5324,16 @@
is selected, the following references will be set;
t4->last_inner=[t4], t4->first_inner=[t4], t4->first_upper=[t2]
t2->last_inner=[t4], t2->first_inner=t3->first_inner=[t2],
- on expression (t1.a=t2.a AND t1.b=t3.b) will be attached to
+ on expression (t1.a=t2.a AND t1.b=t3.b) will be attached to
*t2->on_expr_ref, while t3.a=t4.a will be attached to *t4->on_expr_ref.
-
+
NOTES
The function assumes that the simplification procedure has been
already applied to the join query (see simplify_joins).
This function can be called only after the execution plan
has been chosen.
*/
-
+
static void
make_outerjoin_info(JOIN *join)
{
@@ -5346,7 +5347,7 @@
if (tbl->outer_join)
{
- /*
+ /*
Table tab is the only one inner table for outer join.
(Like table t4 for the table reference t3 LEFT JOIN t4 ON t3.a=t4.a
is in the query above.)
@@ -5356,23 +5357,23 @@
tab->cond_equal= tbl->cond_equal;
if (embedding)
tab->first_upper= embedding->nested_join->first_nested;
- }
+ }
for ( ; embedding ; embedding= embedding->embedding)
{
NESTED_JOIN *nested_join= embedding->nested_join;
if (!nested_join->counter)
{
- /*
+ /*
Table tab is the first inner table for nested_join.
Save reference to it in the nested join structure.
- */
+ */
nested_join->first_nested= tab;
tab->on_expr_ref= &embedding->on_expr;
tab->cond_equal= tbl->cond_equal;
if (embedding->embedding)
tab->first_upper= embedding->embedding->nested_join->first_nested;
}
- if (!tab->first_inner)
+ if (!tab->first_inner)
tab->first_inner= nested_join->first_nested;
if (++nested_join->counter < nested_join->join_list.elements)
break;
@@ -5394,7 +5395,7 @@
add_not_null_conds(join);
table_map used_tables;
if (cond) /* Because of QUICK_GROUP_MIN_MAX_SELECT */
- { /* there may be a select without a cond. */
+ { /* there may be a select without a cond. */
if (join->tables > 1)
cond->update_used_tables(); // Tablenr may have changed
if (join->const_tables == join->tables &&
@@ -5425,7 +5426,7 @@
if (!cond_tab->select_cond)
DBUG_RETURN(1);
cond_tab->select_cond->quick_fix_field();
- }
+ }
}
if (const_cond && !const_cond->val_int())
{
@@ -5439,7 +5440,7 @@
for (uint i=join->const_tables ; i < join->tables ; i++)
{
JOIN_TAB *tab=join->join_tab+i;
- JOIN_TAB *first_inner_tab= tab->first_inner;
+ JOIN_TAB *first_inner_tab= tab->first_inner;
table_map current_map= tab->table->map;
bool use_quick_range=0;
COND *tmp;
@@ -5505,7 +5506,7 @@
add a match guard to the pushed down predicate.
The guard will turn the predicate on only after
the first match for outer tables is encountered.
- */
+ */
if (cond)
{
/*
@@ -5520,7 +5521,7 @@
tab->table->file->pushed_cond= NULL;
if (thd->variables.engine_condition_pushdown)
{
- COND *push_cond=
+ COND *push_cond=
make_cond_for_table(tmp, current_map, current_map);
if (push_cond)
{
@@ -5655,22 +5656,22 @@
}
}
}
-
- /*
+
+ /*
Push down all predicates from on expressions.
Each of these predicated are guarded by a variable
that turns if off just before null complemented row for
outer joins is formed. Thus, the predicates from an
'on expression' are guaranteed not to be checked for
the null complemented row.
- */
+ */
JOIN_TAB *last_tab= tab;
while (first_inner_tab && first_inner_tab->last_inner == last_tab)
- {
- /*
+ {
+ /*
Table tab is the last inner table of an outer join.
An on expression is always attached to it.
- */
+ */
COND *on_expr= *first_inner_tab->on_expr_ref;
table_map used_tables= join->const_table_map |
@@ -5690,12 +5691,12 @@
if (!(tmp= add_found_match_trig_cond(cond_tab->first_inner,
tmp, first_inner_tab)))
DBUG_RETURN(1);
- /*
- Now add the guard turning the predicate off for
+ /*
+ Now add the guard turning the predicate off for
the null complemented row.
- */
+ */
DBUG_PRINT("info", ("Item_func_trig_cond"));
- tmp= new Item_func_trig_cond(tmp,
+ tmp= new Item_func_trig_cond(tmp,
&first_inner_tab->not_null_compl);
DBUG_PRINT("info", ("Item_func_trig_cond 0x%lx", (ulong) tmp));
if (tmp)
@@ -5709,9 +5710,9 @@
if (!cond_tab->select_cond)
DBUG_RETURN(1);
cond_tab->select_cond->quick_fix_field();
- }
+ }
}
- first_inner_tab= first_inner_tab->first_upper;
+ first_inner_tab= first_inner_tab->first_upper;
}
}
}
@@ -6207,7 +6208,7 @@
cond WHERE statement
change_list Set to 1 if we should remove things from list
If this is not set, then only simple_order is
- calculated
+ calculated
simple_order Set to 1 if we are only using simple expressions
RETURN
@@ -6363,15 +6364,15 @@
#endif
-/*
+/*
Find the multiple equality predicate containing a field
-
+
SYNOPSIS
find_item_equal()
cond_equal multiple equalities to search in
field field to look for
inherited_fl :out set up to TRUE if multiple equality is found
- on upper levels (not on current level of cond_equal)
+ on upper levels (not on current level of cond_equal)
DESCRIPTION
The function retrieves the multiple equalities accessed through
@@ -6406,8 +6407,8 @@
return item;
}
-
-/*
+
+/*
Check whether an item is a simple equality predicate and if so
create/find a multiple equality for this predicate
@@ -6439,7 +6440,7 @@
the check_equality will be called for the following equality
predicates a=b, b=c, b=2 and f=e.
For a=b it will be called with *cond_equal=(0,[]) and will transform
- *cond_equal into (0,[Item_equal(a,b)]).
+ *cond_equal into (0,[Item_equal(a,b)]).
For b=c it will be called with *cond_equal=(0,[Item_equal(a,b)])
and will transform *cond_equal into CE=(0,[Item_equal(a,b,c)]).
For b=2 it will be called with *cond_equal=(ptr(CE),[])
@@ -6452,14 +6453,14 @@
the Field::eq_def method) are placed to the same multiple equalities.
Because of this some equality predicates are not eliminated and
can be used in the constant propagation procedure.
- We could weeken the equlity test as soon as at least one of the
- equal fields is to be equal to a constant. It would require a
+ We could weeken the equlity test as soon as at least one of the
+ equal fields is to be equal to a constant. It would require a
more complicated implementation: we would have to store, in
general case, its own constant for each fields from the multiple
equality. But at the same time it would allow us to get rid
of constant propagation completely: it would be done by the call
to build_equal_items_for_cond.
-
+
IMPLEMENTATION
The implementation does not follow exactly the above rules to
build a new multiple equality for the equality predicate.
@@ -6471,7 +6472,7 @@
containing just field1 and field2 is added to the existing
multiple equalities.
If the function processes the predicate of the form field1=const,
- it looks for a multiple equality containing field1. If found, the
+ it looks for a multiple equality containing field1. If found, the
function checks the constant of the multiple equality. If the value
is unknown, it is setup to const. Otherwise the value is compared with
const and the evaluation of the equality predicate is performed.
@@ -6507,24 +6508,24 @@
if (left_field->eq(right_field)) /* f = f */
return TRUE;
-
+
/* Search for multiple equalities containing field1 and/or field2 */
bool left_copyfl, right_copyfl;
Item_equal *left_item_equal=
find_item_equal(cond_equal, left_field, &left_copyfl);
- Item_equal *right_item_equal=
+ Item_equal *right_item_equal=
find_item_equal(cond_equal, right_field, &right_copyfl);
if (left_item_equal && left_item_equal == right_item_equal)
{
- /*
+ /*
The equality predicate is inference of one of the existing
multiple equalities, i.e the condition is already covered
by upper level equalities
*/
return TRUE;
}
-
+
/* Copy the found multiple equalities at the current level if needed */
if (left_copyfl)
{
@@ -6540,7 +6541,7 @@
}
if (left_item_equal)
- {
+ {
/* left item was found in the current or one of the upper levels */
if (! right_item_equal)
left_item_equal->add((Item_field *) right_item);
@@ -6555,11 +6556,11 @@
}
}
else
- {
+ {
/* left item was not found neither the current nor in upper levels */
if (right_item_equal)
right_item_equal->add((Item_field *) left_item);
- else
+ else
{
/* None of the fields was found in multiple equalities */
Item_equal *item= new Item_equal((Item_field *) left_item,
@@ -6610,7 +6611,7 @@
}
if (item_equal)
{
- /*
+ /*
The flag cond_false will be set to 1 after this, if item_equal
already contains a constant and its value is not equal to
the value of const_item.
@@ -6629,7 +6630,7 @@
return FALSE;
}
-/*
+/*
Replace all equality predicates in a condition by multiple equality items
SYNOPSIS
@@ -6640,20 +6641,20 @@
DESCRIPTION
At each 'and' level the function detects items for equality predicates
and replaced them by a set of multiple equality items of class Item_equal,
- taking into account inherited equalities from upper levels.
+ taking into account inherited equalities from upper levels.
If an equality predicate is used not in a conjunction it's just
replaced by a multiple equality predicate.
For each 'and' level the function set a pointer to the inherited
multiple equalities in the cond_equal field of the associated
- object of the type Item_cond_and.
+ object of the type Item_cond_and.
The function also traverses the cond tree and and for each field reference
sets a pointer to the multiple equality item containing the field, if there
is any. If this multiple equality equates fields to a constant the
function replace the field reference by the constant.
- The function also determines the maximum number of members in
+ The function also determines the maximum number of members in
equality lists of each Item_cond_and object assigning it to
cond_equal->max_members of this object and updating accordingly
- the upper levels COND_EQUAL structures.
+ the upper levels COND_EQUAL structures.
NOTES
Multiple equality predicate =(f1,..fn) is equivalent to the conjuction of
@@ -6665,7 +6666,7 @@
in a conjuction for a minimal set of multiple equality predicates.
This set can be considered as a canonical representation of the
sub-conjunction of the equality predicates.
- E.g. (t1.a=t2.b AND t2.b>5 AND t1.a=t3.c) is replaced by
+ E.g. (t1.a=t2.b AND t2.b>5 AND t1.a=t3.c) is replaced by
(=(t1.a,t2.b,t3.c) AND t2.b>5), not by
(=(t1.a,t2.b) AND =(t1.a,t3.c) AND t2.b>5);
while (t1.a=t2.b AND t2.b>5 AND t3.c=t4.d) is replaced by
@@ -6677,16 +6678,16 @@
The function performs the substitution in a recursive descent by
the condtion tree, passing to the next AND level a chain of multiple
equality predicates which have been built at the upper levels.
- The Item_equal items built at the level are attached to other
+ The Item_equal items built at the level are attached to other
non-equality conjucts as a sublist. The pointer to the inherited
multiple equalities is saved in the and condition object (Item_cond_and).
- This chain allows us for any field reference occurence easyly to find a
+ This chain allows us for any field reference occurence easyly to find a
multiple equality that must be held for this occurence.
For each AND level we do the following:
- scan it for all equality predicate (=) items
- join them into disjoint Item_equal() groups
- - process the included OR conditions recursively to do the same for
- lower AND levels.
+ - process the included OR conditions recursively to do the same for
+ lower AND levels.
We need to do things in this order as lower AND levels need to know about
all possible Item_equal objects in upper levels.
@@ -6707,7 +6708,7 @@
bool and_level= ((Item_cond*) cond)->functype() ==
Item_func::COND_AND_FUNC;
List<Item> *args= ((Item_cond*) cond)->argument_list();
-
+
List_iterator<Item> li(*args);
Item *item;
@@ -6716,9 +6717,9 @@
/*
Retrieve all conjucts of this level detecting the equality
that are subject to substitution by multiple equality items and
- removing each such predicate from the conjunction after having
+ removing each such predicate from the conjunction after having
found/created a multiple equality whose inference the predicate is.
- */
+ */
while ((item= li++))
{
/*
@@ -6737,7 +6738,7 @@
item_equal->update_used_tables();
members= item_equal->members();
if (cond_equal.max_members < members)
- cond_equal.max_members= members;
+ cond_equal.max_members= members;
}
members= cond_equal.max_members;
if (inherited && inherited->max_members < members)
@@ -6759,7 +6760,7 @@
*/
li.rewind();
while ((item= li++))
- {
+ {
Item *new_item;
if ((new_item = build_equal_items_for_cond(item, inherited))!= item)
{
@@ -6785,7 +6786,7 @@
(b=5) and (a=c) are standalone equalities.
In general we can't leave alone standalone eqalities:
for WHERE a=b AND c=d AND (b=c OR d=5)
- b=c is replaced by =(a,b,c,d).
+ b=c is replaced by =(a,b,c,d).
*/
if (check_equality(cond, &cond_equal) &&
(item_equal= cond_equal.current_level.pop()))
@@ -6794,10 +6795,10 @@
item_equal->update_used_tables();
return item_equal;
}
- /*
+ /*
For each field reference in cond, not from equalitym predicates,
set a pointer to the multiple equality if belongs to (if there is any)
- */
+ */
cond= cond->transform(&Item::equal_fields_propagator,
(byte *) inherited);
cond->update_used_tables();
@@ -6806,7 +6807,7 @@
}
-/*
+/*
Build multiple equalities for a condition and all on expressions that
inherit these multiple equalities
@@ -6829,7 +6830,7 @@
NOTES
The on expression used in an outer join operation inherits all equalities
- from the on expression of the embedding join, if there is any, or
+ from the on expression of the embedding join, if there is any, or
otherwise - from the where condition.
This fact is not obvious, but presumably can be proved.
Consider the following query:
@@ -6852,18 +6853,18 @@
Similarly the original query can be rewritten to the query:
SELECT * FROM (t1,t2) LEFT JOIN (t3,t4) ON t2.a=t4.a AND t3.a=t4.a
WHERE t1.a=t2.a
- that is equivalent to:
+ that is equivalent to:
SELECT * FROM (t2 LEFT JOIN (t3,t4)ON t2.a=t4.a AND t3.a=t4.a), t1
WHERE t1.a=t2.a
Thus, applying equalities from the where condition we basically
can get more freedom in performing join operations.
- Althogh we don't use this property now, it probably makes sense to use
- it in the future.
-
+ Althogh we don't use this property now, it probably makes sense to use
+ it in the future.
+
RETURN
pointer to the transformed condition containing multiple equalities
*/
-
+
static COND *build_equal_items(THD *thd, COND *cond,
COND_EQUAL *inherited,
List<TABLE_LIST> *join_list,
@@ -6871,7 +6872,7 @@
{
COND_EQUAL *cond_equal= 0;
- if (cond)
+ if (cond)
{
cond= build_equal_items_for_cond(cond, inherited);
cond->update_used_tables();
@@ -6914,26 +6915,26 @@
}
return cond;
-}
+}
-/*
+/*
Compare field items by table order in the execution plan
-
+
SYNOPSIS
compare_fields_by_table_order()
field1 first field item to compare
field2 second field item to compare
- table_join_idx index to tables determining table order
+ table_join_idx index to tables determining table order
DESCRIPTION
field1 considered as better than field2 if the table containing
- field1 is accessed earlier than the table containing field2.
+ field1 is accessed earlier than the table containing field2.
The function finds out what of two fields is better according
this criteria.
RETURN
- 1, if field1 is better than field2
+ 1, if field1 is better than field2
-1, if field2 is better than field1
0, otherwise
*/
@@ -6945,7 +6946,7 @@
int cmp= 0;
bool outer_ref= 0;
if (field2->used_tables() & OUTER_REF_TABLE_BIT)
- {
+ {
outer_ref= 1;
cmp= -1;
}
@@ -6962,14 +6963,14 @@
}
-/*
+/*
Generate minimal set of simple equalities equivalent to a multiple equality
-
+
SYNOPSIS
eliminate_item_equal()
cond condition to add the generated equality to
upper_levels structure to access multiple equality of upper levels
- item_equal multiple equality to generate simple equality from
+ item_equal multiple equality to generate simple equality from
DESCRIPTION
The function retrieves the fields of the multiple equality item
@@ -7011,7 +7012,7 @@
List<Item> eq_list;
Item_func_eq *eq_item= 0;
if (((Item *) item_equal)->const_item() && !item_equal->val_int())
- return new Item_int((longlong) 0,1);
+ return new Item_int((longlong) 0,1);
Item *item_const= item_equal->get_const();
Item_equal_iterator it(*item_equal);
Item *head;
@@ -7028,7 +7029,7 @@
Item_equal *upper= item_field->find_item_equal(upper_levels);
Item_field *item= item_field;
if (upper)
- {
+ {
if (item_const && upper->get_const())
item= 0;
else
@@ -7069,15 +7070,15 @@
cond->quick_fix_field();
cond->update_used_tables();
-
+
return cond;
}
-/*
- Substitute every field reference in a condition by the best equal field
+/*
+ Substitute every field reference in a condition by the best equal field
and eliminate all multiplle equality predicates
-
+
SYNOPSIS
substitute_for_best_equal_field()
cond condition to process
@@ -7089,13 +7090,13 @@
multiple equality predicate it sorts the field references in it
according to the order of tables specified by the table_join_idx
parameter. Then it eliminates the multiple equality predicate it
- replacing it by the conjunction of simple equality predicates
+ replacing it by the conjunction of simple equality predicates
equating every field from the multiple equality to the first
field in it, or to the constant, if there is any.
After this the function retrieves all other conjuncted
predicates substitute every field reference by the field reference
to the first equal field or equal constant if there are any.
-
+
NOTES
At the first glance full sort of fields in multiple equality
seems to be an overkill. Yet it's not the case due to possible
@@ -7123,13 +7124,13 @@
cond_equal= &((Item_cond_and *) cond)->cond_equal;
cond_list->disjoin((List<Item> *) &cond_equal->current_level);
- List_iterator_fast<Item_equal> it(cond_equal->current_level);
+ List_iterator_fast<Item_equal> it(cond_equal->current_level);
while ((item_equal= it++))
{
item_equal->sort(&compare_fields_by_table_order, table_join_idx);
}
}
-
+
List_iterator<Item> li(*cond_list);
Item *item;
while ((item= li++))
@@ -7153,7 +7154,7 @@
}
}
}
- else if (cond->type() == Item::FUNC_ITEM &&
+ else if (cond->type() == Item::FUNC_ITEM &&
((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC)
{
item_equal= (Item_equal *) cond;
@@ -7348,7 +7349,7 @@
join reference to the query info
join_list list representation of the join to be converted
conds conditions to add on expressions for converted joins
- top true <=> conds is the where condition
+ top true <=> conds is the where condition
DESCRIPTION
The function, during a retrieval of join_list, eliminates those
@@ -7356,7 +7357,7 @@
It also moves the on expressions for the converted outer joins
and from inner joins to conds.
The function also calculates some attributes for nested joins:
- - used_tables
+ - used_tables
- not_null_tables
- dep_tables.
- on_expr_dep_tables
@@ -7379,7 +7380,7 @@
or the on expression for an embedding nested join contains a conjunctive
predicate rejecting null values for some attribute of the inner tables.
- E.g. in the query:
+ E.g. in the query:
SELECT * FROM t1 LEFT JOIN t2 ON t2.a=t1.a WHERE t2.b < 5
the predicate t2.b < 5 rejects nulls.
The query is converted first to:
@@ -7389,30 +7390,30 @@
Similarly the following query:
SELECT * from t1 LEFT JOIN (t2, t3) ON t2.a=t1.a t3.b=t1.b
- WHERE t2.c < 5
+ WHERE t2.c < 5
is converted to:
- SELECT * FROM t1, (t2, t3) WHERE t2.c < 5 AND t2.a=t1.a t3.b=t1.b
+ SELECT * FROM t1, (t2, t3) WHERE t2.c < 5 AND t2.a=t1.a t3.b=t1.b
One conversion might trigger another:
SELECT * FROM t1 LEFT JOIN t2 ON t2.a=t1.a
LEFT JOIN t3 ON t3.b=t2.b
WHERE t3 IS NOT NULL =>
SELECT * FROM t1 LEFT JOIN t2 ON t2.a=t1.a, t3
- WHERE t3 IS NOT NULL AND t3.b=t2.b =>
+ WHERE t3 IS NOT NULL AND t3.b=t2.b =>
SELECT * FROM t1, t2, t3
WHERE t3 IS NOT NULL AND t3.b=t2.b AND t2.a=t1.a
-
+
The function removes all unnecessary braces from the expression
produced by the conversions.
E.g. SELECT * FROM t1, (t2, t3) WHERE t2.c < 5 AND t2.a=t1.a AND t3.b=t1.b
- finally is converted to:
+ finally is converted to:
SELECT * FROM t1, t2, t3 WHERE t2.c < 5 AND t2.a=t1.a AND t3.b=t1.b
It also will remove braces from the following queries:
SELECT * from (t1 LEFT JOIN t2 ON t2.a=t1.a) LEFT JOIN t3 ON t3.b=t2.b
SELECT * from (t1, (t2,t3)) WHERE t1.a=t2.a AND t2.b=t3.b.
- The benefit of this simplification procedure is that it might return
+ The benefit of this simplification procedure is that it might return
a query for which the optimizer can evaluate execution plan with more
join orders. With a left join operation the optimizer does not
consider any plan where one of the inner tables is before some of outer
@@ -7427,11 +7428,11 @@
EXAMPLES
Here is an example of a join query with invalid cross references:
- SELECT * FROM t1 LEFT JOIN t2 ON t2.a=t3.a LEFT JOIN ON t3.b=t1.b
-
+ SELECT * FROM t1 LEFT JOIN t2 ON t2.a=t3.a LEFT JOIN ON t3.b=t1.b
+
RETURN VALUE
The new condition, if success
- 0, otherwise
+ 0, otherwise
*/
static COND *
@@ -7443,9 +7444,9 @@
List_iterator<TABLE_LIST> li(*join_list);
DBUG_ENTER("simplify_joins");
- /*
+ /*
Try to simplify join operations from join_list.
- The most outer join operation is checked for conversion first.
+ The most outer join operation is checked for conversion first.
*/
while ((table= li++))
{
@@ -7454,21 +7455,21 @@
if ((nested_join= table->nested_join))
{
- /*
+ /*
If the element of join_list is a nested join apply
the procedure to its nested join list first.
*/
if (table->on_expr)
{
Item *expr= table->prep_on_expr ? table->prep_on_expr : table->on_expr;
- /*
- If an on expression E is attached to the table,
+ /*
+ If an on expression E is attached to the table,
check all null rejected predicates in this expression.
If such a predicate over an attribute belonging to
an inner table of an embedded outer join is found,
the outer join is converted to an inner join and
- the corresponding on expression is added to E.
- */
+ the corresponding on expression is added to E.
+ */
expr= simplify_joins(join, &nested_join->join_list,
expr, FALSE);
table->prep_on_expr= table->on_expr= expr;
@@ -7477,7 +7478,7 @@
nested_join->not_null_tables=(table_map) 0;
conds= simplify_joins(join, &nested_join->join_list, conds, top);
used_tables= nested_join->used_tables;
- not_null_tables= nested_join->not_null_tables;
+ not_null_tables= nested_join->not_null_tables;
}
else
{
@@ -7487,7 +7488,7 @@
if (conds)
not_null_tables= conds->not_null_tables();
}
-
+
if (table->embedding)
{
table->embedding->nested_join->used_tables|= used_tables;
@@ -7496,7 +7497,7 @@
if (!table->outer_join || (used_tables & not_null_tables))
{
- /*
+ /*
For some of the inner tables there are conjunctive predicates
that reject nulls => the outer join can be replaced by an inner join.
*/
@@ -7513,27 +7514,27 @@
conds->fix_fields(join->thd, &conds);
}
else
- conds= table->on_expr;
+ conds= table->on_expr;
table->prep_on_expr= table->on_expr= 0;
}
}
-
+
if (!top)
continue;
- /*
+ /*
Only inner tables of non-convertible outer joins
remain with on_expr.
- */
+ */
if (table->on_expr)
{
- table->dep_tables|= table->on_expr->used_tables();
+ table->dep_tables|= table->on_expr->used_tables();
if (table->embedding)
{
- table->dep_tables&= ~table->embedding->nested_join->used_tables;
+ table->dep_tables&= ~table->embedding->nested_join->used_tables;
/*
Embedding table depends on tables used
- in embedded on expressions.
+ in embedded on expressions.
*/
table->embedding->on_expr_dep_tables|= table->on_expr->used_tables();
}
@@ -7552,19 +7553,19 @@
table_map prev_used_tables= prev_table->nested_join ?
prev_table->nested_join->used_tables :
prev_table->table->map;
- /*
+ /*
If on expression contains only references to inner tables
we still make the inner tables dependent on the outer tables.
It would be enough to set dependency only on one outer table
for them. Yet this is really a rare case.
- */
+ */
if (!(prev_table->on_expr->used_tables() & ~prev_used_tables))
prev_table->dep_tables|= used_tables;
}
}
prev_table= table;
}
-
+
/* Flatten nested joins that can be flattened. */
li.rewind();
while ((table= li++))
@@ -7578,34 +7579,34 @@
{
tbl->embedding= table->embedding;
tbl->join_list= table->join_list;
- }
+ }
li.replace(nested_join->join_list);
}
}
- DBUG_RETURN(conds);
+ DBUG_RETURN(conds);
}
-
+
static COND *
optimize_cond(JOIN *join, COND *conds, List<TABLE_LIST> *join_list,
Item::cond_result *cond_value)
{
THD *thd= join->thd;
- SELECT_LEX *select= thd->lex->current_select;
+ SELECT_LEX *select= thd->lex->current_select;
DBUG_ENTER("optimize_cond");
if (!conds)
*cond_value= Item::COND_TRUE;
else
{
- /*
+ /*
Build all multiple equality predicates and eliminate equality
predicates that can be inferred from these multiple equalities.
For each reference of a field included into a multiple equality
that occurs in a function set a pointer to the multiple equality
predicate. Substitute a constant instead of this field if the
multiple equality contains a constant.
- */
+ */
DBUG_EXECUTE("where", print_where(conds, "original"););
conds= build_equal_items(join->thd, conds, NULL, join_list,
&join->cond_equal);
@@ -7844,7 +7845,7 @@
/*
Create field for temporary table from given field
-
+
SYNOPSIS
create_tmp_field_from_field()
thd Thread handler
@@ -7857,7 +7858,7 @@
the record in the original table.
If item == NULL then fill_record() will update
the temporary table
- convert_blob_length If >0 create a varstring(convert_blob_length) field
+ convert_blob_length If >0 create a varstring(convert_blob_length) field
instead of blob.
RETURN
@@ -7895,7 +7896,7 @@
/*
Create field for temporary table using type of given item
-
+
SYNOPSIS
create_tmp_field_from_item()
thd Thread handler
@@ -7910,7 +7911,7 @@
the record in the original table.
If modify_item is 0 then fill_record() will update
the temporary table
- convert_blob_length If >0 create a varstring(convert_blob_length) field
+ convert_blob_length If >0 create a varstring(convert_blob_length) field
instead of blob.
RETURN
@@ -8012,7 +8013,7 @@
the record in the original table.
If modify_item is 0 then fill_record() will update
the temporary table
- convert_blob_length If >0 create a varstring(convert_blob_length) field
+ convert_blob_length If >0 create a varstring(convert_blob_length) field
instead of blob.
RETURN
@@ -8048,7 +8049,7 @@
!((Item_ref *)org_item)->depended_from)
{
Item_field *field= (Item_field*) item;
- if (table_cant_handle_bit_fields &&
+ if (table_cant_handle_bit_fields &&
field->field->type() == FIELD_TYPE_BIT)
return create_tmp_field_from_item(thd, item, table, copy_func,
modify_item, convert_blob_length);
@@ -9213,19 +9214,19 @@
}
/*
- Retrieve records ends with a given beginning from the result of a join
+ Retrieve records ends with a given beginning from the result of a join
SYNPOSIS
sub_select()
join pointer to the structure providing all context info for the query
join_tab the first next table of the execution plan to be retrieved
- end_records true when we need to perform final steps of retrival
+ end_records true when we need to perform final steps of retrival
DESCRIPTION
- For a given partial join record consisting of records from the tables
+ For a given partial join record consisting of records from the tables
preceding the table join_tab in the execution plan, the function
retrieves all matching full records from the result set and
- send them to the result set stream.
+ send them to the result set stream.
NOTES
The function effectively implements the final (n-k) nested loops
@@ -9234,7 +9235,7 @@
It performs nested loops joins with all conjunctive predicates from
the where condition pushed as low to the tables as possible.
E.g. for the query
- SELECT * FROM t1,t2,t3
+ SELECT * FROM t1,t2,t3
WHERE t1.a=t2.a AND t2.b=t3.b AND t1.a BETWEEN 5 AND 9
the predicate (t1.a BETWEEN 5 AND 9) will be pushed to table t1,
given the selected plan prescribes to nest retrievals of the
@@ -9251,9 +9252,9 @@
the execution plan. In this case the pushed down predicates can be
checked only at certain conditions.
Suppose for the query
- SELECT * FROM t1 LEFT JOIN (t2,t3) ON t3.a=t1.a
+ SELECT * FROM t1 LEFT JOIN (t2,t3) ON t3.a=t1.a
WHERE t1>2 AND (t2.b>5 OR t2.b IS NULL)
- the optimizer has chosen a plan with the table order t1,t2,t3.
+ the optimizer has chosen a plan with the table order t1,t2,t3.
The predicate P1=t1>2 will be pushed down to the table t1, while the
predicate P2=(t2.b>5 OR t2.b IS NULL) will be attached to the table
t2. But the second predicate can not be unconditionally tested right
@@ -9261,7 +9262,7 @@
first row with t3.a=t1.a has been encountered.
Thus, the second predicate P2 is supplied with a guarded value that are
stored in the field 'found' of the first inner table for the outer join
- (table t2). When the first row with t3.a=t1.a for the current row
+ (table t2). When the first row with t3.a=t1.a for the current row
of table t1 appears, the value becomes true. For now on the predicate
is evaluated immediately after the row of table t2 has been read.
When the first row with t3.a=t1.a has been encountered all
@@ -9269,7 +9270,7 @@
Only when all of them are true the row is sent to the output stream.
If not, the function returns to the lowest nest level that has a false
attached condition.
- The predicates from on expressions are also pushed down. If in the
+ The predicates from on expressions are also pushed down. If in the
the above example the on expression were (t3.a=t1.a AND t2.a=t1.a),
then t1.a=t2.a would be pushed down to table t2, and without any
guard.
@@ -9279,7 +9280,7 @@
is complemented by nulls for t2 and t3. Then the pushed down predicates
are checked for the composed row almost in the same way as it had
been done for the first row with a match. The only difference is
- the predicates from on expressions are not checked.
+ the predicates from on expressions are not checked.
IMPLEMENTATION
The function forms output rows for a current partial join of k
@@ -9293,8 +9294,8 @@
and a pointer to a guarding boolean variable.
When the value of the guard variable is true the value of the object
is the same as the value of the predicate, otherwise it's just returns
- true.
- To carry out a return to a nested loop level of join table t the pointer
+ true.
+ To carry out a return to a nested loop level of join table t the pointer
to t is remembered in the field 'return_tab' of the join structure.
Consider the following query:
SELECT * FROM t1,
@@ -9309,12 +9310,12 @@
t5.a=t3.a is found, the pushed down predicate t4.b=2 OR t4.b IS NULL
becomes 'activated', as well the predicate t4.a=t2.a. But
the predicate (t2.b=5 OR t2.b IS NULL) can not be checked until
- t4.a=t2.a becomes true.
+ t4.a=t2.a becomes true.
In order not to re-evaluate the predicates that were already evaluated
as attached pushed down predicates, a pointer to the the first
most inner unmatched table is maintained in join_tab->first_unmatched.
Thus, when the first row from t5 with t5.a=t3.a is found
- this pointer for t5 is changed from t4 to t2.
+ this pointer for t5 is changed from t4 to t2.
STRUCTURE NOTES
join_tab->first_unmatched points always backwards to the first inner
@@ -9695,7 +9696,7 @@
table->const_table=1;
table->null_row=0;
table->status=STATUS_NO_RECORD;
-
+
if (tab->type == JT_SYSTEM)
{
if ((error=join_read_system(tab)))
@@ -9734,7 +9735,7 @@
if (*tab->on_expr_ref && !table->null_row)
{
if ((table->null_row= test((*tab->on_expr_ref)->val_int() == 0)))
- mark_as_null_row(table);
+ mark_as_null_row(table);
}
if (!table->null_row)
table->maybe_null=0;
@@ -9867,10 +9868,10 @@
/*
- This function is used when optimizing away ORDER BY in
+ This function is used when optimizing away ORDER BY in
SELECT * FROM t1 WHERE a=1 ORDER BY a DESC,b DESC
*/
-
+
static int
join_read_last_key(JOIN_TAB *tab)
{
@@ -10180,7 +10181,7 @@
join->send_records = table->file->records;
}
}
- else
+ else
{
join->do_send_rows= 0;
if (join->unit->fake_select_lex)
@@ -10767,7 +10768,7 @@
These are already skipped in the ORDER BY by const_expression_in_where()
*/
for (; const_key_parts & 1 ; const_key_parts>>= 1)
- key_part++;
+ key_part++;
if (key_part == key_part_end || key_part->field != field)
DBUG_RETURN(0);
@@ -10826,7 +10827,7 @@
0 no sub key
*/
-inline bool
+inline bool
is_subkey(KEY_PART_INFO *key_part, KEY_PART_INFO *ref_key_part,
KEY_PART_INFO *ref_key_part_end)
{
@@ -10926,14 +10927,14 @@
else if (select && select->quick) // Range found by opt_range
{
int quick_type= select->quick->get_type();
- /*
- assume results are not ordered when index merge is used
- TODO: sergeyp: Results of all index merge selects actually are ordered
+ /*
+ assume results are not ordered when index merge is used
+ TODO: sergeyp: Results of all index merge selects actually are ordered
by clustered PK values.
*/
-
- if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE ||
- quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION ||
+
+ if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE ||
+ quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION ||
quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT)
DBUG_RETURN(0);
ref_key= select->quick->index;
@@ -10966,17 +10967,17 @@
if (tab->ref.key >= 0)
{
/*
- We'll use ref access method on key new_ref_key. In general case
+ We'll use ref access method on key new_ref_key. In general case
the index search tuple for new_ref_key will be different (e.g.
when one index is defined as (part1, part2, ...) and another as
- (part1, part2(N), ...) and the WHERE clause contains
- "part1 = const1 AND part2=const2".
+ (part1, part2(N), ...) and the WHERE clause contains
+ "part1 = const1 AND part2=const2".
So we build tab->ref from scratch here.
*/
KEYUSE *keyuse= tab->keyuse;
while (keyuse->key != new_ref_key && keyuse->table == tab->table)
keyuse++;
- if (create_ref_for_key(tab->join, tab, keyuse,
+ if (create_ref_for_key(tab->join, tab, keyuse,
tab->join->const_table_map))
DBUG_RETURN(0);
}
@@ -11026,7 +11027,7 @@
quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION ||
quick_type == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX)
DBUG_RETURN(0); // Use filesort
-
+
/* ORDER BY range_key DESC */
QUICK_SELECT_DESC *tmp=new QUICK_SELECT_DESC((QUICK_RANGE_SELECT*)(select->quick),
used_key_parts);
@@ -11075,11 +11076,11 @@
keys.merge(table->used_keys);
/*
- We are adding here also the index specified in FORCE INDEX clause,
+ We are adding here also the index specified in FORCE INDEX clause,
if any.
This is to allow users to use index in ORDER BY.
*/
- if (table->force_index)
+ if (table->force_index)
keys.merge(table->keys_in_use_for_query);
keys.intersect(usable_keys);
}
@@ -11176,7 +11177,7 @@
{
select->quick=tab->quick;
tab->quick=0;
- /*
+ /*
We can only use 'Only index' if quick key is same as ref_key
and in index_merge 'Only index' cannot be used
*/
@@ -11196,7 +11197,7 @@
*/
if (!(select->quick= (tab->type == JT_FT ?
new FT_SELECT(thd, table, tab->ref.key) :
- get_quick_select_for_ref(thd, table, &tab->ref,
+ get_quick_select_for_ref(thd, table, &tab->ref,
tab->found_records))))
goto err;
}
@@ -11324,13 +11325,13 @@
field_count++;
}
- if (!field_count && !(join->select_options & OPTION_FOUND_ROWS))
+ if (!field_count && !(join->select_options & OPTION_FOUND_ROWS))
{ // only const items with no OPTION_FOUND_ROWS
join->unit->select_limit_cnt= 1; // Only send first row
DBUG_RETURN(0);
}
Field **first_field=entry->field+entry->s->fields - field_count;
- offset= field_count ?
+ offset= field_count ?
entry->field[entry->s->fields - field_count]->offset() : 0;
reclength=entry->s->reclength-offset;
@@ -11481,7 +11482,7 @@
extra_length= ALIGN_SIZE(key_length)-key_length;
}
- if (hash_init(&hash, &my_charset_bin, (uint) file->records, 0,
+ if (hash_init(&hash, &my_charset_bin, (uint) file->records, 0,
key_length, (hash_get_key) 0, 0, 0))
{
my_free((char*) key_buffer,MYF(0));
@@ -11724,7 +11725,7 @@
{
if (last_record)
{
- copy->blob_field->get_image((char*) pos,copy->length+sizeof(char*),
+ copy->blob_field->get_image((char*) pos,copy->length+sizeof(char*),
copy->blob_field->charset());
pos+=copy->length+sizeof(char*);
}
@@ -11835,7 +11836,7 @@
{
memcpy(tab->ref.key_buff2, tab->ref.key_buff, tab->ref.key_length);
}
- if ((tab->ref.key_err= cp_buffer_from_ref(tab->join->thd, &tab->ref)) ||
+ if ((tab->ref.key_err= cp_buffer_from_ref(tab->join->thd, &tab->ref)) ||
diff)
return 1;
return memcmp(tab->ref.key_buff2, tab->ref.key_buff, tab->ref.key_length)
@@ -12156,7 +12157,7 @@
static ORDER *
create_distinct_group(THD *thd, Item **ref_pointer_array,
- ORDER *order_list, List<Item> &fields,
+ ORDER *order_list, List<Item> &fields,
bool *all_order_by_fields_used)
{
List_iterator<Item> li(fields);
@@ -12333,7 +12334,7 @@
key_length+= field->pack_length();
}
else
- {
+ {
switch (group_item->result_type()) {
case REAL_RESULT:
key_length+= sizeof(double);
@@ -12342,7 +12343,7 @@
key_length+= sizeof(longlong);
break;
case DECIMAL_RESULT:
- key_length+= my_decimal_get_binary_size(group_item->max_length -
+ key_length+= my_decimal_get_binary_size(group_item->max_length -
(group_item->decimals ? 1 : 0),
group_item->decimals);
break;
@@ -12458,7 +12459,7 @@
Only FIELD_ITEM:s and FUNC_ITEM:s needs to be saved between groups.
Change old item_field to use a new field with points at saved fieldvalue
This function is only called before use of send_fields
-
+
RETURN
0 - ok
!=0 - error
@@ -12480,7 +12481,7 @@
uint i, border= all_fields.elements - elements;
DBUG_ENTER("setup_copy_fields");
- if (param->field_count &&
+ if (param->field_count &&
!(copy=param->copy_field= new Copy_field[param->field_count]))
goto err2;
@@ -12499,21 +12500,21 @@
if (!(pos= new Item_copy_string(pos)))
goto err;
/*
- Item_copy_string::copy for function can call
+ Item_copy_string::copy for function can call
Item_copy_string::val_int for blob via Item_ref.
But if Item_copy_string::copy for blob isn't called before,
it's value will be wrong
- so let's insert Item_copy_string for blobs in the beginning of
+ so let's insert Item_copy_string for blobs in the beginning of
copy_funcs
- (to see full test case look at having.test, BUG #4358)
+ (to see full test case look at having.test, BUG #4358)
*/
if (param->copy_funcs.push_front(pos))
goto err;
}
else
{
- /*
- set up save buffer and change result_field to point at
+ /*
+ set up save buffer and change result_field to point at
saved value
*/
Field *field= item->field;
@@ -12526,7 +12527,7 @@
copy->set(tmp, item->result_field);
item->result_field->move_field(copy->to_ptr,copy->to_null_ptr,1);
copy++;
- }
+ }
}
}
else if ((pos->type() == Item::FUNC_ITEM ||
@@ -12724,7 +12725,7 @@
for (i= 0; (item= it++); i++)
{
Field *field;
-
+
if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM)
item_field= item;
else
@@ -13005,8 +13006,8 @@
EXAMPLES
SELECT a+1 FROM t1 GROUP BY a WITH ROLLUP
- SELECT SUM(a)+a FROM t1 GROUP BY a WITH ROLLUP
-
+ SELECT SUM(a)+a FROM t1 GROUP BY a WITH ROLLUP
+
RETURN
0 if ok
1 on error
@@ -13073,7 +13074,7 @@
ref_pointer_array_size)
* send_group_parts )))
return 1;
-
+
rollup.fields= (List<Item>*) (rollup.null_items + send_group_parts);
rollup.ref_pointer_arrays= (Item***) (rollup.fields + send_group_parts);
ref_array= (Item**) (rollup.ref_pointer_arrays+send_group_parts);
@@ -13114,14 +13115,14 @@
We have to prevent creation of a field in a temporary table for
an expression that contains GROUP BY attributes.
Marking the expression item as 'with_sum_func' will ensure this.
- */
+ */
if (changed)
item->with_sum_func= 1;
}
}
return 0;
}
-
+
/*
Fill up rollup structures with pointers to fields to use
@@ -13215,7 +13216,7 @@
*(*func)= (Item_sum*) item;
(*func)++;
}
- else
+ else
{
/* Check if this is something that is part of this group by */
ORDER *group_tmp;
@@ -13336,7 +13337,7 @@
{
if (create_myisam_from_heap(thd, table, &tmp_table_param,
error, 0))
- return 1;
+ return 1;
}
}
}
@@ -13404,7 +13405,7 @@
}
else if (join->select_lex == join->unit->fake_select_lex)
{
- /*
+ /*
here we assume that the query will return at least two rows, so we
show "filesort" in EXPLAIN. Of course, sometimes we'll be wrong
and no filesort will be actually done, but executing all selects in
@@ -13473,7 +13474,7 @@
{
JOIN_TAB *tab=join->join_tab+i;
TABLE *table=tab->table;
- char buff[512];
+ char buff[512];
char buff1[512], buff2[512], buff3[512];
char keylen_str_buf[64];
String extra(buff, sizeof(buff),cs);
@@ -13532,7 +13533,7 @@
{
if (tmp1.length())
tmp1.append(',');
- tmp1.append(table->key_info[j].name,
+ tmp1.append(table->key_info[j].name,
strlen(table->key_info[j].name),
system_charset_info);
}
@@ -13551,7 +13552,7 @@
item_list.push_back(new Item_string(key_info->name,
strlen(key_info->name),
system_charset_info));
- length= longlong2str(tab->ref.key_length, keylen_str_buf, 10) -
+ length= longlong2str(tab->ref.key_length, keylen_str_buf, 10) -
keylen_str_buf;
item_list.push_back(new Item_string(keylen_str_buf, length,
system_charset_info));
@@ -13570,9 +13571,9 @@
register uint length;
item_list.push_back(new Item_string(key_info->name,
strlen(key_info->name),cs));
- length= longlong2str(key_info->key_length, keylen_str_buf, 10) -
+ length= longlong2str(key_info->key_length, keylen_str_buf, 10) -
keylen_str_buf;
- item_list.push_back(new Item_string(keylen_str_buf,
+ item_list.push_back(new Item_string(keylen_str_buf,
length,
system_charset_info));
item_list.push_back(item_null);
@@ -13602,12 +13603,12 @@
if (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT &&
!((QUICK_ROR_INTERSECT_SELECT*)tab->select->quick)->need_to_fetch_row)
key_read=1;
-
+
if (tab->info)
item_list.push_back(new Item_string(tab->info,strlen(tab->info),cs));
else
{
- if (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION ||
+ if (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION ||
quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT ||
quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE)
{
@@ -13661,7 +13662,7 @@
}
if (distinct & test_all_bits(used_tables,thd->used_tables))
extra.append("; Distinct");
-
+
/* Skip initial "; "*/
const char *str= extra.ptr();
uint32 len= extra.length();
@@ -13702,7 +13703,7 @@
// drop UNCACHEABLE_EXPLAIN, because it is for internal usage only
uint8 uncacheable= (sl->uncacheable & ~UNCACHEABLE_EXPLAIN);
sl->type= (((&thd->lex->select_lex)==sl)?
- ((thd->lex->all_selects_list != sl) ?
+ ((thd->lex->all_selects_list != sl) ?
primary_key_name : "SIMPLE"):
((sl == first)?
((sl->linkage == DERIVED_TABLE_TYPE) ?
--- 1.42/libmysql/libmysql.def 2005-07-26 10:22:18 +02:00
+++ 1.43/libmysql/libmysql.def 2005-07-28 17:11:23 +02:00
@@ -148,7 +148,6 @@
mysql_embedded
mysql_server_init
mysql_server_end
- get_defaults_files
mysql_set_character_set
mysql_get_character_set_info
get_defaults_options
| Thread |
|---|
| • bk commit into 5.0 tree (schwenke:1.1913) | axel | 28 Jul |