Commit b96f340c authored by arjen@fred.bitbike.com's avatar arjen@fred.bitbike.com

Merge work.mysql.com:/home/bk/mysql-4.0

into fred.bitbike.com:/home/arjen/mysql-4.0
parents 38cd5e80 138e5d57
......@@ -32,6 +32,7 @@ miguel@light.local
monty@bitch.mysql.fi
monty@donna.mysql.fi
monty@hundin.mysql.fi
monty@mashka.mysql.fi
monty@narttu.
monty@narttu.mysql.fi
monty@tik.
......@@ -43,11 +44,13 @@ mwagner@evoq.mwagner.org
nick@nick.leippe.com
paul@central.snake.net
paul@teton.kitebird.com
peter@linux.local
root@x3.internalnet
sasha@mysql.sashanet.com
serg@serg.mysql.com
serg@sergbook.mysql.com
sinisa@rhols221.adsl.netsonic.fi
tfr@indrek.tfr.cafe.ee
tfr@sarvik.tfr.cafe.ee
tim@bitch.mysql.fi
tim@black.box
......@@ -64,5 +67,3 @@ venu@work.mysql.com
worm@altair.is.lan
zak@balfor.local
zak@linux.local
tfr@indrek.tfr.cafe.ee
monty@mashka.mysql.fi
......@@ -49458,6 +49458,15 @@ Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}.
@itemize @bullet
@item
Fixed a bug in optimiser with merge tables when non-uniques values are
used in summing up.
This consistently crashed MySQL.
@item
Fixed a bug in optimiser when a range specified makes index grouping impossible.
This consistently crashed MySQL.
@item
Fixed a rare bug when fulltext index is present and no tables are used
@item
Added privileges @code{CREATE TEMPORARY TABLES}, @code{LOCK TABLES},
@code{REPLICATION CLIENT}, @code{REPLICATION SLAVE},
@code{SHOW DATABASES} and @code{SUPER}. To use these, you must have
......@@ -37,4 +37,4 @@ enum options { OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET,
OPT_SELECT_LIMIT, OPT_MAX_JOIN_SIZE, OPT_SSL_SSL,
OPT_SSL_KEY, OPT_SSL_CERT, OPT_SSL_CA, OPT_SSL_CAPATH,
OPT_SSL_CIPHER, OPT_SHUTDOWN_TIMEOUT, OPT_LOCAL_INFILE,
OPT_PROMPT, OPT_IGN_LINES };
OPT_PROMPT, OPT_IGN_LINES,OPT_TRANSACTION };
......@@ -33,6 +33,7 @@
** Tnu Samuel <tonu@please.do.not.remove.this.spam.ee>
** XML by Gary Huntress <ghuntress@mediaone.net> 10/10/01, cleaned up
** and adapted to mysqldump 05/11/01 by Jani Tolonen
** Added --single-transaction option 06/06/2002 by Peter Zaitsev
*/
#define DUMP_VERSION "9.06"
......@@ -76,7 +77,7 @@ static my_bool verbose=0,tFlag=0,cFlag=0,dFlag=0,quick=0, extended_insert = 0,
opt_delayed=0,create_options=0,opt_quoted=0,opt_databases=0,
opt_alldbs=0,opt_create_db=0,opt_first_slave=0,
opt_autocommit=0,opt_master_data,opt_disable_keys=0,opt_xml=0,
tty_password=0;
tty_password=0,opt_single_transaction=0;
static MYSQL mysql_connection,*sock=0;
static char insert_pat[12 * 1024],*opt_password=0,*current_user=0,
*current_host=0,*path=0,*fields_terminated=0,
......@@ -171,6 +172,10 @@ static struct my_option my_long_options[] =
"Wrap tables with autocommit/commit statements.",
(gptr*) &opt_autocommit, (gptr*) &opt_autocommit, 0, GET_BOOL, NO_ARG,
0, 0, 0, 0, 0, 0},
{"single-transaction", OPT_TRANSACTION,
"Dump all tables in single transaction to get consistent snapshot. Mutually exclusive with --lock-tables.",
(gptr*) &opt_single_transaction, (gptr*) &opt_single_transaction, 0, GET_BOOL, NO_ARG,
0, 0, 0, 0, 0, 0},
{"no-create-db", 'n',
"'CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_name;' will not be put in the output. The above line will be added otherwise, if --databases or --all-databases option was given.}",
(gptr*) &opt_create_db, (gptr*) &opt_create_db, 0, GET_BOOL, NO_ARG, 0, 0,
......@@ -340,8 +345,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
usage();
exit(0);
case (int) OPT_OPTIMIZE:
extended_insert=opt_drop=opt_lock=lock_tables=quick=create_options=
opt_disable_keys=1;
extended_insert=opt_drop=opt_lock=quick=create_options=opt_disable_keys=
lock_tables=1;
if (opt_single_transaction) lock_tables=0;
break;
case (int) OPT_TABLES:
opt_databases=0;
......@@ -372,6 +378,12 @@ static int get_options(int *argc, char ***argv)
return(1);
}
if (opt_single_transaction && lock_tables)
{
fprintf(stderr, "%s: You can't use --lock-tables and --single-transaction at the same time.\n", my_progname);
return(1);
}
if (enclosed && opt_enclosed)
{
fprintf(stderr, "%s: You can't use ..enclosed.. and ..optionally-enclosed.. at the same time.\n", my_progname);
......@@ -1369,6 +1381,17 @@ int main(int argc, char **argv)
return(first_error);
}
}
else if (opt_single_transaction)
{
/* There is no sense to start transaction if all tables are locked */
if (mysql_query(sock, "BEGIN"))
{
my_printf_error(0, "Error: Couldn't execute 'BEGIN': %s",
MYF(0), mysql_error(sock));
my_end(0);
return(first_error);
}
}
if (opt_alldbs)
dump_all_databases();
else if (argc > 1 && !opt_databases)
......@@ -1412,6 +1435,20 @@ int main(int argc, char **argv)
my_printf_error(0, "Error: Couldn't execute 'UNLOCK TABLES': %s",
MYF(0), mysql_error(sock));
}
else if (opt_single_transaction) /* Just to make it beautiful enough */
{
/*
In case we were locking all tables, we did not start transaction
so there is no need to commit it.
*/
/* This should just free locks as we did not change anything */
if (mysql_query(sock, "COMMIT"))
{
my_printf_error(0, "Error: Couldn't execute 'COMMIT': %s",
MYF(0), mysql_error(sock));
}
}
dbDisconnect(current_host);
fputs("\n", md_result_file);
if (md_result_file != stdout)
......
/* Copyright (C) 2002 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Header file for my_aes.c */
/* Wrapper to give simple interface for MySQL to AES standard encryption */
#ifndef __MY_AES_H
#define __MY_AES_H
#include "my_global.h"
#include <stdio.h>
#include "rijndael.h"
#define AES_KEY_LENGTH 128
/* Must be 128 192 or 256 */
#ifdef __cplusplus
extern "C" {
#endif
/*
my_aes_encrypt - Crypt buffer with AES encryption algorithm.
source - Pinter to data for encryption
source_length - size of encruption data
dest - buffer to place encrypted data (must be large enough)
key - Key to be used for encryption
kel_length - Lenght of the key. Will handle keys of any length
returns - size of encrypted data, or negative in case of error.
*/
int my_aes_encrypt(const char* source, int source_length, const char* dest,
const char* key, int key_length);
/*
my_aes_decrypt - DeCrypt buffer with AES encryption algorithm.
source - Pinter to data for decryption
source_length - size of encrypted data
dest - buffer to place decrypted data (must be large enough)
key - Key to be used for decryption
kel_length - Lenght of the key. Will handle keys of any length
returns - size of original data, or negative in case of error.
*/
int my_aes_decrypt(const char* source, int source_length, const char* dest,
const char* key, int key_length);
/*
my_aes_get_size - get size of buffer which will be large enough for encrypted
data
source_length - length of data to be encrypted
returns - size of buffer required to store encrypted data
*/
int my_aes_get_size(int source_length);
#ifdef __cplusplus
}
#endif
#endif
/* Copyright (C) 2002 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
rijndael-alg-fst.h
@version 3.0 (December 2000)
Optimised ANSI C code for the Rijndael cipher (now AES)
@author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
@author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
@author Paulo Barreto <paulo.barreto@terra.com.br>
This code is hereby placed in the public domain.
Modified by Peter Zaitsev to fit MySQL coding style.
*/
#ifndef __RIJNDAEL_ALG_FST_H
#define __RIJNDAEL_ALG_FST_H
#define MAXKC (256/32)
#define MAXKB (256/8)
#define MAXNR 14
int rijndaelKeySetupEnc(uint32 rk[/*4*(Nr + 1)*/], const uint8 cipherKey[],
int keyBits);
int rijndaelKeySetupDec(uint32 rk[/*4*(Nr + 1)*/], const uint8 cipherKey[],
int keyBits);
void rijndaelEncrypt(const uint32 rk[/*4*(Nr + 1)*/], int Nr,
const uint8 pt[16], uint8 ct[16]);
void rijndaelDecrypt(const uint32 rk[/*4*(Nr + 1)*/], int Nr,
const uint8 ct[16], uint8 pt[16]);
#endif /* __RIJNDAEL_ALG_FST_H */
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
sha1.h
Description:
This is the header file for code which implements the Secure
Hashing Algorithm 1 as defined in FIPS PUB 180-1 published
April 17, 1995.
Many of the variable names in this code, especially the
single character names, were used because those were the names
used in the publication.
Please read the file sha1.c for more information.
*/
/* Modified 2002 by Peter Zaitsev to better follow MySQL standards */
#ifndef _SHA1_H_
#define _SHA1_H_
#include "my_global.h"
/* Required for uint32, uint8, int16 ulonglong types */
enum sha_result_codes
{
SHA_SUCCESS = 0,
SHA_NULL, /* Null pointer parameter */
SHA_INPUT_TOO_LONG, /* input data too long */
SHA_STATE_ERROR /* called Input after Result */
};
#define SHA1_HASH_SIZE 20 /* Hash size in bytes */
/*
This structure will hold context information for the SHA-1
hashing operation
*/
typedef struct SHA1_CONTEXT
{
ulonglong Length; /* Message length in bits */
uint32 Intermediate_Hash[SHA1_HASH_SIZE/4]; /* Message Digest */
int Computed; /* Is the digest computed? */
int Corrupted; /* Is the message digest corrupted? */
int16 Message_Block_Index; /* Index into message block array */
uint8 Message_Block[64]; /* 512-bit message blocks */
} SHA1_CONTEXT;
/*
* Function Prototypes
*/
#ifdef __cplusplus
extern "C" {
#endif
int sha1_reset( SHA1_CONTEXT* );
int sha1_input( SHA1_CONTEXT*, const uint8 *, unsigned int );
int sha1_result( SHA1_CONTEXT* , uint8 Message_Digest[SHA1_HASH_SIZE] );
#ifdef __cplusplus
}
#endif
#endif
......@@ -192,3 +192,12 @@ a b
2 fullaaa fullzzz
1 I wonder why the fulltext index doesnt work?
drop table t1;
CREATE TABLE t1 ( id int(11) NOT NULL auto_increment primary key, mytext text NOT NULL, FULLTEXT KEY mytext (mytext)) TYPE=MyISAM;
INSERT INTO t1 VALUES (1,'my small mouse'),(2,'la-la-la'),(3,'It is so funny'),(4,'MySQL Tutorial');
select 8 from t1;
8
8
8
8
8
drop table t1;
......@@ -83,6 +83,36 @@ soundex('') soundex('he') soundex('hello all folks')
select md5('hello');
md5('hello')
5d41402abc4b2a76b9719d911017c592
select sha('abc');
sha('abc')
a9993e364706816aba3e25717850c26c9cd0d89d
select sha1('abc');
sha1('abc')
a9993e364706816aba3e25717850c26c9cd0d89d
select aes_decrypt(aes_encrypt('abc','1'),'1');
aes_decrypt(aes_encrypt('abc','1'),'1')
abc
select aes_decrypt(aes_encrypt('abc','1'),1);
aes_decrypt(aes_encrypt('abc','1'),1)
abc
select aes_encrypt(NULL,"a");
aes_encrypt(NULL,"a")
NULL
select aes_encrypt("a",NULL);
aes_encrypt("a",NULL)
NULL
select aes_decrypt(NULL,"a");
aes_decrypt(NULL,"a")
NULL
select aes_decrypt("a",NULL);
aes_decrypt("a",NULL)
NULL
select aes_decrypt("a","a");
aes_decrypt("a","a")
NULL
select aes_decrypt(aes_encrypt("","a"),"a");
aes_decrypt(aes_encrypt("","a"),"a")
select repeat('monty',5),concat('*',space(5),'*');
repeat('monty',5) concat('*',space(5),'*')
montymontymontymontymonty * *
......
......@@ -462,3 +462,12 @@ a b
6 1
6 2
drop table if exists t6, t5, t4, t3, t2, t1;
CREATE TABLE t1 ( a int(11) NOT NULL default '0', b int(11) NOT NULL default '0', PRIMARY KEY (a,b)) TYPE=MyISAM;
INSERT INTO t1 VALUES (1,1), (2,1);
CREATE TABLE t2 ( a int(11) NOT NULL default '0', b int(11) NOT NULL default '0', PRIMARY KEY (a,b)) TYPE=MyISAM;
INSERT INTO t2 VALUES (1,2), (2,2);
CREATE TABLE t ( a int(11) NOT NULL default '0', b int(11) NOT NULL default '0', KEY a (a,b)) TYPE=MRG_MyISAM UNION=(t1,t2);
select max(b) from t where a = 2;
max(b)
NULL
drop table if exists t,t1,t2;
......@@ -3232,3 +3232,11 @@ t2 1 fld3 1 fld3 A NULL NULL NULL BTREE
DO 1;
DO benchmark(100,1+1),1,1;
drop table t4, t3,t2, t1;
DROP TABLE IF EXISTS t1,t2;
CREATE TABLE t1 ( gvid int(10) unsigned default NULL, hmid int(10) unsigned default NULL, volid int(10) unsigned default NULL, mmid int(10) unsigned default NULL, hdid int(10) unsigned default NULL, fsid int(10) unsigned default NULL, ctid int(10) unsigned default NULL, dtid int(10) unsigned default NULL, cost int(10) unsigned default NULL, performance int(10) unsigned default NULL, serialnumber bigint(20) unsigned default NULL, monitored tinyint(3) unsigned default '1', removed tinyint(3) unsigned default '0', target tinyint(3) unsigned default '0', dt_modified timestamp(14) NOT NULL, name varchar(255) binary default NULL, description varchar(255) default NULL, UNIQUE KEY hmid (hmid,volid)) TYPE=MyISAM;
INSERT INTO t1 VALUES (200001,2,1,1,100,1,1,1,0,0,0,1,0,1,20020425060057,'\\\\ARKIVIO-TESTPDC\\E$',''),(200002,2,2,1,101,1,1,1,0,0,0,1,0,1,20020425060057,'\\\\ARKIVIO-TESTPDC\\C$',''),(200003,1,3,2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,0,1,20020425060427,'c:',NULL);
CREATE TABLE t2 ( hmid int(10) unsigned default NULL, volid int(10) unsigned default NULL, sampletid smallint(5) unsigned default NULL, sampletime datetime default NULL, samplevalue bigint(20) unsigned default NULL, KEY idx1 (hmid,volid,sampletid,sampletime)) TYPE=MyISAM;
INSERT INTO t2 VALUES (1,3,10,'2002-06-01 08:00:00',35),(1,3,1010,'2002-06-01 12:00:01',35);
SELECT a.gvid, (SUM(CASE b.sampletid WHEN 140 THEN b.samplevalue ELSE 0 END)) as the_success,(SUM(CASE b.sampletid WHEN 141 THEN b.samplevalue ELSE 0 END)) as the_fail,(SUM(CASE b.sampletid WHEN 142 THEN b.samplevalue ELSE 0 END)) as the_size,(SUM(CASE b.sampletid WHEN 143 THEN b.samplevalue ELSE 0 END)) as the_time FROM t1 a, t2 b WHERE a.hmid = b.hmid AND a.volid = b.volid AND b.sampletime >= 'NULL' AND b.sampletime < 'NULL' AND b.sampletid IN (140, 141, 142, 143) GROUP BY a.gvid;
gvid the_success the_fail the_size the_time
DROP TABLE t1,t2;
......@@ -154,4 +154,8 @@ insert into t1 values (2,"fullaaa fullzzz");
select * from t1 where match b against ('full*' in boolean mode);
drop table t1;
CREATE TABLE t1 ( id int(11) NOT NULL auto_increment primary key, mytext text NOT NULL, FULLTEXT KEY mytext (mytext)) TYPE=MyISAM;
INSERT INTO t1 VALUES (1,'my small mouse'),(2,'la-la-la'),(3,'It is so funny'),(4,'MySQL Tutorial');
select 8 from t1;
drop table t1;
......@@ -37,6 +37,16 @@ select replace('aaaa','a','b'),replace('aaaa','aa','b'),replace('aaaa','a','bb')
select replace(concat(lcase(concat('THIS',' ','IS',' ','A',' ')),ucase('false'),' ','test'),'FALSE','REAL') ;
select soundex(''),soundex('he'),soundex('hello all folks');
select md5('hello');
select sha('abc');
select sha1('abc');
select aes_decrypt(aes_encrypt('abc','1'),'1');
select aes_decrypt(aes_encrypt('abc','1'),1);
select aes_encrypt(NULL,"a");
select aes_encrypt("a",NULL);
select aes_decrypt(NULL,"a");
select aes_decrypt("a",NULL);
select aes_decrypt("a","a");
select aes_decrypt(aes_encrypt("","a"),"a");
select repeat('monty',5),concat('*',space(5),'*');
select reverse('abc'),reverse('abcd');
select rpad('a',4,'1'),rpad('a',4,'12'),rpad('abcd',3,'12');
......
......@@ -168,3 +168,10 @@ select * from t3 order by a,b;
select * from t4 order by a,b;
select * from t5 order by a,b;
drop table if exists t6, t5, t4, t3, t2, t1;
CREATE TABLE t1 ( a int(11) NOT NULL default '0', b int(11) NOT NULL default '0', PRIMARY KEY (a,b)) TYPE=MyISAM;
INSERT INTO t1 VALUES (1,1), (2,1);
CREATE TABLE t2 ( a int(11) NOT NULL default '0', b int(11) NOT NULL default '0', PRIMARY KEY (a,b)) TYPE=MyISAM;
INSERT INTO t2 VALUES (1,2), (2,2);
CREATE TABLE t ( a int(11) NOT NULL default '0', b int(11) NOT NULL default '0', KEY a (a,b)) TYPE=MRG_MyISAM UNION=(t1,t2);
select max(b) from t where a = 2;
drop table if exists t,t1,t2;
......@@ -1723,3 +1723,10 @@ DO benchmark(100,1+1),1,1;
#
drop table t4, t3,t2, t1;
DROP TABLE IF EXISTS t1,t2;
CREATE TABLE t1 ( gvid int(10) unsigned default NULL, hmid int(10) unsigned default NULL, volid int(10) unsigned default NULL, mmid int(10) unsigned default NULL, hdid int(10) unsigned default NULL, fsid int(10) unsigned default NULL, ctid int(10) unsigned default NULL, dtid int(10) unsigned default NULL, cost int(10) unsigned default NULL, performance int(10) unsigned default NULL, serialnumber bigint(20) unsigned default NULL, monitored tinyint(3) unsigned default '1', removed tinyint(3) unsigned default '0', target tinyint(3) unsigned default '0', dt_modified timestamp(14) NOT NULL, name varchar(255) binary default NULL, description varchar(255) default NULL, UNIQUE KEY hmid (hmid,volid)) TYPE=MyISAM;
INSERT INTO t1 VALUES (200001,2,1,1,100,1,1,1,0,0,0,1,0,1,20020425060057,'\\\\ARKIVIO-TESTPDC\\E$',''),(200002,2,2,1,101,1,1,1,0,0,0,1,0,1,20020425060057,'\\\\ARKIVIO-TESTPDC\\C$',''),(200003,1,3,2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,0,1,20020425060427,'c:',NULL);
CREATE TABLE t2 ( hmid int(10) unsigned default NULL, volid int(10) unsigned default NULL, sampletid smallint(5) unsigned default NULL, sampletime datetime default NULL, samplevalue bigint(20) unsigned default NULL, KEY idx1 (hmid,volid,sampletid,sampletime)) TYPE=MyISAM;
INSERT INTO t2 VALUES (1,3,10,'2002-06-01 08:00:00',35),(1,3,1010,'2002-06-01 12:00:01',35);
SELECT a.gvid, (SUM(CASE b.sampletid WHEN 140 THEN b.samplevalue ELSE 0 END)) as the_success,(SUM(CASE b.sampletid WHEN 141 THEN b.samplevalue ELSE 0 END)) as the_fail,(SUM(CASE b.sampletid WHEN 142 THEN b.samplevalue ELSE 0 END)) as the_size,(SUM(CASE b.sampletid WHEN 143 THEN b.samplevalue ELSE 0 END)) as the_time FROM t1 a, t2 b WHERE a.hmid = b.hmid AND a.volid = b.volid AND b.sampletime >= 'NULL' AND b.sampletime < 'NULL' AND b.sampletid IN (140, 141, 142, 143) GROUP BY a.gvid;
DROP TABLE t1,t2;
......@@ -48,7 +48,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c\
default.c my_compress.c checksum.c raid.cc \
my_net.c \
my_vsnprintf.c charset.c my_bitmap.c my_bit.c md5.c \
my_gethostbyname.c
my_gethostbyname.c rijndael.c my_aes.c sha1.c
EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \
thr_mutex.c thr_rwlock.c
libmysys_a_LIBADD = @THREAD_LOBJECTS@
......
/* Copyright (C) 2002 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Implementation of AES Encryption for MySQL
Initial version by Peter Zaitsev June 2002
*/
#include "my_global.h"
#include "m_string.h"
#include "my_aes.h"
enum encrypt_dir { AES_ENCRYPT, AES_DECRYPT };
#define AES_BLOCK_SIZE 16
/* Block size in bytes */
#define AES_BAD_DATA -1
/* If bad data discovered during decoding */
/* The structure for key information */
typedef struct {
int nr; /* Number of rounds */
uint32 rk[4*(MAXNR + 1)]; /* key schedule */
} KEYINSTANCE;
/*
This is internal function just keeps joint code of Key generation
rkey - Address of Key Instance to be created
direction - Direction (are we encoding or decoding)
key - key to use for real key creation
key_length - length of the key
returns - returns 0 on success and negative on error
*/
static int my_aes_create_key(KEYINSTANCE* aes_key,char direction, char* key,
int key_length)
{
char rkey[AES_KEY_LENGTH/8]; /* The real key to be used for encryption */
char *ptr; /* Start of the real key*/
char *rkey_end=rkey+AES_KEY_LENGTH/8; /* Real key boundary */
char *sptr; /* Start of the working key */
char *key_end=key+key_length; /* Working key boundary*/
bzero(rkey,AES_KEY_LENGTH/8); /* Set initial key */
for (ptr= rkey, sptr= key; sptr < key_end; ptr++,sptr++)
{
if (ptr == rkey_end)
ptr= rkey; /* Just loop over tmp_key until we used all key */
*ptr^= *sptr;
}
if (direction==AES_DECRYPT)
aes_key->nr = rijndaelKeySetupDec(aes_key->rk, rkey, AES_KEY_LENGTH);
else
aes_key->nr = rijndaelKeySetupEnc(aes_key->rk, rkey, AES_KEY_LENGTH);
return 0;
}
/*
my_aes_encrypt - Crypt buffer with AES encryption algorithm.
source - Pinter to data for encryption
source_length - size of encruption data
dest - buffer to place encrypted data (must be large enough)
key - Key to be used for encryption
kel_length - Lenght of the key. Will handle keys of any length
returns - size of encrypted data, or negative in case of error.
*/
int my_aes_encrypt(const char* source, int source_length, const char* dest,
const char* key, int key_length)
{
KEYINSTANCE aes_key;
char block[AES_BLOCK_SIZE]; /* 128 bit block used for padding */
int rc; /* result codes */
int num_blocks; /* number of complete blocks */
char pad_len; /* pad size for the last block */
int i;
if ((rc=my_aes_create_key(&aes_key,AES_ENCRYPT,key,key_length)))
return rc;
num_blocks = source_length/AES_BLOCK_SIZE;
for (i = num_blocks; i > 0; i--) /* Encode complete blocks */
{
rijndaelEncrypt(aes_key.rk, aes_key.nr, source, dest);
source+= AES_BLOCK_SIZE;
dest+= AES_BLOCK_SIZE;
}
/* Encode the rest. We always have incomplete block */
pad_len = AES_BLOCK_SIZE - (source_length - AES_BLOCK_SIZE*num_blocks);
memcpy(block, source, 16 - pad_len);
bfill(block + AES_BLOCK_SIZE - pad_len, pad_len, pad_len);
rijndaelEncrypt(aes_key.rk, aes_key.nr, block, dest);
return AES_BLOCK_SIZE*(num_blocks + 1);
}
/*
my_aes_decrypt - DeCrypt buffer with AES encryption algorithm.
source - Pinter to data for decryption
source_length - size of encrypted data
dest - buffer to place decrypted data (must be large enough)
key - Key to be used for decryption
kel_length - Lenght of the key. Will handle keys of any length
returns - size of original data, or negative in case of error.
*/
int my_aes_decrypt(const char* source, int source_length, const char* dest,
const char* key, int key_length)
{
KEYINSTANCE aes_key;
char block[AES_BLOCK_SIZE]; /* 128 bit block used for padding */
int rc; /* result codes */
int num_blocks; /* number of complete blocks */
char pad_len; /* pad size for the last block */
int i;
if ((rc=my_aes_create_key(&aes_key,AES_DECRYPT,key,key_length)))
return rc;
num_blocks = source_length/AES_BLOCK_SIZE;
if ( (source_length!=num_blocks*AES_BLOCK_SIZE) || num_blocks==0)
return AES_BAD_DATA; /* Input size has to be even and at leas one block */
for (i = num_blocks-1; i > 0; i--) /* Decode all but last blocks */
{
rijndaelDecrypt(aes_key.rk, aes_key.nr, source, dest);
source+= AES_BLOCK_SIZE;
dest+= AES_BLOCK_SIZE;
}
rijndaelDecrypt(aes_key.rk, aes_key.nr, source, block);
pad_len = block[AES_BLOCK_SIZE-1]; /* Just use last char in the block as size*/
if (pad_len > AES_BLOCK_SIZE)
return AES_BAD_DATA;
/* We could also check whole padding but we do not really need this */
memcpy(dest, block, AES_BLOCK_SIZE - pad_len);
return AES_BLOCK_SIZE*num_blocks - pad_len;
}
/*
my_aes_get_size - get size of buffer which will be large enough for encrypted
data
source_length - length of data to be encrypted
returns - size of buffer required to store encrypted data
*/
int my_aes_get_size(int source_length)
{
return AES_BLOCK_SIZE*(source_length/AES_BLOCK_SIZE)+AES_BLOCK_SIZE;
}
This diff is collapsed.
This diff is collapsed.
......@@ -32,6 +32,16 @@ Item *create_func_acos(Item* a)
return new Item_func_acos(a);
}
Item *create_func_aes_encrypt(Item* a, Item* b)
{
return new Item_func_aes_encrypt(a, b);
}
Item *create_func_aes_decrypt(Item* a, Item* b)
{
return new Item_func_aes_decrypt(a, b);
}
Item *create_func_ascii(Item* a)
{
return new Item_func_ascii(a);
......@@ -327,6 +337,11 @@ Item *create_func_sin(Item* a)
return new Item_func_sin(a);
}
Item *create_func_sha(Item* a)
{
return new Item_func_sha(a);
}
Item *create_func_space(Item *a)
{
return new Item_func_repeat(new Item_string(" ",1),a);
......
......@@ -18,6 +18,8 @@
Item *create_func_abs(Item* a);
Item *create_func_acos(Item* a);
Item *create_func_aes_encrypt(Item* a, Item* b);
Item *create_func_aes_decrypt(Item* a, Item* b);
Item *create_func_ascii(Item* a);
Item *create_func_asin(Item* a);
Item *create_func_bin(Item* a);
......@@ -75,6 +77,7 @@ Item *create_func_rtrim(Item* a);
Item *create_func_sec_to_time(Item* a);
Item *create_func_sign(Item* a);
Item *create_func_sin(Item* a);
Item *create_func_sha(Item* a);
Item *create_func_soundex(Item* a);
Item *create_func_space(Item *);
Item *create_func_sqrt(Item* a);
......
......@@ -34,6 +34,8 @@
#include <openssl/des.h>
#endif /* HAVE_OPENSSL */
#include "md5.h"
#include "sha1.h"
#include "my_aes.h"
String empty_string("");
......@@ -99,6 +101,112 @@ void Item_func_md5::fix_length_and_dec()
max_length=32;
}
String *Item_func_sha::val_str(String *str)
{
String * sptr= args[0]->val_str(str);
if (sptr) /* If we got value different from NULL */
{
SHA1_CONTEXT context; /* Context used to generate SHA1 hash */
/* Temporary buffer to store 160bit digest */
uint8_t digest[SHA1_HASH_SIZE];
sha1_reset(&context); /* We do not have to check for error here */
/* No need to check error as the only case would be too long message */
sha1_input(&context,(const unsigned char *) sptr->ptr(), sptr->length());
/* Ensure that memory is free and we got result */
if ( !( str->alloc(SHA1_HASH_SIZE*2) || (sha1_result(&context,digest)) ) )
{
sprintf((char *) str->ptr(),
"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\
%02x%02x%02x%02x%02x%02x%02x%02x",
digest[0], digest[1], digest[2], digest[3],
digest[4], digest[5], digest[6], digest[7],
digest[8], digest[9], digest[10], digest[11],
digest[12], digest[13], digest[14], digest[15],
digest[16], digest[17], digest[18], digest[19]);
str->length((uint) SHA1_HASH_SIZE*2);
null_value=0;
return str;
}
}
null_value=1;
return 0;
}
void Item_func_sha::fix_length_and_dec()
{
max_length=SHA1_HASH_SIZE*2; // size of hex representation of hash
}
/* Implementation of AES encryption routines */
String *Item_func_aes_encrypt::val_str(String *str)
{
String * sptr = args[0]->val_str(str); // String to encrypt
String tmp_value; // required to handle second parameter
String * key= args[1]->val_str(&tmp_value); // key
int aes_length;
if (sptr && key) // we need both arguments to be not NULL
{
null_value=0;
aes_length=my_aes_get_size(sptr->length()); // calculate result length
if ( !str->alloc(aes_length) ) // Ensure that memory is free
{
// finally encrypt directly to allocated buffer.
if (my_aes_encrypt(sptr->ptr(),sptr->length(),str->ptr(),key->ptr(),
key->length()) == aes_length)
{
// we have to get expected result length
str->length((uint) aes_length);
return str;
}
}
}
null_value=1;
return 0;
}
void Item_func_aes_encrypt::fix_length_and_dec()
{
max_length=my_aes_get_size(args[0]->max_length);
}
String *Item_func_aes_decrypt::val_str(String *str)
{
String * sptr= args[0]->val_str(str); // String to decrypt
String tmp_value; // temporary string required for parsing
String * key= args[1]->val_str(&tmp_value); // key
int length; // original length after decrypt
if (sptr && key) // Need to have both arguments not NULL
{
null_value=0;
if ( !str->alloc(sptr->length()) ) // Ensure that memory is free
{
// finally decencrypt directly to allocated buffer.
length=my_aes_decrypt(sptr->ptr(),sptr->length(),str->ptr(),
key->ptr(),key->length());
if (length>=0) // if we got correct data data
{
str->length((uint) length);
return str;
}
}
}
// Bad parameters. No memory or bad data will all go here
null_value=1;
return 0;
}
void Item_func_aes_decrypt::fix_length_and_dec()
{
max_length=args[0]->max_length;
}
/*
** Concatinate args with the following premissess
** If only one arg which is ok, return value of arg
......
......@@ -52,6 +52,34 @@ public:
const char *func_name() const { return "md5"; }
};
class Item_func_sha :public Item_str_func
{
public:
Item_func_sha(Item *a) :Item_str_func(a) {}
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "sha"; }
};
class Item_func_aes_encrypt :public Item_str_func
{
public:
Item_func_aes_encrypt(Item *a, Item *b) :Item_str_func(a,b) {}
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "aes_encrypt"; }
};
class Item_func_aes_decrypt :public Item_str_func
{
public:
Item_func_aes_decrypt(Item *a, Item *b) :Item_str_func(a,b) {}
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "aes_decrypt"; }
};
class Item_func_concat :public Item_str_func
{
String tmp_value;
......
......@@ -396,6 +396,8 @@ static SYMBOL sql_functions[] = {
{ "ABS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_abs)},
{ "ACOS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_acos)},
{ "ADDDATE", SYM(DATE_ADD_INTERVAL),0,0},
{ "AES_ENCRYPT", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_aes_encrypt)},
{ "AES_DECRYPT", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_aes_decrypt)},
{ "ASCII", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ascii)},
{ "ASIN", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_asin)},
{ "ATAN", SYM(ATAN),0,0},
......@@ -498,6 +500,8 @@ static SYMBOL sql_functions[] = {
{ "SUBDATE", SYM(DATE_SUB_INTERVAL),0,0},
{ "SIGN", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sign)},
{ "SIN", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sin)},
{ "SHA", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sha)},
{ "SHA1", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sha)},
{ "SOUNDEX", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_soundex)},
{ "SPACE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_space)},
{ "SQRT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sqrt)},
......
......@@ -1291,7 +1291,7 @@ and_all_keys(SEL_ARG *key1,SEL_ARG *key2,uint clone_flag)
}
if (key1->type == SEL_ARG::MAYBE_KEY)
{
key1->left= &null_element; key1->next=0;
key1->right=key1->left= &null_element; key1->next=key1->prev=0;
}
for (next=key1->first(); next ; next=next->next)
{
......
......@@ -152,9 +152,10 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
error=table->file->index_last(table->record[0]) !=0;
else
{
(void) table->file->index_read(table->record[0], key_buff,
error= table->file->index_read(table->record[0], key_buff,
ref.key_length,
HA_READ_AFTER_KEY);
if (!error)
error=table->file->index_prev(table->record[0]) ||
key_cmp(table,key_buff,ref.key,ref.key_length);
}
......
......@@ -257,7 +257,14 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
}
TABLE_LIST *table;
for (table=tables ; table ; table=table->next)
{
join.tables++;
if (!thd->used_tables)
{
TABLE *tbl=table->table;
tbl->keys_in_use_for_query=tbl->used_keys= tbl->keys_in_use=0;
}
}
}
procedure=setup_procedure(thd,proc_param,result,fields,&error);
if (error)
......
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