Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
be27811f
Commit
be27811f
authored
Nov 26, 2003
by
igor@rurik.mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
Post-merge after itroducing Item_equal
parents
d8603604
3938ac54
Changes
14
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
1397 additions
and
113 deletions
+1397
-113
sql/item.cc
sql/item.cc
+46
-1
sql/item.h
sql/item.h
+25
-1
sql/item_cmpfunc.cc
sql/item_cmpfunc.cc
+231
-2
sql/item_cmpfunc.h
sql/item_cmpfunc.h
+63
-0
sql/item_func.cc
sql/item_func.cc
+34
-0
sql/item_func.h
sql/item_func.h
+6
-2
sql/item_row.cc
sql/item_row.cc
+12
-0
sql/item_row.h
sql/item_row.h
+1
-0
sql/item_strfunc.h
sql/item_strfunc.h
+8
-0
sql/opt_range.cc
sql/opt_range.cc
+150
-75
sql/opt_sum.cc
sql/opt_sum.cc
+15
-0
sql/sql_list.h
sql/sql_list.h
+29
-6
sql/sql_select.cc
sql/sql_select.cc
+775
-26
sql/sql_select.h
sql/sql_select.h
+2
-0
No files found.
sql/item.cc
View file @
be27811f
...
...
@@ -299,7 +299,8 @@ bool DTCollation::aggregate(DTCollation &dt)
return
0
;
}
Item_field
::
Item_field
(
Field
*
f
)
:
Item_ident
(
NullS
,
f
->
table_name
,
f
->
field_name
)
Item_field
::
Item_field
(
Field
*
f
)
:
Item_ident
(
NullS
,
f
->
table_name
,
f
->
field_name
),
item_equal
(
0
)
{
set_field
(
f
);
collation
.
set
(
DERIVATION_IMPLICIT
);
...
...
@@ -313,6 +314,7 @@ Item_field::Item_field(THD *thd, Item_field &item)
result_field
(
item
.
result_field
)
{
collation
.
set
(
DERIVATION_IMPLICIT
);
item_equal
=
item
.
item_equal
;
}
void
Item_field
::
set_field
(
Field
*
field_par
)
...
...
@@ -969,6 +971,49 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
return
0
;
}
Item_equal
*
Item_field
::
find_item_equal
(
COND_EQUAL
*
cond_equal
)
{
Item_equal
*
item
=
0
;
while
(
cond_equal
)
{
List_iterator_fast
<
Item_equal
>
li
(
cond_equal
->
current_level
);
while
((
item
=
li
++
))
{
if
(
item
->
contains
(
field
))
return
item
;
}
cond_equal
=
cond_equal
->
parent_level
;
}
return
item
;
}
Item
*
Item_field
::
equal_fields_propagator
(
byte
*
arg
)
{
COND_EQUAL
*
cond_equal
=
(
COND_EQUAL
*
)
arg
;
item_equal
=
find_item_equal
(
cond_equal
);
Item
*
item
=
0
;
if
(
item_equal
)
item
=
item_equal
->
get_const
();
if
(
item
)
item
->
fixed
=
0
;
else
item
=
this
;
return
item
;
}
bool
Item_field
::
replace_equal_field_processor
(
byte
*
arg
)
{
if
(
item_equal
)
{
Item_field
*
subst
=
item_equal
->
get_first
();
if
(
subst
&&
!
field
->
eq
(
subst
->
field
))
{
field
=
subst
->
field
;
return
0
;
}
}
return
0
;
}
void
Item
::
init_make_field
(
Send_field
*
tmp_field
,
enum
enum_field_types
field_type
)
...
...
sql/item.h
View file @
be27811f
...
...
@@ -83,6 +83,7 @@ public:
};
typedef
bool
(
Item
::*
Item_processor
)(
byte
*
arg
);
typedef
Item
*
(
Item
::*
Item_calculator
)
(
byte
*
arg
);
class
Item
{
Item
(
const
Item
&
);
/* Prevent use of these */
...
...
@@ -201,8 +202,15 @@ public:
return
(
this
->*
processor
)(
arg
);
}
virtual
Item
*
traverse
(
Item_calculator
calculator
,
byte
*
arg
)
{
return
(
this
->*
calculator
)(
arg
);
}
virtual
bool
remove_dependence_processor
(
byte
*
arg
)
{
return
0
;
}
virtual
bool
remove_fixed
(
byte
*
arg
)
{
fixed
=
0
;
return
0
;
}
virtual
Item
*
equal_fields_propagator
(
byte
*
arg
)
{
return
this
;
}
virtual
bool
replace_equal_field_processor
(
byte
*
arg
)
{
return
0
;
}
virtual
Item
*
this_item
()
{
return
this
;
}
/* For SPs mostly. */
virtual
Item
*
this_const_item
()
const
{
return
const_cast
<
Item
*>
(
this
);
}
/* For SPs mostly. */
...
...
@@ -334,17 +342,21 @@ public:
bool
remove_dependence_processor
(
byte
*
arg
);
};
class
Item_equal
;
class
COND_EQUAL
;
class
Item_field
:
public
Item_ident
{
void
set_field
(
Field
*
field
);
public:
Field
*
field
,
*
result_field
;
Item_equal
*
item_equal
;
// Item_field() {}
Item_field
(
const
char
*
db_par
,
const
char
*
table_name_par
,
const
char
*
field_name_par
)
:
Item_ident
(
db_par
,
table_name_par
,
field_name_par
),
field
(
0
),
result_field
(
0
)
:
Item_ident
(
db_par
,
table_name_par
,
field_name_par
),
field
(
0
),
result_field
(
0
),
item_equal
(
0
)
{
collation
.
set
(
DERIVATION_IMPLICIT
);
}
// Constructor need to process subselect with temporary tables (see Item)
Item_field
(
THD
*
thd
,
Item_field
&
item
);
...
...
@@ -378,6 +390,9 @@ public:
bool
get_time
(
TIME
*
ltime
);
bool
is_null
()
{
return
field
->
is_null
();
}
Item
*
get_tmp_table_item
(
THD
*
thd
);
Item_equal
*
find_item_equal
(
COND_EQUAL
*
cond_equal
);
Item
*
equal_fields_propagator
(
byte
*
arg
);
bool
replace_equal_field_processor
(
byte
*
arg
);
friend
class
Item_default_value
;
friend
class
Item_insert_value
;
};
...
...
@@ -920,6 +935,15 @@ public:
return
arg
->
walk
(
processor
,
args
)
||
(
this
->*
processor
)(
args
);
}
Item
*
traverse
(
Item_calculator
calculator
,
byte
*
args
)
{
Item
*
new_item
=
arg
->
traverse
(
calculator
,
args
);
if
(
!
new_item
)
return
0
;
arg
=
new_item
;
return
(
this
->*
calculator
)(
args
);
}
};
class
Item_insert_value
:
public
Item_field
...
...
sql/item_cmpfunc.cc
View file @
be27811f
...
...
@@ -225,7 +225,7 @@ void Item_bool_func2::fix_length_and_dec()
}
// Make a special case of compare with fields to get nicer DATE comparisons
if
(
args
[
0
]
->
type
()
==
FIELD_ITEM
)
if
(
args
[
0
]
->
type
()
==
FIELD_ITEM
&&
!
args
[
0
]
->
const_item
()
)
{
Field
*
field
=
((
Item_field
*
)
args
[
0
])
->
field
;
if
(
field
->
store_for_compare
())
...
...
@@ -238,7 +238,7 @@ void Item_bool_func2::fix_length_and_dec()
}
}
}
if
(
args
[
1
]
->
type
()
==
FIELD_ITEM
)
if
(
args
[
1
]
->
type
()
==
FIELD_ITEM
&&
!
args
[
1
]
->
const_item
()
)
{
Field
*
field
=
((
Item_field
*
)
args
[
1
])
->
field
;
if
(
field
->
store_for_compare
())
...
...
@@ -1712,6 +1712,21 @@ bool Item_cond::walk(Item_processor processor, byte *arg)
return
Item_func
::
walk
(
processor
,
arg
);
}
Item
*
Item_cond
::
traverse
(
Item_calculator
calculator
,
byte
*
arg
)
{
List_iterator
<
Item
>
li
(
list
);
Item
*
item
;
while
((
item
=
li
++
))
{
Item
*
new_item
=
item
->
traverse
(
calculator
,
arg
);
if
(
!
new_item
)
return
0
;
if
(
new_item
!=
item
)
li
.
replace
(
new_item
);
}
return
Item_func
::
traverse
(
calculator
,
arg
);
}
void
Item_cond
::
split_sum_func
(
Item
**
ref_pointer_array
,
List
<
Item
>
&
fields
)
{
List_iterator
<
Item
>
li
(
list
);
...
...
@@ -2499,3 +2514,217 @@ Item *Item_cond_or::neg_transformer() /* NOT(a OR b OR ...) -> */
neg_arguments
();
return
new
Item_cond_and
(
list
);
}
Item_equal
::
Item_equal
(
Item_field
*
f1
,
Item_field
*
f2
)
:
Item_bool_func
(),
const_item
(
0
),
eval_item
(
0
),
cond_false
(
0
)
{
const_item_cache
=
0
;
fields
.
push_back
(
f1
);
fields
.
push_back
(
f2
);
}
Item_equal
::
Item_equal
(
Item
*
c
,
Item_field
*
f
)
:
Item_bool_func
(),
eval_item
(
0
),
cond_false
(
0
)
{
const_item_cache
=
0
;
fields
.
push_back
(
f
);
const_item
=
c
;
}
Item_equal
::
Item_equal
(
Item_equal
*
item_equal
)
:
Item_bool_func
(),
eval_item
(
0
),
cond_false
(
0
)
{
const_item_cache
=
0
;
List_iterator_fast
<
Item_field
>
li
(
item_equal
->
fields
);
Item_field
*
item
;
while
((
item
=
li
++
))
{
fields
.
push_back
(
item
);
}
const_item
=
item_equal
->
const_item
;
cond_false
=
item_equal
->
cond_false
;
}
void
Item_equal
::
add
(
Item
*
c
)
{
if
(
cond_false
)
return
;
if
(
!
const_item
)
{
const_item
=
c
;
return
;
}
Item_func_eq
*
func
=
new
Item_func_eq
(
c
,
const_item
);
func
->
set_cmp_func
();
cond_false
=
!
(
func
->
val_int
());
}
void
Item_equal
::
add
(
Item_field
*
f
)
{
fields
.
push_back
(
f
);
}
bool
Item_equal
::
contains
(
Field
*
field
)
{
List_iterator_fast
<
Item_field
>
it
(
fields
);
Item_field
*
item
;
while
((
item
=
it
++
))
{
if
(
field
->
eq
(
item
->
field
))
return
1
;
}
return
0
;
}
void
Item_equal
::
merge
(
Item_equal
*
item
)
{
fields
.
concat
(
&
item
->
fields
);
Item
*
c
=
item
->
const_item
;
if
(
c
)
{
/*
The flag cond_false will be set to 1 after this, if
the multiple equality already contains a constant and its
value is not equal to the value of c.
*/
add
(
const_item
);
}
cond_false
|=
item
->
cond_false
;
}
void
Item_equal
::
sort
(
void
*
table_join_idx
)
{
bool
swap
;
void
**
idx
=
(
void
**
)
table_join_idx
;
List_iterator
<
Item_field
>
it
(
fields
);
do
{
Item_field
*
item1
=
it
++
;
Item_field
**
ref1
=
it
.
ref
();
Item_field
*
item2
;
Item_field
**
ref2
;
if
(
!
item1
)
break
;
swap
=
FALSE
;
while
((
item2
=
it
++
))
{
ref2
=
it
.
ref
();
if
(
idx
[
item1
->
field
->
table
->
tablenr
]
>
idx
[
item2
->
field
->
table
->
tablenr
])
{
Item_field
*
item
=
*
ref1
;
*
ref1
=
*
ref2
;
*
ref2
=
item
;
swap
=
TRUE
;
}
else
{
item1
=
item2
;
ref1
=
ref2
;
}
}
it
.
rewind
();
}
while
(
swap
);
}
bool
Item_equal
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
{
List_iterator_fast
<
Item_field
>
li
(
fields
);
Item
*
item
;
not_null_tables_cache
=
used_tables_cache
=
0
;
const_item_cache
=
0
;
while
((
item
=
li
++
))
{
table_map
tmp_table_map
;
used_tables_cache
|=
item
->
used_tables
();
tmp_table_map
=
item
->
not_null_tables
();
not_null_tables_cache
|=
tmp_table_map
;
if
(
item
->
maybe_null
)
maybe_null
=
1
;
}
fix_length_and_dec
();
fixed
=
1
;
return
0
;
}
void
Item_equal
::
update_used_tables
()
{
List_iterator_fast
<
Item_field
>
li
(
fields
);
Item
*
item
;
not_null_tables_cache
=
used_tables_cache
=
0
;
while
((
item
=
li
++
))
{
item
->
update_used_tables
();
used_tables_cache
|=
item
->
used_tables
();
const_item_cache
&=
item
->
const_item
();
}
}
longlong
Item_equal
::
val_int
()
{
if
(
cond_false
)
return
0
;
List_iterator_fast
<
Item_field
>
it
(
fields
);
Item
*
item
=
const_item
?
const_item
:
it
++
;
if
((
null_value
=
item
->
null_value
))
return
0
;
eval_item
->
store_value
(
item
);
while
((
item
=
it
++
))
{
if
((
null_value
=
item
->
null_value
)
||
eval_item
->
cmp
(
item
))
return
0
;
}
return
1
;
}
void
Item_equal
::
fix_length_and_dec
()
{
Item
*
item
=
const_item
?
const_item
:
get_first
();
eval_item
=
cmp_item
::
get_comparator
(
item
);
if
(
item
->
result_type
()
==
STRING_RESULT
)
eval_item
->
cmp_charset
=
cmp_collation
.
collation
;
}
bool
Item_equal
::
walk
(
Item_processor
processor
,
byte
*
arg
)
{
List_iterator_fast
<
Item_field
>
it
(
fields
);
Item
*
item
;
while
((
item
=
it
++
))
if
(
item
->
walk
(
processor
,
arg
))
return
1
;
return
Item_func
::
walk
(
processor
,
arg
);
}
Item
*
Item_equal
::
traverse
(
Item_calculator
calculator
,
byte
*
arg
)
{
List_iterator
<
Item_field
>
it
(
fields
);
Item
*
item
;
while
((
item
=
it
++
))
{
Item
*
new_item
=
item
->
traverse
(
calculator
,
arg
);
if
(
!
new_item
)
return
0
;
if
(
new_item
!=
item
)
it
.
replace
((
Item_field
*
)
new_item
);
}
return
Item_func
::
traverse
(
calculator
,
arg
);
}
void
Item_equal
::
print
(
String
*
str
)
{
str
->
append
(
func_name
());
str
->
append
(
'('
);
List_iterator_fast
<
Item_field
>
it
(
fields
);
Item
*
item
;
if
((
item
=
it
++
))
item
->
print
(
str
);
while
((
item
=
it
++
))
{
str
->
append
(
','
);
str
->
append
(
' '
);
item
->
print
(
str
);
}
str
->
append
(
')'
);
}
sql/item_cmpfunc.h
View file @
be27811f
...
...
@@ -908,13 +908,76 @@ public:
void
top_level_item
()
{
abort_on_null
=
1
;
}
void
copy_andor_arguments
(
THD
*
thd
,
Item_cond
*
item
);
bool
walk
(
Item_processor
processor
,
byte
*
arg
);
Item
*
traverse
(
Item_calculator
calculator
,
byte
*
arg
);
void
neg_arguments
();
};
class
Item_equal
:
public
Item_bool_func
{
List
<
Item_field
>
fields
;
/* list of equal field items */
Item
*
const_item
;
/* optional constant item equal to fields items */
cmp_item
*
eval_item
;
bool
cond_false
;
DTCollation
cmp_collation
;
public:
inline
Item_equal
()
:
Item_bool_func
(),
const_item
(
0
),
eval_item
(
0
),
cond_false
(
0
)
{
const_item_cache
=
0
;}
Item_equal
(
Item_field
*
f1
,
Item_field
*
f2
);
Item_equal
(
Item
*
c
,
Item_field
*
f
);
Item_equal
(
Item_equal
*
item_equal
);
inline
Item
*
get_const
()
{
return
const_item
;
}
void
add
(
Item
*
c
);
void
add
(
Item_field
*
f
);
bool
is_false
()
{
return
cond_false
;
}
bool
contains
(
Field
*
field
);
Item_field
*
get_first
()
{
return
fields
.
head
();
}
void
merge
(
Item_equal
*
item
);
enum
Functype
functype
()
const
{
return
MULT_EQUAL_FUNC
;
}
longlong
val_int
();
const
char
*
func_name
()
const
{
return
"multiple equal"
;
}
optimize_type
select_optimize
()
const
{
return
OPTIMIZE_EQUAL
;
}
void
sort
(
void
*
table_join_idx
);
friend
class
Item_equal_iterator
;
void
fix_length_and_dec
();
bool
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
);
void
update_used_tables
();
bool
walk
(
Item_processor
processor
,
byte
*
arg
);
Item
*
traverse
(
Item_calculator
calculator
,
byte
*
arg
);
void
print
(
String
*
str
);
};
class
COND_EQUAL
{
public:
COND_EQUAL
*
parent_level
;
List
<
Item_equal
>
current_level
;
COND_EQUAL
()
{
parent_level
=
0
;
}
};
class
Item_equal_iterator
:
List_iterator_fast
<
Item_field
>
{
public:
inline
Item_equal_iterator
(
Item_equal
&
item_equal
)
:
List_iterator_fast
<
Item_field
>
(
item_equal
.
fields
)
{}
inline
Item_field
*
operator
++
(
int
)
{
Item_field
*
item
=
(
*
(
List_iterator_fast
<
Item_field
>
*
)
this
)
++
;
return
item
;
}
inline
void
rewind
(
void
)
{
List_iterator_fast
<
Item_field
>::
rewind
();
}
};
class
Item_cond_and
:
public
Item_cond
{
public:
COND_EQUAL
cond_equal
;
Item_cond_and
()
:
Item_cond
()
{}
Item_cond_and
(
Item
*
i1
,
Item
*
i2
)
:
Item_cond
(
i1
,
i2
)
{}
Item_cond_and
(
THD
*
thd
,
Item_cond_and
&
item
)
:
Item_cond
(
thd
,
item
)
{}
...
...
sql/item_func.cc
View file @
be27811f
...
...
@@ -242,6 +242,40 @@ bool Item_func::walk (Item_processor processor, byte *argument)
return
(
this
->*
processor
)(
argument
);
}
Item
*
Item_func
::
traverse
(
Item_calculator
calculator
,
byte
*
argument
)
{
if
(
arg_count
)
{
Item
**
arg
,
**
arg_end
;
for
(
arg
=
args
,
arg_end
=
args
+
arg_count
;
arg
!=
arg_end
;
arg
++
)
{
Item
*
new_item
=
(
*
arg
)
->
traverse
(
calculator
,
argument
);
if
(
!
new_item
)
return
0
;
*
arg
=
new_item
;
}
}
return
(
this
->*
calculator
)(
argument
);
}
Item
*
Item_func
::
equal_fields_propagator
(
byte
*
argument
)
{
if
(
arg_count
)
{
Item
**
arg
,
**
arg_end
;
for
(
arg
=
args
,
arg_end
=
args
+
arg_count
;
arg
!=
arg_end
;
arg
++
)
{
if
(
!
(
*
arg
)
->
fixed
)
{
fix_fields
(
current_thd
,
0
,
0
);
break
;
}
}
}
return
this
;
}
void
Item_func
::
split_sum_func
(
Item
**
ref_pointer_array
,
List
<
Item
>
&
fields
)
{
Item
**
arg
,
**
arg_end
;
...
...
sql/item_func.h
View file @
be27811f
...
...
@@ -40,7 +40,8 @@ public:
enum
Functype
{
UNKNOWN_FUNC
,
EQ_FUNC
,
EQUAL_FUNC
,
NE_FUNC
,
LT_FUNC
,
LE_FUNC
,
GE_FUNC
,
GT_FUNC
,
FT_FUNC
,
LIKE_FUNC
,
NOTLIKE_FUNC
,
ISNULL_FUNC
,
ISNOTNULL_FUNC
,
COND_AND_FUNC
,
COND_OR_FUNC
,
COND_XOR_FUNC
,
BETWEEN
,
IN_FUNC
,
COND_AND_FUNC
,
COND_OR_FUNC
,
COND_XOR_FUNC
,
BETWEEN
,
IN_FUNC
,
MULT_EQUAL_FUNC
,
INTERVAL_FUNC
,
ISNOTNULLTEST_FUNC
,
SP_EQUALS_FUNC
,
SP_DISJOINT_FUNC
,
SP_INTERSECTS_FUNC
,
SP_TOUCHES_FUNC
,
SP_CROSSES_FUNC
,
SP_WITHIN_FUNC
,
...
...
@@ -49,7 +50,8 @@ public:
SP_POINTN
,
SP_GEOMETRYN
,
SP_INTERIORRINGN
,
NOT_FUNC
,
NOT_ALL_FUNC
,
GUSERVAR_FUNC
};
enum
optimize_type
{
OPTIMIZE_NONE
,
OPTIMIZE_KEY
,
OPTIMIZE_OP
,
OPTIMIZE_NULL
};
enum
optimize_type
{
OPTIMIZE_NONE
,
OPTIMIZE_KEY
,
OPTIMIZE_OP
,
OPTIMIZE_NULL
,
OPTIMIZE_EQUAL
};
enum
Type
type
()
const
{
return
FUNC_ITEM
;
}
virtual
enum
Functype
functype
()
const
{
return
UNKNOWN_FUNC
;
}
Item_func
(
void
)
:
...
...
@@ -146,6 +148,8 @@ public:
bool
agg_arg_collations_for_comparison
(
DTCollation
&
c
,
Item
**
items
,
uint
nitems
);
bool
walk
(
Item_processor
processor
,
byte
*
arg
);
Item
*
traverse
(
Item_calculator
calculator
,
byte
*
arg
);
Item
*
equal_fields_propagator
(
byte
*
arg
);
};
...
...
sql/item_row.cc
View file @
be27811f
...
...
@@ -140,6 +140,18 @@ bool Item_row::walk(Item_processor processor, byte *arg)
return
(
this
->*
processor
)(
arg
);
}
Item
*
Item_row
::
traverse
(
Item_calculator
calculator
,
byte
*
arg
)
{
for
(
uint
i
=
0
;
i
<
arg_count
;
i
++
)
{
Item
*
new_item
=
items
[
i
]
->
traverse
(
calculator
,
arg
);
if
(
!
new_item
)
return
0
;
items
[
i
]
=
new_item
;
}
return
(
this
->*
calculator
)(
arg
);
}
void
Item_row
::
bring_value
()
{
for
(
uint
i
=
0
;
i
<
arg_count
;
i
++
)
...
...
sql/item_row.h
View file @
be27811f
...
...
@@ -71,6 +71,7 @@ public:
void
print
(
String
*
str
);
bool
walk
(
Item_processor
processor
,
byte
*
arg
);
Item
*
traverse
(
Item_calculator
calculator
,
byte
*
arg
);
uint
cols
()
{
return
arg_count
;
}
Item
*
el
(
uint
i
)
{
return
items
[
i
];
}
...
...
sql/item_strfunc.h
View file @
be27811f
...
...
@@ -427,6 +427,14 @@ public:
return
item
->
walk
(
processor
,
arg
)
||
Item_str_func
::
walk
(
processor
,
arg
);
}
Item
*
traverse
(
Item_calculator
calculator
,
byte
*
arg
)
{
Item
*
new_item
=
item
->
traverse
(
calculator
,
arg
);
if
(
!
new_item
)
return
0
;
item
=
new_item
;
return
Item_str_func
::
traverse
(
calculator
,
arg
);
}
void
print
(
String
*
str
);
};
...
...
sql/opt_range.cc
View file @
be27811f
...
...
@@ -1252,11 +1252,75 @@ static int get_quick_select_params(SEL_TREE *tree, PARAM& param,
return
result
;
}
static
SEL_TREE
*
get_func_mm_tree
(
PARAM
*
param
,
Item_func
*
cond_func
,
Field
*
field
,
Item
*
value
,
Item_result
cmp_type
)
{
SEL_TREE
*
tree
=
0
;
DBUG_ENTER
(
"get_func_mm_tree"
);
if
(
cond_func
->
functype
()
==
Item_func
::
NE_FUNC
)
{
tree
=
get_mm_parts
(
param
,
field
,
Item_func
::
LT_FUNC
,
value
,
cmp_type
);
if
(
tree
)
{
tree
=
tree_or
(
param
,
tree
,
get_mm_parts
(
param
,
field
,
Item_func
::
GT_FUNC
,
value
,
cmp_type
));
}
}
else
if
(
cond_func
->
functype
()
==
Item_func
::
BETWEEN
)
{
tree
=
get_mm_parts
(
param
,
field
,
Item_func
::
GE_FUNC
,
cond_func
->
arguments
()[
1
],
cmp_type
);
if
(
tree
)
{
tree
=
tree_and
(
param
,
tree
,
get_mm_parts
(
param
,
field
,
Item_func
::
LE_FUNC
,
cond_func
->
arguments
()[
2
],
cmp_type
));
}
}
else
if
(
cond_func
->
functype
()
==
Item_func
::
IN_FUNC
)
{
Item_func_in
*
func
=
(
Item_func_in
*
)
cond_func
;
tree
=
get_mm_parts
(
param
,
field
,
Item_func
::
EQ_FUNC
,
func
->
arguments
()[
1
],
cmp_type
);
if
(
tree
)
{
for
(
uint
i
=
2
;
i
<
func
->
argument_count
()
;
i
++
)
{
tree
=
tree_or
(
param
,
tree
,
get_mm_parts
(
param
,
field
,
Item_func
::
EQ_FUNC
,
func
->
arguments
()[
i
],
cmp_type
));
}
}
}
else
{
Item_func
::
Functype
func_type
=
(
value
!=
cond_func
->
arguments
()[
0
])
?
cond_func
->
functype
()
:
((
Item_bool_func2
*
)
cond_func
)
->
rev_functype
();
tree
=
get_mm_parts
(
param
,
field
,
func_type
,
value
,
cmp_type
);
}
DBUG_RETURN
(
tree
);
}
/* make a select tree of all keys in condition */
static
SEL_TREE
*
get_mm_tree
(
PARAM
*
param
,
COND
*
cond
)
{
SEL_TREE
*
tree
=
0
;
SEL_TREE
*
ftree
=
0
;
Item_field
*
field_item
=
0
;
Item
*
value
;
DBUG_ENTER
(
"get_mm_tree"
);
if
(
cond
->
type
()
==
Item
::
COND_ITEM
)
...
...
@@ -1304,9 +1368,12 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond)
DBUG_RETURN
(
new
SEL_TREE
(
SEL_TREE
::
IMPOSSIBLE
));
}
table_map
ref_tables
=
cond
->
used_tables
();
table_map
ref_tables
=
0
;
table_map
param_comp
=
~
(
param
->
prev_tables
|
param
->
read_tables
|
param
->
current_table
);
if
(
cond
->
type
()
!=
Item
::
FUNC_ITEM
)
{
// Should be a field
ref_tables
=
cond
->
used_tables
();
if
((
ref_tables
&
param
->
current_table
)
||
(
ref_tables
&
~
(
param
->
prev_tables
|
param
->
read_tables
)))
DBUG_RETURN
(
0
);
...
...
@@ -1318,76 +1385,98 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond)
DBUG_RETURN
(
0
);
// Can't be calculated
if
(
cond_func
->
functype
()
==
Item_func
::
BETWEEN
)
{
{
if
(
cond_func
->
arguments
()[
0
]
->
type
()
==
Item
::
FIELD_ITEM
)
{
Field
*
field
=
((
Item_field
*
)
(
cond_func
->
arguments
()[
0
]))
->
field
;
Item_result
cmp_type
=
field
->
cmp_type
();
DBUG_RETURN
(
tree_and
(
param
,
get_mm_parts
(
param
,
field
,
Item_func
::
GE_FUNC
,
cond_func
->
arguments
()[
1
],
cmp_type
),
get_mm_parts
(
param
,
field
,
Item_func
::
LE_FUNC
,
cond_func
->
arguments
()[
2
],
cmp_type
)));
field_item
=
(
Item_field
*
)
(
cond_func
->
arguments
()[
0
]);
value
=
NULL
;
}
DBUG_RETURN
(
0
);
else
DBUG_RETURN
(
0
);
}
if
(
cond_func
->
functype
()
==
Item_func
::
IN_FUNC
)
{
// COND OR
else
if
(
cond_func
->
functype
()
==
Item_func
::
IN_FUNC
)
{
Item_func_in
*
func
=
(
Item_func_in
*
)
cond_func
;
if
(
func
->
key_item
()
->
type
()
==
Item
::
FIELD_ITEM
)
{
Field
*
field
=
((
Item_field
*
)
(
func
->
key_item
()))
->
field
;
Item_result
cmp_type
=
field
->
cmp_type
();
tree
=
get_mm_parts
(
param
,
field
,
Item_func
::
EQ_FUNC
,
func
->
arguments
()[
1
],
cmp_type
);
if
(
!
tree
)
DBUG_RETURN
(
tree
);
// Not key field
for
(
uint
i
=
2
;
i
<
func
->
argument_count
();
i
++
)
field_item
=
(
Item_field
*
)
(
func
->
key_item
());
value
=
NULL
;
}
else
DBUG_RETURN
(
0
);
}
else
if
(
cond_func
->
functype
()
==
Item_func
::
MULT_EQUAL_FUNC
)
{
Item_equal
*
item_equal
=
(
Item_equal
*
)
cond
;
Item_equal_iterator
it
(
*
item_equal
);
if
(
!
(
value
=
item_equal
->
get_const
()))
value
=
it
++
;
while
(
value
)
{
ref_tables
=
value
->
used_tables
();
Item_equal_iterator
li
(
*
item_equal
);
while
((
field_item
=
li
++
))
{
SEL_TREE
*
new_tree
=
get_mm_parts
(
param
,
field
,
Item_func
::
EQ_FUNC
,
func
->
arguments
()[
i
],
cmp_type
);
tree
=
tree_or
(
param
,
tree
,
new_tree
);
if
(
field_item
!=
value
)
{
Field
*
field
=
field_item
->
field
;
Item_result
cmp_type
=
field
->
cmp_type
();
if
(
!
((
ref_tables
|
field
->
table
->
map
)
&
param_comp
))
{
tree
=
get_mm_parts
(
param
,
field
,
Item_func
::
EQ_FUNC
,
value
,
cmp_type
);
ftree
=
!
ftree
?
tree
:
tree_and
(
param
,
ftree
,
tree
);
}
}
}
DBUG_RETURN
(
tree
);
}
DBUG_RETURN
(
0
);
// Can't optimize this IN
}
if
(
ref_tables
&
~
(
param
->
prev_tables
|
param
->
read_tables
|
param
->
current_table
))
DBUG_RETURN
(
0
);
// Can't be calculated yet
if
(
!
(
ref_tables
&
param
->
current_table
))
DBUG_RETURN
(
new
SEL_TREE
(
SEL_TREE
::
MAYBE
));
// This may be false or true
/* check field op const */
/* btw, ft_func's arguments()[0] isn't FIELD_ITEM. SerG*/
if
(
cond_func
->
arguments
()[
0
]
->
type
()
==
Item
::
FIELD_ITEM
)
{
tree
=
get_mm_parts
(
param
,
((
Item_field
*
)
(
cond_func
->
arguments
()[
0
]))
->
field
,
cond_func
->
functype
(),
cond_func
->
arg_count
>
1
?
cond_func
->
arguments
()[
1
]
:
0
,
((
Item_field
*
)
(
cond_func
->
arguments
()[
0
]))
->
field
->
cmp_type
());
}
/* check const op field */
if
(
!
tree
&&
cond_func
->
have_rev_func
()
&&
cond_func
->
arguments
()[
1
]
->
type
()
==
Item
::
FIELD_ITEM
)
{
DBUG_RETURN
(
get_mm_parts
(
param
,
((
Item_field
*
)
(
cond_func
->
arguments
()[
1
]))
->
field
,
((
Item_bool_func2
*
)
cond_func
)
->
rev_functype
(),
cond_func
->
arguments
()[
0
],
((
Item_field
*
)
(
cond_func
->
arguments
()[
1
]))
->
field
->
cmp_type
()
));
if
(
item_equal
->
get_const
())
break
;
value
=
it
++
;
}
DBUG_RETURN
(
ftree
);
}
DBUG_RETURN
(
tree
);
else
if
(
cond_func
->
arguments
()[
0
]
->
type
()
==
Item
::
FIELD_ITEM
)
{
field_item
=
(
Item_field
*
)
(
cond_func
->
arguments
()[
0
]);
value
=
cond_func
->
arg_count
>
1
?
cond_func
->
arguments
()[
1
]
:
0
;
}
else
if
(
cond_func
->
have_rev_func
()
&&
cond_func
->
arguments
()[
1
]
->
type
()
==
Item
::
FIELD_ITEM
)
{
field_item
=
(
Item_field
*
)
(
cond_func
->
arguments
()[
1
]);
value
=
cond_func
->
arguments
()[
0
];
}
else
DBUG_RETURN
(
0
);
for
(
uint
i
=
0
;
i
<
cond_func
->
arg_count
;
i
++
)
{
Item
*
arg
=
cond_func
->
arguments
()[
i
];
if
(
arg
!=
field_item
)
ref_tables
|=
arg
->
used_tables
();
}
Field
*
field
=
field_item
->
field
;
Item_result
cmp_type
=
field
->
cmp_type
();
if
(
!
((
ref_tables
|
field
->
table
->
map
)
&
param_comp
))
ftree
=
get_func_mm_tree
(
param
,
cond_func
,
field
,
value
,
cmp_type
);
Item_equal
*
item_equal
=
field_item
->
item_equal
;
if
(
item_equal
)
{
Item_equal_iterator
it
(
*
item_equal
);
Item_field
*
item
;
while
((
item
=
it
++
))
{
Field
*
f
=
item
->
field
;
if
(
field
->
eq
(
f
))
continue
;
if
(
!
((
ref_tables
|
f
->
table
->
map
)
&
param_comp
))
{
tree
=
get_func_mm_tree
(
param
,
cond_func
,
f
,
value
,
cmp_type
);
ftree
=
!
ftree
?
tree
:
tree_and
(
param
,
ftree
,
tree
);
}
}
}
DBUG_RETURN
(
ftree
);
}
...
...
@@ -1395,17 +1484,10 @@ static SEL_TREE *
get_mm_parts
(
PARAM
*
param
,
Field
*
field
,
Item_func
::
Functype
type
,
Item
*
value
,
Item_result
cmp_type
)
{
bool
ne_func
=
FALSE
;
DBUG_ENTER
(
"get_mm_parts"
);
if
(
field
->
table
!=
param
->
table
)
DBUG_RETURN
(
0
);
if
(
type
==
Item_func
::
NE_FUNC
)
{
ne_func
=
TRUE
;
type
=
Item_func
::
LT_FUNC
;
}
KEY_PART
*
key_part
=
param
->
key_parts
;
KEY_PART
*
end
=
param
->
key_parts_end
;
SEL_TREE
*
tree
=
0
;
...
...
@@ -1442,13 +1524,6 @@ get_mm_parts(PARAM *param, Field *field, Item_func::Functype type,
}
}
if
(
ne_func
)
{
SEL_TREE
*
tree2
=
get_mm_parts
(
param
,
field
,
Item_func
::
GT_FUNC
,
value
,
cmp_type
);
if
(
tree2
)
tree
=
tree_or
(
param
,
tree
,
tree2
);
}
DBUG_RETURN
(
tree
);
}
...
...
sql/opt_sum.cc
View file @
be27811f
...
...
@@ -352,6 +352,18 @@ static bool simple_pred(Item_func *func_item, Item **args, bool *inv_order)
Item
*
item
;
*
inv_order
=
0
;
switch
(
func_item
->
argument_count
())
{
case
0
:
/* MULT_EQUAL_FUNC */
{
Item_equal
*
item_equal
=
(
Item_equal
*
)
func_item
;
Item_equal_iterator
it
(
*
item_equal
);
args
[
0
]
=
it
++
;
if
(
it
++
)
return
0
;
if
(
!
(
args
[
1
]
=
item_equal
->
get_const
()))
return
0
;
}
break
;
case
1
:
/* field IS NULL */
item
=
func_item
->
arguments
()[
0
];
...
...
@@ -492,6 +504,9 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo,
case
Item_func
:
:
BETWEEN
:
between
=
1
;
break
;
case
Item_func
:
:
MULT_EQUAL_FUNC
:
eq_type
=
1
;
break
;
default:
return
0
;
// Can't optimize function
}
...
...
sql/sql_list.h
View file @
be27811f
...
...
@@ -121,10 +121,12 @@ public:
void
remove
(
list_node
**
prev
)
{
list_node
*
node
=
(
*
prev
)
->
next
;
delete
*
prev
;
*
prev
=
node
;
if
(
!--
elements
)
last
=
&
first
;
else
if
(
last
==
&
(
*
prev
)
->
next
)
last
=
prev
;
delete
*
prev
;
*
prev
=
node
;
}
inline
void
*
pop
(
void
)
{
...
...
@@ -137,9 +139,27 @@ public:
}
inline
void
concat
(
base_list
*
list
)
{
*
last
=
list
->
first
;
last
=
list
->
last
;
elements
+=
list
->
elements
;
if
(
!
list
->
is_empty
())
{
*
last
=
list
->
first
;
last
=
list
->
last
;
elements
+=
list
->
elements
;
}
}
inline
void
disjoin
(
base_list
*
list
)
{
list_node
**
prev
=
&
first
;
list_node
*
node
=
first
;
list_node
*
list_first
=
list
->
first
;
elements
=
0
;
while
(
node
&&
node
!=
list_first
)
{
prev
=
&
node
->
next
;
node
=
node
->
next
;
elements
++
;
}
*
prev
=
*
last
;
last
=
prev
;
}
inline
list_node
*
last_node
()
{
return
*
last
;
}
inline
list_node
*
first_node
()
{
return
first
;}
...
...
@@ -251,6 +271,8 @@ public:
inline
T
*
head
()
{
return
(
T
*
)
base_list
::
head
();
}
inline
T
**
head_ref
()
{
return
(
T
**
)
base_list
::
head_ref
();
}
inline
T
*
pop
()
{
return
(
T
*
)
base_list
::
pop
();
}
inline
void
concat
(
List
<
T
>
*
list
)
{
return
base_list
::
concat
(
list
);
}
inline
void
disjoin
(
List
<
T
>
*
list
)
{
return
base_list
::
disjoin
(
list
);
}
void
delete_elements
(
void
)
{
list_node
*
element
,
*
next
;
...
...
@@ -261,7 +283,6 @@ public:
}
empty
();
}
inline
void
concat
(
List
<
T
>
*
list
)
{
base_list
::
concat
(
list
);
}
};
...
...
@@ -272,6 +293,8 @@ public:
inline
T
*
operator
++
(
int
)
{
return
(
T
*
)
base_list_iterator
::
next
();
}
inline
T
*
replace
(
T
*
a
)
{
return
(
T
*
)
base_list_iterator
::
replace
(
a
);
}
inline
T
*
replace
(
List
<
T
>
&
a
)
{
return
(
T
*
)
base_list_iterator
::
replace
(
a
);
}
inline
void
rewind
(
void
)
{
base_list_iterator
::
rewind
();
}
inline
void
remove
()
{
base_list_iterator
::
remove
();
}
inline
void
after
(
T
*
a
)
{
base_list_iterator
::
after
(
a
);
}
inline
T
**
ref
(
void
)
{
return
(
T
**
)
base_list_iterator
::
ref
();
}
};
...
...
sql/sql_select.cc
View file @
be27811f
This diff is collapsed.
Click to expand it.
sql/sql_select.h
View file @
be27811f
...
...
@@ -184,6 +184,7 @@ class JOIN :public Sql_alloc
ORDER
*
order
,
*
group_list
,
*
proc_param
;
//hold parameters of mysql_select
COND
*
conds
;
// ---"---
Item
*
conds_history
;
// store WHERE for explain
COND_EQUAL
*
cond_equal
;
TABLE_LIST
*
tables_list
;
//hold 'tables' parameter of mysql_selec
SQL_SELECT
*
select
;
//created in optimisation phase
Item
**
ref_pointer_array
;
//used pointer reference for this select
...
...
@@ -243,6 +244,7 @@ class JOIN :public Sql_alloc
ref_pointer_array_size
=
0
;
zero_result_cause
=
0
;
optimized
=
0
;
cond_equal
=
0
;
fields_list
=
fields
;
bzero
((
char
*
)
&
keyuse
,
sizeof
(
keyuse
));
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment