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
87fd219d
Commit
87fd219d
authored
Dec 13, 2001
by
monty@hundin.mysql.fi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed sleep time in mysql-test-run
Fixed bug in query cache. Cleaned up des_crypt code.
parent
8bef3771
Changes
24
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
828 additions
and
384 deletions
+828
-384
Docs/manual.texi
Docs/manual.texi
+8
-6
mysql-test/mysql-test-run.sh
mysql-test/mysql-test-run.sh
+18
-9
mysql-test/r/group_by.result
mysql-test/r/group_by.result
+47
-0
mysql-test/r/innodb_cache.result
mysql-test/r/innodb_cache.result
+15
-0
mysql-test/r/query_cache.result
mysql-test/r/query_cache.result
+2
-14
mysql-test/r/union.result
mysql-test/r/union.result
+8
-0
mysql-test/t/func_str.test
mysql-test/t/func_str.test
+1
-0
mysql-test/t/innodb_cache-master.opt
mysql-test/t/innodb_cache-master.opt
+1
-0
mysql-test/t/innodb_cache.test
mysql-test/t/innodb_cache.test
+14
-0
mysql-test/t/query_cache.test
mysql-test/t/query_cache.test
+2
-13
mysql-test/t/union.test
mysql-test/t/union.test
+2
-0
mysys/my_winsem.c
mysys/my_winsem.c
+74
-100
sql/des_key_file.cc
sql/des_key_file.cc
+58
-50
sql/item_strfunc.cc
sql/item_strfunc.cc
+108
-115
sql/item_strfunc.h
sql/item_strfunc.h
+2
-3
sql/mysql_priv.h
sql/mysql_priv.h
+2
-2
sql/mysqld.cc
sql/mysqld.cc
+0
-3
sql/sql_acl.cc
sql/sql_acl.cc
+28
-6
sql/sql_cache.cc
sql/sql_cache.cc
+361
-11
sql/sql_cache.h
sql/sql_cache.h
+4
-0
sql/sql_delete.cc
sql/sql_delete.cc
+20
-21
sql/sql_parse.cc
sql/sql_parse.cc
+9
-5
sql/sql_union.cc
sql/sql_union.cc
+28
-18
sql/sql_yacc.yy
sql/sql_yacc.yy
+16
-8
No files found.
Docs/manual.texi
View file @
87fd219d
...
...
@@ -11282,7 +11282,7 @@ mysql> SELECT name, birth, death,
+--------+------------+------------+------+
@end example
The query uses @code{death IS NOT NULL} rather than @code{death
!=
NULL}
The query uses @code{death IS NOT NULL} rather than @code{death
<>
NULL}
because @code{NULL} is a special value. This is explained later.
@xref{Working with NULL, , Working with @code{NULL}}.
...
...
@@ -11367,12 +11367,12 @@ The @code{NULL} value can be surprising until you get used to it.
Conceptually, @code{NULL} means missing value or unknown value and it
is treated somewhat differently than other values. To test for @code{NULL},
you cannot use the arithmetic comparison operators such as @code{=}, @code{<},
or @code{
!=
}. To demonstrate this for yourself, try the following query:
or @code{
<>
}. To demonstrate this for yourself, try the following query:
@example
mysql> SELECT 1 = NULL, 1
!=
NULL, 1 < NULL, 1 > NULL;
mysql> SELECT 1 = NULL, 1
<>
NULL, 1 < NULL, 1 > NULL;
+----------+-----------+----------+----------+
| 1 = NULL | 1
!=
NULL | 1 < NULL | 1 > NULL |
| 1 = NULL | 1
<>
NULL | 1 < NULL | 1 > NULL |
+----------+-----------+----------+----------+
| NULL | NULL | NULL | NULL |
+----------+-----------+----------+----------+
...
...
@@ -11395,7 +11395,7 @@ The default truth value from a boolean operation is 1.
This special treatment of @code{NULL} is why, in the previous section, it
was necessary to determine which animals are no longer alive using
@code{death IS NOT NULL} instead of @code{death
!=
NULL}.
@code{death IS NOT NULL} instead of @code{death
<>
NULL}.
@node Pattern matching, Counting rows, Working with NULL, Retrieving data
...
...
@@ -11413,7 +11413,7 @@ SQL pattern matching allows you to use @samp{_} to match any single
character and @samp{%} to match an arbitrary number of characters (including
zero characters). In MySQL, SQL patterns are case insensitive by
default. Some examples are shown below. Note that you do not use @code{=}
or @code{
!=
} when you use SQL patterns; use the @code{LIKE} or @code{NOT
or @code{
<>
} when you use SQL patterns; use the @code{LIKE} or @code{NOT
LIKE} comparison operators instead.
To find names beginning with @samp{b}:
...
...
@@ -46285,6 +46285,8 @@ Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}.
@itemize @bullet
@item
Fixed problem with @code{GRANT} when using @code{lower_case_table_names == 1}.
@item
Changed @code{SELECT ... IN SHARE MODE} to
@code{SELECT .. LOCK IN SHARE MODE} (as in MySQL 3.23).
@item
mysql-test/mysql-test-run.sh
View file @
87fd219d
...
...
@@ -46,7 +46,7 @@ which ()
sleep_until_file_deleted
()
{
file
=
$1
loop
=
$SLEEP_TIME
loop
=
$SLEEP_TIME
_FOR_DELETE
while
(
test
$loop
-gt
0
)
do
sleep
1
...
...
@@ -61,7 +61,8 @@ sleep_until_file_deleted ()
sleep_until_file_exists
()
{
file
=
$1
loop
=
60
# Should be long enough enough for all cases
loop
=
$2
org_time
=
$2
while
(
test
$loop
-gt
0
)
do
sleep
1
...
...
@@ -71,7 +72,7 @@ sleep_until_file_exists ()
fi
loop
=
`
expr
$loop
- 1
`
done
echo
"ERROR:
$file
was not created in
60
seconds; Aborting"
echo
"ERROR:
$file
was not created in
$org_time
seconds; Aborting"
exit
1
;
}
...
...
@@ -172,7 +173,11 @@ DO_GCOV=""
DO_GDB
=
""
DO_DDD
=
""
DO_CLIENT_GDB
=
""
SLEEP_TIME
=
10
SLEEP_TIME_FOR_DELETE
=
10
SLEEP_TIME_FOR_FIRST_MASTER
=
200
# Enough time to create innodb tables
SLEEP_TIME_FOR_SECOND_MASTER
=
30
SLEEP_TIME_FOR_FIRST_SLAVE
=
30
SLEEP_TIME_FOR_SECOND_SLAVE
=
30
CHARACTER_SET
=
latin1
DBUSER
=
""
START_WAIT_TIMEOUT
=
3
...
...
@@ -235,7 +240,6 @@ while test $# -gt 0; do
EXTRA_MYSQL_TEST_OPT
=
"
$EXTRA_MYSQL_TEST_OPT
$1
"
;;
--sleep
=
*
)
EXTRA_MYSQL_TEST_OPT
=
"
$EXTRA_MYSQL_TEST_OPT
$1
"
SLEEP_TIME
=
`
$ECHO
"
$1
"
|
$SED
-e
"s;--sleep=;;"
`
;;
--mysqld
=
*
)
TMP
=
`
$ECHO
"
$1
"
|
$SED
-e
"s;--mysqld=;;"
`
...
...
@@ -260,8 +264,9 @@ while test $# -gt 0; do
fi
DO_GDB
=
1
# We must use manager, as things doesn't work on Linux without it
USE_MANAGER
=
1
USE_RUNNING_SERVER
=
""
# This needs to be checked properly
# USE_MANAGER=1
# USE_RUNNING_SERVER=""
;;
--client-gdb
)
if
[
x
$BINARY_DIST
=
x1
]
;
then
...
...
@@ -755,7 +760,8 @@ EOF
else
manager_launch master
$MYSQLD
$master_args
fi
sleep_until_file_exists
$MASTER_MYPID
sleep_until_file_exists
$MASTER_MYPID
$wait_for_master
wait_for_master
=
$SLEEP_TIME_FOR_SECOND_MASTER
MASTER_RUNNING
=
1
}
...
...
@@ -847,7 +853,8 @@ start_slave()
manager_launch
$slave_ident
$SLAVE_MYSQLD
$slave_args
fi
eval
"SLAVE
$1_RUNNING
=1"
sleep_until_file_exists
$slave_pid
sleep_until_file_exists
$slave_pid
$wait_for_slave
wait_for_slave
=
$SLEEP_TIME_FOR_SECOND_SLAVE
}
mysql_start
()
...
...
@@ -1143,6 +1150,8 @@ then
# Remove files that can cause problems
$RM
-f
$MYSQL_TEST_DIR
/var/run/
*
$MYSQL_TEST_DIR
/var/tmp/
*
wait_for_master
=
$SLEEP_TIME_FOR_FIRST_MASTER
wait_for_slave
=
$SLEEP_TIME_FOR_FIRST_SLAVE
$ECHO
"Installing Test Databases"
mysql_install_db
start_manager
...
...
mysql-test/r/group_by.result
View file @
87fd219d
...
...
@@ -216,3 +216,50 @@ select 1+1,"a",count(*) from t1 where foo in (2);
1+1 a count(*)
2 a 0
drop table t1;
CREATE TABLE t1 (
spID int(10) unsigned,
userID int(10) unsigned,
score smallint(5) unsigned,
key (spid),
key (score)
);
INSERT INTO t1 VALUES (1,1,1),(2,2,2),(2,1,1),(3,3,3),(4,3,3),(5,3,3);
explain select userid,count(*) from t1 group by userid desc;
table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 6 Using temporary
select userid,count(*) from t1 group by userid desc;
userid count(*)
3 3
2 1
1 2
explain select spid,count(*) from t1 where spid between 1 and 2 group by spid desc;
table type possible_keys key key_len ref rows Extra
t1 range spID spID 5 NULL 2 where used; Using index
explain select spid,count(*) from t1 where spid between 1 and 2 group by spid;
table type possible_keys key key_len ref rows Extra
t1 range spID spID 5 NULL 2 where used; Using index
select spid,count(*) from t1 where spid between 1 and 2 group by spid;
spid count(*)
1 1
2 2
select spid,count(*) from t1 where spid between 1 and 2 group by spid desc;
spid count(*)
explain select sql_big_result spid,sum(userid) from t1 group by spid desc;
table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 6 Using filesort
select sql_big_result spid,sum(userid) from t1 group by spid desc;
spid sum(userid)
5 3
4 3
3 3
2 3
1 1
explain select sql_big_result score,count(*) from t1 group by score desc;
table type possible_keys key key_len ref rows Extra
t1 index NULL score 3 NULL 6 Using index
select sql_big_result score,count(*) from t1 group by score desc;
score count(*)
3 3
2 1
1 2
drop table t1;
mysql-test/r/innodb_cache.result
0 → 100644
View file @
87fd219d
drop table if exists t1;
set autocommit=0;
create table t1 (a int not null) type=innodb;
insert into t1 values (1),(2),(3);
select * from t1;
a
1
2
3
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 0
drop table t1;
commit;
set autocommit=1;
mysql-test/r/query_cache.result
View file @
87fd219d
flush query cache;
flush query cache;
reset query cache;
flush status;
drop table if exists t1,t2,t3;
...
...
@@ -148,20 +150,6 @@ show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 0
drop table t1, t2, t3;
set autocommit=0;
create table t1 (a int not null) type=innodb;
insert into t1 values (1),(2),(3);
select * from t1;
a
1
2
3
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 0
drop table t1;
commit;
set autocommit=1;
create table t1 (a int not null);
insert into t1 values (1),(2),(3);
create table t2 (a int not null);
...
...
mysql-test/r/union.result
View file @
87fd219d
...
...
@@ -74,6 +74,14 @@ a b
2 b
3 c
4 d
(select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1);
a b
1 a
(select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by b desc;
a b
3 c
2 b
1 a
explain select a,b from t1 union all select a,b from t2;
table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 4
...
...
mysql-test/t/func_str.test
View file @
87fd219d
...
...
@@ -35,6 +35,7 @@ select insert('txs',2,1,'hi'),insert('is ',4,0,'a'),insert('txxxxt',2,4,'es');
select
replace
(
'aaaa'
,
'a'
,
'b'
),
replace
(
'aaaa'
,
'aa'
,
'b'
),
replace
(
'aaaa'
,
'a'
,
'bb'
),
replace
(
'aaaa'
,
''
,
'b'
),
replace
(
'bbbb'
,
'a'
,
'c'
);
select
replace
(
concat
(
lcase
(
concat
(
'THIS'
,
' '
,
'IS'
,
' '
,
'A'
,
' '
)),
ucase
(
'false'
),
' '
,
'test'
),
'FALSE'
,
'REAL'
)
;
select
soundex
(
''
),
soundex
(
'he'
),
soundex
(
'hello all folks'
);
--
replace_result
$
1
$aa
$
4
OSUA5cjdx0RUQ08opV27
/
aaqPiZY5xR5l
.
select
password
(
'test'
),
length
(
encrypt
(
'test'
)),
encrypt
(
'test'
,
'aa'
);
select
md5
(
'hello'
);
select
repeat
(
'monty'
,
5
),
concat
(
'*'
,
space
(
5
),
'*'
);
...
...
mysql-test/t/innodb_cache-master.opt
0 → 100644
View file @
87fd219d
--set-variable=query_cache_size=1M
mysql-test/t/innodb_cache.test
0 → 100644
View file @
87fd219d
--
source
include
/
have_innodb
.
inc
#
# Without auto_commit.
#
drop
table
if
exists
t1
;
set
autocommit
=
0
;
create
table
t1
(
a
int
not
null
)
type
=
innodb
;
insert
into
t1
values
(
1
),(
2
),(
3
);
select
*
from
t1
;
show
status
like
"Qcache_queries_in_cache"
;
drop
table
t1
;
commit
;
set
autocommit
=
1
;
mysql-test/t/query_cache.test
View file @
87fd219d
--
source
include
/
have_innodb
.
inc
#
# Tests with query cache
#
# Reset query cache variables.
flush
query
cache
;
# This crashed in some versions
flush
query
cache
;
# This crashed in some versions
reset
query
cache
;
flush
status
;
drop
table
if
exists
t1
,
t2
,
t3
;
...
...
@@ -73,17 +73,6 @@ delete from t3 where a=10;
show
status
like
"Qcache_queries_in_cache"
;
drop
table
t1
,
t2
,
t3
;
#
# Without auto_commit.
#
set
autocommit
=
0
;
create
table
t1
(
a
int
not
null
)
type
=
innodb
;
insert
into
t1
values
(
1
),(
2
),(
3
);
select
*
from
t1
;
show
status
like
"Qcache_queries_in_cache"
;
drop
table
t1
;
commit
;
set
autocommit
=
1
;
#
# FLUSH QUERY CACHE
#
create
table
t1
(
a
int
not
null
);
...
...
mysql-test/t/union.test
View file @
87fd219d
...
...
@@ -18,6 +18,8 @@ select 't1',b,count(*) from t1 group by b UNION select 't2',b,count(*) from t2 g
#test alternate syntax for unions
(
select
a
,
b
from
t1
limit
2
)
union
all
(
select
a
,
b
from
t2
order
by
a
)
limit
4
;
(
select
a
,
b
from
t1
limit
2
)
union
all
(
select
a
,
b
from
t2
order
by
a
limit
1
);
(
select
a
,
b
from
t1
limit
2
)
union
all
(
select
a
,
b
from
t2
order
by
a
limit
1
)
order
by
b
desc
;
# Test some error conditions with UNION
explain
select
a
,
b
from
t1
union
all
select
a
,
b
from
t2
;
...
...
mysys/my_winsem.c
View file @
87fd219d
...
...
@@ -54,30 +54,24 @@
initial value of the semaphore is 'value'
PARAMETERS
sem
pointer to an instance of sem_t
sem Pointer to an instance of sem_t
pshared
if zero, this semaphore may only be shared between
pshared If zero, this semaphore may only be shared between
threads in the same process.
i
f nonzero, the semaphore can be shared between
I
f nonzero, the semaphore can be shared between
processes
value
initial value of the semaphore counter
DESCRIPTION
This function initializes an unnamed semaphore. The
initial value of the semaphore is set to 'value'.
value Initial value of the semaphore counter
RESULTS
0 successfully created semaphore,
-1 failed, error in errno
0 Successfully created semaphore,
-1 Failed, error in errno
ERRNO
EINVAL 'sem' is not a valid semaphore,
ENOSPC a
required resource has been exhausted,
ENOSYS s
emaphores are not supported,
EPERM t
he process lacks appropriate privilege
ENOSPC A
required resource has been exhausted,
ENOSYS S
emaphores are not supported,
EPERM T
he process lacks appropriate privilege
*/
...
...
@@ -133,20 +127,15 @@ sem_init (sem_t *sem, int pshared, unsigned int value)
This function destroys an unnamed semaphore.
PARAMETERS
sem
pointer to an instance of sem_t
DESCRIPTION
This function destroys an unnamed semaphore.
sem Pointer to an instance of sem_t
RESULTS
0 s
uccessfully destroyed semaphore,
-1 f
ailed, error in errno
0 S
uccessfully destroyed semaphore,
-1 F
ailed, error in errno
ERRNO
EINVAL 'sem' is not a valid semaphore,
ENOSYS semaphores are not supported,
EBUSY threads (or processes) are currently
blocked on 'sem'
ENOSYS Semaphores are not supported,
EBUSY Threads (or processes) are currently blocked on 'sem'
*/
int
...
...
@@ -183,27 +172,24 @@ sem_destroy (sem_t * sem)
/*
DOCPUBLIC
This function tries to wait on a semaphore.
PARAMETERS
sem
pointer to an instance of sem_t
DESCRIPTION
This function tries to wait on a semaphore. If the
semaphore value is greater than zero, it decreases
its value by one. If the semaphore value is zero, then
this function returns immediately with the error EAGAIN
PARAMETERS
sem Pointer to an instance of sem_t
RESULTS
0 successfully decreased semaphore,
-1 failed, error in errno
0 Successfully decreased semaphore,
-1 Failed, error in errno
ERRNO
EAGAIN t
he semaphore was already locked,
EAGAIN T
he semaphore was already locked,
EINVAL 'sem' is not a valid semaphore,
ENOSYS s
emaphores are not supported,
EINTR t
he function was interrupted by a signal,
EDEADLK a
deadlock condition was detected.
ENOSYS S
emaphores are not supported,
EINTR T
he function was interrupted by a signal,
EDEADLK A
deadlock condition was detected.
*/
int
...
...
@@ -267,13 +253,6 @@ ptw32_increase_semaphore(sem_t * sem, unsigned int n)
/*
------------------------------------------------------
DOCPUBLIC
This function waits on a semaphore.
PARAMETERS
sem
pointer to an instance of sem_t
DESCRIPTION
This function waits on a semaphore. If the
semaphore value is greater than zero, it decreases
its value by one. If the semaphore value is zero, then
...
...
@@ -281,15 +260,18 @@ ptw32_increase_semaphore(sem_t * sem, unsigned int n)
successfully decrease the value or until interrupted by
a signal.
PARAMETERS
sem Pointer to an instance of sem_t
RESULTS
0 successfully decreased semaphore,
-1 failed, error in errno
ERRNO
EINVAL 'sem' is not a valid semaphore,
ENOSYS semaphores are not supported,
EINTR the function was interrupted by a signal,
EDEADLK a deadlock condition was detected.
0 Successfully decreased semaphore,
-1 Failed, error in errno
ERRNO
EINVAL 'Sem' is not a valid semaphore,
ENOSYS Semaphores are not supported,
EINTR The function was interrupted by a signal,
EDEADLK A deadlock condition was detected.
*/
int
...
...
@@ -331,23 +313,20 @@ sem_wait(sem_t *sem)
/*
------------------------------------------------------
DOCPUBLIC
This function posts a wakeup to a semaphore.
PARAMETERS
sem
pointer to an instance of sem_t
DESCRIPTION
This function posts a wakeup to a semaphore. If there
are waiting threads (or processes), one is awakened;
otherwise, the semaphore value is incremented by one.
PARAMETERS
sem Pointer to an instance of sem_t
RESULTS
0 successfully posted semaphore,
-1 failed, error in errno
0 Successfully posted semaphore,
-1 Failed, error in errno
ERRNO
EINVAL 'sem' is not a valid semaphore,
ENOSYS s
emaphores are not supported,
ENOSYS S
emaphores are not supported,
*/
...
...
@@ -378,26 +357,21 @@ sem_post (sem_t * sem)
/*
------------------------------------------------------
DOCPUBLIC
This function posts multiple wakeups to a semaphore.
PARAMETERS
sem
pointer to an instance of sem_t
count
counter, must be greater than zero.
DESCRIPTION
This function posts multiple wakeups to a semaphore. If there
are waiting threads (or processes), n <= count are awakened;
the semaphore value is incremented by count - n.
PARAMETERS
sem Pointer to an instance of sem_t
count Counter, must be greater than zero.
RESULTS
0 successfully posted semaphore,
-1 failed, error in errno
0 Successfully posted semaphore,
-1 Failed, error in errno
ERRNO
EINVAL 'sem' is not a valid semaphore
or count is less
than or equal to zero.
EINVAL 'sem' is not a valid semaphore or count is less
than or equal to zero.
*/
int
...
...
sql/des_key_file.cc
View file @
87fd219d
...
...
@@ -15,72 +15,80 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <mysql_priv.h>
#include <m_ctype.h>
#ifdef HAVE_OPENSSL
/*
Function which loads DES keys from plaintext file
into memory on MySQL server startup and on command
FLUSH DES_KEYS. Blame tonu@spam.ee on bugs ;)
Function which loads DES keys from plaintext file into memory on MySQL
server startup and on command FLUSH DES_KEYS. Blame tonu@spam.ee on bugs ;)
*/
struct
st_des_keyschedule
des_keyschedule
[
10
];
uint
default_des_key
;
void
load_des_key_file
(
const
char
*
file_name
)
{
FILE
*
file
;
int
ret
=
0
;
char
offset
;
char
buf
[
1024
];
File
file
;
des_cblock
ivec
=
{
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
};
st_des_keyblock
keyblock
;
char
offset
;
IO_CACHE
io
;
DBUG_ENTER
(
"load_des_key_file"
);
VOID
(
pthread_mutex_lock
(
&
LOCK_open
));
DBUG_PRINT
(
"enter"
,(
"name: %s"
,
file_name
));
if
(
!
(
file
=
my_fopen
(
file_name
,
O_RDONLY
,
MYF
(
MY_WME
))))
VOID
(
pthread_mutex_lock
(
&
LOCK_open
));
if
((
file
=
my_open
(
file_name
,
O_RDONLY
|
O_BINARY
,
MYF
(
MY_WME
)))
<
0
||
init_io_cache
(
&
io
,
file
,
IO_SIZE
*
2
,
READ_CACHE
,
0
,
0
,
MYF
(
MY_WME
)))
goto
error
;
bzero
((
char
*
)
des_keyschedule
,
sizeof
(
struct
st_des_keyschedule
)
*
10
);
default_des_key
=
15
;
// Impossible key
for
(;;)
{
goto
error_noclose
;
}
while
(
!
feof
(
file
))
char
*
start
,
*
end
;
char
buf
[
1024
];
st_des_keyblock
keyblock
;
uint
length
;
if
(
!
(
length
=
my_b_gets
(
&
io
,
buf
,
sizeof
(
buf
)
-
1
)))
break
;
// End of file
offset
=
buf
[
0
];
if
(
offset
>=
'0'
&&
offset
<=
'9'
)
// If ok key
{
if
((
my_fread
(
file
,
&
offset
,
1
,
MY_WME
))
!=
1
)
goto
error_close
;
fgets
(
buf
,
sizeof
(
buf
),
file
);
int
len
=
strlen
(
buf
);
if
(
len
-->=
1
)
buf
[
len
]
=
'\0'
;
/* We make good 24-byte (168 bit) key from given plaintext key with MD5 */
offset
-=
'0'
;
if
(
offset
>=
0
&&
offset
<=
9
)
offset
=
(
char
)
(
offset
-
'0'
);
// Remove newline and possible other control characters
for
(
start
=
buf
+
1
;
isspace
(
*
start
)
;
start
++
)
;
end
=
buf
+
length
;
for
(
end
=
strend
(
buf
)
;
end
>
start
&&
iscntrl
(
end
[
-
1
])
;
end
--
)
;
if
(
start
!=
end
)
{
// We make good 24-byte (168 bit) key from given plaintext key with MD5
EVP_BytesToKey
(
EVP_des_ede3_cbc
(),
EVP_md5
(),
NULL
,
(
uchar
*
)
buf
,
strlen
(
buf
),
1
,(
uchar
*
)
&
keyblock
,
ivec
);
(
uchar
*
)
start
,
(
int
)
(
end
-
start
),
1
,
(
uchar
*
)
&
keyblock
,
ivec
);
des_set_key_unchecked
(
&
keyblock
.
key1
,
des_keyschedule
[(
int
)
offset
].
ks1
);
des_set_key_unchecked
(
&
keyblock
.
key2
,
des_keyschedule
[(
int
)
offset
].
ks2
);
des_set_key_unchecked
(
&
keyblock
.
key3
,
des_keyschedule
[(
int
)
offset
].
ks3
);
if
(
default_des_key
==
15
)
default_des_key
=
(
uint
)
offset
;
// use first as def.
}
}
else
{
DBUG_PRINT
(
"des"
,(
"wrong offset: %
d
"
,
offset
));
DBUG_PRINT
(
"des"
,(
"wrong offset: %
c
"
,
offset
));
}
}
error_close:
(
void
)
my_fclose
(
file
,
MYF
(
MY_WME
));
error_noclose:
error:
if
(
file
>=
0
)
{
my_close
(
file
,
MYF
(
0
));
end_io_cache
(
&
io
);
}
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
/* if (ret)
do something; */
DBUG_VOID_RETURN
;
}
/*
This function is used to load right key with DES_ENCRYPT(text,integer)
*/
st_des_keyschedule
*
des_key
(
int
key
)
{
DBUG_ENTER
(
"des_key"
);
DBUG_PRINT
(
"exit"
,(
"return: %x"
,
&
des_keyschedule
[
key
]));
DBUG_RETURN
(
&
des_keyschedule
[
key
]);
}
#endif
/* HAVE_OPENSSL */
sql/item_strfunc.cc
View file @
87fd219d
...
...
@@ -75,7 +75,11 @@ String *Item_func_md5::val_str(String *str)
my_MD5Init
(
&
context
);
my_MD5Update
(
&
context
,(
unsigned
char
*
)
sptr
->
ptr
(),
sptr
->
length
());
my_MD5Final
(
digest
,
&
context
);
str
->
alloc
(
32
);
// Ensure that memory is free
if
(
str
->
alloc
(
32
))
// Ensure that memory is free
{
null_value
=
1
;
return
0
;
}
sprintf
((
char
*
)
str
->
ptr
(),
"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
,
digest
[
0
],
digest
[
1
],
digest
[
2
],
digest
[
3
],
...
...
@@ -201,162 +205,150 @@ void Item_func_concat::fix_length_and_dec()
}
}
#define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.')
#define ascii_to_bin(c) ((c)<=57 ? (c)-46 : (c)<=90 ? (c)-53 : (c)-59)
/*
Function des_encrypt() by tonu@spam.ee
Function des_encrypt() by tonu@spam.ee
& monty
Works only if compiled with OpenSSL library support.
Output always starts with magic char "1" and all
encrypted output is encoded into ASCII-protected
container.
Original input is returned as output if input string
begins with magic "1". Credit card number always begin
with 4,5 or 6.
This returns a binary string where first character is
CHAR(128 | tail-length << 4 | key-number).
If one uses a string key key_number is 0.
Encryption result is longer than original by formula:
new_length=
(8-(original_length % 8))*2
+1
new_length=
(8-(original_length % 8))
+1
*/
String
*
Item_func_des_encrypt
::
val_str
(
String
*
str
)
{
String
*
res
=
args
[
0
]
->
val_str
(
str
);
#ifdef HAVE_OPENSSL
des_cblock
ivec
=
{
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
};
struct
st_des_keyblock
keyblock
;
struct
st_des_keyschedule
keyschedule
;
struct
st_des_keyschedule
*
keyschedule_ptr
=&
keyschedule
;
uint
key_number
=
15
;
String
*
res
=
args
[
0
]
->
val_str
(
str
);
if
((
null_value
=
args
[
0
]
->
null_value
))
return
0
;
if
(
res
->
length
()
==
0
)
return
&
empty_string
;
if
(
res
->
c_ptr
()[
0
]
!=
'1'
)
// Skip encryption if already encrypted
{
if
(
args
[
1
]
->
val_int
())
if
(
arg_count
==
1
)
keyschedule_ptr
=
des_keyschedule
[
key_number
=
default_des_key
];
else
if
(
args
[
1
]
->
result_type
==
INT_RESULT
)
{
keyschedule_ptr
=
des_key
(
args
[
1
]
->
val_int
());
key_number
=
(
uint
)
args
[
1
]
->
val_int
();
if
(
key_number
>
9
)
goto
error
;
keyschedule_ptr
=
des_keyschedule
[
key_number
];
}
else
{
const
char
*
append_str
=
"********"
;
uint
tail
,
res_length
;
String
*
keystr
=
args
[
1
]
->
val_str
(
&
tmp_value
);
if
(
!
keystr
)
goto
error
;
/* We make good 24-byte (168 bit) key from given plaintext key with MD5 */
EVP_BytesToKey
(
EVP_des_ede3_cbc
(),
EVP_md5
(),
NULL
,
(
uchar
*
)
keystr
->
c_ptr
(),
(
int
)
keystr
->
length
(),
1
,(
uchar
*
)
&
keyblock
,
ivec
);
(
uchar
*
)
keystr
->
ptr
(),
(
int
)
keystr
->
length
(),
1
,
(
uchar
*
)
&
keyblock
,
ivec
);
des_set_key_unchecked
(
&
keyblock
.
key1
,
keyschedule_ptr
->
ks1
);
des_set_key_unchecked
(
&
keyblock
.
key2
,
keyschedule_ptr
->
ks2
);
des_set_key_unchecked
(
&
keyblock
.
key3
,
keyschedule_ptr
->
ks3
);
}
/*
The problem: DES algorithm requires original data to be in 8-bytes
chunks. Missing bytes get filled with zeros and result of encryption
can be up to 7 bytes longer than original string. When decrypted,
we do not know the size of original string :(
We add one byte with value 0x0..0x7 to original plaintext marking
change of string length
We add one byte with value 0x1..0x8 as the second byte to original
plaintext marking change of string length.
*/
uchar
tail
=
7
-
(
res
->
length
()
%
8
);
// 0..7 marking real offsets 1..8
for
(
int
i
=
0
;
i
<
tail
;
++
i
)
res
->
append
(
'*'
);
res
->
append
(
tail
);
// Write tail length 0..7 to last pos
str
->
length
(
res
->
length
());
for
(
uint
j
=
0
;
j
<
res
->
length
()
;
++
j
)
{
DBUG_PRINT
(
"info"
,(
"## res->c_ptr()[%d]='%c'"
,
j
,
res
->
c_ptr
()[
j
])
);
}
des_ede3_cbc_encrypt
(
// Real encryption
(
const
uchar
*
)(
res
->
c_ptr
()),
(
uchar
*
)(
str
->
c_ptr
()),
tail
=
(
7
-
(
res
->
length
()
+
7
)
%
8
);
// 0..7 marking extra length
res_length
=
res
->
length
()
+
tail
+
1
;
if
(
tail
&&
res
->
append
(
append_str
,
tail
)
||
tmp_value
.
alloc
(
res_length
))
goto
err
;
tmp_value
.
length
(
res_length
);
tmp_value
.[
0
]
=
(
char
)
(
128
|
tail
<<
4
|
key_number
);
// Real encryption
des_ede3_cbc_encrypt
((
const
uchar
*
)
(
res
->
ptr
()),
(
uchar
*
)
(
tmp_value
->
ptr
()
+
1
),
res
->
length
(),
keyschedule_ptr
->
ks1
,
keyschedule_ptr
->
ks2
,
keyschedule_ptr
->
ks3
,
keyschedule_ptr
->
ks1
,
keyschedule_ptr
->
ks2
,
keyschedule_ptr
->
ks3
,
&
ivec
,
TRUE
);
for
(
uint
j
=
0
;
j
<
res
->
length
()
;
++
j
)
{
DBUG_PRINT
(
"info"
,(
"## str->c_ptr()[%d]='%c'"
,
j
,
str
->
c_ptr
()[
j
]));
}
return
&
tmp_value
;
res
->
set
((
const
char
*
)
"1"
,(
uint
)
1
);
for
(
uint
i
=
0
;
i
<
str
->
length
()
;
++
i
)
{
res
->
append
(
bin_to_ascii
((
uchar
)
str
->
c_ptr
()[
i
]
&
0x3f
));
res
->
append
(
bin_to_ascii
(((
uchar
)
str
->
c_ptr
()[
i
]
>>
5
)
&
0x3f
));
}
}
return
res
;
#else
error:
#endif
/* HAVE_OPENSSL */
null_value
=
1
;
return
0
;
#endif
/* HAVE_OPENSSL */
}
String
*
Item_func_des_decrypt
::
val_str
(
String
*
str
)
{
String
*
res
=
args
[
0
]
->
val_str
(
str
);
#ifdef HAVE_OPENSSL
des_key_schedule
ks1
,
ks2
,
ks3
;
des_cblock
ivec
=
{
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
};
struct
st_des_keyblock
keyblock
;
struct
st_des_keyschedule
keyschedule
;
struct
st_des_keyschedule
*
keyschedule_ptr
=&
keyschedule
;
String
*
res
=
args
[
0
]
->
val_str
(
str
);
if
((
null_value
=
args
[
0
]
->
null_value
))
return
0
;
if
(
res
->
length
(
)
==
0
)
return
&
empty_string
;
if
(
res
->
length
(
0
)
<
9
||
(
res
->
length
())
%
8
!=
1
||
!
(
res
->
[
0
]
&
128
)
)
return
res
;
// Skip decryption if not encrypted
if
(
res
->
c_ptr
()[
0
]
==
'1'
)
// Skip decryption if not encrypted
if
(
arg_count
==
1
)
// If automatic uncompression
{
str
->
set
((
const
char
*
)
0
,(
uint
)
0
);
for
(
uint
i
=
1
;
i
<
res
->
length
()
;
i
+=
2
)
{
str
->
append
((
ascii_to_bin
(
res
->
c_ptr
()[
i
]))
|
(
ascii_to_bin
(
res
->
c_ptr
()[
i
+
1
])
<<
5
));
}
if
(
args
[
1
]
->
val_int
())
{
keyschedule_ptr
=
des_key
(
args
[
1
]
->
val_int
());
uint
key_number
=
res
->
[
0
]
&
15
;
// Check if automatic key and that we have privilege to uncompress using it
if
(
!
(
current_thd
->
master_access
&
PROCESS_ACL
)
||
key_number
>
9
)
goto
error
;
keyschedule_ptr
=
des_keyschedule
[
key_number
-
1
];
}
else
{
/*
We make good 24-byte (168 bit) key
from given plaintext key with MD5
*/
// We make good 24-byte (168 bit) key from given plaintext key with MD5
String
*
keystr
=
args
[
1
]
->
val_str
(
&
tmp_value
);
if
(
!
key_str
)
goto
error
;
EVP_BytesToKey
(
EVP_des_ede3_cbc
(),
EVP_md5
(),
NULL
,
(
uchar
*
)
keystr
->
c_ptr
(),
(
int
)
keystr
->
length
(),
1
,(
uchar
*
)
&
keyblock
,
ivec
);
/*
Here we set all 64-bit keys (56 effective) one by one
*/
(
uchar
*
)
keystr
->
ptr
(),(
int
)
keystr
->
length
(),
1
,(
uchar
*
)
&
keyblock
,
ivec
);
// Here we set all 64-bit keys (56 effective) one by one
des_set_key_unchecked
(
&
keyblock
.
key1
,
keyschedule_ptr
->
ks1
);
des_set_key_unchecked
(
&
keyblock
.
key2
,
keyschedule_ptr
->
ks2
);
des_set_key_unchecked
(
&
keyblock
.
key3
,
keyschedule_ptr
->
ks3
);
}
res
->
length
(
str
->
length
());
des_ede3_cbc_encrypt
(
// Real decryption
(
const
uchar
*
)(
str
->
c_ptr
()),
(
uchar
*
)(
res
->
c_ptr
()),
str
->
length
(),
keyschedule_ptr
->
ks1
,
keyschedule_ptr
->
ks2
,
keyschedule_ptr
->
ks3
,
if
(
tmp_value
.
alloc
(
res
->
length
()
-
1
))
goto
err
;
/* Restore old length of key */
tmp_value
.
length
(
res
->
length
()
-
1
-
(((
uchar
)
res
->
[
0
]
>>
4
)
&
7
));
des_ede3_cbc_encrypt
((
const
uchar
*
)
res
->
ptr
()
+
1
,
(
uchar
*
)
(
tmp_value
->
ptr
()),
res
->
length
()
-
1
,
keyschedule_ptr
->
ks1
,
keyschedule_ptr
->
ks2
,
keyschedule_ptr
->
ks3
,
&
ivec
,
FALSE
);
uchar
tail
=
(
res
->
c_ptr
()[
res
->
length
()
-
1
])
&
0x7
;
if
((
res
->
length
()
>
((
uint
)
1
+
tail
)))
// We should avoid negative length
res
->
length
(
res
->
length
()
-
1
-
tail
);
// (can happen with wrong key)
}
return
res
;
#else
return
&
tmp_value
;
error:
#endif
/* HAVE_OPENSSL */
null_value
=
1
;
return
0
;
#endif
/* HAVE_OPENSSL */
}
/*
**
concat with separator. First arg is the separator
**
concat_ws takes at least two arguments.
concat with separator. First arg is the separator
concat_ws takes at least two arguments.
*/
String
*
Item_func_concat_ws
::
val_str
(
String
*
str
)
...
...
@@ -1146,6 +1138,7 @@ String *Item_func_password::val_str(String *str)
return
str
;
}
#define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.')
String
*
Item_func_encrypt
::
val_str
(
String
*
str
)
{
...
...
sql/item_strfunc.h
View file @
87fd219d
...
...
@@ -228,9 +228,9 @@ class Item_func_des_encrypt :public Item_str_func
public:
Item_func_des_encrypt
(
Item
*
a
)
:
Item_str_func
(
a
)
{}
Item_func_des_encrypt
(
Item
*
a
,
Item
*
b
)
:
Item_str_func
(
a
,
b
)
{}
Item_func_des_encrypt
(
Item
*
a
,
Item
*
b
,
Item
*
c
)
:
Item_str_func
(
a
,
b
,
c
)
{}
String
*
val_str
(
String
*
);
void
fix_length_and_dec
()
{
maybe_null
=
1
;
max_length
=
args
[
0
]
->
max_length
;
}
void
fix_length_and_dec
()
{
maybe_null
=
1
;
max_length
=
args
[
0
]
->
max_length
+
8
;
}
const
char
*
func_name
()
const
{
return
"des_encrypt"
;
}
};
...
...
@@ -240,7 +240,6 @@ class Item_func_des_decrypt :public Item_str_func
public:
Item_func_des_decrypt
(
Item
*
a
)
:
Item_str_func
(
a
)
{}
Item_func_des_decrypt
(
Item
*
a
,
Item
*
b
)
:
Item_str_func
(
a
,
b
)
{}
Item_func_des_decrypt
(
Item
*
a
,
Item
*
b
,
Item
*
c
)
:
Item_str_func
(
a
,
b
,
c
)
{}
String
*
val_str
(
String
*
);
void
fix_length_and_dec
()
{
maybe_null
=
1
;
max_length
=
args
[
0
]
->
max_length
;
}
const
char
*
func_name
()
const
{
return
"des_decrypt"
;
}
...
...
sql/mysql_priv.h
View file @
87fd219d
...
...
@@ -405,9 +405,9 @@ struct st_des_keyschedule
{
des_key_schedule
ks1
,
ks2
,
ks3
;
};
extern
struct
st_des_keyschedule
des_keyschedule
[
10
];
extern
struct
st_des_keyschedule
des_keyschedule
[
9
];
extern
uint
des_default_key
;
void
load_des_key_file
(
const
char
*
file_name
);
struct
st_des_keyschedule
*
des_key
(
int
);
#endif
/* HAVE_OPENSSL */
/* sql_list.c */
...
...
sql/mysqld.cc
View file @
87fd219d
...
...
@@ -243,7 +243,6 @@ static char glob_hostname[FN_REFLEN];
#include "sslopt-vars.h"
#ifdef HAVE_OPENSSL
static
char
*
des_key_file
=
0
;
struct
st_des_keyschedule
des_keyschedule
[
10
];
struct
st_VioSSLAcceptorFd
*
ssl_acceptor_fd
=
0
;
#endif
/* HAVE_OPENSSL */
...
...
@@ -1751,8 +1750,6 @@ int main(int argc, char **argv)
opt_use_ssl
=
0
;
/* having ssl_acceptor_fd != 0 signals the use of SSL */
}
bzero
(
des_keyschedule
,
sizeof
(
struct
st_des_keyschedule
)
*
10
);
DBUG_PRINT
(
"des"
,(
"initializing %d bytes of %x"
,
sizeof
(
struct
st_des_keyschedule
)
*
10
,
des_keyschedule
));
if
(
des_key_file
)
load_des_key_file
(
des_key_file
);
#endif
/* HAVE_OPENSSL */
...
...
sql/sql_acl.cc
View file @
87fd219d
...
...
@@ -698,12 +698,17 @@ uint acl_get(const char *host, const char *ip, const char *bin_ip,
{
uint
host_access
,
db_access
,
i
,
key_length
;
db_access
=
0
;
host_access
=
~
0
;
char
key
[
ACL_KEY_LENGTH
],
*
end
;
char
key
[
ACL_KEY_LENGTH
],
*
tmp_db
,
*
end
;
acl_entry
*
entry
;
VOID
(
pthread_mutex_lock
(
&
acl_cache
->
lock
));
memcpy_fixed
(
&
key
,
bin_ip
,
sizeof
(
struct
in_addr
));
end
=
strmov
(
strmov
(
key
+
sizeof
(
struct
in_addr
),
user
)
+
1
,
db
);
end
=
strmov
((
tmp_db
=
strmov
(
key
+
sizeof
(
struct
in_addr
),
user
)
+
1
),
db
);
if
(
lower_case_table_names
)
{
casedn_str
(
tmp_db
);
db
=
tmp_db
;
}
key_length
=
(
uint
)
(
end
-
key
);
if
((
entry
=
(
acl_entry
*
)
acl_cache
->
search
(
key
,
key_length
)))
{
...
...
@@ -1377,6 +1382,11 @@ class GRANT_TABLE :public Sql_alloc
db
=
strdup_root
(
&
memex
,
d
);
user
=
strdup_root
(
&
memex
,
u
);
tname
=
strdup_root
(
&
memex
,
t
);
if
(
lower_case_table_names
)
{
casedn_str
(
db
);
casedn_str
(
tname
);
}
key_length
=
(
uint
)
strlen
(
d
)
+
(
uint
)
strlen
(
u
)
+
(
uint
)
strlen
(
t
)
+
3
;
hash_key
=
(
char
*
)
alloc_root
(
&
memex
,
key_length
);
strmov
(
strmov
(
strmov
(
hash_key
,
user
)
+
1
,
db
)
+
1
,
tname
);
...
...
@@ -1398,7 +1408,13 @@ class GRANT_TABLE :public Sql_alloc
privs
=
cols
=
0
;
/* purecov: inspected */
return
;
/* purecov: inspected */
}
key_length
=
(
uint
)
strlen
(
db
)
+
(
uint
)
strlen
(
user
)
+
(
uint
)
strlen
(
tname
)
+
3
;
if
(
lower_case_table_names
)
{
casedn_str
(
db
);
casedn_str
(
tname
);
}
key_length
=
((
uint
)
strlen
(
db
)
+
(
uint
)
strlen
(
user
)
+
(
uint
)
strlen
(
tname
)
+
3
);
hash_key
=
(
char
*
)
alloc_root
(
&
memex
,
key_length
);
strmov
(
strmov
(
strmov
(
hash_key
,
user
)
+
1
,
db
)
+
1
,
tname
);
privs
=
(
uint
)
form
->
field
[
6
]
->
val_int
();
...
...
@@ -1990,7 +2006,7 @@ int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list, uint rights,
{
List_iterator
<
LEX_USER
>
str_list
(
list
);
LEX_USER
*
Str
;
char
what
;
char
what
,
tmp_db
[
NAME_LEN
+
1
]
;
bool
create_new_users
=
0
;
TABLE_LIST
tables
[
2
];
DBUG_ENTER
(
"mysql_grant"
);
...
...
@@ -2002,6 +2018,12 @@ int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list, uint rights,
}
what
=
(
revoke_grant
)
?
'N'
:
'Y'
;
if
(
lower_case_table_names
&&
db
)
{
strmov
(
tmp_db
,
db
);
casedn_str
(
tmp_db
);
db
=
tmp_db
;
}
/* open the mysql.user and mysql.db tables */
...
...
@@ -2220,8 +2242,8 @@ bool check_grant(THD *thd, uint want_access, TABLE_LIST *tables,
table
->
grant
.
want_privilege
=
0
;
continue
;
// Already checked
}
const
char
*
db
=
table
->
db
?
table
->
db
:
thd
->
db
;
GRANT_TABLE
*
grant_table
=
table_hash_search
(
thd
->
host
,
thd
->
ip
,
db
,
user
,
GRANT_TABLE
*
grant_table
=
table_hash_search
(
thd
->
host
,
thd
->
ip
,
table
->
db
,
user
,
table
->
real_name
,
0
);
if
(
!
grant_table
)
{
...
...
sql/sql_cache.cc
View file @
87fd219d
This diff is collapsed.
Click to expand it.
sql/sql_cache.h
View file @
87fd219d
...
...
@@ -379,6 +379,10 @@ class Query_cache
void
cache_dump
();
void
queries_dump
();
void
tables_dump
();
my_bool
check_integrity
();
my_bool
in_list
(
Query_cache_block
*
root
,
Query_cache_block
*
point
,
const
char
*
name
);
my_bool
in_blocks
(
Query_cache_block
*
point
);
#endif
friend
void
query_cache_insert
(
NET
*
net
,
const
char
*
packet
,
ulong
length
);
friend
void
query_cache_end_of_result
(
NET
*
net
);
...
...
sql/sql_delete.cc
View file @
87fd219d
...
...
@@ -384,6 +384,13 @@ void multi_delete::send_error(uint errcode,const char *err)
}
/*
Do delete from other tables.
Returns values:
0 ok
1 error
*/
int
multi_delete
::
do_deletes
(
bool
from_send_error
)
{
int
error
=
0
,
counter
=
0
;
...
...
@@ -420,7 +427,8 @@ int multi_delete::do_deletes (bool from_send_error)
{
TABLE_LIST
table_list
;
bzero
((
char
*
)
&
table_list
,
sizeof
(
table_list
));
table_list
.
name
=
table
->
table_name
;
table_list
.
real_name
=
table_being_deleted
->
real_name
;
table_list
.
name
=
table
->
table_name
;
table_list
.
real_name
=
table_being_deleted
->
real_name
;
table_list
.
table
=
table
;
table_list
.
grant
=
table
->
grant
;
table_list
.
db
=
table_being_deleted
->
db
;
...
...
@@ -432,23 +440,20 @@ int multi_delete::do_deletes (bool from_send_error)
#endif
/* USE_REGENERATE_TABLE */
READ_RECORD
info
;
error
=
0
;
init_read_record
(
&
info
,
thd
,
table
,
NULL
,
0
,
0
);
bool
not_trans_safe
=
some_table_is_not_transaction_safe
(
delete_tables
);
while
(
!
(
error
=
info
.
read_record
(
&
info
))
&&
(
!
thd
->
killed
||
from_send_error
||
not_trans_safe
))
{
error
=
table
->
file
->
delete_row
(
table
->
record
[
0
]);
if
(
error
)
if
((
error
=
table
->
file
->
delete_row
(
table
->
record
[
0
])))
{
table
->
file
->
print_error
(
error
,
MYF
(
0
));
break
;
}
else
deleted
++
;
}
end_read_record
(
&
info
);
if
(
error
==
-
1
)
if
(
error
==
-
1
)
// End of file
error
=
0
;
}
return
error
;
...
...
@@ -464,7 +469,6 @@ bool multi_delete::send_eof()
/* reset used flags */
delete_tables
->
table
->
no_keyread
=
0
;
if
(
error
==
-
1
)
error
=
0
;
thd
->
proc_info
=
"end"
;
if
(
error
)
{
...
...
@@ -477,22 +481,17 @@ bool multi_delete::send_eof()
was a non-transaction-safe table involved, since
modifications in it cannot be rolled back. */
if
(
deleted
&&
(
!
error
||
some_table_is_not_transaction_safe
(
delete_tables
)))
if
(
deleted
||
some_table_is_not_transaction_safe
(
delete_tables
))
{
mysql_update_log
.
write
(
thd
,
thd
->
query
,
thd
->
query_length
);
if
(
mysql_bin_log
.
is_open
())
{
Query_log_event
qinfo
(
thd
,
thd
->
query
);
/* mysql_bin_log is not open if binlogging or replication
is not used */
if
(
mysql_bin_log
.
is_open
()
&&
mysql_bin_log
.
write
(
&
qinfo
)
&&
if
(
mysql_bin_log
.
write
(
&
qinfo
)
&&
!
some_table_is_not_transaction_safe
(
delete_tables
))
error
=
1
;
/* Log write failed: roll back
the SQL statement */
error
=
1
;
// Log write failed: roll back the SQL statement
}
/* Commit or rollback the current SQL statement */
VOID
(
ha_autocommit_or_rollback
(
thd
,
error
>
0
));
}
...
...
sql/sql_parse.cc
View file @
87fd219d
...
...
@@ -2423,7 +2423,6 @@ mysql_init_query(THD *thd)
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
->
lex
.
sql_command
=
SQLCOM_SELECT
;
DBUG_VOID_RETURN
;
}
...
...
@@ -2860,13 +2859,17 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias,
if
(
!
alias
)
/* Alias is case sensitive */
if
(
!
(
alias_str
=
thd
->
memdup
(
alias_str
,
table
->
table
.
length
+
1
)))
DBUG_RETURN
(
0
);
if
(
lower_case_table_names
)
casedn_str
(
table
->
table
.
str
);
if
(
!
(
ptr
=
(
TABLE_LIST
*
)
thd
->
calloc
(
sizeof
(
TABLE_LIST
))))
DBUG_RETURN
(
0
);
/* purecov: inspected */
ptr
->
db
=
table
->
db
.
str
?
table
->
db
.
str
:
(
thd
->
db
?
thd
->
db
:
(
char
*
)
""
);
ptr
->
real_name
=
table
->
table
.
str
;
ptr
->
name
=
alias_str
;
if
(
lower_case_table_names
)
{
casedn_str
(
ptr
->
db
);
casedn_str
(
table
->
table
.
str
);
}
ptr
->
real_name
=
table
->
table
.
str
;
ptr
->
lock_type
=
flags
;
ptr
->
updating
=
updating
;
if
(
use_index
)
...
...
@@ -2879,7 +2882,8 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias,
/* check that used name is unique */
if
(
flags
!=
TL_IGNORE
)
{
for
(
TABLE_LIST
*
tables
=
(
TABLE_LIST
*
)
thd
->
lex
.
select
->
table_list
.
first
;
tables
;
for
(
TABLE_LIST
*
tables
=
(
TABLE_LIST
*
)
thd
->
lex
.
select
->
table_list
.
first
;
tables
;
tables
=
tables
->
next
)
{
if
(
!
strcmp
(
alias_str
,
tables
->
name
)
&&
!
strcmp
(
ptr
->
db
,
tables
->
db
))
...
...
sql/sql_union.cc
View file @
87fd219d
...
...
@@ -27,7 +27,7 @@
int
mysql_union
(
THD
*
thd
,
LEX
*
lex
,
select_result
*
result
)
{
SELECT_LEX
*
sl
,
*
last_sl
=
(
SELECT_LEX
*
)
NULL
,
lex_sl
;
SELECT_LEX
*
sl
,
*
last_sl
,
*
lex_sl
;
ORDER
*
order
;
List
<
Item
>
item_list
;
TABLE
*
table
;
...
...
@@ -38,7 +38,10 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
DBUG_ENTER
(
"mysql_union"
);
/* Fix tables 'to-be-unioned-from' list to point at opened tables */
for
(
sl
=&
lex
->
select_lex
;
sl
&&
sl
->
linkage
!=
NOT_A_SELECT
;
last_sl
=
sl
,
sl
=
sl
->
next
)
last_sl
=
&
lex
->
select_lex
;
for
(
sl
=
last_sl
;
sl
&&
sl
->
linkage
!=
NOT_A_SELECT
;
last_sl
=
sl
,
sl
=
sl
->
next
)
{
for
(
TABLE_LIST
*
cursor
=
(
TABLE_LIST
*
)
sl
->
table_list
.
first
;
cursor
;
...
...
@@ -46,19 +49,27 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
cursor
->
table
=
((
TABLE_LIST
*
)
cursor
->
table
)
->
table
;
}
/* last_sel now points at the last select where the ORDER BY is stored */
if
(
sl
)
{
lex_sl
=*
sl
;
sl
=
(
SELECT_LEX
*
)
NULL
;
if
(
last_sl
)
last_sl
->
next
=
sl
;
/*
The found SL is an extra SELECT_LEX argument that contains
the ORDER BY and LIMIT parameter for the whole UNION
*/
lex_sl
=
sl
;
last_sl
->
next
=
0
;
// Remove this extra element
order
=
(
ORDER
*
)
lex_sl
->
order_list
.
first
;
}
else
if
(
!
last_sl
->
braces
)
{
lex_sl
=
last_sl
;
// ORDER BY is here
order
=
(
ORDER
*
)
lex_sl
->
order_list
.
first
;
}
else
lex_sl
.
linkage
=
UNSPECIFIED_TYPE
;
/* Find last select part as it's here ORDER BY and GROUP BY is stored */
for
(
last_sl
=
&
lex
->
select_lex
;
last_sl
->
next
;
last_sl
=
last_sl
->
next
)
;
{
lex_sl
=
0
;
order
=
0
;
}
if
(
lex
->
select_lex
.
options
&
SELECT_DESCRIBE
)
{
...
...
@@ -68,7 +79,8 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
res
=
mysql_select
(
thd
,
(
TABLE_LIST
*
)
sl
->
table_list
.
first
,
sl
->
item_list
,
sl
->
where
,
(
sl
->
braces
)
?
(
ORDER
*
)
sl
->
order_list
.
first
:
(
ORDER
*
)
0
,
((
sl
->
braces
)
?
(
ORDER
*
)
sl
->
order_list
.
first
:
(
ORDER
*
)
0
),
(
ORDER
*
)
sl
->
group_list
.
first
,
sl
->
having
,
(
ORDER
*
)
NULL
,
...
...
@@ -79,8 +91,6 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
DBUG_RETURN
(
0
);
}
order
=
(
lex_sl
.
linkage
==
UNSPECIFIED_TYPE
)
?
(
(
last_sl
->
braces
)
?
(
ORDER
*
)
0
:
(
ORDER
*
)
last_sl
->
order_list
.
first
)
:
(
ORDER
*
)
lex_sl
.
order_list
.
first
;
{
Item
*
item
;
List_iterator
<
Item
>
it
(
lex
->
select_lex
.
item_list
);
...
...
@@ -162,11 +172,11 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
}
if
(
!
thd
->
fatal_error
)
// Check if EOM
{
if
(
lex_sl
.
linkage
==
NOT_A_SELECT
&&
(
lex_sl
.
select_limit
||
lex_sl
.
offset_limit
)
)
if
(
lex_sl
)
{
thd
->
offset_limit
=
lex_sl
.
offset_limit
;
thd
->
select_limit
=
lex_sl
.
select_limit
+
lex_sl
.
offset_limit
;
if
(
thd
->
select_limit
<
lex_sl
.
select_limit
)
thd
->
offset_limit
=
lex_sl
->
offset_limit
;
thd
->
select_limit
=
lex_sl
->
select_limit
+
lex_sl
->
offset_limit
;
if
(
thd
->
select_limit
<
lex_sl
->
select_limit
)
thd
->
select_limit
=
HA_POS_ERROR
;
// no limit
if
(
thd
->
select_limit
==
HA_POS_ERROR
)
thd
->
options
&=
~
OPTION_FOUND_ROWS
;
...
...
sql/sql_yacc.yy
View file @
87fd219d
...
...
@@ -1348,9 +1348,13 @@ table_to_table:
select:
select_init { Lex->sql_command=SQLCOM_SELECT; }
select_init:
SELECT_SYM select_part2 { Select->braces=false; } union
|
'(' SELECT_SYM select_part2 ')' {Select->braces=true;} union_opt
'(' SELECT_SYM select_part2 ')' { Select->braces=true;} union_opt
select_part2:
{
...
...
@@ -1643,8 +1647,12 @@ simple_expr:
{ $$= new Item_func_decode($3,$5.str); }
| ENCODE_SYM '(' expr ',' TEXT_STRING ')'
{ $$= new Item_func_encode($3,$5.str); }
| DES_DECRYPT '(' expr ')'
{ $$= new Item_func_des_decrypt($3); }
| DES_DECRYPT '(' expr ',' expr ')'
{ $$= new Item_func_des_decrypt($3,$5); }
| DES_ENCRYPT '(' expr ')'
{ $$= new Item_func_des_encrypt($3); }
| DES_ENCRYPT '(' expr ',' expr ')'
{ $$= new Item_func_des_encrypt($3,$5); }
| EXPORT_SET '(' expr ',' expr ',' expr ')'
...
...
@@ -3573,12 +3581,12 @@ union_list:
net_printf(&lex->thd->net, ER_WRONG_USAGE,"UNION","INTO");
YYABORT;
}
if (lex->select->linkage
==
NOT_A_SELECT)
if (lex->select->linkage
==
NOT_A_SELECT)
YYABORT;
mysql_new_select(lex);
lex->select->linkage=UNION_TYPE;
}
select
select
_init
union_opt:
union {}
...
...
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