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
00738a2b
Commit
00738a2b
authored
Apr 08, 2004
by
monty@mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
Merge bk-internal.mysql.com:/home/bk/mysql-4.1
into mysql.com:/home/my/mysql-4.1
parents
3b6c3dd2
43546e7a
Changes
14
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
449 additions
and
270 deletions
+449
-270
mysql-test/mysql-test-run.sh
mysql-test/mysql-test-run.sh
+1
-1
mysql-test/r/gis-rtree.result
mysql-test/r/gis-rtree.result
+7
-0
mysql-test/r/grant.result
mysql-test/r/grant.result
+2
-0
mysql-test/t/gis-rtree.test
mysql-test/t/gis-rtree.test
+13
-0
mysql-test/t/grant.test
mysql-test/t/grant.test
+2
-0
sql/field.cc
sql/field.cc
+49
-49
sql/field.h
sql/field.h
+2
-1
sql/handler.cc
sql/handler.cc
+138
-0
sql/handler.h
sql/handler.h
+20
-0
sql/opt_range.cc
sql/opt_range.cc
+161
-180
sql/opt_range.h
sql/opt_range.h
+12
-3
sql/sql_class.cc
sql/sql_class.cc
+2
-1
sql/sql_select.cc
sql/sql_select.cc
+40
-34
sql/table.cc
sql/table.cc
+0
-1
No files found.
mysql-test/mysql-test-run.sh
View file @
00738a2b
...
...
@@ -670,7 +670,7 @@ report_stats () {
$ECHO
"The log files in
$MY_LOG_DIR
may give you some hint"
$ECHO
"of what when wrong."
$ECHO
"If you want to report this error, please read first the documentation at"
$ECHO
"http://www.mysql.com/doc/
M/y
/MySQL_test_suite.html"
$ECHO
"http://www.mysql.com/doc/
en
/MySQL_test_suite.html"
fi
if
test
-z
"
$USE_RUNNING_SERVER
"
...
...
mysql-test/r/gis-rtree.result
View file @
00738a2b
...
...
@@ -750,3 +750,10 @@ analyze table t1;
Table Op Msg_type Msg_text
test.t1 analyze status OK
drop table t1;
CREATE TABLE t1 (
fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
g GEOMETRY NOT NULL,
SPATIAL KEY(g)
) ENGINE=MyISAM;
INSERT INTO t1 (g) VALUES (GeomFromText('LineString(1 2, 2 3)')),(GeomFromText('LineString(1 2, 2 4)'));
drop table t1;
mysql-test/r/grant.result
View file @
00738a2b
...
...
@@ -76,6 +76,8 @@ delete from mysql.db where user='mysqltest_1';
delete from mysql.tables_priv where user='mysqltest_1';
delete from mysql.columns_priv where user='mysqltest_1';
flush privileges;
show grants for mysqltest_1@localhost;
ERROR 42000: There is no such grant defined for user 'mysqltest_1' on host 'localhost'
create table t1 (a int);
GRANT select,update,insert on t1 to mysqltest_1@localhost;
GRANT select (a), update (a),insert(a), references(a) on t1 to mysqltest_1@localhost;
...
...
mysql-test/t/gis-rtree.test
View file @
00738a2b
...
...
@@ -103,3 +103,16 @@ check table t1;
analyze
table
t1
;
drop
table
t1
;
#
# The following crashed gis
#
CREATE
TABLE
t1
(
fid
INT
NOT
NULL
AUTO_INCREMENT
PRIMARY
KEY
,
g
GEOMETRY
NOT
NULL
,
SPATIAL
KEY
(
g
)
)
ENGINE
=
MyISAM
;
INSERT
INTO
t1
(
g
)
VALUES
(
GeomFromText
(
'LineString(1 2, 2 3)'
)),(
GeomFromText
(
'LineString(1 2, 2 4)'
));
#select * from t1 where g<GeomFromText('LineString(1 2, 2 3)');
drop
table
t1
;
mysql-test/t/grant.test
View file @
00738a2b
...
...
@@ -53,6 +53,8 @@ delete from mysql.db where user='mysqltest_1';
delete
from
mysql
.
tables_priv
where
user
=
'mysqltest_1'
;
delete
from
mysql
.
columns_priv
where
user
=
'mysqltest_1'
;
flush
privileges
;
--
error
1141
show
grants
for
mysqltest_1
@
localhost
;
#
# Test what happens when you have same table and colum level grants
...
...
sql/field.cc
View file @
00738a2b
...
...
@@ -4359,7 +4359,7 @@ int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
set_warning
(
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
ER_WARN_DATA_TRUNCATED
);
error
=
1
;
}
memcpy
(
ptr
+
2
,
from
,
length
);
memcpy
(
ptr
+
HA_KEY_BLOB_LENGTH
,
from
,
length
);
int2store
(
ptr
,
length
);
return
error
;
}
...
...
@@ -4388,18 +4388,18 @@ int Field_varstring::store(longlong nr)
double
Field_varstring
::
val_real
(
void
)
{
int
not_used
;
uint
length
=
uint2korr
(
ptr
)
+
2
;
uint
length
=
uint2korr
(
ptr
)
+
HA_KEY_BLOB_LENGTH
;
CHARSET_INFO
*
cs
=
charset
();
return
my_strntod
(
cs
,
ptr
+
2
,
length
,
(
char
**
)
0
,
&
not_used
);
return
my_strntod
(
cs
,
ptr
+
HA_KEY_BLOB_LENGTH
,
length
,
(
char
**
)
0
,
&
not_used
);
}
longlong
Field_varstring
::
val_int
(
void
)
{
int
not_used
;
uint
length
=
uint2korr
(
ptr
)
+
2
;
uint
length
=
uint2korr
(
ptr
)
+
HA_KEY_BLOB_LENGTH
;
CHARSET_INFO
*
cs
=
charset
();
return
my_strntoll
(
cs
,
ptr
+
2
,
length
,
10
,
NULL
,
&
not_used
);
return
my_strntoll
(
cs
,
ptr
+
HA_KEY_BLOB_LENGTH
,
length
,
10
,
NULL
,
&
not_used
);
}
...
...
@@ -4407,7 +4407,7 @@ String *Field_varstring::val_str(String *val_buffer __attribute__((unused)),
String
*
val_ptr
)
{
uint
length
=
uint2korr
(
ptr
);
val_ptr
->
set
((
const
char
*
)
ptr
+
2
,
length
,
field_charset
);
val_ptr
->
set
((
const
char
*
)
ptr
+
HA_KEY_BLOB_LENGTH
,
length
,
field_charset
);
return
val_ptr
;
}
...
...
@@ -4417,18 +4417,21 @@ int Field_varstring::cmp(const char *a_ptr, const char *b_ptr)
uint
a_length
=
uint2korr
(
a_ptr
);
uint
b_length
=
uint2korr
(
b_ptr
);
int
diff
;
diff
=
my_strnncoll
(
field_charset
,
(
const
uchar
*
)
a_ptr
+
2
,
min
(
a_length
,
b_length
),
(
const
uchar
*
)
b_ptr
+
2
,
min
(
a_length
,
b_length
));
diff
=
my_strnncoll
(
field_charset
,
(
const
uchar
*
)
a_ptr
+
HA_KEY_BLOB_LENGTH
,
min
(
a_length
,
b_length
),
(
const
uchar
*
)
b_ptr
+
HA_KEY_BLOB_LENGTH
,
min
(
a_length
,
b_length
));
return
diff
?
diff
:
(
int
)
(
a_length
-
b_length
);
}
void
Field_varstring
::
sort_string
(
char
*
to
,
uint
length
)
{
uint
tot_length
=
uint2korr
(
ptr
);
tot_length
=
my_strnxfrm
(
field_charset
,
(
unsigned
char
*
)
to
,
length
,
(
unsigned
char
*
)
ptr
+
2
,
tot_length
);
tot_length
=
my_strnxfrm
(
field_charset
,
(
uchar
*
)
to
,
length
,
(
uchar
*
)
ptr
+
HA_KEY_BLOB_LENGTH
,
tot_length
);
if
(
tot_length
<
length
)
field_charset
->
cset
->
fill
(
field_charset
,
to
+
tot_length
,
length
-
tot_length
,
binary
()
?
(
char
)
0
:
' '
);
...
...
@@ -4453,7 +4456,7 @@ char *Field_varstring::pack(char *to, const char *from, uint max_length)
if
(
max_length
>
255
)
*
to
++=
(
char
)
(
length
>>
8
);
if
(
length
)
memcpy
(
to
,
from
+
2
,
length
);
memcpy
(
to
,
from
+
HA_KEY_BLOB_LENGTH
,
length
);
return
to
+
length
;
}
...
...
@@ -4473,7 +4476,7 @@ const char *Field_varstring::unpack(char *to, const char *from)
to
[
1
]
=
*
from
++
;
}
if
(
length
)
memcpy
(
to
+
2
,
from
,
length
);
memcpy
(
to
+
HA_KEY_BLOB_LENGTH
,
from
,
length
);
return
from
+
length
;
}
...
...
@@ -4484,8 +4487,8 @@ int Field_varstring::pack_cmp(const char *a, const char *b, uint key_length)
uint
b_length
;
if
(
key_length
>
255
)
{
a_length
=
uint2korr
(
a
);
a
+=
2
;
b_length
=
uint2korr
(
b
);
b
+=
2
;
a_length
=
uint2korr
(
a
);
a
+=
2
;
b_length
=
uint2korr
(
b
);
b
+=
2
;
}
else
{
...
...
@@ -4493,32 +4496,32 @@ int Field_varstring::pack_cmp(const char *a, const char *b, uint key_length)
b_length
=
(
uint
)
(
uchar
)
*
b
++
;
}
return
my_strnncoll
(
field_charset
,
(
const
uchar
*
)
a
,
a_length
,
(
const
uchar
*
)
b
,
b_length
);
(
const
uchar
*
)
a
,
a_length
,
(
const
uchar
*
)
b
,
b_length
);
}
int
Field_varstring
::
pack_cmp
(
const
char
*
b
,
uint
key_length
)
{
char
*
a
=
ptr
+
2
;
uint
a_length
=
uint2korr
(
ptr
);
char
*
a
=
ptr
+
HA_KEY_BLOB_LENGTH
;
uint
a_length
=
uint2korr
(
ptr
);
uint
b_length
;
if
(
key_length
>
255
)
{
b_length
=
uint2korr
(
b
);
b
+=
2
;
b_length
=
uint2korr
(
b
);
b
+=
2
;
}
else
{
b_length
=
(
uint
)
(
uchar
)
*
b
++
;
}
return
my_strnncoll
(
field_charset
,
(
const
uchar
*
)
a
,
a_length
,
(
const
uchar
*
)
b
,
b_length
);
(
const
uchar
*
)
a
,
a_length
,
(
const
uchar
*
)
b
,
b_length
);
}
uint
Field_varstring
::
packed_col_length
(
const
char
*
data_ptr
,
uint
length
)
{
if
(
length
>
255
)
return
uint2korr
(
data_ptr
)
+
2
;
return
uint2korr
(
data_ptr
)
+
HA_KEY_BLOB_LENGTH
;
else
return
(
uint
)
((
uchar
)
*
data_ptr
)
+
1
;
}
...
...
@@ -4531,22 +4534,21 @@ uint Field_varstring::max_packed_col_length(uint max_length)
void
Field_varstring
::
get_key_image
(
char
*
buff
,
uint
length
,
CHARSET_INFO
*
cs
,
imagetype
type
)
{
length
-=
HA_KEY_BLOB_LENGTH
;
uint
f_length
=
uint2korr
(
ptr
);
if
(
f_length
>
length
)
f_length
=
length
;
int2store
(
buff
,
length
);
memcpy
(
buff
+
2
,
ptr
+
2
,
length
);
memcpy
(
buff
+
HA_KEY_BLOB_LENGTH
,
ptr
+
HA_KEY_BLOB_LENGTH
,
length
);
#ifdef HAVE_purify
if
(
f_length
<
length
)
bzero
(
buff
+
2
+
f_length
,
(
length
-
f_length
));
bzero
(
buff
+
HA_KEY_BLOB_LENGTH
+
f_length
,
(
length
-
f_length
));
#endif
}
void
Field_varstring
::
set_key_image
(
char
*
buff
,
uint
length
,
CHARSET_INFO
*
cs
)
{
length
=
uint2korr
(
buff
);
// Real length is here
(
void
)
Field_varstring
::
store
(
buff
+
2
,
length
,
cs
);
(
void
)
Field_varstring
::
store
(
buff
+
HA_KEY_BLOB_LENGTH
,
length
,
cs
);
}
...
...
@@ -4799,7 +4801,6 @@ int Field_blob::cmp_binary(const char *a_ptr, const char *b_ptr,
void
Field_blob
::
get_key_image
(
char
*
buff
,
uint
length
,
CHARSET_INFO
*
cs
,
imagetype
type
)
{
length
-=
HA_KEY_BLOB_LENGTH
;
uint32
blob_length
=
get_length
(
ptr
);
char
*
blob
;
...
...
@@ -4838,18 +4839,18 @@ void Field_blob::get_key_image(char *buff,uint length,
Must clear this as we do a memcmp in opt_range.cc to detect
identical keys
*/
bzero
(
buff
+
2
+
blob_length
,
(
length
-
blob_length
));
bzero
(
buff
+
HA_KEY_BLOB_LENGTH
+
blob_length
,
(
length
-
blob_length
));
length
=
(
uint
)
blob_length
;
}
int2store
(
buff
,
length
);
get_ptr
(
&
blob
);
memcpy
(
buff
+
2
,
blob
,
length
);
memcpy
(
buff
+
HA_KEY_BLOB_LENGTH
,
blob
,
length
);
}
void
Field_blob
::
set_key_image
(
char
*
buff
,
uint
length
,
CHARSET_INFO
*
cs
)
{
length
=
uint2korr
(
buff
);
(
void
)
Field_blob
::
store
(
buff
+
2
,
length
,
cs
);
length
=
uint2korr
(
buff
);
(
void
)
Field_blob
::
store
(
buff
+
HA_KEY_BLOB_LENGTH
,
length
,
cs
);
}
...
...
@@ -4857,16 +4858,16 @@ int Field_blob::key_cmp(const byte *key_ptr, uint max_key_length)
{
char
*
blob1
;
uint
blob_length
=
get_length
(
ptr
);
max_key_length
-=
2
;
memcpy_fixed
(
&
blob1
,
ptr
+
packlength
,
sizeof
(
char
*
));
return
Field_blob
::
cmp
(
blob1
,
min
(
blob_length
,
max_key_length
),
(
char
*
)
key_ptr
+
2
,
uint2korr
(
key_ptr
));
(
char
*
)
key_ptr
+
HA_KEY_BLOB_LENGTH
,
uint2korr
(
key_ptr
));
}
int
Field_blob
::
key_cmp
(
const
byte
*
a
,
const
byte
*
b
)
{
return
Field_blob
::
cmp
((
char
*
)
a
+
2
,
uint2korr
(
a
),
(
char
*
)
b
+
2
,
uint2korr
(
b
));
return
Field_blob
::
cmp
((
char
*
)
a
+
HA_KEY_BLOB_LENGTH
,
uint2korr
(
a
),
(
char
*
)
b
+
HA_KEY_BLOB_LENGTH
,
uint2korr
(
b
));
}
...
...
@@ -4882,8 +4883,8 @@ void Field_blob::sort_string(char *to,uint length)
memcpy_fixed
(
&
blob
,
ptr
+
packlength
,
sizeof
(
char
*
));
blob_length
=
my_strnxfrm
(
field_charset
,
(
u
nsigned
char
*
)
to
,
length
,
(
u
nsigned
char
*
)
blob
,
blob_length
);
(
u
char
*
)
to
,
length
,
(
u
char
*
)
blob
,
blob_length
);
if
(
blob_length
<
length
)
field_charset
->
cset
->
fill
(
field_charset
,
to
+
blob_length
,
length
-
blob_length
,
...
...
@@ -4965,8 +4966,8 @@ int Field_blob::pack_cmp(const char *a, const char *b, uint key_length)
b_length
=
(
uint
)
(
uchar
)
*
b
++
;
}
return
my_strnncoll
(
field_charset
,
(
const
uchar
*
)
a
,
a_length
,
(
const
uchar
*
)
b
,
b_length
);
(
const
uchar
*
)
a
,
a_length
,
(
const
uchar
*
)
b
,
b_length
);
}
...
...
@@ -4988,8 +4989,8 @@ int Field_blob::pack_cmp(const char *b, uint key_length)
b_length
=
(
uint
)
(
uchar
)
*
b
++
;
}
return
my_strnncoll
(
field_charset
,
(
const
uchar
*
)
a
,
a_length
,
(
const
uchar
*
)
b
,
b_length
);
(
const
uchar
*
)
a
,
a_length
,
(
const
uchar
*
)
b
,
b_length
);
}
/* Create a packed key that will be used for storage from a MySQL row */
...
...
@@ -5025,7 +5026,7 @@ char *Field_blob::pack_key_from_key_image(char *to, const char *from,
if
(
max_length
>
255
)
*
to
++=
(
char
)
(
length
>>
8
);
if
(
length
)
memcpy
(
to
,
from
+
2
,
length
);
memcpy
(
to
,
from
+
HA_KEY_BLOB_LENGTH
,
length
);
return
to
+
length
;
}
...
...
@@ -5048,11 +5049,12 @@ uint Field_blob::max_packed_col_length(uint max_length)
void
Field_geom
::
get_key_image
(
char
*
buff
,
uint
length
,
CHARSET_INFO
*
cs
,
imagetype
type
)
{
length
-=
HA_KEY_BLOB_LENGTH
;
ulong
blob_length
=
get_length
(
ptr
);
char
*
blob
;
const
char
*
dummy
;
MBR
mbr
;
ulong
blob_length
=
get_length
(
ptr
);
Geometry_buffer
buffer
;
Geometry
*
gobj
;
if
(
blob_length
<
SRID_SIZE
)
{
...
...
@@ -5060,8 +5062,6 @@ void Field_geom::get_key_image(char *buff, uint length, CHARSET_INFO *cs,
return
;
}
get_ptr
(
&
blob
);
Geometry_buffer
buffer
;
Geometry
*
gobj
;
gobj
=
Geometry
::
create_from_wkb
(
&
buffer
,
blob
+
SRID_SIZE
,
blob_length
-
SRID_SIZE
);
if
(
gobj
->
get_mbr
(
&
mbr
,
&
dummy
))
...
...
@@ -5554,7 +5554,7 @@ uint32 calc_pack_length(enum_field_types type,uint32 length)
switch
(
type
)
{
case
FIELD_TYPE_STRING
:
case
FIELD_TYPE_DECIMAL
:
return
(
length
);
case
FIELD_TYPE_VAR_STRING
:
return
(
length
+
2
);
case
FIELD_TYPE_VAR_STRING
:
return
(
length
+
HA_KEY_BLOB_LENGTH
);
case
FIELD_TYPE_YEAR
:
case
FIELD_TYPE_TINY
:
return
1
;
case
FIELD_TYPE_SHORT
:
return
2
;
...
...
sql/field.h
View file @
00738a2b
...
...
@@ -212,7 +212,8 @@ class Field
{
memcpy
(
buff
,
ptr
,
length
);
}
inline
void
set_image
(
char
*
buff
,
uint
length
,
CHARSET_INFO
*
cs
)
{
memcpy
(
ptr
,
buff
,
length
);
}
virtual
void
get_key_image
(
char
*
buff
,
uint
length
,
CHARSET_INFO
*
cs
,
imagetype
type
)
virtual
void
get_key_image
(
char
*
buff
,
uint
length
,
CHARSET_INFO
*
cs
,
imagetype
type
)
{
get_image
(
buff
,
length
,
cs
);
}
virtual
void
set_key_image
(
char
*
buff
,
uint
length
,
CHARSET_INFO
*
cs
)
{
set_image
(
buff
,
length
,
cs
);
}
...
...
sql/handler.cc
View file @
00738a2b
...
...
@@ -1287,3 +1287,141 @@ int ha_change_key_cache(KEY_CACHE *old_key_cache,
mi_change_key_cache
(
old_key_cache
,
new_key_cache
);
return
0
;
}
/*
Read first row between two ranges.
Store ranges for future calls to read_range_next
SYNOPSIS
read_range_first()
start_key Start key. Is 0 if no min range
end_key End key. Is 0 if no max range
sorted Set to 1 if result should be sorted per key
NOTES
Record is read into table->record[0]
RETURN
0 Found row
HA_ERR_END_OF_FILE No rows in range
# Error code
*/
int
handler
::
read_range_first
(
const
key_range
*
start_key
,
const
key_range
*
end_key
,
bool
sorted
)
{
int
result
;
DBUG_ENTER
(
"handler::read_range_first"
);
end_range
=
0
;
if
(
end_key
)
{
end_range
=
&
save_end_range
;
save_end_range
=
*
end_key
;
key_compare_result_on_equal
=
((
end_key
->
flag
==
HA_READ_BEFORE_KEY
)
?
1
:
(
end_key
->
flag
==
HA_READ_AFTER_KEY
)
?
-
1
:
0
);
}
range_key_part
=
table
->
key_info
[
active_index
].
key_part
;
if
(
!
start_key
)
// Read first record
result
=
index_first
(
table
->
record
[
0
]);
else
result
=
index_read
(
table
->
record
[
0
],
start_key
->
key
,
start_key
->
length
,
start_key
->
flag
);
if
(
result
)
DBUG_RETURN
((
result
==
HA_ERR_KEY_NOT_FOUND
||
result
==
HA_ERR_END_OF_FILE
)
?
HA_ERR_END_OF_FILE
:
result
);
DBUG_RETURN
(
compare_key
(
end_range
)
<=
0
?
0
:
HA_ERR_END_OF_FILE
);
}
/*
Read next row between two ranges.
SYNOPSIS
read_range_next()
eq_range Set to 1 if start_key == end_key
NOTES
Record is read into table->record[0]
RETURN
0 Found row
HA_ERR_END_OF_FILE No rows in range
# Error code
*/
int
handler
::
read_range_next
(
bool
eq_range
)
{
int
result
;
DBUG_ENTER
(
"handler::read_range_next"
);
if
(
eq_range
)
result
=
index_next_same
(
table
->
record
[
0
],
end_range
->
key
,
end_range
->
length
);
else
result
=
index_next
(
table
->
record
[
0
]);
if
(
result
)
DBUG_RETURN
(
result
);
DBUG_RETURN
(
compare_key
(
end_range
)
<=
0
?
0
:
HA_ERR_END_OF_FILE
);
}
/*
Compare if found key is over max-value
SYNOPSIS
compare_key
range key to compare to row
NOTES
For this to work, the row must be stored in table->record[0]
RETURN
0 Key is equal to range or 'range' == 0 (no range)
-1 Key is less than range
1 Key is larger than range
*/
int
handler
::
compare_key
(
key_range
*
range
)
{
KEY_PART_INFO
*
key_part
=
range_key_part
;
uint
store_length
;
if
(
!
range
)
return
0
;
// No max range
for
(
const
char
*
key
=
range
->
key
,
*
end
=
key
+
range
->
length
;
key
<
end
;
key
+=
store_length
,
key_part
++
)
{
int
cmp
;
store_length
=
key_part
->
store_length
;
if
(
key_part
->
null_bit
)
{
if
(
*
key
)
{
if
(
!
key_part
->
field
->
is_null
())
return
1
;
continue
;
}
else
if
(
key_part
->
field
->
is_null
())
return
0
;
key
++
;
// Skip null byte
store_length
--
;
}
if
((
cmp
=
key_part
->
field
->
key_cmp
((
byte
*
)
key
,
key_part
->
length
))
<
0
)
return
-
1
;
if
(
cmp
>
0
)
return
1
;
}
return
key_compare_result_on_equal
;
}
sql/handler.h
View file @
00738a2b
...
...
@@ -218,6 +218,14 @@ typedef struct st_ha_check_opt
}
HA_CHECK_OPT
;
typedef
struct
st_key_range
{
const
byte
*
key
;
uint
length
;
enum
ha_rkey_function
flag
;
}
key_range
;
class
handler
:
public
Sql_alloc
{
protected:
...
...
@@ -239,6 +247,12 @@ class handler :public Sql_alloc
time_t
create_time
;
/* When table was created */
time_t
check_time
;
time_t
update_time
;
/* The following are for read_range() */
key_range
save_end_range
,
*
end_range
;
KEY_PART_INFO
*
range_key_part
;
int
key_compare_result_on_equal
;
uint
errkey
;
/* Last dup key */
uint
sortkey
,
key_used_on_scan
;
uint
active_index
;
...
...
@@ -250,6 +264,7 @@ class handler :public Sql_alloc
bool
auto_increment_column_changed
;
bool
implicit_emptied
;
/* Can be !=0 only if HEAP */
handler
(
TABLE
*
table_arg
)
:
table
(
table_arg
),
ref
(
0
),
data_file_length
(
0
),
max_data_file_length
(
0
),
index_file_length
(
0
),
delete_length
(
0
),
auto_increment_value
(
0
),
...
...
@@ -298,6 +313,11 @@ class handler :public Sql_alloc
{
return
(
my_errno
=
HA_ERR_WRONG_COMMAND
);
}
virtual
int
handler
::
read_range_first
(
const
key_range
*
start_key
,
const
key_range
*
end_key
,
bool
sorted
);
virtual
int
handler
::
read_range_next
(
bool
eq_range
);
int
handler
::
compare_key
(
key_range
*
range
);
virtual
int
ft_init
()
{
return
-
1
;
}
virtual
FT_INFO
*
ft_init_ext
(
uint
flags
,
uint
inx
,
const
byte
*
key
,
uint
keylen
)
...
...
sql/opt_range.cc
View file @
00738a2b
This diff is collapsed.
Click to expand it.
sql/opt_range.h
View file @
00738a2b
...
...
@@ -35,7 +35,7 @@
typedef
struct
st_key_part
{
uint16
key
,
part
,
part_
length
;
uint16
key
,
part
,
store_length
,
length
;
uint8
null_bit
;
Field
*
field
;
Field
::
imagetype
image_type
;
...
...
@@ -68,7 +68,7 @@ class QUICK_RANGE :public Sql_alloc {
class
QUICK_SELECT
{
public:
bool
next
,
dont_free
;
bool
next
,
dont_free
,
sorted
;
int
error
;
uint
index
,
max_used_key_length
,
used_key_parts
;
TABLE
*
head
;
...
...
@@ -89,11 +89,20 @@ class QUICK_SELECT {
int
init
()
{
return
error
=
file
->
index_init
(
index
);
}
virtual
int
get_next
();
virtual
bool
reverse_sorted
()
{
return
0
;
}
int
cmp_next
(
QUICK_RANGE
*
range
);
bool
unique_key_range
();
};
class
QUICK_SELECT_GEOM
:
public
QUICK_SELECT
{
public:
QUICK_SELECT_GEOM
(
THD
*
thd
,
TABLE
*
table
,
uint
index_arg
,
bool
no_alloc
)
:
QUICK_SELECT
(
thd
,
table
,
index_arg
,
no_alloc
)
{};
virtual
int
get_next
();
};
class
QUICK_SELECT_DESC
:
public
QUICK_SELECT
{
public:
...
...
sql/sql_class.cc
View file @
00738a2b
...
...
@@ -86,7 +86,8 @@ extern "C" void free_user_var(user_var_entry *entry)
THD
::
THD
()
:
user_time
(
0
),
current_statement
(
0
),
is_fatal_error
(
0
),
last_insert_id_used
(
0
),
insert_id_used
(
0
),
rand_used
(
0
),
in_lock_tables
(
0
),
global_read_lock
(
0
),
bootstrap
(
0
)
global_read_lock
(
0
),
bootstrap
(
0
),
no_table_fix_fields_cache
(
0
)
{
host
=
user
=
priv_user
=
db
=
ip
=
0
;
host_or_ip
=
"connecting host"
;
...
...
sql/sql_select.cc
View file @
00738a2b
...
...
@@ -3746,7 +3746,8 @@ make_join_readinfo(JOIN *join, uint options)
table
->
key_read
=
1
;
table
->
file
->
extra
(
HA_EXTRA_KEYREAD
);
}
else
if
(
!
table
->
used_keys
.
is_clear_all
()
&&
!
(
tab
->
select
&&
tab
->
select
->
quick
))
else
if
(
!
table
->
used_keys
.
is_clear_all
()
&&
!
(
tab
->
select
&&
tab
->
select
->
quick
))
{
// Only read index tree
tab
->
index
=
find_shortest_key
(
table
,
&
table
->
used_keys
);
tab
->
table
->
file
->
index_init
(
tab
->
index
);
...
...
@@ -6907,6 +6908,7 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
key_part_end
=
key_part
+
table
->
key_info
[
idx
].
key_parts
;
key_part_map
const_key_parts
=
table
->
const_key_parts
[
idx
];
int
reverse
=
0
;
DBUG_ENTER
(
"test_if_order_by_key"
);
for
(;
order
;
order
=
order
->
next
,
const_key_parts
>>=
1
)
{
...
...
@@ -6917,25 +6919,24 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
Skip key parts that are constants in the WHERE clause.
These are already skipped in the ORDER BY by const_expression_in_where()
*/
while
(
const_key_parts
&
1
)
{
key_part
++
;
const_key_parts
>>=
1
;
}
for
(;
const_key_parts
&
1
;
const_key_parts
>>=
1
)
key_part
++
;
if
(
key_part
==
key_part_end
||
key_part
->
field
!=
field
)
return
0
;
DBUG_RETURN
(
0
)
;
/* set flag to 1 if we can use read-next on key, else to -1 */
flag
=
(
order
->
asc
==
!
(
key_part
->
key_part_flag
&
HA_REVERSE_SORT
))
?
1
:
-
1
;
flag
=
((
order
->
asc
==
!
(
key_part
->
key_part_flag
&
HA_REVERSE_SORT
))
?
1
:
-
1
);
if
(
reverse
&&
flag
!=
reverse
)
return
0
;
DBUG_RETURN
(
0
)
;
reverse
=
flag
;
// Remember if reverse
key_part
++
;
}
*
used_key_parts
=
(
uint
)
(
key_part
-
table
->
key_info
[
idx
].
key_part
);
return
reverse
;
DBUG_RETURN
(
reverse
)
;
}
static
uint
find_shortest_key
(
TABLE
*
table
,
const
key_map
*
usable_keys
)
{
uint
min_length
=
(
uint
)
~
0
;
...
...
@@ -6958,18 +6959,20 @@ static uint find_shortest_key(TABLE *table, const key_map *usable_keys)
}
/*
Test if a second key is the subkey of the first one.
SYNOPSIS
is_subkey()
key_part - first key parts
ref_key_part - second key parts
ref_key_part_end - last+1 part of the second key
DESCRIPTION
Test if a second key is the subkey of the first one.
key_part First key parts
ref_key_part Second key parts
ref_key_part_end Last+1 part of the second key
NOTE
Second key MUST be shorter than the first one.
RETURN
1
- is the
subkey
0
- otherwise
1
is a
subkey
0
no sub key
*/
inline
bool
...
...
@@ -6983,20 +6986,21 @@ is_subkey(KEY_PART_INFO *key_part, KEY_PART_INFO *ref_key_part,
}
/*
Test if we can use one of the 'usable_keys' instead of 'ref' key for sorting
SYNOPSIS
test_if_subkey()
ref - number of key, used for WHERE clause
usable_keys - keys for testing
DESCRIPTION
Test if we can use one of the 'usable_keys' instead of 'ref' key.
ref Number of key, used for WHERE clause
usable_keys Keys for testing
RETURN
MAX_KEY
- i
f we can't use other key
the number of found key
- o
therwise
MAX_KEY
I
f we can't use other key
the number of found key
O
therwise
*/
static
uint
test_if_subkey
(
ORDER
*
order
,
TABLE
*
table
,
uint
ref
,
uint
ref_key_parts
,
const
key_map
&
usable_keys
)
const
key_map
*
usable_keys
)
{
uint
nr
;
uint
min_length
=
(
uint
)
~
0
;
...
...
@@ -7007,7 +7011,7 @@ test_if_subkey(ORDER *order, TABLE *table, uint ref, uint ref_key_parts,
for
(
nr
=
0
;
nr
<
table
->
keys
;
nr
++
)
{
if
(
usable_keys
.
is_set
(
nr
)
&&
if
(
usable_keys
->
is_set
(
nr
)
&&
table
->
key_info
[
nr
].
key_length
<
min_length
&&
table
->
key_info
[
nr
].
key_parts
>=
ref_key_parts
&&
is_subkey
(
table
->
key_info
[
nr
].
key_part
,
ref_key_part
,
...
...
@@ -7051,12 +7055,12 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
if
((
*
tmp_order
->
item
)
->
type
()
!=
Item
::
FIELD_ITEM
)
{
usable_keys
.
clear_all
();
break
;
DBUG_RETURN
(
0
)
;
}
usable_keys
.
intersect
(
((
Item_field
*
)
(
*
tmp_order
->
item
))
->
field
->
part_of_sortkey
);
usable_keys
.
intersect
(
((
Item_field
*
)
(
*
tmp_order
->
item
))
->
field
->
part_of_sortkey
);
if
(
usable_keys
.
is_clear_all
())
break
;
// No usable keys
DBUG_RETURN
(
0
)
;
// No usable keys
}
ref_key
=
-
1
;
...
...
@@ -7092,9 +7096,9 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
keys
*/
if
(
table
->
used_keys
.
is_set
(
ref_key
))
usable_keys
.
merge
(
table
->
used_keys
);
usable_keys
.
intersect
(
table
->
used_keys
);
if
((
new_ref_key
=
test_if_subkey
(
order
,
table
,
ref_key
,
ref_key_parts
,
usable_keys
))
<
MAX_KEY
)
&
usable_keys
))
<
MAX_KEY
)
{
/* Found key that can be used to retrieve data in sorted order */
if
(
tab
->
ref
.
key
>=
0
)
...
...
@@ -7154,6 +7158,8 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
/* fall through */
}
}
else
if
(
select
&&
select
->
quick
)
select
->
quick
->
sorted
=
1
;
DBUG_RETURN
(
1
);
/* No need to sort */
}
}
...
...
@@ -7292,9 +7298,9 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
For impossible ranges (like when doing a lookup on NULL on a NOT NULL
field, quick will contain an empty record set.
*/
if
(
!
(
select
->
quick
=
tab
->
type
==
JT_FT
?
if
(
!
(
select
->
quick
=
(
tab
->
type
==
JT_FT
?
new
FT_SELECT
(
thd
,
table
,
tab
->
ref
.
key
)
:
get_quick_select_for_ref
(
thd
,
table
,
&
tab
->
ref
)))
get_quick_select_for_ref
(
thd
,
table
,
&
tab
->
ref
)
)))
goto
err
;
}
}
...
...
sql/table.cc
View file @
00738a2b
...
...
@@ -553,7 +553,6 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
keyinfo
->
key_length
+=
HA_KEY_NULL_LENGTH
;
}
if
(
field
->
type
()
==
FIELD_TYPE_BLOB
||
field
->
type
()
==
FIELD_TYPE_GEOMETRY
||
field
->
real_type
()
==
FIELD_TYPE_VAR_STRING
)
{
if
(
field
->
type
()
==
FIELD_TYPE_BLOB
)
...
...
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