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
c4184e59
Commit
c4184e59
authored
Feb 19, 2003
by
unknown
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added chapter about subselect transformations
parent
8e6e5dda
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
237 additions
and
2 deletions
+237
-2
Docs/internals.texi
Docs/internals.texi
+237
-2
No files found.
Docs/internals.texi
View file @
c4184e59
...
...
@@ -54,6 +54,7 @@ This is a manual about @strong{MySQL} internals.
* flush tables:: How MySQL Handles @code
{
FLUSH TABLES
}
* filesort:: How MySQL Does Sorting (@code
{
filesort
}
)
* selects:: How MySQL performs different selects
* transformations:: How MySQL transforms subqueries
* coding guidelines:: Coding Guidelines
* mysys functions:: Functions In The @code
{
mysys
}
Library
* DBUG:: DBUG Tags To Use
...
...
@@ -261,7 +262,7 @@ and then we read the rows in the sorted order into a row buffer
@end itemize
@node selects,
coding guideline
s, flush tables, Top
@node selects,
transformation
s, flush tables, Top
@chapter How MySQL performs different selects
@node select steps,,,
...
...
@@ -604,7 +605,241 @@ mysql_explain_union for every inner UNION
PROBLEM: how it will work with global query optimization?
@node coding guidelines, mysys functions, selects, Top
@node transformations, coding guidelines, selects, Top
@chapter How MySQL transforms subqueries
Item
_
subselect virtual method select
_
transformer is used to rewrite
subqueries. It is called from Item
_
subselect::init (which called in
Item
_
subselect constructor)
@node transformation IN
@section Item
_
in
_
subselect::select
_
transformer
Item
_
in
_
subselect::select
_
transformer is divided on two parts for
scalar left part and row left part:
@node transformation scalar IN
@subsection Scalar IN Subselect
To rewrite scalar IN subselect used method
Item
_
in
_
subselect::single
_
value
_
transformer, Scalar IN subselect will
be replaced with Item
_
in
_
optimizer.
Item
_
in
_
optimizer item is special boolean function. On value request
(one of val, val
_
int or val
_
str methods) it evaluate left expression of
IN by storing it value in cache item (one of Item
_
cache* items), then it
test cache is it NULL. If left expression (cache) is NULL then
Item
_
in
_
optimizer return NULL, else it evaluate Item
_
in
_
subselect.
Example queries.
@example
a) SELECT * from t1 where t1.a in (SELECT t2.a FROM t2);
b) SELECT * from t1 where t1.a in (SELECT t2.a FROM t2 GROUP BY t2.a);
@end example
@itemize
@item
Item
_
in
_
subselect inherit mechanism of getting value from
Item
_
exists
_
subselect.
@item
Select
_
transformer stores reference to left expression in its
conditions: (in WHERE in case 'a' and in a HAVING in case 'b')
@item
Item from item list of this select (t2.a) can be referred with special
reference (Item
_
ref
_
null
_
helper or Item
_
asterisk
_
remover).
This reference informs Item
_
in
_
optimizer if item (t2.a) is NULL by
setting the 'was
_
null' flag.
@item
The return value from Item
_
in
_
subselect will be evaluated as following:
@itemize @bullet
@item
If TRUE return true
@item
If NULL return null
@item
If FALSE and 'was
_
null' is set, return null
@item
return FALSE
@end itemize
@end itemize
<left
_
expression> IN (SELECT <item> ...) will be represented like
following:
@example
+-----------------+
|Item
_
in
_
optimizer|
+-----------------+
|
+---------------------+------------+
| |
+-----------------------+ +-----------------+
| <left
_
expression> | |Item
_
in
_
subselect|
| | +-----------------+
+-----------------------+ |
|<left
_
expression cache>| +-----------+-----------+
| | | |
+-----------------------+ | |
^
+----------+ +--------------------+
+<<<<<<<<<<<<<<<<<| Item
_
ref | +<<<|Item
_
ref
_
null
_
helper|
+----------+ V +--------------------+
V +--------------------+
+>>>| <item> |
+--------------------+
@end example
where '<<<<<<<<<' is reference in meaning of Item
_
ref.
Item
_
ref used for point to <left
_
expression cache>, because in time of
transformation we know only address of variable where pointer on cache
will be stored.
If select have ORDER BY clause it will be wiped out, because no sense in
ORDER BY without LIMIT here.
If IN subselect union condition of every select in UNION will be changed
personally.
Following is examples of IN transformations:
@example
a) <left
_
expression> IN (SELECT <item> FROM t
WHERE <where
_
exp>)
will be represented as
(SELECT 1 FROM t
WHERE <where
_
exp> and
Item
_
ref(<cached
_
left
_
expression>)=<Item
_
asterisk
_
remover(<Item>)>)
b) <left
_
expression> IN (SELECT <item> FROM t
HAVING <having
_
expr>
ORDER BY 1)
will be represented as
(SELECT <item> as ref
_
null
_
helper FROM t
HAVING <having
_
exp> AND
Item
_
ref(<cached
_
left
_
expression>) = ref
_
null
_
helper)
c) <left
_
expression> IN (SELECT <item> UNION ...)
will be represented as
(SELECT 1
HAVING Item
_
ref(<cached
_
left
_
expression>)=
<Item
_
asterisk
_
remover(<Item>)>
UNION ...)
(having without FROM is syntax error, but having condition is checked
even for subselect without FROM)
d) <left
_
expression> IN (select <item>)
will be completely replaced with <left
_
expression> = <item>
@end example
Now conditions (WHERE (a) or HAVING (b)) will be changed depends of
select in following way:
If subselect have HAVING , sum function or GROUP BY (case a) then item
list will be unchanged and Item
_
ref
_
null
_
helper reference will be
created on item list element. Condition will be added to HAVING condition.
If subselect have not HAVING, sum function or GROUP BY (case b) then:
@itemize @bullet
@item
@strong
{
item list
}
will be replaced with 1.
@item
@strong
{
<item>
}
from item list will be stored in Item
_
asterisk
_
remover, which
inherit from Item
_
ref
_
null
_
helper, but store item on which refer by
itself, and also it can resolve '*' item.
@item
@strong
{
<left
_
expression cache> = <Item
_
ref
_
null
_
helper>
}
will be added to
WHERE clause this item or to HAVING clause if this subselect have
no FROM clause and subselect is union (case c).
@end itemize
Single select without FROM will be reduced to just
<left
_
expression> = <item> without using Item
_
in
_
optimizer.
@node transformations row IN
@subsection Row IN Subselect
To rewrite row IN subselect used method
Item
_
in
_
subselect::row
_
value
_
transformer. It work in almost same way as
scalar analog, but work with Item
_
cache
_
row for caching left expression
and use references on elements of Item
_
cache
_
row.
To refer on item list it use Item
_
ref
_
on
_
list
_
position.
Item
_
ref
_
on
_
list
_
position::fix
_
fields will find item in item list of
subselect by number and create Item
_
ref
_
null
_
helper to refer on it. It
used to find reference when all '*' items will be translated in item
list. Subselect with have HAVING, sum functions or GROUP BY will
transformed in following way:
@example
ROW(l1, l2, ... lN) IN (SELECT i1, i2, ... iM FROM t HAVING <having
_
expr>)
will be following:
(SELECT i1, i2, ... iM FROM t
HAVING <having
_
expr> and
<cache
_
l1> = <ref
_
on
_
list
_
position(1)> AND
<cache
_
l2> = <ref
_
on
_
list
_
position(2)> AND
...
<cache
_
lN> = <ref
_
on
_
list
_
position(N)>)
@end example
In this way will be transformed select without FROM, too.
For other subselect it will be same but for WHERE clause.
@node transformations all any
@section Item
_
allany
_
subselect
Item
_
allany
_
subselect is inherited from Item
_
in
_
subselect.
ALL/ANY/SOME use same algorithm (and same method of Item
_
in
_
subselect)
as scalar IN, but use different function instead of '='.
ANY/SOME use same function that was listed after left expression.
ALL use inverted function, and all subselect passed as argument to
Item
_
func
_
not.
@node transformations singlerow
@section Item
_
singlerow
_
subselect
Item
_
singlerow
_
subselect will be rewritten only if it have not FROM
clause, it is not part of UNION and it is scalar subselect. For now will
not be converted subselects with field or reference on top of item list
(we can't change name of such items from one hand, but from other hand
we should assign to it name of whole subselect which will be reduced);
Following will not be reduced:
@example
SELECT a;
SELECT 1 UNION SELECT 2;
SELECT 1 FROM t1;
@end example
Following select will be reduced:
@example
SELECT 1;
SELECT a+2;
@end example
Such subselect will be completely replaced by its expression from item
list and its SELECT
_
LEX and SELECT
_
LEX
_
UNIT will be removed from
SELECT
_
LEX's tree.
But all Item
_
fields and Item
_
ref of that expression will be marked for
special fix
_
fields() procedure. fix
_
fields() for such Item will be
performed is same way as for items of inner subselect. Also if this
expression is Item
_
fields or Item
_
ref then name of this new item will
be same as name of this item (but not '(SELECT ...)'). It is done to
prevent broke references on such items from more inner subselects.
@node coding guidelines, mysys functions, transformations, Top
@chapter Coding Guidelines
@itemize @bullet
...
...
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