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
16a2ea9d
Commit
16a2ea9d
authored
Feb 19, 2003
by
gluh@gluh.mysql.r18.ru
Browse files
Options
Browse Files
Download
Plain Diff
Merge sgluhov@work.mysql.com:/home/bk/mysql-4.1
into gluh.mysql.r18.ru:/home/gluh/mysql-4.1.uvar
parents
ae911ef8
7bcf7f90
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
621 additions
and
37 deletions
+621
-37
Docs/internals.texi
Docs/internals.texi
+581
-3
myisam/ft_dump.c
myisam/ft_dump.c
+1
-5
myisam/mi_check.c
myisam/mi_check.c
+8
-6
myisam/myisamdef.h
myisam/myisamdef.h
+1
-0
myisam/rt_index.c
myisam/rt_index.c
+1
-1
myisam/rt_key.c
myisam/rt_key.c
+2
-2
myisam/rt_split.c
myisam/rt_split.c
+1
-1
myisam/rt_test.c
myisam/rt_test.c
+1
-1
myisam/sort.c
myisam/sort.c
+7
-7
sql/field.cc
sql/field.cc
+0
-1
sql/ha_innodb.cc
sql/ha_innodb.cc
+1
-0
sql/mysqld.cc
sql/mysqld.cc
+2
-1
sql/opt_range.cc
sql/opt_range.cc
+1
-1
sql/sql_table.cc
sql/sql_table.cc
+14
-8
No files found.
Docs/internals.texi
View file @
16a2ea9d
...
...
@@ -53,6 +53,8 @@ This is a manual about @strong{MySQL} internals.
* caching:: How MySQL Handles Caching
* 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
...
...
@@ -220,7 +222,7 @@ After this it will give other threads a chance to open the same tables.
@end itemize
@node filesort,
coding guideline
s, flush tables, Top
@node filesort,
select
s, flush tables, Top
@chapter How MySQL Does Sorting (@code
{
filesort
}
)
@itemize @bullet
...
...
@@ -260,8 +262,584 @@ and then we read the rows in the sorted order into a row buffer
@end itemize
@node selects, transformations, flush tables, Top
@chapter How MySQL performs different selects
@node coding guidelines, mysys functions, filesort, Top
@node select steps,,,
@section Steps of select executing
Every select performed in such base steps:
@itemize
@item
JOIN::prepare
@itemize @bullet
@item
initialization and linking JOIN structure to st
_
select
_
lex
@item
fix
_
fields() for all items (after fix
_
fields we know everything
about item)
@item
moving HAVING to WHERE if possible
@item
initialization procedure if exists
@end itemize
@item
JOIN::optimize
@itemize @bullet
@item
single select optimization
@item
creation first temporary table if need
@end itemize
@item
JOIN::exec
@itemize @bullet
@item
performing select (may be created second temporary table)
@end itemize
@item
JOIN::cleanup
@itemize @bullet
@item
removing all temporary tables, other cleanup
@end itemize
@item
JOIN::reinit
@itemize @bullet
@item
prepare all structures to SELECT executing (with JOIN::exec)
@end itemize
@end itemize
@node select select
_
result
@section select
_
result CLASS
Very important role in SELECT performing have select
_
result class and
classes inherited from it (usually called with "select
_
" prefix). This
class provide interface for results transmitting.
Key methods in this class are following:
@itemize @bullet
@item
@strong
{
send
_
fields
}
sends giving item list headers (type, name, etc..)
@item
@strong
{
send
_
data
}
sends giving item list values as row of table of result
@item
@strong
{
send
_
error
}
send error to used used mainly for error interception,
making some operation and then ::send
_
error will be called.
@end itemize
For example there are fillowing select
_
result classes:
@itemize
@item
@strong
{
select
_
send
}
used for sending results though network layer
@item
@strong
{
select
_
export
}
used for exporting data to file
@item
@strong
{
multi
_
delete
}
used for multi-delete
@item
@strong
{
select
_
insert
}
used for INSERT ... SELECT ...
@item
@strong
{
multi
_
update
}
used for multi-update
@end itemize
@node select simple
@section SIMPLE or PRIMARY SELECT.
For performing single primary select SELECT used function mysql
_
select,
which:
@itemize @bullet
@item
allocate JOIN;
@item
JOIN::prepare;
@item
JOIN::optimize;
@item
JOIN::exec;
@item
JOIN::cleanup.
@end itemize
In previous versions of mysql all SELECTs was performed with help of this
function and mysql
_
select() was not divided on parts.
@node select structure
@section Structure Of Complex Select
There 2 structures which describe SELECTS:
@itemize @bullet
@item
st
_
select
_
lex (SELECT
_
LEX) it represent SELECT itself
@item
st
_
select
_
lex
_
unit (SELECT
_
LEX
_
UNIT) group several selects in bunch
@end itemize
and represent UNION operation (absence of UNION is union
with 1 SELECT and this structure present in any case). In future this
structure will be used for EXCEPT and INTERSECT.
For example:
@example
(SELECT ... )UNION(SELECT ... (SELECT...)...(SELECT...UNION...SELECT))
1 2 3 4 5 6 7
@end example
will be represent as
@example
------------------------------------------------------------------------
level 1
SELECT
_
LEX
_
UNIT(2)
|
+---------------+
| |
SELECT
_
LEX(1) SELECT
_
LEX(3)
|
--------------- | ------------------------------------------------------
| level 2
+-------------------+
| |
SELECT
_
LEX
_
UNIT(4) SELECT
_
LEX
_
UNIT(6)
| |
| +--------------+
| | |
SELECT
_
LEX(4) SELECT
_
LEX(5) SELECT
_
LEX(7)
------------------------------------------------------------------------
@end example
Note: single subselect 4 have it's own SELECT
_
LEX
_
UNIT.
Most upper SELECT
_
LEX
_
UNIT (#2 in example) stored in LEX.
First and most upper SELECT
_
LEX (#1 in example) stored in LEX, too.
This two structures always exist.
In time of creating or performing any JOIN::* operation
LEX::current
_
select point on appropriate SELECT
_
LEX.
Only during parsing global (for whole UNION) ORDER
_
BY
&
LIMIT clauses
LEX::current
_
select points to SELECT
_
LEX
_
UNIT of this unit to store this
parameter in this SELECT
_
LEX
_
UNIT (SELECT
_
LEX and SELECT
_
LEX
_
UNIT are
inherited from st
_
select
_
lex
_
node).
@node select union
@section Non-Subselect UNIONs Executing
Non subselect unions performed with help of mysql
_
union(). for now it
divided on following steps:
@itemize
@item
st
_
select
_
lex
_
unit::prepare
@itemize @bullet
@item
create temporary table for union results storing (if UNION witout
ALL option, 'distinct' parameter will be passed to table creation
procedure). Types/lengths of table's fields will be determinated
by first SELECT item list.
@item
create select
_
union (inherited from select
_
result) which will
write selects results in this temporary table
@item
allocate JOIN and perform JOIN::prepare for all SELECTs belonged
to UNION
@end itemize
@item
st
_
select
_
lex
_
unit::exec
@itemize @bullet
@item
delete rows from temporary table if it is not first call
@item
if first call call JOIN::optimize else JOIN::reinit and then
JOIN::exec for all SELECTs (select
_
union will write result for
temporary table). If union is cacheable and this method called
second, (third, ...) time it will do nothing.
@item
call mysql
_
select on temporary table with global ORDER BY and
LIMIT parameters after collecting results from all SELECTs.
@end itemize
@end itemize
As far as mysql
_
select need SELECT
_
LEX structure SELECT
_
LEX of first
SELECT of this UNION will be passed to it, but also fake
_
select
_
lex
parameter will be passed to mysql
_
select() too, to prevent linking
this SELECT
_
LEX with JOIN on this mysql
_
select() session.
PROBLEM: this fake select need workaround in many places.
@node select derived
@section Derived Tables Executing
Derived tables processing is first operation on any query. It performed
before creation list of tables of whole query and opening/locking this
tables.
If lex->derived
_
tables flag present will be scanned all SELECT
_
LEX (there
are list of all SELECT
_
LEX in reverse order (first SELECT in query will
be last in this list) lex->all
_
selects
_
list).
Pointer on derived table SELECT
_
LEX
_
UNIT stored in TABLE
_
LIST structure
(TABLE
_
LIST::derived). And for any table which have this pointer will
be called mysql
_
derived().
mysql
_
derived():
@itemize @bullet
@item
Creates list of all tables used in this query, opens and locks it
@item
Creates temporary table for storing results
@item
Creates union
_
result for writing result in this table
@item
Calls mysql
_
select or mysql
_
union for execute query
@item
Removes all derived table subtree from SELECTs tree (if it is
not EXPLAIN)
@item
Stores pointer to this temporary table in TABLE
_
LIST structure, then
this table will be used by outer query. This table table will not be
skipped in checking grants, because tables from which this table was
received was checked in mysql
_
derived.
@item
Links this temporary table in thd->derived
_
tables for removing after
query executing. this table will be closed in close
_
thread
_
tables if
second parameter of it (bool skip
_
derived) will be true.
@end itemize
@node select subselect
@section Subselects
In expression subselect represented by Item inherited from Item
_
subselect.
To hide difference in performing single SELECTs and UNIONs
Item
_
subselect use two different engines, which provide uniformed
interface for access to underplaid SELECT or UNION
(subselect
_
single
_
select
_
engine and subselect
_
union
_
engine, both are
inherited from subselect
_
engine).
Engine will be created in time of Item
_
select constructing
(Item
_
subselect::init method).
On Item
_
subselect::fix
_
fields() will be called engine->prepare().
Before calling any value getting method (val, val
_
int, val
_
str,
bring
_
value (in case of row result)) will be called engine->exec(),
which execute query or just do nothing if subselect is cacheable and
already executed.
Items inherited from provide it's own select
_
result classes. There are
2 type of it:
@itemize @bullet
@item
select
_
singlerow
_
subselect it store values of giving row in
Item
_
singlerow
_
subselect cache on send
_
data() call and report error
if Item
_
subselect have 'assigned' attribute.
@item
select
_
exists
_
subselect just store 1 as value of
Item
_
exists
_
subselect on send
_
data() call. As far as
Item
_
in
_
subselect and Item
_
allany
_
subselect inherited from
Item
_
exists
_
subselect, they use same select
_
result class.
@end itemize
Item
_
select will never call cleanup() procedure for JOIN. Every
JOIN::cleanup will call cleanup() for inner JOINs. Most upper
JOIN::cleanup will be called by mysql
_
select() or mysql
_
union().
@node select select engine
@section Single Select Engine
subselect
_
single
_
select
_
engine:
@itemize @bullet
@item
@strong
{
constructor
}
allocate JOIN and store pointers on SELECT
_
LEX and JOIN
@item
@strong
{
prepare()
}
call JOIN::prepare
@item
@strong
{
fix
_
length
_
and
_
dec()
}
prepare cache and receive type and
parameters of returning items (it called only by
Item
_
singlerow
_
subselect)
@item
@strong
{
exec()
}
drop 'assigned flag of Item
_
subselect. If called first time
JOIN::optimize and JOINexec(), else do nothing or JOIN::reinit()
JOIN::exec() depending of type of subquery.
@end itemize
@node select union engine
@section Union Engine
subselect
_
union
_
engine:
@itemize @bullet
@item
@strong
{
constructor
}
just store pointer to st
_
select
_
lex
_
union
(SELECT
_
LEX
_
UNION)
@item
@strong
{
prepare()
}
call st
_
select
_
lex
_
unit::prepare
@item
@strong
{
fix
_
length
_
and
_
dec()
}
prepare cache and receive type and
parameters (maximum of length) of returning items (it called
only by Item
_
singlerow
_
subselect)
@item
@strong
{
exec()
}
call st
_
select
_
lex
_
unit::exec(). st
_
select
_
lex
_
unit::exec()
can drop 'assigned' flag of Item
_
subselect if
st
_
select
_
lex
_
unit::item is not 0.
@end itemize
@node selectexplain
@section Explain Execution
For EXPLAIN result showing for every SELECT will be called mysql
_
select
with option SELECT
_
DESCRIBE.
For main UNION will be called mysql
_
explain
_
union.
mysql
_
explain
_
union call mysql
_
explain
_
select for every SELECT in given
union.
mysql
_
explain
_
select call mysql
_
select with SELECT
_
DESCRIBE.
mysql
_
select create JOIN for select (if it not exists, because if it
called for subselect JOIN can be created in JOIN::optimize of outer
query when it decided to calculate value of subselect). Then it call
JOIN::prepare, JOIN::optimize, JOIN exec and JOIN::cleanup as usual.
JOIN::exec called for SELECT with SELECT
_
DESCRIBE option call
select
_
describe.
select
_
describe return to user description of SELECT and call
mysql
_
explain
_
union for every inner UNION
PROBLEM: how it will work with global query optimization?
@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
...
...
@@ -1836,7 +2414,7 @@ able to provide the optimal information for all parameters.
If number of columns, in the header packet, is not 0 then the
prepared statement will contain a result set. In this case the packet
is followed by a field description result set. @xref
{
4.1 field desc
r
}
.
is followed by a field description result set. @xref
{
4.1 field desc
}
.
@node 4.1 long data,,,
...
...
myisam/ft_dump.c
View file @
16a2ea9d
...
...
@@ -124,13 +124,9 @@ int main(int argc,char *argv[])
{
keylen
=*
(
info
->
lastkey
);
#if HA_FT_WTYPE == HA_KEYTYPE_FLOAT
subkeys
=
mi_sint4korr
(
info
->
lastkey
+
keylen
+
1
);
subkeys
=
ft_sintXkorr
(
info
->
lastkey
+
keylen
+
1
);
if
(
subkeys
>=
0
)
weight
=*
(
float
*
)
&
subkeys
;
#else
#error
#endif
snprintf
(
buf
,
MAX_LEN
,
"%.*s"
,(
int
)
keylen
,
info
->
lastkey
+
1
);
my_casedn_str
(
default_charset_info
,
buf
);
...
...
myisam/mi_check.c
View file @
16a2ea9d
...
...
@@ -1893,6 +1893,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
{
sort_param
.
read_cache
=
param
->
read_cache
;
sort_param
.
keyinfo
=
share
->
keyinfo
+
sort_param
.
key
;
sort_param
.
seg
=
sort_param
.
keyinfo
->
seg
;
if
(
!
(((
ulonglong
)
1
<<
sort_param
.
key
)
&
key_map
))
{
/* Remember old statistics for key */
...
...
@@ -1906,7 +1907,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
if
((
!
(
param
->
testflag
&
T_SILENT
)))
printf
(
"- Fixing index %d
\n
"
,
sort_param
.
key
+
1
);
sort_param
.
max_pos
=
sort_param
.
pos
=
share
->
pack
.
header_length
;
keyseg
=
sort_param
.
keyinfo
->
seg
;
keyseg
=
sort_param
.
seg
;
bzero
((
char
*
)
sort_param
.
unique
,
sizeof
(
sort_param
.
unique
));
sort_param
.
key_length
=
share
->
rec_reflength
;
for
(
i
=
0
;
keyseg
[
i
].
type
!=
HA_KEYTYPE_END
;
i
++
)
...
...
@@ -2255,6 +2256,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
{
sort_param
[
i
].
key
=
key
;
sort_param
[
i
].
keyinfo
=
share
->
keyinfo
+
key
;
sort_param
[
i
].
seg
=
sort_param
[
i
].
keyinfo
->
seg
;
if
(
!
(((
ulonglong
)
1
<<
key
)
&
key_map
))
{
/* Remember old statistics for key */
...
...
@@ -2292,7 +2294,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
(
share
->
base
.
pack_reclength
*
i
));
sort_param
[
i
].
key_length
=
share
->
rec_reflength
;
for
(
keyseg
=
sort_param
[
i
].
keyinfo
->
seg
;
keyseg
->
type
!=
HA_KEYTYPE_END
;
for
(
keyseg
=
sort_param
[
i
].
seg
;
keyseg
->
type
!=
HA_KEYTYPE_END
;
keyseg
++
)
{
sort_param
[
i
].
key_length
+=
keyseg
->
length
;
...
...
@@ -3051,7 +3053,7 @@ static int sort_key_cmp(MI_SORT_PARAM *sort_param, const void *a,
const
void
*
b
)
{
uint
not_used
;
return
(
ha_key_cmp
(
sort_param
->
keyinfo
->
seg
,
*
((
uchar
**
)
a
),
*
((
uchar
**
)
b
),
return
(
ha_key_cmp
(
sort_param
->
seg
,
*
((
uchar
**
)
a
),
*
((
uchar
**
)
b
),
USE_WHOLE_KEY
,
SEARCH_SAME
,
&
not_used
));
}
/* sort_key_cmp */
...
...
@@ -3066,7 +3068,7 @@ static int sort_key_write(MI_SORT_PARAM *sort_param, const void *a)
if
(
sort_info
->
key_block
->
inited
)
{
cmp
=
ha_key_cmp
(
sort_param
->
keyinfo
->
seg
,
sort_info
->
key_block
->
lastkey
,
cmp
=
ha_key_cmp
(
sort_param
->
seg
,
sort_info
->
key_block
->
lastkey
,
(
uchar
*
)
a
,
USE_WHOLE_KEY
,
SEARCH_FIND
|
SEARCH_UPDATE
,
&
diff_pos
);
sort_param
->
unique
[
diff_pos
-
1
]
++
;
...
...
@@ -3091,7 +3093,7 @@ static int sort_key_write(MI_SORT_PARAM *sort_param, const void *a)
llbuff2
));
param
->
testflag
|=
T_RETRY_WITHOUT_QUICK
;
if
(
sort_info
->
param
->
testflag
&
T_VERBOSE
)
_mi_print_key
(
stdout
,
sort_param
->
keyinfo
->
seg
,(
uchar
*
)
a
,
USE_WHOLE_KEY
);
_mi_print_key
(
stdout
,
sort_param
->
seg
,(
uchar
*
)
a
,
USE_WHOLE_KEY
);
return
(
sort_delete_record
(
sort_param
));
}
#ifndef DBUG_OFF
...
...
@@ -3182,7 +3184,7 @@ static int sort_ft_key_write(MI_SORT_PARAM *sort_param, const void *a)
get_key_full_length_rdonly
(
val_off
,
ft_buf
->
lastkey
);
if
(
val_off
==
a_len
&&
mi_compare_text
(
sort_param
->
keyinfo
->
seg
->
charset
,
mi_compare_text
(
sort_param
->
seg
->
charset
,
((
uchar
*
)
a
)
+
1
,
a_len
-
1
,
ft_buf
->
lastkey
+
1
,
val_off
-
1
,
0
)
==
0
)
{
...
...
myisam/myisamdef.h
View file @
16a2ea9d
...
...
@@ -295,6 +295,7 @@ typedef struct st_mi_sort_param
uint
maxbuffers
,
keys
,
find_length
,
sort_keys_length
;
my_bool
fix_datafile
,
master
;
MI_KEYDEF
*
keyinfo
;
HA_KEYSEG
*
seg
;
SORT_INFO
*
sort_info
;
uchar
**
sort_keys
;
byte
*
rec_buff
;
...
...
myisam/rt_index.c
View file @
16a2ea9d
...
...
@@ -785,7 +785,7 @@ int rtree_delete(MI_INFO *info, uint keynr, uchar *key, uint key_length)
goto
err1
;
}
if
(
ReinsertList
.
pages
)
free
(
ReinsertList
.
pages
);
my_free
((
byte
*
)
ReinsertList
.
pages
,
MYF
(
0
)
);
/* check for redundant root (not leaf, 1 child) and eliminate */
if
((
old_root
=
info
->
s
->
state
.
key_root
[
keynr
])
==
HA_OFFSET_ERROR
)
...
...
myisam/rt_key.c
View file @
16a2ea9d
...
...
@@ -56,7 +56,7 @@ int rtree_add_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
}
return
(
rtree_split_page
(
info
,
keyinfo
,
page_buf
,
key
,
key_length
,
new_page
)
?
-
1
:
0
);
new_page
)
?
-
1
:
1
);
}
/*
...
...
@@ -69,7 +69,7 @@ int rtree_delete_key(MI_INFO *info, uchar *page_buf, uchar *key,
uchar
*
key_start
;
key_start
=
key
-
nod_flag
;
if
(
nod_flag
)
if
(
!
nod_flag
)
key_length
+=
info
->
s
->
base
.
rec_reflength
;
memmove
(
key_start
,
key
+
key_length
,
page_size
-
key_length
-
...
...
myisam/rt_split.c
View file @
16a2ea9d
...
...
@@ -263,7 +263,7 @@ int rtree_split_page(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, uchar *key,
int
max_keys
=
(
mi_getint
(
page
)
-
2
)
/
(
full_length
);
n_dim
=
(
keyinfo
->
keysegs
-
1
)
/
2
;
n_dim
=
keyinfo
->
keysegs
/
2
;
{
int
coord_buf_size
=
n_dim
*
2
*
sizeof
(
double
)
*
(
max_keys
+
1
+
4
);
...
...
myisam/rt_test.c
View file @
16a2ea9d
...
...
@@ -55,7 +55,7 @@ int run_test(const char *filename)
int
key_type
=
HA_KEYTYPE_DOUBLE
;
int
key_length
=
8
;
int
null_fields
=
0
;
int
nrecords
=
30
;
int
nrecords
=
30
0
;
int
rec_length
=
0
;
int
uniques
=
0
;
int
i
;
...
...
myisam/sort.c
View file @
16a2ea9d
...
...
@@ -111,7 +111,7 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
DBUG_ENTER
(
"_create_index_by_sort"
);
DBUG_PRINT
(
"enter"
,(
"sort_length: %d"
,
info
->
key_length
));
if
(
info
->
keyinfo
->
flag
&
&
HA_VAR_LENGTH_KEY
)
if
(
info
->
keyinfo
->
flag
&
HA_VAR_LENGTH_KEY
)
{
info
->
write_keys
=
write_keys_varlen
;
info
->
read_to_buffer
=
read_to_buffer_varlen
;
...
...
@@ -622,7 +622,7 @@ inline int my_var_write(MI_SORT_PARAM *info,IO_CACHE *to_file,char *bufs)
{
int
err
;
uint16
len
=
_mi_keylength
(
info
->
keyinfo
,
bufs
);
if
((
err
=
my_b_write
(
to_file
,(
byte
*
)
&
len
,
sizeof
(
len
))))
return
(
err
);
if
((
err
=
my_b_write
(
to_file
,(
byte
*
)
bufs
,(
uint
)
len
)))
...
...
@@ -641,7 +641,7 @@ static int NEAR_F write_keys_varlen(MI_SORT_PARAM *info, register uchar **sort_k
qsort2
((
byte
*
)
sort_keys
,
count
,
sizeof
(
byte
*
),(
qsort2_cmp
)
info
->
key_cmp
,
info
);
if
(
!
my_b_inited
(
tempfile
)
&&
open_cached_file
(
tempfile
,
my_tmpdir
(
info
->
tmpdir
),
"ST"
,
open_cached_file
(
tempfile
,
my_tmpdir
(
info
->
tmpdir
),
"ST"
,
DISK_BUFFER_SIZE
,
info
->
sort_info
->
param
->
myf_rw
))
DBUG_RETURN
(
1
);
/* purecov: inspected */
...
...
@@ -650,7 +650,7 @@ static int NEAR_F write_keys_varlen(MI_SORT_PARAM *info, register uchar **sort_k
for
(
end
=
sort_keys
+
count
;
sort_keys
!=
end
;
sort_keys
++
)
{
if
((
err
=
my_var_write
(
info
,
tempfile
,
*
sort_keys
)))
DBUG_RETURN
(
err
);
DBUG_RETURN
(
err
);
}
DBUG_RETURN
(
0
);
}
/* write_keys_varlen */
...
...
@@ -777,7 +777,7 @@ static uint NEAR_F read_to_buffer_varlen(IO_CACHE *fromfile, BUFFPEK *buffpek,
uint16
length_of_key
=
0
;
uint
idx
;
uchar
*
buffp
;
if
((
count
=
(
uint
)
min
((
ha_rows
)
buffpek
->
max_keys
,
buffpek
->
count
)))
{
buffp
=
buffpek
->
base
;
...
...
@@ -786,11 +786,11 @@ static uint NEAR_F read_to_buffer_varlen(IO_CACHE *fromfile, BUFFPEK *buffpek,
{
if
(
my_pread
(
fromfile
->
file
,(
byte
*
)
&
length_of_key
,
sizeof
(
length_of_key
),
buffpek
->
file_pos
,
MYF_RW
))
return
((
uint
)
-
1
);
return
((
uint
)
-
1
);
buffpek
->
file_pos
+=
sizeof
(
length_of_key
);
if
(
my_pread
(
fromfile
->
file
,(
byte
*
)
buffp
,
length_of_key
,
buffpek
->
file_pos
,
MYF_RW
))
return
((
uint
)
-
1
);
return
((
uint
)
-
1
);
buffpek
->
file_pos
+=
length_of_key
;
buffp
=
buffp
+
sort_length
;
}
...
...
sql/field.cc
View file @
16a2ea9d
...
...
@@ -4530,7 +4530,6 @@ void Field_geom::get_key_image(char *buff,uint length,CHARSET_INFO *cs,
ulong
blob_length
=
get_length
(
ptr
);
char
*
blob
;
get_ptr
(
&
blob
);
memcpy
(
buff
+
2
,
blob
,
length
);
MBR
mbr
;
Geometry
gobj
;
...
...
sql/ha_innodb.cc
View file @
16a2ea9d
...
...
@@ -2293,6 +2293,7 @@ convert_search_mode_to_innobase(
case
HA_READ_BEFORE_KEY
:
return
(
PAGE_CUR_L
);
case
HA_READ_PREFIX
:
return
(
PAGE_CUR_GE
);
case
HA_READ_PREFIX_LAST
:
return
(
PAGE_CUR_LE
);
case
HA_READ_PREFIX_LAST_OR_PREV
:
return
(
PAGE_CUR_LE
);
/* In MySQL HA_READ_PREFIX and HA_READ_PREFIX_LAST always
use a complete-field-prefix of a kay value as the search
tuple. I.e., it is not allowed that the last field would
...
...
sql/mysqld.cc
View file @
16a2ea9d
...
...
@@ -1260,7 +1260,8 @@ void yyerror(const char *s)
{
THD
*
thd
=
current_thd
;
char
*
yytext
=
(
char
*
)
thd
->
lex
.
tok_start
;
if
(
!
strcmp
(
s
,
"parse error"
))
/* "parse error" changed into "syntax error" between bison 1.75 and 1.875 */
if
(
strcmp
(
s
,
"parse error"
)
==
0
||
strcmp
(
s
,
"syntax error"
)
==
0
)
s
=
ER
(
ER_SYNTAX_ERROR
);
net_printf
(
thd
,
ER_PARSE_ERROR
,
s
,
yytext
?
(
char
*
)
yytext
:
""
,
thd
->
lex
.
yylineno
);
...
...
sql/opt_range.cc
View file @
16a2ea9d
...
...
@@ -2153,7 +2153,7 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree,
if
(
tmp_min_flag
&
GEOM_FLAG
)
{
tmp
=
param
->
table
->
file
->
records_in_range
((
int
)
keynr
,
(
byte
*
)(
param
->
min_key
+
1
),
records_in_range
((
int
)
keynr
,
(
byte
*
)(
param
->
min_key
),
min_key_length
,
(
ha_rkey_function
)(
tmp_min_flag
^
GEOM_FLAG
),
(
byte
*
)
NullS
,
0
,
HA_READ_KEY_EXACT
);
...
...
sql/sql_table.cc
View file @
16a2ea9d
...
...
@@ -705,14 +705,6 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
{
if
(
key
->
type
==
Key
::
FULLTEXT
)
column
->
length
=
1
;
/* ft-code ignores it anyway :-) */
else
if
(
key
->
type
==
Key
::
SPATIAL
)
{
/*
BAR: 4 is: (Xmin,Xmax,Ymin,Ymax), this is for 2D case
Lately we'll extend this code to support more dimensions
*/
column
->
length
=
4
*
sizeof
(
double
);
}
else
{
my_printf_error
(
ER_BLOB_KEY_WITHOUT_LENGTH
,
...
...
@@ -722,6 +714,17 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
}
}
}
if
(
key
->
type
==
Key
::
SPATIAL
)
{
if
(
!
column
->
length
)
{
/*
BAR: 4 is: (Xmin,Xmax,Ymin,Ymax), this is for 2D case
Lately we'll extend this code to support more dimensions
*/
column
->
length
=
4
*
sizeof
(
double
);
}
}
if
(
!
(
sql_field
->
flags
&
NOT_NULL_FLAG
))
{
if
(
key
->
type
==
Key
::
PRIMARY
)
...
...
@@ -757,6 +760,9 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
DBUG_RETURN
(
-
1
);
}
}
else
if
(
f_is_geom
(
sql_field
->
pack_flag
))
{
}
else
if
(
column
->
length
>
length
||
((
f_is_packed
(
sql_field
->
pack_flag
)
||
((
file
->
table_flags
()
&
HA_NO_PREFIX_CHAR_KEYS
)
&&
...
...
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