Commit 518787c2 authored by unknown's avatar unknown

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.
parent 9424f80f
...@@ -27645,6 +27645,12 @@ flag again, the @code{SQL_MAX_JOIN_SIZE} variable will be ignored. ...@@ -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 You can set a default value for this variable by starting @code{mysqld} with
@code{-O max_join_size=#}. @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 = OFF | ON | DEMAND
@item SQL_QUERY_CACHE_TYPE = 0 | 1 | 2 @item SQL_QUERY_CACHE_TYPE = 0 | 1 | 2
Set query cache setting for this thread. Set query cache setting for this thread.
...@@ -1438,8 +1438,8 @@ int main(int argc, char **argv) ...@@ -1438,8 +1438,8 @@ int main(int argc, char **argv)
else if (opt_single_transaction) /* Just to make it beautiful enough */ else if (opt_single_transaction) /* Just to make it beautiful enough */
{ {
/* /*
In case we were locking all tables, we did not start transaction In case we were locking all tables, we did not start transaction
so there is no need to commit it. so there is no need to commit it.
*/ */
/* This should just free locks as we did not change anything */ /* This should just free locks as we did not change anything */
......
...@@ -4,81 +4,63 @@ ...@@ -4,81 +4,63 @@
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Header file for my_aes.c */ /* Header file for my_aes.c */
/* Wrapper to give simple interface for MySQL to AES standard encryption */ /* 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" #include "rijndael.h"
#define AES_KEY_LENGTH 128 C_MODE_START
/* Must be 128 192 or 256 */
#ifdef __cplusplus #define AES_KEY_LENGTH 128 /* Must be 128 192 or 256 */
extern "C" {
#endif
/* /*
my_aes_encrypt - Crypt buffer with AES encryption algorithm. my_aes_encrypt - Crypt buffer with AES encryption algorithm.
source - Pinter to data for encryption source - Pointer to data for encryption
source_length - size of encruption data source_length - size of encryption data
dest - buffer to place encrypted data (must be large enough) dest - buffer to place encrypted data (must be large enough)
key - Key to be used for encryption key - Key to be used for encryption
kel_length - Lenght of the key. Will handle keys of any length kel_length - Length of the key. Will handle keys of any length
returns - size of encrypted data, or negative in case of error. returns - size of encrypted data, or negative in case of error.
*/ */
int my_aes_encrypt(const char* source, int source_length, const char* dest, int my_aes_encrypt(const char *source, int source_length, char *dest,
const char* key, int key_length); const char *key, int key_length);
/* /*
my_aes_decrypt - DeCrypt buffer with AES encryption algorithm. my_aes_decrypt - DeCrypt buffer with AES encryption algorithm.
source - Pinter to data for decryption source - Pointer to data for decryption
source_length - size of encrypted data source_length - size of encrypted data
dest - buffer to place decrypted data (must be large enough) dest - buffer to place decrypted data (must be large enough)
key - Key to be used for decryption key - Key to be used for decryption
kel_length - Lenght of the key. Will handle keys of any length kel_length - Length of the key. Will handle keys of any length
returns - size of original data, or negative in case of error. returns - size of original data, or negative in case of error.
*/ */
int my_aes_decrypt(const char* source, int source_length, const char* dest, int my_aes_decrypt(const char *source, int source_length, char *dest,
const char* key, int key_length); const char *key, int key_length);
/* /*
my_aes_get_size - get size of buffer which will be large enough for encrypted my_aes_get_size - get size of buffer which will be large enough for encrypted
data data
source_length - length of data to be encrypted source_length - length of data to be encrypted
returns - size of buffer required to store encrypted data
returns - size of buffer required to store encrypted data
*/ */
int my_aes_get_size(int source_length); int my_aes_get_size(int source_length);
C_MODE_END
#ifdef __cplusplus
}
#endif
#endif
...@@ -4,45 +4,39 @@ ...@@ -4,45 +4,39 @@
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* /*
rijndael-alg-fst.h rijndael-alg-fst.h
@version 3.0 (December 2000) @version 3.0 (December 2000)
Optimised ANSI C code for the Rijndael cipher (now AES) Optimised ANSI C code for the Rijndael cipher (now AES)
@author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be> @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
@author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be> @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
@author Paulo Barreto <paulo.barreto@terra.com.br> @author Paulo Barreto <paulo.barreto@terra.com.br>
This code is hereby placed in the public domain. This code is hereby placed in the public domain.
Modified by Peter Zaitsev to fit MySQL coding style.
Modified by Peter Zaitsev to fit MySQL coding style.
*/ */
#ifndef __RIJNDAEL_ALG_FST_H
#define __RIJNDAEL_ALG_FST_H
#define MAXKC (256/32) #define AES_MAXKC (256/32)
#define MAXKB (256/8) #define AES_MAXKB (256/8)
#define MAXNR 14 #define AES_MAXNR 14
int rijndaelKeySetupEnc(uint32 rk[/*4*(Nr + 1)*/], const uint8 cipherKey[], 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 rijndaelKeySetupDec(uint32 rk[/*4*(Nr + 1)*/], const uint8 cipherKey[],
int keyBits); int keyBits);
void rijndaelEncrypt(const uint32 rk[/*4*(Nr + 1)*/], int Nr, 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, void rijndaelDecrypt(const uint32 rk[/*4*(Nr + 1)*/], int Nr,
const uint8 ct[16], uint8 pt[16]); const uint8 ct[16], uint8 pt[16]);
#endif /* __RIJNDAEL_ALG_FST_H */
...@@ -4,81 +4,64 @@ ...@@ -4,81 +4,64 @@
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 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
Description: April 17, 1995.
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 */
Many of the variable names in this code, especially the
single character names, were used because those were the names
used in the publication.
#ifndef _SHA1_H_ Please read the file sha1.c for more information.
#define _SHA1_H_
#include "my_global.h" Modified 2002 by Peter Zaitsev to better follow MySQL standards
*/
/* Required for uint32, uint8, int16 ulonglong types */
enum sha_result_codes enum sha_result_codes
{ {
SHA_SUCCESS = 0, SHA_SUCCESS = 0,
SHA_NULL, /* Null pointer parameter */ SHA_NULL, /* Null pointer parameter */
SHA_INPUT_TOO_LONG, /* input data too long */ SHA_INPUT_TOO_LONG, /* input data too long */
SHA_STATE_ERROR /* called Input after Result */ SHA_STATE_ERROR /* called Input after Result */
}; };
#define SHA1_HASH_SIZE 20 /* Hash size in bytes */ #define SHA1_HASH_SIZE 20 /* Hash size in bytes */
/* /*
This structure will hold context information for the SHA-1 This structure will hold context information for the SHA-1
hashing operation hashing operation
*/ */
typedef struct SHA1_CONTEXT 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 */ uint32 Intermediate_Hash[SHA1_HASH_SIZE/4]; /* Message Digest */
int Computed; /* Is the digest computed? */ int Computed; /* Is the digest computed? */
int Corrupted; /* Is the message digest corrupted? */ int Corrupted; /* Is the message digest corrupted? */
int16 Message_Block_Index; /* Index into message block array */ int16 Message_Block_Index; /* Index into message block array */
uint8 Message_Block[64]; /* 512-bit message blocks */ uint8 Message_Block[64]; /* 512-bit message blocks */
} SHA1_CONTEXT; } SHA1_CONTEXT;
/* /*
* Function Prototypes Function Prototypes
*/ */
#ifdef __cplusplus C_MODE_START
extern "C" {
#endif
int sha1_reset( SHA1_CONTEXT* ); int sha1_reset( SHA1_CONTEXT* );
int sha1_input( SHA1_CONTEXT*, const uint8 *, unsigned int ); int sha1_input( SHA1_CONTEXT*, const uint8 *, unsigned int );
int sha1_result( SHA1_CONTEXT* , uint8 Message_Digest[SHA1_HASH_SIZE] ); int sha1_result( SHA1_CONTEXT* , uint8 Message_Digest[SHA1_HASH_SIZE] );
#ifdef __cplusplus
}
#endif
#endif C_MODE_END
...@@ -4,184 +4,196 @@ ...@@ -4,184 +4,196 @@
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* /*
Implementation of AES Encryption for MySQL Implementation of AES Encryption for MySQL
Initial version by Peter Zaitsev June 2002 Initial version by Peter Zaitsev June 2002
*/ */
#include "my_global.h" #include <my_global.h>
#include "m_string.h" #include <m_string.h>
#include "my_aes.h" #include "my_aes.h"
enum encrypt_dir { AES_ENCRYPT, AES_DECRYPT }; enum encrypt_dir { AES_ENCRYPT, AES_DECRYPT };
#define AES_BLOCK_SIZE 16 #define AES_BLOCK_SIZE 16 /* Block size in bytes */
/* Block size in bytes */
#define AES_BAD_DATA -1
/* If bad data discovered during decoding */
/* The structure for key information */ #define AES_BAD_DATA -1 /* If bad data discovered during decoding */
/* The structure for key information */
typedef struct { typedef struct {
int nr; /* Number of rounds */ int nr; /* Number of rounds */
uint32 rk[4*(MAXNR + 1)]; /* key schedule */ uint32 rk[4*(AES_MAXNR + 1)]; /* key schedule */
} KEYINSTANCE; } KEYINSTANCE;
/* /*
This is internal function just keeps joint code of Key generation 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) SYNOPSIS
key - key to use for real key creation my_aes_create_key()
key_length - length of the key aes_key Address of Key Instance to be created
direction Direction (are we encoding or decoding)
returns - returns 0 on success and negative on error key Key to use for real key creation
*/ key_length Length of the key
static int my_aes_create_key(KEYINSTANCE* aes_key,char direction, char* key,
int key_length) DESCRIPTION
{
char rkey[AES_KEY_LENGTH/8]; /* The real key to be used for encryption */ RESULT
char *ptr; /* Start of the real key*/ 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 *rkey_end=rkey+AES_KEY_LENGTH/8; /* Real key boundary */ char *rkey_end=rkey+AES_KEY_LENGTH/8; /* Real key boundary */
char *sptr; /* Start of the working key */ char *ptr; /* Start of the real key*/
char *key_end=key+key_length; /* Working key boundary*/ 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 */ bzero(rkey,AES_KEY_LENGTH/8); /* Set initial key */
for (ptr= rkey, sptr= key; sptr < key_end; ptr++,sptr++) for (ptr= rkey, sptr= key; sptr < key_end; ptr++,sptr++)
{ {
if (ptr == rkey_end) if (ptr == rkey_end)
ptr= rkey; /* Just loop over tmp_key until we used all key */ ptr= rkey; /* Just loop over tmp_key until we used all key */
*ptr^= *sptr; *ptr^= *sptr;
} }
if (direction==AES_DECRYPT) if (direction == AES_DECRYPT)
aes_key->nr = rijndaelKeySetupDec(aes_key->rk, rkey, AES_KEY_LENGTH); aes_key->nr = rijndaelKeySetupDec(aes_key->rk, rkey, AES_KEY_LENGTH);
else else
aes_key->nr = rijndaelKeySetupEnc(aes_key->rk, rkey, AES_KEY_LENGTH); aes_key->nr = rijndaelKeySetupEnc(aes_key->rk, rkey, AES_KEY_LENGTH);
return 0; return 0;
} }
/* /*
my_aes_encrypt - Crypt buffer with AES encryption algorithm. Crypt buffer with AES encryption algorithm.
source - Pinter to data for encryption
source_length - size of encruption data SYNOPSIS
dest - buffer to place encrypted data (must be large enough) my_aes_encrypt()
key - Key to be used for encryption source Pointer to data for encryption
kel_length - Lenght of the key. Will handle keys of any length source_length Size of encryption data
dest Buffer to place encrypted data (must be large enough)
returns - size of encrypted data, or negative in case of error. 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, int my_aes_encrypt(const char* source, int source_length, char* dest,
const char* key, int key_length) const char* key, int key_length)
{ {
KEYINSTANCE aes_key; KEYINSTANCE aes_key;
char block[AES_BLOCK_SIZE]; /* 128 bit block used for padding */ char block[AES_BLOCK_SIZE]; /* 128 bit block used for padding */
int rc; /* result codes */ int rc; /* result codes */
int num_blocks; /* number of complete blocks */ int num_blocks; /* number of complete blocks */
char pad_len; /* pad size for the last block */ char pad_len; /* pad size for the last block */
int i; 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; return rc;
num_blocks = source_length/AES_BLOCK_SIZE; num_blocks = source_length/AES_BLOCK_SIZE;
for (i = num_blocks; i > 0; i--) /* Encode complete blocks */ for (i = num_blocks; i > 0; i--) /* Encode complete blocks */
{ {
rijndaelEncrypt(aes_key.rk, aes_key.nr, source, dest); rijndaelEncrypt(aes_key.rk, aes_key.nr, source, dest);
source+= AES_BLOCK_SIZE; source+= AES_BLOCK_SIZE;
dest+= AES_BLOCK_SIZE; dest+= AES_BLOCK_SIZE;
} }
/* Encode the rest. We always have incomplete block */ /* Encode the rest. We always have incomplete block */
pad_len = AES_BLOCK_SIZE - (source_length - AES_BLOCK_SIZE*num_blocks); pad_len = AES_BLOCK_SIZE - (source_length - AES_BLOCK_SIZE*num_blocks);
memcpy(block, source, 16 - pad_len); memcpy(block, source, 16 - pad_len);
bfill(block + AES_BLOCK_SIZE - pad_len, pad_len, pad_len); bfill(block + AES_BLOCK_SIZE - pad_len, pad_len, pad_len);
rijndaelEncrypt(aes_key.rk, aes_key.nr, block, dest); rijndaelEncrypt(aes_key.rk, aes_key.nr, block, dest);
return AES_BLOCK_SIZE*(num_blocks + 1); return AES_BLOCK_SIZE*(num_blocks + 1);
} }
/* /*
my_aes_decrypt - DeCrypt buffer with AES encryption algorithm. DeCrypt buffer with AES encryption algorithm.
source - Pinter to data for decryption
source_length - size of encrypted data SYNOPSIS
dest - buffer to place decrypted data (must be large enough) my_aes_decrypt()
key - Key to be used for decryption source Pointer to data for decryption
kel_length - Lenght of the key. Will handle keys of any length source_length Size of encrypted data
dest Buffer to place decrypted data (must be large enough)
returns - size of original data, or negative in case of error. 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, int my_aes_decrypt(const char *source, int source_length, char *dest,
const char* key, int key_length) const char *key, int key_length)
{ {
KEYINSTANCE aes_key; KEYINSTANCE aes_key;
char block[AES_BLOCK_SIZE]; /* 128 bit block used for padding */ char block[AES_BLOCK_SIZE]; /* 128 bit block used for padding */
int rc; /* result codes */ int rc; /* Result codes */
int num_blocks; /* number of complete blocks */ int num_blocks; /* Number of complete blocks */
char pad_len; /* pad size for the last block */ char pad_len; /* Pad size for the last block */
int i; int i;
if ((rc=my_aes_create_key(&aes_key,AES_DECRYPT,key,key_length))) if ((rc=my_aes_create_key(&aes_key,AES_DECRYPT,key,key_length)))
return rc; return rc;
num_blocks = source_length/AES_BLOCK_SIZE; num_blocks = source_length/AES_BLOCK_SIZE;
if ((source_length != num_blocks*AES_BLOCK_SIZE) || num_blocks ==0 )
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 */
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 */ for (i = num_blocks-1; i > 0; i--) /* Decode all but last blocks */
{ {
rijndaelDecrypt(aes_key.rk, aes_key.nr, source, dest); rijndaelDecrypt(aes_key.rk, aes_key.nr, source, dest);
source+= AES_BLOCK_SIZE; source+= AES_BLOCK_SIZE;
dest+= AES_BLOCK_SIZE; dest+= AES_BLOCK_SIZE;
} }
rijndaelDecrypt(aes_key.rk, aes_key.nr, source, block); 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) if (pad_len > AES_BLOCK_SIZE)
return AES_BAD_DATA; return AES_BAD_DATA;
/* We could also check whole padding but we do not really need this */ /* We could also check whole padding but we do not really need this */
memcpy(dest, block, AES_BLOCK_SIZE - pad_len); memcpy(dest, block, AES_BLOCK_SIZE - pad_len);
return AES_BLOCK_SIZE*num_blocks - 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 Get size of buffer which will be large enough for encrypted data
data
source_length - length of data to be encrypted SYNOPSIS
returns - size of buffer required to store encrypted data 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) int my_aes_get_size(int source_length)
{ {
return AES_BLOCK_SIZE*(source_length/AES_BLOCK_SIZE)+AES_BLOCK_SIZE; return AES_BLOCK_SIZE*(source_length/AES_BLOCK_SIZE)+AES_BLOCK_SIZE;
} }
This diff is collapsed.
This diff is collapsed.
...@@ -88,8 +88,7 @@ class ha_berkeley: public handler ...@@ -88,8 +88,7 @@ class ha_berkeley: public handler
ha_berkeley(TABLE *table): handler(table), alloc_ptr(0),rec_buff(0), file(0), ha_berkeley(TABLE *table): handler(table), alloc_ptr(0),rec_buff(0), file(0),
int_table_flags(HA_REC_NOT_IN_SEQ | int_table_flags(HA_REC_NOT_IN_SEQ |
HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER | HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER |
HA_NULL_KEY | HA_HAVE_KEY_READ_ONLY | HA_NULL_KEY | HA_BLOB_KEY | HA_NOT_EXACT_COUNT |
HA_BLOB_KEY | HA_NOT_EXACT_COUNT |
HA_PRIMARY_KEY_IN_READ_INDEX | HA_DROP_BEFORE_CREATE | HA_PRIMARY_KEY_IN_READ_INDEX | HA_DROP_BEFORE_CREATE |
HA_AUTO_PART_KEY | HA_TABLE_SCAN_ON_INDEX), HA_AUTO_PART_KEY | HA_TABLE_SCAN_ON_INDEX),
changed_rows(0),last_dup_key((uint) -1),version(0),using_ignore(0) changed_rows(0),last_dup_key((uint) -1),version(0),using_ignore(0)
......
...@@ -356,13 +356,12 @@ ha_innobase::update_thd( ...@@ -356,13 +356,12 @@ ha_innobase::update_thd(
/************************************************************************* /*************************************************************************
Opens an InnoDB database. */ Opens an InnoDB database. */
char current_lib[3]; // Set if using current lib
bool bool
innobase_init(void) innobase_init(void)
/*===============*/ /*===============*/
/* out: TRUE if error */ /* out: TRUE if error */
{ {
static char current_lib[3]; // Set if using current lib
int err; int err;
bool ret; bool ret;
char *default_path; char *default_path;
......
...@@ -77,7 +77,6 @@ class ha_innobase: public handler ...@@ -77,7 +77,6 @@ class ha_innobase: public handler
ha_innobase(TABLE *table): handler(table), ha_innobase(TABLE *table): handler(table),
int_table_flags(HA_REC_NOT_IN_SEQ | int_table_flags(HA_REC_NOT_IN_SEQ |
HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER | HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER |
HA_HAVE_KEY_READ_ONLY |
HA_NULL_KEY | HA_NULL_KEY |
HA_NOT_EXACT_COUNT | HA_NOT_EXACT_COUNT |
HA_NO_WRITE_DELAYED | HA_NO_WRITE_DELAYED |
...@@ -98,7 +97,7 @@ class ha_innobase: public handler ...@@ -98,7 +97,7 @@ class ha_innobase: public handler
ulong index_flags(uint idx) const 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_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_record_length() const { return HA_MAX_REC_LENGTH; }
uint max_keys() const { return MAX_KEY; } uint max_keys() const { return MAX_KEY; }
......
...@@ -51,8 +51,6 @@ int ha_isam::open(const char *name, int mode, uint test_if_locked) ...@@ -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); info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED)) if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED))
(void) nisam_extra(file,HA_EXTRA_WAIT_LOCK); (void) nisam_extra(file,HA_EXTRA_WAIT_LOCK);
if (!table->db_record_offset)
int_table_flags|=HA_REC_NOT_IN_SEQ;
return (0); return (0);
} }
......
...@@ -26,21 +26,20 @@ ...@@ -26,21 +26,20 @@
class ha_isam: public handler class ha_isam: public handler
{ {
N_INFO *file; N_INFO *file;
uint int_table_flags;
public: public:
ha_isam(TABLE *table): handler(table), file(0), 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() {} ~ha_isam() {}
const char *table_type() const { return "ISAM"; } const char *table_type() const { return "ISAM"; }
const char *index_type(uint key_number) { return "BTREE"; } const char *index_type(uint key_number) { return "BTREE"; }
const char **bas_ext() const; 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_record_length() const { return HA_MAX_REC_LENGTH; }
uint max_keys() const { return N_MAXKEY; } uint max_keys() const { return N_MAXKEY; }
uint max_key_parts() const { return N_MAXKEY_SEG; } uint max_key_parts() const { return N_MAXKEY_SEG; }
...@@ -80,5 +79,4 @@ class ha_isam: public handler ...@@ -80,5 +79,4 @@ class ha_isam: public handler
int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info); int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info);
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
enum thr_lock_type lock_type); enum thr_lock_type lock_type);
}; };
...@@ -885,7 +885,8 @@ void ha_myisam::info(uint flag) ...@@ -885,7 +885,8 @@ void ha_myisam::info(uint flag)
ref_length=info.reflength; ref_length=info.reflength;
table->db_options_in_use = info.options; table->db_options_in_use = info.options;
block_size=myisam_block_size; 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; table->db_record_offset=info.record_offset;
if (table->key_parts) if (table->key_parts)
memcpy((char*) table->key_info[0].rec_per_key, memcpy((char*) table->key_info[0].rec_per_key,
......
...@@ -45,7 +45,6 @@ class ha_myisam: public handler ...@@ -45,7 +45,6 @@ class ha_myisam: public handler
public: public:
ha_myisam(TABLE *table): handler(table), file(0), ha_myisam(TABLE *table): handler(table), file(0),
int_table_flags(HA_READ_RND_SAME | HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER | 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_NULL_KEY | HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER |
HA_DUPP_POS | HA_BLOB_KEY | HA_AUTO_PART_KEY), HA_DUPP_POS | HA_BLOB_KEY | HA_AUTO_PART_KEY),
enable_activate_all_index(1) enable_activate_all_index(1)
...@@ -55,6 +54,12 @@ class ha_myisam: public handler ...@@ -55,6 +54,12 @@ class ha_myisam: public handler
const char *index_type(uint key_number); const char *index_type(uint key_number);
const char **bas_ext() const; const char **bas_ext() const;
ulong table_flags() const { return int_table_flags; } 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_record_length() const { return HA_MAX_REC_LENGTH; }
uint max_keys() const { return MI_MAX_KEY; } uint max_keys() const { return MI_MAX_KEY; }
uint max_key_parts() const { return MAX_REF_PARTS; } uint max_key_parts() const { return MAX_REF_PARTS; }
......
...@@ -35,10 +35,15 @@ class ha_myisammrg: public handler ...@@ -35,10 +35,15 @@ class ha_myisammrg: public handler
ulong table_flags() const ulong table_flags() const
{ {
return (HA_REC_NOT_IN_SEQ | HA_READ_RND_SAME | return (HA_REC_NOT_IN_SEQ | HA_READ_RND_SAME |
HA_HAVE_KEY_READ_ONLY | HA_KEYPOS_TO_RNDPOS | HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER |
HA_LASTKEY_ORDER |
HA_NULL_KEY | HA_BLOB_KEY); 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_record_length() const { return HA_MAX_REC_LENGTH; }
uint max_keys() const { return MI_MAX_KEY; } uint max_keys() const { return MI_MAX_KEY; }
uint max_key_parts() const { return MAX_REF_PARTS; } uint max_key_parts() const { return MAX_REF_PARTS; }
......
...@@ -48,7 +48,6 @@ ...@@ -48,7 +48,6 @@
#define HA_TABLE_SCAN_ON_INDEX 4 /* No separate data/index file */ #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; #define HA_REC_NOT_IN_SEQ 8 /* ha_info don't return recnumber;
It returns a position to ha_r_rnd */ 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_NO_INDEX 32 /* No index needed for next/prev */
#define HA_KEY_READ_WRONG_STR 64 /* keyread returns converted strings */ #define HA_KEY_READ_WRONG_STR 64 /* keyread returns converted strings */
#define HA_NULL_KEY 128 /* One can have keys with NULL */ #define HA_NULL_KEY 128 /* One can have keys with NULL */
...@@ -83,6 +82,7 @@ ...@@ -83,6 +82,7 @@
#define HA_READ_ORDER 8 /* Read through record-keys in order */ #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_ONLY_WHOLE_INDEX 16 /* Can't use part key searches */
#define HA_NOT_READ_PREFIX_LAST 32 #define HA_NOT_READ_PREFIX_LAST 32
#define HA_KEY_READ_ONLY 64 /* Support HA_EXTRA_KEYREAD */
/* /*
Parameters for open() (in register form->filestat) Parameters for open() (in register form->filestat)
...@@ -321,7 +321,7 @@ public: ...@@ -321,7 +321,7 @@ public:
virtual ulong table_flags(void) const =0; virtual ulong table_flags(void) const =0;
virtual ulong index_flags(uint idx) const 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_record_length() const =0;
virtual uint max_keys() const =0; virtual uint max_keys() const =0;
......
...@@ -153,15 +153,15 @@ String *Item_func_aes_encrypt::val_str(String *str) ...@@ -153,15 +153,15 @@ String *Item_func_aes_encrypt::val_str(String *str)
null_value=0; null_value=0;
aes_length=my_aes_get_size(sptr->length()); // calculate result length 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. // finally encrypt directly to allocated buffer.
if (my_aes_encrypt(sptr->ptr(),sptr->length(),str->ptr(),key->ptr(), if (my_aes_encrypt(sptr->ptr(),sptr->length(), (char*) str->ptr(),
key->length()) == aes_length) key->ptr(), key->length()) == aes_length)
{ {
// we have to get expected result length // We got the expected result length
str->length((uint) aes_length); str->length((uint) aes_length);
return str; return str;
} }
} }
} }
...@@ -169,9 +169,10 @@ String *Item_func_aes_encrypt::val_str(String *str) ...@@ -169,9 +169,10 @@ String *Item_func_aes_encrypt::val_str(String *str)
return 0; return 0;
} }
void Item_func_aes_encrypt::fix_length_and_dec() 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) ...@@ -184,12 +185,12 @@ String *Item_func_aes_decrypt::val_str(String *str)
if (sptr && key) // Need to have both arguments not NULL if (sptr && key) // Need to have both arguments not NULL
{ {
null_value=0; 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. // finally decrypt directly to allocated buffer.
length=my_aes_decrypt(sptr->ptr(),sptr->length(),str->ptr(), length=my_aes_decrypt(sptr->ptr(), sptr->length(), (char*) str->ptr(),
key->ptr(),key->length()); key->ptr(), key->length());
if (length>=0) // if we got correct data data if (length >= 0) // if we got correct data data
{ {
str->length((uint) length); str->length((uint) length);
return str; return str;
...@@ -208,9 +209,9 @@ void Item_func_aes_decrypt::fix_length_and_dec() ...@@ -208,9 +209,9 @@ void Item_func_aes_decrypt::fix_length_and_dec()
/* /*
** Concatinate args with the following premissess Concatenate args with the following premises:
** If only one arg which is ok, return value of arg If only one arg (which is ok), return value of arg
** Don't reallocate val_str() if not absolute necessary. Don't reallocate val_str() if not absolute necessary.
*/ */
String *Item_func_concat::val_str(String *str) 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, ...@@ -682,27 +682,27 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables,
{ {
ha_rows found_records; ha_rows found_records;
double found_read_time; double found_read_time;
if (*key) if (*key)
{ {
uint keynr= param.real_keynr[idx];
if ((*key)->type == SEL_ARG::MAYBE_KEY || if ((*key)->type == SEL_ARG::MAYBE_KEY ||
(*key)->maybe_flag) (*key)->maybe_flag)
needed_reg|= (key_map) 1 << param.real_keynr[idx]; needed_reg|= (key_map) 1 << keynr;
found_records=check_quick_select(&param,idx, *key); found_records=check_quick_select(&param, idx, *key);
if (found_records != HA_POS_ERROR && found_records > 2 && if (found_records != HA_POS_ERROR && found_records > 2 &&
head->used_keys & ((table_map) 1 << param.real_keynr[idx]) && head->used_keys & ((table_map) 1 << keynr) &&
(head->file->table_flags() & HA_HAVE_KEY_READ_ONLY)) (head->file->index_flags(keynr) & HA_KEY_READ_ONLY))
{ {
/* /*
** We can resolve this by only reading through this key We can resolve this by only reading through this key.
** Assume that we will read trough the whole key range Assume that we will read trough the whole key range
** and that all key blocks are half full (normally things are and that all key blocks are half full (normally things are
** much better) much better).
*/ */
uint keys_per_block= head->file->block_size/2/ uint keys_per_block= (head->file->block_size/2/
(head->key_info[param.real_keynr[idx]].key_length+ (head->key_info[keynr].key_length+
head->file->ref_length) + 1; head->file->ref_length) + 1);
found_read_time=((double) (found_records+keys_per_block-1)/ found_read_time=((double) (found_records+keys_per_block-1)/
(double) keys_per_block); (double) keys_per_block);
} }
......
...@@ -730,7 +730,8 @@ TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table_list) ...@@ -730,7 +730,8 @@ TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table_list)
table->const_table=0; table->const_table=0;
table->outer_join=table->null_row=table->maybe_null=0; table->outer_join=table->null_row=table->maybe_null=0;
table->status=STATUS_NO_RECORD; 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); DBUG_RETURN(table);
} }
...@@ -884,7 +885,8 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name, ...@@ -884,7 +885,8 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name,
table->const_table=0; table->const_table=0;
table->outer_join=table->null_row=table->maybe_null=0; table->outer_join=table->null_row=table->maybe_null=0;
table->status=STATUS_NO_RECORD; 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_ASSERT(table->key_read == 0);
DBUG_RETURN(table); DBUG_RETURN(table);
} }
...@@ -950,7 +952,8 @@ bool reopen_table(TABLE *table,bool locked) ...@@ -950,7 +952,8 @@ bool reopen_table(TABLE *table,bool locked)
tmp.null_row= table->null_row; tmp.null_row= table->null_row;
tmp.maybe_null= table->maybe_null; tmp.maybe_null= table->maybe_null;
tmp.status= table->status; 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 */ /* Get state */
tmp.key_length= table->key_length; tmp.key_length= table->key_length;
...@@ -1578,7 +1581,7 @@ Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint 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; field->query_id=thd->query_id;
table->used_fields++; table->used_fields++;
table->used_keys&=field->part_of_key; table->used_keys&= field->part_of_key;
} }
else else
thd->dupp_field=field; thd->dupp_field=field;
...@@ -1783,7 +1786,8 @@ bool setup_tables(TABLE_LIST *tables) ...@@ -1783,7 +1786,8 @@ bool setup_tables(TABLE_LIST *tables)
table->const_table=0; table->const_table=0;
table->outer_join=table->null_row=0; table->outer_join=table->null_row=0;
table->status=STATUS_NO_RECORD; 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->maybe_null=test(table->outer_join=table_list->outer_join);
table->tablenr=tablenr; table->tablenr=tablenr;
table->map= (table_map) 1 << tablenr; table->map= (table_map) 1 << tablenr;
...@@ -1873,7 +1877,7 @@ insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name, ...@@ -1873,7 +1877,7 @@ insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name,
if (field->query_id == thd->query_id) if (field->query_id == thd->query_id)
thd->dupp_field=field; thd->dupp_field=field;
field->query_id=thd->query_id; field->query_id=thd->query_id;
table->used_keys&=field->part_of_key; table->used_keys&= field->part_of_key;
} }
/* All fields are used */ /* All fields are used */
table->used_fields=table->fields; table->used_fields=table->fields;
......
...@@ -3063,8 +3063,8 @@ my_bool Query_cache::check_integrity(bool not_locked) ...@@ -3063,8 +3063,8 @@ my_bool Query_cache::check_integrity(bool not_locked)
DBUG_PRINT("qcache", ("block 0x%lx, type %u...", DBUG_PRINT("qcache", ("block 0x%lx, type %u...",
(ulong) block, (uint) block->type)); (ulong) block, (uint) block->type));
// Check allignment // Check allignment
if ((((ulonglong)block) % (ulonglong)ALIGN_SIZE(1)) != if ((((long)block) % (long) ALIGN_SIZE(1)) !=
(((ulonglong)first_block) % (ulonglong)ALIGN_SIZE(1))) (((long)first_block) % (long)ALIGN_SIZE(1)))
{ {
DBUG_PRINT("error", DBUG_PRINT("error",
("block 0x%lx do not aligned by %d", (ulong) block, ("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, ...@@ -233,7 +233,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
and no GROUP BY. and no GROUP BY.
TODO: Add check of calculation of GROUP functions and fields: TODO: Add check of calculation of GROUP functions and fields:
SELECT COUNT(*)+table.col1 from table1; SELECT COUNT(*)+table.col1 from table1;
*/ */
join.table=0; join.table=0;
join.tables=0; join.tables=0;
{ {
...@@ -257,14 +257,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, ...@@ -257,14 +257,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
} }
TABLE_LIST *table; TABLE_LIST *table;
for (table=tables ; table ; table=table->next) for (table=tables ; table ; table=table->next)
{
join.tables++; 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); procedure=setup_procedure(thd,proc_param,result,fields,&error);
if (error) if (error)
......
...@@ -133,7 +133,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, ...@@ -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)) if (read_string(file,(gptr*) &disk_buff,key_info_length))
goto err_not_open; /* purecov: inspected */ goto err_not_open; /* purecov: inspected */
outparam->keys=keys= disk_buff[0]; 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]; outparam->key_parts=key_parts=disk_buff[1];
n_length=keys*sizeof(KEY)+key_parts*sizeof(KEY_PART_INFO); 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, ...@@ -199,6 +199,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
for (i=0 ; i < keys ; i++, keyinfo++) for (i=0 ; i < keys ; i++, keyinfo++)
keyinfo->algorithm= (enum ha_key_alg) *(strpos++); keyinfo->algorithm= (enum ha_key_alg) *(strpos++);
} }
outparam->reclength = uint2korr((head+16)); outparam->reclength = uint2korr((head+16));
if (*(head+26) == 1) if (*(head+26) == 1)
outparam->system=1; /* one-record-database */ outparam->system=1; /* one-record-database */
...@@ -386,7 +387,17 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, ...@@ -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++) for (uint key=0 ; key < outparam->keys ; key++,keyinfo++)
{ {
uint usable_parts=0; uint usable_parts=0;
ulong index_flags;
keyinfo->name=(char*) outparam->keynames.type_names[key]; 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)) 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, ...@@ -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); keyinfo->key_length ? UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
if (i == 0) if (i == 0)
field->key_start|= ((key_map) 1 << key); 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->key_length() == key_part->length &&
field->type() != FIELD_TYPE_BLOB) field->type() != FIELD_TYPE_BLOB)
{ {
...@@ -454,8 +465,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, ...@@ -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); field->part_of_key|= ((key_map) 1 << key);
if ((field->key_type() != HA_KEYTYPE_TEXT || if ((field->key_type() != HA_KEYTYPE_TEXT ||
!(keyinfo->flags & HA_FULLTEXT)) && !(keyinfo->flags & HA_FULLTEXT)) &&
!(outparam->file->index_flags(key) & !(index_flags & HA_WRONG_ASCII_ORDER))
HA_WRONG_ASCII_ORDER))
field->part_of_sortkey|= ((key_map) 1 << key); field->part_of_sortkey|= ((key_map) 1 << key);
} }
if (!(key_part->key_part_flag & HA_REVERSE_SORT) && if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
......
...@@ -61,7 +61,8 @@ struct st_table { ...@@ -61,7 +61,8 @@ struct st_table {
uint uniques; uint uniques;
uint null_fields; /* number of null fields */ uint null_fields; /* number of null fields */
uint blob_fields; /* number of blob 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 */ KEY *key_info; /* data of keys in database */
TYPELIB keynames; /* Pointers to keynames */ TYPELIB keynames; /* Pointers to keynames */
ha_rows max_rows; /* create information */ ha_rows max_rows; /* create information */
...@@ -119,7 +120,6 @@ struct st_table { ...@@ -119,7 +120,6 @@ struct st_table {
byte *record_pointers; /* If sorted in memory */ byte *record_pointers; /* If sorted in memory */
ha_rows found_records; /* How many records in sort */ ha_rows found_records; /* How many records in sort */
ORDER *group; ORDER *group;
key_map quick_keys, used_keys;
ha_rows quick_rows[MAX_KEY]; ha_rows quick_rows[MAX_KEY];
uint quick_key_parts[MAX_KEY]; uint quick_key_parts[MAX_KEY];
key_part_map const_key_parts[MAX_KEY]; key_part_map const_key_parts[MAX_KEY];
......
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