Commit 1d3e058c authored by monty@hundin.mysql.fi's avatar monty@hundin.mysql.fi

Added FLUSH DES_KEY_FILE.

New HEX() function.
Final (?) cleanup of des_encrypt() / des_decrypt().
Added missing files to Makefiles.
parent f66a9d87
...@@ -21,7 +21,8 @@ info_TEXINFOS = manual.texi ...@@ -21,7 +21,8 @@ info_TEXINFOS = manual.texi
targets = manual.txt mysql.info manual.html targets = manual.txt mysql.info manual.html
BUILT_SOURCES = $(targets) manual_toc.html include.texi BUILT_SOURCES = $(targets) manual_toc.html include.texi
EXTRA_DIST = $(noinst_SCRIPTS) $(BUILT_SOURCES) mysqld_error.txt INSTALL-BINARY EXTRA_DIST = $(noinst_SCRIPTS) $(BUILT_SOURCES) mysqld_error.txt \
INSTALL-BINARY mirrors.texi section.Comparisons.texi
all: $(targets) txt_files all: $(targets) txt_files
......
...@@ -7304,8 +7304,11 @@ version 4.0; ...@@ -7304,8 +7304,11 @@ version 4.0;
@code{LOCATE()} and @code{INSTR()} are case sensitive if neither @code{LOCATE()} and @code{INSTR()} are case sensitive if neither
argument is a binary string. argument is a binary string.
@item @item
In 3.23, @code{HEX(string)} now returns the characters in string converted to
@code{INSERT INTO ... SELECT} always had @code{IGNORE} enabled. hexadecimal. If you want to convert a number to hexadecimal, you should
ensure that you call @code{HEX()} with a numeric argument.
@item
In 3.23, @code{INSERT INTO ... SELECT} always had @code{IGNORE} enabled.
In 4.0.1, MySQL will stop (and possibly roll back) in case of an error if you In 4.0.1, MySQL will stop (and possibly roll back) in case of an error if you
don't specify @code{IGNORE}. don't specify @code{IGNORE}.
@item @item
...@@ -13134,21 +13137,25 @@ specify @code{--core-file-size} to @code{safe_mysqld}. @xref{safe_mysqld, , ...@@ -13134,21 +13137,25 @@ specify @code{--core-file-size} to @code{safe_mysqld}. @xref{safe_mysqld, ,
@item -h, --datadir=path @item -h, --datadir=path
Path to the database root. Path to the database root.
@item --debug[...]=
If MySQL is configured with @code{--with-debug}, you can use this
option to get a trace file of what @code{mysqld} is doing.
@xref{Making trace files}.
@item --default-character-set=charset @item --default-character-set=charset
Set the default character set. @xref{Character sets}. Set the default character set. @xref{Character sets}.
@item --default-table-type=type @item --default-table-type=type
Set the default table type for tables. @xref{Table types}. Set the default table type for tables. @xref{Table types}.
@item --debug[...]=
If MySQL is configured with @code{--with-debug}, you can use this
option to get a trace file of what @code{mysqld} is doing.
@xref{Making trace files}.
@item --delay-key-write-for-all-tables @item --delay-key-write-for-all-tables
Don't flush key buffers between writes for any @code{MyISAM} table. Don't flush key buffers between writes for any @code{MyISAM} table.
@xref{Server parameters}. @xref{Server parameters}.
@item --des-key-file=filename
Read the default keys used by @code{des_encrypt()} and @code{des_decrypt()}
from this file.
@item --enable-locking @item --enable-locking
Enable system locking. Note that if you use this option on a system Enable system locking. Note that if you use this option on a system
which a not fully working lockd() (as on Linux) you will easily get which a not fully working lockd() (as on Linux) you will easily get
...@@ -17911,6 +17918,8 @@ Flushing the host tables allows the host to attempt to connect ...@@ -17911,6 +17918,8 @@ Flushing the host tables allows the host to attempt to connect
again. @xref{Blocked host}. You can start @code{mysqld} with again. @xref{Blocked host}. You can start @code{mysqld} with
@code{-O max_connection_errors=999999999} to avoid this error message. @code{-O max_connection_errors=999999999} to avoid this error message.
@item @code{DES_KEY_FILE} @tab Reloads the des keys from the file specified with @code{--des-key-file}.
@item @code{LOGS} @tab Closes and reopens all log files. @item @code{LOGS} @tab Closes and reopens all log files.
If you have specified the update log file or a binary log file without If you have specified the update log file or a binary log file without
an extension, the extension number of the log file will be incremented an extension, the extension number of the log file will be incremented
...@@ -26644,7 +26653,8 @@ mysql> select 0x5061756c; ...@@ -26644,7 +26653,8 @@ mysql> select 0x5061756c;
The x'hexstring' syntax (new in 4.0) is based on ANSI SQL and the 0x The x'hexstring' syntax (new in 4.0) is based on ANSI SQL and the 0x
syntax is based on ODBC. syntax is based on ODBC.
Hexadecimal strings are often used by ODBC to give values for BLOB columns. Hexadecimal strings are often used by ODBC to give values for BLOB columns.
You can convert a string or a number to hexadecimal with the @code{HEX()}
function.
@node NULL values, , Hexadecimal values, Literals @node NULL values, , Hexadecimal values, Literals
@subsubsection @code{NULL} Values @subsubsection @code{NULL} Values
...@@ -29173,14 +29183,23 @@ mysql> select OCT(12); ...@@ -29173,14 +29183,23 @@ mysql> select OCT(12);
@end example @end example
@findex HEX() @findex HEX()
@item HEX(N) @item HEX(N_or_S)
Returns a string representation of the hexadecimal value of @code{N}, where
@code{N} is a longlong (@code{BIGINT}) number. This is equivalent to If N_OR_S is a number, returns a string representation of the hexadecimal
@code{CONV(N,10,16)}. Returns @code{NULL} if @code{N} is @code{NULL}: value of @code{N}, where @code{N} is a longlong (@code{BIGINT}) number.
This is equivalent to @code{CONV(N,10,16)}.
If N_OR_S is a string, returns a hexadecimal string of N_OR_S where each
character in N_OR_S is converted to 2 hexadecimal digits. This is the
invers of the @code{0xff} strings.
@example @example
mysql> select HEX(255); mysql> select HEX(255);
-> 'FF' -> 'FF'
mysql> select HEX("abc");
-> 616263
mysql> select 0x616263;
-> "abc"
@end example @end example
@findex CHAR() @findex CHAR()
...@@ -31041,6 +31060,83 @@ mysql> select MD5("testing"); ...@@ -31041,6 +31060,83 @@ mysql> select MD5("testing");
This is an "RSA Data Security, Inc. MD5 Message-Digest Algorithm". This is an "RSA Data Security, Inc. MD5 Message-Digest Algorithm".
@findex des_encrypt()
@item des_encrypt(string_to_encrypt, flag, [, (key_number | key_string) ] )
Encrypts the string with the given key using the DES algorithm, which
provides strong encryption.
Note that this function only works if you have configured MySQL with
SLL support. @xref{Secure connections}.
The encryption key to use is chosen the following way:
@multitable @columnfractions .2 .8
@item @strong{Argument} @tab @strong{Description}
@item Only one argument @tab
The first key from @code{des-key-file} is used.
@item key number @tab
The given key (0-9) from the @code{des-key-file} is used.
@item string @tab
The given @code{key_string} will be used to crypt @code{string_to_encrypt}.
@end multitable
The return string will be a binary string where the first character
will be @code{CHAR(128 | key-number)}.
The 128 is added to make it easier to recognize a crypted key.
If one uses a string key, @code{key-number} will be 127.
On error, this function returns NULL.
The string length for the result will be
@code{new_length= org_length + (8-(org_length % 8))+1}.
The @code{des-key-file} has the following format:
@example
key-number key-string
key-number key-string
@end example
The @code{key-number} must be a number between 0-9. The numbers may be
in any order. @code{des-key-string} is string that will be used to
crypt the message. Between the number and the key there should be at
least one space. The first key is the default key that will be used
if one doesn't specify a key to @code{des_encrypt()}
You can tell MySQL to read new key values from the key file with the
@code{FLUSH DES_KEY_FILE} command.
One benefit with having a set of default keys on can use is that it
gives applications a way to check for existence of crypted column,
without giving the end user the right to uncrypt the data.
@example
SELECT customer_address FROM customer_table WHERE
crypted_credit_card = DES_ENCRYPT("credit_card_number");
@end example
@findex des_decrypt()
@item des_decrypt(string_to_decrypt [, key_string])
Decrypts a string crypted with @code{des_encrypt()}.
Note that this function only works if you have configured MySQL with
SLL support. @xref{Secure connections}.
If one only gives this a string argument, then it will use the right key
from the @code{des-key-file} to decrypt the message. For this to work
the user must have the @code{PROCESS_PRIV} privilege.
If one calls this function with 2 arguments, the second argument is
used to decrypt the message.
If the @code{string_to_decrypt} doesn't look like a crypted string MySQL will
return the given @code{string_to_decrypt}.
On error, this function returns NULL.
@findex LAST_INSERT_ID([expr]) @findex LAST_INSERT_ID([expr])
@item LAST_INSERT_ID([expr]) @item LAST_INSERT_ID([expr])
Returns the last automatically generated value that was inserted into an Returns the last automatically generated value that was inserted into an
...@@ -46836,6 +46932,15 @@ Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}. ...@@ -46836,6 +46932,15 @@ Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}.
@itemize @bullet @itemize @bullet
@item @item
Added functions @code{des_encrypt()} and @code{des_decrypt()}.
@item
Added statement FLUSH DES_KEY_FILE.
@item
Added mysqld option @code{--des-key-file}.
@item
@code{HEX(string)} now returns the characters in string converted to
hexadecimal.
@item
Fixed problem with @code{GRANT} when using @code{lower_case_table_names == 1}. Fixed problem with @code{GRANT} when using @code{lower_case_table_names == 1}.
@item @item
Changed @code{SELECT ... IN SHARE MODE} to Changed @code{SELECT ... IN SHARE MODE} to
...@@ -80,6 +80,7 @@ enum enum_server_command {COM_SLEEP,COM_QUIT,COM_INIT_DB,COM_QUERY, ...@@ -80,6 +80,7 @@ enum enum_server_command {COM_SLEEP,COM_QUIT,COM_INIT_DB,COM_QUERY,
/* RESET (remove all queries) from query cache */ /* RESET (remove all queries) from query cache */
#define REFRESH_QUERY_CACHE 65536 #define REFRESH_QUERY_CACHE 65536
#define REFRESH_QUERY_CACHE_FREE 0x20000L /* pack query cache */ #define REFRESH_QUERY_CACHE_FREE 0x20000L /* pack query cache */
#define REFRESH_DES_KEY_FILE 0x40000L
#define CLIENT_LONG_PASSWORD 1 /* new more secure passwords */ #define CLIENT_LONG_PASSWORD 1 /* new more secure passwords */
#define CLIENT_FOUND_ROWS 2 /* Found instead of affected rows */ #define CLIENT_FOUND_ROWS 2 /* Found instead of affected rows */
......
...@@ -75,7 +75,8 @@ uint _mi_ft_segiterator(register FT_SEG_ITERATOR *ftsi) ...@@ -75,7 +75,8 @@ uint _mi_ft_segiterator(register FT_SEG_ITERATOR *ftsi)
if (ftsi->seg->flag & HA_BLOB_PART) if (ftsi->seg->flag & HA_BLOB_PART)
{ {
ftsi->len=_mi_calc_blob_length(ftsi->seg->bit_start,ftsi->pos); ftsi->len=_mi_calc_blob_length(ftsi->seg->bit_start,ftsi->pos);
memcpy_fixed(&ftsi->pos,ftsi->pos+ftsi->seg->bit_start,sizeof(char*)); memcpy_fixed((char*) &ftsi->pos, ftsi->pos+ftsi->seg->bit_start,
sizeof(char*));
set_if_smaller(ftsi->len,ftsi->seg->length); set_if_smaller(ftsi->len,ftsi->seg->length);
return 1; return 1;
} }
...@@ -107,11 +108,11 @@ FT_WORD * _mi_ft_parserecord(MI_INFO *info, uint keynr, ...@@ -107,11 +108,11 @@ FT_WORD * _mi_ft_parserecord(MI_INFO *info, uint keynr,
{ {
TREE ptree; TREE ptree;
bzero(&ptree, sizeof(ptree)); bzero((char*) &ptree, sizeof(ptree));
if (_mi_ft_parse(& ptree, info, keynr, record)) if (_mi_ft_parse(&ptree, info, keynr, record))
return NULL; return NULL;
return ft_linearize(/*info, keynr, keybuf, */ & ptree); return ft_linearize(/*info, keynr, keybuf, */ &ptree);
} }
static int _mi_ft_store(MI_INFO *info, uint keynr, byte *keybuf, static int _mi_ft_store(MI_INFO *info, uint keynr, byte *keybuf,
......
...@@ -76,7 +76,6 @@ sleep_until_file_exists () ...@@ -76,7 +76,6 @@ sleep_until_file_exists ()
exit 1; exit 1;
} }
# No paths below as we can't be sure where the program is! # No paths below as we can't be sure where the program is!
BASENAME=`which basename | head -1` BASENAME=`which basename | head -1`
...@@ -993,7 +992,7 @@ run_testcase () ...@@ -993,7 +992,7 @@ run_testcase ()
then then
if [ -f $master_opt_file ] ; if [ -f $master_opt_file ] ;
then then
EXTRA_MASTER_OPT=`$CAT $master_opt_file` EXTRA_MASTER_OPT=`$CAT $master_opt_file | $SED -e "s;\\$MYSQL_TEST_DIR;$MYSQL_TEST_DIR;"`
stop_master stop_master
start_master start_master
else else
...@@ -1008,7 +1007,7 @@ run_testcase () ...@@ -1008,7 +1007,7 @@ run_testcase ()
if [ -f $slave_opt_file ] ; if [ -f $slave_opt_file ] ;
then then
EXTRA_SLAVE_OPT=`$CAT $slave_opt_file` EXTRA_SLAVE_OPT=`$CAT $slave_opt_file | $SED -e "s;\\$MYSQL_TEST_DIR;$MYSQL_TEST_DIR;"`
do_slave_restart=1 do_slave_restart=1
else else
if [ ! -z "$EXTRA_SLAVE_OPT" ] || [ x$SLAVE_RUNNING != x1 ] ; if [ ! -z "$EXTRA_SLAVE_OPT" ] || [ x$SLAVE_RUNNING != x1 ] ;
......
select length(encrypt('foo', 'ff')) <> 0; select length(encrypt('foo', 'ff')) <> 0;
length(encrypt('foo', 'ff')) <> 0 length(encrypt('foo', 'ff')) <> 0
1 1
select password('test'),length(encrypt('test')),encrypt('test','aa');
password('test') length(encrypt('test')) encrypt('test','aa')
378b243e220ca493 13 aaqPiZY5xR5l.
...@@ -77,9 +77,6 @@ this is a REAL test ...@@ -77,9 +77,6 @@ this is a REAL test
select soundex(''),soundex('he'),soundex('hello all folks'); select soundex(''),soundex('he'),soundex('hello all folks');
soundex('') soundex('he') soundex('hello all folks') soundex('') soundex('he') soundex('hello all folks')
H000 H4142 H000 H4142
select password('test'),length(encrypt('test')),encrypt('test','aa');
password('test') length(encrypt('test')) encrypt('test','aa')
378b243e220ca493 13 aaqPiZY5xR5l.
select md5('hello'); select md5('hello');
md5('hello') md5('hello')
5d41402abc4b2a76b9719d911017c592 5d41402abc4b2a76b9719d911017c592
......
5 default_password
1 password1
4 password4
2 password2
select length(encrypt('foo', 'ff')) <> 0; select length(encrypt('foo', 'ff')) <> 0;
--replace_result $1$aa$4OSUA5cjdx0RUQ08opV27/ aaqPiZY5xR5l.
select password('test'),length(encrypt('test')),encrypt('test','aa');
--des-key-file=$MYSQL_TEST_DIR/std_data/des_key_file
-- source include/have_openssl.inc -- source include/have_openssl.inc
use test; drop table if exists t1;
drop table if exists x; create table t1 (x blob);
create table x (x blob); insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','The quick red fox jumped over the lazy brown dog'));
insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','The quick red fox jumped over the lazy brown dog')); insert into t1 values (des_encrypt('a','The quick red fox jumped over the lazy brown dog'));
insert into x values (des_encrypt('a','The quick red fox jumped over the lazy brown dog')); insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','a'));
insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','a')); insert into t1 values (des_encrypt('ab','The quick red fox jumped over the lazy brown dog'));
insert into x values (des_encrypt('ab','The quick red fox jumped over the lazy brown dog')); insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','ab'));
insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','ab')); insert into t1 values (des_encrypt('abc','The quick red fox jumped over the lazy brown dog'));
insert into x values (des_encrypt('abc','The quick red fox jumped over the lazy brown dog')); insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abc'));
insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','abc')); insert into t1 values (des_encrypt('abcd','The quick red fox jumped over the lazy brown dog'));
insert into x values (des_encrypt('abcd','The quick red fox jumped over the lazy brown dog')); insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcd'));
insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcd')); insert into t1 values (des_encrypt('abcde','The quick red fox jumped over the lazy brown dog'));
insert into x values (des_encrypt('abcde','The quick red fox jumped over the lazy brown dog')); insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcde'));
insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcde')); insert into t1 values (des_encrypt('abcdef','The quick red fox jumped over the lazy brown dog'));
insert into x values (des_encrypt('abcdef','The quick red fox jumped over the lazy brown dog')); insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdef'));
insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdef')); insert into t1 values (des_encrypt('abcdefg','The quick red fox jumped over the lazy brown dog'));
insert into x values (des_encrypt('abcdefg','The quick red fox jumped over the lazy brown dog')); insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefg'));
insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefg')); insert into t1 values (des_encrypt('abcdefgh','The quick red fox jumped over the lazy brown dog'));
insert into x values (des_encrypt('abcdefgh','The quick red fox jumped over the lazy brown dog')); insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefgh'));
insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefgh')); insert into t1 values (des_encrypt('abcdefghi','The quick red fox jumped over the lazy brown dog'));
insert into x values (des_encrypt('abcdefghi','The quick red fox jumped over the lazy brown dog')); insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefghi'));
insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefghi')); insert into t1 values (des_encrypt('abcdefghij','The quick red fox jumped over the lazy brown dog'));
insert into x values (des_encrypt('abcdefghij','The quick red fox jumped over the lazy brown dog')); insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefghij'));
insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefghij')); insert into t1 values (des_encrypt('abcdefghijk','The quick red fox jumped over the lazy brown dog'));
insert into x values (des_encrypt('abcdefghijk','The quick red fox jumped over the lazy brown dog')); insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefghijk'));
insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefghijk')); insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','sabakala'));
insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','sabakala')); insert into t1 values (des_encrypt('quick red fox jumped over the lazy brown dog','sabakala'));
insert into x values (des_encrypt('quick red fox jumped over the lazy brown dog','sabakala')); insert into t1 values (des_encrypt('red fox jumped over the lazy brown dog','sabakala'));
insert into x values (des_encrypt('red fox jumped over the lazy brown dog','sabakala')); insert into t1 values (des_encrypt('fox jumped over the lazy brown dog','sabakala'));
insert into x values (des_encrypt('fox jumped over the lazy brown dog','sabakala')); insert into t1 values (des_encrypt('jumped over the lazy brown dog','sabakala'));
insert into x values (des_encrypt('jumped over the lazy brown dog','sabakala')); insert into t1 values (des_encrypt('over the lazy brown dog','sabakala'));
insert into x values (des_encrypt('over the lazy brown dog','sabakala')); insert into t1 values (des_encrypt('the lazy brown dog','sabakala'));
insert into x values (des_encrypt('the lazy brown dog','sabakala')); insert into t1 values (des_encrypt('lazy brown dog','sabakala'));
insert into x values (des_encrypt('lazy brown dog','sabakala')); insert into t1 values (des_encrypt('brown dog','sabakala'));
insert into x values (des_encrypt('brown dog','sabakala')); insert into t1 values (des_encrypt('dog','sabakala'));
insert into x values (des_encrypt('dog','sabakala')); insert into t1 values (des_encrypt('dog!','sabakala'));
insert into x values (des_encrypt('jumped over the lazy brown dog','sabakala')); insert into t1 values (des_encrypt('dog!!','sabakala'));
insert into x values (des_encrypt('jumped over the lazy brown dog','sabakala')); insert into t1 values (des_encrypt('dog!!!','sabakala'));
insert into x values (des_encrypt('jumped over the lazy brown dog','sabakala')); insert into t1 values (des_encrypt('dog!!!!','sabakala'));
select * from x; insert into t1 values (des_encrypt('dog!!!!!','sabakala'));
select des_decrypt(x,'sabakala') from x; insert into t1 values (des_encrypt('jumped over the lazy brown dog','sabakala'));
drop table x; insert into t1 values (des_encrypt('jumped over the lazy brown dog','sabakala'));
select hex(x), hex(des_decrypt(x,'sabakala')) from t1;
select des_decrypt(x,'sabakala') as s from t1 having s like '%dog%';
drop table t1;
#
# Test default keys
#
select hex(des_encrypt("hello")),des_decrypt(des_encrypt("hello"));
select des_decrypt(des_encrypt("hello",4));
select des_decrypt(des_encrypt("hello",'test'),'test');
select hex(des_encrypt("hello")),hex(des_encrypt("hello",5)),hex(des_encrypt("hello",'default_password'));
select des_decrypt(des_encrypt("hello"),'default_password');
select des_decrypt(des_encrypt("hello",4),'password4');
# Test flush
SET @a=des_decrypt(des_encrypt("hello"));
flush des_key_file;
select @a = des_decrypt(des_encrypt("hello"));
# Test usage of wrong password
select hex("hello");
select hex(des_decrypt(des_encrypt("hello",4),'password2'));
select hex(des_decrypt(des_encrypt("hello","hidden")));
...@@ -35,8 +35,6 @@ select insert('txs',2,1,'hi'),insert('is ',4,0,'a'),insert('txxxxt',2,4,'es'); ...@@ -35,8 +35,6 @@ 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('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 replace(concat(lcase(concat('THIS',' ','IS',' ','A',' ')),ucase('false'),' ','test'),'FALSE','REAL') ;
select soundex(''),soundex('he'),soundex('hello all folks'); select soundex(''),soundex('he'),soundex('hello all folks');
--replace_result $1$aa$4OSUA5cjdx0RUQ08opV27/ aaqPiZY5xR5l.
select password('test'),length(encrypt('test')),encrypt('test','aa');
select md5('hello'); select md5('hello');
select repeat('monty',5),concat('*',space(5),'*'); select repeat('monty',5),concat('*',space(5),'*');
select reverse('abc'),reverse('abcd'); select reverse('abc'),reverse('abcd');
......
...@@ -19,25 +19,37 @@ ...@@ -19,25 +19,37 @@
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
struct st_des_keyschedule des_keyschedule[10];
uint des_default_key;
pthread_mutex_t LOCK_des_key_file;
static int initialized;
/* /*
Function which loads DES keys from plaintext file into memory on MySQL 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 ;) server startup and on command FLUSH DES_KEY_FILE.
*/ Blame tonu@spam.ee on bugs ;)
struct st_des_keyschedule des_keyschedule[10]; RETURN
uint des_default_key; 0 ok
1 Error
*/
void bool
load_des_key_file(const char *file_name) load_des_key_file(const char *file_name)
{ {
bool result=1;
File file; File file;
des_cblock ivec={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
char offset;
IO_CACHE io; IO_CACHE io;
DBUG_ENTER("load_des_key_file"); DBUG_ENTER("load_des_key_file");
DBUG_PRINT("enter",("name: %s",file_name)); DBUG_PRINT("enter",("name: %s",file_name));
VOID(pthread_mutex_lock(&LOCK_open)); if (!initialized)
{
initialized=1;
pthread_mutex_init(&LOCK_des_key_file,MY_MUTEX_INIT_FAST);
}
VOID(pthread_mutex_lock(&LOCK_des_key_file));
if ((file=my_open(file_name,O_RDONLY | O_BINARY ,MYF(MY_WME))) < 0 || 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))) init_io_cache(&io, file, IO_SIZE*2, READ_CACHE, 0, 0, MYF(MY_WME)))
goto error; goto error;
...@@ -47,7 +59,7 @@ load_des_key_file(const char *file_name) ...@@ -47,7 +59,7 @@ load_des_key_file(const char *file_name)
for (;;) for (;;)
{ {
char *start, *end; char *start, *end;
char buf[1024]; char buf[1024], offset;
st_des_keyblock keyblock; st_des_keyblock keyblock;
uint length; uint length;
...@@ -60,10 +72,12 @@ load_des_key_file(const char *file_name) ...@@ -60,10 +72,12 @@ load_des_key_file(const char *file_name)
// Remove newline and possible other control characters // Remove newline and possible other control characters
for (start=buf+1 ; isspace(*start) ; start++) ; for (start=buf+1 ; isspace(*start) ; start++) ;
end=buf+length; end=buf+length;
for (end=strend(buf) ; end > start && iscntrl(end[-1]) ; end--) ; for (end=strend(buf) ; end > start && !isgraph(end[-1]) ; end--) ;
if (start != end) if (start != end)
{ {
des_cblock ivec;
bzero((char*) &ivec,sizeof(ivec));
// 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
EVP_BytesToKey(EVP_des_ede3_cbc(),EVP_md5(),NULL, EVP_BytesToKey(EVP_des_ede3_cbc(),EVP_md5(),NULL,
(uchar *) start, (int) (end-start),1, (uchar *) start, (int) (end-start),1,
...@@ -76,11 +90,10 @@ load_des_key_file(const char *file_name) ...@@ -76,11 +90,10 @@ load_des_key_file(const char *file_name)
des_default_key= (uint) offset; // use first as def. des_default_key= (uint) offset; // use first as def.
} }
} }
else else if (offset != '#')
{ sql_print_error("load_des_file: Found wrong key_number: %c",offset);
DBUG_PRINT("des",("wrong offset: %c",offset));
}
} }
result=0;
error: error:
if (file >= 0) if (file >= 0)
...@@ -88,7 +101,7 @@ error: ...@@ -88,7 +101,7 @@ error:
my_close(file,MYF(0)); my_close(file,MYF(0));
end_io_cache(&io); end_io_cache(&io);
} }
VOID(pthread_mutex_unlock(&LOCK_open)); VOID(pthread_mutex_unlock(&LOCK_des_key_file));
DBUG_VOID_RETURN; DBUG_RETURN(result);
} }
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
...@@ -151,8 +151,7 @@ Item *create_func_get_lock(Item* a, Item *b) ...@@ -151,8 +151,7 @@ Item *create_func_get_lock(Item* a, Item *b)
Item *create_func_hex(Item *a) Item *create_func_hex(Item *a)
{ {
return new Item_func_conv(a,new Item_int((int32) 10,2), return new Item_func_hex(a);
new Item_int((int32) 16,2));
} }
Item *create_func_inet_ntoa(Item* a) Item *create_func_inet_ntoa(Item* a)
......
...@@ -209,78 +209,84 @@ void Item_func_concat::fix_length_and_dec() ...@@ -209,78 +209,84 @@ void Item_func_concat::fix_length_and_dec()
Function des_encrypt() by tonu@spam.ee & monty Function des_encrypt() by tonu@spam.ee & monty
Works only if compiled with OpenSSL library support. Works only if compiled with OpenSSL library support.
This returns a binary string where first character is This returns a binary string where first character is
CHAR(128 | tail-length << 4 | key-number). CHAR(128 | key-number).
If one uses a string key key_number is 0. If one uses a string key key_number is 127.
Encryption result is longer than original by formula: Encryption result is longer than original by formula:
new_length= (8-(original_length % 8))+1 new_length= org_length + (8-(org_length % 8))+1
*/ */
String *Item_func_des_encrypt::val_str(String *str) String *Item_func_des_encrypt::val_str(String *str)
{ {
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
des_cblock ivec={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; des_cblock ivec;
struct st_des_keyblock keyblock; struct st_des_keyblock keyblock;
struct st_des_keyschedule keyschedule; struct st_des_keyschedule keyschedule;
struct st_des_keyschedule *keyschedule_ptr;
const char *append_str="********"; const char *append_str="********";
uint key_number, res_length, tail; uint key_number, res_length, tail;
String *res= args[0]->val_str(str); String *res= args[0]->val_str(str);
if ((null_value=args[0]->null_value)) if ((null_value=args[0]->null_value))
return 0; return 0;
if (res->length() == 0) if ((res_length=res->length()) == 0)
return &empty_string; return &empty_string;
if (arg_count == 1) if (arg_count == 1)
keyschedule_ptr= &des_keyschedule[key_number=des_default_key]; {
/* Protect against someone doing FLUSH DES_KEY_FILE */
VOID(pthread_mutex_lock(&LOCK_des_key_file));
keyschedule= des_keyschedule[key_number=des_default_key];
VOID(pthread_mutex_unlock(&LOCK_des_key_file));
}
else if (args[1]->result_type() == INT_RESULT) else if (args[1]->result_type() == INT_RESULT)
{ {
key_number= (uint) args[1]->val_int(); key_number= (uint) args[1]->val_int();
if (key_number > 9) if (key_number > 9)
goto error; goto error;
keyschedule_ptr= &des_keyschedule[key_number]; VOID(pthread_mutex_lock(&LOCK_des_key_file));
keyschedule= des_keyschedule[key_number];
VOID(pthread_mutex_unlock(&LOCK_des_key_file));
} }
else else
{ {
uint tail,res_length;
String *keystr=args[1]->val_str(&tmp_value); String *keystr=args[1]->val_str(&tmp_value);
if (!keystr) if (!keystr)
goto error; goto error;
key_number=15; // User key string key_number=127; // User key string
/* 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 */
keyschedule_ptr= &keyschedule; bzero((char*) &ivec,sizeof(ivec));
EVP_BytesToKey(EVP_des_ede3_cbc(),EVP_md5(),NULL, EVP_BytesToKey(EVP_des_ede3_cbc(),EVP_md5(),NULL,
(uchar*) keystr->ptr(), (int) keystr->length(), (uchar*) keystr->ptr(), (int) keystr->length(),
1, (uchar*) &keyblock,ivec); 1, (uchar*) &keyblock,ivec);
des_set_key_unchecked(&keyblock.key1,keyschedule_ptr->ks1); des_set_key_unchecked(&keyblock.key1,keyschedule.ks1);
des_set_key_unchecked(&keyblock.key2,keyschedule_ptr->ks2); des_set_key_unchecked(&keyblock.key2,keyschedule.ks2);
des_set_key_unchecked(&keyblock.key3,keyschedule_ptr->ks3); des_set_key_unchecked(&keyblock.key3,keyschedule.ks3);
} }
/* /*
The problem: DES algorithm requires original data to be in 8-bytes The problem: DES algorithm requires original data to be in 8-bytes
chunks. Missing bytes get filled with zeros and result of encryption chunks. Missing bytes get filled with '*'s and result of encryption
can be up to 7 bytes longer than original string. When decrypted, can be up to 8 bytes longer than original string. When decrypted,
we do not know the size of original string :( we do not know the size of original string :(
We add one byte with value 0x1..0x8 as the second byte to original We add one byte with value 0x1..0x8 as the last byte of the padded
plaintext marking change of string length. string marking change of string length.
*/ */
tail= (7-(res->length()+7) % 8); // 0..7 marking extra length tail= (8-(res_length) % 8); // 1..8 marking extra length
res_length=res->length()+tail+1; res_length+=tail;
if (tail && res->append(append_str, tail) || tmp_value.alloc(res_length)) if (tail && res->append(append_str, tail) || tmp_value.alloc(res_length+1))
goto error; goto error;
(*res)[res_length-1]=tail; // save extra length
tmp_value.length(res_length); tmp_value.length(res_length+1);
tmp_value[0]=(char) (128 | tail << 4 | key_number); tmp_value[0]=(char) (128 | key_number);
// Real encryption // Real encryption
bzero((char*) &ivec,sizeof(ivec));
des_ede3_cbc_encrypt((const uchar*) (res->ptr()), des_ede3_cbc_encrypt((const uchar*) (res->ptr()),
(uchar*) (tmp_value.ptr()+1), (uchar*) (tmp_value.ptr()+1),
res->length(), res_length,
keyschedule_ptr->ks1, keyschedule.ks1,
keyschedule_ptr->ks2, keyschedule.ks2,
keyschedule_ptr->ks3, keyschedule.ks3,
&ivec, TRUE); &ivec, TRUE);
return &tmp_value; return &tmp_value;
...@@ -295,24 +301,27 @@ String *Item_func_des_decrypt::val_str(String *str) ...@@ -295,24 +301,27 @@ String *Item_func_des_decrypt::val_str(String *str)
{ {
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
des_key_schedule ks1, ks2, ks3; des_key_schedule ks1, ks2, ks3;
des_cblock ivec={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; des_cblock ivec;
struct st_des_keyblock keyblock; struct st_des_keyblock keyblock;
struct st_des_keyschedule keyschedule; struct st_des_keyschedule keyschedule;
struct st_des_keyschedule *keyschedule_ptr;
String *res= args[0]->val_str(str); String *res= args[0]->val_str(str);
uint length=res->length(),tail;
if ((null_value=args[0]->null_value)) if ((null_value=args[0]->null_value))
return 0; return 0;
if (res->length() < 9 || (res->length() % 8) != 1 || !((*res)[0] & 128)) length=res->length();
if (length < 9 || (length % 8) != 1 || !((*res)[0] & 128))
return res; // Skip decryption if not encrypted return res; // Skip decryption if not encrypted
if (arg_count == 1) // If automatic uncompression if (arg_count == 1) // If automatic uncompression
{ {
uint key_number=(uint) (*res)[0] & 15; uint key_number=(uint) (*res)[0] & 127;
// Check if automatic key and that we have privilege to uncompress using it // Check if automatic key and that we have privilege to uncompress using it
if (!(current_thd->master_access & PROCESS_ACL) || key_number > 9) if (!(current_thd->master_access & PROCESS_ACL) || key_number > 9)
goto error; goto error;
keyschedule_ptr= &des_keyschedule[key_number]; VOID(pthread_mutex_lock(&LOCK_des_key_file));
keyschedule= des_keyschedule[key_number];
VOID(pthread_mutex_unlock(&LOCK_des_key_file));
} }
else else
{ {
...@@ -321,26 +330,30 @@ String *Item_func_des_decrypt::val_str(String *str) ...@@ -321,26 +330,30 @@ String *Item_func_des_decrypt::val_str(String *str)
if (!keystr) if (!keystr)
goto error; goto error;
keyschedule_ptr= &keyschedule; bzero((char*) &ivec,sizeof(ivec));
EVP_BytesToKey(EVP_des_ede3_cbc(),EVP_md5(),NULL, EVP_BytesToKey(EVP_des_ede3_cbc(),EVP_md5(),NULL,
(uchar*) keystr->ptr(),(int) keystr->length(), (uchar*) keystr->ptr(),(int) keystr->length(),
1,(uchar*) &keyblock,ivec); 1,(uchar*) &keyblock,ivec);
// Here we set all 64-bit keys (56 effective) one by one // 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.key1,keyschedule.ks1);
des_set_key_unchecked(&keyblock.key2,keyschedule_ptr->ks2); des_set_key_unchecked(&keyblock.key2,keyschedule.ks2);
des_set_key_unchecked(&keyblock.key3,keyschedule_ptr->ks3); des_set_key_unchecked(&keyblock.key3,keyschedule.ks3);
} }
if (tmp_value.alloc(res->length()-1)) if (tmp_value.alloc(length-1))
goto error; goto error;
/* Restore old length of key */
tmp_value.length(res->length()-1-(((uchar) (*res)[0] >> 4) & 7)); bzero((char*) &ivec,sizeof(ivec));
des_ede3_cbc_encrypt((const uchar*) res->ptr()+1, des_ede3_cbc_encrypt((const uchar*) res->ptr()+1,
(uchar*) (tmp_value.ptr()), (uchar*) (tmp_value.ptr()),
res->length()-1, length-1,
keyschedule_ptr->ks1, keyschedule.ks1,
keyschedule_ptr->ks2, keyschedule.ks2,
keyschedule_ptr->ks3, keyschedule.ks3,
&ivec, FALSE); &ivec, FALSE);
/* Restore old length of key */
if ((tail=(uint) (uchar) tmp_value[length-2]) > 8)
goto error; // Wrong key
tmp_value.length(length-1-tail);
return &tmp_value; return &tmp_value;
error: error:
...@@ -1274,9 +1287,9 @@ String *Item_func_soundex::val_str(String *str) ...@@ -1274,9 +1287,9 @@ String *Item_func_soundex::val_str(String *str)
if ((null_value=args[0]->null_value)) if ((null_value=args[0]->null_value))
return 0; /* purecov: inspected */ return 0; /* purecov: inspected */
if (str_value.alloc(max(res->length(),4))) if (tmp_value.alloc(max(res->length(),4)))
return str; /* purecov: inspected */ return str; /* purecov: inspected */
char *to= (char *) str_value.ptr(); char *to= (char *) tmp_value.ptr();
char *from= (char *) res->ptr(), *end=from+res->length(); char *from= (char *) res->ptr(), *end=from+res->length();
while (from != end && isspace(*from)) // Skip pre-space while (from != end && isspace(*from)) // Skip pre-space
...@@ -1300,11 +1313,11 @@ String *Item_func_soundex::val_str(String *str) ...@@ -1300,11 +1313,11 @@ String *Item_func_soundex::val_str(String *str)
last_ch = ch; // save code of last input letter last_ch = ch; // save code of last input letter
} // for next double-letter check } // for next double-letter check
} }
for (end=(char*) str_value.ptr()+4 ; to < end ; to++) for (end=(char*) tmp_value.ptr()+4 ; to < end ; to++)
*to = '0'; *to = '0';
*to=0; // end string *to=0; // end string
str_value.length((uint) (to-str_value.ptr())); tmp_value.length((uint) (to-tmp_value.ptr()));
return &str_value; return &tmp_value;
} }
...@@ -1759,6 +1772,45 @@ String *Item_func_conv::val_str(String *str) ...@@ -1759,6 +1772,45 @@ String *Item_func_conv::val_str(String *str)
return str; return str;
} }
String *Item_func_hex::val_str(String *str)
{
if (args[0]->result_type() != STRING_RESULT)
{
/* Return hex of unsigned longlong value */
longlong dec= args[0]->val_int();
char ans[65],*ptr;
if ((null_value= args[0]->null_value))
return 0;
ptr= longlong2str(dec,ans,16);
if (str->copy(ans,(uint32) (ptr-ans)))
return &empty_string; // End of memory
return str;
}
/* Convert given string to a hex string, character by character */
String *res= args[0]->val_str(str);
const char *from, *end;
char *to;
if (!res || tmp_value.alloc(res->length()*2))
{
null_value=1;
return 0;
}
null_value=0;
tmp_value.length(res->length()*2);
for (from=res->ptr(), end=from+res->length(), to= (char*) tmp_value.ptr();
from != end ;
from++, to+=2)
{
uint tmp=(uint) (uchar) *from;
to[0]=_dig_vec[tmp >> 4];
to[1]=_dig_vec[tmp & 15];
}
return &tmp_value;
}
#include <my_dir.h> // For my_stat #include <my_dir.h> // For my_stat
String *Item_load_file::val_str(String *str) String *Item_load_file::val_str(String *str)
......
...@@ -297,6 +297,7 @@ public: ...@@ -297,6 +297,7 @@ public:
class Item_func_soundex :public Item_str_func class Item_func_soundex :public Item_str_func
{ {
String tmp_value;
public: public:
Item_func_soundex(Item *a) :Item_str_func(a) {} Item_func_soundex(Item *a) :Item_str_func(a) {}
String *val_str(String *); String *val_str(String *);
...@@ -412,6 +413,18 @@ public: ...@@ -412,6 +413,18 @@ public:
void fix_length_and_dec() { decimals=0; max_length=64; } void fix_length_and_dec() { decimals=0; max_length=64; }
}; };
class Item_func_hex :public Item_str_func
{
String tmp_value;
public:
Item_func_hex(Item *a) :Item_str_func(a) {}
const char *func_name() const { return "hex"; }
String *val_str(String *);
void fix_length_and_dec() { decimals=0; max_length=args[0]->max_length*2; }
};
class Item_func_binary :public Item_str_func class Item_func_binary :public Item_str_func
{ {
public: public:
......
...@@ -672,7 +672,7 @@ String *Item_func_date_format::val_str(String *str) ...@@ -672,7 +672,7 @@ String *Item_func_date_format::val_str(String *str)
else else
size=format_length(format); size=format_length(format);
if (format == str) if (format == str)
str=&str_value; // Save result here str= &str_value; // Save result here
if (str->alloc(size)) if (str->alloc(size))
{ {
null_value=1; null_value=1;
......
...@@ -111,6 +111,7 @@ static SYMBOL symbols[] = { ...@@ -111,6 +111,7 @@ static SYMBOL symbols[] = {
{ "DAY_SECOND", SYM(DAY_SECOND_SYM),0,0}, { "DAY_SECOND", SYM(DAY_SECOND_SYM),0,0},
{ "DEC", SYM(DECIMAL_SYM),0,0}, { "DEC", SYM(DECIMAL_SYM),0,0},
{ "DECIMAL", SYM(DECIMAL_SYM),0,0}, { "DECIMAL", SYM(DECIMAL_SYM),0,0},
{ "DES_KEY_FILE", SYM(DES_KEY_FILE),0,0},
{ "DEFAULT", SYM(DEFAULT),0,0}, { "DEFAULT", SYM(DEFAULT),0,0},
{ "DELAYED", SYM(DELAYED_SYM),0,0}, { "DELAYED", SYM(DELAYED_SYM),0,0},
{ "DELAY_KEY_WRITE", SYM(DELAY_KEY_WRITE_SYM),0,0}, { "DELAY_KEY_WRITE", SYM(DELAY_KEY_WRITE_SYM),0,0},
......
...@@ -263,7 +263,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list); ...@@ -263,7 +263,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list);
bool mysql_change_db(THD *thd,const char *name); bool mysql_change_db(THD *thd,const char *name);
void mysql_parse(THD *thd,char *inBuf,uint length); void mysql_parse(THD *thd,char *inBuf,uint length);
void mysql_init_select(LEX *lex); void mysql_init_select(LEX *lex);
void mysql_new_select(LEX *lex); bool mysql_new_select(LEX *lex);
void init_max_user_conn(void); void init_max_user_conn(void);
void free_max_user_conn(void); void free_max_user_conn(void);
pthread_handler_decl(handle_one_connection,arg); pthread_handler_decl(handle_one_connection,arg);
...@@ -405,9 +405,11 @@ struct st_des_keyschedule ...@@ -405,9 +405,11 @@ struct st_des_keyschedule
{ {
des_key_schedule ks1, ks2, ks3; des_key_schedule ks1, ks2, ks3;
}; };
extern char *des_key_file;
extern struct st_des_keyschedule des_keyschedule[10]; extern struct st_des_keyschedule des_keyschedule[10];
extern uint des_default_key; extern uint des_default_key;
void load_des_key_file(const char *file_name); extern pthread_mutex_t LOCK_des_key_file;
bool load_des_key_file(const char *file_name);
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
/* sql_list.c */ /* sql_list.c */
......
...@@ -242,7 +242,7 @@ static char glob_hostname[FN_REFLEN]; ...@@ -242,7 +242,7 @@ static char glob_hostname[FN_REFLEN];
#include "sslopt-vars.h" #include "sslopt-vars.h"
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
static char * des_key_file = 0; char *des_key_file = 0;
struct st_VioSSLAcceptorFd * ssl_acceptor_fd = 0; struct st_VioSSLAcceptorFd * ssl_acceptor_fd = 0;
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
......
...@@ -2431,9 +2431,10 @@ mysql_init_select(LEX *lex) ...@@ -2431,9 +2431,10 @@ mysql_init_select(LEX *lex)
{ {
SELECT_LEX *select_lex = lex->select; SELECT_LEX *select_lex = lex->select;
select_lex->where=select_lex->having=0; select_lex->where=select_lex->having=0;
select_lex->select_limit=current_thd->default_select_limit; select_lex->select_limit=lex->thd->default_select_limit;
select_lex->offset_limit=0; select_lex->offset_limit=0;
select_lex->options=0; select_lex->linkage=UNSPECIFIED_TYPE; select_lex->options=0;
select_lex->linkage=UNSPECIFIED_TYPE;
lex->exchange = 0; lex->exchange = 0;
lex->proc_list.first=0; lex->proc_list.first=0;
select_lex->order_list.elements=select_lex->group_list.elements=0; select_lex->order_list.elements=select_lex->group_list.elements=0;
...@@ -2444,18 +2445,25 @@ mysql_init_select(LEX *lex) ...@@ -2444,18 +2445,25 @@ mysql_init_select(LEX *lex)
select_lex->next = (SELECT_LEX *)NULL; select_lex->next = (SELECT_LEX *)NULL;
} }
void bool
mysql_new_select(LEX *lex) mysql_new_select(LEX *lex)
{ {
SELECT_LEX *select_lex = (SELECT_LEX *) lex->thd->calloc(sizeof(SELECT_LEX)); SELECT_LEX *select_lex = (SELECT_LEX *) lex->thd->calloc(sizeof(SELECT_LEX));
if (!select_lex)
return 1;
lex->select->next=select_lex; lex->select->next=select_lex;
lex->select=select_lex; lex->select=select_lex;
select_lex->table_list.next= (byte**) &select_lex->table_list.first; select_lex->table_list.next= (byte**) &select_lex->table_list.first;
select_lex->item_list.empty(); select_lex->when_list.empty(); select_lex->item_list.empty();
select_lex->expr_list.empty(); select_lex->interval_list.empty(); select_lex->when_list.empty();
select_lex->use_index.empty(); select_lex->ftfunc_list.empty(); select_lex->expr_list.empty();
select_lex->interval_list.empty();
select_lex->use_index.empty();
select_lex->ftfunc_list.empty();
return 0;
} }
void void
mysql_parse(THD *thd,char *inBuf,uint length) mysql_parse(THD *thd,char *inBuf,uint length)
{ {
...@@ -3035,7 +3043,13 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables) ...@@ -3035,7 +3043,13 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables)
reset_master(); reset_master();
if (options & REFRESH_SLAVE) if (options & REFRESH_SLAVE)
reset_slave(); reset_slave();
#ifdef OPENSSL
if (options & REFRESH_DES_KEY_FILE)
{
if (des_key_file)
result=load_des_key_file(des_key_file);
}
#endif
return result; return result;
} }
......
...@@ -171,13 +171,14 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -171,13 +171,14 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token DEMAND_SYM %token DEMAND_SYM
%token DESC %token DESC
%token DESCRIBE %token DESCRIBE
%token DIRECTORY_SYM %token DES_KEY_FILE
%token DISTINCT
%token DISABLE_SYM %token DISABLE_SYM
%token DISTINCT
%token DYNAMIC_SYM %token DYNAMIC_SYM
%token ENABLE_SYM %token ENABLE_SYM
%token ENCLOSED %token ENCLOSED
%token ESCAPED %token ESCAPED
%token DIRECTORY_SYM
%token ESCAPE_SYM %token ESCAPE_SYM
%token EXISTS %token EXISTS
%token EXTENDED_SYM %token EXTENDED_SYM
...@@ -2106,13 +2107,7 @@ order_dir: ...@@ -2106,13 +2107,7 @@ order_dir:
limit_clause: limit_clause:
/* empty */ /* empty */ {}
{
SELECT_LEX *sel=Select;
sel->select_limit= (Lex->sql_command == SQLCOM_HA_READ) ?
1 : current_thd->default_select_limit;
sel->offset_limit= 0L;
}
| LIMIT ULONG_NUM | LIMIT ULONG_NUM
{ {
SELECT_LEX *sel=Select; SELECT_LEX *sel=Select;
...@@ -2512,11 +2507,12 @@ show_param: ...@@ -2512,11 +2507,12 @@ show_param:
MASTER_LOG_SEQ_SYM EQ ULONG_NUM AND MASTER_SERVER_ID_SYM EQ MASTER_LOG_SEQ_SYM EQ ULONG_NUM AND MASTER_SERVER_ID_SYM EQ
ULONG_NUM ULONG_NUM
{ {
Lex->sql_command = SQLCOM_SHOW_NEW_MASTER; LEX *lex=Lex;
Lex->mi.log_file_name = $8.str; lex->sql_command = SQLCOM_SHOW_NEW_MASTER;
Lex->mi.pos = $12; lex->mi.log_file_name = $8.str;
Lex->mi.last_log_seq = $16; lex->mi.pos = $12;
Lex->mi.server_id = $20; lex->mi.last_log_seq = $16;
lex->mi.server_id = $20;
} }
| MASTER_SYM LOGS_SYM | MASTER_SYM LOGS_SYM
{ {
...@@ -2526,10 +2522,13 @@ show_param: ...@@ -2526,10 +2522,13 @@ show_param:
{ {
Lex->sql_command = SQLCOM_SHOW_SLAVE_HOSTS; Lex->sql_command = SQLCOM_SHOW_SLAVE_HOSTS;
} }
| BINLOG_SYM EVENTS_SYM binlog_in binlog_from limit_clause | BINLOG_SYM EVENTS_SYM binlog_in binlog_from
{ {
Lex->sql_command = SQLCOM_SHOW_BINLOG_EVENTS; LEX *lex=Lex;
} lex->sql_command = SQLCOM_SHOW_BINLOG_EVENTS;
lex->select->select_limit= lex->thd->default_select_limit;
lex->select->offset_limit= 0L;
} limit_clause
| keys_or_index FROM table_ident opt_db | keys_or_index FROM table_ident opt_db
{ {
Lex->sql_command= SQLCOM_SHOW_KEYS; Lex->sql_command= SQLCOM_SHOW_KEYS;
...@@ -2642,6 +2641,7 @@ flush_option: ...@@ -2642,6 +2641,7 @@ flush_option:
| STATUS_SYM { Lex->type|= REFRESH_STATUS; } | STATUS_SYM { Lex->type|= REFRESH_STATUS; }
| SLAVE { Lex->type|= REFRESH_SLAVE; } | SLAVE { Lex->type|= REFRESH_SLAVE; }
| MASTER_SYM { Lex->type|= REFRESH_MASTER; } | MASTER_SYM { Lex->type|= REFRESH_MASTER; }
| DES_KEY_FILE { Lex->type|= REFRESH_DES_KEY_FILE; }
opt_table_list: opt_table_list:
/* empty */ {} /* empty */ {}
...@@ -2912,27 +2912,28 @@ keyword: ...@@ -2912,27 +2912,28 @@ keyword:
| CIPHER_SYM {} | CIPHER_SYM {}
| CLOSE_SYM {} | CLOSE_SYM {}
| COMMENT_SYM {} | COMMENT_SYM {}
| COMMIT_SYM {}
| COMMITTED_SYM {} | COMMITTED_SYM {}
| COMMIT_SYM {}
| COMPRESSED_SYM {} | COMPRESSED_SYM {}
| CONCURRENT {} | CONCURRENT {}
| DATA_SYM {} | DATA_SYM {}
| DATETIME {} | DATETIME {}
| DATE_SYM {} | DATE_SYM {}
| DAY_SYM {} | DAY_SYM {}
| DIRECTORY_SYM {}
| DELAY_KEY_WRITE_SYM {} | DELAY_KEY_WRITE_SYM {}
| DEMAND_SYM {} | DEMAND_SYM {}
| DISABLE_SYM {} | DES_KEY_FILE {}
| DIRECTORY_SYM {}
| DUMPFILE {} | DUMPFILE {}
| DYNAMIC_SYM {} | DYNAMIC_SYM {}
| ENABLE_SYM {}
| END {} | END {}
| ENUM {} | ENUM {}
| ESCAPE_SYM {} | ESCAPE_SYM {}
| EVENTS_SYM {} | EVENTS_SYM {}
| EXTENDED_SYM {} | EXTENDED_SYM {}
| FAST_SYM {} | FAST_SYM {}
| DISABLE_SYM {}
| ENABLE_SYM {}
| FULL {} | FULL {}
| FILE_SYM {} | FILE_SYM {}
| FIRST_SYM {} | FIRST_SYM {}
...@@ -3296,6 +3297,8 @@ handler: ...@@ -3296,6 +3297,8 @@ handler:
LEX *lex=Lex; LEX *lex=Lex;
lex->sql_command = SQLCOM_HA_READ; lex->sql_command = SQLCOM_HA_READ;
lex->ha_rkey_mode= HA_READ_KEY_EXACT; /* Avoid purify warnings */ lex->ha_rkey_mode= HA_READ_KEY_EXACT; /* Avoid purify warnings */
lex->select->select_limit= 1;
lex->select->offset_limit= 0L;
if (!add_table_to_list($2,0,0)) if (!add_table_to_list($2,0,0))
YYABORT; YYABORT;
} }
...@@ -3581,9 +3584,8 @@ union_list: ...@@ -3581,9 +3584,8 @@ union_list:
net_printf(&lex->thd->net, ER_WRONG_USAGE,"UNION","INTO"); net_printf(&lex->thd->net, ER_WRONG_USAGE,"UNION","INTO");
YYABORT; YYABORT;
} }
if (lex->select->linkage == NOT_A_SELECT) if (lex->select->linkage == NOT_A_SELECT || mysql_new_select(lex))
YYABORT; YYABORT;
mysql_new_select(lex);
lex->select->linkage=UNION_TYPE; lex->select->linkage=UNION_TYPE;
} }
select_init select_init
...@@ -3597,11 +3599,11 @@ optional_order_or_limit: ...@@ -3597,11 +3599,11 @@ optional_order_or_limit:
| |
{ {
LEX *lex=Lex; LEX *lex=Lex;
if (!lex->select->braces) if (!lex->select->braces || mysql_new_select(lex))
YYABORT; YYABORT;
mysql_new_select(lex);
mysql_init_select(lex); mysql_init_select(lex);
lex->select->linkage=NOT_A_SELECT; lex->select->linkage=NOT_A_SELECT;
lex->select->select_limit=lex->thd->default_select_limit;
} }
opt_order_clause limit_clause opt_order_clause limit_clause
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment