diff options
Diffstat (limited to 'include')
41 files changed, 1350 insertions, 322 deletions
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index d0c4768e882..e6de8515fdc 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -25,6 +25,7 @@ SET(HEADERS mysql.h mysql_com.h mysql_com_server.h + pack.h my_byteorder.h byte_order_generic.h byte_order_generic_x86.h @@ -60,6 +61,7 @@ SET(HEADERS my_compiler.h handler_state.h handler_ername.h + json_lib.h ) INSTALL(FILES ${HEADERS} DESTINATION ${INSTALL_INCLUDEDIR} COMPONENT Development) diff --git a/include/atomic/nolock.h b/include/atomic/nolock.h deleted file mode 100644 index 2137445a075..00000000000 --- a/include/atomic/nolock.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef ATOMIC_NOLOCK_INCLUDED -#define ATOMIC_NOLOCK_INCLUDED - -/* Copyright (c) 2006, 2010, Oracle and/or its affiliates. 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. - - 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - -#if defined(__i386__) || defined(_MSC_VER) || defined(__x86_64__) \ - || defined(HAVE_GCC_ATOMIC_BUILTINS) \ - || defined(HAVE_SOLARIS_ATOMIC) - -# ifdef MY_ATOMIC_MODE_DUMMY -# define LOCK_prefix "" -# else -# define LOCK_prefix "lock" -# endif -/* - We choose implementation as follows: - ------------------------------------ - On Windows using Visual C++ the native implementation should be - preferrable. When using gcc we prefer the Solaris implementation - before the gcc because of stability preference, we choose gcc - builtins if available, otherwise we choose the somewhat broken - native x86 implementation. If neither Visual C++ or gcc we still - choose the Solaris implementation on Solaris (mainly for SunStudio - compilers). -*/ -# if defined(_MSC_VER) -# include "generic-msvc.h" -# elif __GNUC__ -# if defined(HAVE_SOLARIS_ATOMIC) -# include "solaris.h" -# elif defined(HAVE_GCC_ATOMIC_BUILTINS) -# include "gcc_builtins.h" -# elif defined(__i386__) || defined(__x86_64__) -# include "x86-gcc.h" -# endif -# elif defined(HAVE_SOLARIS_ATOMIC) -# include "solaris.h" -# endif -#endif - -#endif /* ATOMIC_NOLOCK_INCLUDED */ diff --git a/include/atomic/x86-gcc.h b/include/atomic/x86-gcc.h index 173e32e790c..3a081d9bbc5 100644 --- a/include/atomic/x86-gcc.h +++ b/include/atomic/x86-gcc.h @@ -28,6 +28,12 @@ */ #undef MY_ATOMIC_HAS_8_AND_16 +#ifdef MY_ATOMIC_MODE_DUMMY +#define LOCK_prefix "" +#else +#define LOCK_prefix "lock" +#endif + #ifdef __x86_64__ # ifdef MY_ATOMIC_NO_XADD # define MY_ATOMIC_MODE "gcc-amd64" LOCK_prefix "-no-xadd" diff --git a/include/base64.h b/include/base64.h index 9a843b5088e..cb5ac5e0b5e 100644 --- a/include/base64.h +++ b/include/base64.h @@ -22,34 +22,34 @@ extern "C" { #endif /* - Calculate how much memory needed for dst of base64_encode() + Calculate how much memory needed for dst of my_base64_encode() */ -int base64_needed_encoded_length(int length_of_data); +int my_base64_needed_encoded_length(int length_of_data); /* - Maximum length base64_encode_needed_length() can accept with no overflow. + Maximum length my_base64_encode_needed_length() can accept with no overflow. */ -int base64_encode_max_arg_length(void); +int my_base64_encode_max_arg_length(void); /* - Calculate how much memory needed for dst of base64_decode() + Calculate how much memory needed for dst of my_base64_decode() */ -int base64_needed_decoded_length(int length_of_encoded_data); +int my_base64_needed_decoded_length(int length_of_encoded_data); /* - Maximum length base64_decode_needed_length() can accept with no overflow. + Maximum length my_base64_decode_needed_length() can accept with no overflow. */ -int base64_decode_max_arg_length(); +int my_base64_decode_max_arg_length(); /* Encode data as a base64 string */ -int base64_encode(const void *src, size_t src_len, char *dst); +int my_base64_encode(const void *src, size_t src_len, char *dst); /* Decode a base64 string into data */ -int base64_decode(const char *src, size_t src_len, +int my_base64_decode(const char *src, size_t src_len, void *dst, const char **end_ptr, int flags); /* Allow multuple chunks 'AAA= AA== AA==', binlog uses this */ diff --git a/include/byte_order_generic_x86_64.h b/include/byte_order_generic_x86_64.h index 8c7493965a9..fbc6e1f536b 100644 --- a/include/byte_order_generic_x86_64.h +++ b/include/byte_order_generic_x86_64.h @@ -16,6 +16,7 @@ /* Optimized function-like macros for the x86 architecture (_WIN32 included). */ + #define sint2korr(A) (int16) (*((int16 *) (A))) #define sint3korr(A) ((int32) ((((uchar) (A)[2]) & 128) ? \ (((uint32) 255L << 24) | \ @@ -31,17 +32,21 @@ (((uint32) ((uchar) (A)[1])) << 8) +\ (((uint32) ((uchar) (A)[2])) << 16)) #define uint4korr(A) (uint32) (*((uint32 *) (A))) -#define uint5korr(A) ((ulonglong)(((uint32) ((uchar) (A)[0])) +\ - (((uint32) ((uchar) (A)[1])) << 8) +\ - (((uint32) ((uchar) (A)[2])) << 16) +\ - (((uint32) ((uchar) (A)[3])) << 24)) +\ - (((ulonglong) ((uchar) (A)[4])) << 32)) -#define uint6korr(A) ((ulonglong)(((uint32) ((uchar) (A)[0])) + \ - (((uint32) ((uchar) (A)[1])) << 8) + \ - (((uint32) ((uchar) (A)[2])) << 16) + \ - (((uint32) ((uchar) (A)[3])) << 24)) + \ - (((ulonglong) ((uchar) (A)[4])) << 32) + \ - (((ulonglong) ((uchar) (A)[5])) << 40)) + + +static inline ulonglong uint5korr(const void *p) +{ + ulonglong a= *(uint32 *) p; + ulonglong b= *(4 + (uchar *) p); + return a | (b << 32); +} +static inline ulonglong uint6korr(const void *p) +{ + ulonglong a= *(uint32 *) p; + ulonglong b= *(uint16 *) (4 + (char *) p); + return a | (b << 32); +} + #define uint8korr(A) (ulonglong) (*((ulonglong *) (A))) #define sint8korr(A) (longlong) (*((longlong *) (A))) @@ -53,23 +58,67 @@ *(T+1)=(uchar) (((uint) (A) >> 8));\ *(T+2)=(uchar) (((A) >> 16));\ } while (0) + #define int4store(T,A) do { uchar *pT= (uchar*)(T);\ *((uint32 *) (pT))= (uint32) (A); \ } while (0) -#define int5store(T,A) do { *(T)= (uchar)((A));\ - *((T)+1)=(uchar) (((A) >> 8));\ - *((T)+2)=(uchar) (((A) >> 16));\ - *((T)+3)=(uchar) (((A) >> 24));\ - *((T)+4)=(uchar) (((A) >> 32));\ - } while(0) -#define int6store(T,A) do { *(T)= (uchar)((A)); \ - *((T)+1)=(uchar) (((A) >> 8)); \ - *((T)+2)=(uchar) (((A) >> 16)); \ - *((T)+3)=(uchar) (((A) >> 24)); \ - *((T)+4)=(uchar) (((A) >> 32)); \ - *((T)+5)=(uchar) (((A) >> 40)); \ - } while(0) +#define int5store(T,A) do { uchar *pT= (uchar*)(T);\ + *((uint32 *) (pT))= (uint32) (A); \ + *((pT)+4)=(uchar) (((A) >> 32));\ + } while (0) + +#define int6store(T,A) do { uchar *pT= (uchar*)(T);\ + *((uint32 *) (pT))= (uint32) (A); \ + *((uint16*)(pT+4))= (uint16) (A >> 32);\ + } while (0) + #define int8store(T,A) do { uchar *pT= (uchar*)(T);\ *((ulonglong *) (pT))= (ulonglong) (A);\ } while(0) + +#if defined(__GNUC__) + +#define HAVE_mi_uint5korr +#define HAVE_mi_uint6korr +#define HAVE_mi_uint7korr +#define HAVE_mi_uint78orr + +/* Read numbers stored in high-bytes-first order */ + +static inline ulonglong mi_uint5korr(const void *p) +{ + ulonglong a= *(uint32 *) p; + ulonglong b= *(4 + (uchar *) p); + ulonglong v= (a | (b << 32)) << 24; + asm ("bswapq %0" : "=r" (v) : "0" (v)); + return v; +} + +static inline ulonglong mi_uint6korr(const void *p) +{ + ulonglong a= *(uint32 *) p; + ulonglong b= *(uint16 *) (4 + (char *) p); + ulonglong v= (a | (b << 32)) << 16; + asm ("bswapq %0" : "=r" (v) : "0" (v)); + return v; +} + +static inline ulonglong mi_uint7korr(const void *p) +{ + ulonglong a= *(uint32 *) p; + ulonglong b= *(uint16 *) (4 + (char *) p); + ulonglong c= *(6 + (uchar *) p); + ulonglong v= (a | (b << 32) | (c << 48)) << 8; + asm ("bswapq %0" : "=r" (v) : "0" (v)); + return v; +} + +static inline ulonglong mi_uint8korr(const void *p) +{ + ulonglong v= *(ulonglong *) p; + asm ("bswapq %0" : "=r" (v) : "0" (v)); + return v; +} + +#endif diff --git a/include/decimal.h b/include/decimal.h index 2adeb824318..39d617ae08d 100644 --- a/include/decimal.h +++ b/include/decimal.h @@ -51,7 +51,7 @@ int decimal2longlong(const decimal_t *from, longlong *to); int longlong2decimal(longlong from, decimal_t *to); int decimal2double(const decimal_t *from, double *to); int double2decimal(double from, decimal_t *to); -int decimal_actual_fraction(decimal_t *from); +int decimal_actual_fraction(const decimal_t *from); int decimal2bin(const decimal_t *from, uchar *to, int precision, int scale); int bin2decimal(const uchar *from, decimal_t *to, int precision, int scale); diff --git a/include/dur_prop.h b/include/dur_prop.h new file mode 100644 index 00000000000..558ce5acc01 --- /dev/null +++ b/include/dur_prop.h @@ -0,0 +1,32 @@ +/* Copyright (c) 2013, Oracle and/or its affiliates. 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. + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#ifndef _my_dur_prop_h +#define _my_dur_prop_h + +enum durability_properties +{ + /* + Preserves the durability properties defined by the engine + */ + HA_REGULAR_DURABILITY= 0, + /* + Ignore the durability properties defined by the engine and + write only in-memory entries. + */ + HA_IGNORE_DURABILITY= 1 +}; + +#endif /* _my_dur_prop_h */ diff --git a/include/hash.h b/include/hash.h index fde7fc30d38..892922d81a3 100644 --- a/include/hash.h +++ b/include/hash.h @@ -42,7 +42,7 @@ extern "C" { #define HASH_UNIQUE 1 /* hash_insert fails on duplicate key */ #define HASH_THREAD_SPECIFIC 2 /* Mark allocated memory THREAD_SPECIFIC */ -typedef uint my_hash_value_type; +typedef uint32 my_hash_value_type; typedef uchar *(*my_hash_get_key)(const uchar *,size_t*,my_bool); typedef my_hash_value_type (*my_hash_function)(CHARSET_INFO *, const uchar *, size_t); diff --git a/include/json_lib.h b/include/json_lib.h new file mode 100644 index 00000000000..ce7f27317bc --- /dev/null +++ b/include/json_lib.h @@ -0,0 +1,399 @@ +#ifndef JSON_LIB_INCLUDED +#define JSON_LIB_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#define JSON_DEPTH_LIMIT 32 + +/* + When error happens, the c_next of the JSON engine contains the + character that caused the error, and the c_str is the position + in string where the error occurs. +*/ +enum json_errors { + JE_BAD_CHR= -1, /* Invalid character, charset handler cannot read it. */ + + JE_NOT_JSON_CHR= -2, /* Character met not used in JSON. */ + /* ASCII 00-08 for instance. */ + + JE_EOS= -3, /* Unexpected end of string. */ + + JE_SYN= -4, /* The next character breaks the JSON syntax. */ + + JE_STRING_CONST= -5, /* Character disallowed in string constant. */ + + JE_ESCAPING= -6, /* Error in the escaping. */ + + JE_DEPTH= -7, /* The limit on the JSON depth was overrun. */ +}; + + +typedef struct st_json_string_t +{ + const uchar *c_str; /* Current position in JSON string */ + const uchar *str_end; /* The end on the string. */ + my_wc_t c_next; /* UNICODE of the last read character */ + int error; /* error code. */ + + CHARSET_INFO *cs; /* Character set of the JSON string. */ + + my_charset_conv_mb_wc wc; /* UNICODE conversion function. */ + /* It's taken out of the cs just to speed calls. */ +} json_string_t; + + +void json_string_set_cs(json_string_t *s, CHARSET_INFO *i_cs); +void json_string_set_str(json_string_t *s, + const uchar *str, const uchar *end); +#define json_next_char(j) \ + (j)->wc((j)->cs, &(j)->c_next, (j)->c_str, (j)->str_end) +#define json_eos(j) ((j)->c_str >= (j)->str_end) +/* + read_string_const_chr() reads the next character of the string constant + and saves it to the js->c_next. + It takes into account possible escapings, so if for instance + the string is '\b', the read_string_const_chr() sets 8. +*/ +int json_read_string_const_chr(json_string_t *js); + + +/* + Various JSON-related operations expect JSON path as a parameter. + The path is a string like this "$.keyA[2].*" + The path itself is a number of steps specifying either a key or a position + in an array. Some of them can be wildcards. + So the representation of the JSON path is the json_path_t class + containing an array of json_path_step_t objects. +*/ + + +/* Path step types - actually bitmasks to let '&' or '|' operations. */ +enum json_path_step_types +{ + JSON_PATH_KEY_NULL=0, + JSON_PATH_KEY=1, /* Must be equal to JSON_VALUE_OBJECT. */ + JSON_PATH_ARRAY=2, /* Must be equal to JSON_VALUE_ARRAY. */ + JSON_PATH_KEY_OR_ARRAY=3, + JSON_PATH_WILD=4, /* Step like .* or [*] */ + JSON_PATH_DOUBLE_WILD=8, /* Step like **.k or **[1] */ + JSON_PATH_KEY_WILD= 1+4, + JSON_PATH_KEY_DOUBLEWILD= 1+8, + JSON_PATH_ARRAY_WILD= 2+4, + JSON_PATH_ARRAY_DOUBLEWILD= 2+8 +}; + + +typedef struct st_json_path_step_t +{ + enum json_path_step_types type; /* The type of the step - */ + /* see json_path_step_types */ + const uchar *key; /* Pointer to the beginning of the key. */ + const uchar *key_end; /* Pointer to the end of the key. */ + uint n_item; /* Item number in an array. No meaning for the key step. */ +} json_path_step_t; + + +typedef struct st_json_path_t +{ + json_string_t s; /* The string to be parsed. */ + json_path_step_t steps[JSON_DEPTH_LIMIT]; /* Steps of the path. */ + json_path_step_t *last_step; /* Points to the last step. */ + + int mode_strict; /* TRUE if the path specified as 'strict' */ + enum json_path_step_types types_used; /* The '|' of all step's 'type'-s */ +} json_path_t; + + +int json_path_setup(json_path_t *p, + CHARSET_INFO *i_cs, const uchar *str, const uchar *end); + + +/* + The set of functions and structures below provides interface + to the JSON text parser. + Running the parser normally goes like this: + + json_engine_t j_eng; // structure keeps parser's data + json_scan_start(j_eng) // begin the parsing + + do + { + // The parser has read next piece of JSON + // and set fields of j_eng structure accordingly. + // So let's see what we have: + switch (j_eng.state) + { + case JST_KEY: + // Handle key name. See the json_read_keyname_chr() + // Probably compare it with the keyname we're looking for + case JST_VALUE: + // Handle value. It is either value of the key or an array item. + // see the json_read_value() + case JST_OBJ_START: + // parser found an object (the '{' in JSON) + case JST_OBJ_END: + // parser found the end of the object (the '}' in JSON) + case JST_ARRAY_START: + // parser found an array (the '[' in JSON) + case JST_ARRAY_END: + // parser found the end of the array (the ']' in JSON) + + }; + } while (json_scan_next() == 0); // parse next structure + + + if (j_eng.s.error) // we need to check why the loop ended. + // Did we get to the end of JSON, or came upon error. + { + signal_error_in_JSON() + } + + + Parts of JSON can be quickly skipped. If we are not interested + in a particular key, we can just skip it with json_skip_key() call. + Similarly json_skip_level() goes right to the end of an object + or an array. +*/ + + +/* These are JSON parser states that user can expect and handle. */ +enum json_states { + JST_VALUE, /* value found */ + JST_KEY, /* key found */ + JST_OBJ_START, /* object */ + JST_OBJ_END, /* object ended */ + JST_ARRAY_START, /* array */ + JST_ARRAY_END, /* array ended */ + NR_JSON_USER_STATES +}; + + +enum json_value_types +{ + JSON_VALUE_OBJECT=1, + JSON_VALUE_ARRAY=2, + JSON_VALUE_STRING, + JSON_VALUE_NUMBER, + JSON_VALUE_TRUE, + JSON_VALUE_FALSE, + JSON_VALUE_NULL +}; + + +enum json_num_flags +{ + JSON_NUM_NEG=1, /* Number is negative. */ + JSON_NUM_FRAC_PART=2, /* The fractional part is not empty. */ + JSON_NUM_EXP=4, /* The number has the 'e' part. */ +}; + + +typedef struct st_json_engine_t +{ + json_string_t s; /* String to parse. */ + int sav_c_len; /* Length of the current character. + Can be more than 1 for multibyte charsets */ + + int state; /* The state of the parser. One of 'enum json_states'. + It tells us what construction of JSON we've just read. */ + + /* These values are only set after the json_read_value() call. */ + enum json_value_types value_type; /* type of the value.*/ + const uchar *value; /* Points to the value. */ + const uchar *value_begin;/* Points to where the value starts in the JSON. */ + uint num_flags; /* the details of the JSON_VALUE_NUMBER, is it negative, + or if it has the fractional part. + See the enum json_num_flags. */ + + /* + In most cases the 'value' and 'value_begin' are equal. + They only differ if the value is a string constants. Then 'value_begin' + points to the starting quotation mark, while the 'value' - to + the first character of the string. + */ + + const uchar *value_end; /* Points to the next character after the value. */ + int value_len; /* The length of the value. Does not count quotations for */ + /* string constants. */ + + int stack[JSON_DEPTH_LIMIT]; /* Keeps the stack of nested JSON structures. */ + int *stack_p; /* The 'stack' pointer. */ +} json_engine_t; + + +int json_scan_start(json_engine_t *je, + CHARSET_INFO *i_cs, const uchar *str, const uchar *end); +int json_scan_next(json_engine_t *j); + + +/* + json_read_keyname_chr() function assists parsing the name of an JSON key. + It only can be called when the json_engine is in JST_KEY. + The json_read_keyname_chr() reads one character of the name of the key, + and puts it in j_eng.s.next_c. + Typical usage is like this: + + if (j_eng.state == JST_KEY) + { + while (json_read_keyname_chr(&j) == 0) + { + //handle next character i.e. match it against the pattern + } + } +*/ + +int json_read_keyname_chr(json_engine_t *j); + + +/* + Check if the name of the current JSON key matches + the step of the path. +*/ +int json_key_matches(json_engine_t *je, json_string_t *k); + + +/* + json_read_value() function parses the JSON value syntax, + so that we can handle the value of a key or an array item. + It only returns meaningful result when the engine is in + the JST_VALUE state. + + Typical usage is like this: + + if (j_eng.state == JST_VALUE) + { + json_read_value(&j_eng); + switch(j_eng.value_type) + { + case JSON_VALUE_STRING: + // get the string + str= j_eng.value; + str_length= j_eng.value_len; + case JSON_VALUE_NUMBER: + // get the number + ... etc + } +*/ +int json_read_value(json_engine_t *j); + + +/* + json_skip_key() makes parser skip the content of the current + JSON key quickly. + It can be called only when the json_engine state is JST_KEY. + Typical usage is: + + if (j_eng.state == JST_KEY) + { + if (key_does_not_match(j_eng)) + json_skip_key(j_eng); + } +*/ + +int json_skip_key(json_engine_t *j); + + +typedef const int *json_level_t; + +/* + json_skip_to_level() makes parser quickly get out of nested + loops and arrays. It is used when we're not interested in what is + there in the rest of these structures. + The 'level' should be remembered in advance. + json_level_t level= json_get_level(j); + .... // getting into the nested JSON structures + json_skip_to_level(j, level); +*/ +#define json_get_level(j) (j->stack_p) + +int json_skip_to_level(json_engine_t *j, json_level_t level); + +/* + json_skip_level() works as above with just current structre. + So it gets to the end of the current JSON array or object. +*/ +#define json_skip_level(json_engine) \ + json_skip_to_level((json_engine), (json_engine)->stack_p) + + +#define json_skip_array_item json_skip_key + +/* + Checks if the current value is of scalar type - + not an OBJECT nor ARRAY. +*/ +#define json_value_scalar(je) ((je)->value_type > JSON_VALUE_ARRAY) + + +/* + Look for the JSON PATH in the json string. + Function can be called several times with same JSON/PATH to + find multiple matches. + On the first call, the json_engine_t parameter should be + initialized with the JSON string, and the json_path_t with the JSON path + appropriately. The 'p_cur_step' should point at the first + step of the path. + The 'array_counters' is the array of JSON_DEPTH_LIMIT size. + It stores the array counters of the parsed JSON. + If function returns 0, it means it found the match. The position of + the match is je->s.c_str. Then we can call the json_find_path() + with same engine/path/p_cur_step to get the next match. + Non-zero return means no matches found. + Check je->s.error to see if there was an error in JSON. +*/ +int json_find_path(json_engine_t *je, + json_path_t *p, json_path_step_t **p_cur_step, + uint *array_counters); + + +typedef struct st_json_find_paths_t +{ + uint n_paths; + json_path_t *paths; + uint cur_depth; + uint *path_depths; + uint array_counters[JSON_DEPTH_LIMIT]; +} json_find_paths_t; + + +int json_find_paths_first(json_engine_t *je, json_find_paths_t *state, + uint n_paths, json_path_t *paths, uint *path_depths); +int json_find_paths_next(json_engine_t *je, json_find_paths_t *state); + + +/* + Converst JSON string constant into ordinary string constant + which can involve unpacking json escapes and changing character set. + Returns negative integer in the case of an error, + the length of the result otherwise. +*/ +int json_unescape(CHARSET_INFO *json_cs, + const uchar *json_str, const uchar *json_end, + CHARSET_INFO *res_cs, + uchar *res, uchar *res_end); + +/* + Converst ordinary string constant into JSON string constant. + which can involve appropriate escaping and changing character set. + Returns negative integer in the case of an error, + the length of the result otherwise. +*/ +int json_escape(CHARSET_INFO *str_cs, const uchar *str, const uchar *str_end, + CHARSET_INFO *json_cs, uchar *json, uchar *json_end); + + +/* + Appends the ASCII string to the json with the charset conversion. +*/ +int json_append_ascii(CHARSET_INFO *json_cs, + uchar *json, uchar *json_end, + const uchar *ascii, const uchar *ascii_end); + +#ifdef __cplusplus +} +#endif + +#endif /* JSON_LIB_INCLUDED */ + diff --git a/include/lf.h b/include/lf.h index 19bdafce647..1825de62b43 100644 --- a/include/lf.h +++ b/include/lf.h @@ -68,11 +68,8 @@ typedef struct { void *purgatory; uint32 purgatory_count; uint32 volatile link; -/* we want sizeof(LF_PINS) to be 128 to avoid false sharing */ - char pad[128-sizeof(uint32)*2 - -sizeof(LF_PINBOX *) - -sizeof(void*) - -sizeof(void *)*(LF_PINBOX_PINS+1)]; + /* avoid false sharing */ + char pad[CPU_LEVEL1_DCACHE_LINESIZE]; } LF_PINS; /* compile-time assert to make sure we have enough pins. */ diff --git a/include/m_ctype.h b/include/m_ctype.h index ddb4c825e1b..04a82953f0a 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -181,11 +181,12 @@ extern MY_UNI_CTYPE my_uni_ctype[256]; /* A helper macros for "need at least n bytes" */ #define MY_CS_TOOSMALLN(n) (-100-(n)) +#define MY_CS_MBMAXLEN 6 /* Maximum supported mbmaxlen */ #define MY_CS_IS_TOOSMALL(rc) ((rc) >= MY_CS_TOOSMALL6 && (rc) <= MY_CS_TOOSMALL) - #define MY_SEQ_INTTAIL 1 #define MY_SEQ_SPACES 2 +#define MY_SEQ_NONSPACES 3 /* Skip non-space characters, including bad bytes */ /* My charsets_list flags */ #define MY_CS_COMPILED 1 /* compiled-in sets */ @@ -329,8 +330,7 @@ struct my_collation_handler_st int (*strnncoll)(CHARSET_INFO *, const uchar *, size_t, const uchar *, size_t, my_bool); int (*strnncollsp)(CHARSET_INFO *, - const uchar *, size_t, const uchar *, size_t, - my_bool diff_if_only_endspace_difference); + const uchar *, size_t, const uchar *, size_t); size_t (*strnxfrm)(CHARSET_INFO *, uchar *dst, size_t dstlen, uint nweights, const uchar *src, size_t srclen, uint flags); @@ -361,6 +361,8 @@ struct my_collation_handler_st extern MY_COLLATION_HANDLER my_collation_8bit_bin_handler; extern MY_COLLATION_HANDLER my_collation_8bit_simple_ci_handler; +extern MY_COLLATION_HANDLER my_collation_8bit_nopad_bin_handler; +extern MY_COLLATION_HANDLER my_collation_8bit_simple_nopad_ci_handler; extern MY_COLLATION_HANDLER my_collation_ucs2_uca_handler; /* Some typedef to make it easy for C++ to make function pointers */ @@ -394,7 +396,6 @@ typedef struct */ typedef struct { - MY_STRCOPY_STATUS m_native_copy_status; const char *m_cannot_convert_error_pos; } MY_STRCONV_STATUS; @@ -404,14 +405,9 @@ struct my_charset_handler_st { my_bool (*init)(struct charset_info_st *, MY_CHARSET_LOADER *loader); /* Multibyte routines */ - uint (*ismbchar)(CHARSET_INFO *, const char *, const char *); - uint (*mbcharlen)(CHARSET_INFO *, uint c); size_t (*numchars)(CHARSET_INFO *, const char *b, const char *e); size_t (*charpos)(CHARSET_INFO *, const char *b, const char *e, size_t pos); - size_t (*well_formed_len)(CHARSET_INFO *, - const char *b,const char *e, - size_t nchars, int *error); size_t (*lengthsp)(CHARSET_INFO *, const char *ptr, size_t length); size_t (*numcells)(CHARSET_INFO *, const char *b, const char *e); @@ -586,50 +582,87 @@ struct charset_info_st extern MYSQL_PLUGIN_IMPORT struct charset_info_st my_charset_bin; extern MYSQL_PLUGIN_IMPORT struct charset_info_st my_charset_latin1; +extern MYSQL_PLUGIN_IMPORT struct charset_info_st my_charset_latin1_nopad; extern MYSQL_PLUGIN_IMPORT struct charset_info_st my_charset_filename; extern MYSQL_PLUGIN_IMPORT struct charset_info_st my_charset_utf8_general_ci; extern struct charset_info_st my_charset_big5_bin; extern struct charset_info_st my_charset_big5_chinese_ci; +extern struct charset_info_st my_charset_big5_nopad_bin; +extern struct charset_info_st my_charset_big5_chinese_nopad_ci; extern struct charset_info_st my_charset_cp1250_czech_ci; extern struct charset_info_st my_charset_cp932_bin; extern struct charset_info_st my_charset_cp932_japanese_ci; +extern struct charset_info_st my_charset_cp932_nopad_bin; +extern struct charset_info_st my_charset_cp932_japanese_nopad_ci; extern struct charset_info_st my_charset_eucjpms_bin; extern struct charset_info_st my_charset_eucjpms_japanese_ci; +extern struct charset_info_st my_charset_eucjpms_nopad_bin; +extern struct charset_info_st my_charset_eucjpms_japanese_nopad_ci; extern struct charset_info_st my_charset_euckr_bin; extern struct charset_info_st my_charset_euckr_korean_ci; +extern struct charset_info_st my_charset_euckr_nopad_bin; +extern struct charset_info_st my_charset_euckr_korean_nopad_ci; extern struct charset_info_st my_charset_gb2312_bin; extern struct charset_info_st my_charset_gb2312_chinese_ci; +extern struct charset_info_st my_charset_gb2312_nopad_bin; +extern struct charset_info_st my_charset_gb2312_chinese_nopad_ci; extern struct charset_info_st my_charset_gbk_bin; extern struct charset_info_st my_charset_gbk_chinese_ci; +extern struct charset_info_st my_charset_gbk_nopad_bin; +extern struct charset_info_st my_charset_gbk_chinese_nopad_ci; extern struct charset_info_st my_charset_latin1_bin; +extern struct charset_info_st my_charset_latin1_nopad_bin; extern struct charset_info_st my_charset_latin1_german2_ci; extern struct charset_info_st my_charset_latin2_czech_ci; extern struct charset_info_st my_charset_sjis_bin; extern struct charset_info_st my_charset_sjis_japanese_ci; +extern struct charset_info_st my_charset_sjis_nopad_bin; +extern struct charset_info_st my_charset_sjis_japanese_nopad_ci; extern struct charset_info_st my_charset_tis620_bin; extern struct charset_info_st my_charset_tis620_thai_ci; +extern struct charset_info_st my_charset_tis620_nopad_bin; +extern struct charset_info_st my_charset_tis620_thai_nopad_ci; extern struct charset_info_st my_charset_ucs2_bin; extern struct charset_info_st my_charset_ucs2_general_ci; +extern struct charset_info_st my_charset_ucs2_nopad_bin; +extern struct charset_info_st my_charset_ucs2_general_nopad_ci; extern struct charset_info_st my_charset_ucs2_general_mysql500_ci; extern struct charset_info_st my_charset_ucs2_unicode_ci; +extern struct charset_info_st my_charset_ucs2_unicode_nopad_ci; extern struct charset_info_st my_charset_ucs2_general_mysql500_ci; extern struct charset_info_st my_charset_ujis_bin; extern struct charset_info_st my_charset_ujis_japanese_ci; +extern struct charset_info_st my_charset_ujis_nopad_bin; +extern struct charset_info_st my_charset_ujis_japanese_nopad_ci; extern struct charset_info_st my_charset_utf16_bin; extern struct charset_info_st my_charset_utf16_general_ci; extern struct charset_info_st my_charset_utf16_unicode_ci; +extern struct charset_info_st my_charset_utf16_unicode_nopad_ci; extern struct charset_info_st my_charset_utf16le_bin; extern struct charset_info_st my_charset_utf16le_general_ci; +extern struct charset_info_st my_charset_utf16_general_nopad_ci; +extern struct charset_info_st my_charset_utf16_nopad_bin; +extern struct charset_info_st my_charset_utf16le_nopad_bin; +extern struct charset_info_st my_charset_utf16le_general_nopad_ci; extern struct charset_info_st my_charset_utf32_bin; extern struct charset_info_st my_charset_utf32_general_ci; extern struct charset_info_st my_charset_utf32_unicode_ci; +extern struct charset_info_st my_charset_utf32_unicode_nopad_ci; +extern struct charset_info_st my_charset_utf32_nopad_bin; +extern struct charset_info_st my_charset_utf32_general_nopad_ci; extern struct charset_info_st my_charset_utf8_bin; +extern struct charset_info_st my_charset_utf8_nopad_bin; +extern struct charset_info_st my_charset_utf8_general_nopad_ci; extern struct charset_info_st my_charset_utf8_general_mysql500_ci; extern struct charset_info_st my_charset_utf8_unicode_ci; +extern struct charset_info_st my_charset_utf8_unicode_nopad_ci; extern struct charset_info_st my_charset_utf8mb4_bin; extern struct charset_info_st my_charset_utf8mb4_general_ci; +extern struct charset_info_st my_charset_utf8mb4_nopad_bin; +extern struct charset_info_st my_charset_utf8mb4_general_nopad_ci; extern struct charset_info_st my_charset_utf8mb4_unicode_ci; +extern struct charset_info_st my_charset_utf8mb4_unicode_nopad_ci; #define MY_UTF8MB3 "utf8" #define MY_UTF8MB4 "utf8mb4" @@ -649,16 +682,31 @@ extern int my_strnncoll_simple(CHARSET_INFO *, const uchar *, size_t, const uchar *, size_t, my_bool); extern int my_strnncollsp_simple(CHARSET_INFO *, const uchar *, size_t, - const uchar *, size_t, - my_bool diff_if_only_endspace_difference); + 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_simple_nopad(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); +/** + Compare a string to an array of spaces, for PAD SPACE comparison. + The function iterates through the string and compares every byte to 0x20. + @param - the string + @param - its length + @return <0 - if a byte less than 0x20 was found in the string. + @return 0 - if all bytes in the string were 0x20, or if length was 0. + @return >0 - if a byte greater than 0x20 was found in the string. +*/ +extern int my_strnncollsp_padspace_bin(const uchar *str, size_t length); + extern size_t my_lengthsp_8bit(CHARSET_INFO *cs, const char *ptr, size_t length); extern uint my_instr_simple(CHARSET_INFO *, @@ -764,14 +812,11 @@ int my_wildcmp_bin(CHARSET_INFO *, size_t my_numchars_8bit(CHARSET_INFO *, const char *b, const char *e); size_t my_numcells_8bit(CHARSET_INFO *, const char *b, const char *e); size_t my_charpos_8bit(CHARSET_INFO *, const char *b, const char *e, size_t pos); -size_t my_well_formed_len_8bit(CHARSET_INFO *, const char *b, const char *e, - size_t pos, int *error); size_t my_well_formed_char_length_8bit(CHARSET_INFO *cs, const char *b, const char *e, size_t nchars, MY_STRCOPY_STATUS *status); int my_charlen_8bit(CHARSET_INFO *, const uchar *str, const uchar *end); -uint my_mbcharlen_8bit(CHARSET_INFO *, uint c); /* Functions for multibyte charsets */ @@ -798,23 +843,11 @@ int my_wildcmp_mb(CHARSET_INFO *, size_t my_numchars_mb(CHARSET_INFO *, const char *b, const char *e); size_t my_numcells_mb(CHARSET_INFO *, const char *b, const char *e); size_t my_charpos_mb(CHARSET_INFO *, const char *b, const char *e, size_t pos); -size_t my_well_formed_len_mb(CHARSET_INFO *, const char *b, const char *e, - size_t pos, int *error); uint my_instr_mb(CHARSET_INFO *, const char *b, size_t b_length, const char *s, size_t s_length, my_match_t *match, uint nmatch); -int my_strnncoll_mb_bin(CHARSET_INFO * cs, - const uchar *s, size_t slen, - const uchar *t, size_t tlen, - my_bool t_is_prefix); - -int my_strnncollsp_mb_bin(CHARSET_INFO *cs, - const uchar *a, size_t a_length, - const uchar *b, size_t b_length, - my_bool diff_if_only_endspace_difference); - int my_wildcmp_mb_bin(CHARSET_INFO *cs, const char *str,const char *str_end, const char *wildstr,const char *wildend, @@ -826,18 +859,38 @@ int my_strcasecmp_mb_bin(CHARSET_INFO * cs __attribute__((unused)), void my_hash_sort_mb_bin(CHARSET_INFO *cs __attribute__((unused)), const uchar *key, size_t len,ulong *nr1, ulong *nr2); +void my_hash_sort_mb_nopad_bin(CHARSET_INFO *cs __attribute__((unused)), + const uchar *key, size_t len, + ulong *nr1, ulong *nr2); + size_t my_strnxfrm_mb(CHARSET_INFO *, uchar *dst, size_t dstlen, uint nweights, const uchar *src, size_t srclen, uint flags); +size_t my_strnxfrm_mb_nopad(CHARSET_INFO *, + uchar *dst, size_t dstlen, uint nweights, + const uchar *src, size_t srclen, uint flags); + size_t my_strnxfrm_unicode(CHARSET_INFO *, uchar *dst, size_t dstlen, uint nweights, const uchar *src, size_t srclen, uint flags); + +size_t my_strnxfrm_unicode_nopad(CHARSET_INFO *, + uchar *dst, size_t dstlen, uint nweights, + const uchar *src, size_t srclen, uint flags); + size_t my_strnxfrmlen_unicode(CHARSET_INFO *, size_t); size_t my_strnxfrm_unicode_full_bin(CHARSET_INFO *, - uchar *dst, size_t dstlen, uint nweights, - const uchar *src, size_t srclen, uint flags); + uchar *dst, size_t dstlen, + uint nweights, const uchar *src, + size_t srclen, uint flags); + +size_t my_strnxfrm_unicode_full_nopad_bin(CHARSET_INFO *, + uchar *dst, size_t dstlen, + uint nweights, const uchar *src, + size_t srclen, uint flags); + size_t my_strnxfrmlen_unicode_full_bin(CHARSET_INFO *, size_t); int my_wildcmp_unicode(CHARSET_INFO *cs, @@ -867,7 +920,6 @@ void my_string_metadata_get(MY_STRING_METADATA *metadata, CHARSET_INFO *cs, const char *str, size_t len); uint my_string_repertoire(CHARSET_INFO *cs, const char *str, ulong len); my_bool my_charset_is_ascii_based(CHARSET_INFO *cs); -my_bool my_charset_is_8bit_pure_ascii(CHARSET_INFO *cs); uint my_charset_repertoire(CHARSET_INFO *cs); uint my_strxfrm_flag_normalize(uint flags, uint nlevels); @@ -876,8 +928,10 @@ void my_strxfrm_desc_and_reverse(uchar *str, uchar *strend, size_t my_strxfrm_pad_desc_and_reverse(CHARSET_INFO *cs, uchar *str, uchar *frmend, uchar *strend, uint nweights, uint flags, uint level); - -my_bool my_charset_is_ascii_compatible(CHARSET_INFO *cs); +size_t my_strxfrm_pad_desc_and_reverse_nopad(CHARSET_INFO *cs, + uchar *str, uchar *frmend, + uchar *strend, uint nweights, + uint flags, uint level); const MY_CONTRACTIONS *my_charset_get_contractions(CHARSET_INFO *cs, int level); @@ -931,7 +985,9 @@ uint32 my_convert_using_func(char *to, uint32 to_length, CHARSET_INFO *to_cs, */ size_t my_convert_fix(CHARSET_INFO *dstcs, char *dst, size_t dst_length, CHARSET_INFO *srccs, const char *src, size_t src_length, - size_t nchars, MY_STRCONV_STATUS *status); + size_t nchars, + MY_STRCOPY_STATUS *copy_status, + MY_STRCONV_STATUS *conv_status); #define _MY_U 01 /* Upper case */ #define _MY_L 02 /* Lower case */ @@ -976,13 +1032,71 @@ size_t my_convert_fix(CHARSET_INFO *dstcs, char *dst, size_t dst_length, #define my_strcasecmp(s, a, b) ((s)->coll->strcasecmp((s), (a), (b))) #define my_charpos(cs, b, e, num) (cs)->cset->charpos((cs), (const char*) (b), (const char *)(e), (num)) -#define use_mb(s) ((s)->cset->ismbchar != NULL) -#define my_ismbchar(s, a, b) ((s)->cset->ismbchar((s), (a), (b))) -#ifdef USE_MB -#define my_mbcharlen(s, a) ((s)->cset->mbcharlen((s),(a))) -#else -#define my_mbcharlen(s, a) 1 -#endif +#define use_mb(s) ((s)->mbmaxlen > 1) +/** + Detect if the leftmost character in a string is a valid multi-byte character + and return its length, or return 0 otherwise. + @param cs - character set + @param str - the beginning of the string + @param end - the string end (the next byte after the string) + @return >0, for a multi-byte character + @rerurn 0, for a single byte character, broken sequence, empty string. +*/ +static inline +uint my_ismbchar(CHARSET_INFO *cs, const char *str, const char *end) +{ + int char_length= (cs->cset->charlen)(cs, (const uchar *) str, + (const uchar *) end); + return char_length > 1 ? (uint) char_length : 0U; +} + + +/** + Return length of the leftmost character in a string. + @param cs - character set + @param str - the beginning of the string + @param end - the string end (the next byte after the string) + @return <=0 on errors (EOL, wrong byte sequence) + @return 1 on a single byte character + @return >1 on a multi-byte character + + Note, inlike my_ismbchar(), 1 is returned for a single byte character. +*/ +static inline +int my_charlen(CHARSET_INFO *cs, const char *str, const char *end) +{ + return (cs->cset->charlen)(cs, (const uchar *) str, + (const uchar *) end); +} + + +/** + Convert broken and incomplete byte sequences to 1 byte. +*/ +static inline +uint my_charlen_fix(CHARSET_INFO *cs, const char *str, const char *end) +{ + int char_length= my_charlen(cs, str, end); + DBUG_ASSERT(str < end); + return char_length > 0 ? (uint) char_length : (uint) 1U; +} + + +/* + A compatibility replacement pure C function for the former + cs->cset->well_formed_len(). + In C++ code please use Well_formed_prefix::length() instead. +*/ +static inline size_t +my_well_formed_length(CHARSET_INFO *cs, const char *b, const char *e, + size_t nchars, int *error) +{ + MY_STRCOPY_STATUS status; + (void) cs->cset->well_formed_char_length(cs, b, e, nchars, &status); + *error= status.m_well_formed_error_pos == NULL ? 0 : 1; + return status.m_source_end_pos - b; +} + #define my_caseup_str(s, a) ((s)->cset->caseup_str((s), (a))) #define my_casedn_str(s, a) ((s)->cset->casedn_str((s), (a))) diff --git a/include/m_string.h b/include/m_string.h index 969725e4631..0f3cd362b4d 100644 --- a/include/m_string.h +++ b/include/m_string.h @@ -23,6 +23,7 @@ #define _m_string_h #include "my_global.h" /* HAVE_* */ +#include "my_decimal_limits.h" #ifndef __USE_GNU #define __USE_GNU /* We want to use stpcpy */ @@ -138,14 +139,13 @@ size_t my_fcvt(double x, int precision, char *to, my_bool *error); size_t my_gcvt(double x, my_gcvt_arg_type type, int width, char *to, my_bool *error); -#define NOT_FIXED_DEC 31 - /* The longest string my_fcvt can return is 311 + "precision" bytes. - Here we assume that we never cal my_fcvt() with precision >= NOT_FIXED_DEC + Here we assume that we never cal my_fcvt() with + precision >= DECIMAL_NOT_SPECIFIED (+ 1 byte for the terminating '\0'). */ -#define FLOATING_POINT_BUFFER (311 + NOT_FIXED_DEC) +#define FLOATING_POINT_BUFFER (311 + DECIMAL_NOT_SPECIFIED) /* We want to use the 'e' format in some cases even if we have enough space diff --git a/include/my_atomic.h b/include/my_atomic.h index c75b65db38d..8f13a0ab89b 100644 --- a/include/my_atomic.h +++ b/include/my_atomic.h @@ -112,9 +112,26 @@ #undef MY_ATOMIC_HAS_8_16 /* - * Attempt to do atomic ops without locks - */ -#include "atomic/nolock.h" + We choose implementation as follows: + ------------------------------------ + On Windows using Visual C++ the native implementation should be + preferrable. When using gcc we prefer the Solaris implementation + before the gcc because of stability preference, we choose gcc + builtins if available, otherwise we choose the somewhat broken + native x86 implementation. If neither Visual C++ or gcc we still + choose the Solaris implementation on Solaris (mainly for SunStudio + compilers). +*/ +#if defined(_MSC_VER) +#include "atomic/generic-msvc.h" +#elif defined(HAVE_SOLARIS_ATOMIC) +#include "atomic/solaris.h" +#elif defined(HAVE_GCC_ATOMIC_BUILTINS) +#include "atomic/gcc_builtins.h" +#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) +#include "atomic/x86-gcc.h" +#endif + #ifndef make_atomic_cas_body /* nolock.h was not able to generate even a CAS function, fall back */ @@ -280,6 +297,20 @@ make_atomic_store(32) make_atomic_store(64) make_atomic_store(ptr) +#if SIZEOF_LONG == 4 +#define my_atomic_addlong(A,B) my_atomic_add32((int32*) (A), (B)) +#define my_atomic_loadlong(A) my_atomic_load32((int32*) (A)) +#define my_atomic_storelong(A,B) my_atomic_store32((int32*) (A), (B)) +#define my_atomic_faslong(A,B) my_atomic_fas32((int32*) (A), (B)) +#define my_atomic_caslong(A,B,C) my_atomic_cas32((int32*) (A), (int32*) (B), (C)) +#else +#define my_atomic_addlong(A,B) my_atomic_add64((int64*) (A), (B)) +#define my_atomic_loadlong(A) my_atomic_load64((int64*) (A)) +#define my_atomic_storelong(A,B) my_atomic_store64((int64*) (A), (B)) +#define my_atomic_faslong(A,B) my_atomic_fas64((int64*) (A), (B)) +#define my_atomic_caslong(A,B,C) my_atomic_cas64((int64*) (A), (int64*) (B), (C)) +#endif + #ifdef _atomic_h_cleanup_ #include _atomic_h_cleanup_ #undef _atomic_h_cleanup_ diff --git a/include/my_base.h b/include/my_base.h index 8b546edac43..84b2e28d340 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -298,11 +298,7 @@ enum ha_base_keytype { #define HA_SWAP_KEY 64 #define HA_REVERSE_SORT 128 /* Sort key in reverse order */ #define HA_NO_SORT 256 /* do not bother sorting on this keyseg */ -/* - End space in unique/varchar are considered equal. (Like 'a' and 'a ') - Only needed for internal temporary tables. -*/ -#define HA_END_SPACE_ARE_EQUAL 512 + #define HA_BIT_PART 1024 #define HA_CAN_MEMCMP 2048 /* internal, never stored in frm */ @@ -501,13 +497,19 @@ enum ha_base_keytype { #define HA_ERR_DISK_FULL 189 #define HA_ERR_INCOMPATIBLE_DEFINITION 190 #define HA_ERR_FTS_TOO_MANY_WORDS_IN_PHRASE 191 /* Too many words in a phrase */ -#define HA_ERR_DECRYPTION_FAILED 192 /* Table encrypted but - decypt failed */ -#define HA_ERR_LAST 192 /* Copy of last error nr */ +#define HA_ERR_DECRYPTION_FAILED 192 /* Table encrypted but decypt failed */ +#define HA_ERR_FK_DEPTH_EXCEEDED 193 /* FK cascade depth exceeded */ +#define HA_ERR_TABLESPACE_MISSING 194 /* Missing Tablespace */ +#define HA_ERR_LAST 194 /* Copy of last error nr * */ /* Number of different errors */ #define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1) +/* aliases */ +#define HA_ERR_TABLE_CORRUPT HA_ERR_WRONG_IN_RECORD +#define HA_ERR_QUERY_INTERRUPTED HA_ERR_ABORTED_BY_USER +#define HA_ERR_NOT_ALLOWED_COMMAND HA_ERR_WRONG_COMMAND + /* Other constants */ #define HA_NAMELEN 64 /* Max length of saved filename */ @@ -564,7 +566,7 @@ typedef ulong key_part_map; #define HA_STATE_KEY_CHANGED 128 #define HA_STATE_WRITE_AT_END 256 /* set in _ps_find_writepos */ #define HA_STATE_BUFF_SAVED 512 /* If current keybuff is info->buff */ -#define HA_STATE_ROW_CHANGED 1024 /* To invalide ROW cache */ +#define HA_STATE_ROW_CHANGED 1024 /* To invalidate ROW cache */ #define HA_STATE_EXTEND_BLOCK 2048 #define HA_STATE_RNEXT_SAME 4096 /* rnext_same occupied lastkey2 */ @@ -636,17 +638,4 @@ C_MODE_START typedef void (* invalidator_by_filename)(const char * filename); C_MODE_END - -enum durability_properties -{ - /* - Preserves the durability properties defined by the engine */ - HA_REGULAR_DURABILITY= 0, - /* - Ignore the durability properties defined by the engine and - write only in-memory entries. - */ - HA_IGNORE_DURABILITY= 1 -}; - #endif /* _my_base_h */ diff --git a/include/my_bitmap.h b/include/my_bitmap.h index 9c9550e3141..3e242280be4 100644 --- a/include/my_bitmap.h +++ b/include/my_bitmap.h @@ -58,6 +58,7 @@ extern my_bool bitmap_is_overlapping(const MY_BITMAP *map1, extern my_bool bitmap_test_and_set(MY_BITMAP *map, uint bitmap_bit); 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_fast_test_and_clear(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, diff --git a/include/my_compare.h b/include/my_compare.h index 3440d9ef920..12f9971d49b 100644 --- a/include/my_compare.h +++ b/include/my_compare.h @@ -108,7 +108,7 @@ typedef struct st_HA_KEYSEG /* Key-portion */ set_rec_bits(0, bit_ptr, bit_ofs, bit_len) extern int ha_compare_text(CHARSET_INFO *, const uchar *, uint, - const uchar *, uint , my_bool, my_bool); + const uchar *, uint , my_bool); extern int ha_key_cmp(HA_KEYSEG *keyseg, const uchar *a, const uchar *b, uint key_length, uint nextflag, uint *diff_pos); diff --git a/include/my_context.h b/include/my_context.h index c59d6ce3577..ea0e3496887 100644 --- a/include/my_context.h +++ b/include/my_context.h @@ -62,7 +62,7 @@ struct my_context { ucontext_t base_context; ucontext_t spawned_context; int active; -#ifdef HAVE_VALGRIND +#ifdef HAVE_VALGRIND_MEMCHECK_H unsigned int valgrind_stack_id; #endif #ifndef DBUG_OFF @@ -79,7 +79,7 @@ struct my_context { uint64_t save[9]; void *stack_top; void *stack_bot; -#ifdef HAVE_VALGRIND +#ifdef HAVE_VALGRIND_MEMCHECK_H unsigned int valgrind_stack_id; #endif #ifndef DBUG_OFF @@ -96,7 +96,7 @@ struct my_context { uint64_t save[7]; void *stack_top; void *stack_bot; -#ifdef HAVE_VALGRIND +#ifdef HAVE_VALGRIND_MEMCHECK_H unsigned int valgrind_stack_id; #endif #ifndef DBUG_OFF diff --git a/include/my_dbug.h b/include/my_dbug.h index d56033ab025..ba9e8a025d7 100644 --- a/include/my_dbug.h +++ b/include/my_dbug.h @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2010, Oracle and/or its affiliates. - Copyright (C) 2000-2011 Monty Program Ab + Copyright (C) 2000, 2017, MariaDB Corporation 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 @@ -50,7 +50,7 @@ extern void _db_set_init_(const char *control); extern void _db_enter_(const char *_func_, const char *_file_, uint _line_, struct _db_stack_frame_ *_stack_frame_); extern void _db_return_(struct _db_stack_frame_ *_stack_frame_); -extern void _db_pargs_(uint _line_,const char *keyword); +extern int _db_pargs_(uint _line_,const char *keyword); extern void _db_doprnt_(const char *format,...) ATTRIBUTE_FORMAT(printf, 1, 2); extern void _db_dump_(uint _line_,const char *keyword, @@ -91,7 +91,7 @@ extern const char* _db_get_func_(void); #define DBUG_EVALUATE_IF(keyword,a1,a2) \ (_db_keyword_(0,(keyword), 1) ? (a1) : (a2)) #define DBUG_PRINT(keyword,arglist) \ - do {_db_pargs_(__LINE__,keyword); _db_doprnt_ arglist;} while(0) + do if (_db_pargs_(__LINE__,keyword)) _db_doprnt_ arglist; while(0) #define DBUG_PUSH(a1) _db_push_ (a1) #define DBUG_POP() _db_pop_ () #define DBUG_SET(a1) _db_set_ (a1) @@ -193,8 +193,18 @@ void debug_sync_point(const char* lock_name, uint lock_timeout); #define DBUG_SYNC_POINT(lock_name,lock_timeout) #endif /* EXTRA_DEBUG */ -#ifdef __cplusplus +#ifdef __cplusplus } +# ifdef DBUG_OFF +# define DBUG_LOG(keyword, v) do {} while (0) +# else +# include <sstream> +# define DBUG_LOG(keyword, v) do { \ + if (_db_pargs_(__LINE__, keyword)) { \ + std::ostringstream _db_s; _db_s << v; \ + _db_doprnt_("%s", _db_s.str().c_str()); \ + }} while (0) +# endif #endif #endif /* _my_dbug_h */ diff --git a/include/my_decimal_limits.h b/include/my_decimal_limits.h index 50d70357c42..a287e82f989 100644 --- a/include/my_decimal_limits.h +++ b/include/my_decimal_limits.h @@ -31,10 +31,16 @@ 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)) + + With normal precession we can handle 65 digits. MariaDB can store in + the .frm up to 63 digits. By default we use DECIMAL_NOT_SPECIFIED digits + when converting strings to decimal, so we don't want to set this too high. + To not use up all digits for the scale we limit the number of decimals to + 38. */ #define DECIMAL_MAX_PRECISION (DECIMAL_MAX_POSSIBLE_PRECISION - 8*2) -#define DECIMAL_MAX_SCALE 30 -#define DECIMAL_NOT_SPECIFIED 31 +#define DECIMAL_MAX_SCALE 38 +#define DECIMAL_NOT_SPECIFIED 39 /** maximum length of string representation (number of maximum decimal diff --git a/include/my_global.h b/include/my_global.h index bca03bfc4d6..4f40d3e0615 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -153,13 +153,11 @@ */ #if defined(__APPLE__) && defined(__MACH__) # undef SIZEOF_CHARP -# undef SIZEOF_SHORT # undef SIZEOF_INT # undef SIZEOF_LONG # undef SIZEOF_LONG_LONG # undef SIZEOF_OFF_T # undef WORDS_BIGENDIAN -# define SIZEOF_SHORT 2 # define SIZEOF_INT 4 # define SIZEOF_LONG_LONG 8 # define SIZEOF_OFF_T 8 @@ -819,6 +817,7 @@ static inline bool isfinite(double x) { return std::isfinite(x); } #ifndef HAVE_ISNAN #define isnan(x) ((x) != (x)) #endif +#define my_isnan(x) isnan(x) #ifdef HAVE_ISINF #define my_isinf(X) isinf(X) @@ -1233,4 +1232,31 @@ static inline double rint(double x) #undef __GNUG__ #endif +/* + Provide defaults for the CPU cache line size, if it has not been detected by + CMake using getconf +*/ +#if !defined(CPU_LEVEL1_DCACHE_LINESIZE) || CPU_LEVEL1_DCACHE_LINESIZE == 0 + #if CPU_LEVEL1_DCACHE_LINESIZE == 0 + #undef CPU_LEVEL1_DCACHE_LINESIZE + #endif + + #if defined(__s390__) + #define CPU_LEVEL1_DCACHE_LINESIZE 256 + #elif defined(__powerpc__) || defined(__aarch64__) + #define CPU_LEVEL1_DCACHE_LINESIZE 128 + #else + #define CPU_LEVEL1_DCACHE_LINESIZE 64 + #endif +#endif + +#define FLOATING_POINT_DECIMALS 31 + +/* Keep client compatible with earlier versions */ +#ifdef MYSQL_SERVER +#define NOT_FIXED_DEC DECIMAL_NOT_SPECIFIED +#else +#define NOT_FIXED_DEC FLOATING_POINT_DECIMALS +#endif + #endif /* my_global_h */ diff --git a/include/my_handler_errors.h b/include/my_handler_errors.h index 5af6a359348..bdea4f71eaf 100644 --- a/include/my_handler_errors.h +++ b/include/my_handler_errors.h @@ -23,16 +23,18 @@ static const char *handler_error_messages[]= { + /* 120 */ "Didn't find key on read or update", "Duplicate key on write or update", "Internal (unspecified) error in handler", "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", + "Index is corrupted", + "Table file is corrupted", "Out of memory in engine", "Undefined handler error 129", + /* 130 */ "Incorrect file format", "Command not supported by database", "Old database file", @@ -43,6 +45,7 @@ static const char *handler_error_messages[]= "No more records (read after end of file)", "Unsupported extension used for table", "Too big row", + /* 140 */ "Wrong create options", "Duplicate unique key or constraint on write or update", "Unknown character set used in table", @@ -53,6 +56,7 @@ static const char *handler_error_messages[]= "Lock table is full; Restart program with a larger lock table", "Updates are not allowed under a read only transactions", "Lock deadlock; Retry transaction", + /* 150 */ "Foreign key constraint is incorrectly formed", "Cannot add a child row", "Cannot delete a parent row", @@ -63,6 +67,7 @@ static const char *handler_error_messages[]= "Could not connect to storage engine", "Unexpected null pointer found when using spatial index", "The table changed in storage engine", + /* 160 */ "There's no partition in table for the given value", "Row-based binary logging of row failed", "Index needed in foreign key constraint", @@ -73,6 +78,7 @@ static const char *handler_error_messages[]= "Failed to set row auto increment value", "Unknown (generic) error from engine", "Record was not update. Original values was same as new values", + /* 170 */ "It is not possible to log this statement", "The event was corrupt, leading to illegal data being read", "The table is of a new format not supported by this version", @@ -83,6 +89,7 @@ static const char *handler_error_messages[]= "Too many active concurrent transactions", "Record not matching the given partition set", "Index column length exceeds limit", + /* 180 */ "Index corrupted", "Undo record too big", "Invalid InnoDB FTS Doc ID", @@ -93,9 +100,12 @@ static const char *handler_error_messages[]= "Row is not visible by the current transaction", "Operation was interrupted by end user (probably kill command?)", "Disk full", + /* 190 */ "Incompatible key or row definition between the MariaDB .frm file and the information in the storage engine. You have to dump and restore the table to fix this", "Too many words in a FTS phrase or proximity search", - "Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match." + "Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.", + "Foreign key cascade delete/update exceeds max depth", + "Tablespace is missing for table" }; #endif /* MYSYS_MY_HANDLER_ERRORS_INCLUDED */ diff --git a/include/my_pthread.h b/include/my_pthread.h index 37576ac3cb4..bf61a024390 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -54,26 +54,7 @@ typedef struct st_pthread_link { 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; +typedef CONDITION_VARIABLE pthread_cond_t; typedef int pthread_mutexattr_t; @@ -81,10 +62,8 @@ typedef int pthread_mutexattr_t; #define pthread_handler_t EXTERNC void * __cdecl typedef void * (__cdecl *pthread_handler)(void *); -typedef volatile LONG my_pthread_once_t; -#define MY_PTHREAD_ONCE_INIT 0 -#define MY_PTHREAD_ONCE_INPROGRESS 1 -#define MY_PTHREAD_ONCE_DONE 2 +typedef INIT_ONCE my_pthread_once_t; +#define MY_PTHREAD_ONCE_INIT INIT_ONCE_STATIC_INIT; #if !STRUCT_TIMESPEC_HAS_TV_SEC || !STRUCT_TIMESPEC_HAS_TV_NSEC struct timespec { @@ -287,7 +266,7 @@ struct tm *gmtime_r(const time_t *clock, struct tm *res); #undef pthread_detach_this_thread #define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(&tmp); } #else /* HAVE_PTHREAD_ATTR_CREATE && !HAVE_SIGWAIT */ -#define HAVE_PTHREAD_KILL +#define HAVE_PTHREAD_KILL 1 #endif #endif /* defined(__WIN__) */ @@ -445,30 +424,10 @@ void safe_mutex_free_deadlock_data(safe_mutex_t *mp); #define safe_mutex_assert_not_owner(mp) do {} while (0) #define safe_mutex_setflags(mp, F) do {} while (0) -#if defined(MY_PTHREAD_FASTMUTEX) -#define my_cond_timedwait(A,B,C) pthread_cond_timedwait((A), &(B)->mutex, (C)) -#define my_cond_wait(A,B) pthread_cond_wait((A), &(B)->mutex) -#else #define my_cond_timedwait(A,B,C) pthread_cond_timedwait((A),(B),(C)) #define my_cond_wait(A,B) pthread_cond_wait((A), (B)) -#endif /* MY_PTHREAD_FASTMUTEX */ #endif /* !SAFE_MUTEX */ -#if defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX) -typedef struct st_my_pthread_fastmutex_t -{ - pthread_mutex_t mutex; - uint spins; - uint rng_state; -} my_pthread_fastmutex_t; -void fastmutex_global_init(void); - -int my_pthread_fastmutex_init(my_pthread_fastmutex_t *mp, - const pthread_mutexattr_t *attr); -int my_pthread_fastmutex_lock(my_pthread_fastmutex_t *mp); - -#endif /* defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX) */ - /* READ-WRITE thread locking */ #if defined(USE_MUTEX_INSTEAD_OF_RW_LOCKS) @@ -692,7 +651,7 @@ extern pthread_mutexattr_t my_errorcheck_mutexattr; #define ESRCH 1 #endif -typedef ulong my_thread_id; +typedef int64 my_thread_id; extern void my_threadattr_global_init(void); extern my_bool my_thread_global_init(void); @@ -714,7 +673,7 @@ extern void my_mutex_end(void); We need to have at least 256K stack to handle calls to myisamchk_init() with the current number of keys and key parts. */ -#define DEFAULT_THREAD_STACK (289*1024L) +#define DEFAULT_THREAD_STACK (291*1024L) #endif #define MY_PTHREAD_LOCK_READ 0 @@ -732,7 +691,7 @@ struct st_my_thread_var mysql_mutex_t * volatile current_mutex; mysql_cond_t * volatile current_cond; pthread_t pthread_self; - my_thread_id id; + my_thread_id id, dbug_id; int volatile abort; my_bool init; struct st_my_thread_var *next,**prev; diff --git a/include/my_sys.h b/include/my_sys.h index 2b1698ca2bc..2e24bfd02d3 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -192,6 +192,14 @@ extern void my_large_free(uchar *ptr); #define my_large_free(A) my_free_lock((A)) #endif /* HAVE_LARGE_PAGES */ +void my_init_atomic_write(void); +#ifdef __linux__ +my_bool my_test_if_atomic_write(File handle, int pagesize); +#else +#define my_test_if_atomic_write(A, B) 0 +#endif /* __linux__ */ +extern my_bool my_may_have_atomic_write; + #if defined(HAVE_ALLOCA) && !defined(HAVE_valgrind) #if defined(_AIX) && !defined(__GNUC__) && !defined(_AIX43) #pragma alloca @@ -472,6 +480,8 @@ typedef struct st_io_cache /* Used when cacheing files */ const char *dir; char prefix[3]; File file; /* file descriptor */ + + struct st_io_cache *next_file_user; /* seek_not_done is set by my_b_seek() to inform the upcoming read/write operation that a seek needs to be preformed prior to the actual I/O @@ -693,14 +703,14 @@ extern void my_osmaperr(unsigned long last_error); #endif extern void init_glob_errs(void); -extern const char** get_global_errmsgs(void); +extern const char** get_global_errmsgs(int nr); extern void wait_for_free_space(const char *filename, int errors); extern FILE *my_fopen(const char *FileName,int Flags,myf MyFlags); 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_vfprintf(FILE *stream, const char* format, va_list args); -extern void my_strerror(char *buf, size_t len, int nr); +extern const char* my_strerror(char *buf, size_t len, int nr); 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); @@ -718,9 +728,9 @@ extern void my_printf_error(uint my_err, const char *format, ATTRIBUTE_FORMAT(printf, 2, 4); extern void my_printv_error(uint error, const char *format, myf MyFlags, va_list ap); -extern int my_error_register(const char** (*get_errmsgs) (void), +extern int my_error_register(const char** (*get_errmsgs) (int nr), uint first, uint last); -extern const char **my_error_unregister(uint first, uint last); +extern my_bool my_error_unregister(uint first, uint last); extern void my_message(uint my_err, const char *str,myf MyFlags); extern void my_message_stderr(uint my_err, const char *str, myf MyFlags); extern my_bool my_init(void); @@ -806,6 +816,11 @@ extern my_bool reinit_io_cache(IO_CACHE *info,enum cache_type type, extern void setup_io_cache(IO_CACHE* info); extern void init_io_cache_share(IO_CACHE *read_cache, IO_CACHE_SHARE *cshare, IO_CACHE *write_cache, uint num_threads); + +extern int init_slave_io_cache(IO_CACHE *master, IO_CACHE *slave); +void end_slave_io_cache(IO_CACHE *cache); +void seek_io_cache(IO_CACHE *cache, my_off_t needed_offset); + extern void remove_io_thread(IO_CACHE *info); extern int _my_b_async_read(IO_CACHE *info,uchar *Buffer,size_t Count); extern int my_b_append(IO_CACHE *info,const uchar *Buffer,size_t Count); @@ -1023,6 +1038,7 @@ extern void add_compiled_collation(struct charset_info_st *cs); extern size_t escape_string_for_mysql(CHARSET_INFO *charset_info, char *to, size_t to_length, const char *from, size_t length); +extern char *get_tty_password(const char *opt_message); #ifdef __WIN__ #define BACKSLASH_MBTAIL /* File system character set */ diff --git a/include/my_time.h b/include/my_time.h index 557dcdd5670..8dc1f09ba0f 100644 --- a/include/my_time.h +++ b/include/my_time.h @@ -23,6 +23,7 @@ #define _my_time_h_ #include "my_global.h" #include "mysql_time.h" +#include "my_decimal_limits.h" C_MODE_START @@ -170,6 +171,10 @@ static inline my_bool validate_timestamp_range(const MYSQL_TIME *t) return TRUE; } +/* Can't include mysqld_error.h, it needs mysys to build, thus hardcode 2 error values here. */ +#define ER_WARN_DATA_OUT_OF_RANGE 1264 +#define ER_WARN_INVALID_TIMESTAMP 1299 + my_time_t my_system_gmt_sec(const MYSQL_TIME *t, long *my_timezone, uint *error_code); @@ -184,7 +189,7 @@ 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 */ +#define AUTO_SEC_PART_DIGITS DECIMAL_NOT_SPECIFIED 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); diff --git a/include/my_valgrind.h b/include/my_valgrind.h index 4531ec78f9a..9ceb49c1094 100644 --- a/include/my_valgrind.h +++ b/include/my_valgrind.h @@ -19,18 +19,18 @@ #define IF_VALGRIND(A,B) B #endif -#if defined(HAVE_VALGRIND) && defined(HAVE_valgrind) +#if defined(HAVE_VALGRIND_MEMCHECK_H) && defined(HAVE_valgrind) # include <valgrind/memcheck.h> # define MEM_UNDEFINED(a,len) VALGRIND_MAKE_MEM_UNDEFINED(a,len) # define MEM_NOACCESS(a,len) VALGRIND_MAKE_MEM_NOACCESS(a,len) # define MEM_CHECK_ADDRESSABLE(a,len) VALGRIND_CHECK_MEM_IS_ADDRESSABLE(a,len) # define MEM_CHECK_DEFINED(a,len) VALGRIND_CHECK_MEM_IS_DEFINED(a,len) -#else /* HAVE_VALGRIND */ +#else /* HAVE_VALGRIND_MEMCHECK_H */ # define MEM_UNDEFINED(a,len) ((void) 0) # define MEM_NOACCESS(a,len) ((void) 0) # define MEM_CHECK_ADDRESSABLE(a,len) ((void) 0) # define MEM_CHECK_DEFINED(a,len) ((void) 0) -#endif /* HAVE_VALGRIND */ +#endif /* HAVE_VALGRIND_MEMCHECK_H */ #ifndef DBUG_OFF #define TRASH_FILL(A,B,C) do { const size_t trash_tmp= (B); memset(A, C, trash_tmp); MEM_UNDEFINED(A, trash_tmp); } while (0) @@ -41,3 +41,5 @@ #define TRASH_FREE(A,B) TRASH_FILL(A,B,0x8F) #define TRASH(A,B) TRASH_FREE(A,B) +# define DBUG_ASSERT_DEFINED(x) \ + DBUG_ASSERT(!VALGRIND_CHECK_MEM_IS_DEFINED(&(x), sizeof(x))) diff --git a/include/myisamchk.h b/include/myisamchk.h index 64724de1789..643241d84e5 100644 --- a/include/myisamchk.h +++ b/include/myisamchk.h @@ -16,14 +16,6 @@ /* Definitions needed for myisamchk/mariachk.c */ -/* - Entries marked as "QQ to be removed" are NOT used to - pass check/repair options to xxx_check.c. They are used - internally by xxxchk.c or/and ha_xxxx.cc and should NOT - be stored together with other flags. They should be removed - from the following list to make addition of new flags possible. -*/ - #ifndef _myisamchk_h #define _myisamchk_h @@ -66,6 +58,7 @@ typedef enum MI_STATS_METHOD_IGNORE_NULLS } enum_handler_stats_method; +struct st_myisam_info; typedef struct st_handler_check_param { @@ -122,6 +115,8 @@ typedef struct st_handler_check_param uint progress_counter; /* How often to call _report_progress() */ ulonglong progress, max_progress; + int (*fix_record)(struct st_myisam_info *info, uchar *record, int keynum); + mysql_mutex_t print_msg_mutex; my_bool need_print_msg_lock; myf malloc_flags; diff --git a/include/myisampack.h b/include/myisampack.h index 0795455dc3e..cfe1fcbc24a 100644 --- a/include/myisampack.h +++ b/include/myisampack.h @@ -52,11 +52,16 @@ (((uint32) (((const uchar*) (A))[2])) << 8) +\ (((uint32) (((const uchar*) (A))[1])) << 16) +\ (((uint32) (((const uchar*) (A))[0])) << 24))) + +#ifndef HAVE_mi_uint5korr #define mi_uint5korr(A) ((ulonglong)(((uint32) (((const uchar*) (A))[4])) +\ (((uint32) (((const uchar*) (A))[3])) << 8) +\ (((uint32) (((const uchar*) (A))[2])) << 16) +\ (((uint32) (((const uchar*) (A))[1])) << 24)) +\ (((ulonglong) (((const uchar*) (A))[0])) << 32)) +#endif /* HAVE_mi_uint5korr */ + +#ifndef HAVE_mi_uint6korr #define mi_uint6korr(A) ((ulonglong)(((uint32) (((const uchar*) (A))[5])) +\ (((uint32) (((const uchar*) (A))[4])) << 8) +\ (((uint32) (((const uchar*) (A))[3])) << 16) +\ @@ -64,6 +69,9 @@ (((ulonglong) (((uint32) (((const uchar*) (A))[1])) +\ (((uint32) (((const uchar*) (A))[0]) << 8)))) <<\ 32)) +#endif /* HAVE_mi_uint6korr */ + +#ifndef HAVE_mi_uint7korr #define mi_uint7korr(A) ((ulonglong)(((uint32) (((const uchar*) (A))[6])) +\ (((uint32) (((const uchar*) (A))[5])) << 8) +\ (((uint32) (((const uchar*) (A))[4])) << 16) +\ @@ -72,6 +80,9 @@ (((uint32) (((const uchar*) (A))[1])) << 8) +\ (((uint32) (((const uchar*) (A))[0])) << 16))) <<\ 32)) +#endif /* HAVE_mi_uint7korr */ + +#ifndef HAVE_mi_uint8korr #define mi_uint8korr(A) ((ulonglong)(((uint32) (((const uchar*) (A))[7])) +\ (((uint32) (((const uchar*) (A))[6])) << 8) +\ (((uint32) (((const uchar*) (A))[5])) << 16) +\ @@ -81,6 +92,7 @@ (((uint32) (((const uchar*) (A))[1])) << 16) +\ (((uint32) (((const uchar*) (A))[0])) << 24))) <<\ 32)) +#endif /* HAVE_mi_uint8korr */ /* This one is for uniformity */ #define mi_int1store(T,A) *((uchar*)(T))= (uchar) (A) diff --git a/include/mysql.h b/include/mysql.h index f088ad668a1..80e75c264e8 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -137,6 +137,13 @@ typedef unsigned long long my_ulonglong; /* backward compatibility define - to be removed eventually */ #define ER_WARN_DATA_TRUNCATED WARN_DATA_TRUNCATED #define WARN_PLUGIN_DELETE_BUILTIN ER_PLUGIN_DELETE_BUILTIN +#define ER_FK_DUP_NAME ER_DUP_CONSTRAINT_NAME +#define ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED +#define ER_PRIMARY_KEY_BASED_ON_VIRTUAL_COLUMN ER_PRIMARY_KEY_BASED_ON_GENERATED_COLUMN +#define ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN ER_WRONG_FK_OPTION_FOR_GENERATED_COLUMN +#define ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN +#define ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN ER_UNSUPPORTED_ACTION_ON_GENERATED_COLUMN +#define ER_UNSUPPORTED_ENGINE_FOR_VIRTUAL_COLUMNS ER_UNSUPPORTED_ENGINE_FOR_GENERATED_COLUMNS typedef struct st_mysql_rows { struct st_mysql_rows *next; /* list of rows */ @@ -367,7 +374,7 @@ void STDCALL mysql_server_end(void); /* mysql_server_init/end need to be called when using libmysqld or libmysqlclient (exactly, mysql_server_init() is called by mysql_init() so - you don't need to call it explicitely; but you need to call + you don't need to call it explicitly; but you need to call mysql_server_end() to free memory). The names are a bit misleading (mysql_SERVER* to be used when using libmysqlCLIENT). So we add more general names which suit well whether you're using libmysqld or libmysqlclient. We diff --git a/include/mysql.h.pp b/include/mysql.h.pp index 32d87b7391c..9d93b9ad325 100644 --- a/include/mysql.h.pp +++ b/include/mysql.h.pp @@ -9,7 +9,20 @@ enum enum_server_command COM_TABLE_DUMP, COM_CONNECT_OUT, COM_REGISTER_SLAVE, COM_STMT_PREPARE, COM_STMT_EXECUTE, COM_STMT_SEND_LONG_DATA, COM_STMT_CLOSE, COM_STMT_RESET, COM_SET_OPTION, COM_STMT_FETCH, COM_DAEMON, - COM_END + COM_MDB_GAP_BEG, + COM_MDB_GAP_END=250, + COM_SLAVE_WORKER=251, + COM_SLAVE_IO=252, + COM_SLAVE_SQL=253, + COM_MULTI=254, + COM_END=255 +}; +enum enum_indicator_type +{ + STMT_INDICATOR_NONE= 0, + STMT_INDICATOR_NULL, + STMT_INDICATOR_DEFAULT, + STMT_INDICATOR_IGNORE }; struct st_vio; typedef struct st_vio Vio; @@ -81,6 +94,16 @@ enum enum_mysql_set_option MYSQL_OPTION_MULTI_STATEMENTS_ON, MYSQL_OPTION_MULTI_STATEMENTS_OFF }; +enum enum_session_state_type +{ + SESSION_TRACK_SYSTEM_VARIABLES, + SESSION_TRACK_SCHEMA, + SESSION_TRACK_STATE_CHANGE, + SESSION_TRACK_GTIDS, + SESSION_TRACK_TRANSACTION_CHARACTERISTICS, + SESSION_TRACK_TRANSACTION_STATE, + SESSION_TRACK_always_at_the_end +}; my_bool my_net_init(NET *net, Vio* vio, void *thd, unsigned int my_flags); void my_net_local_init(NET *net); void net_end(NET *net); @@ -93,6 +116,8 @@ my_bool net_write_command(NET *net,unsigned char command, const unsigned char *packet, size_t len); int net_real_write(NET *net,const unsigned char *packet, size_t len); unsigned long my_net_read_packet(NET *net, my_bool read_from_server); +unsigned long my_net_read_packet_reallen(NET *net, my_bool read_from_server, + unsigned long* reallen); struct sockaddr; int my_connect(my_socket s, const struct sockaddr *name, unsigned int namelen, unsigned int timeout); diff --git a/include/mysql/plugin_audit.h b/include/mysql/plugin_audit.h index cbdd6591b70..10039c4c1fa 100644 --- a/include/mysql/plugin_audit.h +++ b/include/mysql/plugin_audit.h @@ -60,7 +60,7 @@ struct mysql_event_general unsigned int general_command_length; const char *general_query; unsigned int general_query_length; - struct charset_info_st *general_charset; + const struct charset_info_st *general_charset; unsigned long long general_time; unsigned long long general_rows; /* Added in version 0x302 */ diff --git a/include/mysql/plugin_audit.h.pp b/include/mysql/plugin_audit.h.pp index 24f2c69345d..aaf41c74a54 100644 --- a/include/mysql/plugin_audit.h.pp +++ b/include/mysql/plugin_audit.h.pp @@ -423,7 +423,7 @@ struct mysql_event_general unsigned int general_command_length; const char *general_query; unsigned int general_query_length; - struct charset_info_st *general_charset; + const struct charset_info_st *general_charset; unsigned long long general_time; unsigned long long general_rows; unsigned long long query_id; diff --git a/include/mysql/psi/mysql_socket.h b/include/mysql/psi/mysql_socket.h index 1dbe8c7eb22..619f600a776 100644 --- a/include/mysql/psi/mysql_socket.h +++ b/include/mysql/psi/mysql_socket.h @@ -19,8 +19,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA #ifndef MYSQL_SOCKET_H #define MYSQL_SOCKET_H -/* For strlen() */ -#include <string.h> /* For MY_STAT */ #include <my_dir.h> /* For my_chsize */ @@ -1014,7 +1012,7 @@ inline_mysql_socket_accept MYSQL_SOCKET socket_listen, struct sockaddr *addr, socklen_t *addr_len) { #ifdef FD_CLOEXEC - int flags; + int flags __attribute__ ((unused)); #endif MYSQL_SOCKET socket_accept= MYSQL_INVALID_SOCKET; diff --git a/include/mysql/psi/mysql_thread.h b/include/mysql/psi/mysql_thread.h index 08dfeac37f1..54a0eaabef7 100644 --- a/include/mysql/psi/mysql_thread.h +++ b/include/mysql/psi/mysql_thread.h @@ -71,8 +71,6 @@ struct st_mysql_mutex /** The real mutex. */ #ifdef SAFE_MUTEX safe_mutex_t m_mutex; -#elif defined(MY_PTHREAD_FASTMUTEX) - my_pthread_fastmutex_t m_mutex; #else pthread_mutex_t m_mutex; #endif @@ -619,8 +617,6 @@ static inline int inline_mysql_mutex_init( #endif #ifdef SAFE_MUTEX return safe_mutex_init(&that->m_mutex, attr, src_name, src_file, src_line); -#elif defined(MY_PTHREAD_FASTMUTEX) - return my_pthread_fastmutex_init(&that->m_mutex, attr); #else return pthread_mutex_init(&that->m_mutex, attr); #endif @@ -642,8 +638,6 @@ static inline int inline_mysql_mutex_destroy( #endif #ifdef SAFE_MUTEX return safe_mutex_destroy(&that->m_mutex, src_file, src_line); -#elif defined(MY_PTHREAD_FASTMUTEX) - return pthread_mutex_destroy(&that->m_mutex.mutex); #else return pthread_mutex_destroy(&that->m_mutex); #endif @@ -670,8 +664,6 @@ static inline int inline_mysql_mutex_lock( /* Instrumented code */ #ifdef SAFE_MUTEX result= safe_mutex_lock(&that->m_mutex, FALSE, src_file, src_line); -#elif defined(MY_PTHREAD_FASTMUTEX) - result= my_pthread_fastmutex_lock(&that->m_mutex); #else result= pthread_mutex_lock(&that->m_mutex); #endif @@ -687,8 +679,6 @@ static inline int inline_mysql_mutex_lock( /* Non instrumented code */ #ifdef SAFE_MUTEX result= safe_mutex_lock(&that->m_mutex, FALSE, src_file, src_line); -#elif defined(MY_PTHREAD_FASTMUTEX) - result= my_pthread_fastmutex_lock(&that->m_mutex); #else result= pthread_mutex_lock(&that->m_mutex); #endif @@ -717,8 +707,6 @@ static inline int inline_mysql_mutex_trylock( /* Instrumented code */ #ifdef SAFE_MUTEX result= safe_mutex_lock(&that->m_mutex, TRUE, src_file, src_line); -#elif defined(MY_PTHREAD_FASTMUTEX) - result= pthread_mutex_trylock(&that->m_mutex.mutex); #else result= pthread_mutex_trylock(&that->m_mutex); #endif @@ -734,8 +722,6 @@ static inline int inline_mysql_mutex_trylock( /* Non instrumented code */ #ifdef SAFE_MUTEX result= safe_mutex_lock(&that->m_mutex, TRUE, src_file, src_line); -#elif defined(MY_PTHREAD_FASTMUTEX) - result= pthread_mutex_trylock(&that->m_mutex.mutex); #else result= pthread_mutex_trylock(&that->m_mutex); #endif @@ -759,8 +745,6 @@ static inline int inline_mysql_mutex_unlock( #ifdef SAFE_MUTEX result= safe_mutex_unlock(&that->m_mutex, src_file, src_line); -#elif defined(MY_PTHREAD_FASTMUTEX) - result= pthread_mutex_unlock(&that->m_mutex.mutex); #else result= pthread_mutex_unlock(&that->m_mutex); #endif @@ -1256,7 +1240,7 @@ static inline int inline_mysql_thread_create( return result; } -static inline void inline_mysql_thread_set_psi_id(ulong id) +static inline void inline_mysql_thread_set_psi_id(my_thread_id id) { struct PSI_thread *psi= PSI_THREAD_CALL(get_thread)(); PSI_THREAD_CALL(set_thread_id)(psi, id); diff --git a/include/mysql/psi/psi_base.h b/include/mysql/psi/psi_base.h new file mode 100644 index 00000000000..10593c4dab4 --- /dev/null +++ b/include/mysql/psi/psi_base.h @@ -0,0 +1,147 @@ +/* Copyright (c) 2008, 2015, Oracle and/or its affiliates. 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. + + 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, + 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */ + +#ifndef MYSQL_PSI_BASE_H +#define MYSQL_PSI_BASE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + @file mysql/psi/psi_base.h + Performance schema instrumentation interface. + + @defgroup Instrumentation_interface Instrumentation Interface + @ingroup Performance_schema + @{ +*/ + +#define PSI_INSTRUMENT_ME 0 + +#define PSI_NOT_INSTRUMENTED 0 + +/** + Global flag. + This flag indicate that an instrumentation point is a global variable, + or a singleton. +*/ +#define PSI_FLAG_GLOBAL (1 << 0) + +/** + Mutable flag. + This flag indicate that an instrumentation point is a general placeholder, + that can mutate into a more specific instrumentation point. +*/ +#define PSI_FLAG_MUTABLE (1 << 1) + +#define PSI_FLAG_THREAD (1 << 2) + +/** + Stage progress flag. + This flag apply to the stage instruments only. + It indicates the instrumentation provides progress data. +*/ +#define PSI_FLAG_STAGE_PROGRESS (1 << 3) + +/** + Shared Exclusive flag. + Indicates that rwlock support the shared exclusive state. +*/ +#define PSI_RWLOCK_FLAG_SX (1 << 4) + +/** + Transferable flag. + This flag indicate that an instrumented object can + be created by a thread and destroyed by another thread. +*/ +#define PSI_FLAG_TRANSFER (1 << 5) + +#ifdef HAVE_PSI_INTERFACE + +/** + @def PSI_VERSION_1 + Performance Schema Interface number for version 1. + This version is supported. +*/ +#define PSI_VERSION_1 1 + +/** + @def PSI_VERSION_2 + Performance Schema Interface number for version 2. + This version is not implemented, it's a placeholder. +*/ +#define PSI_VERSION_2 2 + +/** + @def PSI_CURRENT_VERSION + Performance Schema Interface number for the most recent version. + The most current version is @c PSI_VERSION_1 +*/ +#define PSI_CURRENT_VERSION 1 + +/** + @def USE_PSI_1 + Define USE_PSI_1 to use the interface version 1. +*/ + +/** + @def USE_PSI_2 + Define USE_PSI_2 to use the interface version 2. +*/ + +/** + @def HAVE_PSI_1 + Define HAVE_PSI_1 if the interface version 1 needs to be compiled in. +*/ + +/** + @def HAVE_PSI_2 + Define HAVE_PSI_2 if the interface version 2 needs to be compiled in. +*/ + +#ifndef USE_PSI_2 +#ifndef USE_PSI_1 +#define USE_PSI_1 +#endif +#endif + +#ifdef USE_PSI_1 +#define HAVE_PSI_1 +#endif + +#ifdef USE_PSI_2 +#define HAVE_PSI_2 +#endif + +/* + Allow to override PSI_XXX_CALL at compile time + with more efficient implementations, if available. + If nothing better is available, + make a dynamic call using the PSI_server function pointer. +*/ + +#define PSI_DYNAMIC_CALL(M) PSI_server->M + +#endif /* HAVE_PSI_INTERFACE */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* MYSQL_PSI_BASE_H */ + diff --git a/include/mysql/psi/psi_memory.h b/include/mysql/psi/psi_memory.h new file mode 100644 index 00000000000..725b3ed77d0 --- /dev/null +++ b/include/mysql/psi/psi_memory.h @@ -0,0 +1,155 @@ +/* Copyright (c) 2013, 2015, Oracle and/or its affiliates. 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. + + 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, + 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */ + +#ifndef MYSQL_PSI_MEMORY_H +#define MYSQL_PSI_MEMORY_H + +#include "psi_base.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + @file mysql/psi/psi_memory.h + Performance schema instrumentation interface. + + @defgroup Instrumentation_interface Instrumentation Interface + @ingroup Performance_schema + @{ +*/ + +#ifdef HAVE_PSI_INTERFACE +#ifndef DISABLE_ALL_PSI +#ifndef DISABLE_PSI_MEMORY +#define HAVE_PSI_MEMORY_INTERFACE +#endif /* DISABLE_PSI_MEMORY */ +#endif /* DISABLE_ALL_PSI */ +#endif /* HAVE_PSI_INTERFACE */ + +struct PSI_thread; + +/** + Instrumented memory key. + To instrument memory, a memory key must be obtained using @c register_memory. + Using a zero key always disable the instrumentation. +*/ +typedef unsigned int PSI_memory_key; + +#ifdef HAVE_PSI_1 + +/** + @defgroup Group_PSI_v1 Application Binary Interface, version 1 + @ingroup Instrumentation_interface + @{ +*/ + +/** + Memory instrument information. + @since PSI_VERSION_1 + This structure is used to register instrumented memory. +*/ +struct PSI_memory_info_v1 +{ + /** Pointer to the key assigned to the registered memory. */ + PSI_memory_key *m_key; + /** The name of the memory instrument to register. */ + const char *m_name; + /** + The flags of the socket instrument to register. + @sa PSI_FLAG_GLOBAL + */ + int m_flags; +}; +typedef struct PSI_memory_info_v1 PSI_memory_info_v1; + +/** + Memory registration API. + @param category a category name (typically a plugin name) + @param info an array of memory info to register + @param count the size of the info array +*/ +typedef void (*register_memory_v1_t) + (const char *category, struct PSI_memory_info_v1 *info, int count); + +/** + Instrument memory allocation. + @param key the memory instrument key + @param size the size of memory allocated + @param[out] owner the memory owner + @return the effective memory instrument key +*/ +typedef PSI_memory_key (*memory_alloc_v1_t) + (PSI_memory_key key, size_t size, struct PSI_thread ** owner); + +/** + Instrument memory re allocation. + @param key the memory instrument key + @param old_size the size of memory previously allocated + @param new_size the size of memory re allocated + @param[in, out] owner the memory owner + @return the effective memory instrument key +*/ +typedef PSI_memory_key (*memory_realloc_v1_t) + (PSI_memory_key key, size_t old_size, size_t new_size, struct PSI_thread ** owner); + +/** + Instrument memory claim. + @param key the memory instrument key + @param size the size of memory allocated + @param[in, out] owner the memory owner + @return the effective memory instrument key +*/ +typedef PSI_memory_key (*memory_claim_v1_t) + (PSI_memory_key key, size_t size, struct PSI_thread ** owner); + +/** + Instrument memory free. + @param key the memory instrument key + @param size the size of memory allocated + @param owner the memory owner +*/ +typedef void (*memory_free_v1_t) + (PSI_memory_key key, size_t size, struct PSI_thread * owner); + +/** @} (end of group Group_PSI_v1) */ + +#endif /* HAVE_PSI_1 */ + +#ifdef HAVE_PSI_2 +struct PSI_memory_info_v2 +{ + int placeholder; +}; + +#endif /* HAVE_PSI_2 */ + +#ifdef USE_PSI_1 +typedef struct PSI_memory_info_v1 PSI_memory_info; +#endif + +#ifdef USE_PSI_2 +typedef struct PSI_memory_info_v2 PSI_memory_info; +#endif + +/** @} (end of group Instrumentation_interface) */ + +#ifdef __cplusplus +} +#endif + + +#endif /* MYSQL_PSI_MEMORY_H */ + diff --git a/include/mysql_com.h b/include/mysql_com.h index 23be12bdc43..c399520022d 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -21,6 +21,8 @@ #ifndef _mysql_com_h #define _mysql_com_h +#include "my_decimal_limits.h" + #define HOSTNAME_LENGTH 60 #define SYSTEM_CHARSET_MBMAXLEN 3 #define NAME_CHAR_LEN 64 /* Field/table name length */ @@ -71,6 +73,14 @@ #define TABLE_PARTITION_COMMENT_MAXLEN 1024 /* + Maximum length of protocol packet. + OK packet length limit also restricted to this value as any length greater + than this value will have first byte of OK packet to be 254 thus does not + provide a means to identify if this is OK or EOF packet. +*/ +#define MAX_PACKET_LENGTH (256L*256L*256L-1) + +/* USER_HOST_BUFF_SIZE -- length of string buffer, that is enough to contain username and hostname parts of the user identifier with trailing zero in MySQL standard format: @@ -102,9 +112,26 @@ enum enum_server_command COM_STMT_PREPARE, COM_STMT_EXECUTE, COM_STMT_SEND_LONG_DATA, COM_STMT_CLOSE, COM_STMT_RESET, COM_SET_OPTION, COM_STMT_FETCH, COM_DAEMON, /* don't forget to update const char *command_name[] in sql_parse.cc */ - + COM_MDB_GAP_BEG, + COM_MDB_GAP_END=250, + COM_SLAVE_WORKER=251, + COM_SLAVE_IO=252, + COM_SLAVE_SQL=253, + COM_MULTI=254, /* Must be last */ - COM_END + COM_END=255 +}; + + +/* + Bulk PS protocol indicator value: +*/ +enum enum_indicator_type +{ + STMT_INDICATOR_NONE= 0, + STMT_INDICATOR_NULL, + STMT_INDICATOR_DEFAULT, + STMT_INDICATOR_IGNORE }; /* sql type stored in .frm files for virtual fields */ @@ -139,7 +166,6 @@ enum enum_server_command #define NUM_FLAG 32768 /* Field is num (for clients) */ #define PART_KEY_FLAG 16384 /* Intern; Part of some key */ #define GROUP_FLAG 32768 /* Intern: Group field */ -#define UNIQUE_FLAG 65536 /* Intern: Used by sql_yacc */ #define BINCMP_FLAG 131072 /* Intern: Used by sql_yacc */ #define GET_FIXED_FIELDS_FLAG (1 << 18) /* Used to get fields in item tree */ #define FIELD_IN_PART_FUNC_FLAG (1 << 19)/* Field part of partition func */ @@ -155,8 +181,6 @@ enum enum_server_command #define FIELD_FLAGS_COLUMN_FORMAT 24 /* Field column format, bit 24-25 */ #define FIELD_FLAGS_COLUMN_FORMAT_MASK (3 << FIELD_FLAGS_COLUMN_FORMAT) #define FIELD_IS_DROPPED (1<< 26) /* Intern: Field is being dropped */ -#define HAS_EXPLICIT_VALUE (1 << 27) /* An INSERT/UPDATE operation supplied - an explicit default value */ #define REFRESH_GRANT (1ULL << 0) /* Refresh grant tables */ #define REFRESH_LOG (1ULL << 1) /* Start on new log file */ @@ -189,35 +213,44 @@ enum enum_server_command #define REFRESH_GENERIC (1ULL << 30) #define REFRESH_FAST (1ULL << 31) /* Intern flag */ -#define CLIENT_LONG_PASSWORD 1 /* new more secure passwords */ -#define CLIENT_FOUND_ROWS 2 /* Found instead of affected rows */ -#define CLIENT_LONG_FLAG 4 /* Get all column flags */ -#define CLIENT_CONNECT_WITH_DB 8 /* One can specify db on connect */ -#define CLIENT_NO_SCHEMA 16 /* Don't allow database.table.column */ -#define CLIENT_COMPRESS 32 /* Can use compression protocol */ -#define CLIENT_ODBC 64 /* Odbc client */ -#define CLIENT_LOCAL_FILES 128 /* Can use LOAD DATA LOCAL */ -#define CLIENT_IGNORE_SPACE 256 /* Ignore spaces before '(' */ -#define CLIENT_PROTOCOL_41 512 /* New 4.1 protocol */ -#define CLIENT_INTERACTIVE 1024 /* This is an interactive client */ -#define CLIENT_SSL 2048 /* Switch to SSL after handshake */ -#define CLIENT_IGNORE_SIGPIPE 4096 /* IGNORE sigpipes */ -#define CLIENT_TRANSACTIONS 8192 /* Client knows about transactions */ -#define CLIENT_RESERVED 16384 /* Old flag for 4.1 protocol */ -#define CLIENT_SECURE_CONNECTION 32768 /* New 4.1 authentication */ -#define CLIENT_MULTI_STATEMENTS (1UL << 16) /* Enable/disable multi-stmt support */ -#define CLIENT_MULTI_RESULTS (1UL << 17) /* Enable/disable multi-results */ -#define CLIENT_PS_MULTI_RESULTS (1UL << 18) /* Multi-results in PS-protocol */ - -#define CLIENT_PLUGIN_AUTH (1UL << 19) /* Client supports plugin authentication */ -#define CLIENT_CONNECT_ATTRS (1UL << 20) /* Client supports connection attributes */ +#define CLIENT_LONG_PASSWORD 0 /* obsolete flag */ +#define CLIENT_MYSQL 1ULL /* mysql/old mariadb server/client */ +#define CLIENT_FOUND_ROWS 2ULL /* Found instead of affected rows */ +#define CLIENT_LONG_FLAG 4ULL /* Get all column flags */ +#define CLIENT_CONNECT_WITH_DB 8ULL /* One can specify db on connect */ +#define CLIENT_NO_SCHEMA 16ULL /* Don't allow database.table.column */ +#define CLIENT_COMPRESS 32ULL /* Can use compression protocol */ +#define CLIENT_ODBC 64ULL /* Odbc client */ +#define CLIENT_LOCAL_FILES 128ULL /* Can use LOAD DATA LOCAL */ +#define CLIENT_IGNORE_SPACE 256ULL /* Ignore spaces before '(' */ +#define CLIENT_PROTOCOL_41 512ULL /* New 4.1 protocol */ +#define CLIENT_INTERACTIVE 1024ULL /* This is an interactive client */ +#define CLIENT_SSL 2048ULL /* Switch to SSL after handshake */ +#define CLIENT_IGNORE_SIGPIPE 4096ULL /* IGNORE sigpipes */ +#define CLIENT_TRANSACTIONS 8192ULL /* Client knows about transactions */ +#define CLIENT_RESERVED 16384ULL /* Old flag for 4.1 protocol */ +#define CLIENT_SECURE_CONNECTION 32768ULL /* New 4.1 authentication */ +#define CLIENT_MULTI_STATEMENTS (1ULL << 16) /* Enable/disable multi-stmt support */ +#define CLIENT_MULTI_RESULTS (1ULL << 17) /* Enable/disable multi-results */ +#define CLIENT_PS_MULTI_RESULTS (1ULL << 18) /* Multi-results in PS-protocol */ + +#define CLIENT_PLUGIN_AUTH (1ULL << 19) /* Client supports plugin authentication */ +#define CLIENT_CONNECT_ATTRS (1ULL << 20) /* Client supports connection attributes */ /* Enable authentication response packet to be larger than 255 bytes. */ -#define CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA (1UL << 21) +#define CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA (1ULL << 21) /* Don't close the connection for a connection with expired password. */ -#define CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS (1UL << 22) +#define CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS (1ULL << 22) + +/** + Capable of handling server state change information. Its a hint to the + server to include the state change information in Ok packet. +*/ +#define CLIENT_SESSION_TRACK (1ULL << 23) +/* Client no longer needs EOF packet */ +#define CLIENT_DEPRECATE_EOF (1ULL << 24) -#define CLIENT_PROGRESS (1UL << 29) /* Client support progress indicator */ -#define CLIENT_SSL_VERIFY_SERVER_CERT (1UL << 30) +#define CLIENT_PROGRESS_OBSOLETE (1ULL << 29) +#define CLIENT_SSL_VERIFY_SERVER_CERT (1ULL << 30) /* It used to be that if mysql_real_connect() failed, it would delete any options set by the client, unless the CLIENT_REMEMBER_OPTIONS flag was @@ -227,7 +260,16 @@ enum enum_server_command always preserve any options set in case of failed connect, and this option is effectively always set. */ -#define CLIENT_REMEMBER_OPTIONS (1UL << 31) +#define CLIENT_REMEMBER_OPTIONS (1ULL << 31) + +/* MariaDB extended capability flags */ +#define MARIADB_CLIENT_FLAGS_MASK 0xffffffff00000000ULL +/* Client support progress indicator */ +#define MARIADB_CLIENT_PROGRESS (1ULL << 32) +/* support COM_MULTI */ +#define MARIADB_CLIENT_COM_MULTI (1ULL << 33) +/* support of array binding */ +#define MARIADB_CLIENT_STMT_BULK_OPERATIONS (1ULL << 34) #ifdef HAVE_COMPRESS #define CAN_CLIENT_COMPRESS CLIENT_COMPRESS @@ -235,8 +277,12 @@ enum enum_server_command #define CAN_CLIENT_COMPRESS 0 #endif -/* Gather all possible capabilites (flags) supported by the server */ -#define CLIENT_ALL_FLAGS (CLIENT_LONG_PASSWORD | \ +/* + Gather all possible capabilites (flags) supported by the server + + MARIADB_* flags supported only by MariaDB connector(s). +*/ +#define CLIENT_ALL_FLAGS (\ CLIENT_FOUND_ROWS | \ CLIENT_LONG_FLAG | \ CLIENT_CONNECT_WITH_DB | \ @@ -257,10 +303,14 @@ enum enum_server_command CLIENT_PS_MULTI_RESULTS | \ CLIENT_SSL_VERIFY_SERVER_CERT | \ CLIENT_REMEMBER_OPTIONS | \ - CLIENT_PROGRESS | \ + MARIADB_CLIENT_PROGRESS | \ CLIENT_PLUGIN_AUTH | \ CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA | \ - CLIENT_CONNECT_ATTRS) + CLIENT_SESSION_TRACK |\ + CLIENT_DEPRECATE_EOF |\ + CLIENT_CONNECT_ATTRS |\ + MARIADB_CLIENT_COM_MULTI |\ + MARIADB_CLIENT_STMT_BULK_OPERATIONS) /* To be added later: @@ -323,6 +373,11 @@ enum enum_server_command */ #define SERVER_STATUS_IN_TRANS_READONLY 8192 +/** + This status flag, when on, implies that one of the state information has + changed on the server because of the execution of the last statement. +*/ +#define SERVER_SESSION_STATE_CHANGED (1UL << 14) /** Server status flags that must be cleared when starting @@ -339,7 +394,8 @@ enum enum_server_command SERVER_QUERY_WAS_SLOW |\ SERVER_STATUS_DB_DROPPED |\ SERVER_STATUS_CURSOR_EXISTS|\ - SERVER_STATUS_LAST_ROW_SENT) + SERVER_STATUS_LAST_ROW_SENT|\ + SERVER_SESSION_STATE_CHANGED) #define MYSQL_ERRMSG_SIZE 512 #define NET_READ_TIMEOUT 30 /* Timeout on read */ @@ -506,6 +562,26 @@ enum enum_mysql_set_option MYSQL_OPTION_MULTI_STATEMENTS_OFF }; +/* + Type of state change information that the server can include in the Ok + packet. +*/ +enum enum_session_state_type +{ + SESSION_TRACK_SYSTEM_VARIABLES, /* Session system variables */ + SESSION_TRACK_SCHEMA, /* Current schema */ + SESSION_TRACK_STATE_CHANGE, /* track session state changes */ + SESSION_TRACK_GTIDS, + SESSION_TRACK_TRANSACTION_CHARACTERISTICS, /* Transaction chistics */ + SESSION_TRACK_TRANSACTION_STATE, /* Transaction state */ + SESSION_TRACK_always_at_the_end /* must be last */ +}; + +#define SESSION_TRACK_BEGIN SESSION_TRACK_SYSTEM_VARIABLES + +#define IS_SESSION_STATE_TYPE(T) \ + (((int)(T) >= SESSION_TRACK_BEGIN) && ((T) < SESSION_TRACK_always_at_the_end)) + #define net_new_transaction(net) ((net)->pkt_nr=0) #ifdef __cplusplus @@ -524,6 +600,8 @@ my_bool net_write_command(NET *net,unsigned char command, const unsigned char *packet, size_t len); int net_real_write(NET *net,const unsigned char *packet, size_t len); unsigned long my_net_read_packet(NET *net, my_bool read_from_server); +unsigned long my_net_read_packet_reallen(NET *net, my_bool read_from_server, + unsigned long* reallen); #define my_net_read(A) my_net_read_packet((A), 0) #ifdef MY_GLOBAL_INCLUDED @@ -619,11 +697,7 @@ my_bool my_thread_init(void); void my_thread_end(void); #ifdef MY_GLOBAL_INCLUDED -ulong STDCALL net_field_length(uchar **packet); -my_ulonglong net_field_length_ll(uchar **packet); -my_ulonglong safe_net_field_length_ll(uchar **packet, size_t packet_len); -uchar *net_store_length(uchar *pkg, ulonglong length); -uchar *safe_net_store_length(uchar *pkg, size_t pkg_len, ulonglong length); +#include "pack.h" #endif #ifdef __cplusplus @@ -634,5 +708,11 @@ uchar *safe_net_store_length(uchar *pkg, size_t pkg_len, ulonglong length); #define MYSQL_STMT_HEADER 4 #define MYSQL_LONG_DATA_HEADER 6 -#define NOT_FIXED_DEC 31 +/* + If a float or double field have more than this number of decimals, + it's regarded as floating point field without any specific number of + decimals +*/ + + #endif diff --git a/include/pack.h b/include/pack.h new file mode 100644 index 00000000000..f991e72326b --- /dev/null +++ b/include/pack.h @@ -0,0 +1,29 @@ +/* Copyright (c) 2016, MariaDB + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#ifdef __cplusplus +extern "C" { +#endif + +ulong net_field_length(uchar **packet); +my_ulonglong net_field_length_ll(uchar **packet); +my_ulonglong safe_net_field_length_ll(uchar **packet, size_t packet_len); +uchar *net_store_length(uchar *pkg, ulonglong length); +uchar *safe_net_store_length(uchar *pkg, size_t pkg_len, ulonglong length); +unsigned int net_length_size(ulonglong num); + +#ifdef __cplusplus +} +#endif diff --git a/include/sql_common.h b/include/sql_common.h index 39b8ce18517..bbf459e1e55 100644 --- a/include/sql_common.h +++ b/include/sql_common.h @@ -77,9 +77,13 @@ typedef struct st_mysql_methods #endif } MYSQL_METHODS; +#ifdef LIBMARIADB +#define simple_command(mysql, command, arg, length, skip_check) ma_simple_command(mysql, command, (char *)arg, length, skip_check, NULL) +#else #define simple_command(mysql, command, arg, length, skip_check) \ (*(mysql)->methods->advanced_command)(mysql, command, 0, \ 0, arg, length, skip_check, NULL) +#endif #define stmt_command(mysql, command, arg, length, stmt) \ (*(mysql)->methods->advanced_command)(mysql, command, 0, \ 0, arg, length, 1, stmt) @@ -100,6 +104,7 @@ cli_advanced_command(MYSQL *mysql, enum enum_server_command command, const unsigned char *arg, ulong arg_length, my_bool skip_check, MYSQL_STMT *stmt); unsigned long cli_safe_read(MYSQL *mysql); +unsigned long cli_safe_read_reallen(MYSQL *mysql, ulong* reallen); void net_clear_error(NET *net); void set_stmt_errmsg(MYSQL_STMT *stmt, NET *net); void set_stmt_error(MYSQL_STMT *stmt, int errcode, const char *sqlstate, @@ -109,8 +114,9 @@ void set_mysql_extended_error(MYSQL *mysql, int errcode, const char *sqlstate, const char *format, ...); /* client side of the pluggable authentication */ +struct st_vio; struct st_plugin_vio_info; -void mpvio_info(Vio *vio, struct st_plugin_vio_info *info); +void mpvio_info(struct st_vio *vio, struct st_plugin_vio_info *info); int run_plugin_auth(MYSQL *mysql, char *data, uint data_len, const char *data_plugin, const char *db); int mysql_client_plugin_init(); diff --git a/include/thr_lock.h b/include/thr_lock.h index bc916b8ec9c..fb69d8a693e 100644 --- a/include/thr_lock.h +++ b/include/thr_lock.h @@ -139,9 +139,10 @@ typedef struct st_thr_lock { extern LIST *thr_lock_thread_list; extern mysql_mutex_t THR_LOCK_lock; +struct st_my_thread_var; my_bool init_thr_lock(void); /* Must be called once/thread */ -void thr_lock_info_init(THR_LOCK_INFO *info); +void thr_lock_info_init(THR_LOCK_INFO *info, struct st_my_thread_var *tmp); void thr_lock_init(THR_LOCK *lock); void thr_lock_delete(THR_LOCK *lock); void thr_lock_data_init(THR_LOCK *lock,THR_LOCK_DATA *data, diff --git a/include/thread_pool_priv.h b/include/thread_pool_priv.h index 4270c32c826..afa2848ae88 100644 --- a/include/thread_pool_priv.h +++ b/include/thread_pool_priv.h @@ -100,8 +100,6 @@ bool thd_is_connection_alive(THD *thd); void close_connection(THD *thd, uint errcode); /* End the connection before closing it */ void end_connection(THD *thd); -/* Cleanup the THD object */ -void thd_cleanup(THD *thd); /* Decrement connection counter */ void dec_connection_count(); /* Destroy THD object */ diff --git a/include/violite.h b/include/violite.h index a7165ca91a9..8be9859ceb4 100644 --- a/include/violite.h +++ b/include/violite.h @@ -211,14 +211,6 @@ void vio_end(void); #define SHUT_RD SD_RECEIVE #endif -/* - Set thread id for io cancellation (required on Windows XP only, - and should to be removed if XP is no more supported) -*/ - -#define vio_set_thread_id(vio, tid) if(vio) vio->thread_id= tid -#else -#define vio_set_thread_id(vio, tid) #endif /* This enumerator is used in parser - should be always visible */ @@ -288,7 +280,6 @@ struct st_vio #ifdef _WIN32 HANDLE hPipe; OVERLAPPED overlapped; - DWORD thread_id; /* Used on XP only by vio_shutdown() */ DWORD read_timeout_ms; DWORD write_timeout_ms; #endif |