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
35faf872
Commit
35faf872
authored
May 26, 2002
by
bell@sanja.is.com.ua
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
added depended subselect processing
parent
17e839d4
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
109 additions
and
17 deletions
+109
-17
mysql-test/r/subselect.result
mysql-test/r/subselect.result
+8
-0
mysql-test/t/subselect.test
mysql-test/t/subselect.test
+2
-0
sql/item.cc
sql/item.cc
+28
-1
sql/item_subselect.cc
sql/item_subselect.cc
+21
-7
sql/item_subselect.h
sql/item_subselect.h
+4
-1
sql/sql_lex.cc
sql/sql_lex.cc
+1
-0
sql/sql_lex.h
sql/sql_lex.h
+7
-1
sql/sql_select.cc
sql/sql_select.cc
+35
-7
sql/sql_select.h
sql/sql_select.h
+3
-0
No files found.
mysql-test/r/subselect.result
View file @
35faf872
...
...
@@ -6,6 +6,14 @@ create table t4 (a int, b int);
insert into t1 values (2);
insert into t2 values (1,7),(2,7);
insert into t4 values (4,8),(3,8),(5,9);
select (select a from t1 where t1.a=t2.a), a from t2;
(select a from t1 where t1.a=t2.a) a
NULL 1
2 2
select (select a from t1 where t1.a=t2.b), a from t2;
(select a from t1 where t1.a=t2.b) a
NULL 1
NULL 2
select (select a from t1), a from t2;
(select a from t1) a
2 1
...
...
mysql-test/t/subselect.test
View file @
35faf872
...
...
@@ -8,6 +8,8 @@ create table t4 (a int, b int);
insert
into
t1
values
(
2
);
insert
into
t2
values
(
1
,
7
),(
2
,
7
);
insert
into
t4
values
(
4
,
8
),(
3
,
8
),(
5
,
9
);
select
(
select
a
from
t1
where
t1
.
a
=
t2
.
a
),
a
from
t2
;
select
(
select
a
from
t1
where
t1
.
a
=
t2
.
b
),
a
from
t2
;
select
(
select
a
from
t1
),
a
from
t2
;
select
(
select
a
from
t3
),
a
from
t2
;
select
*
from
t2
where
t2
.
a
=
(
select
a
from
t1
);
...
...
sql/item.cc
View file @
35faf872
...
...
@@ -320,7 +320,34 @@ bool Item_field::fix_fields(THD *thd,TABLE_LIST *tables)
{
Field
*
tmp
;
if
(
!
(
tmp
=
find_field_in_tables
(
thd
,
this
,
tables
)))
return
1
;
{
/*
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.
*/
for
(
SELECT_LEX
*
sl
=
thd
->
lex
.
select
->
outer_select
();
sl
&&
!
tmp
;
sl
=
sl
->
outer_select
())
tmp
=
find_field_in_tables
(
thd
,
this
,
(
TABLE_LIST
*
)
sl
->
table_list
.
first
);
if
(
!
tmp
)
return
1
;
else
if
(
!
thd
->
lex
.
select
->
depended
)
{
thd
->
lex
.
select
->
depended
=
1
;
//Select is depended of outer select(s)
//Tables will be reopened many times
for
(
TABLE_LIST
*
tbl
=
(
TABLE_LIST
*
)
thd
->
lex
.
select
->
table_list
.
first
;
tbl
;
tbl
=
tbl
->
next
)
tbl
->
shared
=
1
;
}
}
set_field
(
tmp
);
}
else
if
(
thd
&&
thd
->
set_query_id
&&
field
->
query_id
!=
thd
->
query_id
)
...
...
sql/item_subselect.cc
View file @
35faf872
...
...
@@ -36,7 +36,7 @@ SUBSELECT TODO:
#include "sql_select.h"
Item_subselect
::
Item_subselect
(
THD
*
thd
,
st_select_lex
*
select_lex
)
:
executed
(
0
)
executed
(
0
)
,
optimized
(
0
),
error
(
0
)
{
DBUG_ENTER
(
"Item_subselect::Item_subselect"
);
DBUG_PRINT
(
"subs"
,
(
"select_lex 0x%xl"
,
(
long
)
select_lex
));
...
...
@@ -48,7 +48,7 @@ Item_subselect::Item_subselect(THD *thd, st_select_lex *select_lex):
item value is NULL if select_subselect not changed this value
(i.e. some rows will be found returned)
*/
assign_null
();
assign_null
();
DBUG_VOID_RETURN
;
}
...
...
@@ -110,17 +110,31 @@ bool Item_subselect::fix_fields(THD *thd,TABLE_LIST *tables)
(
ORDER
*
)
0
,
select_lex
,
(
SELECT_LEX_UNIT
*
)
select_lex
->
master
))
return
1
;
if
(
join
->
optimize
())
{
executed
=
1
;
return
1
;
}
thd
->
lex
.
select
=
save_select
;
return
0
;
}
int
Item_subselect
::
exec
()
{
if
(
!
optimized
)
{
optimized
=
1
;
if
(
join
->
optimize
())
{
executed
=
1
;
return
(
join
->
error
?
join
->
error
:
1
);
}
}
if
(
join
->
select_lex
->
depended
&&
executed
)
{
if
(
join
->
reinit
())
{
error
=
1
;
return
1
;
}
assign_null
();
executed
=
0
;
}
if
(
!
executed
)
{
SELECT_LEX
*
save_select
=
join
->
thd
->
lex
.
select
;
...
...
sql/item_subselect.h
View file @
35faf872
...
...
@@ -29,9 +29,11 @@ class select_subselect;
class
Item_subselect
:
public
Item
{
protected:
my_bool
executed
;
/* simple subselect is executed */
longlong
int_value
;
double
real_value
;
my_bool
executed
;
/* simple subselect is executed */
my_bool
optimized
;
/* simple subselect is optimized */
my_bool
error
;
/* error in query */
enum
Item_result
res_type
;
int
exec
();
...
...
@@ -62,6 +64,7 @@ class Item_subselect :public Item
join
=
item
->
join
;
result
=
item
->
result
;
name
=
item
->
name
;
error
=
item
->
error
;
}
enum
Type
type
()
const
;
double
val
();
...
...
sql/sql_lex.cc
View file @
35faf872
...
...
@@ -931,6 +931,7 @@ void st_select_lex::init_select()
use_index
.
empty
();
ftfunc_list
.
empty
();
linkage
=
UNSPECIFIED_TYPE
;
depended
=
0
;
}
/*
...
...
sql/sql_lex.h
View file @
35faf872
...
...
@@ -208,6 +208,7 @@ struct st_select_lex_node {
SELECT_LEXs
*/
struct
st_lex
;
struct
st_select_lex
;
struct
st_select_lex_unit
:
public
st_select_lex_node
{
/*
Pointer to 'last' select or pointer to unit where stored
...
...
@@ -218,6 +219,8 @@ struct st_select_lex_unit: public st_select_lex_node {
ha_rows
select_limit_cnt
,
offset_limit_cnt
;
void
init_query
();
bool
create_total_list
(
THD
*
thd
,
st_lex
*
lex
,
TABLE_LIST
**
result
);
st_select_lex
*
first_select
()
{
return
(
st_select_lex
*
)
slave
;
}
st_select_lex_unit
*
next_unit
()
{
return
(
st_select_lex_unit
*
)
next
;
}
private:
bool
create_total_list_n_last_return
(
THD
*
thd
,
st_lex
*
lex
,
TABLE_LIST
***
result
);
...
...
@@ -240,9 +243,12 @@ struct st_select_lex: public st_select_lex_node {
List
<
Item_func_match
>
ftfunc_list
;
uint
in_sum_expr
,
sort_default
;
bool
create_refs
,
braces
;
/* SELECT ... UNION (SELECT ... ) <- this braces */
braces
,
/* SELECT ... UNION (SELECT ... ) <- this braces */
depended
;
/* depended from outer select subselect */
void
init_query
();
void
init_select
();
st_select_lex
*
outer_select
()
{
return
(
st_select_lex
*
)
master
->
master
;
}
st_select_lex
*
next_select
()
{
return
(
st_select_lex
*
)
next
;
}
};
typedef
struct
st_select_lex
SELECT_LEX
;
...
...
sql/sql_select.cc
View file @
35faf872
...
...
@@ -213,7 +213,8 @@ JOIN::prepare(TABLE_LIST *tables_init,
proc_param
=
proc_param_init
;
tables_list
=
tables_init
;
select_lex
=
select
;
union_part
=
(
unit
->
first_select
()
->
next_select
()
!=
0
);
/* Check that all tables, fields, conds and order are ok */
if
(
setup_tables
(
tables_list
)
||
...
...
@@ -334,7 +335,6 @@ int
JOIN
::
optimize
()
{
DBUG_ENTER
(
"JOIN::optimize"
);
SELECT_LEX
*
select_lex
=
&
(
thd
->
lex
.
select_lex
);
#ifdef HAVE_REF_TO_FIELDS // Not done yet
/* Add HAVING to WHERE if possible */
...
...
@@ -380,7 +380,7 @@ JOIN::optimize()
}
if
(
select_options
&
SELECT_DESCRIBE
)
{
if
(
select_lex
->
nex
t
)
if
(
union_par
t
)
select_describe
(
this
,
false
,
false
,
false
,
"Select tables optimized away"
);
else
...
...
@@ -406,6 +406,17 @@ JOIN::optimize()
if
(
make_join_statistics
(
this
,
tables_list
,
conds
,
&
keyuse
)
||
thd
->
fatal_error
)
DBUG_RETURN
(
-
1
);
if
(
select_lex
->
depended
)
{
/*
Just remove all const-table optimization in case of depended query
TODO: optimize
*/
const_table_map
=
0
;
const_tables
=
0
;
found_const_table_map
=
0
;
}
thd
->
proc_info
=
"preparing"
;
result
->
initialize_tables
(
this
);
if
(
const_table_map
!=
found_const_table_map
&&
...
...
@@ -576,7 +587,7 @@ JOIN::optimize()
}
/*
global uptimis
ation (with subselect) must be here (TODO)
Global optimiz
ation (with subselect) must be here (TODO)
*/
int
...
...
@@ -585,8 +596,25 @@ JOIN::global_optimize()
return
0
;
}
int
JOIN
::
reinit
()
{
DBUG_ENTER
(
"JOIN::reinit"
);
//TODO move to unit reinit
unit
->
offset_limit_cnt
=
select_lex
->
offset_limit
;
unit
->
select_limit_cnt
=
select_lex
->
select_limit
+
select_lex
->
offset_limit
;
if
(
unit
->
select_limit_cnt
<
select_lex
->
select_limit
)
unit
->
select_limit_cnt
=
HA_POS_ERROR
;
// no limit
if
(
unit
->
select_limit_cnt
==
HA_POS_ERROR
)
select_lex
->
options
&=
~
OPTION_FOUND_ROWS
;
if
(
setup_tables
(
tables_list
))
DBUG_RETURN
(
1
);
DBUG_RETURN
(
0
);
}
/*
e
xec select
E
xec select
*/
void
JOIN
::
exec
()
...
...
@@ -600,7 +628,7 @@ JOIN::exec()
error
=
0
;
if
(
select_options
&
SELECT_DESCRIBE
)
{
if
(
select_lex
->
nex
t
)
if
(
union_par
t
)
select_describe
(
this
,
false
,
false
,
false
,
"No tables used"
);
else
describe_info
(
thd
,
"No tables used"
);
...
...
@@ -627,7 +655,7 @@ JOIN::exec()
if
(
zero_result_cause
)
{
if
(
select_options
&
SELECT_DESCRIBE
&&
select_lex
->
nex
t
)
if
(
select_options
&
SELECT_DESCRIBE
&&
union_par
t
)
select_describe
(
this
,
false
,
false
,
false
,
zero_result_cause
);
else
error
=
return_zero_rows
(
result
,
tables_list
,
fields_list
,
...
...
sql/sql_select.h
View file @
35faf872
...
...
@@ -196,6 +196,8 @@ class JOIN :public Sql_alloc{
my_bool
test_function_query
;
// need to return select items 1 row
const
char
*
zero_result_cause
;
// not 0 if exec must return zero result
my_bool
union_part
;
// this subselect is part of union
JOIN
(
THD
*
thd
,
List
<
Item
>
&
fields
,
ulong
select_options
,
select_result
*
result
)
:
...
...
@@ -236,6 +238,7 @@ class JOIN :public Sql_alloc{
ORDER
*
proc_param
,
SELECT_LEX
*
select
,
SELECT_LEX_UNIT
*
unit
);
int
optimize
();
int
global_optimize
();
int
reinit
();
void
exec
();
int
cleanup
(
THD
*
thd
);
};
...
...
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