diff options
author | unknown <monty@mysql.com/narttu.mysql.fi> | 2007-10-11 18:07:40 +0300 |
---|---|---|
committer | unknown <monty@mysql.com/narttu.mysql.fi> | 2007-10-11 18:07:40 +0300 |
commit | fb84f573adf00de5e606a3b312bec99d24a0f49c (patch) | |
tree | 2f3bb6c8948945094ff740b1991e2d9b80a55ec3 | |
parent | d7a8509795728fb3cffd6890cdc1ac6a971ae035 (diff) | |
download | mariadb-git-fb84f573adf00de5e606a3b312bec99d24a0f49c.tar.gz |
Moved a lot of old bug fixes and safe cleanups from Maria 5.1 tree to 5.1
- Reserver namespace and place in frm for TABLE_CHECKSUM and PAGE_CHECKSUM create options
- Added syncing of directory when creating .frm files
- Portability fixes
- Added missing cast that could cause bugs
- Code cleanups
- Made some bit functions inline
- Moved things out of myisam.h to my_handler.h to make them more accessable
- Renamed some myisam variables and defines to make them more globaly usable (as they are used outside of MyISAM)
- Fixed bugs in error conditions
- Use compiler time asserts instead of run time
- Fixed indentation
HA_EXTRA_PREPARE_FOR_DELETE -> HA_EXTRA_PREPARE_FOR_DROP as the old name was wrong
(Added a define for old value to ensure we don't break any old code)
Added HA_EXTRA_PREPARE_FOR_RENAME as a signal for rename (before we used a DROP signal which is wrong)
- Initialize error messages early to get better errors when mysqld or an engine fails to start
- Fix windows bug that query_performance_frequency was not initialized if registry code failed
- thread_stack -> my_thread_stack_size
BitKeeper/etc/ignore:
added libmysqld/scheduler.cc libmysqld/sql_connect.cc libmysqld/sql_tablespace.cc
include/Makefile.am:
Added my_bit.h
include/m_string.h:
Added bzero_if_purify() to simplify code
include/my_base.h:
Reserve options for the future
Added HA_OPTION_NULL_FIELDS, HA_OPTION_PAGE_CHECKSUM, HA_CREATE_PAGE_CHECKSUM
Added new error message HA_ERR_NEW_FILE
Added optional new row type BLOCK_RECORD
Renamed HA_EXTRA_PREPARE_FOR_DELETE to HA_EXTRA_PREPARE_FOR_DROP
Added HA_EXTRA_PREARE_FOR_RENAME to inform handler we will do a rename
(Added define to make things compatible until 6.0)
Moved invalidator_by_filename form myisam.h
include/my_dbug.h:
Poirtablity fix
include/my_global.h:
Added helper macros STATIC_INLINE and MY_ERRPTR
Added NEED_EXPLICIT_SYNC_DIR
include/my_handler.h:
Added missing casts
Moved some constants and macros out from myisam.h to make these generally available
Renamed mi_compare_text() to ha_compare_text() as this function is not myisam specific
Renamed mi_portable_sizeof_char_ptr to portable_sizeof_char_ptr
Added registering of handler messages for better error reporting during startup
include/my_sys.h:
Added my_sync_dir() and my_sync_dir_by_file()
More comments
Some indentation fixes
Moved bit functions to my_bit.h
Added prototype for crc32()
include/myisam.h:
Moved things from here to my_handler.h to make them more accessable
libmysql/Makefile.shared:
Added my_sync
mysys/array.c:
Fixed indentation and spelling errors
Split set_dynamic() to two functions
Added allocate_dynamic() as a new visiable function
(no new code, only refactoring)
mysys/mf_iocache.c:
More DBUG
mysys/mf_keycache.c:
More explicite ASSERT
Removed some casts
Fixed indentation
mysys/mf_tempfile.c:
Fixed bug with possible dangling file descriptor
mysys/my_atomic.c:
Use compile time asserts instead of run time
mysys/my_bit.c:
Make most bit functions inline
mysys/my_bitmap.c:
Added my_bit.h
mysys/my_compress.c:
Fixed indentation
mysys/my_create.c:
Added my_sync_by_dir()
mysys/my_delete.c:
Added my_sync_by_dir()
mysys/my_error.c:
init_glob_errs() is now done in my_init()
mysys/my_handler.c:
mi_compare_text() -> ha_compare_text() as this is not MyISAM specific
Added functions to initialize handler error messages
Fixed indentation
More clear usage of include files
mysys/my_init.c:
Added my_thread_stack_size to be used by other programs
Ensure that global error messages are always initialized
Fix windows bug that query_performance_frequency was not initialized if registry code failed
mysys/my_open.c:
More comments
Removed duplicate code
mysys/my_pread.c:
Ensure that my_errno is set even if errno is 0
mysys/my_realloc.c:
Added comment
mysys/my_rename.c:
Added syncing of directories
mysys/my_symlink.c:
Added my_sync_by_dir()
mysys/my_sync.c:
Added my_sync_dir()
On recent Mac OS X, fcntl(F_FULLFSYNC) is recommended over fsync()
(see "man fsync" on Mac OS X 10.3).
my_sync_dir(): to sync a directory after a file creation/deletion/
renaming; can be called directly or via MY_SYNC_DIR in my_create/
my_delete/my_rename(). No-op except on Linux (see "man fsync" on Linux).
my_sync_dir_from_file(): same as above, just more practical when the
caller has a file name but no directory name ready.
Should the #warning even be a #error? I mean do we want to release
binaries which don't guarantee any durability?
mysys/safemalloc.c:
Added sf_malloc_report_allocated() (Debugging aid)
sql/gen_lex_hash.cc:
Remove inline for big function
sql/ha_partition.cc:
HA_EXTRA_PREPARE_FOR_DELETE -> HA_EXTRA_PREPARE_FOR_DROP
prepare_for_delete -> prepare_for_rename() as this is the the time this function is called
sql/ha_partition.h:
prepare_for_delete -> prepare_for_rename() as this is the the time this function is called
sql/handler.cc:
ha_init_errors() is now called at startup before plugins
This allows us to get better error messages
sql/handler.h:
Reserve enum value for Maria
Add future proof enum for page checksums
sql/item_func.cc:
Include my_bit.h
sql/lex.h:
Added future proof CREATE table options
sql/log.cc:
Added comment
sql/mysql_priv.h:
thread_stack moved to mysys
sql/mysqld.cc:
thread_stack moved to mysys
thread_stack -> my_thread_stack_size
Initialize myisam key caches before plugins starts
Initialize error to allow storage engine to give better error messages if init failes.
Fixed indentation
Group all MyISAM options together
Added new status variable 'Opened_table_definitions' to allow one to monitor if table definition cache is too small
Clarified some option help messages
sql/opt_range.cc:
Removed wrong usage of SAFE_MODE (this disabled key usage for UPDATES, which was never the intention)
Removed print if total cost in a place where it didn't have any usable value
sql/set_var.cc:
thread_stack -> my_thread_stack
sql/sql_class.cc:
Intialize transaction object properly
sql/sql_parse.cc:
thread_stack -> my_thread_stack
sql/sql_select.cc:
Include my_bit.h
mi_portable_sizeof_char_ptr -> portable_sizeof_char_ptr
sql/sql_show.cc:
Simplify handling of ha_choice variables
Added future safe PAGE_CHECKSUM option
Addid missing 'transactional=#' in information schema
sql/sql_table.cc:
HA_EXTRA_PREPARE_FOR_DELETE -> HA_EXTRA_FORCE_REOPEN when doing reopen
HA_EXTRA_PREPARE_FOR_DELETE -> HA_EXTRA_PREPARE_FOR_RENAME when doing rename
Removed not needed initialization
sql/sql_test.cc:
thread_stack -> my_thread_stack
sql/sql_yacc.yy:
Simplify handling of ha_choice variables
Added future proof create table options TABLE_CHECKSUM=# & PAGE_CHECKSUM=#
sql/table.cc:
Save page_checksum in .frm
sql/table.h:
Added variable to hold create table option PAGE_CHECKSUM
sql/unireg.cc:
Added syncing of directories
storage/myisam/ft_boolean_search.c:
mi_compare_text() -> ha_compare_text()
storage/myisam/ft_eval.c:
mi_compare_text() -> ha_compare_text()
storage/myisam/ft_nlq_search.c:
mi_compare_text() -> ha_compare_text()
storage/myisam/ft_parser.c:
mi_compare_text() -> ha_compare_text()
storage/myisam/ft_stopwords.c:
mi_compare_text() -> ha_compare_text()
storage/myisam/ft_test1.c:
mi_portable_sizeof_char_ptr -> portable_sizeof_char_ptr
storage/myisam/ft_update.c:
mi_compare_text() -> ha_compare_text()
storage/myisam/ha_myisam.cc:
Include my_bit.h
storage/myisam/mi_check.c:
MI_MAX_POSSIBLE_KEY_BUFF -> HA_MAX_POSSIBLE_KEY_BUFF
mi_compare_text() -> ha_compare_text()
Added BLOCK_RECORD to avoid compiler warnings
storage/myisam/mi_checksum.c:
mi_portable_sizeof_char_ptr -> portable_sizeof_char_ptr
storage/myisam/mi_create.c:
MI_MAX_POSSIBLE_KEY -> HA_MAX_POSSIBLE_KEY
MI_MAX_KEY_BLOCK_SIZE -> HA_MAX_KEY_BLOCK_SIZE
mi_portable_sizeof_char_ptr -> portable_sizeof_char_ptr
storage/myisam/mi_dynrec.c:
mi_portable_sizeof_char_ptr -> portable_sizeof_char_ptr
storage/myisam/mi_extra.c:
HA_EXTRA_PREPARE_FOR_DELETE -> HA_EXTRA_PREPARE_FOR_DROP
storage/myisam/mi_open.c:
MI_MAX_POSSIBLE_KEY -> HA_MAX_POSSIBLE_KEY
mi_portable_sizeof_char_ptr -> portable_sizeof_char_ptr
storage/myisam/mi_packrec.c:
mi_portable_sizeof_char_ptr -> portable_sizeof_char_ptr
storage/myisam/mi_range.c:
mi_compare_text -> ha_compare_text
storage/myisam/mi_test1.c:
mi_portable_sizeof_char_ptr -> portable_sizeof_char_ptr
storage/myisam/mi_test2.c:
mi_portable_sizeof_char_ptr -> portable_sizeof_char_ptr
storage/myisam/mi_unique.c:
mi_compare_text() -> ha_compare_text()
storage/myisam/mi_write.c:
mi_compare_text() -> ha_compare_text()
storage/myisam/myisamchk.c:
Include my_bit.h
storage/myisam/myisamdef.h:
Moved store_key_length_inc to handler.h
storage/myisam/myisampack.c:
mi_portable_sizeof_char_ptr -> portable_sizeof_char_ptr
storage/myisam/sp_test.c:
mi_portable_sizeof_char_ptr -> portable_sizeof_char_ptr
storage/myisammrg/ha_myisammrg.cc:
HA_EXTRA_PREPARE_FOR_DELETE -> HA_EXTRA_PREPARE_FOR_DROP
include/my_bit.h:
New BitKeeper file ``include/my_bit.h''
78 files changed, 844 insertions, 386 deletions
diff --git a/.bzrignore b/.bzrignore index e1ad5a89015..f6a40871315 100644 --- a/.bzrignore +++ b/.bzrignore @@ -3004,3 +3004,7 @@ win/vs71cache.txt win/vs8cache.txt zlib/*.ds? zlib/*.vcproj +libmysql_r/client_settings.h +libmysqld/scheduler.cc +libmysqld/sql_connect.cc +libmysqld/sql_tablespace.cc diff --git a/include/Makefile.am b/include/Makefile.am index 8335da36e93..bf85409c36f 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -26,7 +26,7 @@ pkginclude_HEADERS = $(HEADERS_ABI) my_dbug.h m_string.h my_sys.h \ my_getopt.h sslopt-longopts.h my_dir.h \ sslopt-vars.h sslopt-case.h sql_common.h keycache.h \ m_ctype.h my_attribute.h $(HEADERS_GEN) -noinst_HEADERS = config-win.h config-netware.h \ +noinst_HEADERS = config-win.h config-netware.h my_bit.h \ heap.h my_bitmap.h my_uctype.h \ myisam.h myisampack.h myisammrg.h ft_global.h\ mysys_err.h my_base.h help_start.h help_end.h \ diff --git a/include/m_string.h b/include/m_string.h index 00fb4cb0656..036eb8fe4d6 100644 --- a/include/m_string.h +++ b/include/m_string.h @@ -67,7 +67,7 @@ # define bcopy(s, d, n) memcpy((d), (s), (n)) # define bcmp(A,B,C) memcmp((A),(B),(C)) # define bzero(A,B) memset((A),0,(B)) -# define bmove_align(A,B,C) memcpy((A),(B),(C)) +# define bmove_align(A,B,C) memcpy((A),(B),(C)) #endif #if defined(__cplusplus) @@ -129,7 +129,10 @@ extern size_t bcmp(const uchar *s1,const uchar *s2,size_t len); extern size_t my_bcmp(const uchar *s1,const uchar *s2,size_t len); #undef bcmp #define bcmp(A,B,C) my_bcmp((A),(B),(C)) -#endif +#define bzero_if_purify(A,B) bzero(A,B) +#else +#define bzero_if_purify(A,B) +#endif /* HAVE_purify */ #ifndef bmove512 extern void bmove512(uchar *dst,const uchar *src,size_t len); diff --git a/include/my_base.h b/include/my_base.h index 339554979a8..acf6920e21d 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -14,7 +14,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* This file includes constants used with all databases */ -/* Author: Michael Widenius */ #ifndef _my_base_h #define _my_base_h @@ -48,10 +47,11 @@ #define HA_OPEN_FOR_REPAIR 32 /* open even if crashed */ #define HA_OPEN_FROM_SQL_LAYER 64 #define HA_OPEN_MMAP 128 /* open memory mapped */ +#define HA_OPEN_COPY 256 /* Open copy (for repair) */ /* Internal temp table, used for temporary results */ -#define HA_OPEN_INTERNAL_TABLE 256 +#define HA_OPEN_INTERNAL_TABLE 512 - /* The following is parameter to ha_rkey() how to use key */ +/* The following is parameter to ha_rkey() how to use key */ /* We define a complete-field prefix of a key value as a prefix where @@ -137,7 +137,7 @@ enum ha_extra_function { HA_EXTRA_RESET_STATE, /* Reset positions */ HA_EXTRA_IGNORE_DUP_KEY, /* Dup keys don't rollback everything*/ HA_EXTRA_NO_IGNORE_DUP_KEY, - HA_EXTRA_PREPARE_FOR_DELETE, + HA_EXTRA_PREPARE_FOR_DROP, HA_EXTRA_PREPARE_FOR_UPDATE, /* Remove read cache if problems */ HA_EXTRA_PRELOAD_BUFFER_SIZE, /* Set buffer size for preloading */ /* @@ -187,9 +187,14 @@ enum ha_extra_function { Inform handler that an "INSERT...ON DUPLICATE KEY UPDATE" will be executed. This condition is unset by HA_EXTRA_NO_IGNORE_DUP_KEY. */ - HA_EXTRA_INSERT_WITH_UPDATE + HA_EXTRA_INSERT_WITH_UPDATE, + /* Inform handler that we will do a rename */ + HA_EXTRA_PREPARE_FOR_RENAME }; +/* Compatible option, to be deleted in 6.0 */ +#define HA_EXTRA_PREPARE_FOR_DELETE HA_EXTRA_PREPARE_FOR_DROP + /* The following is parameter to ha_panic() */ enum ha_panic_function { @@ -292,6 +297,8 @@ enum ha_base_keytype { #define HA_OPTION_NO_PACK_KEYS 128 /* Reserved for MySQL */ #define HA_OPTION_CREATE_FROM_ENGINE 256 #define HA_OPTION_RELIES_ON_SQL_LAYER 512 +#define HA_OPTION_NULL_FIELDS 1024 +#define HA_OPTION_PAGE_CHECKSUM 2048 #define HA_OPTION_TEMP_COMPRESS_RECORD ((uint) 16384) /* set by isamchk */ #define HA_OPTION_READ_ONLY_DATA ((uint) 32768) /* Set by isamchk */ @@ -302,6 +309,7 @@ enum ha_base_keytype { #define HA_CREATE_TMP_TABLE 4 #define HA_CREATE_CHECKSUM 8 #define HA_CREATE_KEEP_FILES 16 /* don't overwrite .MYD and MYI */ +#define HA_CREATE_PAGE_CHECKSUM 32 #define HA_CREATE_DELAY_KEY_WRITE 64 #define HA_CREATE_RELIES_ON_SQL_LAYER 128 @@ -348,12 +356,15 @@ enum ha_base_keytype { */ #define HA_STATUS_AUTO 64 - /* Errorcodes given by functions */ +/* + Errorcodes given by handler functions + + opt_sum_query() assumes these codes are > 1 + Do not add error numbers before HA_ERR_FIRST. + If necessary to add lower numbers, change HA_ERR_FIRST accordingly. +*/ +#define HA_ERR_FIRST 120 /* Copy of first error nr.*/ -/* opt_sum_query() assumes these codes are > 1 */ -/* Do not add error numbers before HA_ERR_FIRST. */ -/* If necessary to add lower numbers, change HA_ERR_FIRST accordingly. */ -#define HA_ERR_FIRST 120 /*Copy first error nr.*/ #define HA_ERR_KEY_NOT_FOUND 120 /* Didn't find key on read or update */ #define HA_ERR_FOUND_DUPP_KEY 121 /* Dupplicate key on write */ #define HA_ERR_RECORD_CHANGED 123 /* Uppdate with is recoverable */ @@ -374,7 +385,7 @@ enum ha_base_keytype { #define HA_WRONG_CREATE_OPTION 140 /* Wrong create option */ #define HA_ERR_FOUND_DUPP_UNIQUE 141 /* Dupplicate unique on write */ #define HA_ERR_UNKNOWN_CHARSET 142 /* Can't open charset */ -#define HA_ERR_WRONG_MRG_TABLE_DEF 143 /* conflicting MyISAM tables in MERGE */ +#define HA_ERR_WRONG_MRG_TABLE_DEF 143 /* conflicting tables in MERGE */ #define HA_ERR_CRASHED_ON_REPAIR 144 /* Last (automatic?) repair failed */ #define HA_ERR_CRASHED_ON_USAGE 145 /* Table must be repaired */ #define HA_ERR_LOCK_WAIT_TIMEOUT 146 @@ -389,28 +400,33 @@ enum ha_base_keytype { #define HA_ERR_NO_SUCH_TABLE 155 /* The table does not exist in engine */ #define HA_ERR_TABLE_EXIST 156 /* The table existed in storage engine */ #define HA_ERR_NO_CONNECTION 157 /* Could not connect to storage engine */ -#define HA_ERR_NULL_IN_SPATIAL 158 /* NULLs are not supported in spatial index */ +/* NULLs are not supported in spatial index */ +#define HA_ERR_NULL_IN_SPATIAL 158 #define HA_ERR_TABLE_DEF_CHANGED 159 /* The table changed in storage engine */ #define HA_ERR_NO_PARTITION_FOUND 160 /* There's no partition in table for given value */ #define HA_ERR_RBR_LOGGING_FAILED 161 /* Row-based binlogging of row failed */ -#define HA_ERR_DROP_INDEX_FK 162 /* Index needed in foreign key constr. */ -#define HA_ERR_FOREIGN_DUPLICATE_KEY 163 /* Upholding foreign key constraints - would lead to a duplicate key - error in some other table. */ -#define HA_ERR_TABLE_NEEDS_UPGRADE 164 /* The table changed in storage engine */ -#define HA_ERR_TABLE_READONLY 165 /* The table is not writable */ +#define HA_ERR_DROP_INDEX_FK 162 /* Index needed in foreign key constr */ +/* + Upholding foreign key constraints would lead to a duplicate key error + in some other table. +*/ +#define HA_ERR_FOREIGN_DUPLICATE_KEY 163 +/* The table changed in storage engine */ +#define HA_ERR_TABLE_NEEDS_UPGRADE 164 +#define HA_ERR_TABLE_READONLY 165 /* The table is not writable */ #define HA_ERR_AUTOINC_READ_FAILED 166 /* Failed to get next autoinc value */ #define HA_ERR_AUTOINC_ERANGE 167 /* Failed to set row autoinc value */ #define HA_ERR_GENERIC 168 /* Generic error */ -#define HA_ERR_RECORD_IS_THE_SAME 169 /* row not actually updated : - new values same as the old values */ - -#define HA_ERR_LOGGING_IMPOSSIBLE 170 /* It is not possible to log this - statement */ -#define HA_ERR_LAST 170 /*Copy last error nr.*/ -/* Add error numbers before HA_ERR_LAST and change it accordingly. */ +/* row not actually updated: new values same as the old values */ +#define HA_ERR_RECORD_IS_THE_SAME 169 +/* It is not possible to log this statement */ +#define HA_ERR_LOGGING_IMPOSSIBLE 170 +#define HA_ERR_NEW_FILE 171 /* New file format */ +#define HA_ERR_LAST 171 /* Copy of last error nr */ + +/* Number of different errors */ #define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1) /* Other constants */ @@ -474,7 +490,7 @@ enum en_fieldtype { }; enum data_file_type { - STATIC_RECORD,DYNAMIC_RECORD,COMPRESSED_RECORD + STATIC_RECORD, DYNAMIC_RECORD, COMPRESSED_RECORD, BLOCK_RECORD }; /* For key ranges */ @@ -526,4 +542,7 @@ typedef ulong ha_rows; #define HA_VARCHAR_PACKLENGTH(field_length) ((field_length) < 256 ? 1 :2) +/* invalidator function reference for Query Cache */ +typedef void (* invalidator_by_filename)(const char * filename); + #endif /* _my_base_h */ diff --git a/include/my_bit.h b/include/my_bit.h new file mode 100644 index 00000000000..58e8bb39683 --- /dev/null +++ b/include/my_bit.h @@ -0,0 +1,107 @@ +/* + Some useful bit functions +*/ + +#ifdef HAVE_INLINE + +extern const char _my_bits_nbits[256]; +extern const uchar _my_bits_reverse_table[256]; + +/* + Find smallest X in 2^X >= value + This can be used to divide a number with value by doing a shift instead +*/ + +STATIC_INLINE uint my_bit_log2(ulong value) +{ + uint bit; + for (bit=0 ; value > 1 ; value>>=1, bit++) ; + return bit; +} + +STATIC_INLINE uint my_count_bits(ulonglong v) +{ +#if SIZEOF_LONG_LONG > 4 + /* The following code is a bit faster on 16 bit machines than if we would + only shift v */ + ulong v2=(ulong) (v >> 32); + return (uint) (uchar) (_my_bits_nbits[(uchar) v] + + _my_bits_nbits[(uchar) (v >> 8)] + + _my_bits_nbits[(uchar) (v >> 16)] + + _my_bits_nbits[(uchar) (v >> 24)] + + _my_bits_nbits[(uchar) (v2)] + + _my_bits_nbits[(uchar) (v2 >> 8)] + + _my_bits_nbits[(uchar) (v2 >> 16)] + + _my_bits_nbits[(uchar) (v2 >> 24)]); +#else + return (uint) (uchar) (_my_bits_nbits[(uchar) v] + + _my_bits_nbits[(uchar) (v >> 8)] + + _my_bits_nbits[(uchar) (v >> 16)] + + _my_bits_nbits[(uchar) (v >> 24)]); +#endif +} + +STATIC_INLINE uint my_count_bits_ushort(ushort v) +{ + return _my_bits_nbits[v]; +} + + +/* + Next highest power of two + + SYNOPSIS + my_round_up_to_next_power() + v Value to check + + RETURN + Next or equal power of 2 + Note: 0 will return 0 + + NOTES + Algorithm by Sean Anderson, according to: + http://graphics.stanford.edu/~seander/bithacks.html + (Orignal code public domain) + + Comments shows how this works with 01100000000000000000000000001011 +*/ + +STATIC_INLINE uint32 my_round_up_to_next_power(uint32 v) +{ + v--; /* 01100000000000000000000000001010 */ + v|= v >> 1; /* 01110000000000000000000000001111 */ + v|= v >> 2; /* 01111100000000000000000000001111 */ + v|= v >> 4; /* 01111111110000000000000000001111 */ + v|= v >> 8; /* 01111111111111111100000000001111 */ + v|= v >> 16; /* 01111111111111111111111111111111 */ + return v+1; /* 10000000000000000000000000000000 */ +} + +STATIC_INLINE uint32 my_clear_highest_bit(uint32 v) +{ + uint32 w=v >> 1; + w|= w >> 1; + w|= w >> 2; + w|= w >> 4; + w|= w >> 8; + w|= w >> 16; + return v & w; +} + +STATIC_INLINE uint32 my_reverse_bits(uint32 key) +{ + return + (_my_bits_reverse_table[ key & 255] << 24) | + (_my_bits_reverse_table[(key>> 8) & 255] << 16) | + (_my_bits_reverse_table[(key>>16) & 255] << 8) | + _my_bits_reverse_table[(key>>24) ]; +} + +#else +extern uint my_bit_log2(ulong value); +extern uint32 my_round_up_to_next_power(uint32 v); +uint32 my_clear_highest_bit(uint32 v); +uint32 my_reverse_bits(uint32 key); +extern uint my_count_bits(ulonglong v); +extern uint my_count_bits_ushort(ushort v); +#endif diff --git a/include/my_dbug.h b/include/my_dbug.h index 514cd17099b..a77e439b5db 100644 --- a/include/my_dbug.h +++ b/include/my_dbug.h @@ -101,7 +101,7 @@ extern FILE *_db_fp_(void); #define DBUG_LONGJMP(a1) longjmp(a1) #define DBUG_DUMP(keyword,a1,a2) #define DBUG_END() -#define DBUG_ASSERT(A) +#define DBUG_ASSERT(A) do { } while(0) #define DBUG_LOCK_FILE #define DBUG_FILE (stderr) #define DBUG_UNLOCK_FILE diff --git a/include/my_global.h b/include/my_global.h index 12129523939..366996618ed 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -242,6 +242,8 @@ #endif #undef inline_test_2 #undef inline_test_1 +/* helper macro for "instantiating" inline functions */ +#define STATIC_INLINE static inline /* The following macros are used to control inlining a bit more than @@ -1015,6 +1017,8 @@ typedef long long intptr; #error sizeof(void *) is neither sizeof(int) nor sizeof(long) nor sizeof(long long) #endif +#define MY_ERRPTR ((void*)(intptr)1) + #ifdef USE_RAID /* The following is done with a if to not get problems with pre-processors @@ -1476,6 +1480,7 @@ do { doubleget_union _tmp; \ #define dlerror() "" #endif + #ifndef __NETWARE__ /* * Include standard definitions of operator new and delete. @@ -1506,6 +1511,13 @@ inline void operator delete[](void*, void*) { /* Do nothing */ } #if !defined(max) #define max(a, b) ((a) > (b) ? (a) : (b)) #define min(a, b) ((a) < (b) ? (a) : (b)) +#endif +/* + Only Linux is known to need an explicit sync of the directory to make sure a + file creation/deletion/renaming in(from,to) this directory durable. +*/ +#ifdef TARGET_OS_LINUX +#define NEED_EXPLICIT_SYNC_DIR 1 #endif #endif /* my_global_h */ diff --git a/include/my_handler.h b/include/my_handler.h index d7cd0567f9c..dabe73bd138 100644 --- a/include/my_handler.h +++ b/include/my_handler.h @@ -18,10 +18,30 @@ #ifndef _my_handler_h #define _my_handler_h -#include "my_base.h" -#include "m_ctype.h" #include "myisampack.h" +/* + There is a hard limit for the maximum number of keys as there are only + 8 bits in the index file header for the number of keys in a table. + This means that 0..255 keys can exist for a table. The idea of + HA_MAX_POSSIBLE_KEY is to ensure that one can use myisamchk & tools on + a MyISAM table for which one has more keys than MyISAM is normally + compiled for. If you don't have this, you will get a core dump when + running myisamchk compiled for 128 keys on a table with 255 keys. +*/ + +#define HA_MAX_POSSIBLE_KEY 255 /* For myisamchk */ +/* + The following defines can be increased if necessary. + But beware the dependency of MI_MAX_POSSIBLE_KEY_BUFF and HA_MAX_KEY_LENGTH. +*/ + +#define HA_MAX_KEY_LENGTH 1000 /* Max length in bytes */ +#define HA_MAX_KEY_SEG 16 /* Max segments for key */ + +#define HA_MAX_POSSIBLE_KEY_BUFF (HA_MAX_KEY_LENGTH + 24+ 6+6) +#define HA_MAX_KEY_BUFF (HA_MAX_KEY_LENGTH+HA_MAX_KEY_SEG*6+8+8) + typedef struct st_HA_KEYSEG /* Key-portion */ { CHARSET_INFO *charset; @@ -38,33 +58,35 @@ typedef struct st_HA_KEYSEG /* Key-portion */ } HA_KEYSEG; #define get_key_length(length,key) \ -{ if ((uchar) *(key) != 255) \ - length= (uint) (uchar) *((key)++); \ +{ if (*(uchar*) (key) != 255) \ + length= (uint) *(uchar*) ((key)++); \ else \ - { length=mi_uint2korr((key)+1); (key)+=3; } \ + { length= mi_uint2korr((key)+1); (key)+=3; } \ } #define get_key_length_rdonly(length,key) \ -{ if ((uchar) *(key) != 255) \ - length= ((uint) (uchar) *((key))); \ +{ if (*(uchar*) (key) != 255) \ + length= ((uint) *(uchar*) ((key))); \ else \ - { length=mi_uint2korr((key)+1); } \ + { length= mi_uint2korr((key)+1); } \ } #define get_key_pack_length(length,length_pack,key) \ -{ if ((uchar) *(key) != 255) \ - { length= (uint) (uchar) *((key)++); length_pack=1; }\ +{ if (*(uchar*) (key) != 255) \ + { length= (uint) *(uchar*) ((key)++); length_pack= 1; }\ else \ - { length=mi_uint2korr((key)+1); (key)+=3; length_pack=3; } \ + { length=mi_uint2korr((key)+1); (key)+= 3; length_pack= 3; } \ } #define store_key_length_inc(key,length) \ { if ((length) < 255) \ - { *(key)++=(length); } \ + { *(key)++= (length); } \ else \ { *(key)=255; mi_int2store((key)+1,(length)); (key)+=3; } \ } +#define size_to_store_key_length(length) ((length) < 255 ? 1 : 3) + #define get_rec_bits(bit_ptr, bit_ofs, bit_len) \ (((((uint16) (bit_ptr)[1] << 8) | (uint16) (bit_ptr)[0]) >> (bit_ofs)) & \ ((1 << (bit_len)) - 1)) @@ -81,12 +103,20 @@ typedef struct st_HA_KEYSEG /* Key-portion */ #define clr_rec_bits(bit_ptr, bit_ofs, bit_len) \ set_rec_bits(0, bit_ptr, bit_ofs, bit_len) -extern int mi_compare_text(CHARSET_INFO *, uchar *, uint, uchar *, uint , +extern int ha_compare_text(CHARSET_INFO *, uchar *, uint, uchar *, uint , my_bool, my_bool); extern int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, register uchar *b, uint key_length, uint nextflag, uint *diff_pos); extern HA_KEYSEG *ha_find_null(HA_KEYSEG *keyseg, uchar *a); +extern void my_handler_error_register(void); +extern void my_handler_error_unregister(void); +/* + Inside an in-memory data record, memory pointers to pieces of the + record (like BLOBs) are stored in their native byte order and in + this amount of bytes. +*/ +#define portable_sizeof_char_ptr 8 #endif /* _my_handler_h */ diff --git a/include/my_sys.h b/include/my_sys.h index 2ce36760032..1b087360ef3 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -51,6 +51,7 @@ extern int NEAR my_errno; /* Last error in mysys */ #define MY_WME 16 /* Write message on error */ #define MY_WAIT_IF_FULL 32 /* Wait and try again if disk full error */ #define MY_IGNORE_BADFD 32 /* my_sync: ignore 'bad descriptor' errors */ +#define MY_SYNC_DIR 1024 /* my_create/delete/rename: sync directory */ #define MY_RAID 64 /* Support for RAID */ #define MY_FULL_IO 512 /* For my_read - loop intil I/O is complete */ #define MY_DONT_CHECK_FILESIZE 128 /* Option to init_io_cache() */ @@ -212,6 +213,7 @@ extern int (*error_handler_hook)(uint my_err, const char *str,myf MyFlags); extern int (*fatal_error_handler_hook)(uint my_err, const char *str, myf MyFlags); extern uint my_file_limit; +extern ulong my_thread_stack_size; #ifdef HAVE_LARGE_PAGES extern my_bool my_use_large_pages; @@ -276,7 +278,14 @@ enum cache_type enum flush_type { - FLUSH_KEEP, FLUSH_RELEASE, FLUSH_IGNORE_CHANGED, FLUSH_FORCE_WRITE + FLUSH_KEEP, /* flush block and keep it in the cache */ + FLUSH_RELEASE, /* flush block and remove it from the cache */ + FLUSH_IGNORE_CHANGED, /* remove block from the cache */ + /* + As my_disable_flush_pagecache_blocks is always 0, the following option + is strictly equivalent to FLUSH_KEEP + */ + FLUSH_FORCE_WRITE }; typedef struct st_record_cache /* Used when cacheing records */ @@ -627,6 +636,8 @@ extern FILE *my_fdopen(File Filedes,const char *name, int Flags,myf MyFlags); extern int my_fclose(FILE *fd,myf MyFlags); extern int my_chsize(File fd,my_off_t newlength, int filler, myf MyFlags); extern int my_sync(File fd, myf my_flags); +extern int my_sync_dir(const char *dir_name, myf my_flags); +extern int my_sync_dir_by_file(const char *file_name, myf my_flags); extern int my_error _VARARGS((int nr,myf MyFlags, ...)); extern int my_printf_error _VARARGS((uint my_err, const char *format, myf MyFlags, ...)) @@ -661,7 +672,7 @@ extern char *my_tmpdir(MY_TMPDIR *tmpdir); extern void free_tmpdir(MY_TMPDIR *tmpdir); extern void my_remember_signal(int signal_number,sig_handler (*func)(int)); -extern size_t dirname_part(char * to, const char *name, size_t *to_res_length); +extern size_t dirname_part(char * to,const char *name, size_t *to_res_length); extern size_t dirname_length(const char *name); #define base_name(A) (A+dirname_length(A)) extern int test_if_hard_path(const char *dir_name); @@ -707,7 +718,7 @@ extern sig_handler sigtstp_handler(int signal_number); extern void handle_recived_signals(void); extern sig_handler my_set_alarm_variable(int signo); -extern void my_string_ptr_sort(uchar *base, uint items, size_t size); +extern void my_string_ptr_sort(uchar *base,uint items,size_t size); extern void radixsort_for_str_ptr(uchar* base[], uint number_of_elements, size_t size_of_element,uchar *buffer[]); extern qsort_t qsort2(void *base_ptr, size_t total_elems, size_t size, @@ -773,6 +784,7 @@ extern my_bool insert_dynamic(DYNAMIC_ARRAY *array,uchar * element); extern uchar *alloc_dynamic(DYNAMIC_ARRAY *array); extern uchar *pop_dynamic(DYNAMIC_ARRAY*); extern my_bool set_dynamic(DYNAMIC_ARRAY *array,uchar * element,uint array_index); +extern my_bool allocate_dynamic(DYNAMIC_ARRAY *array, uint max_elements); extern void get_dynamic(DYNAMIC_ARRAY *array,uchar * element,uint array_index); extern void delete_dynamic(DYNAMIC_ARRAY *array); extern void delete_dynamic_element(DYNAMIC_ARRAY *array, uint array_index); @@ -839,11 +851,8 @@ extern int unpackfrm(uchar **, size_t *, const uchar *); extern ha_checksum my_checksum(ha_checksum crc, const uchar *mem, size_t count); -extern uint my_bit_log2(ulong value); -extern uint32 my_round_up_to_next_power(uint32 v); -extern uint my_count_bits(ulonglong v); -extern uint my_count_bits_ushort(ushort v); extern void my_sleep(ulong m_seconds); +extern ulong crc32(ulong crc, const uchar *buf, uint len); extern uint my_set_max_open_files(uint files); void my_free_open_file_info(void); @@ -861,7 +870,7 @@ extern int my_getncpus(); #ifndef MAP_NOSYNC #define MAP_NOSYNC 0 #endif -#ifndef MAP_NORESERVE +#ifndef MAP_NORESERVE #define MAP_NORESERVE 0 /* For irix and AIX */ #endif diff --git a/include/myisam.h b/include/myisam.h index 6a76a298dee..e49446769dc 100644 --- a/include/myisam.h +++ b/include/myisam.h @@ -34,22 +34,16 @@ extern "C" { #include <mysql/plugin.h> /* - There is a hard limit for the maximum number of keys as there are only - 8 bits in the index file header for the number of keys in a table. - This means that 0..255 keys can exist for a table. The idea of - MI_MAX_POSSIBLE_KEY is to ensure that one can use myisamchk & tools on - a MyISAM table for which one has more keys than MyISAM is normally - compiled for. If you don't have this, you will get a core dump when - running myisamchk compiled for 128 keys on a table with 255 keys. + Limit max keys according to HA_MAX_POSSIBLE_KEY */ -#define MI_MAX_POSSIBLE_KEY 255 /* For myisam_chk */ -#if MAX_INDEXES > MI_MAX_POSSIBLE_KEY -#define MI_MAX_KEY MI_MAX_POSSIBLE_KEY /* Max allowed keys */ + +#if MAX_INDEXES > HA_MAX_POSSIBLE_KEY +#define MI_MAX_KEY HA_MAX_POSSIBLE_KEY /* Max allowed keys */ #else #define MI_MAX_KEY MAX_INDEXES /* Max allowed keys */ #endif -#define MI_MAX_POSSIBLE_KEY_BUFF (1024+6+6) /* For myisam_chk */ +#define MI_MAX_POSSIBLE_KEY_BUFF HA_MAX_POSSIBLE_KEY_BUFF /* The following defines can be increased if necessary. But beware the dependency of MI_MAX_POSSIBLE_KEY_BUFF and MI_MAX_KEY_LENGTH. @@ -69,8 +63,6 @@ extern "C" { #define MI_MIN_KEY_BLOCK_LENGTH 1024 /* Min key block length */ #define MI_MAX_KEY_BLOCK_LENGTH 16384 -#define mi_portable_sizeof_char_ptr 8 - /* In the following macros '_keyno_' is 0 .. keys-1. If there can be more keys than bits in the key_map, the highest bit @@ -256,8 +248,6 @@ typedef struct st_columndef /* column information */ #endif } MI_COLUMNDEF; -/* invalidator function reference for Query Cache */ -typedef void (* invalidator_by_filename)(const char * filename); extern char * myisam_log_filename; /* Name of logfile */ extern ulong myisam_block_size; @@ -310,7 +300,7 @@ extern int mi_delete_all_rows(struct st_myisam_info *info); extern ulong _mi_calc_blob_length(uint length , const uchar *pos); extern uint mi_get_pointer_length(ulonglong file_length, uint def); -/* this is used to pass to mysql_myisamchk_table -- by Sasha Pachev */ +/* this is used to pass to mysql_myisamchk_table */ #define MYISAMCHK_REPAIR 1 /* equivalent to myisamchk -r */ #define MYISAMCHK_VERIFY 2 /* Verify, run repair if failure */ @@ -431,8 +421,8 @@ typedef struct st_mi_check_param ulonglong unique_count[MI_MAX_KEY_SEG+1]; ulonglong notnull_count[MI_MAX_KEY_SEG+1]; - ha_checksum key_crc[MI_MAX_POSSIBLE_KEY]; - ulong rec_per_key_part[MI_MAX_KEY_SEG*MI_MAX_POSSIBLE_KEY]; + ha_checksum key_crc[HA_MAX_POSSIBLE_KEY]; + ulong rec_per_key_part[MI_MAX_KEY_SEG*HA_MAX_POSSIBLE_KEY]; void *thd; const char *db_name, *table_name; const char *op_name; diff --git a/libmysql/Makefile.shared b/libmysql/Makefile.shared index 3a2559921f9..a4efd5b184f 100644 --- a/libmysql/Makefile.shared +++ b/libmysql/Makefile.shared @@ -68,7 +68,7 @@ mysysobjects1 = my_init.lo my_static.lo my_malloc.lo my_realloc.lo \ mf_iocache2.lo my_seek.lo my_sleep.lo \ my_pread.lo mf_cache.lo md5.lo sha1.lo \ my_getopt.lo my_gethostbyname.lo my_port.lo \ - my_rename.lo my_chsize.lo my_getsystime.lo + my_rename.lo my_chsize.lo my_sync.lo my_getsystime.lo sqlobjects = net.lo sql_cmn_objects = pack.lo client.lo my_time.lo diff --git a/mysys/array.c b/mysys/array.c index 8a539f18a20..f11a327232c 100644 --- a/mysys/array.c +++ b/mysys/array.c @@ -63,7 +63,8 @@ my_bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint element_size, array->size_of_element=element_size; if ((array->buffer= init_buffer)) DBUG_RETURN(FALSE); - if (!(array->buffer=(uchar*) my_malloc_ci(element_size*init_alloc,MYF(MY_WME)))) + if (!(array->buffer=(uchar*) my_malloc_ci(element_size*init_alloc, + MYF(MY_WME)))) { array->max_element=0; DBUG_RETURN(TRUE); @@ -179,7 +180,7 @@ uchar *pop_dynamic(DYNAMIC_ARRAY *array) } /* - Replace elemnent in array with given element and index + Replace element in array with given element and index SYNOPSIS set_dynamic() @@ -200,42 +201,69 @@ my_bool set_dynamic(DYNAMIC_ARRAY *array, uchar* element, uint idx) { if (idx >= array->elements) { - if (idx >= array->max_element) - { - uint size; - char *new_ptr; - size=(idx+array->alloc_increment)/array->alloc_increment; - size*= array->alloc_increment; - if (array->buffer == (uchar *)(array + 1)) - { - /* - In this senerio, the buffer is statically preallocated, - so we have to create an all-new malloc since we overflowed - */ - if (!(new_ptr= (char *) my_malloc(size * - array->size_of_element, - MYF(MY_WME)))) - return 0; - memcpy(new_ptr, array->buffer, - array->elements * array->size_of_element); - } - else - if (!(new_ptr=(char*) my_realloc(array->buffer,size* - array->size_of_element, - MYF(MY_WME | MY_ALLOW_ZERO_PTR)))) - return TRUE; - array->buffer= (uchar*) new_ptr; - array->max_element=size; - } + if (idx >= array->max_element && allocate_dynamic(array, idx)) + return TRUE; bzero((uchar*) (array->buffer+array->elements*array->size_of_element), - (idx - array->elements)*array->size_of_element); + (idx - array->elements)*array->size_of_element); array->elements=idx+1; } memcpy(array->buffer+(idx * array->size_of_element),element, - (size_t) array->size_of_element); + (size_t) array->size_of_element); + return FALSE; +} + + +/* + Ensure that dynamic array has enough elements + + SYNOPSIS + allocate_dynamic() + array + max_elements Numbers of elements that is needed + + NOTES + Any new allocated element are NOT initialized + + RETURN VALUE + FALSE Ok + TRUE Allocation of new memory failed +*/ + +my_bool allocate_dynamic(DYNAMIC_ARRAY *array, uint max_elements) +{ + if (max_elements >= array->max_element) + { + uint size; + uchar *new_ptr; + size= (max_elements + array->alloc_increment)/array->alloc_increment; + size*= array->alloc_increment; + if (array->buffer == (uchar *)(array + 1)) + { + /* + In this senerio, the buffer is statically preallocated, + so we have to create an all-new malloc since we overflowed + */ + if (!(new_ptr= (uchar *) my_malloc(size * + array->size_of_element, + MYF(MY_WME)))) + return 0; + memcpy(new_ptr, array->buffer, + array->elements * array->size_of_element); + } + else + + + if (!(new_ptr= (uchar*) my_realloc(array->buffer,size* + array->size_of_element, + MYF(MY_WME | MY_ALLOW_ZERO_PTR)))) + return TRUE; + array->buffer= new_ptr; + array->max_element= size; + } return FALSE; } + /* Get an element from array by given index diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c index 58650733490..0f49dd22bb9 100644 --- a/mysys/mf_iocache.c +++ b/mysys/mf_iocache.c @@ -1701,6 +1701,7 @@ int my_b_flush_io_cache(IO_CACHE *info, int need_append_buffer_lock) my_bool append_cache; my_off_t pos_in_file; DBUG_ENTER("my_b_flush_io_cache"); + DBUG_PRINT("enter", ("cache: 0x%lx", (long) info)); if (!(append_cache = (info->type == SEQ_READ_APPEND))) need_append_buffer_lock=0; diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c index c81da9a469a..bb9a06747b9 100644 --- a/mysys/mf_keycache.c +++ b/mysys/mf_keycache.c @@ -105,6 +105,7 @@ #include <keycache.h> #include "my_static.h" #include <m_string.h> +#include <my_bit.h> #include <errno.h> #include <stdarg.h> @@ -1262,12 +1263,12 @@ static void unlink_block(KEY_CACHE *keycache, BLOCK_LINK *block) KEYCACHE_THREAD_TRACE("unlink_block"); #if defined(KEYCACHE_DEBUG) + KEYCACHE_DBUG_ASSERT(keycache->blocks_available != 0); keycache->blocks_available--; KEYCACHE_DBUG_PRINT("unlink_block", ("unlinked block %u status=%x #requests=%u #available=%u", BLOCK_NUMBER(block), block->status, block->requests, keycache->blocks_available)); - KEYCACHE_DBUG_ASSERT(keycache->blocks_available >= 0); #endif } @@ -2360,9 +2361,9 @@ restart: (block->hash_link->diskpos == filepos))); *page_st=page_status; KEYCACHE_DBUG_PRINT("find_key_block", - ("fd: %d pos: %lu block->status: %u page_status: %u", + ("fd: %d pos: %lu block->status: %u page_status: %d", file, (ulong) filepos, block->status, - (uint) page_status)); + page_status)); #if !defined(DBUG_OFF) && defined(EXTRA_DEBUG) DBUG_EXECUTE("check_keycache2", @@ -2513,10 +2514,10 @@ static void read_block(KEY_CACHE *keycache, */ uchar *key_cache_read(KEY_CACHE *keycache, - File file, my_off_t filepos, int level, - uchar *buff, uint length, - uint block_length __attribute__((unused)), - int return_buffer __attribute__((unused))) + File file, my_off_t filepos, int level, + uchar *buff, uint length, + uint block_length __attribute__((unused)), + int return_buffer __attribute__((unused))) { my_bool locked_and_incremented= FALSE; int error=0; @@ -2534,12 +2535,12 @@ uchar *key_cache_read(KEY_CACHE *keycache, uint status; int page_st; - /* + /* When the key cache is once initialized, we use the cache_lock to reliably distinguish the cases of normal operation, resizing, and disabled cache. We always increment and decrement 'cnt_for_resize_op' so that a resizer can wait for pending I/O. - */ + */ keycache_pthread_mutex_lock(&keycache->cache_lock); /* Cache resizing has two phases: Flushing and re-initializing. In @@ -2976,9 +2977,10 @@ int key_cache_write(KEY_CACHE *keycache, int error=0; DBUG_ENTER("key_cache_write"); DBUG_PRINT("enter", - ("fd: %u pos: %lu length: %u block_length: %u key_block_length: %u", - (uint) file, (ulong) filepos, length, block_length, - keycache ? keycache->key_cache_block_size : 0)); + ("fd: %u pos: %lu length: %u block_length: %u" + " key_block_length: %u", + (uint) file, (ulong) filepos, length, block_length, + keycache ? keycache->key_cache_block_size : 0)); if (!dont_write) { @@ -3184,7 +3186,6 @@ int key_cache_write(KEY_CACHE *keycache, a flush. */ block->status&= ~BLOCK_FOR_UPDATE; - set_if_smaller(block->offset, offset); set_if_bigger(block->length, read_length+offset); diff --git a/mysys/mf_tempfile.c b/mysys/mf_tempfile.c index 9460f27b104..40016210de4 100644 --- a/mysys/mf_tempfile.c +++ b/mysys/mf_tempfile.c @@ -136,6 +136,7 @@ File create_temp_file(char *to, const char *dir, const char *prefix, if (org_file >= 0 && file < 0) { int tmp=my_errno; + close(org_file); (void) my_delete(to, MYF(MY_WME | ME_NOINPUT)); my_errno=tmp; } diff --git a/mysys/my_atomic.c b/mysys/my_atomic.c index 6a30267eb80..aa04d55f624 100644 --- a/mysys/my_atomic.c +++ b/mysys/my_atomic.c @@ -17,11 +17,10 @@ #include <my_pthread.h> #ifndef HAVE_INLINE -/* - the following will cause all inline functions to be instantiated -*/ +/* the following will cause all inline functions to be instantiated */ #define HAVE_INLINE -#define static extern +#undef STATIC_INLINE +#define STATIC_INLINE extern #endif #include <my_atomic.h> @@ -35,7 +34,7 @@ */ int my_atomic_initialize() { - DBUG_ASSERT(sizeof(intptr) == sizeof(void *)); + compile_time_assert(sizeof(intptr) == sizeof(void *)); /* currently the only thing worth checking is SMP/UP issue */ #ifdef MY_ATOMIC_MODE_DUMMY return my_getncpus() == 1 ? MY_ATOMIC_OK : MY_ATOMIC_NOT_1CPU; diff --git a/mysys/my_bit.c b/mysys/my_bit.c index 5a9b1187c83..2881eb1ebd2 100644 --- a/mysys/my_bit.c +++ b/mysys/my_bit.c @@ -13,23 +13,18 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* Some useful bit functions */ +#include <my_global.h> -#include "mysys_priv.h" - -/* - Find smallest X in 2^X >= value - This can be used to divide a number with value by doing a shift instead -*/ +#ifndef HAVE_INLINE +/* the following will cause all inline functions to be instantiated */ +#define HAVE_INLINE +#undef STATIC_INLINE +#define STATIC_INLINE extern +#endif -uint my_bit_log2(ulong value) -{ - uint bit; - for (bit=0 ; value > 1 ; value>>=1, bit++) ; - return bit; -} +#include <my_bit.h> -static char nbits[256] = { +const char _my_bits_nbits[256] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, @@ -48,60 +43,29 @@ static char nbits[256] = { 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, }; -uint my_count_bits(ulonglong v) -{ -#if SIZEOF_LONG_LONG > 4 - /* The following code is a bit faster on 16 bit machines than if we would - only shift v */ - ulong v2=(ulong) (v >> 32); - return (uint) (uchar) (nbits[(uchar) v] + - nbits[(uchar) (v >> 8)] + - nbits[(uchar) (v >> 16)] + - nbits[(uchar) (v >> 24)] + - nbits[(uchar) (v2)] + - nbits[(uchar) (v2 >> 8)] + - nbits[(uchar) (v2 >> 16)] + - nbits[(uchar) (v2 >> 24)]); -#else - return (uint) (uchar) (nbits[(uchar) v] + - nbits[(uchar) (v >> 8)] + - nbits[(uchar) (v >> 16)] + - nbits[(uchar) (v >> 24)]); -#endif -} - -uint my_count_bits_ushort(ushort v) -{ - return nbits[v]; -} - - /* - Next highest power of two - - SYNOPSIS - my_round_up_to_next_power() - v Value to check - - RETURN - Next or equal power of 2 - Note: 0 will return 0 - - NOTES - Algorithm by Sean Anderson, according to: - http://graphics.stanford.edu/~seander/bithacks.html - (Orignal code public domain) - - Comments shows how this works with 01100000000000000000000000001011 + perl -e 'print map{", 0x".unpack H2,pack B8,unpack b8,chr$_}(0..255)' */ +const uchar _my_bits_reverse_table[256]={ +0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, +0xB0, 0x70, 0xF0, 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, +0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, +0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, 0x0C, 0x8C, 0x4C, 0xCC, +0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, 0x02, +0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, +0x72, 0xF2, 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, +0xDA, 0x3A, 0xBA, 0x7A, 0xFA, 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, +0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, +0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, 0x01, 0x81, +0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, +0xF1, 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, +0x39, 0xB9, 0x79, 0xF9, 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, +0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, +0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD, 0x03, 0x83, 0x43, +0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, +0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, +0xBB, 0x7B, 0xFB, 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, +0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, +0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF +}; -uint32 my_round_up_to_next_power(uint32 v) -{ - v--; /* 01100000000000000000000000001010 */ - v|= v >> 1; /* 01110000000000000000000000001111 */ - v|= v >> 2; /* 01111100000000000000000000001111 */ - v|= v >> 4; /* 01111111110000000000000000001111 */ - v|= v >> 8; /* 01111111111111111100000000001111 */ - v|= v >> 16; /* 01111111111111111111111111111111 */ - return v+1; /* 10000000000000000000000000000000 */ -} diff --git a/mysys/my_bitmap.c b/mysys/my_bitmap.c index 10eff40b9ed..e127b2584ae 100644 --- a/mysys/my_bitmap.c +++ b/mysys/my_bitmap.c @@ -38,6 +38,7 @@ #include "mysys_priv.h" #include <my_bitmap.h> #include <m_string.h> +#include <my_bit.h> void create_last_word_mask(MY_BITMAP *map) { diff --git a/mysys/my_compress.c b/mysys/my_compress.c index bc9f8317487..0d076e77c35 100644 --- a/mysys/my_compress.c +++ b/mysys/my_compress.c @@ -181,7 +181,8 @@ int packfrm(uchar *data, size_t len, if (my_compress((uchar*)data, &org_len, &comp_len)) goto err; - DBUG_PRINT("info", ("org_len: %lu comp_len: %lu", (ulong) org_len, (ulong) comp_len)); + DBUG_PRINT("info", ("org_len: %lu comp_len: %lu", (ulong) org_len, + (ulong) comp_len)); DBUG_DUMP("compressed", data, org_len); error= 2; diff --git a/mysys/my_create.c b/mysys/my_create.c index 55878318ead..454ccf6ab7d 100644 --- a/mysys/my_create.c +++ b/mysys/my_create.c @@ -52,6 +52,13 @@ File my_create(const char *FileName, int CreateFlags, int access_flags, fd = open(FileName, access_flags); #endif + if ((MyFlags & MY_SYNC_DIR) && (fd >=0) && + my_sync_dir_by_file(FileName, MyFlags)) + { + my_close(fd, MyFlags); + fd= -1; + } + DBUG_RETURN(my_register_filename(fd, FileName, FILE_BY_CREATE, EE_CANTCREATEFILE, MyFlags)); } /* my_create */ diff --git a/mysys/my_delete.c b/mysys/my_delete.c index bac3e2513e1..14374fd3fa8 100644 --- a/mysys/my_delete.c +++ b/mysys/my_delete.c @@ -29,6 +29,9 @@ int my_delete(const char *name, myf MyFlags) my_error(EE_DELETE,MYF(ME_BELL+ME_WAITTANG+(MyFlags & ME_NOINPUT)), name,errno); } + else if ((MyFlags & MY_SYNC_DIR) && + my_sync_dir_by_file(name, MyFlags)) + err= -1; DBUG_RETURN(err); } /* my_delete */ diff --git a/mysys/my_error.c b/mysys/my_error.c index e8fd8b938ee..75701536dd3 100644 --- a/mysys/my_error.c +++ b/mysys/my_error.c @@ -84,11 +84,6 @@ int my_error(int nr, myf MyFlags, ...) if (nr <= meh_p->meh_last) break; -#ifdef SHARED_LIBRARY - if ((meh_p == &my_errmsgs_globerrs) && ! globerrs[0]) - init_glob_errs(); -#endif - /* get the error message string. Default, if NULL or empty string (""). */ if (! (format= (meh_p && (nr >= meh_p->meh_first)) ? meh_p->meh_errmsgs[nr - meh_p->meh_first] : NULL) || ! *format) diff --git a/mysys/my_handler.c b/mysys/my_handler.c index 1c3bb20426e..bf75d992f9d 100644 --- a/mysys/my_handler.c +++ b/mysys/my_handler.c @@ -16,9 +16,12 @@ MA 02111-1307, USA */ #include <my_global.h> -#include "my_handler.h" +#include <m_ctype.h> +#include <my_base.h> +#include <my_handler.h> +#include <my_sys.h> -int mi_compare_text(CHARSET_INFO *charset_info, uchar *a, uint a_length, +int ha_compare_text(CHARSET_INFO *charset_info, uchar *a, uint a_length, uchar *b, uint b_length, my_bool part_key, my_bool skip_end_space) { @@ -174,7 +177,7 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, next_key_length=key_length-b_length-pack_length; if (piks && - (flag=mi_compare_text(keyseg->charset,a,a_length,b,b_length, + (flag=ha_compare_text(keyseg->charset,a,a_length,b,b_length, (my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0), (my_bool)!(nextflag & SEARCH_PREFIX)))) @@ -187,7 +190,7 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, { uint length=(uint) (end-a), a_length=length, b_length=length; if (piks && - (flag= mi_compare_text(keyseg->charset, a, a_length, b, b_length, + (flag= ha_compare_text(keyseg->charset, a, a_length, b, b_length, (my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0), (my_bool)!(nextflag & SEARCH_PREFIX)))) @@ -235,7 +238,7 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, next_key_length=key_length-b_length-pack_length; if (piks && - (flag= mi_compare_text(keyseg->charset,a,a_length,b,b_length, + (flag= ha_compare_text(keyseg->charset,a,a_length,b,b_length, (my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0), (my_bool) ((nextflag & (SEARCH_FIND | @@ -482,12 +485,15 @@ end: DESCRIPTION Find the first NULL value in index-suffix values tuple. - TODO Consider optimizing this fuction or its use so we don't search for - NULL values in completely NOT NULL index suffixes. + + TODO + Consider optimizing this function or its use so we don't search for + NULL values in completely NOT NULL index suffixes. RETURN - First key part that has NULL as value in values tuple, or the last key part - (with keyseg->type==HA_TYPE_END) if values tuple doesn't contain NULLs. + First key part that has NULL as value in values tuple, or the last key + part (with keyseg->type==HA_TYPE_END) if values tuple doesn't contain + NULLs. */ HA_KEYSEG *ha_find_null(HA_KEYSEG *keyseg, uchar *a) @@ -557,3 +563,69 @@ HA_KEYSEG *ha_find_null(HA_KEYSEG *keyseg, uchar *a) } return keyseg; } + + +/* + Errors a handler can give you +*/ + +static const char *handler_error_messages[]= +{ + "Didn't find key on read or update", + "Duplicate key on write or update", + "Undefined handler error 122", + "Someone has changed the row since it was read (while the table was locked to prevent it)", + "Wrong index given to function", + "Undefined handler error 125", + "Index file is crashed", + "Record file is crashed", + "Out of memory in engine", + "Undefined handler error 129", + "Incorrect file format", + "Command not supported by database", + "Old database file", + "No record read before update", + "Record was already deleted (or record file crashed)", + "No more room in record file", + "No more room in index file", + "No more records (read after end of file)", + "Unsupported extension used for table", + "Too big row", + "Wrong create options", + "Duplicate unique key or constraint on write or update", + "Unknown character set used in table", + "Conflicting table definitions in sub-tables of MERGE table", + "Table is crashed and last repair failed", + "Table was marked as crashed and should be repaired", + "Lock timed out; Retry transaction", + "Lock table is full; Restart program with a larger locktable", + "Updates are not allowed under a read only transactions", + "Lock deadlock; Retry transaction", + "Foreign key constraint is incorrectly formed", + "Cannot add a child row", + "Cannot delete a parent row", + "Unknown handler error" +}; + + +/* + Register handler error messages for usage with my_error() + + NOTES + This is safe to call multiple times as my_error_register() + will ignore calls to register already registered error numbers. +*/ + + +void my_handler_error_register(void) +{ + my_error_register(handler_error_messages, HA_ERR_FIRST, + HA_ERR_FIRST+ array_elements(handler_error_messages)-1); +} + + +void my_handler_error_unregister(void) +{ + my_error_unregister(HA_ERR_FIRST, + HA_ERR_FIRST+ array_elements(handler_error_messages)-1); +} diff --git a/mysys/my_init.c b/mysys/my_init.c index b2eefe97ee8..607cba77140 100644 --- a/mysys/my_init.c +++ b/mysys/my_init.c @@ -43,6 +43,7 @@ static void netware_init(); my_bool my_init_done= 0; uint mysys_usage_id= 0; /* Incremented for each my_init() */ +ulong my_thread_stack_size= 65536; static ulong atoi_octal(const char *str) { @@ -76,6 +77,7 @@ my_bool my_init(void) mysys_usage_id++; my_umask= 0660; /* Default umask for new files */ my_umask_dir= 0700; /* Default umask for new directories */ + init_glob_errs(); #if defined(THREAD) && defined(SAFE_MUTEX) safe_mutex_global_init(); /* Must be called early */ #endif @@ -343,6 +345,30 @@ static void my_win_init(void) _tzset(); + /* The following is used by time functions */ +#define OFFSET_TO_EPOC ((__int64) 134774 * 24 * 60 * 60 * 1000 * 1000 * 10) +#define MS 10000000 + { + FILETIME ft; + LARGE_INTEGER li, t_cnt; + DBUG_ASSERT(sizeof(LARGE_INTEGER) == sizeof(query_performance_frequency)); + if (QueryPerformanceFrequency((LARGE_INTEGER *)&query_performance_frequency) == 0) + query_performance_frequency= 0; + else + { + GetSystemTimeAsFileTime(&ft); + li.LowPart= ft.dwLowDateTime; + li.HighPart= ft.dwHighDateTime; + query_performance_offset= li.QuadPart-OFFSET_TO_EPOC; + QueryPerformanceCounter(&t_cnt); + query_performance_offset-= (t_cnt.QuadPart / + query_performance_frequency * MS + + t_cnt.QuadPart % + query_performance_frequency * MS / + query_performance_frequency); + } + } + /* apre la chiave HKEY_LOCAL_MACHINES\software\MySQL */ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,(LPCTSTR)targetKey,0, KEY_READ,&hSoftMysql) != ERROR_SUCCESS) @@ -380,27 +406,6 @@ static void my_win_init(void) /* chiude la chiave */ RegCloseKey(hSoftMysql) ; - /* The following is used by time functions */ -#define OFFSET_TO_EPOC ((__int64) 134774 * 24 * 60 * 60 * 1000 * 1000 * 10) -#define MS 10000000 - { - FILETIME ft; - LARGE_INTEGER li, t_cnt; - DBUG_ASSERT(sizeof(LARGE_INTEGER) == sizeof(query_performance_frequency)); - if (QueryPerformanceFrequency((LARGE_INTEGER *)&query_performance_frequency)) - query_performance_frequency= 0; - else - { - GetSystemTimeAsFileTime(&ft); - li.LowPart= ft.dwLowDateTime; - li.HighPart= ft.dwHighDateTime; - query_performance_offset= li.QuadPart-OFFSET_TO_EPOC; - QueryPerformanceCounter(&t_cnt); - query_performance_offset-= (t_cnt.QuadPart / query_performance_frequency * MS + - t_cnt.QuadPart % query_performance_frequency * MS / - query_performance_frequency); - } - } DBUG_VOID_RETURN ; } diff --git a/mysys/my_open.c b/mysys/my_open.c index 938dbc5dde2..fe7f65c450b 100644 --- a/mysys/my_open.c +++ b/mysys/my_open.c @@ -71,6 +71,7 @@ File my_open(const char *FileName, int Flags, myf MyFlags) #else fd = open((char *) FileName, Flags); #endif + DBUG_RETURN(my_register_filename(fd, FileName, FILE_BY_OPEN, EE_FILENOTFOUND, MyFlags)); } /* my_open */ @@ -124,61 +125,66 @@ int my_close(File fd, myf MyFlags) SYNOPSIS my_register_filename() - fd - FileName - type_file_type + fd File number opened, -1 if error on open + FileName File name + type_file_type How file was created + error_message_number Error message number if caller got error (fd == -1) + MyFlags Flags for my_close() + + RETURN + -1 error + # Filenumber + */ File my_register_filename(File fd, const char *FileName, enum file_type type_of_file, uint error_message_number, myf MyFlags) { + DBUG_ENTER("my_register_filename"); if ((int) fd >= 0) { if ((uint) fd >= my_file_limit) { #if defined(THREAD) && !defined(HAVE_PREAD) - (void) my_close(fd,MyFlags); - my_errno=EMFILE; - if (MyFlags & (MY_FFNF | MY_FAE | MY_WME)) - my_error(EE_OUT_OF_FILERESOURCES, MYF(ME_BELL+ME_WAITTANG), - FileName, my_errno); - return(-1); -#endif + my_errno= EMFILE; +#else thread_safe_increment(my_file_opened,&THR_LOCK_open); - return(fd); /* safeguard */ + DBUG_RETURN(fd); /* safeguard */ +#endif } - pthread_mutex_lock(&THR_LOCK_open); - if ((my_file_info[fd].name = (char*) my_strdup(FileName,MyFlags))) + else { - my_file_opened++; - my_file_total_opened++; - my_file_info[fd].type = type_of_file; + pthread_mutex_lock(&THR_LOCK_open); + if ((my_file_info[fd].name = (char*) my_strdup(FileName,MyFlags))) + { + my_file_opened++; + my_file_total_opened++; + my_file_info[fd].type = type_of_file; #if defined(THREAD) && !defined(HAVE_PREAD) - pthread_mutex_init(&my_file_info[fd].mutex,MY_MUTEX_INIT_FAST); + pthread_mutex_init(&my_file_info[fd].mutex,MY_MUTEX_INIT_FAST); #endif + pthread_mutex_unlock(&THR_LOCK_open); + DBUG_PRINT("exit",("fd: %d",fd)); + DBUG_RETURN(fd); + } pthread_mutex_unlock(&THR_LOCK_open); - DBUG_PRINT("exit",("fd: %d",fd)); - return(fd); + my_errno= ENOMEM; } - pthread_mutex_unlock(&THR_LOCK_open); (void) my_close(fd, MyFlags); - my_errno=ENOMEM; } else - my_errno=errno; - DBUG_PRINT("error",("Got error %d on open",my_errno)); - if (MyFlags & (MY_FFNF | MY_FAE | MY_WME)) { - if (my_errno == EMFILE) { - DBUG_PRINT("error",("print err: %d",EE_OUT_OF_FILERESOURCES)); - my_error(EE_OUT_OF_FILERESOURCES, MYF(ME_BELL+ME_WAITTANG), - FileName, my_errno); - } else { - DBUG_PRINT("error",("print err: %d",error_message_number)); - my_error(error_message_number, MYF(ME_BELL+ME_WAITTANG), - FileName, my_errno); - } + my_errno= errno; + + DBUG_PRINT("error",("Got error %d on open", my_errno)); + if (MyFlags & (MY_FFNF | MY_FAE | MY_WME)) + { + if (my_errno == EMFILE) + error_message_number= EE_OUT_OF_FILERESOURCES; + DBUG_PRINT("error",("print err: %d",error_message_number)); + my_error(error_message_number, MYF(ME_BELL+ME_WAITTANG), + FileName, my_errno); } - return(fd); + DBUG_RETURN(-1); } #ifdef __WIN__ diff --git a/mysys/my_pread.c b/mysys/my_pread.c index 6e98132db73..de7a2b611ed 100644 --- a/mysys/my_pread.c +++ b/mysys/my_pread.c @@ -63,12 +63,12 @@ size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset, pthread_mutex_unlock(&my_file_info[Filedes].mutex); #else if ((error= ((readbytes= pread(Filedes, Buffer, Count, offset)) != Count))) - my_errno= errno; + my_errno= errno ? errno : -1; #endif if (error || readbytes != Count) { DBUG_PRINT("warning",("Read only %d bytes off %u from %d, errno: %d", - (int) readbytes, (uint) Count,Filedes,my_errno)); + (int) readbytes, (uint) Count,Filedes,my_errno)); #ifdef THREAD if ((readbytes == 0 || readbytes == (size_t) -1) && errno == EINTR) { @@ -115,7 +115,7 @@ size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset, RETURN (size_t) -1 Error # Number of bytes read - */ +*/ size_t my_pwrite(int Filedes, const uchar *Buffer, size_t Count, my_off_t offset, myf MyFlags) diff --git a/mysys/my_realloc.c b/mysys/my_realloc.c index c7cf1323cd4..a55282e03a0 100644 --- a/mysys/my_realloc.c +++ b/mysys/my_realloc.c @@ -22,6 +22,16 @@ /* My memory re allocator */ +/** + @brief wrapper around realloc() + + @param oldpoint pointer to currently allocated area + @param size new size requested, must be >0 + @param my_flags flags + + @note if size==0 realloc() may return NULL; my_realloc() treats this as an + error which is not the intention of realloc() +*/ void* my_realloc(void* oldpoint, size_t size, myf my_flags) { void *point; @@ -29,6 +39,7 @@ void* my_realloc(void* oldpoint, size_t size, myf my_flags) DBUG_PRINT("my",("ptr: 0x%lx size: %lu my_flags: %d", (long) oldpoint, (ulong) size, my_flags)); + DBUG_ASSERT(size > 0); if (!oldpoint && (my_flags & MY_ALLOW_ZERO_PTR)) DBUG_RETURN(my_malloc(size,my_flags)); #ifdef USE_HALLOC diff --git a/mysys/my_rename.c b/mysys/my_rename.c index 6a6aa6a5796..39e6056a9e4 100644 --- a/mysys/my_rename.c +++ b/mysys/my_rename.c @@ -16,8 +16,9 @@ #include "mysys_priv.h" #include <my_dir.h> #include "mysys_err.h" - +#include "m_string.h" #undef my_rename + /* On unix rename deletes to file if it exists */ int my_rename(const char *from, const char *to, myf MyFlags) @@ -60,5 +61,19 @@ int my_rename(const char *from, const char *to, myf MyFlags) if (MyFlags & (MY_FAE+MY_WME)) my_error(EE_LINK, MYF(ME_BELL+ME_WAITTANG),from,to,my_errno); } + else if (MyFlags & MY_SYNC_DIR) + { +#ifdef NEED_EXPLICIT_SYNC_DIR + /* do only the needed amount of syncs: */ + char dir_from[FN_REFLEN], dir_to[FN_REFLEN]; + size_t dir_from_length, dir_to_length; + dirname_part(dir_from, from, &dir_from_length); + dirname_part(dir_to, to, &dir_to_length); + if (my_sync_dir(dir_from, MyFlags) || + (strcmp(dir_from, dir_to) && + my_sync_dir(dir_to, MyFlags))) + error= -1; +#endif + } DBUG_RETURN(error); } /* my_rename */ diff --git a/mysys/my_symlink.c b/mysys/my_symlink.c index 810c0c72632..98059ccd508 100644 --- a/mysys/my_symlink.c +++ b/mysys/my_symlink.c @@ -84,6 +84,8 @@ int my_symlink(const char *content, const char *linkname, myf MyFlags) if (MyFlags & MY_WME) my_error(EE_CANT_SYMLINK, MYF(0), linkname, content, errno); } + else if ((MyFlags & MY_SYNC_DIR) && my_sync_dir_by_file(linkname, MyFlags)) + result= -1; DBUG_RETURN(result); #endif /* HAVE_READLINK */ } diff --git a/mysys/my_sync.c b/mysys/my_sync.c index 64fce3aac21..ba6964b00d6 100644 --- a/mysys/my_sync.c +++ b/mysys/my_sync.c @@ -48,6 +48,16 @@ int my_sync(File fd, myf my_flags) do { +#if defined(F_FULLFSYNC) + /* + In Mac OS X >= 10.3 this call is safer than fsync() (it forces the + disk's cache and guarantees ordered writes). + */ + if (!(res= fcntl(fd, F_FULLFSYNC, 0))) + break; /* ok */ + /* Some file systems don't support F_FULLFSYNC and fail above: */ + DBUG_PRINT("info",("fcntl(F_FULLFSYNC) failed, falling back")); +#endif #if defined(HAVE_FDATASYNC) res= fdatasync(fd); #elif defined(HAVE_FSYNC) @@ -55,6 +65,7 @@ int my_sync(File fd, myf my_flags) #elif defined(__WIN__) res= _commit(fd); #else +#error Cannot find a way to sync a file, durability in danger res= 0; /* No sync (strange OS) */ #endif } while (res == -1 && errno == EINTR); @@ -66,10 +77,79 @@ int my_sync(File fd, myf my_flags) my_errno= -1; /* Unknown error */ if ((my_flags & MY_IGNORE_BADFD) && (er == EBADF || er == EINVAL || er == EROFS)) + { + DBUG_PRINT("info", ("ignoring errno %d", er)); res= 0; + } else if (my_flags & MY_WME) my_error(EE_SYNC, MYF(ME_BELL+ME_WAITTANG), my_filename(fd), my_errno); } DBUG_RETURN(res); } /* my_sync */ + +static const char cur_dir_name[]= {FN_CURLIB, 0}; +/* + Force directory information to disk. + + SYNOPSIS + my_sync_dir() + dir_name the name of the directory + my_flags flags (MY_WME etc) + + RETURN + 0 if ok, !=0 if error +*/ +int my_sync_dir(const char *dir_name, myf my_flags) +{ +#ifdef NEED_EXPLICIT_SYNC_DIR + DBUG_ENTER("my_sync_dir"); + DBUG_PRINT("my",("Dir: '%s' my_flags: %d", dir_name, my_flags)); + File dir_fd; + int res= 0; + const char *correct_dir_name; + /* Sometimes the path does not contain an explicit directory */ + correct_dir_name= (dir_name[0] == 0) ? cur_dir_name : dir_name; + /* + Syncing a dir may give EINVAL on tmpfs on Linux, which is ok. + EIO on the other hand is very important. Hence MY_IGNORE_BADFD. + */ + if ((dir_fd= my_open(correct_dir_name, O_RDONLY, MYF(my_flags))) >= 0) + { + if (my_sync(dir_fd, MYF(my_flags | MY_IGNORE_BADFD))) + res= 2; + if (my_close(dir_fd, MYF(my_flags))) + res= 3; + } + else + res= 1; + DBUG_RETURN(res); +#else + return 0; +#endif +} + + +/* + Force directory information to disk. + + SYNOPSIS + my_sync_dir_by_file() + file_name the name of a file in the directory + my_flags flags (MY_WME etc) + + RETURN + 0 if ok, !=0 if error +*/ +int my_sync_dir_by_file(const char *file_name, myf my_flags) +{ +#ifdef NEED_EXPLICIT_SYNC_DIR + char dir_name[FN_REFLEN]; + size_t dir_name_length; + dirname_part(dir_name, file_name, &dir_name_length); + return my_sync_dir(dir_name, my_flags); +#else + return 0; +#endif +} + diff --git a/mysys/safemalloc.c b/mysys/safemalloc.c index 7a2f448b2dc..a7a7bcc9c53 100644 --- a/mysys/safemalloc.c +++ b/mysys/safemalloc.c @@ -430,6 +430,29 @@ void TERMINATE(FILE *file, uint flag) } +/* + Report where a piece of memory was allocated + + This is usefull to call from withing a debugger +*/ + + +void sf_malloc_report_allocated(void *memory) +{ + struct st_irem *irem; + for (irem= sf_malloc_root ; irem ; irem=irem->next) + { + char *data= (((char*) irem) + ALIGN_SIZE(sizeof(struct st_irem)) + + sf_malloc_prehunc); + if (data <= (char*) memory && (char*) memory <= data + irem->datasize) + { + printf("%u bytes at 0x%lx, allocated at line %u in '%s'\n", + irem->datasize, (long) data, irem->linenum, irem->filename); + break; + } + } +} + /* Returns 0 if chunk is ok */ static int _checkchunk(register struct st_irem *irem, const char *filename, diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc index 36b7f30dc64..18f80e11a15 100644 --- a/sql/gen_lex_hash.cc +++ b/sql/gen_lex_hash.cc @@ -481,8 +481,8 @@ int main(int argc,char **argv) printf("\nstatic unsigned int symbols_max_len=%d;\n\n", max_len2); printf("\ -static inline SYMBOL *get_hash_symbol(const char *s,\n\ - unsigned int len,bool function)\n\ +static SYMBOL *get_hash_symbol(const char *s,\n\ + unsigned int len,bool function)\n\ {\n\ register uchar *hash_map;\n\ register const char *cur_str= s;\n\ diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 200e8a97c67..a57f1d24758 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -4701,11 +4701,14 @@ void ha_partition::get_dynamic_partition_info(PARTITION_INFO *stat_info, about this call). We pass this along to all underlying MyISAM handlers and ignore it for the rest. - HA_EXTRA_PREPARE_FOR_DELETE: + HA_EXTRA_PREPARE_FOR_DROP: Only used by MyISAM, called in preparation for a DROP TABLE. It's used mostly by Windows that cannot handle dropping an open file. On other platforms it has the same effect as HA_EXTRA_FORCE_REOPEN. + HA_EXTRA_PREPARE_FOR_RENAME: + Informs the handler we are about to attempt a rename of the table. + HA_EXTRA_READCHECK: HA_EXTRA_NO_READCHECK: Only one call to HA_EXTRA_NO_READCHECK from ha_open where it says that @@ -4831,14 +4834,15 @@ int ha_partition::extra(enum ha_extra_function operation) } /* Category 3), used by MyISAM handlers */ - case HA_EXTRA_PREPARE_FOR_DELETE: - DBUG_RETURN(prepare_for_delete()); + case HA_EXTRA_PREPARE_FOR_RENAME: + DBUG_RETURN(prepare_for_rename()); break; case HA_EXTRA_NORMAL: case HA_EXTRA_QUICK: case HA_EXTRA_NO_READCHECK: case HA_EXTRA_PREPARE_FOR_UPDATE: case HA_EXTRA_FORCE_REOPEN: + case HA_EXTRA_PREPARE_FOR_DROP: case HA_EXTRA_FLUSH_CACHE: { if (m_myisam) @@ -4990,24 +4994,24 @@ void ha_partition::prepare_extra_cache(uint cachesize) 0 Success */ -int ha_partition::prepare_for_delete() +int ha_partition::prepare_for_rename() { int result= 0, tmp; handler **file; - DBUG_ENTER("ha_partition::prepare_for_delete()"); + DBUG_ENTER("ha_partition::prepare_for_rename()"); if (m_new_file != NULL) { for (file= m_new_file; *file; file++) - if ((tmp= (*file)->extra(HA_EXTRA_PREPARE_FOR_DELETE))) + if ((tmp= (*file)->extra(HA_EXTRA_PREPARE_FOR_RENAME))) result= tmp; for (file= m_reorged_file; *file; file++) - if ((tmp= (*file)->extra(HA_EXTRA_PREPARE_FOR_DELETE))) + if ((tmp= (*file)->extra(HA_EXTRA_PREPARE_FOR_RENAME))) result= tmp; DBUG_RETURN(result); } - DBUG_RETURN(loop_extra(HA_EXTRA_PREPARE_FOR_DELETE)); + DBUG_RETURN(loop_extra(HA_EXTRA_PREPARE_FOR_RENAME)); } /* diff --git a/sql/ha_partition.h b/sql/ha_partition.h index 9d10aea2b6f..ac00581fae0 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -211,7 +211,7 @@ public: } virtual void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share); private: - int prepare_for_delete(); + int prepare_for_rename(); int copy_partitions(ulonglong *copied, ulonglong *deleted); void cleanup_new_partition(uint part_count); int prepare_new_partition(TABLE *table, HA_CREATE_INFO *create_info, diff --git a/sql/handler.cc b/sql/handler.cc index 9e47baadd4a..5b121ac258a 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -290,7 +290,8 @@ handler *get_ha_partition(partition_info *part_info) 0 OK != 0 Error */ -static int ha_init_errors(void) + +int ha_init_errors(void) { #define SETMSG(nr, msg) errmsgs[(nr) - HA_ERR_FIRST]= (msg) const char **errmsgs; @@ -505,9 +506,6 @@ int ha_init() int error= 0; DBUG_ENTER("ha_init"); - if (ha_init_errors()) - DBUG_RETURN(1); - DBUG_ASSERT(total_ha < MAX_HA); /* Check if there is a transaction-capable storage engine besides the @@ -2505,8 +2503,7 @@ int ha_enable_transaction(THD *thd, bool on) DBUG_ENTER("ha_enable_transaction"); DBUG_PRINT("enter", ("on: %d", (int) on)); - thd->transaction.on= on; - if (on) + if ((thd->transaction.on= on)) { /* Now all storage engines should have transaction handling enabled. diff --git a/sql/handler.h b/sql/handler.h index b91d8a39b88..6b3975351a1 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -20,6 +20,7 @@ #pragma interface /* gcc class implementation */ #endif +#include <my_handler.h> #include <ft_global.h> #include <keycache.h> @@ -272,6 +273,7 @@ enum legacy_db_type DB_TYPE_TABLE_FUNCTION, DB_TYPE_MEMCACHE, DB_TYPE_FALCON, + DB_TYPE_MARIA, DB_TYPE_FIRST_DYNAMIC=42, DB_TYPE_DEFAULT=127 // Must be last }; @@ -322,6 +324,7 @@ enum enum_binlog_command { #define HA_CREATE_USED_CONNECTION (1L << 18) #define HA_CREATE_USED_KEY_BLOCK_SIZE (1L << 19) #define HA_CREATE_USED_TRANSACTIONAL (1L << 20) +#define HA_CREATE_USED_PAGE_CHECKSUM (1L << 21) typedef ulonglong my_xid; // this line is the same as in log_event.h #define MYSQL_XID_PREFIX "MySQLXid" @@ -818,6 +821,7 @@ typedef struct st_ha_create_information bool frm_only; /* 1 if no ha_create_table() */ bool varchar; /* 1 if table has a VARCHAR */ enum ha_storage_media storage_media; /* DEFAULT, DISK or MEMORY */ + enum ha_choice page_checksum; /* If we have page_checksums */ } HA_CREATE_INFO; @@ -1851,6 +1855,7 @@ static inline bool ha_storage_engine_is_enabled(const handlerton *db_type) } /* basic stuff */ +int ha_init_errors(void); int ha_init(void); int ha_end(void); int ha_initialize_handlerton(st_plugin_int *plugin); diff --git a/sql/item_func.cc b/sql/item_func.cc index efc42c1b73f..8891838bb2a 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -27,6 +27,7 @@ #include <hash.h> #include <time.h> #include <ft_global.h> +#include <my_bit.h> #include "sp_head.h" #include "sp_rcontext.h" diff --git a/sql/lex.h b/sql/lex.h index e311379120d..aab2182b097 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -380,6 +380,8 @@ static SYMBOL symbols[] = { { "OWNER", SYM(OWNER_SYM)}, { "PACK_KEYS", SYM(PACK_KEYS_SYM)}, { "PARSER", SYM(PARSER_SYM)}, + { "PAGE", SYM(PAGE_SYM)}, + { "PAGE_CHECKSUM", SYM(PAGE_CHECKSUM_SYM)}, { "PARTIAL", SYM(PARTIAL)}, { "PARTITION", SYM(PARTITION_SYM)}, { "PARTITIONING", SYM(PARTITIONING_SYM)}, @@ -512,7 +514,8 @@ static SYMBOL symbols[] = { { "SUSPEND", SYM(SUSPEND_SYM)}, { "TABLE", SYM(TABLE_SYM)}, { "TABLES", SYM(TABLES)}, - { "TABLESPACE", SYM(TABLESPACE)}, + { "TABLESPACE", SYM(TABLESPACE)}, + { "TABLE_CHECKSUM", SYM(TABLE_CHECKSUM_SYM)}, { "TEMPORARY", SYM(TEMPORARY)}, { "TEMPTABLE", SYM(TEMPTABLE_SYM)}, { "TERMINATED", SYM(TERMINATED)}, @@ -529,6 +532,7 @@ static SYMBOL symbols[] = { { "TO", SYM(TO_SYM)}, { "TRAILING", SYM(TRAILING)}, { "TRANSACTION", SYM(TRANSACTION_SYM)}, + { "TRANSACTIONAL", SYM(TRANSACTIONAL_SYM)}, { "TRIGGER", SYM(TRIGGER_SYM)}, { "TRIGGERS", SYM(TRIGGERS_SYM)}, { "TRUE", SYM(TRUE_SYM)}, diff --git a/sql/log.cc b/sql/log.cc index 95204e89d0e..f8c78b03228 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -2270,6 +2270,11 @@ bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg, my_seek(index_file_nr,0L,MY_SEEK_END,MYF(0)), 0, MYF(MY_WME | MY_WAIT_IF_FULL))) { + /* + TODO: all operations creating/deleting the index file or a log, should + call my_sync_dir() or my_sync_dir_by_file() to be durable. + TODO: file creation should be done with my_create() not my_open(). + */ if (index_file_nr >= 0) my_close(index_file_nr,MYF(0)); return TRUE; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 47a42354423..4aa574e5d47 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1760,7 +1760,7 @@ extern ulong max_connections,max_connect_errors, connect_timeout; extern ulong slave_net_timeout, slave_trans_retries; extern uint max_user_connections; extern ulong what_to_log,flush_time; -extern ulong query_buff_size, thread_stack; +extern ulong query_buff_size; extern ulong max_prepared_stmt_count, prepared_stmt_count; extern ulong binlog_cache_size, max_binlog_cache_size, open_files_limit; extern ulong max_binlog_size, max_relay_log_size; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 6ea1cf111bb..c02fdc85d32 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -16,6 +16,7 @@ #include "mysql_priv.h" #include <m_ctype.h> #include <my_dir.h> +#include <my_bit.h> #include "slave.h" #include "rpl_mi.h" #include "sql_repl.h" @@ -441,7 +442,7 @@ uint volatile thread_count, thread_running; ulonglong thd_startup_options; ulong back_log, connect_timeout, concurrency, server_id; ulong table_cache_size, table_def_size; -ulong thread_stack, what_to_log; +ulong what_to_log; ulong query_buff_size, slow_launch_time, slave_open_temp_tables; ulong open_files_limit, max_binlog_size, max_relay_log_size; ulong slave_net_timeout, slave_trans_retries; @@ -2194,7 +2195,7 @@ or misconfigured. This error can also be caused by malfunctioning hardware.\n", We will try our best to scrape up some info that will hopefully help diagnose\n\ the problem, but since we have already crashed, something is definitely wrong\n\ and this may fail.\n\n"); - fprintf(stderr, "key_buffer_size=%lu\n", + fprintf(stderr, "key_buffer_size=%lu\n", (ulong) dflt_key_cache->key_cache_mem_size); fprintf(stderr, "read_buffer_size=%ld\n", (long) global_system_variables.read_buff_size); fprintf(stderr, "max_used_connections=%lu\n", max_used_connections); @@ -2226,7 +2227,7 @@ the thread stack. Please read http://www.mysql.com/doc/en/Linux.html\n\n", { fprintf(stderr,"thd: 0x%lx\n",(long) thd); print_stacktrace(thd ? (uchar*) thd->thread_stack : (uchar*) 0, - thread_stack); + my_thread_stack_size); } if (thd) { @@ -2385,9 +2386,9 @@ static void start_signal_handler(void) Peculiar things with ia64 platforms - it seems we only have half the stack size in reality, so we have to double it here */ - pthread_attr_setstacksize(&thr_attr,thread_stack*2); + pthread_attr_setstacksize(&thr_attr,my_thread_stack_size*2); #else - pthread_attr_setstacksize(&thr_attr,thread_stack); + pthread_attr_setstacksize(&thr_attr,my_thread_stack_size); #endif #endif @@ -3397,6 +3398,13 @@ server."); using_update_log=1; } + /* call ha_init_key_cache() on all key caches to init them */ + process_key_caches(&ha_init_key_cache); + + /* Allow storage engine to give real error messages */ + if (ha_init_errors()) + DBUG_RETURN(1); + if (plugin_init(&defaults_argc, defaults_argv, (opt_noacl ? PLUGIN_INIT_SKIP_PLUGIN_TABLE : 0) | (opt_help ? PLUGIN_INIT_SKIP_INITIALIZATION : 0))) @@ -3563,9 +3571,6 @@ server."); if (opt_myisam_log) (void) mi_log(1); - /* call ha_init_key_cache() on all key caches to init them */ - process_key_caches(&ha_init_key_cache); - #if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) && !defined(EMBEDDED_LIBRARY) if (locked_in_memory && !getuid()) { @@ -3755,9 +3760,9 @@ int main(int argc, char **argv) Peculiar things with ia64 platforms - it seems we only have half the stack size in reality, so we have to double it here */ - pthread_attr_setstacksize(&connection_attrib,thread_stack*2); + pthread_attr_setstacksize(&connection_attrib,my_thread_stack_size*2); #else - pthread_attr_setstacksize(&connection_attrib,thread_stack); + pthread_attr_setstacksize(&connection_attrib,my_thread_stack_size); #endif #ifdef HAVE_PTHREAD_ATTR_GETSTACKSIZE { @@ -3768,15 +3773,15 @@ int main(int argc, char **argv) stack_size/= 2; #endif /* We must check if stack_size = 0 as Solaris 2.9 can return 0 here */ - if (stack_size && stack_size < thread_stack) + if (stack_size && stack_size < my_thread_stack_size) { if (global_system_variables.log_warnings) sql_print_warning("Asked for %lu thread stack, but got %ld", - thread_stack, (long) stack_size); + my_thread_stack_size, (long) stack_size); #if defined(__ia64__) || defined(__ia64) - thread_stack= stack_size*2; + my_thread_stack_size= stack_size*2; #else - thread_stack= stack_size; + my_thread_stack_size= stack_size; #endif } } @@ -5022,7 +5027,7 @@ enum options_mysqld OPT_MAX_ERROR_COUNT, OPT_MULTI_RANGE_COUNT, OPT_MYISAM_DATA_POINTER_SIZE, OPT_MYISAM_BLOCK_SIZE, OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE, OPT_MYISAM_MAX_SORT_FILE_SIZE, OPT_MYISAM_SORT_BUFFER_SIZE, - OPT_MYISAM_USE_MMAP, + OPT_MYISAM_USE_MMAP, OPT_MYISAM_REPAIR_THREADS, OPT_MYISAM_STATS_METHOD, OPT_NET_BUFFER_LENGTH, OPT_NET_RETRY_COUNT, OPT_NET_READ_TIMEOUT, OPT_NET_WRITE_TIMEOUT, @@ -5037,7 +5042,7 @@ enum options_mysqld OPT_SORT_BUFFER, OPT_TABLE_OPEN_CACHE, OPT_TABLE_DEF_CACHE, OPT_THREAD_CONCURRENCY, OPT_THREAD_CACHE_SIZE, OPT_TMP_TABLE_SIZE, OPT_THREAD_STACK, - OPT_WAIT_TIMEOUT, OPT_MYISAM_REPAIR_THREADS, + OPT_WAIT_TIMEOUT, OPT_ERROR_LOG_FILE, OPT_DEFAULT_WEEK_FORMAT, OPT_RANGE_ALLOC_BLOCK_SIZE, OPT_ALLOW_SUSPICIOUS_UDFS, @@ -6193,10 +6198,10 @@ The minimum value for this variable is 4096.", (uchar**) &opt_plugin_load, (uchar**) &opt_plugin_load, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"preload_buffer_size", OPT_PRELOAD_BUFFER_SIZE, - "The size of the buffer that is allocated when preloading indexes", - (uchar**) &global_system_variables.preload_buff_size, - (uchar**) &max_system_variables.preload_buff_size, 0, GET_ULONG, - REQUIRED_ARG, 32*1024L, 1024, 1024*1024*1024L, 0, 1, 0}, + "The size of the buffer that is allocated when preloading indexes", + (uchar**) &global_system_variables.preload_buff_size, + (uchar**) &max_system_variables.preload_buff_size, 0, GET_ULONG, + REQUIRED_ARG, 32*1024L, 1024, 1024*1024*1024L, 0, 1, 0}, {"query_alloc_block_size", OPT_QUERY_ALLOC_BLOCK_SIZE, "Allocation block size for query parsing and execution", (uchar**) &global_system_variables.query_alloc_block_size, @@ -6339,8 +6344,8 @@ The minimum value for this variable is 4096.", REQUIRED_ARG, 20, 1, 16384, 0, 1, 0}, #endif {"thread_stack", OPT_THREAD_STACK, - "The stack size for each thread.", (uchar**) &thread_stack, - (uchar**) &thread_stack, 0, GET_ULONG, REQUIRED_ARG,DEFAULT_THREAD_STACK, + "The stack size for each thread.", (uchar**) &my_thread_stack_size, + (uchar**) &my_thread_stack_size, 0, GET_ULONG, REQUIRED_ARG,DEFAULT_THREAD_STACK, 1024L*128L, ~0L, 0, 1024, 0}, { "time_format", OPT_TIME_FORMAT, "The TIME format (for future).", @@ -6354,12 +6359,12 @@ The minimum value for this variable is 4096.", (uchar**) &max_system_variables.tmp_table_size, 0, GET_ULL, REQUIRED_ARG, 16*1024*1024L, 1024, MAX_MEM_TABLE_SIZE, 0, 1, 0}, {"transaction_alloc_block_size", OPT_TRANS_ALLOC_BLOCK_SIZE, - "Allocation block size for various transaction-related structures", + "Allocation block size for transactions to be stored in binary log", (uchar**) &global_system_variables.trans_alloc_block_size, (uchar**) &max_system_variables.trans_alloc_block_size, 0, GET_ULONG, REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ~0L, 0, 1024, 0}, {"transaction_prealloc_size", OPT_TRANS_PREALLOC_SIZE, - "Persistent buffer for various transaction-related structures", + "Persistent buffer for transactions to be stored in binary log", (uchar**) &global_system_variables.trans_prealloc_size, (uchar**) &max_system_variables.trans_prealloc_size, 0, GET_ULONG, REQUIRED_ARG, TRANS_ALLOC_PREALLOC_SIZE, 1024, ~0L, 0, 1024, 0}, @@ -6889,6 +6894,7 @@ SHOW_VAR status_vars[]= { {"Open_tables", (char*) &show_open_tables, SHOW_FUNC}, {"Opened_files", (char*) &my_file_total_opened, SHOW_LONG_NOFLUSH}, {"Opened_tables", (char*) offsetof(STATUS_VAR, opened_tables), SHOW_LONG_STATUS}, + {"Opened_table_definitions", (char*) offsetof(STATUS_VAR, opened_shares), SHOW_LONG_STATUS}, {"Prepared_stmt_count", (char*) &show_prepared_stmt_count, SHOW_FUNC}, #ifdef HAVE_QUERY_CACHE {"Qcache_free_blocks", (char*) &query_cache.free_memory_blocks, SHOW_LONG_NOFLUSH}, @@ -7112,9 +7118,10 @@ static void mysql_init_variables(void) thread_cache.empty(); key_caches.empty(); if (!(dflt_key_cache= get_or_create_key_cache(default_key_cache_base.str, - default_key_cache_base.length))) + default_key_cache_base.length))) exit(1); - multi_keycache_init(); /* set key_cache_hash.default_value = dflt_key_cache */ + /* set key_cache_hash.default_value = dflt_key_cache */ + multi_keycache_init(); /* Set directory paths */ strmake(language, LANGUAGE, sizeof(language)-1); @@ -7129,7 +7136,7 @@ static void mysql_init_variables(void) master_password= master_host= 0; master_info_file= (char*) "master.info", relay_log_info_file= (char*) "relay-log.info"; - master_ssl_key= master_ssl_cert= master_ssl_ca= + master_ssl_key= master_ssl_cert= master_ssl_ca= master_ssl_capath= master_ssl_cipher= 0; report_user= report_password = report_host= 0; /* TO BE DELETED */ opt_relay_logname= opt_relaylog_index_name= 0; @@ -7782,7 +7789,7 @@ mysql_getopt_value(const char *keyname, uint key_length, } } } - return option->value; + return option->value; } diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 5a772501e48..97d0bcc8707 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -2139,9 +2139,6 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, quick=0; needed_reg.clear_all(); quick_keys.clear_all(); - if ((specialflag & SPECIAL_SAFE_MODE) && ! force_quick_range || - !limit) - DBUG_RETURN(0); /* purecov: inspected */ if (keys_to_use.is_clear_all()) DBUG_RETURN(0); records= head->file->stats.records; @@ -4308,7 +4305,6 @@ static bool ror_intersect_add(ROR_INTERSECT_INFO *info, } info->out_rows *= selectivity_mult; - DBUG_PRINT("info", ("info->total_cost= %g", info->total_cost)); if (is_cpk_scan) { diff --git a/sql/set_var.cc b/sql/set_var.cc index 697de9cda97..f67ccc02dc7 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -706,7 +706,7 @@ static SHOW_VAR fixed_vars[]= { #ifdef HAVE_THR_SETCONCURRENCY {"thread_concurrency", (char*) &concurrency, SHOW_LONG}, #endif - {"thread_stack", (char*) &thread_stack, SHOW_LONG}, + {"thread_stack", (char*) &my_thread_stack_size, SHOW_LONG}, }; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 66a51d5bb00..afe0383658f 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -440,6 +440,7 @@ THD::THD() cleanup_done= abort_on_warning= no_warnings_for_error= 0; peer_port= 0; // For SHOW PROCESSLIST transaction.m_pending_rows_event= 0; + transaction.on= 1; #ifdef SIGNAL_WITH_VIO_CLOSE active_vio = 0; #endif diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index ae347bebb47..e440aeaa588 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -5120,10 +5120,10 @@ bool check_stack_overrun(THD *thd, long margin, long stack_used; DBUG_ASSERT(thd == current_thd); if ((stack_used=used_stack(thd->thread_stack,(char*) &stack_used)) >= - (long) (thread_stack - margin)) + (long) (my_thread_stack_size - margin)) { sprintf(errbuff[0],ER(ER_STACK_OVERRUN_NEED_MORE), - stack_used,thread_stack,margin); + stack_used,my_thread_stack_size,margin); my_message(ER_STACK_OVERRUN_NEED_MORE,errbuff[0],MYF(0)); thd->fatal_error(); return 1; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index b77bb719e1e..1f206e2ec17 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -29,6 +29,7 @@ #include "sql_cursor.h" #include <m_ctype.h> +#include <my_bit.h> #include <hash.h> #include <ft_global.h> @@ -9580,7 +9581,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, table->s= share; init_tmp_table_share(share, "", 0, tmpname, tmpname); share->blob_field= blob_field; - share->blob_ptr_size= mi_portable_sizeof_char_ptr; + share->blob_ptr_size= portable_sizeof_char_ptr; share->db_low_byte_first=1; // True for HEAP and MyISAM share->table_charset= param->table_charset; share->primary_key= MAX_KEY; // Indicate no primary key @@ -10145,7 +10146,7 @@ TABLE *create_virtual_tmp_table(THD *thd, List<Create_field> &field_list) table->s= share; share->blob_field= blob_field; share->fields= field_count; - share->blob_ptr_size= mi_portable_sizeof_char_ptr; + share->blob_ptr_size= portable_sizeof_char_ptr; setup_tmp_table_column_bitmaps(table, bitmaps); /* Create all fields and calculate the total length of record */ diff --git a/sql/sql_show.cc b/sql/sql_show.cc index f7813b73089..38db2fe85a5 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -70,6 +70,9 @@ static TYPELIB grant_types = { sizeof(grant_names)/sizeof(char **), grant_names, NULL}; #endif +/* Match the values of enum ha_choice */ +static const char *ha_choice_values[] = {"", "0", "1"}; + static void store_key_options(THD *thd, String *packet, TABLE *table, KEY *key_info); @@ -1182,6 +1185,8 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet, key_info= table->key_info; bzero((char*) &create_info, sizeof(create_info)); + /* Allow update_create_info to update row type */ + create_info.row_type= share->row_type; file->update_create_info(&create_info); primary_key= share->primary_key; @@ -1366,19 +1371,25 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet, packet->append(STRING_WITH_LEN(" PACK_KEYS=1")); if (share->db_create_options & HA_OPTION_NO_PACK_KEYS) packet->append(STRING_WITH_LEN(" PACK_KEYS=0")); + /* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */ if (share->db_create_options & HA_OPTION_CHECKSUM) packet->append(STRING_WITH_LEN(" CHECKSUM=1")); + if (share->page_checksum != HA_CHOICE_UNDEF) + { + packet->append(STRING_WITH_LEN(" PAGE_CHECKSUM=")); + packet->append(ha_choice_values[(uint) share->page_checksum], 1); + } if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE) packet->append(STRING_WITH_LEN(" DELAY_KEY_WRITE=1")); - if (share->row_type != ROW_TYPE_DEFAULT) + if (create_info.row_type != ROW_TYPE_DEFAULT) { packet->append(STRING_WITH_LEN(" ROW_FORMAT=")); - packet->append(ha_row_type[(uint) share->row_type]); + packet->append(ha_row_type[(uint) create_info.row_type]); } if (share->transactional != HA_CHOICE_UNDEF) { packet->append(STRING_WITH_LEN(" TRANSACTIONAL=")); - packet->append(share->transactional == HA_CHOICE_YES ? "1" : "0", 1); + packet->append(ha_choice_values[(uint) share->transactional], 1); } if (table->s->key_block_size) { @@ -3462,8 +3473,12 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, ptr=strmov(ptr," pack_keys=1"); if (share->db_create_options & HA_OPTION_NO_PACK_KEYS) ptr=strmov(ptr," pack_keys=0"); + /* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */ if (share->db_create_options & HA_OPTION_CHECKSUM) ptr=strmov(ptr," checksum=1"); + if (share->page_checksum != HA_CHOICE_UNDEF) + ptr= strxmov(ptr, " page_checksum=", + ha_choice_values[(uint) share->page_checksum], NullS); if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE) ptr=strmov(ptr," delay_key_write=1"); if (share->row_type != ROW_TYPE_DEFAULT) @@ -3482,6 +3497,9 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, show_table->part_info->no_parts > 0) ptr= strmov(ptr, " partitioned"); #endif + if (share->transactional != HA_CHOICE_UNDEF) + ptr= strxmov(ptr, " transactional=", + ha_choice_values[(uint) share->transactional], NullS); table->field[19]->store(option_buff+1, (ptr == option_buff ? 0 : (uint) (ptr-option_buff)-1), cs); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index cd39623f2b4..5f1f7f9db0e 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -3678,8 +3678,9 @@ mysql_rename_table(handlerton *base, const char *old_db, wait_while_table_is_used() thd Thread handler table Table to remove from cache - function HA_EXTRA_PREPARE_FOR_DELETE if table is to be deleted - HA_EXTRA_FORCE_REOPEN if table is not be used + function HA_EXTRA_PREPARE_FOR_DROP if table is to be deleted + HA_EXTRA_FORCE_REOPEN if table is not be used + HA_EXTRA_PREPARE_FOR_RENAME if table is to be renamed NOTES When returning, the table will be unusable for other threads until the table is closed. @@ -3729,7 +3730,7 @@ void close_cached_table(THD *thd, TABLE *table) { DBUG_ENTER("close_cached_table"); - wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_DELETE); + wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN); /* Close lock if this is not got with LOCK TABLES */ if (thd->lock) { @@ -6488,7 +6489,7 @@ view_err: if (lower_case_table_names) my_casedn_str(files_charset_info, old_name); - wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_DELETE); + wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_RENAME); close_data_files_and_morph_locks(thd, db, table_name); error=0; @@ -6946,7 +6947,6 @@ bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list) DBUG_ENTER("mysql_recreate_table"); bzero((char*) &create_info, sizeof(create_info)); - create_info.db_type= 0; create_info.row_type=ROW_TYPE_NOT_USED; create_info.default_table_charset=default_charset_info; /* Force alter table to recreate table */ diff --git a/sql/sql_test.cc b/sql/sql_test.cc index 0fe299d4505..f1d7e4a7312 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -459,7 +459,7 @@ void mysql_print_status() VOID(my_getwd(current_dir, sizeof(current_dir),MYF(0))); printf("Current dir: %s\n", current_dir); printf("Running threads: %d Stack size: %ld\n", thread_count, - (long) thread_stack); + (long) my_thread_stack_size); thr_print_locks(); // Write some debug info #ifndef DBUG_OFF print_cached_tables(); @@ -536,7 +536,7 @@ Estimated memory (with thread stack): %ld\n", (int) info.uordblks, (int) info.fordblks, (int) info.keepcost, - (long) (thread_count * thread_stack + info.hblkhd + info.arena)); + (long) (thread_count * my_thread_stack_size + info.hblkhd + info.arena)); #endif Events::dump_internal_status(); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 68680addc58..560aebcc456 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -487,6 +487,7 @@ Item* handle_sql2003_note184_exception(THD *thd, Item* left, bool equal, enum enum_tx_isolation tx_isolation; enum Cast_target cast_type; enum Item_udftype udf_type; + enum ha_choice choice; CHARSET_INFO *charset; thr_lock_type lock_type; interval_type interval, interval_time_st; @@ -875,6 +876,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token OWNER_SYM %token PACK_KEYS_SYM %token PAGE_SYM +%token PAGE_CHECKSUM_SYM %token PARAM_MARKER %token PARSER_SYM %token PARTIAL /* SQL-2003-N */ @@ -1010,6 +1012,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token TABLESPACE %token TABLE_REF_PRIORITY %token TABLE_SYM /* SQL-2003-R */ +%token TABLE_CHECKSUM_SYM %token TEMPORARY /* SQL-2003-N */ %token TEMPTABLE_SYM %token TERMINATED @@ -1145,6 +1148,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %type <ulonglong_number> ulonglong_num real_ulonglong_num size_number +%type <choice> choice + %type <p_elem_value> part_bit_expr @@ -4440,6 +4445,16 @@ create_table_option: Lex->create_info.table_options|= $3 ? HA_OPTION_CHECKSUM : HA_OPTION_NO_CHECKSUM; Lex->create_info.used_fields|= HA_CREATE_USED_CHECKSUM; } + | TABLE_CHECKSUM_SYM opt_equal ulong_num + { + Lex->create_info.table_options|= $3 ? HA_OPTION_CHECKSUM : HA_OPTION_NO_CHECKSUM; + Lex->create_info.used_fields|= HA_CREATE_USED_CHECKSUM; + } + | PAGE_CHECKSUM_SYM opt_equal choice + { + Lex->create_info.used_fields|= HA_CREATE_USED_PAGE_CHECKSUM; + Lex->create_info.page_checksum= $3; + } | DELAY_KEY_WRITE_SYM opt_equal ulong_num { Lex->create_info.table_options|= $3 ? HA_OPTION_DELAY_KEY_WRITE : HA_OPTION_NO_DELAY_KEY_WRITE; @@ -4499,13 +4514,11 @@ create_table_option: Lex->create_info.used_fields|= HA_CREATE_USED_KEY_BLOCK_SIZE; Lex->create_info.key_block_size= $3; } - | TRANSACTIONAL_SYM opt_equal ulong_num + | TRANSACTIONAL_SYM opt_equal choice { Lex->create_info.used_fields|= HA_CREATE_USED_TRANSACTIONAL; - Lex->create_info.transactional= ($3 != 0 ? HA_CHOICE_YES : - HA_CHOICE_NO); + Lex->create_info.transactional= $3; } - ; default_charset: @@ -8379,6 +8392,11 @@ dec_num: | FLOAT_NUM ; +choice: + ulong_num { $$= $1 != 0 ? HA_CHOICE_YES : HA_CHOICE_NO; } + | DEFAULT { $$= HA_CHOICE_UNDEF; } + ; + procedure_clause: /* empty */ | PROCEDURE ident /* Procedure name */ @@ -10575,6 +10593,7 @@ keyword_sp: | ONE_SYM {} | PACK_KEYS_SYM {} | PAGE_SYM {} + | PAGE_CHECKSUM_SYM {} | PARTIAL {} | PARTITIONING_SYM {} | PARTITIONS_SYM {} @@ -10638,6 +10657,7 @@ keyword_sp: | SUPER_SYM {} | SUSPEND_SYM {} | TABLES {} + | TABLE_CHECKSUM_SYM {} | TABLESPACE {} | TEMPORARY {} | TEMPTABLE_SYM {} diff --git a/sql/table.cc b/sql/table.cc index c1d8e3abe94..417cd78fe2e 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -705,7 +705,8 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, if (!head[32]) // New frm file in 3.23 { share->avg_row_length= uint4korr(head+34); - share->transactional= (ha_choice) head[39]; + share->transactional= (ha_choice) (head[39] & 3); + share->page_checksum= (ha_choice) ((head[39] >> 2) & 3); share->row_type= (row_type) head[40]; share->table_charset= get_charset((uint) head[38],MYF(0)); share->null_field_first= 1; @@ -2428,7 +2429,9 @@ File create_frm(THD *thd, const char *name, const char *db, int2store(fileinfo+16,reclength); int4store(fileinfo+18,create_info->max_rows); int4store(fileinfo+22,create_info->min_rows); + /* fileinfo[26] is set in mysql_create_frm() */ fileinfo[27]=2; // Use long pack-fields + /* fileinfo[28 & 29] is set to key_info_length in mysql_create_frm() */ create_info->table_options|=HA_OPTION_LONG_BLOB_PTR; // Use portable blob pointers int2store(fileinfo+30,create_info->table_options); fileinfo[32]=0; // No filename anymore @@ -2436,9 +2439,10 @@ File create_frm(THD *thd, const char *name, const char *db, int4store(fileinfo+34,create_info->avg_row_length); fileinfo[38]= (create_info->default_table_charset ? create_info->default_table_charset->number : 0); - fileinfo[39]= (uchar) create_info->transactional; + fileinfo[39]= (uchar) ((uint) create_info->transactional | + ((uint) create_info->page_checksum << 2)); fileinfo[40]= (uchar) create_info->row_type; - /* Next few bytes were for RAID support */ + /* Next few bytes where for RAID support */ fileinfo[41]= 0; fileinfo[42]= 0; fileinfo[43]= 0; diff --git a/sql/table.h b/sql/table.h index 6554b6ed578..b9c15ea2b6d 100644 --- a/sql/table.h +++ b/sql/table.h @@ -311,6 +311,7 @@ typedef struct st_table_share enum row_type row_type; /* How rows are stored */ enum tmp_table_type tmp_table; enum ha_choice transactional; + enum ha_choice page_checksum; uint ref_count; /* How many TABLE objects uses this */ uint open_count; /* Number of tables in open list */ diff --git a/sql/unireg.cc b/sql/unireg.cc index f9e8e54439a..da52889fb2f 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -284,8 +284,10 @@ bool mysql_create_frm(THD *thd, const char *file_name, my_free(keybuff, MYF(0)); if (opt_sync_frm && !(create_info->options & HA_LEX_CREATE_TMP_TABLE) && - my_sync(file, MYF(MY_WME))) - goto err2; + (my_sync(file, MYF(MY_WME)) || + my_sync_dir_by_file(file_name, MYF(MY_WME)))) + goto err2; + if (my_close(file,MYF(MY_WME))) goto err3; diff --git a/storage/myisam/ft_boolean_search.c b/storage/myisam/ft_boolean_search.c index 15f4e1e1d34..a9551a4b4ec 100644 --- a/storage/myisam/ft_boolean_search.c +++ b/storage/myisam/ft_boolean_search.c @@ -162,7 +162,7 @@ static int FTB_WORD_cmp(my_off_t *v, FTB_WORD *a, FTB_WORD *b) static int FTB_WORD_cmp_list(CHARSET_INFO *cs, FTB_WORD **a, FTB_WORD **b) { /* ORDER BY word DESC, ndepth DESC */ - int i= mi_compare_text(cs, (uchar*) (*b)->word+1,(*b)->len-1, + int i= ha_compare_text(cs, (uchar*) (*b)->word+1,(*b)->len-1, (uchar*) (*a)->word+1,(*a)->len-1,0,0); if (!i) i=CMP_NUM((*b)->ndepth,(*a)->ndepth); @@ -395,7 +395,7 @@ static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search) if (!r && !ftbw->off) { - r= mi_compare_text(ftb->charset, + r= ha_compare_text(ftb->charset, info->lastkey+1, info->lastkey_length-extra-1, (uchar*) ftbw->word+1, @@ -868,7 +868,7 @@ static int ftb_find_relevance_add_word(MYSQL_FTPARSER_PARAM *param, for (a= 0, b= ftb->queue.elements, c= (a+b)/2; b-a>1; c= (a+b)/2) { ftbw= ftb->list[c]; - if (mi_compare_text(ftb->charset, (uchar*)word, len, + if (ha_compare_text(ftb->charset, (uchar*)word, len, (uchar*)ftbw->word+1, ftbw->len-1, (my_bool)(ftbw->flags&FTB_FLAG_TRUNC), 0) > 0) b= c; @@ -878,7 +878,7 @@ static int ftb_find_relevance_add_word(MYSQL_FTPARSER_PARAM *param, for (; c >= 0; c--) { ftbw= ftb->list[c]; - if (mi_compare_text(ftb->charset, (uchar*)word, len, + if (ha_compare_text(ftb->charset, (uchar*)word, len, (uchar*)ftbw->word + 1,ftbw->len - 1, (my_bool)(ftbw->flags & FTB_FLAG_TRUNC), 0)) break; diff --git a/storage/myisam/ft_eval.c b/storage/myisam/ft_eval.c index 7eb78861e5e..de01510fdd7 100644 --- a/storage/myisam/ft_eval.c +++ b/storage/myisam/ft_eval.c @@ -48,7 +48,7 @@ int main(int argc, char *argv[]) recinfo[0].type=FIELD_SKIP_ENDSPACE; recinfo[0].length=docid_length; recinfo[1].type=FIELD_BLOB; - recinfo[1].length= 4+mi_portable_sizeof_char_ptr; + recinfo[1].length= 4+portable_sizeof_char_ptr; /* Define a key over the first column */ keyinfo[0].seg=keyseg; diff --git a/storage/myisam/ft_nlq_search.c b/storage/myisam/ft_nlq_search.c index 282fa6751d8..b3a2e47a382 100644 --- a/storage/myisam/ft_nlq_search.c +++ b/storage/myisam/ft_nlq_search.c @@ -103,7 +103,7 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio) { if (keylen && - mi_compare_text(aio->charset,info->lastkey+1, + ha_compare_text(aio->charset,info->lastkey+1, info->lastkey_length-extra-1, keybuff+1,keylen-1,0,0)) break; diff --git a/storage/myisam/ft_parser.c b/storage/myisam/ft_parser.c index df2423aa50f..042a999fffa 100644 --- a/storage/myisam/ft_parser.c +++ b/storage/myisam/ft_parser.c @@ -31,7 +31,7 @@ typedef struct st_my_ft_parser_param static int FT_WORD_cmp(CHARSET_INFO* cs, FT_WORD *w1, FT_WORD *w2) { - return mi_compare_text(cs, (uchar*) w1->pos, w1->len, + return ha_compare_text(cs, (uchar*) w1->pos, w1->len, (uchar*) w2->pos, w2->len, 0, 0); } diff --git a/storage/myisam/ft_stopwords.c b/storage/myisam/ft_stopwords.c index 59866d9a351..9838b15af34 100644 --- a/storage/myisam/ft_stopwords.c +++ b/storage/myisam/ft_stopwords.c @@ -29,7 +29,7 @@ static TREE *stopwords3=NULL; static int FT_STOPWORD_cmp(void* cmp_arg __attribute__((unused)), FT_STOPWORD *w1, FT_STOPWORD *w2) { - return mi_compare_text(default_charset_info, + return ha_compare_text(default_charset_info, (uchar *)w1->pos,w1->len, (uchar *)w2->pos,w2->len,0,0); } diff --git a/storage/myisam/ft_test1.c b/storage/myisam/ft_test1.c index e49c47bb268..b37935a0d7a 100644 --- a/storage/myisam/ft_test1.c +++ b/storage/myisam/ft_test1.c @@ -75,12 +75,12 @@ static int run_test(const char *filename) /* First define 2 columns */ recinfo[0].type=extra_field; - recinfo[0].length= (extra_field == FIELD_BLOB ? 4 + mi_portable_sizeof_char_ptr : + recinfo[0].length= (extra_field == FIELD_BLOB ? 4 + portable_sizeof_char_ptr : extra_length); if (extra_field == FIELD_VARCHAR) recinfo[0].length+= HA_VARCHAR_PACKLENGTH(extra_length); recinfo[1].type=key_field; - recinfo[1].length= (key_field == FIELD_BLOB ? 4+mi_portable_sizeof_char_ptr : + recinfo[1].length= (key_field == FIELD_BLOB ? 4+portable_sizeof_char_ptr : key_length); if (key_field == FIELD_VARCHAR) recinfo[1].length+= HA_VARCHAR_PACKLENGTH(key_length); diff --git a/storage/myisam/ft_update.c b/storage/myisam/ft_update.c index e3e4c62158f..d1548e32870 100644 --- a/storage/myisam/ft_update.c +++ b/storage/myisam/ft_update.c @@ -180,7 +180,7 @@ int _mi_ft_cmp(MI_INFO *info, uint keynr, const uchar *rec1, const uchar *rec2) { if ((ftsi1.pos != ftsi2.pos) && (!ftsi1.pos || !ftsi2.pos || - mi_compare_text(cs, (uchar*) ftsi1.pos,ftsi1.len, + ha_compare_text(cs, (uchar*) ftsi1.pos,ftsi1.len, (uchar*) ftsi2.pos,ftsi2.len,0,0))) DBUG_RETURN(THOSE_TWO_DAMN_KEYS_ARE_REALLY_DIFFERENT); } @@ -209,7 +209,7 @@ int _mi_ft_update(MI_INFO *info, uint keynr, uchar *keybuf, error=0; while(old_word->pos && new_word->pos) { - cmp= mi_compare_text(cs, (uchar*) old_word->pos,old_word->len, + cmp= ha_compare_text(cs, (uchar*) old_word->pos,old_word->len, (uchar*) new_word->pos,new_word->len,0,0); cmp2= cmp ? 0 : (fabs(old_word->weight - new_word->weight) > 1.e-5); diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index ca4c40547ee..f3b18c0630c 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -22,6 +22,7 @@ #include "mysql_priv.h" #include <mysql/plugin.h> #include <m_ctype.h> +#include <my_bit.h> #include <myisampack.h> #include "ha_myisam.h" #include <stdarg.h> diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c index fe6b716877c..7e9334d4cf6 100644 --- a/storage/myisam/mi_check.c +++ b/storage/myisam/mi_check.c @@ -737,7 +737,7 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo, { int flag; uint used_length,comp_flag,nod_flag,key_length=0; - uchar key[MI_MAX_POSSIBLE_KEY_BUFF],*temp_buff,*keypos,*old_keypos,*endpos; + uchar key[HA_MAX_POSSIBLE_KEY_BUFF],*temp_buff,*keypos,*old_keypos,*endpos; my_off_t next_page,record; char llbuff[22]; uint diff_pos[2]; @@ -944,7 +944,7 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend) uchar *record,*to; char llbuff[22],llbuff2[22],llbuff3[22]; ha_checksum intern_record_checksum; - ha_checksum key_checksum[MI_MAX_POSSIBLE_KEY]; + ha_checksum key_checksum[HA_MAX_POSSIBLE_KEY]; my_bool static_row_size; MI_KEYDEF *keyinfo; MI_BLOCK_INFO block_info; @@ -1211,6 +1211,8 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend) param->glob_crc+= mi_checksum(info,record); link_used+= (block_info.filepos - start_recpos); used+= (pos-start_recpos); + case BLOCK_RECORD: + assert(0); /* Impossible */ } /* switch */ if (! got_error) { @@ -1808,7 +1810,7 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, char * name) reg2 uint key; reg1 MI_KEYDEF *keyinfo; File new_file; - my_off_t index_pos[MI_MAX_POSSIBLE_KEY]; + my_off_t index_pos[HA_MAX_POSSIBLE_KEY]; uint r_locks,w_locks; int old_lock; MYISAM_SHARE *share=info->s; @@ -1908,7 +1910,7 @@ static int sort_one_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo, { uint length,nod_flag,used_length, key_length; uchar *buff,*keypos,*endpos; - uchar key[MI_MAX_POSSIBLE_KEY_BUFF]; + uchar key[HA_MAX_POSSIBLE_KEY_BUFF]; my_off_t new_page_pos,next_page; char llbuff[22]; DBUG_ENTER("sort_one_index"); @@ -3522,8 +3524,10 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param) mi_checksum(info, sort_param->record)); DBUG_RETURN(0); } + case BLOCK_RECORD: + assert(0); /* Impossible */ } - DBUG_RETURN(1); /* Impossible */ + DBUG_RETURN(1); /* Impossible */ } @@ -3633,6 +3637,8 @@ int sort_write_record(MI_SORT_PARAM *sort_param) sort_param->filepos+=reclength+length; info->s->state.split++; break; + case BLOCK_RECORD: + assert(0); /* Impossible */ } } if (sort_param->master) @@ -3804,7 +3810,7 @@ static int sort_ft_key_write(MI_SORT_PARAM *sort_param, const void *a) } get_key_full_length_rdonly(val_off, ft_buf->lastkey); - if (mi_compare_text(sort_param->seg->charset, + if (ha_compare_text(sort_param->seg->charset, ((uchar *)a)+1,a_len-1, ft_buf->lastkey+1,val_off-1, 0, 0)==0) { diff --git a/storage/myisam/mi_checksum.c b/storage/myisam/mi_checksum.c index 4e87de373bd..1aa56e571e3 100644 --- a/storage/myisam/mi_checksum.c +++ b/storage/myisam/mi_checksum.c @@ -31,9 +31,9 @@ ha_checksum mi_checksum(MI_INFO *info, const uchar *buf) case FIELD_BLOB: { length=_mi_calc_blob_length(rec->length- - mi_portable_sizeof_char_ptr, + portable_sizeof_char_ptr, buf); - memcpy((char*) &pos, buf+rec->length- mi_portable_sizeof_char_ptr, + memcpy((char*) &pos, buf+rec->length- portable_sizeof_char_ptr, sizeof(char*)); break; } diff --git a/storage/myisam/mi_create.c b/storage/myisam/mi_create.c index 0cac5f08b3b..bc4dcf0bdbb 100644 --- a/storage/myisam/mi_create.c +++ b/storage/myisam/mi_create.c @@ -17,6 +17,7 @@ #include "ftdefs.h" #include "sp_defs.h" +#include <my_bit.h> #if defined(MSDOS) || defined(__WIN__) #ifdef __WIN__ @@ -56,7 +57,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, HA_KEYSEG *keyseg,tmp_keyseg; MI_COLUMNDEF *rec; ulong *rec_per_key_part; - my_off_t key_root[MI_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE]; + my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE]; MI_CREATE_INFO tmp_create_info; DBUG_ENTER("mi_create"); DBUG_PRINT("enter", ("keys: %u columns: %u uniques: %u flags: %u", @@ -116,10 +117,10 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, share.base.blobs++; if (pack_reclength != INT_MAX32) { - if (rec->length == 4+mi_portable_sizeof_char_ptr) + if (rec->length == 4+portable_sizeof_char_ptr) pack_reclength= INT_MAX32; else - pack_reclength+=(1 << ((rec->length-mi_portable_sizeof_char_ptr)*8)); /* Max blob length */ + pack_reclength+=(1 << ((rec->length-portable_sizeof_char_ptr)*8)); /* Max blob length */ } } else if (type == FIELD_SKIP_PRESPACE || diff --git a/storage/myisam/mi_dynrec.c b/storage/myisam/mi_dynrec.c index cdd70abe9ad..f67eba39ff7 100644 --- a/storage/myisam/mi_dynrec.c +++ b/storage/myisam/mi_dynrec.c @@ -901,7 +901,7 @@ uint _mi_rec_pack(MI_INFO *info, register uchar *to, else { char *temp_pos; - size_t tmp_length=length-mi_portable_sizeof_char_ptr; + size_t tmp_length=length-portable_sizeof_char_ptr; memcpy((uchar*) to,from,tmp_length); memcpy_fixed(&temp_pos,from+tmp_length,sizeof(char*)); memcpy(to+tmp_length,temp_pos,(size_t) blob->length); @@ -1022,11 +1022,11 @@ my_bool _mi_rec_check(MI_INFO *info,const uchar *record, uchar *rec_buff, if (type == FIELD_BLOB) { uint blob_length= - _mi_calc_blob_length(length-mi_portable_sizeof_char_ptr,record); + _mi_calc_blob_length(length-portable_sizeof_char_ptr,record); if (!blob_length && !(flag & bit)) goto err; if (blob_length) - to+=length - mi_portable_sizeof_char_ptr+ blob_length; + to+=length - portable_sizeof_char_ptr+ blob_length; } else if (type == FIELD_SKIP_ZERO) { @@ -1209,7 +1209,7 @@ ulong _mi_rec_unpack(register MI_INFO *info, register uchar *to, uchar *from, } else if (type == FIELD_BLOB) { - uint size_length=rec_length- mi_portable_sizeof_char_ptr; + uint size_length=rec_length- portable_sizeof_char_ptr; ulong blob_length=_mi_calc_blob_length(size_length,from); ulong from_left= (ulong) (from_end - from); if (from_left < size_length || diff --git a/storage/myisam/mi_extra.c b/storage/myisam/mi_extra.c index 1b4c79d13de..f0ddc15b325 100644 --- a/storage/myisam/mi_extra.c +++ b/storage/myisam/mi_extra.c @@ -256,7 +256,7 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg) share->last_version= 0L; /* Impossible version */ pthread_mutex_unlock(&THR_LOCK_myisam); break; - case HA_EXTRA_PREPARE_FOR_DELETE: + case HA_EXTRA_PREPARE_FOR_DROP: pthread_mutex_lock(&THR_LOCK_myisam); share->last_version= 0L; /* Impossible version */ #ifdef __WIN__REMOVE_OBSOLETE_WORKAROUND diff --git a/storage/myisam/mi_open.c b/storage/myisam/mi_open.c index b848c822f75..40f55e78bca 100644 --- a/storage/myisam/mi_open.c +++ b/storage/myisam/mi_open.c @@ -82,8 +82,8 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) uchar *disk_cache, *disk_pos, *end_pos; MI_INFO info,*m_info,*old_info; MYISAM_SHARE share_buff,*share; - ulong rec_per_key_part[MI_MAX_POSSIBLE_KEY*MI_MAX_KEY_SEG]; - my_off_t key_root[MI_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE]; + ulong rec_per_key_part[HA_MAX_POSSIBLE_KEY*MI_MAX_KEY_SEG]; + my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE]; ulonglong max_key_file_length, max_data_file_length; DBUG_ENTER("mi_open"); @@ -452,7 +452,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) if (share->rec[i].type == (int) FIELD_BLOB) { share->blobs[j].pack_length= - share->rec[i].length-mi_portable_sizeof_char_ptr;; + share->rec[i].length-portable_sizeof_char_ptr; share->blobs[j].offset=offset; j++; } diff --git a/storage/myisam/mi_packrec.c b/storage/myisam/mi_packrec.c index 305b7e5532c..98c0dcb4dcc 100644 --- a/storage/myisam/mi_packrec.c +++ b/storage/myisam/mi_packrec.c @@ -1036,7 +1036,7 @@ static void uf_blob(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, else { ulong length=get_bits(bit_buff,rec->space_length_bits); - uint pack_length=(uint) (end-to)-mi_portable_sizeof_char_ptr; + uint pack_length=(uint) (end-to)-portable_sizeof_char_ptr; if (bit_buff->blob_pos+length > bit_buff->blob_end) { bit_buff->error=1; diff --git a/storage/myisam/mi_range.c b/storage/myisam/mi_range.c index 932a4abd1b3..dc6dc9d62b7 100644 --- a/storage/myisam/mi_range.c +++ b/storage/myisam/mi_range.c @@ -139,7 +139,7 @@ static ha_rows _mi_record_pos(MI_INFO *info, const uchar *key, key_len=USE_WHOLE_KEY; /* - my_handler.c:mi_compare_text() has a flag 'skip_end_space'. + my_handler.c:ha_compare_text() has a flag 'skip_end_space'. This is set in my_handler.c:ha_key_cmp() in dependence on the compare flags 'nextflag' and the column type. diff --git a/storage/myisam/mi_test1.c b/storage/myisam/mi_test1.c index a68bcbed56c..f218bf4e77f 100644 --- a/storage/myisam/mi_test1.c +++ b/storage/myisam/mi_test1.c @@ -71,12 +71,12 @@ static int run_test(const char *filename) /* First define 2 columns */ recinfo[0].type=FIELD_NORMAL; recinfo[0].length=1; /* For NULL bits */ recinfo[1].type=key_field; - recinfo[1].length= (key_field == FIELD_BLOB ? 4+mi_portable_sizeof_char_ptr : + recinfo[1].length= (key_field == FIELD_BLOB ? 4+portable_sizeof_char_ptr : key_length); if (key_field == FIELD_VARCHAR) recinfo[1].length+= HA_VARCHAR_PACKLENGTH(key_length);; recinfo[2].type=extra_field; - recinfo[2].length= (extra_field == FIELD_BLOB ? 4 + mi_portable_sizeof_char_ptr : 24); + recinfo[2].length= (extra_field == FIELD_BLOB ? 4 + portable_sizeof_char_ptr : 24); if (extra_field == FIELD_VARCHAR) recinfo[2].length+= HA_VARCHAR_PACKLENGTH(recinfo[2].length); if (opt_unique) diff --git a/storage/myisam/mi_test2.c b/storage/myisam/mi_test2.c index 902801b5e6e..23c58638166 100644 --- a/storage/myisam/mi_test2.c +++ b/storage/myisam/mi_test2.c @@ -26,6 +26,7 @@ #endif #include "myisamdef.h" #include <m_ctype.h> +#include <my_bit.h> #define STANDARD_LENGTH 37 #define MYISAM_KEYS 6 @@ -187,7 +188,7 @@ int main(int argc, char *argv[]) if (use_blob) { recinfo[6].type=FIELD_BLOB; - recinfo[6].length=4+mi_portable_sizeof_char_ptr; + recinfo[6].length=4+portable_sizeof_char_ptr; recinfo[6].null_bit=0; recinfo[6].null_pos=0; } diff --git a/storage/myisam/mi_unique.c b/storage/myisam/mi_unique.c index e490fb683e4..02fcd9289dd 100644 --- a/storage/myisam/mi_unique.c +++ b/storage/myisam/mi_unique.c @@ -212,7 +212,7 @@ int mi_unique_comp(MI_UNIQUEDEF *def, const uchar *a, const uchar *b, if (type == HA_KEYTYPE_TEXT || type == HA_KEYTYPE_VARTEXT1 || type == HA_KEYTYPE_VARTEXT2) { - if (mi_compare_text(keyseg->charset, (uchar *) pos_a, a_length, + if (ha_compare_text(keyseg->charset, (uchar *) pos_a, a_length, (uchar *) pos_b, b_length, 0, 1)) return 1; } diff --git a/storage/myisam/mi_write.c b/storage/myisam/mi_write.c index 70ba7a4588a..d34939fdf1b 100644 --- a/storage/myisam/mi_write.c +++ b/storage/myisam/mi_write.c @@ -545,7 +545,7 @@ int _mi_insert(register MI_INFO *info, register MI_KEYDEF *keyinfo, get_key_length(alen,a); DBUG_ASSERT(info->ft1_to_ft2==0); if (alen == blen && - mi_compare_text(keyinfo->seg->charset, a, alen, b, blen, 0, 0)==0) + ha_compare_text(keyinfo->seg->charset, a, alen, b, blen, 0, 0)==0) { /* yup. converting */ info->ft1_to_ft2=(DYNAMIC_ARRAY *) diff --git a/storage/myisam/myisamchk.c b/storage/myisam/myisamchk.c index 567e1057e5d..d335954fe08 100644 --- a/storage/myisam/myisamchk.c +++ b/storage/myisam/myisamchk.c @@ -20,6 +20,7 @@ #include <m_ctype.h> #include <stdarg.h> #include <my_getopt.h> +#include <my_bit.h> #ifdef HAVE_SYS_VADVICE_H #include <sys/vadvise.h> #endif diff --git a/storage/myisam/myisamdef.h b/storage/myisam/myisamdef.h index 721d6b9f271..d8cb3b6519f 100644 --- a/storage/myisam/myisamdef.h +++ b/storage/myisam/myisamdef.h @@ -400,13 +400,6 @@ typedef struct st_mi_sort_param /* Functions to store length of space packed keys, VARCHAR or BLOB keys */ -#define store_key_length_inc(key,length) \ -{ if ((length) < 255) \ - { *(key)++=(length); } \ - else \ - { *(key)=255; mi_int2store((key)+1,(length)); (key)+=3; } \ -} - #define store_key_length(key,length) \ { if ((length) < 255) \ { *(key)=(length); } \ diff --git a/storage/myisam/myisampack.c b/storage/myisam/myisampack.c index 37428ddd279..cb00264e1db 100644 --- a/storage/myisam/myisampack.c +++ b/storage/myisam/myisampack.c @@ -1008,7 +1008,7 @@ static int get_statistic(PACK_MRG_INFO *mrg,HUFF_COUNTS *huff_counts) /* Calculate pos, end_pos, and max_length for variable length fields. */ if (count->field_type == FIELD_BLOB) { - uint field_length=count->field_length -mi_portable_sizeof_char_ptr; + uint field_length=count->field_length -portable_sizeof_char_ptr; ulong blob_length= _mi_calc_blob_length(field_length, start_pos); memcpy_fixed((char*) &pos, start_pos+field_length,sizeof(char*)); end_pos=pos+blob_length; @@ -2650,7 +2650,7 @@ static int compress_isam_file(PACK_MRG_INFO *mrg, HUFF_COUNTS *huff_counts) case FIELD_BLOB: { ulong blob_length=_mi_calc_blob_length(field_length- - mi_portable_sizeof_char_ptr, + portable_sizeof_char_ptr, start_pos); /* Empty blobs are encoded with a single 1 bit. */ if (!blob_length) @@ -2667,7 +2667,7 @@ static int compress_isam_file(PACK_MRG_INFO *mrg, HUFF_COUNTS *huff_counts) DBUG_PRINT("fields", ("FIELD_BLOB %lu bytes, bits: %2u", blob_length, count->length_bits)); write_bits(blob_length,count->length_bits); - memcpy_fixed(&blob,end_pos-mi_portable_sizeof_char_ptr, + memcpy_fixed(&blob,end_pos-portable_sizeof_char_ptr, sizeof(char*)); blob_end=blob+blob_length; /* Encode the blob bytes. */ diff --git a/storage/myisam/sp_test.c b/storage/myisam/sp_test.c index dee32ba423e..f572c7ab19b 100644 --- a/storage/myisam/sp_test.c +++ b/storage/myisam/sp_test.c @@ -79,7 +79,7 @@ int run_test(const char *filename) /* Define spatial column */ recinfo[1].type=FIELD_BLOB; - recinfo[1].length=4 + mi_portable_sizeof_char_ptr; + recinfo[1].length=4 + portable_sizeof_char_ptr; diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc index 8a914e8a2de..dade3d02e2a 100644 --- a/storage/myisammrg/ha_myisammrg.cc +++ b/storage/myisammrg/ha_myisammrg.cc @@ -390,7 +390,7 @@ int ha_myisammrg::extra(enum ha_extra_function operation) /* As this is just a mapping, we don't have to force the underlying tables to be closed */ if (operation == HA_EXTRA_FORCE_REOPEN || - operation == HA_EXTRA_PREPARE_FOR_DELETE) + operation == HA_EXTRA_PREPARE_FOR_DROP) return 0; return myrg_extra(file,operation,0); } |