diff options
Diffstat (limited to 'include')
33 files changed, 645 insertions, 221 deletions
diff --git a/include/Makefile.am b/include/Makefile.am index 67ffef3e714..793c73718bd 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -22,6 +22,7 @@ HEADERS_ABI = mysql.h mysql_com.h mysql_time.h \ my_list.h my_alloc.h typelib.h mysql/plugin.h pkginclude_HEADERS = $(HEADERS_ABI) my_dbug.h m_string.h my_sys.h \ my_xml.h mysql_embed.h mysql/services.h \ + mysql/service_progress_report.h \ mysql/service_my_snprintf.h mysql/service_thd_alloc.h \ my_pthread.h my_no_pthread.h \ mysql/plugin_auth.h mysql/client_plugin.h \ @@ -30,10 +31,12 @@ 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 my_compiler.h \ + my_decimal_limits.h ma_dyncol.h \ $(HEADERS_GEN_CONFIGURE) \ $(HEADERS_GEN_MAKE) -noinst_HEADERS = config-win.h config-netware.h lf.h my_bit.h \ +internalincludedir = $(pkgincludedir)/private +internalinclude_HEADERS = config-win.h config-netware.h lf.h my_bit.h \ heap.h maria.h myisamchk.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 \ @@ -42,13 +45,16 @@ noinst_HEADERS = config-win.h config-netware.h lf.h my_bit.h \ thr_lock.h t_ctype.h violite.h my_md5.h base64.h \ service_versions.h \ my_compare.h my_handler.h my_time.h \ - my_vle.h my_user.h my_atomic.h atomic/nolock.h \ - atomic/rwlock.h atomic/x86-gcc.h \ - atomic/generic-msvc.h \ - atomic/gcc_builtins.h my_libwrap.h my_stacktrace.h \ + my_vle.h my_user.h my_atomic.h my_libwrap.h my_stacktrace.h \ wqueue.h waiting_threads.h \ welcome_copyright_notice.h +atomicincludedir = $(internalincludedir)/atomic +atomicinclude_HEADERS = atomic/nolock.h \ + atomic/rwlock.h atomic/x86-gcc.h \ + atomic/generic-msvc.h \ + atomic/gcc_builtins.h + EXTRA_DIST = mysql.h.pp mysql/plugin_auth.h.pp mysql/client_plugin.h.pp CMakeLists.txt # Remove built files and the symlinked directories diff --git a/include/config-netware.h b/include/config-netware.h index 4759d144040..e231d068c29 100644 --- a/include/config-netware.h +++ b/include/config-netware.h @@ -59,6 +59,7 @@ extern "C" { #undef HAVE_RWLOCK_INIT #undef HAVE_SCHED_H #undef HAVE_SYS_MMAN_H +#undef HAVE_SYS_UN_H #undef HAVE_SYNCH_H #undef HAVE_MMAP #undef HAVE_RINT diff --git a/include/config-win.h b/include/config-win.h index 86fcc61aa9b..da93251ec90 100644 --- a/include/config-win.h +++ b/include/config-win.h @@ -68,7 +68,6 @@ #endif /* File and lock constants */ -#define O_SHARE 0x1000 /* Open file in sharing mode */ #ifdef __BORLANDC__ #define F_RDLCK LK_NBLCK /* read lock */ #define F_WRLCK LK_NBRLCK /* write lock */ @@ -332,10 +331,9 @@ inline ulonglong double2ulonglong(double d) #define FILE_SHARE_DELETE 0 /* Not implemented on Win 98/ME */ #endif -#ifdef NOT_USED -#define HAVE_SNPRINTF /* Gave link error */ -#define _snprintf snprintf -#endif + +#define HAVE_SNPRINTF +#define snprintf _snprintf #ifdef _MSC_VER #define HAVE_LDIV /* The optimizer breaks in zortech for ldiv */ @@ -376,7 +374,7 @@ inline ulonglong double2ulonglong(double d) #define FN_DEVCHAR ':' #define FN_NETWORK_DRIVES /* Uses \\ to indicate network drives */ #define FN_NO_CASE_SENCE /* Files are not case-sensitive */ -#define OS_FILE_LIMIT 2048 +#define OS_FILE_LIMIT UINT_MAX #define DO_NOT_REMOVE_THREAD_WRAPPERS #define thread_safe_increment(V,L) InterlockedIncrement((long*) &(V)) diff --git a/include/decimal.h b/include/decimal.h index 09ff879fa03..5e3fea9f912 100644 --- a/include/decimal.h +++ b/include/decimal.h @@ -38,17 +38,17 @@ typedef struct st_decimal_t { int internal_str2dec(const char *from, decimal_t *to, char **end, my_bool fixed); -int decimal2string(decimal_t *from, char *to, int *to_len, +int decimal2string(const decimal_t *from, char *to, int *to_len, int fixed_precision, int fixed_decimals, char filler); -int decimal2ulonglong(decimal_t *from, ulonglong *to); +int decimal2ulonglong(const decimal_t *from, ulonglong *to); int ulonglong2decimal(ulonglong from, decimal_t *to); -int decimal2longlong(decimal_t *from, longlong *to); +int decimal2longlong(const decimal_t *from, longlong *to); int longlong2decimal(longlong from, decimal_t *to); -int decimal2double(decimal_t *from, double *to); +int decimal2double(const decimal_t *from, double *to); int double2decimal(double from, decimal_t *to); int decimal_actual_fraction(decimal_t *from); -int decimal2bin(decimal_t *from, uchar *to, int precision, int scale); +int decimal2bin(const decimal_t *from, uchar *to, int precision, int scale); int bin2decimal(const uchar *from, decimal_t *to, int precision, int scale); int decimal_size(int precision, int scale); @@ -64,7 +64,7 @@ int decimal_mul(decimal_t *from1, decimal_t *from2, decimal_t *to); int decimal_div(decimal_t *from1, decimal_t *from2, decimal_t *to, int scale_incr); int decimal_mod(decimal_t *from1, decimal_t *from2, decimal_t *to); -int decimal_round(decimal_t *from, decimal_t *to, int new_scale, +int decimal_round(const decimal_t *from, decimal_t *to, int new_scale, decimal_round_mode mode); int decimal_is_zero(decimal_t *from); void max_decimal(int precision, int frac, decimal_t *to); diff --git a/include/heap.h b/include/heap.h index b41f1a2519c..d0566919404 100644 --- a/include/heap.h +++ b/include/heap.h @@ -137,6 +137,8 @@ typedef struct st_heap_share ulong min_records,max_records; /* Params to open */ ulonglong data_length,index_length,max_table_size; uint key_stat_version; /* version to indicate insert/delete */ + uint key_version; /* Updated on key change */ + uint file_version; /* Update on clear */ uint records; /* records */ uint blength; /* records rounded up to 2^n */ uint deleted; /* Deleted records in database */ @@ -175,6 +177,8 @@ typedef struct st_heap_info enum ha_rkey_function last_find_flag; TREE_ELEMENT *parents[MAX_TREE_HEIGHT+1]; TREE_ELEMENT **last_pos; + uint key_version; /* Version at last read */ + uint file_version; /* Version at scan */ uint lastkey_len; my_bool implicit_emptied; #ifdef THREAD diff --git a/include/m_ctype.h b/include/m_ctype.h index 31dbfd2b476..8badfb53c15 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -151,7 +151,8 @@ enum my_lex_states MY_LEX_USER_VARIABLE_DELIMITER, MY_LEX_SYSTEM_VAR, MY_LEX_IDENT_OR_KEYWORD, MY_LEX_IDENT_OR_HEX, MY_LEX_IDENT_OR_BIN, MY_LEX_IDENT_OR_NCHAR, - MY_LEX_STRING_OR_DELIMITER + MY_LEX_STRING_OR_DELIMITER, MY_LEX_MINUS_OR_COMMENT, MY_LEX_PLACEHOLDER, + MY_LEX_COMMA }; struct charset_info_st; @@ -362,6 +363,9 @@ extern int my_strnncollsp_simple(CHARSET_INFO *, const uchar *, size_t, extern void my_hash_sort_simple(CHARSET_INFO *cs, const uchar *key, size_t len, ulong *nr1, ulong *nr2); +extern void my_hash_sort_bin(CHARSET_INFO *cs, + const uchar *key, size_t len, ulong *nr1, + ulong *nr2); extern size_t my_lengthsp_8bit(CHARSET_INFO *cs, const char *ptr, size_t length); diff --git a/include/m_string.h b/include/m_string.h index 13bdbf32f47..1b32d9df0c1 100644 --- a/include/m_string.h +++ b/include/m_string.h @@ -236,7 +236,7 @@ longlong my_strtoll10(const char *nptr, char **endptr, int *error); #endif #else #ifdef HAVE_LONG_LONG - extern char *longlong2str(longlong val,char *dst,int radix, int upcase); +extern char *longlong2str(longlong val,char *dst,int radix, int upcase); extern char *longlong10_to_str(longlong val,char *dst,int radix); #if (!defined(HAVE_STRTOULL) || defined(NO_STRTOLL_PROTO)) extern longlong strtoll(const char *str, char **ptr, int base); diff --git a/include/ma_dyncol.h b/include/ma_dyncol.h new file mode 100644 index 00000000000..6174328d62a --- /dev/null +++ b/include/ma_dyncol.h @@ -0,0 +1,147 @@ +/* Copyright (c) 2011, Monty Program Ab + Copyright (c) 2011, Oleksandr Byelkin + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. +*/ + +#ifndef ma_dyncol_h +#define ma_dyncol_h + +#include <decimal.h> +#include <my_decimal_limits.h> +#include <mysql_time.h> + +/* + Max length for data in a dynamic colums. This comes from how the + how the offset are stored. +*/ +#define MAX_DYNAMIC_COLUMN_LENGTH 0X1FFFFFFFL + +/* NO and OK is the same used just to show semantics */ +#define ER_DYNCOL_NO ER_DYNCOL_OK + +enum enum_dyncol_func_result +{ + ER_DYNCOL_OK= 0, + ER_DYNCOL_YES= 1, /* For functions returning 0/1 */ + ER_DYNCOL_FORMAT= -1, /* Wrong format of the encoded string */ + ER_DYNCOL_LIMIT= -2, /* Some limit reached */ + ER_DYNCOL_RESOURCE= -3, /* Out of resourses */ + ER_DYNCOL_DATA= -4, /* Incorrect input data */ + ER_DYNCOL_UNKNOWN_CHARSET= -5 /* Unknown character set */ +}; + +typedef DYNAMIC_STRING DYNAMIC_COLUMN; + +enum enum_dynamic_column_type +{ + DYN_COL_NULL= 0, + DYN_COL_INT, + DYN_COL_UINT, + DYN_COL_DOUBLE, + DYN_COL_STRING, + DYN_COL_DECIMAL, + DYN_COL_DATETIME, + DYN_COL_DATE, + DYN_COL_TIME +}; + +typedef enum enum_dynamic_column_type DYNAMIC_COLUMN_TYPE; + +struct st_dynamic_column_value +{ + DYNAMIC_COLUMN_TYPE type; + union + { + long long long_value; + unsigned long long ulong_value; + double double_value; + struct { + LEX_STRING value; + CHARSET_INFO *charset; + } string; + struct { + decimal_digit_t buffer[DECIMAL_BUFF_LENGTH]; + decimal_t value; + } decimal; + MYSQL_TIME time_value; + } x; +}; + +typedef struct st_dynamic_column_value DYNAMIC_COLUMN_VALUE; + +enum enum_dyncol_func_result +dynamic_column_create(DYNAMIC_COLUMN *str, + uint column_nr, DYNAMIC_COLUMN_VALUE *value); + +enum enum_dyncol_func_result +dynamic_column_create_many(DYNAMIC_COLUMN *str, + uint column_count, + uint *column_numbers, + DYNAMIC_COLUMN_VALUE *values); + +enum enum_dyncol_func_result +dynamic_column_update(DYNAMIC_COLUMN *org, uint column_nr, + DYNAMIC_COLUMN_VALUE *value); +enum enum_dyncol_func_result +dynamic_column_update_many(DYNAMIC_COLUMN *str, + uint add_column_count, + uint *column_numbers, + DYNAMIC_COLUMN_VALUE *values); + +enum enum_dyncol_func_result +dynamic_column_delete(DYNAMIC_COLUMN *org, uint column_nr); + +enum enum_dyncol_func_result +dynamic_column_exists(DYNAMIC_COLUMN *org, uint column_nr); + +/* List of not NULL columns */ +enum enum_dyncol_func_result +dynamic_column_list(DYNAMIC_COLUMN *org, DYNAMIC_ARRAY *array_of_uint); + +/* + if the column do not exists it is NULL +*/ +enum enum_dyncol_func_result +dynamic_column_get(DYNAMIC_COLUMN *org, uint column_nr, + DYNAMIC_COLUMN_VALUE *store_it_here); + +#define dynamic_column_initialize(A) memset((A), 0, sizeof(*(A))) +#define dynamic_column_column_free(V) dynstr_free(V) + +/*************************************************************************** + Internal functions, don't use if you don't know what you are doing... +***************************************************************************/ + +#define dynamic_column_reassociate(V,P,L, A) dynstr_reassociate((V),(P),(L),(A)) + +#define dynamic_column_value_init(V) (V)->type= DYN_COL_NULL + +/* + Prepare value for using as decimal +*/ +void dynamic_column_prepare_decimal(DYNAMIC_COLUMN_VALUE *value); + +#endif diff --git a/include/maria.h b/include/maria.h index 328cb491bca..0844e3f58c4 100644 --- a/include/maria.h +++ b/include/maria.h @@ -24,7 +24,6 @@ extern "C" { #include <my_base.h> #include <my_sys.h> #include <m_ctype.h> -#include "../storage/maria/ma_pagecache.h" #include "my_handler.h" #include "my_compare.h" #include "ft_global.h" @@ -271,7 +270,6 @@ extern my_bool maria_flush, maria_single_user, maria_page_checksums; extern my_bool maria_delay_key_write; extern my_off_t maria_max_temp_length; extern ulong maria_bulk_insert_tree_size, maria_data_pointer_size; -extern PAGECACHE maria_pagecache_var, *maria_pagecache; extern MY_TMPDIR *maria_tmpdir; /* This is used to check if a symlink points into the mysql data home, @@ -356,71 +354,6 @@ typedef struct st_maria_bit_buff uint error; } MARIA_BIT_BUFF; - -typedef struct st_maria_sort_info -{ -#ifdef THREAD - /* sync things */ - pthread_mutex_t mutex; - pthread_cond_t cond; -#endif - MARIA_HA *info, *new_info; - HA_CHECK *param; - char *buff; - SORT_KEY_BLOCKS *key_block, *key_block_end; - SORT_FT_BUF *ft_buf; - my_off_t filelength, dupp, buff_length; - pgcache_page_no_t page; - ha_rows max_records; - uint current_key, total_keys; - uint got_error, threads_running; - myf myf_rw; - enum data_file_type new_data_file_type, org_data_file_type; -} MARIA_SORT_INFO; - -typedef struct st_maria_sort_param -{ - pthread_t thr; - IO_CACHE read_cache, tempfile, tempfile_for_exceptions; - DYNAMIC_ARRAY buffpek; - MARIA_BIT_BUFF bit_buff; /* For parallel repair of packrec. */ - - MARIA_KEYDEF *keyinfo; - MARIA_SORT_INFO *sort_info; - HA_KEYSEG *seg; - uchar **sort_keys; - uchar *rec_buff; - void *wordlist, *wordptr; - MEM_ROOT wordroot; - uchar *record; - MY_TMPDIR *tmpdir; - - /* - The next two are used to collect statistics, see maria_update_key_parts for - description. - */ - ulonglong unique[HA_MAX_KEY_SEG+1]; - ulonglong notnull[HA_MAX_KEY_SEG+1]; - - MARIA_RECORD_POS pos,max_pos,filepos,start_recpos, current_filepos; - uint key, key_length,real_key_length,sortbuff_size; - uint maxbuffers, keys, find_length, sort_keys_length; - my_bool fix_datafile, master; - my_bool calc_checksum; /* calculate table checksum */ - size_t rec_buff_size; - - int (*key_cmp)(struct st_maria_sort_param *, const void *, const void *); - int (*key_read)(struct st_maria_sort_param *, uchar *); - int (*key_write)(struct st_maria_sort_param *, const uchar *); - void (*lock_in_memory)(HA_CHECK *); - int (*write_keys)(struct st_maria_sort_param *, register uchar **, - uint , struct st_buffpek *, IO_CACHE *); - uint (*read_to_buffer)(IO_CACHE *,struct st_buffpek *, uint); - int (*write_key)(struct st_maria_sort_param *, IO_CACHE *,uchar *, - uint, uint); -} MARIA_SORT_PARAM; - - /* functions in maria_check */ void maria_chk_init(HA_CHECK *param); void maria_chk_init_for_check(HA_CHECK *param, MARIA_HA *info); @@ -448,7 +381,6 @@ int maria_filecopy(HA_CHECK *param, File to, File from, my_off_t start, my_off_t length, const char *type); int maria_movepoint(MARIA_HA *info, uchar *record, my_off_t oldpos, my_off_t newpos, uint prot_key); -int maria_write_data_suffix(MARIA_SORT_INFO *sort_info, my_bool fix_datafile); int maria_test_if_almost_full(MARIA_HA *info); int maria_recreate_table(HA_CHECK *param, MARIA_HA **org_info, char *filename); int maria_disable_indexes(MARIA_HA *info); @@ -461,13 +393,11 @@ my_bool maria_test_if_sort_rep(MARIA_HA *info, ha_rows rows, ulonglong key_map, int maria_init_bulk_insert(MARIA_HA *info, ulong cache_size, ha_rows rows); void maria_flush_bulk_insert(MARIA_HA *info, uint inx); void maria_end_bulk_insert(MARIA_HA *info); -int maria_assign_to_pagecache(MARIA_HA *info, ulonglong key_map, - PAGECACHE *key_cache); -void maria_change_pagecache(PAGECACHE *old_key_cache, - PAGECACHE *new_key_cache); int maria_preload(MARIA_HA *info, ulonglong key_map, my_bool ignore_leaves); void maria_versioning(MARIA_HA *info, my_bool versioning); void maria_ignore_trids(MARIA_HA *info); +uint maria_max_key_length(void); +#define maria_max_key_segments() HA_MAX_KEY_SEG /* fulltext functions */ FT_INFO *maria_ft_init_search(uint,void *, uint, uchar *, size_t, diff --git a/include/my_base.h b/include/my_base.h index 6d58cf8071a..e33a9fbcfb8 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -54,6 +54,7 @@ /* Internal temp table, used for temporary results */ #define HA_OPEN_INTERNAL_TABLE 512 #define HA_OPEN_MERGE_TABLE 1024 +#define HA_OPEN_FOR_STATUS 2048 /* The following is parameter to ha_rkey() how to use key */ @@ -447,7 +448,8 @@ enum ha_base_keytype { #define HA_ERR_FILE_TOO_SHORT 175 /* File too short */ #define HA_ERR_WRONG_CRC 176 /* Wrong CRC on page */ #define HA_ERR_TOO_MANY_CONCURRENT_TRXS 177 /*Too many active concurrent transactions */ - +#define HA_ERR_ABORTED_BY_USER 178 +#define HA_ERR_DISK_FULL 179 #define HA_ERR_ROW_NOT_VISIBLE 180 /*Too many active concurrent transactions */ #define HA_ERR_TABLE_IN_FK_CHECK 181 /* Table being used in foreign key check */ #define HA_ERR_LAST 181 /* Copy of last error nr */ @@ -524,7 +526,7 @@ enum en_fieldtype { }; enum data_file_type { - STATIC_RECORD, DYNAMIC_RECORD, COMPRESSED_RECORD, BLOCK_RECORD + STATIC_RECORD, DYNAMIC_RECORD, COMPRESSED_RECORD, BLOCK_RECORD, NO_RECORD }; /* For key ranges */ @@ -547,11 +549,13 @@ typedef struct st_key_range enum ha_rkey_function flag; } key_range; +typedef void *range_id_t; + typedef struct st_key_multi_range { key_range start_key; key_range end_key; - char *ptr; /* Free to use by caller (ptr to row etc) */ + range_id_t ptr; /* Free to use by caller (ptr to row etc) */ uint range_flag; /* key range flags see above */ } KEY_MULTI_RANGE; diff --git a/include/my_bitmap.h b/include/my_bitmap.h index a98dd58bd72..99dcdafb784 100644 --- a/include/my_bitmap.h +++ b/include/my_bitmap.h @@ -57,6 +57,10 @@ extern my_bool bitmap_test_and_clear(MY_BITMAP *map, uint bitmap_bit); extern my_bool bitmap_fast_test_and_set(MY_BITMAP *map, uint bitmap_bit); extern my_bool bitmap_union_is_set_all(const MY_BITMAP *map1, const MY_BITMAP *map2); +extern my_bool bitmap_exists_intersection(const MY_BITMAP **bitmap_array, + uint bitmap_count, + uint start_bit, uint end_bit); + extern uint bitmap_set_next(MY_BITMAP *map); extern uint bitmap_get_first(const MY_BITMAP *map); extern uint bitmap_get_first_set(const MY_BITMAP *map); diff --git a/include/my_compare.h b/include/my_compare.h index fc607a5b6c6..058d6b6d94a 100644 --- a/include/my_compare.h +++ b/include/my_compare.h @@ -92,6 +92,32 @@ extern int ha_key_cmp(register HA_KEYSEG *keyseg, register const uchar *a, uint32 nextflag, uint *diff_pos); extern HA_KEYSEG *ha_find_null(HA_KEYSEG *keyseg, const uchar *a); +/** + Return values of index_cond_func_xxx functions. + + 0=ICP_NO_MATCH - index tuple doesn't satisfy the pushed index condition (the + engine should discard the tuple and go to the next one) + 1=ICP_MATCH - index tuple satisfies the pushed index condition (the + engine should fetch and return the record) + 2=ICP_OUT_OF_RANGE - index tuple is out range that we're scanning, e.g. this + if we're scanning "t.key BETWEEN 10 AND 20" and got a + "t.key=21" tuple (the engine should stop scanning and + return HA_ERR_END_OF_FILE right away). + 3=ICP_ABORTED_BY_USER - engine must stop scanning and should return + HA_ERR_ABORTED_BY_USER right away + -1= ICP_ERROR - Reserved for internal errors in engines. Should not be + returned by index_cond_func_xxx +*/ + +typedef enum icp_result { + ICP_ERROR=-1, + ICP_NO_MATCH=0, + ICP_MATCH=1, + ICP_OUT_OF_RANGE=2, + ICP_ABORTED_BY_USER=3, +} ICP_RESULT; + + #ifdef __cplusplus } #endif diff --git a/include/my_decimal_limits.h b/include/my_decimal_limits.h new file mode 100644 index 00000000000..ecc544dc164 --- /dev/null +++ b/include/my_decimal_limits.h @@ -0,0 +1,31 @@ +#ifndef my_decimal_limits_h +#define my_decimal_limits_h + +#define DECIMAL_LONGLONG_DIGITS 22 +#define DECIMAL_LONG_DIGITS 10 +#define DECIMAL_LONG3_DIGITS 8 + +/** maximum length of buffer in our big digits (uint32). */ +#define DECIMAL_BUFF_LENGTH 9 + +/* the number of digits that my_decimal can possibly contain */ +#define DECIMAL_MAX_POSSIBLE_PRECISION (DECIMAL_BUFF_LENGTH * 9) + + +/** + maximum guaranteed precision of number in decimal digits (number of our + digits * number of decimal digits in one our big digit - number of decimal + digits in one our big digit decreased by 1 (because we always put decimal + point on the border of our big digits)) +*/ +#define DECIMAL_MAX_PRECISION (DECIMAL_MAX_POSSIBLE_PRECISION - 8*2) +#define DECIMAL_MAX_SCALE 30 +#define DECIMAL_NOT_SPECIFIED 31 + +/** + maximum length of string representation (number of maximum decimal + digits + 1 position for sign + 1 position for decimal point, no terminator) +*/ +#define DECIMAL_MAX_STR_LENGTH (DECIMAL_MAX_POSSIBLE_PRECISION + 2) + +#endif diff --git a/include/my_dir.h b/include/my_dir.h index 06509a3af19..90d708ac811 100644 --- a/include/my_dir.h +++ b/include/my_dir.h @@ -69,7 +69,11 @@ typedef struct my_stat #else +#if(_MSC_VER) +#define MY_STAT struct _stati64 /* 64 bit file size */ +#else #define MY_STAT struct stat /* Orginal struct have what we need */ +#endif #endif /* USE_MY_STAT_STRUCT */ diff --git a/include/my_global.h b/include/my_global.h index 9d982373545..41ab8bc518d 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -41,6 +41,8 @@ #undef __WIN__ #undef __WIN32__ #define HAVE_ERRNO_AS_DEFINE +#define _POSIX_MONOTONIC_CLOCK +#define _POSIX_THREAD_CPUTIME #endif /* __CYGWIN__ */ #if defined(__QNXNTO__) && !defined(FD_SETSIZE) @@ -791,7 +793,41 @@ typedef SOCKET_SIZE_TYPE size_socket; #define FN_DIRSEP "/" /* Valid directory separators */ #define FN_ROOTDIR "/" #endif -#define MY_NFILE 64 /* This is only used to save filenames */ + +/* + MY_FILE_MIN is Windows speciality and is used to quickly detect + the mismatch of CRT and mysys file IO usage on Windows at runtime. + CRT file descriptors can be in the range 0-2047, whereas descriptors returned + by my_open() will start with 2048. If a file descriptor with value less then + MY_FILE_MIN is passed to mysys IO function, chances are it stemms from + open()/fileno() and not my_open()/my_fileno. + + For Posix, mysys functions are light wrappers around libc, and MY_FILE_MIN + is logically 0. +*/ + +#ifdef _WIN32 +#define MY_FILE_MIN 2048 +#else +#define MY_FILE_MIN 0 +#endif + +/* + MY_NFILE is the default size of my_file_info array. + + It is larger on Windows, because it all file handles are stored in my_file_info + Default size is 16384 and this should be enough for most cases.If it is not + enough, --max-open-files with larger value can be used. + + For Posix , my_file_info array is only used to store filenames for + error reporting and its size is not a limitation for number of open files. +*/ +#ifdef _WIN32 +#define MY_NFILE (16384 + MY_FILE_MIN) +#else +#define MY_NFILE 64 +#endif + #ifndef OS_FILE_LIMIT #define OS_FILE_LIMIT UINT_MAX #endif @@ -828,9 +864,8 @@ typedef SOCKET_SIZE_TYPE size_socket; /* Some things that this system doesn't have */ #define NO_HASH /* Not needed anymore */ -#ifdef __WIN__ -#define NO_DIR_LIBRARY /* Not standar dir-library */ -#define USE_MY_STAT_STRUCT /* For my_lib */ +#ifdef _WIN32 +#define NO_DIR_LIBRARY /* Not standard dir-library */ #endif /* Some defines of functions for portability */ @@ -861,10 +896,10 @@ typedef SOCKET_SIZE_TYPE size_socket; #define strtok_r(A,B,C) strtok((A),(B)) #endif -/* This is from the old m-machine.h file */ - -#if SIZEOF_LONG_LONG > 4 +#if SIZEOF_LONG_LONG >= 8 #define HAVE_LONG_LONG 1 +#else +#error WHAT? sizeof(long long) < 8 ??? #endif /* diff --git a/include/my_pthread.h b/include/my_pthread.h index fffb883912a..7057f90a89a 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -48,19 +48,30 @@ typedef struct st_pthread_link { struct st_pthread_link *next; } pthread_link; -typedef struct { - uint32 waiting; - CRITICAL_SECTION lock_waiting; - - enum { - SIGNAL= 0, - BROADCAST= 1, - MAX_EVENTS= 2 - } EVENTS; - - HANDLE events[MAX_EVENTS]; - HANDLE broadcast_block_event; - +/** + Implementation of Windows condition variables. + We use native conditions on Vista and later, and fallback to own + implementation on earlier OS version. +*/ +typedef union +{ + /* Native condition (used on Vista and later) */ + CONDITION_VARIABLE native_cond; + + /* Own implementation (used on XP) */ + struct + { + uint32 waiting; + CRITICAL_SECTION lock_waiting; + enum + { + SIGNAL= 0, + BROADCAST= 1, + MAX_EVENTS= 2 + } EVENTS; + HANDLE events[MAX_EVENTS]; + HANDLE broadcast_block_event; + }; } pthread_cond_t; @@ -75,37 +86,11 @@ typedef volatile LONG my_pthread_once_t; #define MY_PTHREAD_ONCE_INPROGRESS 1 #define MY_PTHREAD_ONCE_DONE 2 -/* - Struct and macros to be used in combination with the - windows implementation of pthread_cond_timedwait -*/ - -/* - Declare a union to make sure FILETIME is properly aligned - so it can be used directly as a 64 bit value. The value - stored is in 100ns units. - */ -union ft64 { - FILETIME ft; - __int64 i64; -}; - struct timespec { - union ft64 tv; - /* The max timeout value in millisecond for pthread_cond_timedwait */ - long max_timeout_msec; + time_t tv_sec; + long tv_nsec; }; -#define set_timespec_time_nsec(ABSTIME,TIME,NSEC) do { \ - (ABSTIME).tv.i64= (TIME)+(__int64)(NSEC)/100; \ - (ABSTIME).max_timeout_msec= (long)((NSEC)/1000000); \ -} while(0) - -#define set_timespec_nsec(ABSTIME,NSEC) do { \ - union ft64 tv; \ - GetSystemTimeAsFileTime(&tv.ft); \ - set_timespec_time_nsec((ABSTIME), tv.i64, (NSEC)); \ -} while(0) void win_pthread_init(void); int win_pthread_setspecific(void *A,void *B,uint length); @@ -442,7 +427,7 @@ int my_pthread_mutex_trylock(pthread_mutex_t *mutex); #ifndef set_timespec_nsec #define set_timespec_nsec(ABSTIME,NSEC) \ - set_timespec_time_nsec((ABSTIME),my_getsystime(),(NSEC)) + set_timespec_time_nsec((ABSTIME), my_hrtime().val*1000 + (NSEC)) #endif /* !set_timespec_nsec */ /* adapt for two different flavors of struct timespec */ @@ -455,11 +440,10 @@ int my_pthread_mutex_trylock(pthread_mutex_t *mutex); #endif /* HAVE_TIMESPEC_TS_SEC */ #ifndef set_timespec_time_nsec -#define set_timespec_time_nsec(ABSTIME,TIME,NSEC) do { \ - ulonglong nsec= (NSEC); \ - ulonglong now= (TIME) + (nsec/100); \ - (ABSTIME).MY_tv_sec= (now / ULL(10000000)); \ - (ABSTIME).MY_tv_nsec= (now % ULL(10000000) * 100 + (nsec % 100)); \ +#define set_timespec_time_nsec(ABSTIME,NSEC) do { \ + ulonglong now= (NSEC); \ + (ABSTIME).MY_tv_sec= (now / 1000000000ULL); \ + (ABSTIME).MY_tv_nsec= (now % 1000000000ULL); \ } while(0) #endif /* !set_timespec_time_nsec */ @@ -632,6 +616,45 @@ int my_pthread_fastmutex_lock(my_pthread_fastmutex_t *mp); #endif #define my_rwlock_init(A,B) rwlock_init((A),USYNC_THREAD,0) #else +#ifdef _WIN32 +/** + Implementation of Windows rwlock. + + We use native (slim) rwlocks on Win7 and later, and fallback to portable + implementation on earlier Windows. + + slim rwlock are also available on Vista/WS2008, but we do not use it + ("trylock" APIs are missing on Vista) +*/ +typedef union +{ + /* Native rwlock (is_srwlock == TRUE) */ + struct + { + SRWLOCK srwlock; /* native reader writer lock */ + BOOL have_exclusive_srwlock; /* used for unlock */ + }; + + /* + Portable implementation (is_srwlock == FALSE) + Fields are identical with Unix my_rw_lock_t fields. + */ + struct + { + pthread_mutex_t lock; /* lock for structure */ + pthread_cond_t readers; /* waiting readers */ + pthread_cond_t writers; /* waiting writers */ + int state; /* -1:writer,0:free,>0:readers */ + int waiters; /* number of waiting writers */ +#ifdef SAFE_MUTEX + pthread_t write_thread; +#endif + }; +} my_rw_lock_t; + + +#else /* _WIN32 */ + /* Use our own version of read/write locks */ typedef struct _my_rw_lock_t { pthread_mutex_t lock; /* lock for structure */ @@ -641,6 +664,8 @@ typedef struct _my_rw_lock_t { int waiters; /* number of waiting writers */ } my_rw_lock_t; +#endif /* _WIN32 */ + #define rw_lock_t my_rw_lock_t #define rw_rdlock(A) my_rw_rdlock((A)) #define rw_wrlock(A) my_rw_wrlock((A)) diff --git a/include/my_sys.h b/include/my_sys.h index 0c1ea1ae2d1..ebe643abce5 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -70,6 +70,7 @@ extern int NEAR my_errno; /* Last error in mysys */ #define MY_THREADSAFE 2048 /* my_seek(): lock fd mutex */ #define MY_SYNC 4096 /* my_copy(): sync dst file */ #define MY_SYNC_DIR 32768 /* my_create/delete/rename: sync directory */ +#define MY_SYNC_FILESIZE 65536 /* my_sync(): safe sync when file is extended */ #define MY_CHECK_ERROR 1 /* Params to my_end; Check open-close */ #define MY_GIVE_INFO 2 /* Give time info about process*/ @@ -343,11 +344,12 @@ enum file_type struct st_my_file_info { - char * name; - enum file_type type; -#if defined(THREAD) && !defined(HAVE_PREAD) - pthread_mutex_t mutex; + char *name; +#ifdef _WIN32 + HANDLE fhandle; /* win32 file handle */ + int oflag; /* open flags, e.g O_APPEND */ #endif + enum file_type type; }; extern struct st_my_file_info *my_file_info; @@ -562,6 +564,8 @@ typedef int (*qsort2_cmp)(const void *, const void *, const void *); #define my_b_tell(info) ((info)->pos_in_file + \ (size_t) (*(info)->current_pos - (info)->request_pos)) +#define my_b_write_tell(info) ((info)->pos_in_file + \ + ((info)->write_pos - (info)->write_buffer)) #define my_b_get_buffer_start(info) (info)->request_pos #define my_b_get_bytes_in_buffer(info) (char*) (info)->read_end - \ @@ -651,12 +655,12 @@ extern void *my_memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen); -#ifdef __WIN__ -extern int my_access(const char *path, int amode); -extern File my_sopen(const char *path, int oflag, int shflag, int pmode); +#ifdef _WIN32 +extern int my_access(const char *path, int amode); #else #define my_access access #endif + extern int check_if_legal_filename(const char *path); extern int check_if_legal_tablename(const char *path); @@ -667,6 +671,13 @@ extern int nt_share_delete(const char *name,myf MyFlags); #define my_delete_allow_opened(fname,flags) my_delete((fname),(flags)) #endif +#ifdef _WIN32 +/* Windows-only functions (CRT equivalents)*/ +extern File my_sopen(const char *path, int oflag, int shflag, int pmode); +extern HANDLE my_get_osfhandle(File fd); +extern void my_osmaperr(unsigned long last_error); +#endif + #ifndef TERMINATE extern void TERMINATE(FILE *file, uint flag); #endif @@ -677,6 +688,7 @@ extern FILE *my_fdopen(File Filedes,const char *name, int Flags,myf MyFlags); extern FILE *my_freopen(const char *path, const char *mode, FILE *stream); extern int my_fclose(FILE *fd,myf MyFlags); extern int my_fprintf(FILE *stream, const char* format, ...); +extern File my_fileno(FILE *fd); extern int my_chsize(File fd,my_off_t newlength, int filler, myf MyFlags); extern int my_chmod(const char *name, mode_t mode, myf my_flags); extern int my_sync(File fd, myf my_flags); @@ -865,6 +877,8 @@ extern my_bool dynstr_set(DYNAMIC_STRING *str, const char *init_str); extern my_bool dynstr_realloc(DYNAMIC_STRING *str, size_t additional_size); extern my_bool dynstr_trunc(DYNAMIC_STRING *str, size_t n); extern void dynstr_free(DYNAMIC_STRING *str); +extern void dynstr_reassociate(DYNAMIC_STRING *str, char **res, size_t *length, + size_t *alloc_length); #ifdef HAVE_MLOCK extern void *my_malloc_lock(size_t length,myf flags); extern void my_free_lock(void *ptr,myf flags); @@ -931,15 +945,23 @@ 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); -extern time_t my_time(myf flags); -extern ulonglong my_getsystime(void); -extern ulonglong my_getcputime(void); -extern ulonglong my_micro_time(); -extern ulonglong my_micro_time_and_time(time_t *time_arg); -time_t my_time_possible_from_micro(ulonglong microtime); extern my_bool my_gethwaddr(uchar *to); extern int my_getncpus(); +#define HRTIME_RESOLUTION 1000000ULL /* microseconds */ +typedef struct {ulonglong val;} my_hrtime_t; +void my_time_init(); +extern my_hrtime_t my_hrtime(); +extern ulonglong my_interval_timer(void); +extern ulonglong my_getcputime(void); + +#define microsecond_interval_timer() (my_interval_timer()/1000) +#define hrtime_to_time(X) ((X).val/HRTIME_RESOLUTION) +#define hrtime_from_time(X) ((ulonglong)((X)*HRTIME_RESOLUTION)) +#define hrtime_to_double(X) ((X).val/(double)HRTIME_RESOLUTION) +#define hrtime_sec_part(X) ((ulong)((X).val % HRTIME_RESOLUTION)) +#define my_time(X) hrtime_to_time(my_hrtime()) + #ifdef HAVE_SYS_MMAN_H #include <sys/mman.h> diff --git a/include/my_time.h b/include/my_time.h index 3e198d9c8e1..dbef712a038 100644 --- a/include/my_time.h +++ b/include/my_time.h @@ -49,7 +49,7 @@ typedef long my_time_t; #define TIMESTAMP_MAX_YEAR 2038 #define TIMESTAMP_MIN_YEAR (1900 + YY_PART_YEAR - 1) #define TIMESTAMP_MAX_VALUE INT_MAX32 -#define TIMESTAMP_MIN_VALUE 1 +#define TIMESTAMP_MIN_VALUE 0 /* two-digit years < this are 20..; >= this are 19.. */ #define YY_PART_YEAR 70 @@ -70,6 +70,7 @@ typedef long my_time_t; /* Flags to str_to_datetime */ #define TIME_FUZZY_DATE 1 #define TIME_DATETIME_ONLY 2 +#define TIME_TIME_ONLY 4 /* Must be same as MODE_NO_ZERO_IN_DATE */ #define TIME_NO_ZERO_IN_DATE (65536L*2*2*2*2*2*2*2) /* Must be same as MODE_NO_ZERO_DATE */ @@ -83,28 +84,46 @@ typedef long my_time_t; #define TIME_MAX_HOUR 838 #define TIME_MAX_MINUTE 59 #define TIME_MAX_SECOND 59 -#define TIME_MAX_VALUE (TIME_MAX_HOUR*10000 + TIME_MAX_MINUTE*100 + \ - TIME_MAX_SECOND) +#define TIME_MAX_SECOND_PART 999999 +#define TIME_SECOND_PART_FACTOR (TIME_MAX_SECOND_PART+1) +#define TIME_SECOND_PART_DIGITS 6 +#define TIME_MAX_VALUE (TIME_MAX_HOUR*10000 + TIME_MAX_MINUTE*100 + TIME_MAX_SECOND) #define TIME_MAX_VALUE_SECONDS (TIME_MAX_HOUR * 3600L + \ TIME_MAX_MINUTE * 60L + TIME_MAX_SECOND) my_bool check_date(const MYSQL_TIME *ltime, my_bool not_zero_date, ulong flags, int *was_cut); enum enum_mysql_timestamp_type +str_to_time(const char *str, uint length, MYSQL_TIME *l_time, + ulong flag, int *warning); +enum enum_mysql_timestamp_type str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time, - uint flags, int *was_cut); -longlong number_to_datetime(longlong nr, MYSQL_TIME *time_res, + ulong flags, int *was_cut); +longlong number_to_datetime(longlong nr, ulong sec_part, MYSQL_TIME *time_res, uint flags, int *was_cut); + +static inline +longlong double_to_datetime(double nr, MYSQL_TIME *ltime, uint flags, int *cut) +{ + if (nr < 0 || nr > LONGLONG_MAX) + nr= (double)LONGLONG_MAX; + return number_to_datetime((longlong) floor(nr), + (ulong)((nr-floor(nr))*TIME_SECOND_PART_FACTOR), + ltime, flags, cut); +} + +int number_to_time(my_bool neg, longlong nr, ulong sec_part, + MYSQL_TIME *ltime, int *was_cut); ulonglong TIME_to_ulonglong_datetime(const MYSQL_TIME *); ulonglong TIME_to_ulonglong_date(const MYSQL_TIME *); ulonglong TIME_to_ulonglong_time(const MYSQL_TIME *); ulonglong TIME_to_ulonglong(const MYSQL_TIME *); +double TIME_to_double(const MYSQL_TIME *my_time); +longlong pack_time(MYSQL_TIME *my_time); +MYSQL_TIME *unpack_time(longlong packed, MYSQL_TIME *my_time); -my_bool str_to_time(const char *str,uint length, MYSQL_TIME *l_time, - int *warning); - -int check_time_range(struct st_mysql_time *, int *warning); +int check_time_range(struct st_mysql_time *my_time, uint dec, int *warning); long calc_daynr(uint year,uint month,uint day); uint calc_days_in_year(uint year); @@ -137,8 +156,7 @@ static inline my_bool validate_timestamp_range(const MYSQL_TIME *t) } my_time_t -my_system_gmt_sec(const MYSQL_TIME *t, long *my_timezone, - my_bool *in_dst_time_gap); +my_system_gmt_sec(const MYSQL_TIME *t, long *my_timezone, uint *error_code); void set_zero_time(MYSQL_TIME *tm, enum enum_mysql_timestamp_type time_type); @@ -151,11 +169,28 @@ void set_zero_time(MYSQL_TIME *tm, enum enum_mysql_timestamp_type time_type); sent using binary protocol fit in this buffer. */ #define MAX_DATE_STRING_REP_LENGTH 30 +#define AUTO_SEC_PART_DIGITS 31 /* same as NOT_FIXED_DEC */ -int my_time_to_str(const MYSQL_TIME *l_time, char *to); +int my_time_to_str(const MYSQL_TIME *l_time, char *to, uint digits); int my_date_to_str(const MYSQL_TIME *l_time, char *to); -int my_datetime_to_str(const MYSQL_TIME *l_time, char *to); -int my_TIME_to_str(const MYSQL_TIME *l_time, char *to); +int my_datetime_to_str(const MYSQL_TIME *l_time, char *to, uint digits); +int my_TIME_to_str(const MYSQL_TIME *l_time, char *to, uint digits); + +static inline longlong sec_part_shift(longlong second_part, uint digits) +{ + return second_part / (longlong)log_10_int[TIME_SECOND_PART_DIGITS - digits]; +} +static inline longlong sec_part_unshift(longlong second_part, uint digits) +{ + return second_part * (longlong)log_10_int[TIME_SECOND_PART_DIGITS - digits]; +} +static inline ulong sec_part_truncate(ulong second_part, uint digits) +{ + /* the cast here should be unnecessary! */ + return second_part - second_part % (ulong)log_10_int[TIME_SECOND_PART_DIGITS - digits]; +} + +#define hrtime_to_my_time(X) ((my_time_t)hrtime_to_time(X)) /* Available interval types used in any statement. diff --git a/include/my_tree.h b/include/my_tree.h index ceeb849ad0c..3aeef20e0ad 100644 --- a/include/my_tree.h +++ b/include/my_tree.h @@ -30,7 +30,17 @@ extern "C" { #define tree_set_pointer(element,ptr) *((uchar **) (element+1))=((uchar*) (ptr)) +/* + A tree with its flag set to TREE_ONLY_DUPS behaves differently on inserting + an element that is not in the tree: + the element is not added at all, but instead tree_insert() returns a special + address TREE_ELEMENT_UNIQUE as an indication that the function has not failed + due to lack of memory. +*/ + +#define TREE_ELEMENT_UNIQUE ((TREE_ELEMENT *) 1) #define TREE_NO_DUPS 1 +#define TREE_ONLY_DUPS 2 typedef enum { left_root_right, right_root_left } TREE_WALK; typedef uint32 element_count; diff --git a/include/myisam.h b/include/myisam.h index 34ed58d354c..14ef24c99ff 100644 --- a/include/myisam.h +++ b/include/myisam.h @@ -300,6 +300,8 @@ extern ulong _mi_calc_blob_length(uint length , const uchar *pos); extern uint mi_get_pointer_length(ulonglong file_length, uint def); extern int mi_make_backup_of_index(struct st_myisam_info *info, time_t backup_time, myf flags); +#define myisam_max_key_length() HA_MAX_KEY_LENGTH +#define myisam_max_key_segments() HA_MAX_KEY_SEG #define MEMMAP_EXTRA_MARGIN 7 /* Write this as a suffix for mmap file */ /* this is used to pass to mysql_myisamchk_table */ diff --git a/include/myisamchk.h b/include/myisamchk.h index e8f1ce576bf..f85824e76bb 100644 --- a/include/myisamchk.h +++ b/include/myisamchk.h @@ -155,6 +155,11 @@ typedef struct st_handler_check_param char temp_filename[FN_REFLEN]; IO_CACHE read_cache; enum_handler_stats_method stats_method; + /* For reporting progress */ + uint stage, max_stage; + uint progress_counter; /* How often to call _report_progress() */ + ulonglong progress, max_progress; + #ifdef THREAD pthread_mutex_t print_msg_mutex; my_bool need_print_msg_lock; diff --git a/include/mysql.h b/include/mysql.h index 8a94a4d3a09..4849df2c143 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -171,7 +171,8 @@ enum mysql_option MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION, MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH, MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT, - MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_PLUGIN_DIR, MYSQL_DEFAULT_AUTH + MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_PLUGIN_DIR, MYSQL_DEFAULT_AUTH, + MYSQL_PROGRESS_CALLBACK }; /** diff --git a/include/mysql.h.pp b/include/mysql.h.pp index 44f07c8a541..bb75af4554a 100644 --- a/include/mysql.h.pp +++ b/include/mysql.h.pp @@ -67,8 +67,8 @@ enum mysql_enum_shutdown_level { SHUTDOWN_WAIT_UPDATES= (unsigned char)(1 << 3), SHUTDOWN_WAIT_ALL_BUFFERS= ((unsigned char)(1 << 3) << 1), SHUTDOWN_WAIT_CRITICAL_BUFFERS= ((unsigned char)(1 << 3) << 1) + 1, - KILL_QUERY= 254, - KILL_CONNECTION= 255 + SHUTDOWN_KILL_QUERY= 254, + SHUTDOWN_KILL_CONNECTION= 255 }; enum enum_cursor_type { @@ -100,7 +100,8 @@ int my_connect(my_socket s, const struct sockaddr *name, unsigned int namelen, struct my_rnd_struct; enum Item_result { - STRING_RESULT=0, REAL_RESULT, INT_RESULT, ROW_RESULT, DECIMAL_RESULT + STRING_RESULT=0, REAL_RESULT, INT_RESULT, ROW_RESULT, DECIMAL_RESULT, + TIME_RESULT }; typedef struct st_udf_args { @@ -258,7 +259,8 @@ enum mysql_option MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION, MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH, MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT, - MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_PLUGIN_DIR, MYSQL_DEFAULT_AUTH + MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_PLUGIN_DIR, MYSQL_DEFAULT_AUTH, + MYSQL_PROGRESS_CALLBACK }; struct st_mysql_options_extention; struct st_mysql_options { diff --git a/include/mysql/plugin.h b/include/mysql/plugin.h index b8f4ad6f3fc..d7189ff30b7 100644 --- a/include/mysql/plugin.h +++ b/include/mysql/plugin.h @@ -1,5 +1,5 @@ -/* - Copyright (c) 2005, 2010, Oracle and/or its affiliates +/* Copyright (c) 2005, 2010, Oracle and/or its affiliates + Copyright (C) 2009-2011 Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -72,7 +72,7 @@ typedef struct st_mysql_xid MYSQL_XID; /* MySQL plugin interface version */ #define MYSQL_PLUGIN_INTERFACE_VERSION 0x0101 /* MariaDB plugin interface version */ -#define MARIA_PLUGIN_INTERFACE_VERSION 0x0100 +#define MARIA_PLUGIN_INTERFACE_VERSION 0x0101 /* The allowable types of plugins @@ -765,10 +765,6 @@ char *thd_security_context(MYSQL_THD thd, char *buffer, unsigned int length, /* Increments the row counter, see THD::row_count */ void thd_inc_row_count(MYSQL_THD thd); -#define thd_proc_info(thd, msg) set_thd_proc_info(thd, msg, __func__, __FILE__, __LINE__) -const char *set_thd_proc_info(MYSQL_THD, const char * info, const char *func, - const char *file, const unsigned int line); - /** Create a temporary file. diff --git a/include/mysql/plugin_auth.h.pp b/include/mysql/plugin_auth.h.pp index b0d5daf4c64..e4878d28f94 100644 --- a/include/mysql/plugin_auth.h.pp +++ b/include/mysql/plugin_auth.h.pp @@ -31,6 +31,27 @@ void *thd_memdup(void* thd, const void* str, unsigned int size); MYSQL_LEX_STRING *thd_make_lex_string(void* thd, MYSQL_LEX_STRING *lex_str, const char *str, unsigned int size, int allocate_lex_string); +#include <mysql/service_progress_report.h> +extern struct progress_report_service_st { + void (*thd_progress_init_func)(void* thd, unsigned int max_stage); + void (*thd_progress_report_func)(void* thd, + unsigned long long progress, + unsigned long long max_progress); + void (*thd_progress_next_stage_func)(void* thd); + void (*thd_progress_end_func)(void* thd); + const char *(*set_thd_proc_info_func)(void*, const char *info, + const char *func, + const char *file, + unsigned int line); +} *progress_report_service; +void thd_progress_init(void* thd, unsigned int max_stage); +void thd_progress_report(void* thd, + unsigned long long progress, + unsigned long long max_progress); +void thd_progress_next_stage(void* thd); +void thd_progress_end(void* thd); +const char *set_thd_proc_info(void*, const char * info, const char *func, + const char *file, unsigned int line); struct st_mysql_xid { long formatID; long gtrid_length; @@ -166,8 +187,6 @@ int thd_tx_isolation(const void* thd); char *thd_security_context(void* thd, char *buffer, unsigned int length, unsigned int max_query_len); void thd_inc_row_count(void* thd); -const char *set_thd_proc_info(void*, const char * info, const char *func, - const char *file, const unsigned int line); int mysql_tmpfile(const char *prefix); int thd_killed(const void* thd); unsigned long thd_get_thread_id(const void* thd); diff --git a/include/mysql/service_progress_report.h b/include/mysql/service_progress_report.h new file mode 100644 index 00000000000..670b1c37630 --- /dev/null +++ b/include/mysql/service_progress_report.h @@ -0,0 +1,82 @@ +#ifndef MYSQL_SERVICE_PROGRESS_REPORT_INCLUDED +/* Copyright (C) 2011 Monty Program Ab + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/** + @file + This service allows plugins to report progress of long running operations + to the server. The progress report is visible in SHOW PROCESSLIST, + INFORMATION_SCHEMA.PROCESSLIST, and is sent to the client + if requested. + + The functions are documented at + http://kb.askmonty.org/en/progress-reporting#how-to-add-support-for-progress-reporting-to-a-storage-engine +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#define thd_proc_info(thd, msg) set_thd_proc_info(thd, msg, \ + __func__, __FILE__, __LINE__) + +extern struct progress_report_service_st { + void (*thd_progress_init_func)(MYSQL_THD thd, unsigned int max_stage); + void (*thd_progress_report_func)(MYSQL_THD thd, + unsigned long long progress, + unsigned long long max_progress); + void (*thd_progress_next_stage_func)(MYSQL_THD thd); + void (*thd_progress_end_func)(MYSQL_THD thd); + const char *(*set_thd_proc_info_func)(MYSQL_THD, const char *info, + const char *func, + const char *file, + unsigned int line); +} *progress_report_service; + +#ifdef MYSQL_DYNAMIC_PLUGIN + +#define thd_progress_init(thd,max_stage) (progress_report_service->thd_progress_init_func((thd),(max_stage))) +#define thd_progress_report(thd, progress, max_progress) (progress_report_service->thd_progress_report_func((thd), (progress), (max_progress))) +#define thd_progress_next_stage(thd) (progress_report_service->thd_progress_next_stage_func(thd)) +#define thd_progress_end(thd) (progress_report_service->thd_progress_end_func(thd)) +#define set_thd_proc_info(thd,info,func,file,line) (progress_report_service->set_thd_proc_info_func((thd),(info),(func),(file),(line))) + +#else + +/** + Report progress for long running operations + + @param thd User thread connection handle + @param progress Where we are now + @param max_progress Progress will continue up to this +*/ +void thd_progress_init(MYSQL_THD thd, unsigned int max_stage); +void thd_progress_report(MYSQL_THD thd, + unsigned long long progress, + unsigned long long max_progress); +void thd_progress_next_stage(MYSQL_THD thd); +void thd_progress_end(MYSQL_THD thd); +const char *set_thd_proc_info(MYSQL_THD, const char * info, const char *func, + const char *file, unsigned int line); + +#endif + +#ifdef __cplusplus +} +#endif + +#define MYSQL_SERVICE_PROGRESS_REPORT_INCLUDED +#endif + diff --git a/include/mysql/services.h b/include/mysql/services.h index 19003e66b96..b8cdfc3510d 100644 --- a/include/mysql/services.h +++ b/include/mysql/services.h @@ -20,6 +20,7 @@ extern "C" { #include <mysql/service_my_snprintf.h> #include <mysql/service_thd_alloc.h> +#include <mysql/service_progress_report.h> #ifdef __cplusplus } diff --git a/include/mysql_com.h b/include/mysql_com.h index ec38d516172..29869254171 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -161,6 +161,7 @@ enum enum_server_command #define REFRESH_QUERY_CACHE_FREE 0x20000L /* pack query cache */ #define REFRESH_DES_KEY_FILE 0x40000L #define REFRESH_USER_RESOURCES 0x80000L +#define REFRESH_CHECKPOINT 0x100000L /* Don't do checkpoints */ #define CLIENT_LONG_PASSWORD 1 /* new more secure passwords */ #define CLIENT_FOUND_ROWS 2 /* Found instead of affected rows */ @@ -182,6 +183,7 @@ enum enum_server_command #define CLIENT_MULTI_RESULTS (1UL << 17) /* Enable/disable multi-results */ #define CLIENT_PLUGIN_AUTH (1UL << 19) /* Client supports plugin authentication */ +#define CLIENT_PROGRESS (1UL << 29) /* Client support progress indicator */ #define CLIENT_SSL_VERIFY_SERVER_CERT (1UL << 30) #define CLIENT_REMEMBER_OPTIONS (1UL << 31) @@ -213,6 +215,7 @@ enum enum_server_command CLIENT_MULTI_RESULTS | \ CLIENT_SSL_VERIFY_SERVER_CERT | \ CLIENT_REMEMBER_OPTIONS | \ + CLIENT_PROGRESS | \ CLIENT_PLUGIN_AUTH) /* @@ -407,12 +410,15 @@ enum mysql_enum_shutdown_level { /* don't flush InnoDB buffers, flush other storage engines' buffers*/ SHUTDOWN_WAIT_CRITICAL_BUFFERS= (MYSQL_SHUTDOWN_KILLABLE_UPDATE << 1) + 1, /* Now the 2 levels of the KILL command */ -#if MYSQL_VERSION_ID >= 50000 - KILL_QUERY= 254, -#endif - KILL_CONNECTION= 255 + SHUTDOWN_KILL_QUERY= 254, + SHUTDOWN_KILL_CONNECTION= 255 }; +/* Compatibility */ +#if !defined(MYSQL_SERVER) && defined(USE_OLD_FUNCTIONS) +#define KILL_QUERY SHUTDOWN_KILL_QUERY +#define KILL_CONNECTION SHUTDOWN_KILL_CONNECTION +#endif enum enum_cursor_type { @@ -471,7 +477,8 @@ struct my_rnd_struct; enum Item_result { - STRING_RESULT=0, REAL_RESULT, INT_RESULT, ROW_RESULT, DECIMAL_RESULT + STRING_RESULT=0, REAL_RESULT, INT_RESULT, ROW_RESULT, DECIMAL_RESULT, + TIME_RESULT #ifdef MYSQL_SERVER ,IMPOSSIBLE_RESULT /* Yes, we know this is ugly, don't tell us */ #endif diff --git a/include/queues.h b/include/queues.h index d01b73ba999..efe78feb264 100644 --- a/include/queues.h +++ b/include/queues.h @@ -1,23 +1,31 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (C) 2010 Monty Program Ab + All Rights reserved - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the following disclaimer + in the documentation and/or other materials provided with the + distribution. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. +*/ /* Code for generell handling of priority Queues. Implemention of queues from "Algoritms in C" by Robert Sedgewick. - Copyright Monty Program KB. - By monty. */ #ifndef _queues_h @@ -31,38 +39,43 @@ typedef struct st_queue { void *first_cmp_arg; uint elements; uint max_elements; - uint offset_to_key; /* compare is done on element+offset */ + uint offset_to_key; /* compare is done on element+offset */ + uint offset_to_queue_pos; /* If we want to store position in element */ + uint auto_extent; int max_at_top; /* Normally 1, set to -1 if queue_top gives max */ int (*compare)(void *, uchar *,uchar *); - uint auto_extent; } QUEUE; +#define queue_first_element(queue) 1 +#define queue_last_element(queue) (queue)->elements #define queue_top(queue) ((queue)->root[1]) -#define queue_element(queue,index) ((queue)->root[index+1]) +#define queue_element(queue,index) ((queue)->root[index]) #define queue_end(queue) ((queue)->root[(queue)->elements]) -#define queue_replaced(queue) _downheap(queue,1) +#define queue_replace_top(queue) _downheap(queue, 1, (queue)->root[1]) #define queue_set_cmp_arg(queue, set_arg) (queue)->first_cmp_arg= set_arg #define queue_set_max_at_top(queue, set_arg) \ (queue)->max_at_top= set_arg ? -1 : 1 +#define queue_remove_top(queue_arg) queue_remove((queue_arg), queue_first_element(queue_arg)) typedef int (*queue_compare)(void *,uchar *, uchar *); int init_queue(QUEUE *queue,uint max_elements,uint offset_to_key, pbool max_at_top, queue_compare compare, - void *first_cmp_arg); -int init_queue_ex(QUEUE *queue,uint max_elements,uint offset_to_key, - pbool max_at_top, queue_compare compare, - void *first_cmp_arg, uint auto_extent); + void *first_cmp_arg, uint offset_to_queue_pos, + uint auto_extent); int reinit_queue(QUEUE *queue,uint max_elements,uint offset_to_key, pbool max_at_top, queue_compare compare, - void *first_cmp_arg); + void *first_cmp_arg, uint offset_to_queue_pos, + uint auto_extent); int resize_queue(QUEUE *queue, uint max_elements); void delete_queue(QUEUE *queue); void queue_insert(QUEUE *queue,uchar *element); int queue_insert_safe(QUEUE *queue, uchar *element); uchar *queue_remove(QUEUE *queue,uint idx); +void queue_replace(QUEUE *queue,uint idx); + #define queue_remove_all(queue) { (queue)->elements= 0; } #define queue_is_full(queue) (queue->elements == queue->max_elements) -void _downheap(QUEUE *queue,uint idx); +void _downheap(QUEUE *queue, uint idx, uchar *element); void queue_fix(QUEUE *queue); #define is_queue_inited(queue) ((queue)->root != 0) diff --git a/include/service_versions.h b/include/service_versions.h index 114957cdd86..6f06b609e61 100644 --- a/include/service_versions.h +++ b/include/service_versions.h @@ -21,4 +21,5 @@ #define VERSION_my_snprintf 0x0100 #define VERSION_thd_alloc 0x0100 +#define VERSION_progress_report 0x0100 diff --git a/include/sql_common.h b/include/sql_common.h index 34b131cf331..f54bcb0e61b 100644 --- a/include/sql_common.h +++ b/include/sql_common.h @@ -31,6 +31,12 @@ extern const char *not_error_sqlstate; struct st_mysql_options_extention { char *plugin_dir; char *default_auth; + void (*report_progress)(const MYSQL *mysql, + unsigned int stage, + unsigned int max_stage, + double progress, + const char *proc_info, + uint proc_info_length); }; typedef struct st_mysql_methods diff --git a/include/thr_alarm.h b/include/thr_alarm.h index fb906039269..806735b2d38 100644 --- a/include/thr_alarm.h +++ b/include/thr_alarm.h @@ -34,7 +34,7 @@ extern "C" { typedef struct st_alarm_info { - ulong next_alarm_time; + time_t next_alarm_time; uint active_alarms; uint max_used_alarms; } ALARM_INFO; @@ -78,15 +78,17 @@ typedef int thr_alarm_entry; typedef thr_alarm_entry* thr_alarm_t; typedef struct st_alarm { - ulong expire_time; + time_t expire_time; thr_alarm_entry alarmed; /* set when alarm is due */ pthread_t thread; my_thread_id thread_id; + uint index_in_queue; my_bool malloced; } ALARM; extern uint thr_client_alarm; extern pthread_t alarm_thread; +extern my_bool my_disable_thr_alarm; #define thr_alarm_init(A) (*(A))=0 #define thr_alarm_in_use(A) (*(A)!= 0) diff --git a/include/thr_lock.h b/include/thr_lock.h index e13960d1558..5d9cccedda6 100644 --- a/include/thr_lock.h +++ b/include/thr_lock.h @@ -126,8 +126,9 @@ typedef struct st_thr_lock_data { struct st_thr_lock *lock; pthread_cond_t *cond; void *status_param; /* Param to status functions */ - void *debug_print_param; /* Used by MariaDB for TABLE ref */ + void *debug_print_param; /* For error messages */ enum thr_lock_type type; + enum thr_lock_type org_type; /* Cache for MariaDB */ uint priority; } THR_LOCK_DATA; |