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
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
8035ce40
Commit
8035ce40
authored
Mar 17, 2004
by
bell@sanja.is.com.ua
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
DBUG_ASSERT(fixed == 0) added to fix_fields()
parent
b8c065c5
Changes
18
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
292 additions
and
95 deletions
+292
-95
sql/item.cc
sql/item.cc
+41
-9
sql/item.h
sql/item.h
+23
-8
sql/item_cmpfunc.cc
sql/item_cmpfunc.cc
+104
-32
sql/item_cmpfunc.h
sql/item_cmpfunc.h
+17
-12
sql/item_func.cc
sql/item_func.cc
+4
-1
sql/item_func.h
sql/item_func.h
+2
-0
sql/item_row.cc
sql/item_row.cc
+2
-0
sql/item_strfunc.h
sql/item_strfunc.h
+2
-0
sql/item_subselect.cc
sql/item_subselect.cc
+6
-5
sql/item_sum.cc
sql/item_sum.cc
+5
-0
sql/item_sum.h
sql/item_sum.h
+1
-0
sql/item_uniq.h
sql/item_uniq.h
+1
-0
sql/sql_base.cc
sql/sql_base.cc
+6
-3
sql/sql_derived.cc
sql/sql_derived.cc
+5
-1
sql/sql_select.cc
sql/sql_select.cc
+31
-20
sql/sql_select.h
sql/sql_select.h
+1
-1
sql/sql_union.cc
sql/sql_union.cc
+7
-2
tests/client_test.c
tests/client_test.c
+34
-1
No files found.
sql/item.cc
View file @
8035ce40
...
@@ -103,21 +103,33 @@ void Item::print_item_w_name(String *str)
...
@@ -103,21 +103,33 @@ void Item::print_item_w_name(String *str)
Item_ident
::
Item_ident
(
const
char
*
db_name_par
,
const
char
*
table_name_par
,
Item_ident
::
Item_ident
(
const
char
*
db_name_par
,
const
char
*
table_name_par
,
const
char
*
field_name_par
)
const
char
*
field_name_par
)
:
db_name
(
db_name_par
),
table_name
(
table_name_par
),
field_name
(
field_name_par
),
:
changed_during_fix_field
(
0
),
db_name
(
db_name_par
),
table_name
(
table_name_par
),
field_name
(
field_name_par
),
depended_from
(
0
)
depended_from
(
0
)
{
{
name
=
(
char
*
)
field_name_par
;
name
=
(
char
*
)
field_name_par
;
}
}
// Constructor used by Item_field & Item_ref (see Item comment)
// Constructor used by Item_field & Item_ref (see Item comment)
Item_ident
::
Item_ident
(
THD
*
thd
,
Item_ident
*
item
)
:
Item_ident
::
Item_ident
(
THD
*
thd
,
Item_ident
*
item
)
Item
(
thd
,
item
),
:
Item
(
thd
,
item
),
db_name
(
item
->
db_name
),
changed_during_fix_field
(
0
),
table_name
(
item
->
table_name
),
db_name
(
item
->
db_name
),
field_name
(
item
->
field_name
),
table_name
(
item
->
table_name
),
depended_from
(
item
->
depended_from
)
field_name
(
item
->
field_name
),
depended_from
(
item
->
depended_from
)
{}
{}
void
Item_ident
::
cleanup
()
{
Item
::
cleanup
();
if
(
changed_during_fix_field
)
{
*
changed_during_fix_field
=
this
;
changed_during_fix_field
=
0
;
}
}
bool
Item_ident
::
remove_dependence_processor
(
byte
*
arg
)
bool
Item_ident
::
remove_dependence_processor
(
byte
*
arg
)
{
{
DBUG_ENTER
(
"Item_ident::remove_dependence_processor"
);
DBUG_ENTER
(
"Item_ident::remove_dependence_processor"
);
...
@@ -289,11 +301,14 @@ bool DTCollation::aggregate(DTCollation &dt)
...
@@ -289,11 +301,14 @@ bool DTCollation::aggregate(DTCollation &dt)
return
0
;
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
)
#ifndef DBUG_OFF
,
double_fix
(
0
)
#endif
{
{
set_field
(
f
);
set_field
(
f
);
collation
.
set
(
DERIVATION_IMPLICIT
);
collation
.
set
(
DERIVATION_IMPLICIT
);
fixed
=
1
;
// This item is not needed in fix_fields
}
}
// Constructor need to process subselect with temporary tables (see Item)
// Constructor need to process subselect with temporary tables (see Item)
...
@@ -301,6 +316,9 @@ Item_field::Item_field(THD *thd, Item_field *item)
...
@@ -301,6 +316,9 @@ Item_field::Item_field(THD *thd, Item_field *item)
:
Item_ident
(
thd
,
item
),
:
Item_ident
(
thd
,
item
),
field
(
item
->
field
),
field
(
item
->
field
),
result_field
(
item
->
result_field
)
result_field
(
item
->
result_field
)
#ifndef DBUG_OFF
,
double_fix
(
0
)
#endif
{
{
collation
.
set
(
DERIVATION_IMPLICIT
);
collation
.
set
(
DERIVATION_IMPLICIT
);
}
}
...
@@ -786,6 +804,9 @@ bool Item::fix_fields(THD *thd,
...
@@ -786,6 +804,9 @@ bool Item::fix_fields(THD *thd,
struct
st_table_list
*
list
,
struct
st_table_list
*
list
,
Item
**
ref
)
Item
**
ref
)
{
{
// We do not check fields which are fixed during construction
DBUG_ASSERT
(
fixed
==
0
||
type
()
==
INT_ITEM
||
type
()
==
CACHE_ITEM
);
fixed
=
1
;
fixed
=
1
;
return
0
;
return
0
;
}
}
...
@@ -847,6 +868,7 @@ static void mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current,
...
@@ -847,6 +868,7 @@ static void mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current,
bool
Item_field
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
bool
Item_field
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
{
{
DBUG_ASSERT
(
fixed
==
0
||
double_fix
==
0
);
if
(
!
field
)
// If field is not checked
if
(
!
field
)
// If field is not checked
{
{
TABLE_LIST
*
where
=
0
;
TABLE_LIST
*
where
=
0
;
...
@@ -952,6 +974,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
...
@@ -952,6 +974,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
ref
,
ref
,
(
char
*
)
table_name
,
(
char
*
)
table_name
,
(
char
*
)
field_name
);
(
char
*
)
field_name
);
register_item_tree_changing
(
ref
);
if
(
!
rf
)
if
(
!
rf
)
return
1
;
return
1
;
/*
/*
...
@@ -1005,6 +1028,11 @@ void Item_field::cleanup()
...
@@ -1005,6 +1028,11 @@ void Item_field::cleanup()
{
{
DBUG_ENTER
(
"Item_field::cleanup"
);
DBUG_ENTER
(
"Item_field::cleanup"
);
Item_ident
::
cleanup
();
Item_ident
::
cleanup
();
/*
Even if this object was created by direct link to field in setup_wild()
it will be linked correctly next tyme by name of field and table alias.
I.e. we can drop 'field'.
*/
field
=
result_field
=
0
;
field
=
result_field
=
0
;
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
...
@@ -1480,6 +1508,7 @@ bool Item_field::send(Protocol *protocol, String *buffer)
...
@@ -1480,6 +1508,7 @@ bool Item_field::send(Protocol *protocol, String *buffer)
bool
Item_ref
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
reference
)
bool
Item_ref
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
reference
)
{
{
DBUG_ASSERT
(
fixed
==
0
);
uint
counter
;
uint
counter
;
if
(
!
ref
)
if
(
!
ref
)
{
{
...
@@ -1585,6 +1614,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
...
@@ -1585,6 +1614,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
Item_field
*
fld
;
Item_field
*
fld
;
if
(
!
((
*
reference
)
=
fld
=
new
Item_field
(
tmp
)))
if
(
!
((
*
reference
)
=
fld
=
new
Item_field
(
tmp
)))
return
1
;
return
1
;
register_item_tree_changing
(
reference
);
mark_as_dependent
(
thd
,
last
,
thd
->
lex
->
current_select
,
fld
);
mark_as_dependent
(
thd
,
last
,
thd
->
lex
->
current_select
,
fld
);
return
0
;
return
0
;
}
}
...
@@ -1696,6 +1726,7 @@ bool Item_default_value::fix_fields(THD *thd,
...
@@ -1696,6 +1726,7 @@ bool Item_default_value::fix_fields(THD *thd,
struct
st_table_list
*
table_list
,
struct
st_table_list
*
table_list
,
Item
**
items
)
Item
**
items
)
{
{
DBUG_ASSERT
(
fixed
==
0
);
if
(
!
arg
)
if
(
!
arg
)
return
0
;
return
0
;
if
(
arg
->
fix_fields
(
thd
,
table_list
,
&
arg
))
if
(
arg
->
fix_fields
(
thd
,
table_list
,
&
arg
))
...
@@ -1744,6 +1775,7 @@ bool Item_insert_value::fix_fields(THD *thd,
...
@@ -1744,6 +1775,7 @@ bool Item_insert_value::fix_fields(THD *thd,
struct
st_table_list
*
table_list
,
struct
st_table_list
*
table_list
,
Item
**
items
)
Item
**
items
)
{
{
DBUG_ASSERT
(
fixed
==
0
);
if
(
arg
->
fix_fields
(
thd
,
table_list
,
&
arg
))
if
(
arg
->
fix_fields
(
thd
,
table_list
,
&
arg
))
return
1
;
return
1
;
...
...
sql/item.h
View file @
8035ce40
...
@@ -233,7 +233,7 @@ class Item {
...
@@ -233,7 +233,7 @@ class Item {
Field
*
tmp_table_field_from_field_type
(
TABLE
*
table
);
Field
*
tmp_table_field_from_field_type
(
TABLE
*
table
);
/* Used in sql_select.cc:eliminate_not_funcs() */
/* Used in sql_select.cc:eliminate_not_funcs() */
virtual
Item
*
neg_transformer
()
{
return
NULL
;
}
virtual
Item
*
neg_transformer
(
THD
*
thd
)
{
return
NULL
;
}
void
delete_self
()
void
delete_self
()
{
{
cleanup
();
cleanup
();
...
@@ -245,6 +245,7 @@ class Item {
...
@@ -245,6 +245,7 @@ class Item {
class
st_select_lex
;
class
st_select_lex
;
class
Item_ident
:
public
Item
class
Item_ident
:
public
Item
{
{
Item
**
changed_during_fix_field
;
public:
public:
const
char
*
db_name
;
const
char
*
db_name
;
const
char
*
table_name
;
const
char
*
table_name
;
...
@@ -254,7 +255,9 @@ class Item_ident :public Item
...
@@ -254,7 +255,9 @@ class Item_ident :public Item
const
char
*
field_name_par
);
const
char
*
field_name_par
);
Item_ident
(
THD
*
thd
,
Item_ident
*
item
);
Item_ident
(
THD
*
thd
,
Item_ident
*
item
);
const
char
*
full_name
()
const
;
const
char
*
full_name
()
const
;
void
cleanup
();
void
register_item_tree_changing
(
Item
**
ref
)
{
changed_during_fix_field
=
ref
;
}
bool
remove_dependence_processor
(
byte
*
arg
);
bool
remove_dependence_processor
(
byte
*
arg
);
};
};
...
@@ -264,11 +267,17 @@ class Item_field :public Item_ident
...
@@ -264,11 +267,17 @@ class Item_field :public Item_ident
void
set_field
(
Field
*
field
);
void
set_field
(
Field
*
field
);
public:
public:
Field
*
field
,
*
result_field
;
Field
*
field
,
*
result_field
;
// Item_field() {}
#ifndef DBUG_OFF
bool
double_fix
;
#endif
Item_field
(
const
char
*
db_par
,
const
char
*
table_name_par
,
Item_field
(
const
char
*
db_par
,
const
char
*
table_name_par
,
const
char
*
field_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
)
#ifndef DBUG_OFF
,
double_fix
(
0
)
#endif
{
collation
.
set
(
DERIVATION_IMPLICIT
);
}
{
collation
.
set
(
DERIVATION_IMPLICIT
);
}
// Constructor need to process subselect with temporary tables (see Item)
// Constructor need to process subselect with temporary tables (see Item)
Item_field
(
THD
*
thd
,
Item_field
*
item
);
Item_field
(
THD
*
thd
,
Item_field
*
item
);
...
@@ -324,6 +333,7 @@ class Item_null :public Item
...
@@ -324,6 +333,7 @@ class Item_null :public Item
enum_field_types
field_type
()
const
{
return
MYSQL_TYPE_NULL
;
}
enum_field_types
field_type
()
const
{
return
MYSQL_TYPE_NULL
;
}
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
list
,
Item
**
item
)
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
list
,
Item
**
item
)
{
{
DBUG_ASSERT
(
fixed
==
0
);
bool
res
=
Item
::
fix_fields
(
thd
,
list
,
item
);
bool
res
=
Item
::
fix_fields
(
thd
,
list
,
item
);
max_length
=
0
;
max_length
=
0
;
return
res
;
return
res
;
...
@@ -413,7 +423,8 @@ class Item_int :public Item
...
@@ -413,7 +423,8 @@ class Item_int :public Item
int
save_in_field
(
Field
*
field
,
bool
no_conversions
);
int
save_in_field
(
Field
*
field
,
bool
no_conversions
);
bool
basic_const_item
()
const
{
return
1
;
}
bool
basic_const_item
()
const
{
return
1
;
}
Item
*
new_item
()
{
return
new
Item_int
(
name
,
value
,
max_length
);
}
Item
*
new_item
()
{
return
new
Item_int
(
name
,
value
,
max_length
);
}
void
cleanup
()
{
fixed
=
1
;
}
// to prevent drop fixed flag
// to prevent drop fixed flag (no need parent cleanup call)
void
cleanup
()
{
fixed
=
1
;
}
void
print
(
String
*
str
);
void
print
(
String
*
str
);
};
};
...
@@ -422,14 +433,17 @@ class Item_uint :public Item_int
...
@@ -422,14 +433,17 @@ class Item_uint :public Item_int
{
{
public:
public:
Item_uint
(
const
char
*
str_arg
,
uint
length
)
:
Item_uint
(
const
char
*
str_arg
,
uint
length
)
:
Item_int
(
str_arg
,
(
longlong
)
strtoull
(
str_arg
,(
char
**
)
0
,
10
),
length
)
{}
Item_int
(
str_arg
,
(
longlong
)
strtoull
(
str_arg
,(
char
**
)
0
,
10
),
length
)
Item_uint
(
uint32
i
)
:
Item_int
((
longlong
)
i
,
10
)
{}
{
fixed
=
0
;
}
Item_uint
(
uint32
i
)
:
Item_int
((
longlong
)
i
,
10
)
{
fixed
=
0
;
}
double
val
()
{
return
ulonglong2double
((
ulonglong
)
value
);
}
double
val
()
{
return
ulonglong2double
((
ulonglong
)
value
);
}
String
*
val_str
(
String
*
);
String
*
val_str
(
String
*
);
Item
*
new_item
()
{
return
new
Item_uint
(
name
,
max_length
);
}
Item
*
new_item
()
{
return
new
Item_uint
(
name
,
max_length
);
}
int
save_in_field
(
Field
*
field
,
bool
no_conversions
);
int
save_in_field
(
Field
*
field
,
bool
no_conversions
);
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
list
,
Item
**
item
)
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
list
,
Item
**
item
)
{
{
DBUG_ASSERT
(
fixed
==
0
);
bool
res
=
Item
::
fix_fields
(
thd
,
list
,
item
);
bool
res
=
Item
::
fix_fields
(
thd
,
list
,
item
);
unsigned_flag
=
1
;
unsigned_flag
=
1
;
return
res
;
return
res
;
...
@@ -903,7 +917,8 @@ class Item_cache: public Item
...
@@ -903,7 +917,8 @@ class Item_cache: public Item
static
Item_cache
*
get_cache
(
Item_result
type
);
static
Item_cache
*
get_cache
(
Item_result
type
);
table_map
used_tables
()
const
{
return
used_table_map
;
}
table_map
used_tables
()
const
{
return
used_table_map
;
}
virtual
void
keep_array
()
{}
virtual
void
keep_array
()
{}
void
cleanup
()
{
fixed
=
1
;
}
// to prevent drop fixed flag
// to prevent drop fixed flag (no need parent cleanup call)
void
cleanup
()
{
fixed
=
1
;
}
void
print
(
String
*
str
);
void
print
(
String
*
str
);
};
};
...
...
sql/item_cmpfunc.cc
View file @
8035ce40
...
@@ -502,7 +502,6 @@ bool Item_in_optimizer::fix_left(THD *thd,
...
@@ -502,7 +502,6 @@ bool Item_in_optimizer::fix_left(THD *thd,
not_null_tables_cache
=
args
[
0
]
->
not_null_tables
();
not_null_tables_cache
=
args
[
0
]
->
not_null_tables
();
with_sum_func
=
args
[
0
]
->
with_sum_func
;
with_sum_func
=
args
[
0
]
->
with_sum_func
;
const_item_cache
=
args
[
0
]
->
const_item
();
const_item_cache
=
args
[
0
]
->
const_item
();
fixed
=
1
;
return
0
;
return
0
;
}
}
...
@@ -510,7 +509,8 @@ bool Item_in_optimizer::fix_left(THD *thd,
...
@@ -510,7 +509,8 @@ bool Item_in_optimizer::fix_left(THD *thd,
bool
Item_in_optimizer
::
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tables
,
bool
Item_in_optimizer
::
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tables
,
Item
**
ref
)
Item
**
ref
)
{
{
if
(
fix_left
(
thd
,
tables
,
ref
))
DBUG_ASSERT
(
fixed
==
0
);
if
(
!
args
[
0
]
->
fixed
&&
fix_left
(
thd
,
tables
,
ref
))
return
1
;
return
1
;
if
(
args
[
0
]
->
maybe_null
)
if
(
args
[
0
]
->
maybe_null
)
maybe_null
=
1
;
maybe_null
=
1
;
...
@@ -529,6 +529,7 @@ bool Item_in_optimizer::fix_fields(THD *thd, struct st_table_list *tables,
...
@@ -529,6 +529,7 @@ bool Item_in_optimizer::fix_fields(THD *thd, struct st_table_list *tables,
used_tables_cache
|=
args
[
1
]
->
used_tables
();
used_tables_cache
|=
args
[
1
]
->
used_tables
();
not_null_tables_cache
|=
args
[
1
]
->
not_null_tables
();
not_null_tables_cache
|=
args
[
1
]
->
not_null_tables
();
const_item_cache
&=
args
[
1
]
->
const_item
();
const_item_cache
&=
args
[
1
]
->
const_item
();
fixed
=
1
;
return
0
;
return
0
;
}
}
...
@@ -1755,6 +1756,7 @@ void Item_cond::copy_andor_arguments(THD *thd, Item_cond *item)
...
@@ -1755,6 +1756,7 @@ void Item_cond::copy_andor_arguments(THD *thd, Item_cond *item)
bool
bool
Item_cond
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
Item_cond
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
{
{
DBUG_ASSERT
(
fixed
==
0
);
List_iterator
<
Item
>
li
(
list
);
List_iterator
<
Item
>
li
(
list
);
Item
*
item
;
Item
*
item
;
#ifndef EMBEDDED_LIBRARY
#ifndef EMBEDDED_LIBRARY
...
@@ -1878,14 +1880,27 @@ void Item_cond::print(String *str)
...
@@ -1878,14 +1880,27 @@ void Item_cond::print(String *str)
}
}
void
Item_cond
::
neg_arguments
()
void
Item_cond
::
neg_arguments
(
THD
*
thd
)
{
{
List_iterator
<
Item
>
li
(
list
);
List_iterator
<
Item
>
li
(
list
);
Item
*
item
;
Item
*
item
;
while
((
item
=
li
++
))
/* Apply not transformation to the arguments */
while
((
item
=
li
++
))
/* Apply not transformation to the arguments */
{
{
Item
*
new_item
=
item
->
neg_transformer
();
Item
*
new_item
=
item
->
neg_transformer
(
thd
);
VOID
(
li
.
replace
(
new_item
?
new_item
:
new
Item_func_not
(
item
)));
if
(
!
new_item
)
{
new_item
=
new
Item_func_not
(
item
);
/*
We can use 0 as tables list because Item_func_not do not use it
on fix_fields and its arguments are already fixed.
We do not check results of fix_fields, because there are not way
to return error in this functions interface, thd->net.report_error
will be checked on upper level call.
*/
new_item
->
fix_fields
(
thd
,
0
,
&
new_item
);
}
VOID
(
li
.
replace
(
new_item
));
}
}
}
}
...
@@ -2097,6 +2112,7 @@ Item_func::optimize_type Item_func_like::select_optimize() const
...
@@ -2097,6 +2112,7 @@ Item_func::optimize_type Item_func_like::select_optimize() const
bool
Item_func_like
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tlist
,
Item
**
ref
)
bool
Item_func_like
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tlist
,
Item
**
ref
)
{
{
DBUG_ASSERT
(
fixed
==
0
);
if
(
Item_bool_func2
::
fix_fields
(
thd
,
tlist
,
ref
))
if
(
Item_bool_func2
::
fix_fields
(
thd
,
tlist
,
ref
))
return
1
;
return
1
;
...
@@ -2150,6 +2166,7 @@ bool Item_func_like::fix_fields(THD *thd, TABLE_LIST *tlist, Item ** ref)
...
@@ -2150,6 +2166,7 @@ bool Item_func_like::fix_fields(THD *thd, TABLE_LIST *tlist, Item ** ref)
bool
bool
Item_func_regex
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
Item_func_regex
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
{
{
DBUG_ASSERT
(
fixed
==
0
);
if
(
args
[
0
]
->
fix_fields
(
thd
,
tables
,
args
)
||
args
[
0
]
->
check_cols
(
1
)
||
if
(
args
[
0
]
->
fix_fields
(
thd
,
tables
,
args
)
||
args
[
0
]
->
check_cols
(
1
)
||
args
[
1
]
->
fix_fields
(
thd
,
tables
,
args
+
1
)
||
args
[
1
]
->
check_cols
(
1
))
args
[
1
]
->
fix_fields
(
thd
,
tables
,
args
+
1
)
||
args
[
1
]
->
check_cols
(
1
))
return
1
;
/* purecov: inspected */
return
1
;
/* purecov: inspected */
...
@@ -2518,6 +2535,7 @@ longlong Item_cond_xor::val_int()
...
@@ -2518,6 +2535,7 @@ longlong Item_cond_xor::val_int()
SYNPOSIS
SYNPOSIS
neg_transformer()
neg_transformer()
thd thread handler
DESCRIPTION
DESCRIPTION
Transform the item using next rules:
Transform the item using next rules:
...
@@ -2541,62 +2559,116 @@ longlong Item_cond_xor::val_int()
...
@@ -2541,62 +2559,116 @@ longlong Item_cond_xor::val_int()
NULL if we cannot apply NOT transformation (see Item::neg_transformer()).
NULL if we cannot apply NOT transformation (see Item::neg_transformer()).
*/
*/
Item
*
Item_func_not
::
neg_transformer
(
)
/* NOT(x) -> x */
Item
*
Item_func_not
::
neg_transformer
(
THD
*
thd
)
/* NOT(x) -> x */
{
{
/
* We should apply negation elimination to the argument of the NOT function */
/
/ We should apply negation elimination to the argument of the NOT function
return
eliminate_not_funcs
(
args
[
0
]);
return
eliminate_not_funcs
(
thd
,
args
[
0
]);
}
}
Item
*
Item_func_eq
::
neg_transformer
()
/* a = b -> a != b */
Item
*
Item_bool_rowready_func2
::
neg_transformer
(
THD
*
thd
)
{
{
return
new
Item_func_ne
(
args
[
0
],
args
[
1
]);
Item
*
item
=
negated_item
();
if
(
item
)
{
/*
We can use 0 as tables list because Item_func* family do not use it
on fix_fields and its arguments are already fixed.
We do not check results of fix_fields, because there are not way
to return error in this functions interface, thd->net.report_error
will be checked on upper level call.
*/
item
->
fix_fields
(
thd
,
0
,
&
item
);
}
return
item
;
}
}
Item
*
Item_func_ne
::
neg_transformer
()
/* a != b -> a = b */
/* a IS NULL -> a IS NOT NULL */
Item
*
Item_func_isnull
::
neg_transformer
(
THD
*
thd
)
{
{
return
new
Item_func_eq
(
args
[
0
],
args
[
1
]);
Item
*
item
=
new
Item_func_isnotnull
(
args
[
0
]);
// see comment before fix_fields in Item_bool_rowready_func2::neg_transformer
if
(
item
)
item
->
fix_fields
(
thd
,
0
,
&
item
);
return
item
;
}
}
Item
*
Item_func_lt
::
neg_transformer
()
/* a < b -> a >= b */
/* a IS NOT NULL -> a IS NULL */
Item
*
Item_func_isnotnull
::
neg_transformer
(
THD
*
thd
)
{
{
return
new
Item_func_ge
(
args
[
0
],
args
[
1
]);
Item
*
item
=
new
Item_func_isnull
(
args
[
0
]);
// see comment before fix_fields in Item_bool_rowready_func2::neg_transformer
if
(
item
)
item
->
fix_fields
(
thd
,
0
,
&
item
);
return
item
;
}
}
Item
*
Item_func_ge
::
neg_transformer
()
/* a >= b -> a < b */
Item
*
Item_cond_and
::
neg_transformer
(
THD
*
thd
)
/* NOT(a AND b AND ...) -> */
/* NOT a OR NOT b OR ... */
{
{
return
new
Item_func_lt
(
args
[
0
],
args
[
1
]);
neg_arguments
(
thd
);
Item
*
item
=
new
Item_cond_or
(
list
);
// see comment before fix_fields in Item_bool_rowready_func2::neg_transformer
if
(
item
)
item
->
fix_fields
(
thd
,
0
,
&
item
);
return
item
;
}
}
Item
*
Item_func_gt
::
neg_transformer
()
/* a > b -> a <= b */
Item
*
Item_cond_or
::
neg_transformer
(
THD
*
thd
)
/* NOT(a OR b OR ...) -> */
/* NOT a AND NOT b AND ... */
{
{
return
new
Item_func_le
(
args
[
0
],
args
[
1
]);
neg_arguments
(
thd
);
Item
*
item
=
new
Item_cond_and
(
list
);
// see comment before fix_fields in Item_bool_rowready_func2::neg_transformer
if
(
item
)
item
->
fix_fields
(
thd
,
0
,
&
item
);
return
item
;
}
}
Item
*
Item_func_le
::
neg_transformer
()
/* a <= b -> a > b */
Item
*
Item_func_eq
::
negated_item
()
/* a = b -> a != b */
{
{
return
new
Item_func_
gt
(
args
[
0
],
args
[
1
]);
return
new
Item_func_
ne
(
args
[
0
],
args
[
1
]);
}
}
Item
*
Item_func_isnull
::
neg_transformer
()
/* a IS NULL -> a IS NOT NULL */
Item
*
Item_func_ne
::
negated_item
()
/* a != b -> a = b */
{
{
return
new
Item_func_
isnotnull
(
args
[
0
]);
return
new
Item_func_
eq
(
args
[
0
],
args
[
1
]);
}
}
Item
*
Item_func_isnotnull
::
neg_transformer
()
/* a IS NOT NULL -> a IS NULL */
Item
*
Item_func_lt
::
negated_item
()
/* a < b -> a >= b */
{
{
return
new
Item_func_
isnull
(
args
[
0
]);
return
new
Item_func_
ge
(
args
[
0
],
args
[
1
]);
}
}
Item
*
Item_cond_and
::
neg_transformer
()
/* NOT(a AND b AND ...) -> */
/* NOT a OR NOT b OR ...
*/
Item
*
Item_func_ge
::
negated_item
()
/* a >= b -> a < b
*/
{
{
neg_arguments
();
return
new
Item_func_lt
(
args
[
0
],
args
[
1
]);
return
new
Item_cond_or
(
list
);
}
}
Item
*
Item_cond_or
::
neg_transformer
()
/* NOT(a OR b OR ...) -> */
/* NOT a AND NOT b AND ...
*/
Item
*
Item_func_gt
::
negated_item
()
/* a > b -> a <= b
*/
{
{
neg_arguments
();
return
new
Item_func_le
(
args
[
0
],
args
[
1
]);
return
new
Item_cond_and
(
list
);
}
Item
*
Item_func_le
::
negated_item
()
/* a <= b -> a > b */
{
return
new
Item_func_gt
(
args
[
0
],
args
[
1
]);
}
// just fake method, should never be called
Item
*
Item_bool_rowready_func2
::
negated_item
()
{
DBUG_ASSERT
(
0
);
return
0
;
}
}
sql/item_cmpfunc.h
View file @
8035ce40
...
@@ -218,6 +218,8 @@ class Item_bool_rowready_func2 :public Item_bool_func2
...
@@ -218,6 +218,8 @@ class Item_bool_rowready_func2 :public Item_bool_func2
tmp_arg
[
1
]
=
orig_b
;
tmp_arg
[
1
]
=
orig_b
;
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
Item
*
neg_transformer
(
THD
*
thd
);
virtual
Item
*
negated_item
();
};
};
class
Item_func_not
:
public
Item_bool_func
class
Item_func_not
:
public
Item_bool_func
...
@@ -227,7 +229,7 @@ class Item_func_not :public Item_bool_func
...
@@ -227,7 +229,7 @@ class Item_func_not :public Item_bool_func
longlong
val_int
();
longlong
val_int
();
enum
Functype
functype
()
const
{
return
NOT_FUNC
;
}
enum
Functype
functype
()
const
{
return
NOT_FUNC
;
}
const
char
*
func_name
()
const
{
return
"not"
;
}
const
char
*
func_name
()
const
{
return
"not"
;
}
Item
*
neg_transformer
();
Item
*
neg_transformer
(
THD
*
thd
);
};
};
class
Item_func_not_all
:
public
Item_func_not
class
Item_func_not_all
:
public
Item_func_not
...
@@ -254,7 +256,7 @@ class Item_func_eq :public Item_bool_rowready_func2
...
@@ -254,7 +256,7 @@ class Item_func_eq :public Item_bool_rowready_func2
enum
Functype
rev_functype
()
const
{
return
EQ_FUNC
;
}
enum
Functype
rev_functype
()
const
{
return
EQ_FUNC
;
}
cond_result
eq_cmp_result
()
const
{
return
COND_TRUE
;
}
cond_result
eq_cmp_result
()
const
{
return
COND_TRUE
;
}
const
char
*
func_name
()
const
{
return
"="
;
}
const
char
*
func_name
()
const
{
return
"="
;
}
Item
*
neg
_transformer
();
Item
*
neg
ated_item
();
};
};
class
Item_func_equal
:
public
Item_bool_rowready_func2
class
Item_func_equal
:
public
Item_bool_rowready_func2
...
@@ -267,6 +269,7 @@ class Item_func_equal :public Item_bool_rowready_func2
...
@@ -267,6 +269,7 @@ class Item_func_equal :public Item_bool_rowready_func2
enum
Functype
rev_functype
()
const
{
return
EQUAL_FUNC
;
}
enum
Functype
rev_functype
()
const
{
return
EQUAL_FUNC
;
}
cond_result
eq_cmp_result
()
const
{
return
COND_TRUE
;
}
cond_result
eq_cmp_result
()
const
{
return
COND_TRUE
;
}
const
char
*
func_name
()
const
{
return
"<=>"
;
}
const
char
*
func_name
()
const
{
return
"<=>"
;
}
Item
*
neg_transformer
(
THD
*
thd
)
{
return
0
;
}
};
};
...
@@ -279,7 +282,7 @@ class Item_func_ge :public Item_bool_rowready_func2
...
@@ -279,7 +282,7 @@ class Item_func_ge :public Item_bool_rowready_func2
enum
Functype
rev_functype
()
const
{
return
LE_FUNC
;
}
enum
Functype
rev_functype
()
const
{
return
LE_FUNC
;
}
cond_result
eq_cmp_result
()
const
{
return
COND_TRUE
;
}
cond_result
eq_cmp_result
()
const
{
return
COND_TRUE
;
}
const
char
*
func_name
()
const
{
return
">="
;
}
const
char
*
func_name
()
const
{
return
">="
;
}
Item
*
neg
_transformer
();
Item
*
neg
ated_item
();
};
};
...
@@ -292,7 +295,7 @@ class Item_func_gt :public Item_bool_rowready_func2
...
@@ -292,7 +295,7 @@ class Item_func_gt :public Item_bool_rowready_func2
enum
Functype
rev_functype
()
const
{
return
LT_FUNC
;
}
enum
Functype
rev_functype
()
const
{
return
LT_FUNC
;
}
cond_result
eq_cmp_result
()
const
{
return
COND_FALSE
;
}
cond_result
eq_cmp_result
()
const
{
return
COND_FALSE
;
}
const
char
*
func_name
()
const
{
return
">"
;
}
const
char
*
func_name
()
const
{
return
">"
;
}
Item
*
neg
_transformer
();
Item
*
neg
ated_item
();
};
};
...
@@ -305,7 +308,7 @@ class Item_func_le :public Item_bool_rowready_func2
...
@@ -305,7 +308,7 @@ class Item_func_le :public Item_bool_rowready_func2
enum
Functype
rev_functype
()
const
{
return
GE_FUNC
;
}
enum
Functype
rev_functype
()
const
{
return
GE_FUNC
;
}
cond_result
eq_cmp_result
()
const
{
return
COND_TRUE
;
}
cond_result
eq_cmp_result
()
const
{
return
COND_TRUE
;
}
const
char
*
func_name
()
const
{
return
"<="
;
}
const
char
*
func_name
()
const
{
return
"<="
;
}
Item
*
neg
_transformer
();
Item
*
neg
ated_item
();
};
};
...
@@ -318,7 +321,7 @@ class Item_func_lt :public Item_bool_rowready_func2
...
@@ -318,7 +321,7 @@ class Item_func_lt :public Item_bool_rowready_func2
enum
Functype
rev_functype
()
const
{
return
GT_FUNC
;
}
enum
Functype
rev_functype
()
const
{
return
GT_FUNC
;
}
cond_result
eq_cmp_result
()
const
{
return
COND_FALSE
;
}
cond_result
eq_cmp_result
()
const
{
return
COND_FALSE
;
}
const
char
*
func_name
()
const
{
return
"<"
;
}
const
char
*
func_name
()
const
{
return
"<"
;
}
Item
*
neg
_transformer
();
Item
*
neg
ated_item
();
};
};
...
@@ -331,7 +334,7 @@ class Item_func_ne :public Item_bool_rowready_func2
...
@@ -331,7 +334,7 @@ class Item_func_ne :public Item_bool_rowready_func2
cond_result
eq_cmp_result
()
const
{
return
COND_FALSE
;
}
cond_result
eq_cmp_result
()
const
{
return
COND_FALSE
;
}
optimize_type
select_optimize
()
const
{
return
OPTIMIZE_KEY
;
}
optimize_type
select_optimize
()
const
{
return
OPTIMIZE_KEY
;
}
const
char
*
func_name
()
const
{
return
"<>"
;
}
const
char
*
func_name
()
const
{
return
"<>"
;
}
Item
*
neg
_transformer
();
Item
*
neg
ated_item
();
};
};
...
@@ -409,6 +412,7 @@ class Item_func_if :public Item_func
...
@@ -409,6 +412,7 @@ class Item_func_if :public Item_func
enum
Item_result
result_type
()
const
{
return
cached_result_type
;
}
enum
Item_result
result_type
()
const
{
return
cached_result_type
;
}
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tlist
,
Item
**
ref
)
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tlist
,
Item
**
ref
)
{
{
DBUG_ASSERT
(
fixed
==
0
);
args
[
0
]
->
top_level_item
();
args
[
0
]
->
top_level_item
();
return
Item_func
::
fix_fields
(
thd
,
tlist
,
ref
);
return
Item_func
::
fix_fields
(
thd
,
tlist
,
ref
);
}
}
...
@@ -726,6 +730,7 @@ class Item_func_in :public Item_int_func
...
@@ -726,6 +730,7 @@ class Item_func_in :public Item_int_func
void
cleanup
()
void
cleanup
()
{
{
DBUG_ENTER
(
"Item_func_in::cleanup"
);
DBUG_ENTER
(
"Item_func_in::cleanup"
);
Item_int_func
::
cleanup
();
delete
array
;
delete
array
;
delete
in_item
;
delete
in_item
;
array
=
0
;
array
=
0
;
...
@@ -778,7 +783,7 @@ class Item_func_isnull :public Item_bool_func
...
@@ -778,7 +783,7 @@ class Item_func_isnull :public Item_bool_func
}
}
table_map
not_null_tables
()
const
{
return
0
;
}
table_map
not_null_tables
()
const
{
return
0
;
}
optimize_type
select_optimize
()
const
{
return
OPTIMIZE_NULL
;
}
optimize_type
select_optimize
()
const
{
return
OPTIMIZE_NULL
;
}
Item
*
neg_transformer
();
Item
*
neg_transformer
(
THD
*
thd
);
CHARSET_INFO
*
compare_collation
()
{
return
args
[
0
]
->
collation
.
collation
;
}
CHARSET_INFO
*
compare_collation
()
{
return
args
[
0
]
->
collation
.
collation
;
}
};
};
...
@@ -812,7 +817,7 @@ class Item_func_isnotnull :public Item_bool_func
...
@@ -812,7 +817,7 @@ class Item_func_isnotnull :public Item_bool_func
const
char
*
func_name
()
const
{
return
"isnotnull"
;
}
const
char
*
func_name
()
const
{
return
"isnotnull"
;
}
optimize_type
select_optimize
()
const
{
return
OPTIMIZE_NULL
;
}
optimize_type
select_optimize
()
const
{
return
OPTIMIZE_NULL
;
}
table_map
not_null_tables
()
const
{
return
0
;
}
table_map
not_null_tables
()
const
{
return
0
;
}
Item
*
neg_transformer
();
Item
*
neg_transformer
(
THD
*
thd
);
void
print
(
String
*
str
);
void
print
(
String
*
str
);
CHARSET_INFO
*
compare_collation
()
{
return
args
[
0
]
->
collation
.
collation
;
}
CHARSET_INFO
*
compare_collation
()
{
return
args
[
0
]
->
collation
.
collation
;
}
};
};
...
@@ -920,7 +925,7 @@ class Item_cond :public Item_bool_func
...
@@ -920,7 +925,7 @@ class Item_cond :public Item_bool_func
void
top_level_item
()
{
abort_on_null
=
1
;
}
void
top_level_item
()
{
abort_on_null
=
1
;
}
void
copy_andor_arguments
(
THD
*
thd
,
Item_cond
*
item
);
void
copy_andor_arguments
(
THD
*
thd
,
Item_cond
*
item
);
bool
walk
(
Item_processor
processor
,
byte
*
arg
);
bool
walk
(
Item_processor
processor
,
byte
*
arg
);
void
neg_arguments
();
void
neg_arguments
(
THD
*
thd
);
};
};
...
@@ -941,7 +946,7 @@ class Item_cond_and :public Item_cond
...
@@ -941,7 +946,7 @@ class Item_cond_and :public Item_cond
item
->
copy_andor_arguments
(
thd
,
this
);
item
->
copy_andor_arguments
(
thd
,
this
);
return
item
;
return
item
;
}
}
Item
*
neg_transformer
();
Item
*
neg_transformer
(
THD
*
thd
);
};
};
class
Item_cond_or
:
public
Item_cond
class
Item_cond_or
:
public
Item_cond
...
@@ -962,7 +967,7 @@ class Item_cond_or :public Item_cond
...
@@ -962,7 +967,7 @@ class Item_cond_or :public Item_cond
item
->
copy_andor_arguments
(
thd
,
this
);
item
->
copy_andor_arguments
(
thd
,
this
);
return
item
;
return
item
;
}
}
Item
*
neg_transformer
();
Item
*
neg_transformer
(
THD
*
thd
);
};
};
...
...
sql/item_func.cc
View file @
8035ce40
...
@@ -199,6 +199,7 @@ Item_func::Item_func(THD *thd, Item_func *item)
...
@@ -199,6 +199,7 @@ Item_func::Item_func(THD *thd, Item_func *item)
bool
bool
Item_func
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
Item_func
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
{
{
DBUG_ASSERT
(
fixed
==
0
);
Item
**
arg
,
**
arg_end
;
Item
**
arg
,
**
arg_end
;
#ifndef EMBEDDED_LIBRARY // Avoid compiler warning
#ifndef EMBEDDED_LIBRARY // Avoid compiler warning
char
buff
[
STACK_BUFF_ALLOC
];
// Max argument in function
char
buff
[
STACK_BUFF_ALLOC
];
// Max argument in function
...
@@ -215,7 +216,7 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
...
@@ -215,7 +216,7 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
{
{
Item
*
item
;
Item
*
item
;
/* We can't yet set item to *arg as fix_fields may change *arg */
/* We can't yet set item to *arg as fix_fields may change *arg */
if
((
*
arg
)
->
fix_fields
(
thd
,
tables
,
arg
)
||
if
((
!
(
*
arg
)
->
fixed
&&
(
*
arg
)
->
fix_fields
(
thd
,
tables
,
arg
)
)
||
(
*
arg
)
->
check_cols
(
allowed_arg_cols
))
(
*
arg
)
->
check_cols
(
allowed_arg_cols
))
return
1
;
/* purecov: inspected */
return
1
;
/* purecov: inspected */
item
=
*
arg
;
item
=
*
arg
;
...
@@ -2172,6 +2173,7 @@ static user_var_entry *get_variable(HASH *hash, LEX_STRING &name,
...
@@ -2172,6 +2173,7 @@ static user_var_entry *get_variable(HASH *hash, LEX_STRING &name,
bool
Item_func_set_user_var
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
bool
Item_func_set_user_var
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
Item
**
ref
)
{
{
DBUG_ASSERT
(
fixed
==
0
);
/* fix_fields will call Item_func_set_user_var::fix_length_and_dec */
/* fix_fields will call Item_func_set_user_var::fix_length_and_dec */
if
(
Item_func
::
fix_fields
(
thd
,
tables
,
ref
)
||
if
(
Item_func
::
fix_fields
(
thd
,
tables
,
ref
)
||
!
(
entry
=
get_variable
(
&
thd
->
user_vars
,
name
,
1
)))
!
(
entry
=
get_variable
(
&
thd
->
user_vars
,
name
,
1
)))
...
@@ -2741,6 +2743,7 @@ void Item_func_match::init_search(bool no_order)
...
@@ -2741,6 +2743,7 @@ void Item_func_match::init_search(bool no_order)
bool
Item_func_match
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tlist
,
Item
**
ref
)
bool
Item_func_match
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tlist
,
Item
**
ref
)
{
{
DBUG_ASSERT
(
fixed
==
0
);
Item
*
item
;
Item
*
item
;
LINT_INIT
(
item
);
// Safe as arg_count is > 1
LINT_INIT
(
item
);
// Safe as arg_count is > 1
...
...
sql/item_func.h
View file @
8035ce40
...
@@ -765,6 +765,7 @@ class Item_udf_func :public Item_func
...
@@ -765,6 +765,7 @@ class Item_udf_func :public Item_func
const
char
*
func_name
()
const
{
return
udf
.
name
();
}
const
char
*
func_name
()
const
{
return
udf
.
name
();
}
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tables
,
Item
**
ref
)
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tables
,
Item
**
ref
)
{
{
DBUG_ASSERT
(
fixed
==
0
);
bool
res
=
udf
.
fix_fields
(
thd
,
tables
,
this
,
arg_count
,
args
);
bool
res
=
udf
.
fix_fields
(
thd
,
tables
,
this
,
arg_count
,
args
);
used_tables_cache
=
udf
.
used_tables_cache
;
used_tables_cache
=
udf
.
used_tables_cache
;
const_item_cache
=
udf
.
const_item_cache
;
const_item_cache
=
udf
.
const_item_cache
;
...
@@ -1000,6 +1001,7 @@ class Item_func_match :public Item_real_func
...
@@ -1000,6 +1001,7 @@ class Item_func_match :public Item_real_func
void
cleanup
()
void
cleanup
()
{
{
DBUG_ENTER
(
"Item_func_match"
);
DBUG_ENTER
(
"Item_func_match"
);
Item_real_func
::
cleanup
();
if
(
!
master
&&
ft_handler
)
if
(
!
master
&&
ft_handler
)
{
{
ft_handler
->
please
->
close_search
(
ft_handler
);
ft_handler
->
please
->
close_search
(
ft_handler
);
...
...
sql/item_row.cc
View file @
8035ce40
...
@@ -55,6 +55,7 @@ void Item_row::illegal_method_call(const char *method)
...
@@ -55,6 +55,7 @@ void Item_row::illegal_method_call(const char *method)
bool
Item_row
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tabl
,
Item
**
ref
)
bool
Item_row
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tabl
,
Item
**
ref
)
{
{
DBUG_ASSERT
(
fixed
==
0
);
null_value
=
0
;
null_value
=
0
;
maybe_null
=
0
;
maybe_null
=
0
;
Item
**
arg
,
**
arg_end
;
Item
**
arg
,
**
arg_end
;
...
@@ -78,6 +79,7 @@ bool Item_row::fix_fields(THD *thd, TABLE_LIST *tabl, Item **ref)
...
@@ -78,6 +79,7 @@ bool Item_row::fix_fields(THD *thd, TABLE_LIST *tabl, Item **ref)
maybe_null
|=
item
->
maybe_null
;
maybe_null
|=
item
->
maybe_null
;
with_sum_func
=
with_sum_func
||
item
->
with_sum_func
;
with_sum_func
=
with_sum_func
||
item
->
with_sum_func
;
}
}
fixed
=
1
;
return
0
;
return
0
;
}
}
...
...
sql/item_strfunc.h
View file @
8035ce40
...
@@ -100,6 +100,7 @@ class Item_func_concat_ws :public Item_str_func
...
@@ -100,6 +100,7 @@ class Item_func_concat_ws :public Item_str_func
void
update_used_tables
();
void
update_used_tables
();
bool
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tlist
,
Item
**
ref
)
bool
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tlist
,
Item
**
ref
)
{
{
DBUG_ASSERT
(
fixed
==
0
);
return
(
separator
->
fix_fields
(
thd
,
tlist
,
&
separator
)
||
return
(
separator
->
fix_fields
(
thd
,
tlist
,
&
separator
)
||
separator
->
check_cols
(
1
)
||
separator
->
check_cols
(
1
)
||
Item_func
::
fix_fields
(
thd
,
tlist
,
ref
));
Item_func
::
fix_fields
(
thd
,
tlist
,
ref
));
...
@@ -411,6 +412,7 @@ class Item_func_make_set :public Item_str_func
...
@@ -411,6 +412,7 @@ class Item_func_make_set :public Item_str_func
String
*
val_str
(
String
*
str
);
String
*
val_str
(
String
*
str
);
bool
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tlist
,
Item
**
ref
)
bool
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tlist
,
Item
**
ref
)
{
{
DBUG_ASSERT
(
fixed
==
0
);
return
(
item
->
fix_fields
(
thd
,
tlist
,
&
item
)
||
return
(
item
->
fix_fields
(
thd
,
tlist
,
&
item
)
||
item
->
check_cols
(
1
)
||
item
->
check_cols
(
1
)
||
Item_func
::
fix_fields
(
thd
,
tlist
,
ref
));
Item_func
::
fix_fields
(
thd
,
tlist
,
ref
));
...
...
sql/item_subselect.cc
View file @
8035ce40
...
@@ -102,6 +102,7 @@ Item_subselect::select_transformer(JOIN *join)
...
@@ -102,6 +102,7 @@ Item_subselect::select_transformer(JOIN *join)
bool
Item_subselect
::
fix_fields
(
THD
*
thd_param
,
TABLE_LIST
*
tables
,
Item
**
ref
)
bool
Item_subselect
::
fix_fields
(
THD
*
thd_param
,
TABLE_LIST
*
tables
,
Item
**
ref
)
{
{
DBUG_ASSERT
(
fixed
==
0
);
engine
->
set_thd
((
thd
=
thd_param
));
engine
->
set_thd
((
thd
=
thd_param
));
stmt
=
thd
->
current_statement
;
stmt
=
thd
->
current_statement
;
...
@@ -125,8 +126,10 @@ bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref)
...
@@ -125,8 +126,10 @@ bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref)
engine
->
exclude
();
engine
->
exclude
();
substitution
=
0
;
substitution
=
0
;
fixed
=
1
;
fixed
=
1
;
thd
->
where
=
"checking transformed subquery"
;
thd
->
where
=
"checking transformed subquery"
;
int
ret
=
(
*
ref
)
->
fix_fields
(
thd
,
tables
,
ref
);
int
ret
=
0
;
if
(
!
(
*
ref
)
->
fixed
)
ret
=
(
*
ref
)
->
fix_fields
(
thd
,
tables
,
ref
);
// We can't substitute aggregate functions (like (SELECT (max(i)))
// We can't substitute aggregate functions (like (SELECT (max(i)))
if
((
*
ref
)
->
with_sum_func
)
if
((
*
ref
)
->
with_sum_func
)
{
{
...
@@ -651,9 +654,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
...
@@ -651,9 +654,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
select_lex
->
item_list
.
empty
();
select_lex
->
item_list
.
empty
();
select_lex
->
item_list
.
push_back
(
item
);
select_lex
->
item_list
.
push_back
(
item
);
if
(
item
->
fix_fields
(
thd
,
join
->
tables_list
,
// fix_fields call for 'item' will be made during new subquery fix_fields
select_lex
->
item_list
.
head_ref
()))
goto
err
;
subs
=
new
Item_singlerow_subselect
(
select_lex
);
subs
=
new
Item_singlerow_subselect
(
select_lex
);
}
}
...
...
sql/item_sum.cc
View file @
8035ce40
...
@@ -162,6 +162,7 @@ Item_sum_int::val_str(String *str)
...
@@ -162,6 +162,7 @@ Item_sum_int::val_str(String *str)
bool
bool
Item_sum_num
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
Item_sum_num
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
{
{
DBUG_ASSERT
(
fixed
==
0
);
if
(
!
thd
->
allow_sum_func
)
if
(
!
thd
->
allow_sum_func
)
{
{
my_error
(
ER_INVALID_GROUP_FUNC_USE
,
MYF
(
0
));
my_error
(
ER_INVALID_GROUP_FUNC_USE
,
MYF
(
0
));
...
@@ -191,6 +192,7 @@ Item_sum_num::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
...
@@ -191,6 +192,7 @@ Item_sum_num::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
bool
bool
Item_sum_hybrid
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
Item_sum_hybrid
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
{
{
DBUG_ASSERT
(
fixed
==
0
);
Item
*
item
=
args
[
0
];
Item
*
item
=
args
[
0
];
if
(
!
thd
->
allow_sum_func
)
if
(
!
thd
->
allow_sum_func
)
{
{
...
@@ -1116,6 +1118,7 @@ void Item_sum_count_distinct::cleanup()
...
@@ -1116,6 +1118,7 @@ void Item_sum_count_distinct::cleanup()
bool
Item_sum_count_distinct
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
bool
Item_sum_count_distinct
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
Item
**
ref
)
{
{
DBUG_ASSERT
(
fixed
==
0
);
if
(
Item_sum_num
::
fix_fields
(
thd
,
tables
,
ref
))
if
(
Item_sum_num
::
fix_fields
(
thd
,
tables
,
ref
))
return
1
;
return
1
;
return
0
;
return
0
;
...
@@ -1679,6 +1682,7 @@ Item_func_group_concat::Item_func_group_concat(bool is_distinct,
...
@@ -1679,6 +1682,7 @@ Item_func_group_concat::Item_func_group_concat(bool is_distinct,
void
Item_func_group_concat
::
cleanup
()
void
Item_func_group_concat
::
cleanup
()
{
{
DBUG_ENTER
(
"Item_func_group_concat::cleanup"
);
DBUG_ENTER
(
"Item_func_group_concat::cleanup"
);
Item_sum
::
cleanup
();
/*
/*
Free table and tree if they belong to this item (if item have not pointer
Free table and tree if they belong to this item (if item have not pointer
to original item from which was made copy => it own its objects )
to original item from which was made copy => it own its objects )
...
@@ -1794,6 +1798,7 @@ void Item_func_group_concat::reset_field()
...
@@ -1794,6 +1798,7 @@ void Item_func_group_concat::reset_field()
bool
bool
Item_func_group_concat
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
Item_func_group_concat
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
{
{
DBUG_ASSERT
(
fixed
==
0
);
uint
i
;
/* for loop variable */
uint
i
;
/* for loop variable */
if
(
!
thd
->
allow_sum_func
)
if
(
!
thd
->
allow_sum_func
)
...
...
sql/item_sum.h
View file @
8035ce40
...
@@ -533,6 +533,7 @@ class Item_udf_sum : public Item_sum
...
@@ -533,6 +533,7 @@ class Item_udf_sum : public Item_sum
const
char
*
func_name
()
const
{
return
udf
.
name
();
}
const
char
*
func_name
()
const
{
return
udf
.
name
();
}
bool
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
bool
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
{
{
DBUG_ASSERT
(
fixed
==
0
);
fixed
=
1
;
fixed
=
1
;
return
udf
.
fix_fields
(
thd
,
tables
,
this
,
this
->
arg_count
,
this
->
args
);
return
udf
.
fix_fields
(
thd
,
tables
,
this
,
this
->
arg_count
,
this
->
args
);
}
}
...
...
sql/item_uniq.h
View file @
8035ce40
...
@@ -48,6 +48,7 @@ class Item_sum_unique_users :public Item_sum_num
...
@@ -48,6 +48,7 @@ class Item_sum_unique_users :public Item_sum_num
void
update_field
()
{}
void
update_field
()
{}
bool
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tlist
,
Item
**
ref
)
bool
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tlist
,
Item
**
ref
)
{
{
DBUG_ASSERT
(
fixed
==
0
);
fixed
=
1
;
fixed
=
1
;
return
0
;
return
0
;
}
}
...
...
sql/sql_base.cc
View file @
8035ce40
...
@@ -2140,7 +2140,7 @@ int setup_fields(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
...
@@ -2140,7 +2140,7 @@ int setup_fields(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
Item
**
ref
=
ref_pointer_array
;
Item
**
ref
=
ref_pointer_array
;
while
((
item
=
it
++
))
while
((
item
=
it
++
))
{
{
if
(
item
->
fix_fields
(
thd
,
tables
,
it
.
ref
())
||
if
(
!
item
->
fixed
&&
item
->
fix_fields
(
thd
,
tables
,
it
.
ref
())
||
(
item
=
*
(
it
.
ref
()))
->
check_cols
(
1
))
(
item
=
*
(
it
.
ref
()))
->
check_cols
(
1
))
DBUG_RETURN
(
-
1
);
/* purecov: inspected */
DBUG_RETURN
(
-
1
);
/* purecov: inspected */
if
(
ref
)
if
(
ref
)
...
@@ -2322,7 +2322,8 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
...
@@ -2322,7 +2322,8 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
if
(
*
conds
)
if
(
*
conds
)
{
{
thd
->
where
=
"where clause"
;
thd
->
where
=
"where clause"
;
if
((
*
conds
)
->
fix_fields
(
thd
,
tables
,
conds
)
||
(
*
conds
)
->
check_cols
(
1
))
if
(
!
(
*
conds
)
->
fixed
&&
(
*
conds
)
->
fix_fields
(
thd
,
tables
,
conds
)
||
(
*
conds
)
->
check_cols
(
1
))
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
not_null_tables
=
(
*
conds
)
->
not_null_tables
();
not_null_tables
=
(
*
conds
)
->
not_null_tables
();
}
}
...
@@ -2334,7 +2335,9 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
...
@@ -2334,7 +2335,9 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
{
{
/* Make a join an a expression */
/* Make a join an a expression */
thd
->
where
=
"on clause"
;
thd
->
where
=
"on clause"
;
if
(
table
->
on_expr
->
fix_fields
(
thd
,
tables
,
&
table
->
on_expr
)
||
if
(
!
table
->
on_expr
->
fixed
&&
table
->
on_expr
->
fix_fields
(
thd
,
tables
,
&
table
->
on_expr
)
||
table
->
on_expr
->
check_cols
(
1
))
table
->
on_expr
->
check_cols
(
1
))
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
thd
->
lex
->
current_select
->
cond_count
++
;
thd
->
lex
->
current_select
->
cond_count
++
;
...
...
sql/sql_derived.cc
View file @
8035ce40
...
@@ -151,7 +151,11 @@ static int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit,
...
@@ -151,7 +151,11 @@ static int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit,
if
(
is_union
)
if
(
is_union
)
res
=
mysql_union
(
thd
,
lex
,
derived_result
,
unit
);
{
// execute union without clean up
if
(
!
(
res
=
unit
->
prepare
(
thd
,
derived_result
,
SELECT_NO_UNLOCK
)))
res
=
unit
->
exec
();
}
else
else
{
{
unit
->
offset_limit_cnt
=
first_select
->
offset_limit
;
unit
->
offset_limit_cnt
=
first_select
->
offset_limit
;
...
...
sql/sql_select.cc
View file @
8035ce40
...
@@ -70,8 +70,10 @@ static int return_zero_rows(JOIN *join, select_result *res,TABLE_LIST *tables,
...
@@ -70,8 +70,10 @@ static int return_zero_rows(JOIN *join, select_result *res,TABLE_LIST *tables,
uint
select_options
,
const
char
*
info
,
uint
select_options
,
const
char
*
info
,
Item
*
having
,
Procedure
*
proc
,
Item
*
having
,
Procedure
*
proc
,
SELECT_LEX_UNIT
*
unit
);
SELECT_LEX_UNIT
*
unit
);
static
COND
*
optimize_cond
(
COND
*
conds
,
Item
::
cond_result
*
cond_value
);
static
COND
*
optimize_cond
(
THD
*
thd
,
COND
*
conds
,
static
COND
*
remove_eq_conds
(
COND
*
cond
,
Item
::
cond_result
*
cond_value
);
Item
::
cond_result
*
cond_value
);
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
const_expression_in_where
(
COND
*
conds
,
Item
*
item
,
Item
**
comp_item
);
static
bool
open_tmp_table
(
TABLE
*
table
);
static
bool
open_tmp_table
(
TABLE
*
table
);
static
bool
create_myisam_tmp_table
(
TABLE
*
table
,
TMP_TABLE_PARAM
*
param
,
static
bool
create_myisam_tmp_table
(
TABLE
*
table
,
TMP_TABLE_PARAM
*
param
,
...
@@ -286,6 +288,10 @@ JOIN::prepare(Item ***rref_pointer_array,
...
@@ -286,6 +288,10 @@ JOIN::prepare(Item ***rref_pointer_array,
{
{
DBUG_ENTER
(
"JOIN::prepare"
);
DBUG_ENTER
(
"JOIN::prepare"
);
// to prevent double initialization on EXPLAIN
if
(
optimized
)
DBUG_RETURN
(
0
);
conds
=
conds_init
;
conds
=
conds_init
;
order
=
order_init
;
order
=
order_init
;
group_list
=
group_init
;
group_list
=
group_init
;
...
@@ -315,8 +321,9 @@ JOIN::prepare(Item ***rref_pointer_array,
...
@@ -315,8 +321,9 @@ JOIN::prepare(Item ***rref_pointer_array,
thd
->
where
=
"having clause"
;
thd
->
where
=
"having clause"
;
thd
->
allow_sum_func
=
1
;
thd
->
allow_sum_func
=
1
;
select_lex
->
having_fix_field
=
1
;
select_lex
->
having_fix_field
=
1
;
bool
having_fix_rc
=
(
having
->
fix_fields
(
thd
,
tables_list
,
&
having
)
||
bool
having_fix_rc
=
!
having
->
fixed
&&
having
->
check_cols
(
1
));
(
having
->
fix_fields
(
thd
,
tables_list
,
&
having
)
||
having
->
check_cols
(
1
));
select_lex
->
having_fix_field
=
0
;
select_lex
->
having_fix_field
=
0
;
if
(
having_fix_rc
||
thd
->
net
.
report_error
)
if
(
having_fix_rc
||
thd
->
net
.
report_error
)
DBUG_RETURN
(
-
1
);
/* purecov: inspected */
DBUG_RETURN
(
-
1
);
/* purecov: inspected */
...
@@ -518,7 +525,7 @@ JOIN::optimize()
...
@@ -518,7 +525,7 @@ JOIN::optimize()
}
}
#endif
#endif
conds
=
optimize_cond
(
conds
,
&
cond_value
);
conds
=
optimize_cond
(
thd
,
conds
,
&
cond_value
);
if
(
thd
->
net
.
report_error
)
if
(
thd
->
net
.
report_error
)
{
{
error
=
1
;
error
=
1
;
...
@@ -4333,6 +4340,7 @@ propagate_cond_constants(I_List<COND_CMP> *save_list,COND *and_father,
...
@@ -4333,6 +4340,7 @@ propagate_cond_constants(I_List<COND_CMP> *save_list,COND *and_father,
SYNPOSIS
SYNPOSIS
eliminate_not_funcs()
eliminate_not_funcs()
thd thread handler
cond condition tree
cond condition tree
DESCRIPTION
DESCRIPTION
...
@@ -4349,7 +4357,7 @@ propagate_cond_constants(I_List<COND_CMP> *save_list,COND *and_father,
...
@@ -4349,7 +4357,7 @@ propagate_cond_constants(I_List<COND_CMP> *save_list,COND *and_father,
New condition tree
New condition tree
*/
*/
COND
*
eliminate_not_funcs
(
COND
*
cond
)
COND
*
eliminate_not_funcs
(
THD
*
thd
,
COND
*
cond
)
{
{
if
(
!
cond
)
if
(
!
cond
)
return
cond
;
return
cond
;
...
@@ -4359,7 +4367,7 @@ COND *eliminate_not_funcs(COND *cond)
...
@@ -4359,7 +4367,7 @@ COND *eliminate_not_funcs(COND *cond)
Item
*
item
;
Item
*
item
;
while
((
item
=
li
++
))
while
((
item
=
li
++
))
{
{
Item
*
new_item
=
eliminate_not_funcs
(
item
);
Item
*
new_item
=
eliminate_not_funcs
(
thd
,
item
);
if
(
item
!=
new_item
)
if
(
item
!=
new_item
)
VOID
(
li
.
replace
(
new_item
));
/* replace item with a new condition */
VOID
(
li
.
replace
(
new_item
));
/* replace item with a new condition */
}
}
...
@@ -4367,14 +4375,13 @@ COND *eliminate_not_funcs(COND *cond)
...
@@ -4367,14 +4375,13 @@ COND *eliminate_not_funcs(COND *cond)
else
if
(
cond
->
type
()
==
Item
::
FUNC_ITEM
&&
/* 'NOT' operation? */
else
if
(
cond
->
type
()
==
Item
::
FUNC_ITEM
&&
/* 'NOT' operation? */
((
Item_func
*
)
cond
)
->
functype
()
==
Item_func
::
NOT_FUNC
)
((
Item_func
*
)
cond
)
->
functype
()
==
Item_func
::
NOT_FUNC
)
{
{
COND
*
new_cond
=
((
Item_func
*
)
cond
)
->
arguments
()[
0
]
->
neg_transformer
();
COND
*
new_cond
=
((
Item_func
*
)
cond
)
->
arguments
()[
0
]
->
neg_transformer
(
thd
);
if
(
new_cond
)
if
(
new_cond
)
{
{
/*
/*
Here we can delete the NOT function. Something like: delete cond;
Here we can delete the NOT function. Something like: delete cond;
But we don't need to do it. All items will be deleted later at once.
But we don't need to do it. All items will be deleted later at once.
*/
*/
new_cond
->
fix_fields
(
current_thd
,
0
,
&
new_cond
);
cond
=
new_cond
;
cond
=
new_cond
;
}
}
}
}
...
@@ -4383,7 +4390,7 @@ COND *eliminate_not_funcs(COND *cond)
...
@@ -4383,7 +4390,7 @@ COND *eliminate_not_funcs(COND *cond)
static
COND
*
static
COND
*
optimize_cond
(
COND
*
conds
,
Item
::
cond_result
*
cond_value
)
optimize_cond
(
THD
*
thd
,
COND
*
conds
,
Item
::
cond_result
*
cond_value
)
{
{
DBUG_ENTER
(
"optimize_cond"
);
DBUG_ENTER
(
"optimize_cond"
);
if
(
!
conds
)
if
(
!
conds
)
...
@@ -4393,7 +4400,7 @@ optimize_cond(COND *conds,Item::cond_result *cond_value)
...
@@ -4393,7 +4400,7 @@ optimize_cond(COND *conds,Item::cond_result *cond_value)
}
}
DBUG_EXECUTE
(
"where"
,
print_where
(
conds
,
"original"
););
DBUG_EXECUTE
(
"where"
,
print_where
(
conds
,
"original"
););
/* eliminate NOT operators */
/* eliminate NOT operators */
conds
=
eliminate_not_funcs
(
conds
);
conds
=
eliminate_not_funcs
(
thd
,
conds
);
DBUG_EXECUTE
(
"where"
,
print_where
(
conds
,
"after negation elimination"
););
DBUG_EXECUTE
(
"where"
,
print_where
(
conds
,
"after negation elimination"
););
/* change field = field to field = const for each found field = const */
/* change field = field to field = const for each found field = const */
propagate_cond_constants
((
I_List
<
COND_CMP
>
*
)
0
,
conds
,
conds
);
propagate_cond_constants
((
I_List
<
COND_CMP
>
*
)
0
,
conds
,
conds
);
...
@@ -4402,7 +4409,7 @@ optimize_cond(COND *conds,Item::cond_result *cond_value)
...
@@ -4402,7 +4409,7 @@ optimize_cond(COND *conds,Item::cond_result *cond_value)
Remove all and-levels where CONST item != CONST item
Remove all and-levels where CONST item != CONST item
*/
*/
DBUG_EXECUTE
(
"where"
,
print_where
(
conds
,
"after const change"
););
DBUG_EXECUTE
(
"where"
,
print_where
(
conds
,
"after const change"
););
conds
=
remove_eq_conds
(
conds
,
cond_value
)
;
conds
=
remove_eq_conds
(
thd
,
conds
,
cond_value
)
;
DBUG_EXECUTE
(
"info"
,
print_where
(
conds
,
"after remove"
););
DBUG_EXECUTE
(
"info"
,
print_where
(
conds
,
"after remove"
););
DBUG_RETURN
(
conds
);
DBUG_RETURN
(
conds
);
}
}
...
@@ -4417,7 +4424,7 @@ optimize_cond(COND *conds,Item::cond_result *cond_value)
...
@@ -4417,7 +4424,7 @@ optimize_cond(COND *conds,Item::cond_result *cond_value)
*/
*/
static
COND
*
static
COND
*
remove_eq_conds
(
COND
*
cond
,
Item
::
cond_result
*
cond_value
)
remove_eq_conds
(
THD
*
thd
,
COND
*
cond
,
Item
::
cond_result
*
cond_value
)
{
{
if
(
cond
->
type
()
==
Item
::
COND_ITEM
)
if
(
cond
->
type
()
==
Item
::
COND_ITEM
)
{
{
...
@@ -4431,7 +4438,7 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value)
...
@@ -4431,7 +4438,7 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value)
Item
*
item
;
Item
*
item
;
while
((
item
=
li
++
))
while
((
item
=
li
++
))
{
{
Item
*
new_item
=
remove_eq_conds
(
item
,
&
tmp_cond_value
);
Item
*
new_item
=
remove_eq_conds
(
thd
,
item
,
&
tmp_cond_value
);
if
(
!
new_item
)
if
(
!
new_item
)
li
.
remove
();
li
.
remove
();
else
if
(
item
!=
new_item
)
else
if
(
item
!=
new_item
)
...
@@ -4465,7 +4472,7 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value)
...
@@ -4465,7 +4472,7 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value)
}
}
}
}
if
(
should_fix_fields
)
if
(
should_fix_fields
)
cond
->
fix_fields
(
current_thd
,
0
,
&
cond
);
cond
->
update_used_tables
(
);
if
(
!
((
Item_cond
*
)
cond
)
->
argument_list
()
->
elements
||
if
(
!
((
Item_cond
*
)
cond
)
->
argument_list
()
->
elements
||
*
cond_value
!=
Item
::
COND_OK
)
*
cond_value
!=
Item
::
COND_OK
)
...
@@ -4492,7 +4499,6 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value)
...
@@ -4492,7 +4499,6 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value)
Item_func_isnull
*
func
=
(
Item_func_isnull
*
)
cond
;
Item_func_isnull
*
func
=
(
Item_func_isnull
*
)
cond
;
Item
**
args
=
func
->
arguments
();
Item
**
args
=
func
->
arguments
();
THD
*
thd
=
current_thd
;
if
(
args
[
0
]
->
type
()
==
Item
::
FIELD_ITEM
)
if
(
args
[
0
]
->
type
()
==
Item
::
FIELD_ITEM
)
{
{
Field
*
field
=
((
Item_field
*
)
args
[
0
])
->
field
;
Field
*
field
=
((
Item_field
*
)
args
[
0
])
->
field
;
...
@@ -7913,10 +7919,15 @@ find_order_in_list(THD *thd, Item **ref_pointer_array,
...
@@ -7913,10 +7919,15 @@ find_order_in_list(THD *thd, Item **ref_pointer_array,
}
}
order
->
in_field_list
=
0
;
order
->
in_field_list
=
0
;
Item
*
it
=
*
order
->
item
;
Item
*
it
=
*
order
->
item
;
if
(
it
->
fix_fields
(
thd
,
tables
,
order
->
item
)
||
/*
//'it' ressigned because fix_field can change it
we check it->fixed because Item_func_group_concat can put
(
it
=
*
order
->
item
)
->
check_cols
(
1
)
||
arguments for which fix_fields already was called
thd
->
is_fatal_error
)
*/
if
(
!
it
->
fixed
&&
(
it
->
fix_fields
(
thd
,
tables
,
order
->
item
)
||
//'it' ressigned because fix_field can change it
(
it
=
*
order
->
item
)
->
check_cols
(
1
)
||
thd
->
is_fatal_error
))
return
1
;
// Wrong field
return
1
;
// Wrong field
uint
el
=
all_fields
.
elements
;
uint
el
=
all_fields
.
elements
;
all_fields
.
push_front
(
it
);
// Add new field to field list
all_fields
.
push_front
(
it
);
// Add new field to field list
...
...
sql/sql_select.h
View file @
8035ce40
...
@@ -432,4 +432,4 @@ bool cp_buffer_from_ref(TABLE_REF *ref);
...
@@ -432,4 +432,4 @@ bool cp_buffer_from_ref(TABLE_REF *ref);
bool
error_if_full_join
(
JOIN
*
join
);
bool
error_if_full_join
(
JOIN
*
join
);
int
report_error
(
TABLE
*
table
,
int
error
);
int
report_error
(
TABLE
*
table
,
int
error
);
int
safe_index_read
(
JOIN_TAB
*
tab
);
int
safe_index_read
(
JOIN_TAB
*
tab
);
COND
*
eliminate_not_funcs
(
COND
*
cond
);
COND
*
eliminate_not_funcs
(
THD
*
thd
,
COND
*
cond
);
sql/sql_union.cc
View file @
8035ce40
...
@@ -203,6 +203,8 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
...
@@ -203,6 +203,8 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
}
}
}
}
item_list
.
empty
();
// it is not single select
if
(
first_select
->
next_select
())
if
(
first_select
->
next_select
())
{
{
union_result
->
tmp_table_param
.
field_count
=
types
.
elements
;
union_result
->
tmp_table_param
.
field_count
=
types
.
elements
;
...
@@ -222,14 +224,17 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
...
@@ -222,14 +224,17 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
result_table_list
.
table
=
table
;
result_table_list
.
table
=
table
;
union_result
->
set_table
(
table
);
union_result
->
set_table
(
table
);
item_list
.
empty
();
thd_arg
->
lex
->
current_select
=
lex_select_save
;
thd_arg
->
lex
->
current_select
=
lex_select_save
;
{
{
Field
**
field
;
Field
**
field
;
for
(
field
=
table
->
field
;
*
field
;
field
++
)
for
(
field
=
table
->
field
;
*
field
;
field
++
)
{
{
if
(
item_list
.
push_back
(
new
Item_field
(
*
field
)))
Item_field
*
item
=
new
Item_field
(
*
field
);
if
(
item_list
.
push_back
(
item
))
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
#ifndef DBUG_OFF
item
->
double_fix
=
0
;
#endif
}
}
}
}
}
}
...
...
tests/client_test.c
View file @
8035ce40
...
@@ -8206,7 +8206,6 @@ static void test_bug2247()
...
@@ -8206,7 +8206,6 @@ static void test_bug2247()
}
}
static
void
test_subqueries
()
static
void
test_subqueries
()
{
{
MYSQL_STMT
*
stmt
;
MYSQL_STMT
*
stmt
;
...
@@ -8346,6 +8345,37 @@ static void test_bug2248()
...
@@ -8346,6 +8345,37 @@ static void test_bug2248()
myquery
(
rc
);
myquery
(
rc
);
}
}
static
void
test_subqueries_ref
()
{
MYSQL_STMT
*
stmt
;
int
rc
,
i
;
const
char
*
query
=
"SELECT a as ccc from t1 where a+1=(SELECT 1+ccc from t1 where ccc+1=a+1 and a=1)"
;
myheader
(
"test_subquery_ref"
);
rc
=
mysql_query
(
mysql
,
"DROP TABLE IF EXISTS t1"
);
myquery
(
rc
);
rc
=
mysql_query
(
mysql
,
"CREATE TABLE t1 (a int);"
);
myquery
(
rc
);
rc
=
mysql_query
(
mysql
,
"insert into t1 values (1), (2), (3), (4), (5);"
);
myquery
(
rc
);
stmt
=
mysql_prepare
(
mysql
,
query
,
strlen
(
query
));
mystmt_init
(
stmt
);
for
(
i
=
0
;
i
<
3
;
i
++
)
{
rc
=
mysql_execute
(
stmt
);
mystmt
(
stmt
,
rc
);
assert
(
1
==
my_process_stmt_result
(
stmt
));
}
mysql_stmt_close
(
stmt
);
rc
=
mysql_query
(
mysql
,
"DROP TABLE t1"
);
myquery
(
rc
);
}
/*
/*
Read and parse arguments and MySQL options from my.cnf
Read and parse arguments and MySQL options from my.cnf
...
@@ -8602,6 +8632,9 @@ int main(int argc, char **argv)
...
@@ -8602,6 +8632,9 @@ int main(int argc, char **argv)
test_subqueries
();
/* repeatable subqueries */
test_subqueries
();
/* repeatable subqueries */
test_bad_union
();
/* correct setup of UNION */
test_bad_union
();
/* correct setup of UNION */
test_distinct
();
/* distinct aggregate functions */
test_distinct
();
/* distinct aggregate functions */
test_subqueries_ref
();
/* outer reference in subqueries converted
Item_field -> Item_ref */
end_time
=
time
((
time_t
*
)
0
);
end_time
=
time
((
time_t
*
)
0
);
...
...
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