mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Made keyread (key scanning) a key specific attribute.
This avoids using fulltext keys for table scanning. This also reverts Sinisa's original fix for this problem. Docs/manual.texi: Update of SQL_JOIN_MAX_SIZE information3602 client/mysqldump.c: comment cleanup include/my_aes.h: General cleanup for new file include/rijndael.h: General cleanup for new file include/sha1.h: General cleanup for new file mysys/my_aes.c: General cleanup for new file mysys/rijndael.c: General cleanup for new file mysys/sha1.c: General cleanup for new file sql/ha_berkeley.h: Made keyread (key scanning) a key specific attribute. sql/ha_innodb.cc: Merge with 3.23.x sql/ha_innodb.h: Made keyread (key scanning) a key specific attribute. sql/ha_isam.cc: Moved things to table_flags() sql/ha_isam.h: Made keyread (key scanning) a key specific attribute. sql/ha_myisam.cc: Made keyread (key scanning) a key specific attribute. sql/ha_myisam.h: Made keyread (key scanning) a key specific attribute. sql/ha_myisammrg.h: Made keyread (key scanning) a key specific attribute. sql/handler.h: Made keyread (key scanning) a key specific attribute. sql/item_strfunc.cc: Cleanup of AES_xxx code sql/opt_range.cc: Made keyread (key scanning) a key specific attribute. sql/sql_base.cc: Made keyread (key scanning) a key specific attribute. sql/sql_cache.cc: Removed compiler warning sql/sql_select.cc: Removed wrong patch to fulltext problem sql/table.cc: Made keyread (key scanning) a key specific attribute. sql/table.h: Made keyread (key scanning) a key specific attribute.
This commit is contained in:
@ -27645,6 +27645,12 @@ flag again, the @code{SQL_MAX_JOIN_SIZE} variable will be ignored.
|
||||
You can set a default value for this variable by starting @code{mysqld} with
|
||||
@code{-O max_join_size=#}.
|
||||
|
||||
Note that if the result of the query is in the query cache, the above
|
||||
check will not be made, but MySQL will instead send the result to the
|
||||
client. We regard this as a feature as in this case the query result is
|
||||
already computed and it will not cause any big burden for the server to
|
||||
send the result to the client.
|
||||
|
||||
@item SQL_QUERY_CACHE_TYPE = OFF | ON | DEMAND
|
||||
@item SQL_QUERY_CACHE_TYPE = 0 | 1 | 2
|
||||
Set query cache setting for this thread.
|
||||
|
@ -1438,8 +1438,8 @@ int main(int argc, char **argv)
|
||||
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.
|
||||
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 */
|
||||
|
@ -18,67 +18,49 @@
|
||||
/* 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 */
|
||||
C_MODE_START
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#define AES_KEY_LENGTH 128 /* Must be 128 192 or 256 */
|
||||
|
||||
/*
|
||||
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.
|
||||
my_aes_encrypt - Crypt buffer with AES encryption algorithm.
|
||||
source - Pointer to data for encryption
|
||||
source_length - size of encryption data
|
||||
dest - buffer to place encrypted data (must be large enough)
|
||||
key - Key to be used for encryption
|
||||
kel_length - Length 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);
|
||||
int my_aes_encrypt(const char *source, int source_length, 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.
|
||||
my_aes_decrypt - DeCrypt buffer with AES encryption algorithm.
|
||||
source - Pointer 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 - Length 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);
|
||||
|
||||
int my_aes_decrypt(const char *source, int source_length, 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
|
||||
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
|
||||
C_MODE_END
|
||||
|
@ -16,33 +16,27 @@
|
||||
|
||||
|
||||
/*
|
||||
rijndael-alg-fst.h
|
||||
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.
|
||||
@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
|
||||
#define AES_MAXKC (256/32)
|
||||
#define AES_MAXKB (256/8)
|
||||
#define AES_MAXNR 14
|
||||
|
||||
int rijndaelKeySetupEnc(uint32 rk[/*4*(Nr + 1)*/], const uint8 cipherKey[],
|
||||
int keyBits);
|
||||
int keyBits);
|
||||
int rijndaelKeySetupDec(uint32 rk[/*4*(Nr + 1)*/], const uint8 cipherKey[],
|
||||
int keyBits);
|
||||
int keyBits);
|
||||
void rijndaelEncrypt(const uint32 rk[/*4*(Nr + 1)*/], int Nr,
|
||||
const uint8 pt[16], uint8 ct[16]);
|
||||
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 */
|
||||
const uint8 ct[16], uint8 pt[16]);
|
||||
|
@ -15,70 +15,53 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
/*
|
||||
sha1.h
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
Please read the file sha1.c for more information.
|
||||
|
||||
Modified 2002 by Peter Zaitsev to better follow MySQL standards
|
||||
*/
|
||||
|
||||
/* 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 */
|
||||
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
|
||||
*/
|
||||
This structure will hold context information for the SHA-1
|
||||
hashing operation
|
||||
*/
|
||||
|
||||
typedef struct SHA1_CONTEXT
|
||||
{
|
||||
ulonglong Length; /* Message length in bits */
|
||||
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 */
|
||||
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
|
||||
*/
|
||||
Function Prototypes
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
C_MODE_START
|
||||
|
||||
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
|
||||
C_MODE_END
|
||||
|
144
mysys/my_aes.c
144
mysys/my_aes.c
@ -16,49 +16,55 @@
|
||||
|
||||
|
||||
/*
|
||||
Implementation of AES Encryption for MySQL
|
||||
Initial version by Peter Zaitsev June 2002
|
||||
Implementation of AES Encryption for MySQL
|
||||
Initial version by Peter Zaitsev June 2002
|
||||
*/
|
||||
|
||||
|
||||
#include "my_global.h"
|
||||
#include "m_string.h"
|
||||
#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_BLOCK_SIZE 16 /* Block size in bytes */
|
||||
|
||||
#define AES_BAD_DATA -1
|
||||
/* If bad data discovered during decoding */
|
||||
#define AES_BAD_DATA -1 /* If bad data discovered during decoding */
|
||||
|
||||
|
||||
/* The structure for key information */
|
||||
/* The structure for key information */
|
||||
typedef struct {
|
||||
int nr; /* Number of rounds */
|
||||
uint32 rk[4*(MAXNR + 1)]; /* key schedule */
|
||||
int nr; /* Number of rounds */
|
||||
uint32 rk[4*(AES_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)
|
||||
SYNOPSIS
|
||||
my_aes_create_key()
|
||||
aes_key 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
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
RESULT
|
||||
0 ok
|
||||
-1 Error Note: The current impementation never returns this
|
||||
*/
|
||||
|
||||
static int my_aes_create_key(KEYINSTANCE *aes_key,
|
||||
enum encrypt_dir direction, const 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[AES_KEY_LENGTH/8]; /* The real key to be used for encryption */
|
||||
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*/
|
||||
char *ptr; /* Start of the real key*/
|
||||
const char *sptr; /* Start of the working key */
|
||||
const char *key_end=key+key_length; /* Working key boundary*/
|
||||
|
||||
bzero(rkey,AES_KEY_LENGTH/8); /* Set initial key */
|
||||
|
||||
@ -68,7 +74,7 @@ static int my_aes_create_key(KEYINSTANCE* aes_key,char direction, char* key,
|
||||
ptr= rkey; /* Just loop over tmp_key until we used all key */
|
||||
*ptr^= *sptr;
|
||||
}
|
||||
if (direction==AES_DECRYPT)
|
||||
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);
|
||||
@ -77,28 +83,32 @@ static int my_aes_create_key(KEYINSTANCE* aes_key,char direction, char* key,
|
||||
|
||||
|
||||
/*
|
||||
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
|
||||
Crypt buffer with AES encryption algorithm.
|
||||
|
||||
returns - size of encrypted data, or negative in case of error.
|
||||
SYNOPSIS
|
||||
my_aes_encrypt()
|
||||
source Pointer to data for encryption
|
||||
source_length Size of encryption data
|
||||
dest Buffer to place encrypted data (must be large enough)
|
||||
key Key to be used for encryption
|
||||
key_length Length of the key. Will handle keys of any length
|
||||
|
||||
RETURN
|
||||
>= 0 Size of encrypted data
|
||||
< 0 Error
|
||||
*/
|
||||
|
||||
int my_aes_encrypt(const char* source, int source_length, const char* dest,
|
||||
const char* key, int key_length)
|
||||
int my_aes_encrypt(const char* source, int source_length, 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 */
|
||||
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)))
|
||||
if ((rc= my_aes_create_key(&aes_key,AES_ENCRYPT,key,key_length)))
|
||||
return rc;
|
||||
|
||||
num_blocks = source_length/AES_BLOCK_SIZE;
|
||||
@ -120,25 +130,29 @@ int my_aes_encrypt(const char* source, int source_length, const char* dest,
|
||||
|
||||
|
||||
/*
|
||||
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
|
||||
DeCrypt buffer with AES encryption algorithm.
|
||||
|
||||
returns - size of original data, or negative in case of error.
|
||||
SYNOPSIS
|
||||
my_aes_decrypt()
|
||||
source Pointer 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
|
||||
key_length Length of the key. Will handle keys of any length
|
||||
|
||||
RETURN
|
||||
>= 0 Size of encrypted data
|
||||
< 0 Error
|
||||
*/
|
||||
|
||||
int my_aes_decrypt(const char* source, int source_length, const char* dest,
|
||||
const char* key, int key_length)
|
||||
int my_aes_decrypt(const char *source, int source_length, 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 */
|
||||
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)))
|
||||
@ -146,10 +160,8 @@ int my_aes_decrypt(const char* source, int source_length, const char* dest,
|
||||
|
||||
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 */
|
||||
|
||||
if ((source_length != num_blocks*AES_BLOCK_SIZE) || num_blocks ==0 )
|
||||
return AES_BAD_DATA; /* Input size has to be even and at least one block */
|
||||
|
||||
for (i = num_blocks-1; i > 0; i--) /* Decode all but last blocks */
|
||||
{
|
||||
@ -159,29 +171,29 @@ int my_aes_decrypt(const char* source, int source_length, const char* dest,
|
||||
}
|
||||
|
||||
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*/
|
||||
pad_len = block[AES_BLOCK_SIZE-1]; /* 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
|
||||
Get size of buffer which will be large enough for encrypted data
|
||||
|
||||
SYNOPSIS
|
||||
my_aes_get_size()
|
||||
source_length Length of data to be encrypted
|
||||
|
||||
RETURN
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
892
mysys/rijndael.c
892
mysys/rijndael.c
File diff suppressed because it is too large
Load Diff
296
mysys/sha1.c
296
mysys/sha1.c
@ -15,43 +15,38 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
/*
|
||||
sha1.c
|
||||
Original Source from: http://www.faqs.org/rfcs/rfc3174.html
|
||||
Original Source from: http://www.faqs.org/rfcs/rfc3174.html
|
||||
|
||||
Description:
|
||||
This file implements the Secure Hashing Algorithm 1 as
|
||||
defined in FIPS PUB 180-1 published April 17, 1995.
|
||||
DESCRIPTION
|
||||
This file implements the Secure Hashing Algorithm 1 as
|
||||
defined in FIPS PUB 180-1 published April 17, 1995.
|
||||
|
||||
The SHA-1, produces a 160-bit message digest for a given
|
||||
data stream. It should take about 2**n steps to find a
|
||||
message with the same digest as a given message and
|
||||
2**(n/2) to find any two messages with the same digest,
|
||||
when n is the digest size in bits. Therefore, this
|
||||
algorithm can serve as a means of providing a
|
||||
"fingerprint" for a message.
|
||||
The SHA-1, produces a 160-bit message digest for a given data
|
||||
stream. It should take about 2**n steps to find a message with the
|
||||
same digest as a given message and 2**(n/2) to find any two
|
||||
messages with the same digest, when n is the digest size in bits.
|
||||
Therefore, this algorithm can serve as a means of providing a
|
||||
"fingerprint" for a message.
|
||||
|
||||
Portability Issues:
|
||||
SHA-1 is defined in terms of 32-bit "words". This code
|
||||
uses <stdint.h> (included via "sha1.h" to define 32 and 8
|
||||
bit unsigned integer types. If your C compiler does not
|
||||
support 32 bit unsigned integers, this code is not
|
||||
appropriate.
|
||||
PORTABILITY ISSUES
|
||||
SHA-1 is defined in terms of 32-bit "words". This code uses
|
||||
<stdint.h> (included via "sha1.h" to define 32 and 8 bit unsigned
|
||||
integer types. If your C compiler does not support 32 bit unsigned
|
||||
integers, this code is not appropriate.
|
||||
|
||||
Caveats:
|
||||
SHA-1 is designed to work with messages less than 2^64 bits
|
||||
long. Although SHA-1 allows a message digest to be generated
|
||||
for messages of any number of bits less than 2^64, this
|
||||
implementation only works with messages with a length that is
|
||||
a multiple of the size of an 8-bit character.
|
||||
CAVEATS
|
||||
SHA-1 is designed to work with messages less than 2^64 bits long.
|
||||
Although SHA-1 allows a message digest to be generated for messages
|
||||
of any number of bits less than 2^64, this implementation only
|
||||
works with messages with a length that is a multiple of the size of
|
||||
an 8-bit character.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
Modified 2002 by Peter Zaitsev to
|
||||
- fit to new prototypes according to MySQL standard
|
||||
- Some optimizations
|
||||
- All checking is now done in debug only mode
|
||||
- More comments
|
||||
CHANGES
|
||||
2002 by Peter Zaitsev to
|
||||
- fit to new prototypes according to MySQL standard
|
||||
- Some optimizations
|
||||
- All checking is now done in debug only mode
|
||||
- More comments
|
||||
*/
|
||||
|
||||
#include "my_global.h"
|
||||
@ -59,30 +54,31 @@
|
||||
#include "sha1.h"
|
||||
|
||||
/*
|
||||
Define the SHA1 circular left shift macro
|
||||
Define the SHA1 circular left shift macro
|
||||
*/
|
||||
|
||||
#define SHA1CircularShift(bits,word) \
|
||||
(((word) << (bits)) | ((word) >> (32-(bits))))
|
||||
(((word) << (bits)) | ((word) >> (32-(bits))))
|
||||
|
||||
/* Local Function Prototyptes */
|
||||
void SHA1PadMessage(SHA1_CONTEXT*);
|
||||
void SHA1ProcessMessageBlock(SHA1_CONTEXT*);
|
||||
static void SHA1PadMessage(SHA1_CONTEXT*);
|
||||
static void SHA1ProcessMessageBlock(SHA1_CONTEXT*);
|
||||
|
||||
|
||||
/*
|
||||
sha1_reset
|
||||
Initialize SHA1Context
|
||||
|
||||
Description:
|
||||
This function will initialize the SHA1Context in preparation
|
||||
for computing a new SHA1 message digest.
|
||||
SYNOPSIS
|
||||
sha1_reset()
|
||||
context [in/out] The context to reset.
|
||||
|
||||
Parameters:
|
||||
context: [in/out]
|
||||
The context to reset.
|
||||
|
||||
Returns:
|
||||
sha Error Code.
|
||||
DESCRIPTION
|
||||
This function will initialize the SHA1Context in preparation
|
||||
for computing a new SHA1 message digest.
|
||||
|
||||
RETURN
|
||||
SHA_SUCCESS ok
|
||||
!= SHA_SUCCESS sha Error Code.
|
||||
*/
|
||||
|
||||
|
||||
@ -98,16 +94,13 @@ const uint32 sha_const_key[5]=
|
||||
|
||||
int sha1_reset(SHA1_CONTEXT *context)
|
||||
{
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
if (!context)
|
||||
{
|
||||
return SHA_NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
context->Length = 0;
|
||||
context->Message_Block_Index = 0;
|
||||
context->Length = 0;
|
||||
context->Message_Block_Index = 0;
|
||||
|
||||
context->Intermediate_Hash[0] = sha_const_key[0];
|
||||
context->Intermediate_Hash[1] = sha_const_key[1];
|
||||
@ -121,128 +114,97 @@ int sha1_reset(SHA1_CONTEXT *context)
|
||||
return SHA_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
sha1_result
|
||||
Return the 160-bit message digest into the array provided by the caller
|
||||
|
||||
Description:
|
||||
This function will return the 160-bit message digest into the
|
||||
Message_Digest array provided by the caller.
|
||||
NOTE: The first octet of hash is stored in the 0th element,
|
||||
the last octet of hash in the 19th element.
|
||||
SYNOPSIS
|
||||
sha1_result()
|
||||
context [in/out] The context to use to calculate the SHA-1 hash.
|
||||
Message_Digest: [out] Where the digest is returned.
|
||||
|
||||
Parameters:
|
||||
context: [in/out]
|
||||
The context to use to calculate the SHA-1 hash.
|
||||
Message_Digest: [out]
|
||||
Where the digest is returned.
|
||||
|
||||
Returns:
|
||||
sha Error Code.
|
||||
DESCRIPTION
|
||||
NOTE: The first octet of hash is stored in the 0th element,
|
||||
the last octet of hash in the 19th element.
|
||||
|
||||
RETURN
|
||||
SHA_SUCCESS ok
|
||||
!= SHA_SUCCESS sha Error Code.
|
||||
*/
|
||||
|
||||
int sha1_result( SHA1_CONTEXT *context,
|
||||
uint8 Message_Digest[SHA1_HASH_SIZE])
|
||||
int sha1_result(SHA1_CONTEXT *context,
|
||||
uint8 Message_Digest[SHA1_HASH_SIZE])
|
||||
{
|
||||
int i;
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
if (!context || !Message_Digest)
|
||||
{
|
||||
return SHA_NULL;
|
||||
}
|
||||
|
||||
if (context->Corrupted)
|
||||
{
|
||||
return context->Corrupted;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!context->Computed)
|
||||
{
|
||||
|
||||
#endif
|
||||
SHA1PadMessage(context);
|
||||
/* message may be sensitive, clear it out */
|
||||
bzero((char*) context->Message_Block,64);
|
||||
context->Length = 0; /* and clear length */
|
||||
context->Computed = 1;
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < SHA1_HASH_SIZE; i++)
|
||||
{
|
||||
Message_Digest[i] = (context->Intermediate_Hash[i>>2] >> 8
|
||||
* ( 3 - ( i & 0x03 ) ));
|
||||
}
|
||||
|
||||
* ( 3 - ( i & 0x03 ) ));
|
||||
return SHA_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
sha1_input
|
||||
Accepts an array of octets as the next portion of the message.
|
||||
|
||||
Description:
|
||||
This function accepts an array of octets as the next portion
|
||||
of the message.
|
||||
|
||||
Parameters:
|
||||
context: [in/out]
|
||||
The SHA context to update
|
||||
message_array: [in]
|
||||
An array of characters representing the next portion of
|
||||
the message.
|
||||
length: [in]
|
||||
The length of the message in message_array
|
||||
|
||||
Returns:
|
||||
sha Error Code.
|
||||
SYNOPSIS
|
||||
sha1_input()
|
||||
context [in/out] The SHA context to update
|
||||
message_array An array of characters representing the next portion
|
||||
of the message.
|
||||
length The length of the message in message_array
|
||||
|
||||
RETURN
|
||||
SHA_SUCCESS ok
|
||||
!= SHA_SUCCESS sha Error Code.
|
||||
*/
|
||||
|
||||
int sha1_input(SHA1_CONTEXT *context, const uint8 *message_array,
|
||||
unsigned length)
|
||||
unsigned length)
|
||||
{
|
||||
if (!length)
|
||||
{
|
||||
return SHA_SUCCESS;
|
||||
}
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
/* We assume client konows what it is doing in non-debug mode */
|
||||
if (!context || !message_array)
|
||||
{
|
||||
return SHA_NULL;
|
||||
}
|
||||
if (context->Computed)
|
||||
{
|
||||
context->Corrupted = SHA_STATE_ERROR;
|
||||
return SHA_STATE_ERROR;
|
||||
}
|
||||
|
||||
return (context->Corrupted= SHA_STATE_ERROR);
|
||||
if (context->Corrupted)
|
||||
{
|
||||
return context->Corrupted;
|
||||
}
|
||||
#endif
|
||||
|
||||
while (length--)
|
||||
{
|
||||
context->Message_Block[context->Message_Block_Index++] =
|
||||
(*message_array & 0xFF);
|
||||
context->Message_Block[context->Message_Block_Index++]=
|
||||
(*message_array & 0xFF);
|
||||
context->Length += 8; /* Length is in bits */
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
/*
|
||||
Then we're not debugging we assume we never will get message longer
|
||||
2^64 bits.
|
||||
Then we're not debugging we assume we never will get message longer
|
||||
2^64 bits.
|
||||
*/
|
||||
if (context->Length == 0)
|
||||
{
|
||||
/* Message is too long */
|
||||
context->Corrupted = 1;
|
||||
return 1;
|
||||
}
|
||||
return (context->Corrupted= 1); /* Message is too long */
|
||||
#endif
|
||||
|
||||
if (context->Message_Block_Index == 64)
|
||||
@ -251,33 +213,23 @@ int sha1_input(SHA1_CONTEXT *context, const uint8 *message_array,
|
||||
}
|
||||
message_array++;
|
||||
}
|
||||
|
||||
return SHA_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
SHA1ProcessMessageBlock
|
||||
|
||||
Description:
|
||||
This function will process the next 512 bits of the message
|
||||
stored in the Message_Block array.
|
||||
|
||||
Parameters:
|
||||
None.
|
||||
|
||||
Returns:
|
||||
Nothing.
|
||||
|
||||
Comments:
|
||||
|
||||
Many of the variable names in this code, especially the
|
||||
single character names, were used because those were the
|
||||
names used in the publication.
|
||||
Process the next 512 bits of the message stored in the Message_Block array.
|
||||
|
||||
SYNOPSIS
|
||||
SHA1ProcessMessageBlock()
|
||||
|
||||
DESCRIPTION
|
||||
Many of the variable names in this code, especially the single
|
||||
character names, were used because those were the names used in
|
||||
the publication.
|
||||
*/
|
||||
|
||||
/* Constants defined in SHA-1 */
|
||||
/* Constants defined in SHA-1 */
|
||||
static const uint32 K[]=
|
||||
{
|
||||
0x5A827999,
|
||||
@ -287,17 +239,17 @@ static const uint32 K[]=
|
||||
};
|
||||
|
||||
|
||||
void SHA1ProcessMessageBlock(SHA1_CONTEXT *context)
|
||||
static void SHA1ProcessMessageBlock(SHA1_CONTEXT *context)
|
||||
{
|
||||
int t; /* Loop counter */
|
||||
uint32 temp; /* Temporary word value */
|
||||
uint32 W[80]; /* Word sequence */
|
||||
uint32 A, B, C, D, E; /* Word buffers */
|
||||
int t; /* Loop counter */
|
||||
uint32 temp; /* Temporary word value */
|
||||
uint32 W[80]; /* Word sequence */
|
||||
uint32 A, B, C, D, E; /* Word buffers */
|
||||
int index;
|
||||
|
||||
/*
|
||||
Initialize the first 16 words in the array W
|
||||
*/
|
||||
Initialize the first 16 words in the array W
|
||||
*/
|
||||
|
||||
for (t = 0; t < 16; t++)
|
||||
{
|
||||
@ -322,8 +274,7 @@ void SHA1ProcessMessageBlock(SHA1_CONTEXT *context)
|
||||
|
||||
for (t = 0; t < 20; t++)
|
||||
{
|
||||
temp = SHA1CircularShift(5,A) +
|
||||
((B & C) | ((~B) & D)) + E + W[t] + K[0];
|
||||
temp= SHA1CircularShift(5,A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0];
|
||||
E = D;
|
||||
D = C;
|
||||
C = SHA1CircularShift(30,B);
|
||||
@ -343,8 +294,8 @@ void SHA1ProcessMessageBlock(SHA1_CONTEXT *context)
|
||||
|
||||
for (t = 40; t < 60; t++)
|
||||
{
|
||||
temp = SHA1CircularShift(5,A) +
|
||||
((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
|
||||
temp= (SHA1CircularShift(5,A) + ((B & C) | (B & D) | (C & D)) + E + W[t] +
|
||||
K[2]);
|
||||
E = D;
|
||||
D = C;
|
||||
C = SHA1CircularShift(30,B);
|
||||
@ -373,36 +324,31 @@ void SHA1ProcessMessageBlock(SHA1_CONTEXT *context)
|
||||
|
||||
|
||||
/*
|
||||
SHA1PadMessage
|
||||
Pad message
|
||||
|
||||
SYNOPSIS
|
||||
SHA1PadMessage()
|
||||
context: [in/out] The context to pad
|
||||
|
||||
Description:
|
||||
According to the standard, the message must be padded to an even
|
||||
512 bits. The first padding bit must be a '1'. The last 64
|
||||
bits represent the length of the original message. All bits in
|
||||
between should be 0. This function will pad the message
|
||||
according to those rules by filling the Message_Block array
|
||||
accordingly. It will also call the ProcessMessageBlock function
|
||||
provided appropriately. When it returns, it can be assumed that
|
||||
the message digest has been computed.
|
||||
|
||||
Parameters:
|
||||
context: [in/out]
|
||||
The context to pad
|
||||
ProcessMessageBlock: [in]
|
||||
The appropriate SHA*ProcessMessageBlock function
|
||||
Returns:
|
||||
Nothing.
|
||||
DESCRIPTION
|
||||
According to the standard, the message must be padded to an even
|
||||
512 bits. The first padding bit must be a '1'. The last 64 bits
|
||||
represent the length of the original message. All bits in between
|
||||
should be 0. This function will pad the message according to
|
||||
those rules by filling the Message_Block array accordingly. It
|
||||
will also call the ProcessMessageBlock function provided
|
||||
appropriately. When it returns, it can be assumed that the message
|
||||
digest has been computed.
|
||||
|
||||
*/
|
||||
|
||||
void SHA1PadMessage(SHA1_CONTEXT *context)
|
||||
{
|
||||
/*
|
||||
Check to see if the current message block is too small to hold
|
||||
the initial padding bits and length. If so, we will pad the
|
||||
block, process it, and then continue padding into a second
|
||||
block.
|
||||
Check to see if the current message block is too small to hold
|
||||
the initial padding bits and length. If so, we will pad the
|
||||
block, process it, and then continue padding into a second
|
||||
block.
|
||||
*/
|
||||
|
||||
int i=context->Message_Block_Index;
|
||||
@ -411,27 +357,26 @@ void SHA1PadMessage(SHA1_CONTEXT *context)
|
||||
{
|
||||
context->Message_Block[i++] = 0x80;
|
||||
bzero((char*) &context->Message_Block[i],
|
||||
sizeof(context->Message_Block[0])*(64-i));
|
||||
sizeof(context->Message_Block[0])*(64-i));
|
||||
context->Message_Block_Index=64;
|
||||
|
||||
/* This function sets context->Message_Block_Index to zero */
|
||||
/* This function sets context->Message_Block_Index to zero */
|
||||
SHA1ProcessMessageBlock(context);
|
||||
|
||||
bzero((char*) &context->Message_Block[0],
|
||||
sizeof(context->Message_Block[0])*56);
|
||||
sizeof(context->Message_Block[0])*56);
|
||||
context->Message_Block_Index=56;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
context->Message_Block[i++] = 0x80;
|
||||
bzero((char*) &context->Message_Block[i],
|
||||
sizeof(context->Message_Block[0])*(56-i));
|
||||
sizeof(context->Message_Block[0])*(56-i));
|
||||
context->Message_Block_Index=56;
|
||||
}
|
||||
|
||||
/*
|
||||
Store the message length as the last 8 octets
|
||||
Store the message length as the last 8 octets
|
||||
*/
|
||||
|
||||
context->Message_Block[56] = context->Length >> 56;
|
||||
@ -445,4 +390,3 @@ void SHA1PadMessage(SHA1_CONTEXT *context)
|
||||
|
||||
SHA1ProcessMessageBlock(context);
|
||||
}
|
||||
|
||||
|
@ -88,8 +88,7 @@ class ha_berkeley: public handler
|
||||
ha_berkeley(TABLE *table): handler(table), alloc_ptr(0),rec_buff(0), file(0),
|
||||
int_table_flags(HA_REC_NOT_IN_SEQ |
|
||||
HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER |
|
||||
HA_NULL_KEY | HA_HAVE_KEY_READ_ONLY |
|
||||
HA_BLOB_KEY | HA_NOT_EXACT_COUNT |
|
||||
HA_NULL_KEY | HA_BLOB_KEY | HA_NOT_EXACT_COUNT |
|
||||
HA_PRIMARY_KEY_IN_READ_INDEX | HA_DROP_BEFORE_CREATE |
|
||||
HA_AUTO_PART_KEY | HA_TABLE_SCAN_ON_INDEX),
|
||||
changed_rows(0),last_dup_key((uint) -1),version(0),using_ignore(0)
|
||||
|
@ -356,13 +356,12 @@ ha_innobase::update_thd(
|
||||
/*************************************************************************
|
||||
Opens an InnoDB database. */
|
||||
|
||||
char current_lib[3]; // Set if using current lib
|
||||
|
||||
bool
|
||||
innobase_init(void)
|
||||
/*===============*/
|
||||
/* out: TRUE if error */
|
||||
{
|
||||
static char current_lib[3]; // Set if using current lib
|
||||
int err;
|
||||
bool ret;
|
||||
char *default_path;
|
||||
|
@ -77,7 +77,6 @@ class ha_innobase: public handler
|
||||
ha_innobase(TABLE *table): handler(table),
|
||||
int_table_flags(HA_REC_NOT_IN_SEQ |
|
||||
HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER |
|
||||
HA_HAVE_KEY_READ_ONLY |
|
||||
HA_NULL_KEY |
|
||||
HA_NOT_EXACT_COUNT |
|
||||
HA_NO_WRITE_DELAYED |
|
||||
@ -98,7 +97,7 @@ class ha_innobase: public handler
|
||||
ulong index_flags(uint idx) const
|
||||
{
|
||||
return (HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER |
|
||||
HA_NOT_READ_PREFIX_LAST);
|
||||
HA_NOT_READ_PREFIX_LAST | HA_KEY_READ_ONLY);
|
||||
}
|
||||
uint max_record_length() const { return HA_MAX_REC_LENGTH; }
|
||||
uint max_keys() const { return MAX_KEY; }
|
||||
|
@ -51,8 +51,6 @@ int ha_isam::open(const char *name, int mode, uint test_if_locked)
|
||||
info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
|
||||
if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED))
|
||||
(void) nisam_extra(file,HA_EXTRA_WAIT_LOCK);
|
||||
if (!table->db_record_offset)
|
||||
int_table_flags|=HA_REC_NOT_IN_SEQ;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -26,21 +26,20 @@
|
||||
class ha_isam: public handler
|
||||
{
|
||||
N_INFO *file;
|
||||
uint int_table_flags;
|
||||
|
||||
public:
|
||||
ha_isam(TABLE *table): handler(table), file(0),
|
||||
int_table_flags(HA_READ_RND_SAME |
|
||||
HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER |
|
||||
HA_HAVE_KEY_READ_ONLY |
|
||||
HA_KEY_READ_WRONG_STR | HA_DUPP_POS |
|
||||
HA_NOT_DELETE_WITH_CACHE)
|
||||
{}
|
||||
ha_isam(TABLE *table): handler(table), file(0)
|
||||
{}
|
||||
~ha_isam() {}
|
||||
const char *table_type() const { return "ISAM"; }
|
||||
const char *index_type(uint key_number) { return "BTREE"; }
|
||||
const char **bas_ext() const;
|
||||
ulong table_flags() const { return int_table_flags; }
|
||||
ulong table_flags() const
|
||||
{
|
||||
return (HA_READ_RND_SAME | HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER |
|
||||
HA_KEY_READ_WRONG_STR | HA_DUPP_POS | HA_NOT_DELETE_WITH_CACHE |
|
||||
((table->db_record_offset) ? 0 : HA_REC_NOT_IN_SEQ));
|
||||
}
|
||||
uint max_record_length() const { return HA_MAX_REC_LENGTH; }
|
||||
uint max_keys() const { return N_MAXKEY; }
|
||||
uint max_key_parts() const { return N_MAXKEY_SEG; }
|
||||
@ -80,5 +79,4 @@ class ha_isam: public handler
|
||||
int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info);
|
||||
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
|
||||
enum thr_lock_type lock_type);
|
||||
|
||||
};
|
||||
|
@ -885,7 +885,8 @@ void ha_myisam::info(uint flag)
|
||||
ref_length=info.reflength;
|
||||
table->db_options_in_use = info.options;
|
||||
block_size=myisam_block_size;
|
||||
table->keys_in_use &= info.key_map;
|
||||
table->keys_in_use&= info.key_map;
|
||||
table->keys_for_keyread&= info.key_map;
|
||||
table->db_record_offset=info.record_offset;
|
||||
if (table->key_parts)
|
||||
memcpy((char*) table->key_info[0].rec_per_key,
|
||||
|
@ -45,7 +45,6 @@ class ha_myisam: public handler
|
||||
public:
|
||||
ha_myisam(TABLE *table): handler(table), file(0),
|
||||
int_table_flags(HA_READ_RND_SAME | HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER |
|
||||
HA_HAVE_KEY_READ_ONLY |
|
||||
HA_NULL_KEY | HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER |
|
||||
HA_DUPP_POS | HA_BLOB_KEY | HA_AUTO_PART_KEY),
|
||||
enable_activate_all_index(1)
|
||||
@ -55,6 +54,12 @@ class ha_myisam: public handler
|
||||
const char *index_type(uint key_number);
|
||||
const char **bas_ext() const;
|
||||
ulong table_flags() const { return int_table_flags; }
|
||||
ulong index_flags(uint inx) const
|
||||
{
|
||||
ulong flags=(HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER);
|
||||
return (flags | ((table->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT) ?
|
||||
0 : HA_KEY_READ_ONLY));
|
||||
}
|
||||
uint max_record_length() const { return HA_MAX_REC_LENGTH; }
|
||||
uint max_keys() const { return MI_MAX_KEY; }
|
||||
uint max_key_parts() const { return MAX_REF_PARTS; }
|
||||
|
@ -35,10 +35,15 @@ class ha_myisammrg: public handler
|
||||
ulong table_flags() const
|
||||
{
|
||||
return (HA_REC_NOT_IN_SEQ | HA_READ_RND_SAME |
|
||||
HA_HAVE_KEY_READ_ONLY | HA_KEYPOS_TO_RNDPOS |
|
||||
HA_LASTKEY_ORDER |
|
||||
HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER |
|
||||
HA_NULL_KEY | HA_BLOB_KEY);
|
||||
}
|
||||
ulong index_flags(uint inx) const
|
||||
{
|
||||
ulong flags=(HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER);
|
||||
return (flags | ((table->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT) ?
|
||||
0 : HA_KEY_READ_ONLY));
|
||||
}
|
||||
uint max_record_length() const { return HA_MAX_REC_LENGTH; }
|
||||
uint max_keys() const { return MI_MAX_KEY; }
|
||||
uint max_key_parts() const { return MAX_REF_PARTS; }
|
||||
|
@ -48,7 +48,6 @@
|
||||
#define HA_TABLE_SCAN_ON_INDEX 4 /* No separate data/index file */
|
||||
#define HA_REC_NOT_IN_SEQ 8 /* ha_info don't return recnumber;
|
||||
It returns a position to ha_r_rnd */
|
||||
#define HA_HAVE_KEY_READ_ONLY 16 /* Can read only keys (no record) */
|
||||
#define HA_NO_INDEX 32 /* No index needed for next/prev */
|
||||
#define HA_KEY_READ_WRONG_STR 64 /* keyread returns converted strings */
|
||||
#define HA_NULL_KEY 128 /* One can have keys with NULL */
|
||||
@ -83,6 +82,7 @@
|
||||
#define HA_READ_ORDER 8 /* Read through record-keys in order */
|
||||
#define HA_ONLY_WHOLE_INDEX 16 /* Can't use part key searches */
|
||||
#define HA_NOT_READ_PREFIX_LAST 32
|
||||
#define HA_KEY_READ_ONLY 64 /* Support HA_EXTRA_KEYREAD */
|
||||
|
||||
/*
|
||||
Parameters for open() (in register form->filestat)
|
||||
@ -321,7 +321,7 @@ public:
|
||||
virtual ulong table_flags(void) const =0;
|
||||
virtual ulong index_flags(uint idx) const
|
||||
{
|
||||
return (HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER);
|
||||
return (HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | HA_KEY_READ_ONLY);
|
||||
}
|
||||
virtual uint max_record_length() const =0;
|
||||
virtual uint max_keys() const =0;
|
||||
|
@ -153,15 +153,15 @@ String *Item_func_aes_encrypt::val_str(String *str)
|
||||
null_value=0;
|
||||
aes_length=my_aes_get_size(sptr->length()); // calculate result length
|
||||
|
||||
if ( !str->alloc(aes_length) ) // Ensure that memory is free
|
||||
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)
|
||||
if (my_aes_encrypt(sptr->ptr(),sptr->length(), (char*) str->ptr(),
|
||||
key->ptr(), key->length()) == aes_length)
|
||||
{
|
||||
// we have to get expected result length
|
||||
str->length((uint) aes_length);
|
||||
return str;
|
||||
// We got the expected result length
|
||||
str->length((uint) aes_length);
|
||||
return str;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -169,9 +169,10 @@ String *Item_func_aes_encrypt::val_str(String *str)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void Item_func_aes_encrypt::fix_length_and_dec()
|
||||
{
|
||||
max_length=my_aes_get_size(args[0]->max_length);
|
||||
max_length=my_aes_get_size(args[0]->max_length);
|
||||
}
|
||||
|
||||
|
||||
@ -184,12 +185,12 @@ String *Item_func_aes_decrypt::val_str(String *str)
|
||||
if (sptr && key) // Need to have both arguments not NULL
|
||||
{
|
||||
null_value=0;
|
||||
if ( !str->alloc(sptr->length()) ) // Ensure that memory is free
|
||||
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
|
||||
// finally decrypt directly to allocated buffer.
|
||||
length=my_aes_decrypt(sptr->ptr(), sptr->length(), (char*) str->ptr(),
|
||||
key->ptr(), key->length());
|
||||
if (length >= 0) // if we got correct data data
|
||||
{
|
||||
str->length((uint) length);
|
||||
return str;
|
||||
@ -208,9 +209,9 @@ void Item_func_aes_decrypt::fix_length_and_dec()
|
||||
|
||||
|
||||
/*
|
||||
** Concatinate args with the following premissess
|
||||
** If only one arg which is ok, return value of arg
|
||||
** Don't reallocate val_str() if not absolute necessary.
|
||||
Concatenate args with the following premises:
|
||||
If only one arg (which is ok), return value of arg
|
||||
Don't reallocate val_str() if not absolute necessary.
|
||||
*/
|
||||
|
||||
String *Item_func_concat::val_str(String *str)
|
||||
|
@ -682,27 +682,27 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables,
|
||||
{
|
||||
ha_rows found_records;
|
||||
double found_read_time;
|
||||
|
||||
if (*key)
|
||||
{
|
||||
uint keynr= param.real_keynr[idx];
|
||||
if ((*key)->type == SEL_ARG::MAYBE_KEY ||
|
||||
(*key)->maybe_flag)
|
||||
needed_reg|= (key_map) 1 << param.real_keynr[idx];
|
||||
needed_reg|= (key_map) 1 << keynr;
|
||||
|
||||
found_records=check_quick_select(¶m,idx, *key);
|
||||
found_records=check_quick_select(¶m, idx, *key);
|
||||
if (found_records != HA_POS_ERROR && found_records > 2 &&
|
||||
head->used_keys & ((table_map) 1 << param.real_keynr[idx]) &&
|
||||
(head->file->table_flags() & HA_HAVE_KEY_READ_ONLY))
|
||||
head->used_keys & ((table_map) 1 << keynr) &&
|
||||
(head->file->index_flags(keynr) & HA_KEY_READ_ONLY))
|
||||
{
|
||||
/*
|
||||
** We can resolve this by only reading through this key
|
||||
** Assume that we will read trough the whole key range
|
||||
** and that all key blocks are half full (normally things are
|
||||
** much better)
|
||||
We can resolve this by only reading through this key.
|
||||
Assume that we will read trough the whole key range
|
||||
and that all key blocks are half full (normally things are
|
||||
much better).
|
||||
*/
|
||||
uint keys_per_block= head->file->block_size/2/
|
||||
(head->key_info[param.real_keynr[idx]].key_length+
|
||||
head->file->ref_length) + 1;
|
||||
uint keys_per_block= (head->file->block_size/2/
|
||||
(head->key_info[keynr].key_length+
|
||||
head->file->ref_length) + 1);
|
||||
found_read_time=((double) (found_records+keys_per_block-1)/
|
||||
(double) keys_per_block);
|
||||
}
|
||||
|
@ -730,7 +730,8 @@ TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table_list)
|
||||
table->const_table=0;
|
||||
table->outer_join=table->null_row=table->maybe_null=0;
|
||||
table->status=STATUS_NO_RECORD;
|
||||
table->keys_in_use_for_query=table->used_keys= table->keys_in_use;
|
||||
table->keys_in_use_for_query= table->keys_in_use;
|
||||
table->used_keys= table->keys_for_keyread;
|
||||
DBUG_RETURN(table);
|
||||
}
|
||||
|
||||
@ -884,7 +885,8 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name,
|
||||
table->const_table=0;
|
||||
table->outer_join=table->null_row=table->maybe_null=0;
|
||||
table->status=STATUS_NO_RECORD;
|
||||
table->keys_in_use_for_query=table->used_keys= table->keys_in_use;
|
||||
table->keys_in_use_for_query= table->keys_in_use;
|
||||
table->used_keys= table->keys_for_keyread;
|
||||
DBUG_ASSERT(table->key_read == 0);
|
||||
DBUG_RETURN(table);
|
||||
}
|
||||
@ -950,7 +952,8 @@ bool reopen_table(TABLE *table,bool locked)
|
||||
tmp.null_row= table->null_row;
|
||||
tmp.maybe_null= table->maybe_null;
|
||||
tmp.status= table->status;
|
||||
tmp.keys_in_use_for_query=tmp.used_keys=tmp.keys_in_use;
|
||||
tmp.keys_in_use_for_query= tmp.keys_in_use;
|
||||
tmp.used_keys= tmp.keys_for_keyread;
|
||||
|
||||
/* Get state */
|
||||
tmp.key_length= table->key_length;
|
||||
@ -1578,7 +1581,7 @@ Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length,
|
||||
{
|
||||
field->query_id=thd->query_id;
|
||||
table->used_fields++;
|
||||
table->used_keys&=field->part_of_key;
|
||||
table->used_keys&= field->part_of_key;
|
||||
}
|
||||
else
|
||||
thd->dupp_field=field;
|
||||
@ -1783,7 +1786,8 @@ bool setup_tables(TABLE_LIST *tables)
|
||||
table->const_table=0;
|
||||
table->outer_join=table->null_row=0;
|
||||
table->status=STATUS_NO_RECORD;
|
||||
table->keys_in_use_for_query=table->used_keys= table->keys_in_use;
|
||||
table->keys_in_use_for_query= table->keys_in_use;
|
||||
table->used_keys= table->keys_for_keyread;
|
||||
table->maybe_null=test(table->outer_join=table_list->outer_join);
|
||||
table->tablenr=tablenr;
|
||||
table->map= (table_map) 1 << tablenr;
|
||||
@ -1873,7 +1877,7 @@ insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name,
|
||||
if (field->query_id == thd->query_id)
|
||||
thd->dupp_field=field;
|
||||
field->query_id=thd->query_id;
|
||||
table->used_keys&=field->part_of_key;
|
||||
table->used_keys&= field->part_of_key;
|
||||
}
|
||||
/* All fields are used */
|
||||
table->used_fields=table->fields;
|
||||
|
@ -3063,8 +3063,8 @@ my_bool Query_cache::check_integrity(bool not_locked)
|
||||
DBUG_PRINT("qcache", ("block 0x%lx, type %u...",
|
||||
(ulong) block, (uint) block->type));
|
||||
// Check allignment
|
||||
if ((((ulonglong)block) % (ulonglong)ALIGN_SIZE(1)) !=
|
||||
(((ulonglong)first_block) % (ulonglong)ALIGN_SIZE(1)))
|
||||
if ((((long)block) % (long) ALIGN_SIZE(1)) !=
|
||||
(((long)first_block) % (long)ALIGN_SIZE(1)))
|
||||
{
|
||||
DBUG_PRINT("error",
|
||||
("block 0x%lx do not aligned by %d", (ulong) block,
|
||||
|
@ -233,7 +233,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
|
||||
and no GROUP BY.
|
||||
TODO: Add check of calculation of GROUP functions and fields:
|
||||
SELECT COUNT(*)+table.col1 from table1;
|
||||
*/
|
||||
*/
|
||||
join.table=0;
|
||||
join.tables=0;
|
||||
{
|
||||
@ -257,14 +257,7 @@ 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)
|
||||
|
18
sql/table.cc
18
sql/table.cc
@ -133,7 +133,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
|
||||
if (read_string(file,(gptr*) &disk_buff,key_info_length))
|
||||
goto err_not_open; /* purecov: inspected */
|
||||
outparam->keys=keys= disk_buff[0];
|
||||
outparam->keys_in_use= set_bits(key_map, keys);
|
||||
outparam->keys_for_keyread= outparam->keys_in_use= set_bits(key_map, keys);
|
||||
|
||||
outparam->key_parts=key_parts=disk_buff[1];
|
||||
n_length=keys*sizeof(KEY)+key_parts*sizeof(KEY_PART_INFO);
|
||||
@ -199,6 +199,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
|
||||
for (i=0 ; i < keys ; i++, keyinfo++)
|
||||
keyinfo->algorithm= (enum ha_key_alg) *(strpos++);
|
||||
}
|
||||
|
||||
outparam->reclength = uint2korr((head+16));
|
||||
if (*(head+26) == 1)
|
||||
outparam->system=1; /* one-record-database */
|
||||
@ -386,7 +387,17 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
|
||||
for (uint key=0 ; key < outparam->keys ; key++,keyinfo++)
|
||||
{
|
||||
uint usable_parts=0;
|
||||
ulong index_flags;
|
||||
keyinfo->name=(char*) outparam->keynames.type_names[key];
|
||||
/* Fix fulltext keys for old .frm files */
|
||||
if (outparam->key_info[key].flags & HA_FULLTEXT)
|
||||
outparam->key_info[key].algorithm= HA_KEY_ALG_FULLTEXT;
|
||||
|
||||
/* This has to be done after the above fulltext correction */
|
||||
index_flags=outparam->file->index_flags(key);
|
||||
if (!(index_flags & HA_KEY_READ_ONLY))
|
||||
outparam->keys_for_keyread&= ~((key_map) 1 << key);
|
||||
|
||||
if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
|
||||
{
|
||||
/*
|
||||
@ -444,7 +455,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
|
||||
keyinfo->key_length ? UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
|
||||
if (i == 0)
|
||||
field->key_start|= ((key_map) 1 << key);
|
||||
if ((ha_option & HA_HAVE_KEY_READ_ONLY) &&
|
||||
if ((index_flags & HA_KEY_READ_ONLY) &&
|
||||
field->key_length() == key_part->length &&
|
||||
field->type() != FIELD_TYPE_BLOB)
|
||||
{
|
||||
@ -454,8 +465,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
|
||||
field->part_of_key|= ((key_map) 1 << key);
|
||||
if ((field->key_type() != HA_KEYTYPE_TEXT ||
|
||||
!(keyinfo->flags & HA_FULLTEXT)) &&
|
||||
!(outparam->file->index_flags(key) &
|
||||
HA_WRONG_ASCII_ORDER))
|
||||
!(index_flags & HA_WRONG_ASCII_ORDER))
|
||||
field->part_of_sortkey|= ((key_map) 1 << key);
|
||||
}
|
||||
if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
|
||||
|
@ -61,7 +61,8 @@ struct st_table {
|
||||
uint uniques;
|
||||
uint null_fields; /* number of null fields */
|
||||
uint blob_fields; /* number of blob fields */
|
||||
key_map keys_in_use, keys_in_use_for_query;
|
||||
key_map keys_in_use, keys_for_keyread;
|
||||
key_map quick_keys, used_keys, keys_in_use_for_query;
|
||||
KEY *key_info; /* data of keys in database */
|
||||
TYPELIB keynames; /* Pointers to keynames */
|
||||
ha_rows max_rows; /* create information */
|
||||
@ -119,7 +120,6 @@ struct st_table {
|
||||
byte *record_pointers; /* If sorted in memory */
|
||||
ha_rows found_records; /* How many records in sort */
|
||||
ORDER *group;
|
||||
key_map quick_keys, used_keys;
|
||||
ha_rows quick_rows[MAX_KEY];
|
||||
uint quick_key_parts[MAX_KEY];
|
||||
key_part_map const_key_parts[MAX_KEY];
|
||||
|
Reference in New Issue
Block a user