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
2cf62000
Commit
2cf62000
authored
Jul 01, 2002
by
bell@sanja.is.com.ua
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
subselect in having clause
fixed bug in sum function in subselect
parent
97d9936f
Changes
23
Hide whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
177 additions
and
99 deletions
+177
-99
mysql-test/r/subselect.result
mysql-test/r/subselect.result
+10
-2
mysql-test/t/subselect.test
mysql-test/t/subselect.test
+5
-0
sql/item.cc
sql/item.cc
+56
-6
sql/item.h
sql/item.h
+7
-4
sql/item_cmpfunc.cc
sql/item_cmpfunc.cc
+11
-10
sql/item_cmpfunc.h
sql/item_cmpfunc.h
+10
-8
sql/item_func.cc
sql/item_func.cc
+10
-9
sql/item_func.h
sql/item_func.h
+10
-9
sql/item_strfunc.h
sql/item_strfunc.h
+9
-7
sql/item_subselect.cc
sql/item_subselect.cc
+1
-8
sql/item_subselect.h
sql/item_subselect.h
+1
-1
sql/item_sum.cc
sql/item_sum.cc
+7
-6
sql/item_sum.h
sql/item_sum.h
+4
-4
sql/item_uniq.h
sql/item_uniq.h
+1
-1
sql/sql_base.cc
sql/sql_base.cc
+3
-3
sql/sql_class.cc
sql/sql_class.cc
+1
-1
sql/sql_class.h
sql/sql_class.h
+0
-1
sql/sql_handler.cc
sql/sql_handler.cc
+1
-1
sql/sql_lex.cc
sql/sql_lex.cc
+2
-2
sql/sql_lex.h
sql/sql_lex.h
+4
-1
sql/sql_prepare.cc
sql/sql_prepare.cc
+2
-2
sql/sql_select.cc
sql/sql_select.cc
+18
-10
sql/sql_yacc.yy
sql/sql_yacc.yy
+4
-3
No files found.
mysql-test/r/subselect.result
View file @
2cf62000
...
...
@@ -65,8 +65,8 @@ a
select b,(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2) from t4;
b (select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2)
8 7.5000
8
6.0
000
9
5
.5000
8
4.5
000
9
7
.5000
select * from t3 where exists (select * from t2 where t2.b=t3.a);
a
7
...
...
@@ -74,4 +74,12 @@ select * from t3 where not exists (select * from t2 where t2.b=t3.a);
a
6
3
insert into t4 values (12,7),(1,7),(10,9),(9,6),(7,6),(3,9);
select b,max(a) as ma from t4 group by b having b < (select max(t2.a)
from t2 where t2.b=t4.b);
b ma
select b,max(a) as ma from t4 group by b having b >= (select max(t2.a)
from t2 where t2.b=t4.b);
b ma
7 12
drop table t1,t2,t3,t4;
mysql-test/t/subselect.test
View file @
2cf62000
...
...
@@ -28,4 +28,9 @@ select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from
select
b
,(
select
avg
(
t2
.
a
+
(
select
min
(
t3
.
a
)
from
t3
where
t3
.
a
>=
t4
.
a
))
from
t2
)
from
t4
;
select
*
from
t3
where
exists
(
select
*
from
t2
where
t2
.
b
=
t3
.
a
);
select
*
from
t3
where
not
exists
(
select
*
from
t2
where
t2
.
b
=
t3
.
a
);
insert
into
t4
values
(
12
,
7
),(
1
,
7
),(
10
,
9
),(
9
,
6
),(
7
,
6
),(
3
,
9
);
select
b
,
max
(
a
)
as
ma
from
t4
group
by
b
having
b
<
(
select
max
(
t2
.
a
)
from
t2
where
t2
.
b
=
t4
.
b
);
select
b
,
max
(
a
)
as
ma
from
t4
group
by
b
having
b
>=
(
select
max
(
t2
.
a
)
from
t2
where
t2
.
b
=
t4
.
b
);
drop
table
t1
,
t2
,
t3
,
t4
;
sql/item.cc
View file @
2cf62000
...
...
@@ -446,12 +446,13 @@ String *Item_copy_string::val_str(String *str)
/* ARGSUSED */
bool
Item
::
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
list
)
struct
st_table_list
*
list
,
Item
**
ref
)
{
return
0
;
}
bool
Item_field
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
)
bool
Item_field
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
{
if
(
!
field
)
// If field is not checked
{
...
...
@@ -467,7 +468,7 @@ bool Item_field::fix_fields(THD *thd,TABLE_LIST *tables)
mention of table name, but if we join tables in one list it will
cause error ER_NON_UNIQ_ERROR in find_field_in_tables.
*/
SELECT_LEX
*
last
;
SELECT_LEX
*
last
=
0
;
for
(
SELECT_LEX
*
sl
=
thd
->
lex
.
select
->
outer_select
();
sl
&&
!
tmp
;
sl
=
sl
->
outer_select
())
...
...
@@ -476,6 +477,8 @@ bool Item_field::fix_fields(THD *thd,TABLE_LIST *tables)
if
(
!
tmp
)
return
1
;
else
{
depended_from
=
last
;
/*
Mark all selects from resolved to 1 before select where was
found table as depended (of select where was found table)
...
...
@@ -493,6 +496,7 @@ bool Item_field::fix_fields(THD *thd,TABLE_LIST *tables)
tbl
=
tbl
->
next
)
tbl
->
shared
=
1
;
}
}
}
set_field
(
tmp
);
}
...
...
@@ -504,6 +508,14 @@ bool Item_field::fix_fields(THD *thd,TABLE_LIST *tables)
table
->
used_fields
++
;
table
->
used_keys
&=
field
->
part_of_key
;
}
if
(
depended_from
!=
0
&&
depended_from
->
having_fix_field
)
{
*
ref
=
new
Item_ref
((
char
*
)
db_name
,
(
char
*
)
table_name
,
(
char
*
)
field_name
);
if
(
!*
ref
)
return
1
;
return
(
*
ref
)
->
fix_fields
(
thd
,
tables
,
ref
);
}
return
0
;
}
...
...
@@ -787,12 +799,50 @@ bool Item_null::send(THD *thd, String *packet)
Find field in select list having the same name
*/
bool
Item_ref
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
)
bool
Item_ref
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
reference
)
{
if
(
!
ref
)
{
if
(
!
(
ref
=
find_item_in_list
(
this
,
thd
->
lex
.
select
->
item_list
)))
return
1
;
if
(
!
(
ref
=
find_item_in_list
(
this
,
thd
->
lex
.
select
->
item_list
)))
{
/*
We can't find table field in table list of current select,
consequently we have to find it in outer subselect(s).
We can't join lists of outer & current select, because of scope
of view rules. For example if both tables (outer & current) have
field 'field' it is not mistake to refer to this field without
mention of table name, but if we join tables in one list it will
cause error ER_NON_UNIQ_ERROR in find_field_in_tables.
*/
SELECT_LEX
*
last
=
0
;
for
(
SELECT_LEX
*
sl
=
thd
->
lex
.
select
->
outer_select
();
sl
&&
!
ref
;
sl
=
sl
->
outer_select
())
ref
=
find_item_in_list
(
this
,
(
last
=
sl
)
->
item_list
);
if
(
!
ref
)
return
1
;
else
{
depended_from
=
last
;
/*
Mark all selects from resolved to 1 before select where was
found table as depended (of select where was found table)
*/
for
(
SELECT_LEX
*
s
=
thd
->
lex
.
select
;
s
&&
s
!=
last
;
s
=
s
->
outer_select
())
if
(
!
s
->
depended
)
{
s
->
depended
=
1
;
//Select is depended of outer select
//Tables will be reopened many times
for
(
TABLE_LIST
*
tbl
=
(
TABLE_LIST
*
)
s
->
table_list
.
first
;
tbl
;
tbl
=
tbl
->
next
)
tbl
->
shared
=
1
;
}
}
}
max_length
=
(
*
ref
)
->
max_length
;
maybe_null
=
(
*
ref
)
->
maybe_null
;
decimals
=
(
*
ref
)
->
decimals
;
...
...
sql/item.h
View file @
2cf62000
...
...
@@ -52,7 +52,7 @@ class Item {
virtual
~
Item
()
{
name
=
0
;
}
/*lint -e1509 */
void
set_name
(
char
*
str
,
uint
length
=
0
);
void
init_make_field
(
Send_field
*
tmp_field
,
enum
enum_field_types
type
);
virtual
bool
fix_fields
(
THD
*
,
struct
st_table_list
*
);
virtual
bool
fix_fields
(
THD
*
,
struct
st_table_list
*
,
Item
*
*
);
virtual
bool
save_in_field
(
Field
*
field
);
virtual
void
save_org_in_field
(
Field
*
field
)
{
(
void
)
save_in_field
(
field
);
}
...
...
@@ -85,15 +85,18 @@ class Item {
};
class
st_select_lex
;
class
Item_ident
:
public
Item
{
public:
const
char
*
db_name
;
const
char
*
table_name
;
const
char
*
field_name
;
st_select_lex
*
depended_from
;
Item_ident
(
const
char
*
db_name_par
,
const
char
*
table_name_par
,
const
char
*
field_name_par
)
:
db_name
(
db_name_par
),
table_name
(
table_name_par
),
field_name
(
field_name_par
)
:
db_name
(
db_name_par
),
table_name
(
table_name_par
),
field_name
(
field_name_par
),
depended_from
(
0
)
{
name
=
(
char
*
)
field_name_par
;
}
const
char
*
full_name
()
const
;
};
...
...
@@ -120,7 +123,7 @@ class Item_field :public Item_ident
String
*
str_result
(
String
*
tmp
);
bool
send
(
THD
*
thd
,
String
*
str_arg
)
{
return
result_field
->
send
(
thd
,
str_arg
);
}
void
make_field
(
Send_field
*
field
);
bool
fix_fields
(
THD
*
,
struct
st_table_list
*
);
bool
fix_fields
(
THD
*
,
struct
st_table_list
*
,
Item
*
*
);
bool
save_in_field
(
Field
*
field
);
void
save_org_in_field
(
Field
*
field
);
table_map
used_tables
()
const
;
...
...
@@ -390,7 +393,7 @@ class Item_ref :public Item_ident
}
bool
send
(
THD
*
thd
,
String
*
tmp
)
{
return
(
*
ref
)
->
send
(
thd
,
tmp
);
}
void
make_field
(
Send_field
*
field
)
{
(
*
ref
)
->
make_field
(
field
);
}
bool
fix_fields
(
THD
*
,
struct
st_table_list
*
);
bool
fix_fields
(
THD
*
,
struct
st_table_list
*
,
Item
*
*
);
bool
save_in_field
(
Field
*
field
)
{
return
(
*
ref
)
->
save_in_field
(
field
);
}
void
save_org_in_field
(
Field
*
field
)
{
(
*
ref
)
->
save_org_in_field
(
field
);
}
enum
Item_result
result_type
()
const
{
return
(
*
ref
)
->
result_type
();
}
...
...
sql/item_cmpfunc.cc
View file @
2cf62000
...
...
@@ -727,12 +727,12 @@ double Item_func_case::val()
bool
Item_func_case
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
)
Item_func_case
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
{
if
(
first_expr
&&
first_expr
->
fix_fields
(
thd
,
tables
)
||
else_expr
&&
else_expr
->
fix_fields
(
thd
,
tables
))
if
(
first_expr
&&
first_expr
->
fix_fields
(
thd
,
tables
,
&
first_expr
)
||
else_expr
&&
else_expr
->
fix_fields
(
thd
,
tables
,
&
else_expr
))
return
1
;
if
(
Item_func
::
fix_fields
(
thd
,
tables
))
if
(
Item_func
::
fix_fields
(
thd
,
tables
,
ref
))
return
1
;
if
(
first_expr
)
{
...
...
@@ -1074,7 +1074,7 @@ longlong Item_func_bit_and::val_int()
bool
Item_cond
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
)
Item_cond
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
{
List_iterator
<
Item
>
li
(
list
);
Item
*
item
;
...
...
@@ -1096,7 +1096,7 @@ Item_cond::fix_fields(THD *thd,TABLE_LIST *tables)
#endif
item
=
*
li
.
ref
();
// new current item
}
if
(
item
->
fix_fields
(
thd
,
tables
))
if
(
item
->
fix_fields
(
thd
,
tables
,
li
.
ref
()
))
return
1
;
/* purecov: inspected */
used_tables_cache
|=
item
->
used_tables
();
with_sum_func
=
with_sum_func
||
item
->
with_sum_func
;
...
...
@@ -1272,9 +1272,9 @@ Item_func::optimize_type Item_func_like::select_optimize() const
return
OPTIMIZE_NONE
;
}
bool
Item_func_like
::
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tlist
)
bool
Item_func_like
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tlist
,
Item
**
ref
)
{
if
(
Item_bool_func2
::
fix_fields
(
thd
,
tlist
))
if
(
Item_bool_func2
::
fix_fields
(
thd
,
tlist
,
ref
))
return
1
;
/*
...
...
@@ -1324,9 +1324,10 @@ bool Item_func_like::fix_fields(THD *thd,struct st_table_list *tlist)
#ifdef USE_REGEX
bool
Item_func_regex
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
)
Item_func_regex
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
{
if
(
args
[
0
]
->
fix_fields
(
thd
,
tables
)
||
args
[
1
]
->
fix_fields
(
thd
,
tables
))
if
(
args
[
0
]
->
fix_fields
(
thd
,
tables
,
args
)
||
args
[
1
]
->
fix_fields
(
thd
,
tables
,
args
+
1
))
return
1
;
/* purecov: inspected */
with_sum_func
=
args
[
0
]
->
with_sum_func
||
args
[
1
]
->
with_sum_func
;
max_length
=
1
;
decimals
=
0
;
...
...
sql/item_cmpfunc.h
View file @
2cf62000
...
...
@@ -177,9 +177,10 @@ class Item_func_interval :public Item_int_func
Item_func_interval
(
Item
*
a
,
List
<
Item
>
&
list
)
:
Item_int_func
(
list
),
item
(
a
),
intervals
(
0
)
{}
longlong
val_int
();
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tlist
)
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tlist
,
Item
**
ref
)
{
return
(
item
->
fix_fields
(
thd
,
tlist
)
||
Item_func
::
fix_fields
(
thd
,
tlist
));
return
(
item
->
fix_fields
(
thd
,
tlist
,
&
item
)
||
Item_func
::
fix_fields
(
thd
,
tlist
,
ref
));
}
void
fix_length_and_dec
();
~
Item_func_interval
()
{
delete
item
;
}
...
...
@@ -259,7 +260,7 @@ class Item_func_case :public Item_func
enum
Item_result
result_type
()
const
{
return
cached_result_type
;
}
const
char
*
func_name
()
const
{
return
"case"
;
}
void
print
(
String
*
str
);
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tlist
);
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tlist
,
Item
**
ref
);
Item
*
find_item
(
String
*
str
);
};
...
...
@@ -409,9 +410,10 @@ class Item_func_in :public Item_int_func
Item_func_in
(
Item
*
a
,
List
<
Item
>
&
list
)
:
Item_int_func
(
list
),
item
(
a
),
array
(
0
),
in_item
(
0
)
{}
longlong
val_int
();
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tlist
)
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tlist
,
Item
**
ref
)
{
return
(
item
->
fix_fields
(
thd
,
tlist
)
||
Item_func
::
fix_fields
(
thd
,
tlist
));
return
(
item
->
fix_fields
(
thd
,
tlist
,
&
item
)
||
Item_func
::
fix_fields
(
thd
,
tlist
,
ref
));
}
void
fix_length_and_dec
();
~
Item_func_in
()
{
delete
item
;
delete
array
;
delete
in_item
;
}
...
...
@@ -505,7 +507,7 @@ class Item_func_like :public Item_bool_func2
cond_result
eq_cmp_result
()
const
{
return
COND_TRUE
;
}
const
char
*
func_name
()
const
{
return
"like"
;
}
void
fix_length_and_dec
();
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tlist
);
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tlist
,
Item
**
ref
);
};
#ifdef USE_REGEX
...
...
@@ -523,7 +525,7 @@ class Item_func_regex :public Item_bool_func
regex_compiled
(
0
),
regex_is_const
(
0
)
{}
~
Item_func_regex
();
longlong
val_int
();
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tlist
);
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tlist
,
Item
**
ref
);
const
char
*
func_name
()
const
{
return
"regex"
;
}
};
...
...
@@ -552,7 +554,7 @@ class Item_cond :public Item_bool_func
{
list
.
push_back
(
i1
);
list
.
push_back
(
i2
);
}
~
Item_cond
()
{
list
.
delete_elements
();
}
bool
add
(
Item
*
item
)
{
return
list
.
push_back
(
item
);
}
bool
fix_fields
(
THD
*
,
struct
st_table_list
*
);
bool
fix_fields
(
THD
*
,
struct
st_table_list
*
,
Item
**
ref
);
enum
Type
type
()
const
{
return
COND_ITEM
;
}
List
<
Item
>*
argument_list
()
{
return
&
list
;
}
...
...
sql/item_func.cc
View file @
2cf62000
...
...
@@ -58,7 +58,7 @@ Item_func::Item_func(List<Item> &list)
}
bool
Item_func
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
)
Item_func
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
{
Item
**
arg
,
**
arg_end
;
char
buff
[
STACK_BUFF_ALLOC
];
// Max argument in function
...
...
@@ -72,7 +72,7 @@ Item_func::fix_fields(THD *thd,TABLE_LIST *tables)
{
// Print purify happy
for
(
arg
=
args
,
arg_end
=
args
+
arg_count
;
arg
!=
arg_end
;
arg
++
)
{
if
((
*
arg
)
->
fix_fields
(
thd
,
tables
))
if
((
*
arg
)
->
fix_fields
(
thd
,
tables
,
arg
))
return
1
;
/* purecov: inspected */
if
((
*
arg
)
->
maybe_null
)
maybe_null
=
1
;
...
...
@@ -1102,7 +1102,7 @@ udf_handler::~udf_handler()
bool
udf_handler
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item_result_field
*
func
,
udf_handler
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item_result_field
*
func
,
uint
arg_count
,
Item
**
arguments
)
{
char
buff
[
STACK_BUFF_ALLOC
];
// Max argument in function
...
...
@@ -1146,7 +1146,7 @@ udf_handler::fix_fields(THD *thd,TABLE_LIST *tables,Item_result_field *func,
arg
!=
arg_end
;
arg
++
,
i
++
)
{
if
((
*
arg
)
->
fix_fields
(
thd
,
tables
))
if
((
*
arg
)
->
fix_fields
(
thd
,
tables
,
arg
))
return
1
;
if
((
*
arg
)
->
binary
)
func
->
binary
=
1
;
...
...
@@ -1765,11 +1765,12 @@ 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
)
{
if
(
!
thd
)
thd
=
current_thd
;
if
(
Item_func
::
fix_fields
(
thd
,
tables
)
||
if
(
Item_func
::
fix_fields
(
thd
,
tables
,
ref
)
||
!
(
entry
=
get_variable
(
&
thd
->
user_vars
,
name
,
1
)))
return
1
;
entry
->
update_query_id
=
thd
->
query_id
;
...
...
@@ -2095,7 +2096,7 @@ void Item_func_match::init_search(bool no_order)
}
}
bool
Item_func_match
::
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tlist
)
bool
Item_func_match
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tlist
,
Item
**
ref
)
{
List_iterator
<
Item
>
li
(
fields
);
Item
*
item
;
...
...
@@ -2108,7 +2109,7 @@ bool Item_func_match::fix_fields(THD *thd,struct st_table_list *tlist)
modifications to find_best and auto_close as complement to auto_init code
above.
*/
if
(
Item_func
::
fix_fields
(
thd
,
tlist
)
||
!
const_item
())
if
(
Item_func
::
fix_fields
(
thd
,
tlist
,
ref
)
||
!
const_item
())
{
my_error
(
ER_WRONG_ARGUMENTS
,
MYF
(
0
),
"AGAINST"
);
return
1
;
...
...
@@ -2116,7 +2117,7 @@ bool Item_func_match::fix_fields(THD *thd,struct st_table_list *tlist)
while
((
item
=
li
++
))
{
if
(
item
->
fix_fields
(
thd
,
tlist
))
if
(
item
->
fix_fields
(
thd
,
tlist
,
li
.
ref
()
))
return
1
;
if
(
item
->
type
()
==
Item
::
REF_ITEM
)
li
.
replace
(
item
=
*
((
Item_ref
*
)
item
)
->
ref
);
...
...
sql/item_func.h
View file @
2cf62000
...
...
@@ -99,7 +99,7 @@ class Item_func :public Item_result_field
}
Item_func
(
List
<
Item
>
&
list
);
~
Item_func
()
{}
/* Nothing to do; Items are freed automaticly */
bool
fix_fields
(
THD
*
,
struct
st_table_list
*
);
bool
fix_fields
(
THD
*
,
struct
st_table_list
*
,
Item
**
ref
);
void
make_field
(
Send_field
*
field
);
table_map
used_tables
()
const
;
void
update_used_tables
();
...
...
@@ -567,9 +567,10 @@ class Item_func_field :public Item_int_func
Item_func_field
(
Item
*
a
,
List
<
Item
>
&
list
)
:
Item_int_func
(
list
),
item
(
a
)
{}
~
Item_func_field
()
{
delete
item
;
}
longlong
val_int
();
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tlist
)
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tlist
,
Item
**
ref
)
{
return
(
item
->
fix_fields
(
thd
,
tlist
)
||
Item_func
::
fix_fields
(
thd
,
tlist
));
return
(
item
->
fix_fields
(
thd
,
tlist
,
&
item
)
||
Item_func
::
fix_fields
(
thd
,
tlist
,
ref
));
}
void
update_used_tables
()
{
...
...
@@ -708,11 +709,11 @@ class Item_udf_func :public Item_func
:
Item_func
(
list
),
udf
(
udf_arg
)
{}
~
Item_udf_func
()
{}
const
char
*
func_name
()
const
{
return
udf
.
name
();
}
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tables
)
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tables
,
Item
**
ref
)
{
bool
res
=
udf
.
fix_fields
(
thd
,
tables
,
this
,
arg_count
,
args
);
used_tables_cache
=
udf
.
used_tables_cache
;
const_item_cache
=
udf
.
const_item_cache
;
bool
res
=
udf
.
fix_fields
(
thd
,
tables
,
this
,
arg_count
,
args
);
used_tables_cache
=
udf
.
used_tables_cache
;
const_item_cache
=
udf
.
const_item_cache
;
return
res
;
}
Item_result
result_type
()
const
{
return
udf
.
result_type
();
}
...
...
@@ -867,7 +868,7 @@ class Item_func_set_user_var :public Item_func
void
update_hash
(
void
*
ptr
,
uint
length
,
enum
Item_result
type
);
bool
update
();
enum
Item_result
result_type
()
const
{
return
cached_result_type
;
}
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tables
);
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tables
,
Item
**
ref
);
void
fix_length_and_dec
();
void
print
(
String
*
str
);
const
char
*
func_name
()
const
{
return
"set_user_var"
;
}
...
...
@@ -941,7 +942,7 @@ class Item_func_match :public Item_real_func
}
enum
Functype
functype
()
const
{
return
FT_FUNC
;
}
void
update_used_tables
()
{}
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tlist
);
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tlist
,
Item
**
ref
);
bool
eq
(
const
Item
*
,
bool
binary_cmp
)
const
;
longlong
val_int
()
{
return
val
()
!=
0.0
;
}
double
val
();
...
...
sql/item_strfunc.h
View file @
2cf62000
...
...
@@ -79,10 +79,10 @@ class Item_func_concat_ws :public Item_str_func
String
*
val_str
(
String
*
);
void
fix_length_and_dec
();
void
update_used_tables
();
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tlist
)
bool
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tlist
,
Item
**
ref
)
{
return
(
separator
->
fix_fields
(
thd
,
tlist
)
||
Item_func
::
fix_fields
(
thd
,
tlist
));
return
(
separator
->
fix_fields
(
thd
,
tlist
,
&
separator
)
||
Item_func
::
fix_fields
(
thd
,
tlist
,
ref
));
}
const
char
*
func_name
()
const
{
return
"concat_ws"
;
}
};
...
...
@@ -325,9 +325,10 @@ class Item_func_elt :public Item_str_func
double
val
();
longlong
val_int
();
String
*
val_str
(
String
*
str
);
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tlist
)
bool
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tlist
,
Item
**
ref
)
{
return
(
item
->
fix_fields
(
thd
,
tlist
)
||
Item_func
::
fix_fields
(
thd
,
tlist
));
return
(
item
->
fix_fields
(
thd
,
tlist
,
&
item
)
||
Item_func
::
fix_fields
(
thd
,
tlist
,
ref
));
}
void
fix_length_and_dec
();
void
update_used_tables
();
...
...
@@ -344,9 +345,10 @@ class Item_func_make_set :public Item_str_func
Item_func_make_set
(
Item
*
a
,
List
<
Item
>
&
list
)
:
Item_str_func
(
list
),
item
(
a
)
{}
~
Item_func_make_set
()
{
delete
item
;
}
String
*
val_str
(
String
*
str
);
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tlist
)
bool
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tlist
,
Item
**
ref
)
{
return
(
item
->
fix_fields
(
thd
,
tlist
)
||
Item_func
::
fix_fields
(
thd
,
tlist
));
return
(
item
->
fix_fields
(
thd
,
tlist
,
&
item
)
||
Item_func
::
fix_fields
(
thd
,
tlist
,
ref
));
}
void
fix_length_and_dec
();
void
update_used_tables
();
...
...
sql/item_subselect.cc
View file @
2cf62000
...
...
@@ -75,15 +75,8 @@ void Item_subselect::make_field (Send_field *tmp_field)
}
}
bool
Item_subselect
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
)
bool
Item_subselect
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
{
if
(
thd
->
having_fix_field
)
{
//TODO: subselects in having do not suported now
my_printf_error
(
ER_SYNTAX_ERROR
,
ER
(
ER_SYNTAX_ERROR
),
MYF
(
0
));
return
1
;
}
// Is it one field subselect?
if
(
select_lex
->
item_list
.
elements
>
max_columns
)
{
...
...
sql/item_subselect.h
View file @
2cf62000
...
...
@@ -63,7 +63,7 @@ class Item_subselect :public Item
enum
Type
type
()
const
;
bool
is_null
()
{
return
null_value
;
}
void
make_field
(
Send_field
*
);
bool
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
);
bool
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
);
table_map
used_tables
()
const
;
friend
class
select_subselect
;
...
...
sql/item_sum.cc
View file @
2cf62000
...
...
@@ -112,7 +112,7 @@ Item_sum_int::val_str(String *str)
bool
Item_sum_num
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
)
Item_sum_num
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
{
if
(
!
thd
->
allow_sum_func
)
{
...
...
@@ -124,7 +124,7 @@ Item_sum_num::fix_fields(THD *thd,TABLE_LIST *tables)
maybe_null
=
0
;
for
(
uint
i
=
0
;
i
<
arg_count
;
i
++
)
{
if
(
args
[
i
]
->
fix_fields
(
thd
,
tables
))
if
(
args
[
i
]
->
fix_fields
(
thd
,
tables
,
args
+
i
))
return
1
;
if
(
decimals
<
args
[
i
]
->
decimals
)
decimals
=
args
[
i
]
->
decimals
;
...
...
@@ -140,7 +140,7 @@ Item_sum_num::fix_fields(THD *thd,TABLE_LIST *tables)
bool
Item_sum_hybrid
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
)
Item_sum_hybrid
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
{
Item
*
item
=
args
[
0
];
if
(
!
thd
->
allow_sum_func
)
...
...
@@ -149,7 +149,7 @@ Item_sum_hybrid::fix_fields(THD *thd,TABLE_LIST *tables)
return
1
;
}
thd
->
allow_sum_func
=
0
;
// No included group funcs
if
(
item
->
fix_fields
(
thd
,
table
s
))
if
(
item
->
fix_fields
(
thd
,
tables
,
arg
s
))
return
1
;
hybrid_type
=
item
->
result_type
();
if
(
hybrid_type
==
INT_RESULT
)
...
...
@@ -930,9 +930,10 @@ Item_sum_count_distinct::~Item_sum_count_distinct()
}
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
)
{
if
(
Item_sum_num
::
fix_fields
(
thd
,
tables
)
||
if
(
Item_sum_num
::
fix_fields
(
thd
,
tables
,
ref
)
||
!
(
tmp_table_param
=
new
TMP_TABLE_PARAM
))
return
1
;
return
0
;
...
...
sql/item_sum.h
View file @
2cf62000
...
...
@@ -80,7 +80,7 @@ class Item_sum_num :public Item_sum
Item_sum_num
(
Item
*
item_par
)
:
Item_sum
(
item_par
)
{}
Item_sum_num
(
Item
*
a
,
Item
*
b
)
:
Item_sum
(
a
,
b
)
{}
Item_sum_num
(
List
<
Item
>
&
list
)
:
Item_sum
(
list
)
{}
bool
fix_fields
(
THD
*
,
struct
st_table_list
*
);
bool
fix_fields
(
THD
*
,
TABLE_LIST
*
,
Item
*
*
);
longlong
val_int
()
{
return
(
longlong
)
val
();
}
/* Real as default */
String
*
val_str
(
String
*
str
);
void
reset_field
();
...
...
@@ -146,7 +146,7 @@ class Item_sum_count_distinct :public Item_sum_int
{
TABLE
*
table
;
table_map
used_table_cache
;
bool
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
);
bool
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
);
uint32
*
field_lengths
;
TMP_TABLE_PARAM
*
tmp_table_param
;
TREE
tree
;
...
...
@@ -283,7 +283,7 @@ class Item_sum_hybrid :public Item_sum
Item_sum_hybrid
(
Item
*
item_par
,
int
sign
)
:
Item_sum
(
item_par
),
cmp_sign
(
sign
),
used_table_cache
(
~
(
table_map
)
0
)
{}
bool
fix_fields
(
THD
*
,
struct
st_table_list
*
);
bool
fix_fields
(
THD
*
,
TABLE_LIST
*
,
Item
*
*
);
table_map
used_tables
()
const
{
return
used_table_cache
;
}
bool
const_item
()
const
{
return
!
used_table_cache
;
}
...
...
@@ -382,7 +382,7 @@ class Item_udf_sum : public Item_sum
{
quick_group
=
0
;}
~
Item_udf_sum
()
{}
const
char
*
func_name
()
const
{
return
udf
.
name
();
}
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tables
)
bool
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
{
return
udf
.
fix_fields
(
thd
,
tables
,
this
,
this
->
arg_count
,
this
->
args
);
}
...
...
sql/item_uniq.h
View file @
2cf62000
...
...
@@ -42,5 +42,5 @@ class Item_sum_unique_users :public Item_sum_num
bool
add
()
{
return
0
;
}
void
reset_field
()
{}
void
update_field
(
int
offset
)
{}
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tlist
)
{
return
0
;}
bool
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tlist
,
Item
**
ref
)
{
return
0
;}
};
sql/sql_base.cc
View file @
2cf62000
...
...
@@ -1874,7 +1874,7 @@ int setup_fields(THD *thd, TABLE_LIST *tables, List<Item> &fields,
}
else
{
if
(
item
->
fix_fields
(
thd
,
tables
))
if
(
item
->
fix_fields
(
thd
,
tables
,
it
.
ref
()
))
DBUG_RETURN
(
-
1
);
/* purecov: inspected */
if
(
item
->
with_sum_func
&&
item
->
type
()
!=
Item
::
SUM_FUNC_ITEM
&&
sum_func_list
)
...
...
@@ -2025,7 +2025,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
if
(
*
conds
)
{
thd
->
where
=
"where clause"
;
if
((
*
conds
)
->
fix_fields
(
thd
,
table
s
))
if
((
*
conds
)
->
fix_fields
(
thd
,
tables
,
cond
s
))
DBUG_RETURN
(
1
);
}
...
...
@@ -2036,7 +2036,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
{
/* Make a join an a expression */
thd
->
where
=
"on clause"
;
if
(
table
->
on_expr
->
fix_fields
(
thd
,
tables
))
if
(
table
->
on_expr
->
fix_fields
(
thd
,
tables
,
&
table
->
on_expr
))
DBUG_RETURN
(
1
);
thd
->
cond_count
++
;
...
...
sql/sql_class.cc
View file @
2cf62000
...
...
@@ -81,7 +81,7 @@ static void free_var(user_var_entry *entry)
THD
::
THD
()
:
user_time
(
0
),
fatal_error
(
0
),
last_insert_id_used
(
0
),
insert_id_used
(
0
),
in_lock_tables
(
0
),
global_read_lock
(
0
),
bootstrap
(
0
)
,
having_fix_field
(
0
)
global_read_lock
(
0
),
bootstrap
(
0
)
{
host
=
user
=
priv_user
=
db
=
query
=
ip
=
0
;
host_or_ip
=
"unknown ip"
;
...
...
sql/sql_class.h
View file @
2cf62000
...
...
@@ -453,7 +453,6 @@ class THD :public ilink {
bool
query_error
,
bootstrap
,
cleanup_done
;
bool
safe_to_cache_query
;
bool
volatile
killed
;
bool
having_fix_field
;
//TRUE when having fix field called
bool
prepare_command
;
ulong
param_count
,
current_param_number
;
Error
<
mysql_st_error
>
err_list
;
...
...
sql/sql_handler.cc
View file @
2cf62000
...
...
@@ -106,7 +106,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
}
tables
->
table
=
table
;
if
(
cond
&&
cond
->
fix_fields
(
thd
,
tables
))
if
(
cond
&&
cond
->
fix_fields
(
thd
,
tables
,
&
cond
))
return
-
1
;
if
(
keyname
)
...
...
sql/sql_lex.cc
View file @
2cf62000
...
...
@@ -942,8 +942,8 @@ void st_select_lex::init_select()
interval_list
.
empty
();
use_index
.
empty
();
ftfunc_list
.
empty
();
linkage
=
UNSPECIFIED_TYPE
;
depended
=
0
;
linkage
=
UNSPECIFIED_TYPE
;
depended
=
having_fix_field
=
0
;
}
/*
...
...
sql/sql_lex.h
View file @
2cf62000
...
...
@@ -253,7 +253,10 @@ class st_select_lex: public st_select_lex_node {
uint
in_sum_expr
;
bool
create_refs
,
braces
,
/* SELECT ... UNION (SELECT ... ) <- this braces */
depended
;
/* depended from outer select subselect */
depended
,
/* depended from outer select subselect */
/* TRUE when having fix field called in processing of this SELECT */
having_fix_field
;
void
init_query
();
void
init_select
();
st_select_lex_unit
*
master_unit
()
{
return
(
st_select_lex_unit
*
)
master
;
}
...
...
sql/sql_prepare.cc
View file @
2cf62000
...
...
@@ -448,7 +448,7 @@ static bool mysql_test_upd_fields(THD *thd, TABLE_LIST *table_list,
static
bool
mysql_test_select_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
List
<
Item
>
&
fields
,
List
<
Item
>
&
values
,
COND
*
conds
,
ORDER
*
order
,
ORDER
*
group
,
Item
*
having
,
thr_lock_type
lock_type
)
Item
*
having
,
thr_lock_type
lock_type
)
{
TABLE
*
table
;
bool
hidden_group_fields
;
...
...
@@ -470,7 +470,7 @@ static bool mysql_test_select_fields(THD *thd, TABLE_LIST *tables,
{
thd
->
where
=
"having clause"
;
thd
->
allow_sum_func
=
1
;
if
(
having
->
fix_fields
(
thd
,
tables
)
||
thd
->
fatal_error
)
if
(
having
->
fix_fields
(
thd
,
tables
,
&
having
)
||
thd
->
fatal_error
)
DBUG_RETURN
(
1
);
if
(
having
->
with_sum_func
)
having
->
split_sum_func
(
all_fields
);
...
...
sql/sql_select.cc
View file @
2cf62000
...
...
@@ -227,10 +227,9 @@ JOIN::prepare(TABLE_LIST *tables_init,
{
thd
->
where
=
"having clause"
;
thd
->
allow_sum_func
=
1
;
bool
having_fix_field_store
=
thd
->
having_fix_field
;
thd
->
having_fix_field
=
1
;
bool
having_fix_rc
=
having
->
fix_fields
(
thd
,
tables_list
);
thd
->
having_fix_field
=
having_fix_field_store
;
select_lex
->
having_fix_field
=
1
;
bool
having_fix_rc
=
having
->
fix_fields
(
thd
,
tables_list
,
&
having
);
select_lex
->
having_fix_field
=
0
;
if
(
having_fix_rc
||
thd
->
fatal_error
)
DBUG_RETURN
(
-
1
);
/* purecov: inspected */
if
(
having
->
with_sum_func
)
...
...
@@ -349,7 +348,7 @@ JOIN::optimize()
}
else
if
((
conds
=
new
Item_cond_and
(
conds
,
having
)))
{
conds
->
fix_fields
(
thd
,
tables_list
);
conds
->
fix_fields
(
thd
,
tables_list
,
&
conds
);
conds
->
change_ref_to_fields
(
thd
,
tables_list
);
having
=
0
;
}
...
...
@@ -612,6 +611,15 @@ JOIN::reinit()
if
(
setup_tables
(
tables_list
))
DBUG_RETURN
(
1
);
// Reset of sum functions
first_record
=
0
;
if
(
sum_funcs
)
{
Item_sum
*
func
,
**
func_ptr
=
sum_funcs
;
while
((
func
=
*
(
func_ptr
++
)))
func
->
null_value
=
1
;
}
DBUG_RETURN
(
0
);
}
...
...
@@ -3381,7 +3389,7 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value)
21
))))
{
cond
=
new_cond
;
cond
->
fix_fields
(
thd
,
0
);
cond
->
fix_fields
(
thd
,
0
,
&
cond
);
}
thd
->
insert_id
(
0
);
// Clear for next request
}
...
...
@@ -3395,7 +3403,7 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value)
if
((
new_cond
=
new
Item_func_eq
(
args
[
0
],
new
Item_int
(
"0"
,
0
,
2
))))
{
cond
=
new_cond
;
cond
->
fix_fields
(
thd
,
0
);
cond
->
fix_fields
(
thd
,
0
,
&
cond
);
}
}
}
...
...
@@ -6429,7 +6437,7 @@ find_order_in_list(THD *thd,TABLE_LIST *tables,ORDER *order,List<Item> &fields,
return
0
;
}
order
->
in_field_list
=
0
;
if
((
*
order
->
item
)
->
fix_fields
(
thd
,
tables
)
||
thd
->
fatal_error
)
if
((
*
order
->
item
)
->
fix_fields
(
thd
,
tables
,
order
->
item
)
||
thd
->
fatal_error
)
return
1
;
// Wrong field
all_fields
.
push_front
(
*
order
->
item
);
// Add new field to field list
order
->
item
=
(
Item
**
)
all_fields
.
head_ref
();
...
...
@@ -6527,7 +6535,7 @@ setup_new_fields(THD *thd,TABLE_LIST *tables,List<Item> &fields,
else
{
thd
->
where
=
"procedure list"
;
if
((
*
new_field
->
item
)
->
fix_fields
(
thd
,
tables
))
if
((
*
new_field
->
item
)
->
fix_fields
(
thd
,
tables
,
new_field
->
item
))
DBUG_RETURN
(
1
);
/* purecov: inspected */
thd
->
where
=
0
;
all_fields
.
push_front
(
*
new_field
->
item
);
...
...
@@ -7092,7 +7100,7 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab)
Here we pass 0 as the first argument to fix_fields that don't need
to do any stack checking (This is already done in the initial fix_fields).
*/
cond
->
fix_fields
((
THD
*
)
0
,(
TABLE_LIST
*
)
0
);
cond
->
fix_fields
((
THD
*
)
0
,(
TABLE_LIST
*
)
0
,
(
Item
**
)
&
cond
);
if
(
join_tab
->
select
)
{
error
=
(
int
)
cond
->
add
(
join_tab
->
select
->
cond
);
...
...
sql/sql_yacc.yy
View file @
2cf62000
...
...
@@ -2973,7 +2973,7 @@ kill:
KILL_SYM expr
{
LEX *lex=Lex;
if ($2->fix_fields(lex->thd,
0
))
if ($2->fix_fields(lex->thd,
0, &$2
))
{
send_error(&lex->thd->net, ER_SET_CONSTANTS_ONLY);
YYABORT;
...
...
@@ -3469,7 +3469,8 @@ option_value:
| '@' ident_or_text equal expr
{
Item_func_set_user_var *item = new Item_func_set_user_var($2,$4);
if (item->fix_fields(current_thd,0) || item->update())
if (item->fix_fields(current_thd, 0, (Item**) &item) ||
item->update())
{
send_error(¤t_thd->net, ER_SET_CONSTANTS_ONLY);
YYABORT;
...
...
@@ -3501,7 +3502,7 @@ option_value:
{
THD *thd=current_thd;
Item *item= $3;
if (item->fix_fields(current_thd,
0
))
if (item->fix_fields(current_thd,
0, &item
))
{
send_error(&thd->net, ER_SET_CONSTANTS_ONLY);
YYABORT;
...
...
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