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
494184ff
Commit
494184ff
authored
May 07, 2002
by
bell@sanja.is.com.ua
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
new SELECT_LEX structure
parent
06ed215c
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
372 additions
and
111 deletions
+372
-111
mysql-test/r/derived.result
mysql-test/r/derived.result
+8
-2
mysql-test/t/derived.test
mysql-test/t/derived.test
+5
-2
sql/mysql_priv.h
sql/mysql_priv.h
+3
-3
sql/sql_class.h
sql/sql_class.h
+15
-6
sql/sql_derived.cc
sql/sql_derived.cc
+11
-8
sql/sql_lex.cc
sql/sql_lex.cc
+115
-0
sql/sql_lex.h
sql/sql_lex.h
+133
-16
sql/sql_parse.cc
sql/sql_parse.cc
+45
-43
sql/sql_union.cc
sql/sql_union.cc
+16
-12
sql/sql_yacc.yy
sql/sql_yacc.yy
+13
-11
sql/table.h
sql/table.h
+8
-8
No files found.
mysql-test/r/derived.result
View file @
494184ff
drop table if exists t1,t2;
drop table if exists t1,t2
,t3
;
CREATE TABLE t1 (a int not null, b char (10) not null);
insert into t1 values(1,'a'),(2,'b'),(3,'c'),(3,'c');
CREATE TABLE t2 (a int not null, b char (10) not null);
...
...
@@ -7,4 +7,10 @@ select t1.a,t3.y from t1,(select a as y from t2 where b='c') as t3 where t1.a
a y
3 3
3 3
drop table if exists t1.t2;
CREATE TABLE t3 (a int not null, b char (10) not null);
insert into t3 values (3,'f'),(4,'y'),(5,'z'),(6,'c');
select t1.a,t4.y from t1,(select t2.a as y from t2,(select t3.b from t3 where t3.a>3) as t5 where t2.b=t5.b) as t4 where t1.a = t4.y;
a y
3 3
3 3
drop table if exists t1.t2,t3;
mysql-test/t/derived.test
View file @
494184ff
drop
table
if
exists
t1
,
t2
;
drop
table
if
exists
t1
,
t2
,
t3
;
CREATE
TABLE
t1
(
a
int
not
null
,
b
char
(
10
)
not
null
);
insert
into
t1
values
(
1
,
'a'
),(
2
,
'b'
),(
3
,
'c'
),(
3
,
'c'
);
CREATE
TABLE
t2
(
a
int
not
null
,
b
char
(
10
)
not
null
);
insert
into
t2
values
(
3
,
'c'
),(
4
,
'd'
),(
5
,
'f'
),(
6
,
'e'
);
select
t1
.
a
,
t3
.
y
from
t1
,(
select
a
as
y
from
t2
where
b
=
'c'
)
as
t3
where
t1
.
a
=
t3
.
y
;
drop
table
if
exists
t1
.
t2
;
\ No newline at end of file
CREATE
TABLE
t3
(
a
int
not
null
,
b
char
(
10
)
not
null
);
insert
into
t3
values
(
3
,
'f'
),(
4
,
'y'
),(
5
,
'z'
),(
6
,
'c'
);
select
t1
.
a
,
t4
.
y
from
t1
,(
select
t2
.
a
as
y
from
t2
,(
select
t3
.
b
from
t3
where
t3
.
a
>
3
)
as
t5
where
t2
.
b
=
t5
.
b
)
as
t4
where
t1
.
a
=
t4
.
y
;
drop
table
if
exists
t1
.
t2
,
t3
;
sql/mysql_priv.h
View file @
494184ff
...
...
@@ -291,7 +291,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list);
bool
mysql_change_db
(
THD
*
thd
,
const
char
*
name
);
void
mysql_parse
(
THD
*
thd
,
char
*
inBuf
,
uint
length
);
void
mysql_init_select
(
LEX
*
lex
);
bool
mysql_new_select
(
LEX
*
lex
);
bool
mysql_new_select
(
LEX
*
lex
,
bool
move_down
);
void
mysql_init_multi_delete
(
LEX
*
lex
);
void
init_max_user_conn
(
void
);
void
free_max_user_conn
(
void
);
...
...
@@ -360,8 +360,8 @@ int handle_select(THD *thd, LEX *lex, select_result *result);
int
mysql_select
(
THD
*
thd
,
TABLE_LIST
*
tables
,
List
<
Item
>
&
list
,
COND
*
conds
,
ORDER
*
order
,
ORDER
*
group
,
Item
*
having
,
ORDER
*
proc_param
,
ulong
select_type
,
select_result
*
result
);
int
mysql_union
(
THD
*
thd
,
LEX
*
lex
,
select_result
*
result
);
int
mysql_derived
(
THD
*
thd
,
LEX
*
lex
,
SELECT_LEX
*
s
,
TABLE_LIST
*
t
);
int
mysql_union
(
THD
*
thd
,
LEX
*
lex
,
select_result
*
result
);
int
mysql_derived
(
THD
*
thd
,
LEX
*
lex
,
SELECT_LEX_UNIT
*
s
,
TABLE_LIST
*
t
);
Field
*
create_tmp_field
(
THD
*
thd
,
TABLE
*
table
,
Item
*
item
,
Item
::
Type
type
,
Item_result_field
***
copy_func
,
Field
**
from_field
,
bool
group
,
bool
modify_item
);
...
...
sql/sql_class.h
View file @
494184ff
...
...
@@ -706,19 +706,28 @@ class Table_ident :public Sql_alloc {
public:
LEX_STRING
db
;
LEX_STRING
table
;
SELECT_LEX
*
sel
;
inline
Table_ident
(
LEX_STRING
db_arg
,
LEX_STRING
table_arg
,
bool
force
)
:
table
(
table_arg
),
sel
((
SELECT_LEX
*
)
0
)
SELECT_LEX
_UNIT
*
sel
;
inline
Table_ident
(
LEX_STRING
db_arg
,
LEX_STRING
table_arg
,
bool
force
)
:
table
(
table_arg
),
sel
((
SELECT_LEX
_UNIT
*
)
0
)
{
if
(
!
force
&&
(
current_thd
->
client_capabilities
&
CLIENT_NO_SCHEMA
))
db
.
str
=
0
;
else
db
=
db_arg
;
}
inline
Table_ident
(
LEX_STRING
table_arg
)
:
table
(
table_arg
),
sel
((
SELECT_LEX
*
)
0
)
{
db
.
str
=
0
;}
inline
Table_ident
(
SELECT_LEX
*
s
)
:
sel
(
s
)
{
db
.
str
=
0
;
table
.
str
=
(
char
*
)
""
;
table
.
length
=
0
;}
inline
Table_ident
(
LEX_STRING
table_arg
)
:
table
(
table_arg
),
sel
((
SELECT_LEX_UNIT
*
)
0
)
{
db
.
str
=
0
;
}
inline
Table_ident
(
SELECT_LEX_UNIT
*
s
)
:
sel
(
s
)
{
db
.
str
=
0
;
table
.
str
=
(
char
*
)
""
;
table
.
length
=
0
;
}
inline
void
change_db
(
char
*
db_name
)
{
db
.
str
=
db_name
;
db
.
length
=
(
uint
)
strlen
(
db_name
);
}
{
db
.
str
=
db_name
;
db
.
length
=
(
uint
)
strlen
(
db_name
);
}
};
// this is needed for user_vars hash
...
...
sql/sql_derived.cc
View file @
494184ff
...
...
@@ -28,21 +28,25 @@
static
const
char
*
any_db
=
"*any*"
;
// Special symbol for check_access
int
mysql_derived
(
THD
*
thd
,
LEX
*
lex
,
SELECT_LEX
*
s
,
TABLE_LIST
*
t
)
int
mysql_derived
(
THD
*
thd
,
LEX
*
lex
,
SELECT_LEX_UNIT
*
s
,
TABLE_LIST
*
t
)
{
SELECT_LEX
*
sl
=
s
;
/*
TODO: make derived tables with union inside (now only 1 SELECT may be
procesed)
*/
SELECT_LEX
*
sl
=
(
SELECT_LEX
*
)
s
->
slave
;
List
<
Item
>
item_list
;
TABLE
*
table
;
int
res
;
select_union
*
derived_result
;
TABLE_LIST
*
tables
=
(
TABLE_LIST
*
)
sl
->
table_list
.
first
;
TABLE_LIST
*
tables
=
(
TABLE_LIST
*
)
sl
->
table_list
.
first
;
TMP_TABLE_PARAM
tmp_table_param
;
DBUG_ENTER
(
"mysql_derived"
);
if
(
tables
)
res
=
check_table_access
(
thd
,
SELECT_ACL
,
tables
);
res
=
check_table_access
(
thd
,
SELECT_ACL
,
tables
);
else
res
=
check_access
(
thd
,
SELECT_ACL
,
any_db
);
res
=
check_access
(
thd
,
SELECT_ACL
,
any_db
);
if
(
res
)
DBUG_RETURN
(
-
1
);
...
...
@@ -52,7 +56,7 @@ int mysql_derived(THD *thd, LEX *lex,SELECT_LEX *s, TABLE_LIST *t)
{
if
(
cursor
->
derived
)
{
res
=
mysql_derived
(
thd
,
lex
,(
SELECT_LEX
*
)
cursor
->
derived
,
cursor
);
res
=
mysql_derived
(
thd
,
lex
,
(
SELECT_LEX_UNIT
*
)
cursor
->
derived
,
cursor
);
if
(
res
)
DBUG_RETURN
(
res
);
}
}
...
...
@@ -103,9 +107,8 @@ int mysql_derived(THD *thd, LEX *lex,SELECT_LEX *s, TABLE_LIST *t)
{
t
->
real_name
=
table
->
real_name
;
t
->
table
=
table
;
sl
->
prev
->
next
=
sl
->
next
;
sl
->
exclude
()
;
t
->
derived
=
(
SELECT_LEX
*
)
0
;
// just in case ...
if
(
!
sl
->
next
)
lex
->
last_select
=
sl
;
}
}
delete
derived_result
;
...
...
sql/sql_lex.cc
View file @
494184ff
...
...
@@ -879,3 +879,118 @@ int yylex(void *arg)
}
}
}
/*
st_select_lex structures initialisations
*/
void
st_select_lex_node
::
init_query
()
{
next
=
master
=
slave
=
link_next
=
0
;
prev
=
link_prev
=
0
;
}
void
st_select_lex_node
::
init_select
()
{
order_list
.
elements
=
0
;
order_list
.
first
=
0
;
order_list
.
next
=
(
byte
**
)
&
order_list
.
first
;
select_limit
=
offset_limit
=
0
;
}
void
st_select_lex_unit
::
init_query
()
{
st_select_lex_node
::
init_query
();
global_parameters
=
this
;
select_limit_cnt
=
offset_limit_cnt
=
0
;
}
void
st_select_lex
::
init_query
()
{
st_select_lex_node
::
init_query
();
table_list
.
elements
=
0
;
table_list
.
first
=
0
;
table_list
.
next
=
(
byte
**
)
&
table_list
.
first
;
item_list
.
empty
();
}
void
st_select_lex
::
init_select
()
{
st_select_lex_node
::
init_select
();
group_list
.
elements
=
0
;
group_list
.
first
=
0
;
group_list
.
next
=
(
byte
**
)
&
group_list
.
first
;
options
=
0
;
where
=
having
=
0
;
when_list
.
empty
();
expr_list
.
empty
();
interval_list
.
empty
();
use_index
.
empty
();
ftfunc_list
.
empty
();
linkage
=
UNSPECIFIED_TYPE
;
}
/*
st_select_lex structures linking
*/
/* include on level down */
void
st_select_lex_node
::
include_down
(
st_select_lex_node
*
upper
)
{
if
((
next
=
upper
->
slave
))
next
->
prev
=
&
next
;
prev
=
&
upper
->
slave
;
upper
->
slave
=
this
;
master
=
upper
;
}
/* include neighbour (on same level) */
void
st_select_lex_node
::
include_neighbour
(
st_select_lex_node
*
before
)
{
if
((
next
=
before
->
next
))
next
->
prev
=
&
next
;
prev
=
&
before
->
next
;
before
->
next
=
this
;
master
=
before
->
master
;
}
/* including in global SELECT_LEX list */
void
st_select_lex_node
::
include_global
(
st_select_lex_node
**
plink
)
{
if
((
link_next
=
*
plink
))
link_next
->
link_prev
=
&
link_next
;
link_prev
=
plink
;
*
plink
=
this
;
}
//excluding from global list (internal function)
void
st_select_lex_node
::
fast_exclude
()
{
if
(
link_prev
)
{
if
((
*
link_prev
=
link_next
))
link_next
->
link_prev
=
link_prev
;
// Remove slave structure
for
(;
slave
;
slave
=
slave
->
next
)
slave
->
fast_exclude
();
}
}
/*
excluding select_lex structure (except first (first select can't be
deleted, because it is most upper select))
*/
void
st_select_lex_node
::
exclude
()
{
//exclude from global list
fast_exclude
();
//exclude from other structures
if
((
*
prev
=
next
))
next
->
prev
=
prev
;
/*
We do not need following statements, because prev pointer of first
list element point to master->slave
if (master->slave == this)
master->slave= next;
*/
}
sql/sql_lex.h
View file @
494184ff
...
...
@@ -103,28 +103,143 @@ typedef struct st_lex_master_info
}
LEX_MASTER_INFO
;
enum
sub_select_type
{
UNSPECIFIED_TYPE
,
UNION_TYPE
,
INTERSECT_TYPE
,
EXCEPT_TYPE
,
NOT_A_SELECT
,
DERIVED_TABLE_TYPE
};
enum
sub_select_type
{
UNSPECIFIED_TYPE
,
UNION_TYPE
,
INTERSECT_TYPE
,
EXCEPT_TYPE
,
GLOBAL_OPTIONS_TYPE
,
DERIVED_TABLE_TYPE
};
/* The state of the lex parsing for selects */
/*
The state of the lex parsing for selects
All select describing structures linked with following pointers:
- list of neighbors (next/prev) (prev of first element point to slave
pointer of upper structure)
- one level units for unit (union) structure
- member of one union(unit) for ordinary select_lex
- pointer to master
- outer select_lex for unit (union)
- unit structure for ordinary select_lex
- pointer to slave
- first list element of select_lex belonged to this unit for unit
- first unit in list of units that belong to this select_lex (as
subselects or derived tables) for ordinary select_lex
- list of all select_lex (for group operation like correcting list of opened
tables)
for example for following query:
typedef
struct
st_select_lex
{
select *
from table1
where table1.field IN (select * from table1_1_1 union
select * from table1_1_2)
union
select *
from table2
where table2.field=(select (select f1 from table2_1_1_1_1
where table2_1_1_1_1.f2=table2_1_1.f3)
from table2_1_1
where table2_1_1.f1=table2.f2)
union
select * from table3;
we will have following structure:
main unit
select1 select2 select3
|^^ |^
s||| ||master
l||| |+---------------------------------+
a||| +---------------------------------+|
v|||master slave ||
e||+-------------------------+ ||
V| neighbor | V|
unit 1.1<==================>unit1.2 unit2.1
select1.1.1 select 1.1.2 select1.2.1 select2.1.1 select2.1.2
|^
||
V|
unit2.1.1.1
select2.1.1.1.1
relation in main unit will be following:
main unit
|^^^
||||
|||+------------------------------+
||+--------------+ |
slave||master | |
V| neighbor | neighbor |
select1<========>select2<========>select3
list of all select_lex will be following (as it will be constructed by
parser):
select1->select2->select3->select2.1.1->select 2.1.2->select2.1.1.1.1-+
|
+---------------------------------------------------------------------+
|
+->select1.1.1->select1.1.2
*/
/*
Base class for st_select_lex (SELECT_LEX) &
st_select_lex_unit (SELECT_LEX_UNIT)
*/
struct
st_select_lex_node
{
enum
sub_select_type
linkage
;
char
*
db
,
*
db1
,
*
table1
,
*
db2
,
*
table2
;
/* For outer join using .. */
Item
*
where
,
*
having
;
ha_rows
select_limit
,
offset_limit
;
st_select_lex_node
*
next
,
**
prev
,
/* neighbor list */
*
master
,
*
slave
,
/* vertical links */
*
link_next
,
**
link_prev
;
/* list of whole SELECT_LEX */
SQL_LIST
order_list
;
/* ORDER clause */
ha_rows
select_limit
,
offset_limit
;
/* LIMIT clause parameters */
void
init_query
();
void
init_select
();
void
include_down
(
st_select_lex_node
*
upper
);
void
include_neighbour
(
st_select_lex_node
*
before
);
void
include_global
(
st_select_lex_node
**
plink
);
void
exclude
();
private:
void
fast_exclude
();
};
/*
SELECT_LEX_UNIT - unit of selects (UNION, INTERSECT, ...) group
SELECT_LEXs
*/
struct
st_select_lex_unit
:
public
st_select_lex_node
{
/*
Pointer to 'last' select or pointer to unit where stored
global parameters for union
*/
st_select_lex_node
*
global_parameters
;
/* LIMIT clause runtime counters */
ha_rows
select_limit_cnt
,
offset_limit_cnt
;
void
init_query
();
};
typedef
struct
st_select_lex_unit
SELECT_LEX_UNIT
;
/*
SELECT_LEX - store information of parsed SELECT_LEX statment
*/
struct
st_select_lex
:
public
st_select_lex_node
{
char
*
db
,
*
db1
,
*
table1
,
*
db2
,
*
table2
;
/* For outer join using .. */
Item
*
where
,
*
having
;
/* WHERE & HAVING clauses */
ulong
options
;
List
<
List_item
>
expr_list
;
List
<
List_item
>
when_list
;
SQL_LIST
order_list
,
table_list
,
group_list
;
List
<
Item
>
item_list
;
List
<
String
>
interval_list
,
use_index
,
*
use_index_ptr
,
List
<
List_item
>
when_list
;
/* WHEN clause */
SQL_LIST
table_list
,
group_list
;
/* FROM & GROUP BY clauses */
List
<
Item
>
item_list
;
/* list of fields & expressions */
List
<
String
>
interval_list
,
use_index
,
*
use_index_ptr
,
ignore_index
,
*
ignore_index_ptr
;
List
<
Item_func_match
>
ftfunc_list
;
uint
in_sum_expr
,
sort_default
;
bool
create_refs
,
braces
;
st_select_lex
*
next
,
*
prev
;
}
SELECT_LEX
;
bool
create_refs
,
braces
;
/* SELECT ... UNION (SELECT ... ) <- this braces */
void
init_query
();
void
init_select
();
};
typedef
struct
st_select_lex
SELECT_LEX
;
class
Set_option
:
public
Sql_alloc
{
public:
...
...
@@ -137,13 +252,15 @@ class Set_option :public Sql_alloc {
:
name
(
par_name
),
item
(
par_item
),
name_length
(
length
),
type
(
par_type
)
{}
};
/* The state of the lex parsing. This is saved in the THD struct */
typedef
struct
st_lex
{
uint
yylineno
,
yytoklen
;
/* Simulate lex */
LEX_YYSTYPE
yylval
;
SELECT_LEX
select_lex
,
*
select
,
*
last_select
;
SELECT_LEX_UNIT
unit
;
/* most upper unit */
SELECT_LEX
select_lex
,
/* first SELECT_LEX */
/* current SELECT_LEX in parsing */
*
select
;
uchar
*
ptr
,
*
tok_start
,
*
tok_end
,
*
end_of_query
;
char
*
length
,
*
dec
,
*
change
,
*
name
;
char
*
backup_dir
;
/* For RESTORE/BACKUP */
...
...
sql/sql_parse.cc
View file @
494184ff
...
...
@@ -1240,8 +1240,10 @@ mysql_execute_command(void)
{
for
(
TABLE_LIST
*
cursor
=
tables
;
cursor
;
cursor
=
cursor
->
next
)
if
(
cursor
->
derived
&&
mysql_derived
(
thd
,
lex
,(
SELECT_LEX
*
)
cursor
->
derived
,
cursor
))
cursor
=
cursor
->
next
)
if
(
cursor
->
derived
&&
mysql_derived
(
thd
,
lex
,
(
SELECT_LEX_UNIT
*
)
cursor
->
derived
,
cursor
))
DBUG_VOID_RETURN
;
}
if
((
lex
->
select_lex
.
next
&&
create_total_list
(
thd
,
lex
,
&
tables
))
||
...
...
@@ -2664,18 +2666,19 @@ static void
mysql_init_query
(
THD
*
thd
)
{
DBUG_ENTER
(
"mysql_init_query"
);
thd
->
lex
.
select_lex
.
item_list
.
empty
();
thd
->
lex
.
unit
.
init_query
();
thd
->
lex
.
select_lex
.
init_query
();
thd
->
lex
.
unit
.
slave
=
&
thd
->
lex
.
select_lex
;
thd
->
lex
.
select_lex
.
master
=
&
thd
->
lex
.
unit
;
thd
->
lex
.
select_lex
.
prev
=
&
thd
->
lex
.
unit
.
slave
;
thd
->
lex
.
value_list
.
empty
();
thd
->
lex
.
select_lex
.
table_list
.
elements
=
0
;
thd
->
free_list
=
0
;
thd
->
lex
.
union_option
=
0
;
thd
->
lex
.
select
=
thd
->
lex
.
last_select
=
&
thd
->
lex
.
select_lex
;
thd
->
lex
.
select_lex
.
table_list
.
first
=
0
;
thd
->
lex
.
select_lex
.
table_list
.
next
=
(
byte
**
)
&
thd
->
lex
.
select_lex
.
table_list
.
first
;
thd
->
lex
.
select_lex
.
next
=
0
;
thd
->
fatal_error
=
0
;
// Safety
thd
->
last_insert_id_used
=
thd
->
query_start_used
=
thd
->
insert_id_used
=
0
;
thd
->
sent_row_count
=
thd
->
examined_row_count
=
0
;
thd
->
safe_to_cache_query
=
1
;
thd
->
free_list
=
0
;
thd
->
lex
.
union_option
=
0
;
thd
->
lex
.
select
=
&
thd
->
lex
.
select_lex
;
thd
->
fatal_error
=
0
;
// Safety
thd
->
last_insert_id_used
=
thd
->
query_start_used
=
thd
->
insert_id_used
=
0
;
thd
->
sent_row_count
=
thd
->
examined_row_count
=
0
;
thd
->
safe_to_cache_query
=
1
;
DBUG_VOID_RETURN
;
}
...
...
@@ -2683,53 +2686,52 @@ void
mysql_init_select
(
LEX
*
lex
)
{
SELECT_LEX
*
select_lex
=
lex
->
select
;
select_lex
->
where
=
select_lex
->
having
=
0
;
select_lex
->
init_select
()
;
select_lex
->
select_limit
=
lex
->
thd
->
default_select_limit
;
select_lex
->
offset_limit
=
0
;
select_lex
->
options
=
0
;
select_lex
->
linkage
=
UNSPECIFIED_TYPE
;
lex
->
exchange
=
0
;
lex
->
proc_list
.
first
=
0
;
select_lex
->
order_list
.
elements
=
select_lex
->
group_list
.
elements
=
0
;
select_lex
->
order_list
.
first
=
0
;
select_lex
->
order_list
.
next
=
(
byte
**
)
&
select_lex
->
order_list
.
first
;
select_lex
->
group_list
.
first
=
0
;
select_lex
->
group_list
.
next
=
(
byte
**
)
&
select_lex
->
group_list
.
first
;
select_lex
->
next
=
select_lex
->
prev
=
(
SELECT_LEX
*
)
NULL
;
}
bool
mysql_new_select
(
LEX
*
lex
)
mysql_new_select
(
LEX
*
lex
,
bool
move_down
)
{
SELECT_LEX
*
select_lex
=
(
SELECT_LEX
*
)
lex
->
thd
->
calloc
(
sizeof
(
SELECT_LEX
));
if
(
!
select_lex
)
return
1
;
lex
->
select
=
lex
->
last_select
;
lex
->
select
->
next
=
select_lex
;
lex
->
select
=
lex
->
last_select
=
select_lex
;
select_lex
->
table_list
.
next
=
(
byte
**
)
&
select_lex
->
table_list
.
first
;
select_lex
->
item_list
.
empty
();
select_lex
->
when_list
.
empty
();
select_lex
->
expr_list
.
empty
();
select_lex
->
interval_list
.
empty
();
select_lex
->
use_index
.
empty
();
select_lex
->
ftfunc_list
.
empty
();
select_lex
->
init_query
();
select_lex
->
init_select
();
if
(
move_down
)
{
/* first select_lex of subselect or derived table */
SELECT_LEX_UNIT
*
unit
=
(
SELECT_LEX_UNIT
*
)
lex
->
thd
->
calloc
(
sizeof
(
SELECT_LEX_UNIT
));
if
(
!
unit
)
return
1
;
unit
->
init_query
();
unit
->
init_select
();
unit
->
include_down
(
lex
->
select
);
select_lex
->
include_down
(
unit
);
}
else
select_lex
->
include_neighbour
(
lex
->
select
);
select_lex
->
include_global
(
&
lex
->
select
->
link_next
);
lex
->
select
=
select_lex
;
return
0
;
}
void
mysql_init_multi_delete
(
LEX
*
lex
)
{
lex
->
sql_command
=
SQLCOM_DELETE_MULTI
;
lex
->
sql_command
=
SQLCOM_DELETE_MULTI
;
mysql_init_select
(
lex
);
lex
->
select
->
select_limit
=
HA_POS_ERROR
;
lex
->
auxilliary_table_list
=
lex
->
select_lex
.
table_list
;
lex
->
select
->
table_list
.
elements
=
0
;
lex
->
select
->
table_list
.
first
=
0
;
lex
->
select
->
table_list
.
next
=
(
byte
**
)
&
(
lex
->
select
->
table_list
.
first
);
lex
->
select
->
select_limit
=
HA_POS_ERROR
;
lex
->
auxilliary_table_list
=
lex
->
select_lex
.
table_list
;
lex
->
select
->
init_query
();
}
void
mysql_parse
(
THD
*
thd
,
char
*
inBuf
,
uint
length
)
mysql_parse
(
THD
*
thd
,
char
*
inBuf
,
uint
length
)
{
DBUG_ENTER
(
"mysql_parse"
);
...
...
@@ -3159,7 +3161,7 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias,
ptr
->
real_name_length
=
table
->
table
.
length
;
ptr
->
lock_type
=
flags
;
ptr
->
updating
=
updating
;
ptr
->
derived
=
(
SELECT_LEX
*
)
table
->
sel
;
ptr
->
derived
=
(
SELECT_LEX_UNIT
*
)
table
->
sel
;
if
(
use_index
)
ptr
->
use_index
=
(
List
<
String
>
*
)
thd
->
memdup
((
gptr
)
use_index
,
sizeof
(
*
use_index
));
...
...
@@ -3204,8 +3206,8 @@ static bool create_total_list(THD *thd, LEX *lex, TABLE_LIST **result)
SELECT_LEX
*
sl
;
TABLE_LIST
**
new_table_list
=
result
,
*
aux
;
*
new_table_list
=
0
;
// end result list
for
(
sl
=
&
lex
->
select_lex
;
sl
;
sl
=
sl
->
next
)
*
new_table_list
=
0
;
// end result list
for
(
sl
=
&
lex
->
select_lex
;
sl
;
sl
=
(
SELECT_LEX
*
)
sl
->
next
)
{
if
(
sl
->
order_list
.
first
&&
sl
->
next
&&
!
sl
->
braces
)
{
...
...
sql/sql_union.cc
View file @
494184ff
...
...
@@ -43,8 +43,8 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
/* Fix tables 'to-be-unioned-from' list to point at opened tables */
last_sl
=
&
lex
->
select_lex
;
for
(
sl
=
last_sl
;
sl
&&
sl
->
linkage
!=
NOT_A_SELECT
;
last_sl
=
sl
,
sl
=
sl
->
next
)
sl
&&
sl
->
linkage
!=
GLOBAL_OPTIONS_TYPE
;
last_sl
=
sl
,
sl
=
(
SELECT_LEX
*
)
sl
->
next
)
{
for
(
TABLE_LIST
*
cursor
=
(
TABLE_LIST
*
)
sl
->
table_list
.
first
;
cursor
;
...
...
@@ -133,7 +133,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
}
union_result
->
save_time_stamp
=!
describe
;
for
(
sl
=
&
lex
->
select_lex
;
sl
;
sl
=
sl
->
next
)
for
(
sl
=
&
lex
->
select_lex
;
sl
;
sl
=
(
SELECT_LEX
*
)
sl
->
next
)
{
lex
->
select
=
sl
;
thd
->
offset_limit
=
sl
->
offset_limit
;
...
...
@@ -143,15 +143,19 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
if
(
thd
->
select_limit
==
HA_POS_ERROR
)
sl
->
options
&=
~
OPTION_FOUND_ROWS
;
res
=
mysql_select
(
thd
,
(
describe
&&
sl
->
linkage
==
NOT_A_SELECT
)
?
first_table
:
(
TABLE_LIST
*
)
sl
->
table_list
.
first
,
sl
->
item_list
,
sl
->
where
,
(
sl
->
braces
)
?
(
ORDER
*
)
sl
->
order_list
.
first
:
(
ORDER
*
)
0
,
(
ORDER
*
)
sl
->
group_list
.
first
,
sl
->
having
,
(
ORDER
*
)
NULL
,
sl
->
options
|
thd
->
options
|
SELECT_NO_UNLOCK
|
((
describe
)
?
SELECT_DESCRIBE
:
0
),
union_result
);
res
=
mysql_select
(
thd
,
(
describe
&&
sl
->
linkage
==
GLOBAL_OPTIONS_TYPE
)
?
first_table
:
(
TABLE_LIST
*
)
sl
->
table_list
.
first
,
sl
->
item_list
,
sl
->
where
,
(
sl
->
braces
)
?
(
ORDER
*
)
sl
->
order_list
.
first
:
(
ORDER
*
)
0
,
(
ORDER
*
)
sl
->
group_list
.
first
,
sl
->
having
,
(
ORDER
*
)
NULL
,
sl
->
options
|
thd
->
options
|
SELECT_NO_UNLOCK
|
((
describe
)
?
SELECT_DESCRIBE
:
0
),
union_result
);
if
(
res
)
goto
exit
;
}
...
...
sql/sql_yacc.yy
View file @
494184ff
...
...
@@ -2155,21 +2155,22 @@ join_table:
| '(' SELECT_SYM select_part3 ')' opt_table_alias
{
LEX *lex=Lex;
lex->select=lex->select->prev;
if (!($$=add_table_to_list(new Table_ident(Lex->last_select),$5,0,TL_UNLOCK)))
SELECT_LEX_UNIT *unit= (SELECT_LEX_UNIT*) lex->select->master;
lex->select= (SELECT_LEX*) unit->master;
if (!($$= add_table_to_list(new Table_ident(unit),
$5,0,TL_UNLOCK)))
YYABORT;
}
select_part3:
{
LEX *lex=Lex;
lex->derived_tables=true;
SELECT_LEX *tmp=lex->select;
if (lex->select->linkage == NOT_A_SELECT || mysql_new_select(lex
))
LEX *lex=
Lex;
lex->derived_tables=
true;
if (lex->select->linkage == GLOBAL_OPTIONS_TYPE ||
mysql_new_select(lex, 1
))
YYABORT;
mysql_init_select(lex);
lex->select->linkage=DERIVED_TABLE_TYPE;
lex->select->prev=tmp;
lex->select->linkage= DERIVED_TABLE_TYPE;
}
select_options select_item_list select_intoto
...
...
@@ -3809,7 +3810,8 @@ union_list:
net_printf(&lex->thd->net, ER_WRONG_USAGE,"UNION","INTO");
YYABORT;
}
if (lex->select->linkage == NOT_A_SELECT || mysql_new_select(lex))
if (lex->select->linkage == GLOBAL_OPTIONS_TYPE ||
mysql_new_select(lex, 0))
YYABORT;
lex->select->linkage=UNION_TYPE;
}
...
...
@@ -3824,10 +3826,10 @@ optional_order_or_limit:
|
{
LEX *lex=Lex;
if (!lex->select->braces || mysql_new_select(lex))
if (!lex->select->braces || mysql_new_select(lex
, 0
))
YYABORT;
mysql_init_select(lex);
lex->select->linkage=
NOT_A_SELECT
;
lex->select->linkage=
GLOBAL_OPTIONS_TYPE
;
lex->select->select_limit=lex->thd->default_select_limit;
}
opt_order_clause limit_clause
...
...
sql/table.h
View file @
494184ff
...
...
@@ -139,18 +139,18 @@ typedef struct st_table_list {
struct
st_table_list
*
next
;
char
*
db
,
*
name
,
*
real_name
;
uint32
db_length
,
real_name_length
;
Item
*
on_expr
;
/* Used with outer join */
struct
st_table_list
*
natural_join
;
/* natural join on this table*/
Item
*
on_expr
;
/* Used with outer join */
struct
st_table_list
*
natural_join
;
/* natural join on this table*/
/* ... join ... USE INDEX ... IGNORE INDEX */
List
<
String
>
*
use_index
,
*
ignore_index
;
List
<
String
>
*
use_index
,
*
ignore_index
;
TABLE
*
table
;
GRANT_INFO
grant
;
thr_lock_type
lock_type
;
uint
outer_join
;
/* Which join type */
bool
straight
;
/* optimize with prev table */
bool
updating
;
/* for replicate-do/ignore table */
bool
shared
;
/* Used twice in union */
void
*
derived
;
uint
outer_join
;
/* Which join type */
bool
straight
;
/* optimize with prev table */
bool
updating
;
/* for replicate-do/ignore table */
bool
shared
;
/* Used twice in union */
void
*
derived
;
/* SELECT_LEX_UNIT of derived table */
}
TABLE_LIST
;
typedef
struct
st_changed_table_list
{
...
...
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