Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
1575f623
Commit
1575f623
authored
Nov 05, 2002
by
bell@sanja.is.com.ua
Browse files
Options
Browse Files
Download
Plain Diff
IN subselect erged with current 4.1 (pointer conversion)
parents
ded512d5
ee9b1b6e
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
276 additions
and
18 deletions
+276
-18
mysql-test/r/subselect.result
mysql-test/r/subselect.result
+22
-0
mysql-test/t/subselect.test
mysql-test/t/subselect.test
+11
-0
sql/item.cc
sql/item.cc
+47
-0
sql/item.h
sql/item.h
+47
-0
sql/item_subselect.cc
sql/item_subselect.cc
+83
-6
sql/item_subselect.h
sql/item_subselect.h
+18
-3
sql/item_sum.cc
sql/item_sum.cc
+5
-2
sql/item_sum.h
sql/item_sum.h
+8
-3
sql/sql_lex.cc
sql/sql_lex.cc
+1
-0
sql/sql_lex.h
sql/sql_lex.h
+1
-0
sql/sql_yacc.yy
sql/sql_yacc.yy
+33
-4
No files found.
mysql-test/r/subselect.result
View file @
1575f623
...
...
@@ -99,6 +99,17 @@ select * from t3 where not exists (select * from t2 where t2.b=t3.a);
a
6
3
select * from t3 where a in (select b from t2);
a
7
select * from t3 where a not in (select b from t2);
a
6
3
select * from t3 where a in (select a,b from t2);
Subselect returns more than 1 field
select * from t3 where a in (select * from t2);
Subselect returns more than 1 field
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);
...
...
@@ -219,4 +230,15 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY searchconthardwarefr3 index NULL topic 3 NULL 2 Using index
2 SUBSELECT No tables used
3 UNION No tables used
SELECT 1 IN (SELECT 1 FROM searchconthardwarefr3 HAVING a);
Unknown column 'a' in 'having clause'
SELECT * from searchconthardwarefr3 where topic IN (SELECT topic FROM searchconthardwarefr3 GROUP BY date);
topic date pseudo
40143 2002-08-03 joce
43506 2002-10-02 joce
SELECT * from searchconthardwarefr3 where topic IN (SELECT topic FROM searchconthardwarefr3 GROUP BY date HAVING topic < 4100);
topic date pseudo
43506 2002-10-02 joce
SELECT * from searchconthardwarefr3 where topic IN (SELECT SUM(topic) FROM searchconthardwarefr3);
topic date pseudo
drop table searchconthardwarefr3;
mysql-test/t/subselect.test
View file @
1575f623
...
...
@@ -34,6 +34,12 @@ select b,(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2
explain
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
);
select
*
from
t3
where
a
in
(
select
b
from
t2
);
select
*
from
t3
where
a
not
in
(
select
b
from
t2
);
--
error
1239
select
*
from
t3
where
a
in
(
select
a
,
b
from
t2
);
--
error
1239
select
*
from
t3
where
a
in
(
select
*
from
t2
);
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
);
...
...
@@ -114,4 +120,9 @@ SELECT 1 FROM searchconthardwarefr3 WHERE 1=(SELECT 1 UNION SELECT 1) UNION ALL
--
error
1240
SELECT
1
FROM
searchconthardwarefr3
WHERE
1
=
(
SELECT
1
UNION
ALL
SELECT
1
)
UNION
SELECT
1
;
EXPLAIN
SELECT
1
FROM
searchconthardwarefr3
WHERE
1
=
(
SELECT
1
UNION
SELECT
1
);
--
error
1054
SELECT
1
IN
(
SELECT
1
FROM
searchconthardwarefr3
HAVING
a
);
SELECT
*
from
searchconthardwarefr3
where
topic
IN
(
SELECT
topic
FROM
searchconthardwarefr3
GROUP
BY
date
);
SELECT
*
from
searchconthardwarefr3
where
topic
IN
(
SELECT
topic
FROM
searchconthardwarefr3
GROUP
BY
date
HAVING
topic
<
4100
);
SELECT
*
from
searchconthardwarefr3
where
topic
IN
(
SELECT
SUM
(
topic
)
FROM
searchconthardwarefr3
);
drop
table
searchconthardwarefr3
;
\ No newline at end of file
sql/item.cc
View file @
1575f623
...
...
@@ -424,6 +424,53 @@ bool Item::fix_fields(THD *thd,
return
0
;
}
bool
Item_outer_select_context_saver
::
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
list
,
Item
**
ref
)
{
DBUG_ENTER
(
"Item_outer_select_context_saver::fix_fields"
);
bool
res
=
item
->
fix_fields
(
thd
,
0
,
// do not show current subselect fields
&
item
);
*
ref
=
item
;
DBUG_RETURN
(
res
);
}
bool
Item_asterisk_remover
::
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
list
,
Item
**
ref
)
{
DBUG_ENTER
(
"Item_asterisk_remover::fix_fields"
);
bool
res
;
if
(
item
)
if
(
item
->
type
()
==
Item
::
FIELD_ITEM
&&
((
Item_field
*
)
item
)
->
field_name
[
0
]
==
'*'
)
{
List
<
Item
>
fields
;
fields
.
push_back
(
item
);
List_iterator
<
Item
>
it
(
fields
);
it
++
;
uint
elem
=
fields
.
elements
;
if
(
insert_fields
(
thd
,
list
,
((
Item_field
*
)
item
)
->
db_name
,
((
Item_field
*
)
item
)
->
table_name
,
&
it
))
res
=
-
1
;
else
if
(
fields
.
elements
>
1
)
{
my_message
(
ER_SUBSELECT_NO_1_COL
,
ER
(
ER_SUBSELECT_NO_1_COL
),
MYF
(
0
));
res
=
-
1
;
}
}
else
res
=
item
->
fix_fields
(
thd
,
list
,
&
item
);
else
res
=
-
1
;
*
ref
=
item
;
DBUG_RETURN
(
res
);
}
bool
Item_field
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
{
if
(
!
field
)
// If field is not checked
...
...
sql/item.h
View file @
1575f623
...
...
@@ -90,6 +90,53 @@ public:
};
/*
Wrapper base class
*/
class
Item_wrapper
:
public
Item
{
protected:
Item
*
item
;
public:
/*
Following methods should not be used, because fix_fields exclude this
item (it assign '*ref' with field 'item' in derived classes)
*/
enum
Type
type
()
const
{
return
item
->
type
();
}
double
val
()
{
return
item
->
val
();
}
longlong
val_int
()
{
return
item
->
val_int
();
}
String
*
val_str
(
String
*
s
)
{
return
item
->
val_str
(
s
);
}
void
make_field
(
Send_field
*
f
)
{
item
->
make_field
(
f
);
}
};
/*
Save context of name resolution for Item, used in subselect transformer.
*/
class
Item_outer_select_context_saver
:
public
Item_wrapper
{
public:
Item_outer_select_context_saver
(
Item
*
i
)
{
item
=
i
;
}
bool
fix_fields
(
THD
*
,
struct
st_table_list
*
,
Item
**
ref
);
};
/*
To resolve '*' field moved to condition
*/
class
Item_asterisk_remover
:
public
Item_wrapper
{
public:
Item_asterisk_remover
(
Item
*
i
)
{
item
=
i
;
}
bool
fix_fields
(
THD
*
,
struct
st_table_list
*
,
Item
**
ref
);
};
class
st_select_lex
;
class
Item_ident
:
public
Item
{
...
...
sql/item_subselect.cc
View file @
1575f623
...
...
@@ -44,12 +44,13 @@ Item_subselect::Item_subselect():
}
void
Item_subselect
::
init
(
THD
*
thd
,
st_select_lex
*
select_lex
,
select_subselect
*
result
)
select_subselect
*
result
,
Item
*
left_expr
)
{
DBUG_ENTER
(
"Item_subselect::init"
);
DBUG_PRINT
(
"subs"
,
(
"select_lex 0x%xl"
,
(
long
)
select_lex
));
DBUG_PRINT
(
"subs"
,
(
"select_lex 0x%xl"
,
(
u
long
)
select_lex
));
select_transformer
(
select_lex
,
left_expr
);
if
(
select_lex
->
next_select
())
engine
=
new
subselect_union_engine
(
thd
,
select_lex
->
master_unit
(),
result
,
this
);
...
...
@@ -65,6 +66,14 @@ Item_subselect::~Item_subselect()
delete
engine
;
}
void
Item_subselect
::
select_transformer
(
st_select_lex
*
select_lex
,
Item
*
left_expr
)
{
DBUG_ENTER
(
"Item_subselect::select_transformer"
);
DBUG_VOID_RETURN
;
}
void
Item_subselect
::
make_field
(
Send_field
*
tmp_field
)
{
if
(
null_value
)
...
...
@@ -109,9 +118,11 @@ Item_singleval_subselect::Item_singleval_subselect(THD *thd,
st_select_lex
*
select_lex
)
:
Item_subselect
()
{
init
(
thd
,
select_lex
,
new
select_singleval_subselect
(
this
));
DBUG_ENTER
(
"Item_singleval_subselect::Item_singleval_subselect"
);
init
(
thd
,
select_lex
,
new
select_singleval_subselect
(
this
),
0
);
max_columns
=
1
;
maybe_null
=
1
;
DBUG_VOID_RETURN
;
}
void
Item_singleval_subselect
::
fix_length_and_dec
()
...
...
@@ -156,17 +167,37 @@ String *Item_singleval_subselect::val_str (String *str)
}
Item_exists_subselect
::
Item_exists_subselect
(
THD
*
thd
,
st_select_lex
*
select_lex
)
:
st_select_lex
*
select_lex
,
Item
*
left_expr
)
:
Item_subselect
()
{
init
(
thd
,
select_lex
,
new
select_exists_subselect
(
this
));
DBUG_ENTER
(
"Item_exists_subselect::Item_exists_subselect"
);
init
(
thd
,
select_lex
,
new
select_exists_subselect
(
this
),
left_expr
);
max_columns
=
UINT_MAX
;
null_value
=
0
;
//can't be NULL
maybe_null
=
0
;
//can't be NULL
value
=
0
;
select_lex
->
select_limit
=
1
;
// we need only 1 row to determinate existence
// We need only 1 row to determinate existence
select_lex
->
master_unit
()
->
global_parameters
->
select_limit
=
1
;
DBUG_VOID_RETURN
;
}
Item_in_subselect
::
Item_in_subselect
(
THD
*
thd
,
Item
*
left_expr
,
st_select_lex
*
select_lex
)
:
Item_exists_subselect
()
{
DBUG_ENTER
(
"Item_in_subselect::Item_in_subselect"
);
init
(
thd
,
select_lex
,
new
select_exists_subselect
(
this
),
left_expr
);
max_columns
=
UINT_MAX
;
null_value
=
0
;
//can't be NULL
maybe_null
=
0
;
//can't be NULL
value
=
0
;
// We need only 1 row to determinate existence
select_lex
->
master_unit
()
->
global_parameters
->
select_limit
=
1
;
DBUG_VOID_RETURN
;
}
void
Item_exists_subselect
::
fix_length_and_dec
()
{
max_length
=
1
;
...
...
@@ -204,6 +235,52 @@ String *Item_exists_subselect::val_str(String *str)
return
str
;
}
Item_in_subselect
::
Item_in_subselect
(
Item_in_subselect
*
item
)
:
Item_exists_subselect
(
item
)
{
}
void
Item_in_subselect
::
select_transformer
(
st_select_lex
*
select_lex
,
Item
*
left_expr
)
{
DBUG_ENTER
(
"Item_in_subselect::select_transformer"
);
for
(
SELECT_LEX
*
sl
=
select_lex
;
sl
;
sl
=
sl
->
next_select
())
{
Item
*
item
;
if
(
sl
->
item_list
.
elements
>
1
)
{
my_message
(
ER_SUBSELECT_NO_1_COL
,
ER
(
ER_SUBSELECT_NO_1_COL
),
MYF
(
0
));
item
=
0
;
// Item_asterisk_remover mast fail
}
else
item
=
(
Item
*
)
sl
->
item_list
.
pop
();
left_expr
=
new
Item_outer_select_context_saver
(
left_expr
);
if
(
sl
->
having
||
sl
->
with_sum_func
||
sl
->
group_list
.
first
)
{
sl
->
item_list
.
push_back
(
item
);
item
=
new
Item_ref
(
sl
->
item_list
.
head_ref
(),
0
,
"<result>"
);
if
(
sl
->
having
)
sl
->
having
=
new
Item_cond_and
(
sl
->
having
,
new
Item_func_eq
(
item
,
left_expr
));
else
sl
->
having
=
new
Item_func_eq
(
item
,
left_expr
);
}
else
{
sl
->
item_list
.
empty
();
sl
->
item_list
.
push_back
(
new
Item_int
(
1
));
item
=
new
Item_asterisk_remover
(
item
);
if
(
sl
->
where
)
sl
->
where
=
new
Item_cond_and
(
sl
->
where
,
new
Item_func_eq
(
item
,
left_expr
));
else
sl
->
where
=
new
Item_func_eq
(
item
,
left_expr
);
}
}
DBUG_VOID_RETURN
;
}
subselect_single_select_engine
::
subselect_single_select_engine
(
THD
*
thd
,
st_select_lex
*
select
,
...
...
sql/item_subselect.h
View file @
1575f623
...
...
@@ -55,13 +55,16 @@ public:
pointer in constructor initialization list, but we need pass pointer
to subselect Item class to select_subselect classes constructor.
*/
void
init
(
THD
*
thd
,
st_select_lex
*
select_lex
,
select_subselect
*
result
);
virtual
void
init
(
THD
*
thd
,
st_select_lex
*
select_lex
,
select_subselect
*
result
,
Item
*
left_expr
=
0
);
~
Item_subselect
();
virtual
void
assign_null
()
{
null_value
=
1
;
}
virtual
void
select_transformer
(
st_select_lex
*
select_lex
,
Item
*
left_expr
);
bool
assigned
()
{
return
value_assigned
;
}
void
assigned
(
bool
a
)
{
value_assigned
=
a
;
}
enum
Type
type
()
const
;
...
...
@@ -74,7 +77,6 @@ public:
friend
class
select_subselect
;
};
/* single value subselect */
class
Item_singleval_subselect
:
public
Item_subselect
...
...
@@ -127,12 +129,15 @@ protected:
longlong
value
;
/* value of this item (boolean: exists/not-exists) */
public:
Item_exists_subselect
(
THD
*
thd
,
st_select_lex
*
select_lex
);
Item_exists_subselect
(
THD
*
thd
,
st_select_lex
*
select_lex
,
Item
*
left_expr
=
0
);
Item_exists_subselect
(
Item_exists_subselect
*
item
)
:
Item_subselect
(
item
)
{
value
=
item
->
value
;
}
Item_exists_subselect
()
:
Item_subselect
()
{}
virtual
void
assign_null
()
{
value
=
0
;
...
...
@@ -147,6 +152,16 @@ public:
friend
class
select_exists_subselect
;
};
/* IN subselect */
class
Item_in_subselect
:
public
Item_exists_subselect
{
public:
Item_in_subselect
(
THD
*
thd
,
Item
*
left_expr
,
st_select_lex
*
select_lex
);
Item_in_subselect
(
Item_in_subselect
*
item
);
virtual
void
select_transformer
(
st_select_lex
*
select_lex
,
Item
*
left_exp
);
};
class
subselect_engine
{
protected:
...
...
sql/item_sum.cc
View file @
1575f623
...
...
@@ -23,7 +23,6 @@
#include "mysql_priv.h"
Item_sum
::
Item_sum
(
List
<
Item
>
&
list
)
{
arg_count
=
list
.
elements
;
...
...
@@ -38,10 +37,14 @@ Item_sum::Item_sum(List<Item> &list)
args
[
i
++
]
=
item
;
}
}
with_sum_func
=
1
;
mark_as_sum_func
()
;
list
.
empty
();
// Fields are used
}
void
Item_sum
::
mark_as_sum_func
()
{
current_thd
->
lex
.
select
->
with_sum_func
=
with_sum_func
=
1
;
}
void
Item_sum
::
make_field
(
Send_field
*
tmp_field
)
{
...
...
sql/item_sum.h
View file @
1575f623
...
...
@@ -34,23 +34,28 @@ public:
uint
arg_count
;
bool
quick_group
;
/* If incremental update of fields */
Item_sum
()
:
arg_count
(
0
),
quick_group
(
1
)
{
with_sum_func
=
1
;
}
Item_sum
()
:
arg_count
(
0
),
quick_group
(
1
)
{
mark_as_sum_func
();
}
Item_sum
(
Item
*
a
)
:
quick_group
(
1
)
{
arg_count
=
1
;
args
=
tmp_args
;
args
[
0
]
=
a
;
with_sum_func
=
1
;
mark_as_sum_func
()
;
}
Item_sum
(
Item
*
a
,
Item
*
b
)
:
quick_group
(
1
)
{
arg_count
=
2
;
args
=
tmp_args
;
args
[
0
]
=
a
;
args
[
1
]
=
b
;
with_sum_func
=
1
;
mark_as_sum_func
()
;
}
Item_sum
(
List
<
Item
>
&
list
);
~
Item_sum
()
{
result_field
=
0
;
}
inline
void
mark_as_sum_func
();
enum
Type
type
()
const
{
return
SUM_FUNC_ITEM
;
}
virtual
enum
Sumfunctype
sum_func
()
const
=
0
;
virtual
void
reset
()
=
0
;
...
...
sql/sql_lex.cc
View file @
1575f623
...
...
@@ -936,6 +936,7 @@ void st_select_lex_node::init_select()
order_list
.
next
=
(
byte
**
)
&
order_list
.
first
;
select_limit
=
HA_POS_ERROR
;
offset_limit
=
0
;
with_sum_func
=
0
;
create_refs
=
dependent
=
0
;
}
...
...
sql/sql_lex.h
View file @
1575f623
...
...
@@ -200,6 +200,7 @@ public:
List
<
List_item
>
expr_list
;
List
<
List_item
>
when_list
;
/* WHEN clause (expression) */
ha_rows
select_limit
,
offset_limit
;
/* LIMIT clause parameters */
bool
with_sum_func
;
bool
create_refs
;
bool
dependent
;
/* dependent from outer select subselect */
...
...
sql/sql_yacc.yy
View file @
1575f623
...
...
@@ -70,6 +70,7 @@ inline Item *or_or_concat(Item* A, Item* B)
enum Item_udftype udf_type;
CHARSET_INFO *charset;
interval_type interval;
st_select_lex *select_lex;
}
%{
...
...
@@ -530,7 +531,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%type <lex_str>
IDENT TEXT_STRING REAL_NUM FLOAT_NUM NUM LONG_NUM HEX_NUM LEX_HOSTNAME
ULONGLONG_NUM field_ident select_alias ident ident_or_text UNDERSCORE_CHARSET
ULONGLONG_NUM field_ident select_alias ident ident_or_text
UNDERSCORE_CHARSET
%type <lex_str_ptr>
opt_table_alias
...
...
@@ -612,6 +614,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%type <variable> internal_variable_name
%type <select_lex> in_subselect in_subselect_init
%type <NONE>
query verb_clause create change select do drop insert replace insert2
insert_values update delete truncate rename
...
...
@@ -1721,10 +1725,16 @@ expr: expr_expr { $$= $1; }
/* expressions that begin with 'expr' */
expr_expr:
expr IN_SYM '(' expr_list ')'
expr IN_SYM '(' expr_list ')'
{ $$= new Item_func_in($1,*$4); }
| expr NOT IN_SYM '(' expr_list ')'
{ $$= new Item_func_not(new Item_func_in($1,*$5)); }
| expr IN_SYM in_subselect
{ $$= new Item_in_subselect(current_thd, $1, $3); }
| expr NOT IN_SYM in_subselect
{
$$= new Item_func_not(new Item_in_subselect(current_thd, $1, $4));
}
| expr BETWEEN_SYM no_and_expr AND expr
{ $$= new Item_func_between($1,$3,$5); }
| expr NOT BETWEEN_SYM no_and_expr AND expr
...
...
@@ -1804,10 +1814,16 @@ no_in_expr:
/* expressions that begin with 'expr' that does NOT follow AND */
no_and_expr:
no_and_expr IN_SYM '(' expr_list ')'
{ $$= new Item_func_in($1,*$4); }
no_and_expr IN_SYM '(' expr_list ')'
{ $$= new Item_func_in($1,*$4); }
| no_and_expr NOT IN_SYM '(' expr_list ')'
{ $$= new Item_func_not(new Item_func_in($1,*$5)); }
| no_and_expr IN_SYM in_subselect
{ $$= new Item_in_subselect(current_thd, $1, $3); }
| no_and_expr NOT IN_SYM in_subselect
{
$$= new Item_func_not(new Item_in_subselect(current_thd, $1, $4));
}
| no_and_expr BETWEEN_SYM no_and_expr AND expr
{ $$= new Item_func_between($1,$3,$5); }
| no_and_expr NOT BETWEEN_SYM no_and_expr AND expr
...
...
@@ -4232,6 +4248,19 @@ exists_subselect_init:
first_select());
};
in_subselect:
subselect_start in_subselect_init
subselect_end
{
$$= $2;
};
in_subselect_init:
select_init
{
$$= Lex->select->master_unit()->first_select();
};
subselect_start:
'('
{
...
...
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