Merge branch '10.0-galera' into 10.1

This commit is contained in:
Sergei Golubchik 2016-11-02 13:44:07 +01:00
commit a98c85bb50
162 changed files with 5637 additions and 870 deletions

View file

@ -245,7 +245,8 @@ static void end_pager();
static void init_tee(const char *);
static void end_tee();
static const char* construct_prompt();
static char *get_arg(char *line, my_bool get_next_arg);
enum get_arg_mode { CHECK, GET, GET_NEXT};
static char *get_arg(char *line, get_arg_mode mode);
static void init_username();
static void add_int_to_prompt(int toadd);
static int get_result_width(MYSQL_RES *res);
@ -2255,7 +2256,7 @@ static COMMANDS *find_command(char *name)
if (!my_strnncoll(&my_charset_latin1, (uchar*) name, len,
(uchar*) commands[i].name, len) &&
(commands[i].name[len] == '\0') &&
(!end || commands[i].takes_params))
(!end || (commands[i].takes_params && get_arg(name, CHECK))))
{
index= i;
break;
@ -3173,7 +3174,7 @@ com_charset(String *buffer __attribute__((unused)), char *line)
char buff[256], *param;
CHARSET_INFO * new_cs;
strmake_buf(buff, line);
param= get_arg(buff, 0);
param= get_arg(buff, GET);
if (!param || !*param)
{
return put_info("Usage: \\C charset_name | charset charset_name",
@ -4259,12 +4260,12 @@ com_connect(String *buffer, char *line)
#ifdef EXTRA_DEBUG
tmp[1]= 0;
#endif
tmp= get_arg(buff, 0);
tmp= get_arg(buff, GET);
if (tmp && *tmp)
{
my_free(current_db);
current_db= my_strdup(tmp, MYF(MY_WME));
tmp= get_arg(buff, 1);
tmp= get_arg(buff, GET_NEXT);
if (tmp)
{
my_free(current_host);
@ -4367,7 +4368,7 @@ com_delimiter(String *buffer __attribute__((unused)), char *line)
char buff[256], *tmp;
strmake_buf(buff, line);
tmp= get_arg(buff, 0);
tmp= get_arg(buff, GET);
if (!tmp || !*tmp)
{
@ -4398,7 +4399,7 @@ com_use(String *buffer __attribute__((unused)), char *line)
bzero(buff, sizeof(buff));
strmake_buf(buff, line);
tmp= get_arg(buff, 0);
tmp= get_arg(buff, GET);
if (!tmp || !*tmp)
{
put_info("USE must be followed by a database name", INFO_ERROR);
@ -4483,23 +4484,22 @@ com_nowarnings(String *buffer __attribute__((unused)),
}
/*
Gets argument from a command on the command line. If get_next_arg is
not defined, skips the command and returns the first argument. The
line is modified by adding zero to the end of the argument. If
get_next_arg is defined, then the function searches for end of string
first, after found, returns the next argument and adds zero to the
end. If you ever wish to use this feature, remember to initialize all
items in the array to zero first.
Gets argument from a command on the command line. If mode is not GET_NEXT,
skips the command and returns the first argument. The line is modified by
adding zero to the end of the argument. If mode is GET_NEXT, then the
function searches for end of string first, after found, returns the next
argument and adds zero to the end. If you ever wish to use this feature,
remember to initialize all items in the array to zero first.
*/
char *get_arg(char *line, my_bool get_next_arg)
static char *get_arg(char *line, get_arg_mode mode)
{
char *ptr, *start;
my_bool quoted= 0, valid_arg= 0;
bool short_cmd= false;
char qtype= 0;
ptr= line;
if (get_next_arg)
if (mode == GET_NEXT)
{
for (; *ptr; ptr++) ;
if (*(ptr + 1))
@ -4510,7 +4510,7 @@ char *get_arg(char *line, my_bool get_next_arg)
/* skip leading white spaces */
while (my_isspace(charset_info, *ptr))
ptr++;
if (*ptr == '\\') // short command was used
if ((short_cmd= *ptr == '\\')) // short command was used
ptr+= 2;
else
while (*ptr &&!my_isspace(charset_info, *ptr)) // skip command
@ -4523,24 +4523,28 @@ char *get_arg(char *line, my_bool get_next_arg)
if (*ptr == '\'' || *ptr == '\"' || *ptr == '`')
{
qtype= *ptr;
quoted= 1;
ptr++;
}
for (start=ptr ; *ptr; ptr++)
{
if (*ptr == '\\' && ptr[1]) // escaped character
if ((*ptr == '\\' && ptr[1]) || // escaped character
(!short_cmd && qtype && *ptr == qtype && ptr[1] == qtype)) // quote
{
// Remove the backslash
strmov_overlapp(ptr, ptr+1);
// Remove (or skip) the backslash (or a second quote)
if (mode != CHECK)
strmov_overlapp(ptr, ptr+1);
else
ptr++;
}
else if ((!quoted && *ptr == ' ') || (quoted && *ptr == qtype))
else if (*ptr == (qtype ? qtype : ' '))
{
*ptr= 0;
qtype= 0;
if (mode != CHECK)
*ptr= 0;
break;
}
}
valid_arg= ptr != start;
return valid_arg ? start : NullS;
return ptr != start && !qtype ? start : NullS;
}

View file

@ -577,9 +577,7 @@ static int dump_all_tablespaces();
static int dump_tablespaces_for_tables(char *db, char **table_names, int tables);
static int dump_tablespaces_for_databases(char** databases);
static int dump_tablespaces(char* ts_where);
static void print_comment(FILE *sql_file, my_bool is_error, const char *format,
...);
static void print_comment(FILE *, my_bool, const char *, ...);
/*
Print the supplied message if in verbose mode
@ -657,6 +655,30 @@ static void short_usage(FILE *f)
}
/** returns a string fixed to be safely printed inside a -- comment
that is, any new line in it gets prefixed with --
*/
static const char *fix_for_comment(const char *ident)
{
static char buf[1024];
char c, *s= buf;
while ((c= *s++= *ident++))
{
if (s >= buf + sizeof(buf) - 10)
{
strmov(s, "...");
break;
}
if (c == '\n')
s= strmov(s, "-- ");
}
return buf;
}
static void write_header(FILE *sql_file, char *db_name)
{
if (opt_xml)
@ -679,8 +701,8 @@ static void write_header(FILE *sql_file, char *db_name)
DUMP_VERSION, MYSQL_SERVER_VERSION, SYSTEM_TYPE,
MACHINE_TYPE);
print_comment(sql_file, 0, "-- Host: %s Database: %s\n",
current_host ? current_host : "localhost",
db_name ? db_name : "");
fix_for_comment(current_host ? current_host : "localhost"),
fix_for_comment(db_name ? db_name : ""));
print_comment(sql_file, 0,
"-- ------------------------------------------------------\n"
);
@ -2250,7 +2272,8 @@ static uint dump_events_for_db(char *db)
/* nice comments */
print_comment(sql_file, 0,
"\n--\n-- Dumping events for database '%s'\n--\n", db);
"\n--\n-- Dumping events for database '%s'\n--\n",
fix_for_comment(db));
/*
not using "mysql_query_with_error_report" because we may have not
@ -2462,7 +2485,8 @@ static uint dump_routines_for_db(char *db)
/* nice comments */
print_comment(sql_file, 0,
"\n--\n-- Dumping routines for database '%s'\n--\n", db);
"\n--\n-- Dumping routines for database '%s'\n--\n",
fix_for_comment(db));
/*
not using "mysql_query_with_error_report" because we may have not
@ -2758,11 +2782,11 @@ static uint get_table_structure(char *table, char *db, char *table_type,
if (strcmp (table_type, "VIEW") == 0) /* view */
print_comment(sql_file, 0,
"\n--\n-- Temporary table structure for view %s\n--\n\n",
result_table);
fix_for_comment(result_table));
else
print_comment(sql_file, 0,
"\n--\n-- Table structure for table %s\n--\n\n",
result_table);
fix_for_comment(result_table));
if (opt_drop)
{
@ -3006,7 +3030,7 @@ static uint get_table_structure(char *table, char *db, char *table_type,
print_comment(sql_file, 0,
"\n--\n-- Table structure for table %s\n--\n\n",
result_table);
fix_for_comment(result_table));
if (opt_drop)
fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n", result_table);
if (!opt_xml)
@ -3715,21 +3739,21 @@ static void dump_table(char *table, char *db)
{
print_comment(md_result_file, 0,
"\n--\n-- Dumping data for table %s\n--\n",
result_table);
fix_for_comment(result_table));
dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ * FROM ");
dynstr_append_checked(&query_string, result_table);
if (where)
{
print_comment(md_result_file, 0, "-- WHERE: %s\n", where);
print_comment(md_result_file, 0, "-- WHERE: %s\n", fix_for_comment(where));
dynstr_append_checked(&query_string, " WHERE ");
dynstr_append_checked(&query_string, where);
}
if (order_by)
{
print_comment(md_result_file, 0, "-- ORDER BY: %s\n", order_by);
print_comment(md_result_file, 0, "-- ORDER BY: %s\n", fix_for_comment(order_by));
dynstr_append_checked(&query_string, " ORDER BY ");
dynstr_append_checked(&query_string, order_by);
@ -4239,7 +4263,7 @@ static int dump_tablespaces(char* ts_where)
if (first)
{
print_comment(md_result_file, 0, "\n--\n-- Logfile group: %s\n--\n",
row[0]);
fix_for_comment(row[0]));
fprintf(md_result_file, "\nCREATE");
}
@ -4308,7 +4332,8 @@ static int dump_tablespaces(char* ts_where)
first= 1;
if (first)
{
print_comment(md_result_file, 0, "\n--\n-- Tablespace: %s\n--\n", row[0]);
print_comment(md_result_file, 0, "\n--\n-- Tablespace: %s\n--\n",
fix_for_comment(row[0]));
fprintf(md_result_file, "\nCREATE");
}
else
@ -4512,7 +4537,8 @@ static int init_dumping(char *database, int init_func(char*))
char *qdatabase= quote_name(database,quoted_database_buf,opt_quoted);
print_comment(md_result_file, 0,
"\n--\n-- Current Database: %s\n--\n", qdatabase);
"\n--\n-- Current Database: %s\n--\n",
fix_for_comment(qdatabase));
/* Call the view or table specific function */
init_func(qdatabase);
@ -5772,7 +5798,7 @@ static my_bool get_view_structure(char *table, char* db)
print_comment(sql_file, 0,
"\n--\n-- Final view structure for view %s\n--\n\n",
result_table);
fix_for_comment(result_table));
/* Table might not exist if this view was dumped with --tab. */
fprintf(sql_file, "/*!50001 DROP TABLE IF EXISTS %s*/;\n", opt_quoted_table);

View file

@ -3371,10 +3371,6 @@ void do_exec(struct st_command *command)
#endif
#endif
/* exec command is interpreted externally and will not take newlines */
while(replace(&ds_cmd, "\n", 1, " ", 1) == 0)
;
DBUG_PRINT("info", ("Executing '%s' as '%s'",
command->first_argument, ds_cmd.str));

View file

@ -30,6 +30,10 @@ IF(NOT VERSION)
SET(64BIT 1)
ENDIF()
IF(NOT 64BIT AND CMAKE_SYSTEM_PROCESSOR MATCHES "^mips64")
SET(DEFAULT_MACHINE "mips")
ENDIF()
IF(CMAKE_SYSTEM_NAME MATCHES "Windows")
SET(NEED_DASH_BETWEEN_PLATFORM_AND_MACHINE 0)
SET(DEFAULT_PLATFORM "win")

View file

@ -679,10 +679,9 @@ int main(int argc, char **argv)
time_t lastt; /* last time */
ulint oldcsum, oldcsumfield, csum, csumfield, crc32, logseq, logseqfield;
/* ulints for checksum storage */
struct stat st; /* for stat, if you couldn't guess */
unsigned long long int size; /* size of file (has to be 64 bits) */
ulint pages; /* number of pages in file */
off_t offset= 0;
long long offset= 0;
int fd;
printf("InnoDB offline file checksum utility.\n");
@ -705,6 +704,47 @@ int main(int argc, char **argv)
goto error_out;
}
#ifdef _WIN32
/* Switch off OS file buffering for the file. */
HANDLE h = CreateFile(filename, GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE, 0,
OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, 0);
if (!h)
{
fprintf(stderr, "Error; cant open file\n");
goto error;
}
if (!GetFileSizeEx(h, (LARGE_INTEGER *)&size))
{
fprintf(stderr, "Error; GetFileSize() failed\n");
goto error;
}
fd = _open_osfhandle ((intptr_t) h, _O_RDONLY);
if (fd < 0)
{
fprintf(stderr, "Error; _open_osfhandle() failed\n");
goto error;
}
f = _fdopen(fd, "rb");
if (!f)
{
fprintf(stderr, "Error; fdopen() failed\n");
goto error;
}
/*
Disable stdio buffering (FILE_FLAG_NO_BUFFERING requires properly IO buffers
which stdio does not guarantee.
*/
setvbuf(f, NULL, _IONBF, 0);
#else
struct stat st;
/* stat the file to get size and page count */
if (stat(filename, &st))
{
@ -715,6 +755,8 @@ int main(int argc, char **argv)
/* Open the file for reading */
f= fopen(filename, "rb");
#endif
if (f == NULL)
{
fprintf(stderr, "Error; %s cannot be opened", filename);
@ -772,7 +814,7 @@ int main(int argc, char **argv)
}
else if (verbose)
{
printf("file %s = %llu bytes (%lu pages)...\n", filename, size, pages);
printf("file %s = %llu bytes (%lu pages)...\n", filename, size, (ulong)pages);
if (do_one_page)
printf("InnoChecksum; checking page %lu\n", do_page);
else
@ -797,9 +839,12 @@ int main(int argc, char **argv)
goto error;
}
offset= (off_t)start_page * (off_t)physical_page_size;
offset= (longlong)start_page * (longlong)physical_page_size;
#ifdef _WIN32
if (_lseeki64(fd, offset, SEEK_SET) != offset)
#else
if (lseek(fd, offset, SEEK_SET) != offset)
#endif
{
perror("Error; Unable to seek to necessary offset");
goto error;

View file

@ -12,6 +12,24 @@ before calling SSL_new();
*** end Note ***
yaSSL Release notes, version 2.4.2 (9/22/2016)
This release of yaSSL fixes a medium security vulnerability. A fix for
potential AES side channel leaks is included that a local user monitoring
the same CPU core cache could exploit. VM users, hyper-threading users,
and users where potential attackers have access to the CPU cache will need
to update if they utilize AES.
DSA padding fixes for unusual sizes is included as well. Users with DSA
certficiates should update.
yaSSL Release notes, version 2.4.0 (5/20/2016)
This release of yaSSL fixes the OpenSSL compatibility function
SSL_CTX_load_verify_locations() when using the path directory to allow
unlimited path sizes. Minor Windows build fixes are included.
No high level security fixes in this version but we always recommend
updating.
yaSSL Release notes, version 2.3.9b (2/03/2016)
This release of yaSSL fixes the OpenSSL compatibility function
X509_NAME_get_index_by_NID() to use the actual index of the common name

View file

@ -1,22 +1,22 @@
-----BEGIN CERTIFICATE-----
MIIDqzCCA2ugAwIBAgIJAMGqrgDU6DyhMAkGByqGSM44BAMwgY4xCzAJBgNVBAYT
MIIDrzCCA2+gAwIBAgIJAK1zRM7YFcNjMAkGByqGSM44BAMwgZAxCzAJBgNVBAYT
AlVTMQ8wDQYDVQQIDAZPcmVnb24xETAPBgNVBAcMCFBvcnRsYW5kMRAwDgYDVQQK
DAd3b2xmU1NMMRAwDgYDVQQLDAd0ZXN0aW5nMRYwFAYDVQQDDA13d3cueWFzc2wu
Y29tMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZzc2wuY29tMB4XDTEzMDQyMjIw
MDk0NFoXDTE2MDExNzIwMDk0NFowgY4xCzAJBgNVBAYTAlVTMQ8wDQYDVQQIDAZP
cmVnb24xETAPBgNVBAcMCFBvcnRsYW5kMRAwDgYDVQQKDAd3b2xmU1NMMRAwDgYD
VQQLDAd0ZXN0aW5nMRYwFAYDVQQDDA13d3cueWFzc2wuY29tMR8wHQYJKoZIhvcN
AQkBFhBpbmZvQHdvbGZzc2wuY29tMIIBuDCCASwGByqGSM44BAEwggEfAoGBAL1R
7koy4IrH6sbh6nDEUUPPKgfhxxLCWCVexF2+qzANEr+hC9M002haJXFOfeS9DyoO
WFbL0qMZOuqv+22CaHnoUWl7q3PjJOAI3JH0P54ZyUPuU1909RzgTdIDp5+ikbr7
KYjnltL73FQVMbjTZQKthIpPn3MjYcF+4jp2W2zFAhUAkcntYND6MGf+eYzIJDN2
L7SonHUCgYEAklpxErfqznIZjVvqqHFaq+mgAL5J8QrKVmdhYZh/Y8z4jCjoCA8o
TDoFKxf7s2ZzgaPKvglaEKiYqLqic9qY78DYJswzQMLFvjsF4sFZ+pYCBdWPQI4N
PgxCiznK6Ce+JH9ikSBvMvG+tevjr2UpawDIHX3+AWYaZBZwKADAaboDgYUAAoGB
AJ3LY89yHyvQ/TsQ6zlYbovjbk/ogndsMqPdNUvL4RuPTgJP/caaDDa0XJ7ak6A7
TJ+QheLNwOXoZPYJC4EGFSDAXpYniGhbWIrVTCGe6lmZDfnx40WXS0kk3m/DHaC0
3ElLAiybxVGxyqoUfbT3Zv1JwftWMuiqHH5uADhdXuXVo1AwTjAdBgNVHQ4EFgQU
IJjk416o4v8qpH9LBtXlR9v8gccwHwYDVR0jBBgwFoAUIJjk416o4v8qpH9LBtXl
R9v8gccwDAYDVR0TBAUwAwEB/zAJBgcqhkjOOAQDAy8AMCwCFCjGKIdOSV12LcTu
k08owGM6YkO1AhQe+K173VuaO/OsDNsxZlKpyH8+1g==
DAd3b2xmU1NMMRAwDgYDVQQLDAd0ZXN0aW5nMRgwFgYDVQQDDA93d3cud29sZnNz
bC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wHhcNMTYwOTIy
MjEyMzA0WhcNMjIwMzE1MjEyMzA0WjCBkDELMAkGA1UEBhMCVVMxDzANBgNVBAgM
Bk9yZWdvbjERMA8GA1UEBwwIUG9ydGxhbmQxEDAOBgNVBAoMB3dvbGZTU0wxEDAO
BgNVBAsMB3Rlc3RpbmcxGDAWBgNVBAMMD3d3dy53b2xmc3NsLmNvbTEfMB0GCSqG
SIb3DQEJARYQaW5mb0B3b2xmc3NsLmNvbTCCAbgwggEsBgcqhkjOOAQBMIIBHwKB
gQC9Ue5KMuCKx+rG4epwxFFDzyoH4ccSwlglXsRdvqswDRK/oQvTNNNoWiVxTn3k
vQ8qDlhWy9KjGTrqr/ttgmh56FFpe6tz4yTgCNyR9D+eGclD7lNfdPUc4E3SA6ef
opG6+ymI55bS+9xUFTG402UCrYSKT59zI2HBfuI6dltsxQIVAJHJ7WDQ+jBn/nmM
yCQzdi+0qJx1AoGBAJJacRK36s5yGY1b6qhxWqvpoAC+SfEKylZnYWGYf2PM+Iwo
6AgPKEw6BSsX+7Nmc4Gjyr4JWhComKi6onPamO/A2CbMM0DCxb47BeLBWfqWAgXV
j0CODT4MQos5yugnviR/YpEgbzLxvrXr469lKWsAyB19/gFmGmQWcCgAwGm6A4GF
AAKBgQCdy2PPch8r0P07EOs5WG6L425P6IJ3bDKj3TVLy+Ebj04CT/3Gmgw2tFye
2pOgO0yfkIXizcDl6GT2CQuBBhUgwF6WJ4hoW1iK1UwhnupZmQ358eNFl0tJJN5v
wx2gtNxJSwIsm8VRscqqFH2092b9ScH7VjLoqhx+bgA4XV7l1aNQME4wHQYDVR0O
BBYEFCCY5ONeqOL/KqR/SwbV5Ufb/IHHMB8GA1UdIwQYMBaAFCCY5ONeqOL/KqR/
SwbV5Ufb/IHHMAwGA1UdEwQFMAMBAf8wCQYHKoZIzjgEAwMvADAsAhQRYSCVN/Ge
agV3mffU3qNZ92fI0QIUPH7Jp+iASI7U1ocaYDc10qXGaGY=
-----END CERTIFICATE-----

View file

@ -34,7 +34,7 @@
#include "rsa.h"
#define YASSL_VERSION "2.3.9b"
#define YASSL_VERSION "2.4.2"
#if defined(__cplusplus)

View file

@ -162,7 +162,7 @@ int read_file(SSL_CTX* ctx, const char* file, int format, CertType type)
TaoCrypt::DSA_PrivateKey dsaKey;
dsaKey.Initialize(dsaSource);
if (rsaSource.GetError().What()) {
if (dsaSource.GetError().What()) {
// neither worked
ret = SSL_FAILURE;
}
@ -785,40 +785,67 @@ int SSL_CTX_load_verify_locations(SSL_CTX* ctx, const char* file,
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
char name[MAX_PATH + 1]; // directory specification
strncpy(name, path, MAX_PATH - 3);
strncat(name, "\\*", 3);
const int DELIMITER_SZ = 2;
const int DELIMITER_STAR_SZ = 3;
int pathSz = (int)strlen(path);
int nameSz = pathSz + DELIMITER_STAR_SZ + 1; // plus 1 for terminator
char* name = NEW_YS char[nameSz]; // directory specification
memset(name, 0, nameSz);
strncpy(name, path, nameSz - DELIMITER_STAR_SZ - 1);
strncat(name, "\\*", DELIMITER_STAR_SZ);
hFind = FindFirstFile(name, &FindFileData);
if (hFind == INVALID_HANDLE_VALUE) return SSL_BAD_PATH;
if (hFind == INVALID_HANDLE_VALUE) {
ysArrayDelete(name);
return SSL_BAD_PATH;
}
do {
if (FindFileData.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY) {
strncpy(name, path, MAX_PATH - 2 - HALF_PATH);
strncat(name, "\\", 2);
strncat(name, FindFileData.cFileName, HALF_PATH);
if (!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
int curSz = (int)strlen(FindFileData.cFileName);
if (pathSz + curSz + DELIMITER_SZ + 1 > nameSz) {
ysArrayDelete(name);
// plus 1 for terminator
nameSz = pathSz + curSz + DELIMITER_SZ + 1;
name = NEW_YS char[nameSz];
}
memset(name, 0, nameSz);
strncpy(name, path, nameSz - curSz - DELIMITER_SZ - 1);
strncat(name, "\\", DELIMITER_SZ);
strncat(name, FindFileData.cFileName,
nameSz - pathSz - DELIMITER_SZ - 1);
ret = read_file(ctx, name, SSL_FILETYPE_PEM, CA);
}
} while (ret == SSL_SUCCESS && FindNextFile(hFind, &FindFileData));
ysArrayDelete(name);
FindClose(hFind);
#else // _WIN32
const int MAX_PATH = 260;
DIR* dir = opendir(path);
if (!dir) return SSL_BAD_PATH;
struct dirent* entry;
struct stat buf;
char name[MAX_PATH + 1];
const int DELIMITER_SZ = 1;
int pathSz = (int)strlen(path);
int nameSz = pathSz + DELIMITER_SZ + 1; //plus 1 for null terminator
char* name = NEW_YS char[nameSz]; // directory specification
while (ret == SSL_SUCCESS && (entry = readdir(dir))) {
strncpy(name, path, MAX_PATH - 1 - HALF_PATH);
strncat(name, "/", 1);
strncat(name, entry->d_name, HALF_PATH);
int curSz = (int)strlen(entry->d_name);
if (pathSz + curSz + DELIMITER_SZ + 1 > nameSz) {
ysArrayDelete(name);
nameSz = pathSz + DELIMITER_SZ + curSz + 1;
name = NEW_YS char[nameSz];
}
memset(name, 0, nameSz);
strncpy(name, path, nameSz - curSz - 1);
strncat(name, "/", DELIMITER_SZ);
strncat(name, entry->d_name, nameSz - pathSz - DELIMITER_SZ - 1);
if (stat(name, &buf) < 0) {
ysArrayDelete(name);
closedir(dir);
return SSL_BAD_STAT;
}
@ -827,6 +854,7 @@ int SSL_CTX_load_verify_locations(SSL_CTX* ctx, const char* file,
ret = read_file(ctx, name, SSL_FILETYPE_PEM, CA);
}
ysArrayDelete(name);
closedir(dir);
#endif

View file

@ -60,6 +60,7 @@ private:
static const word32 Te[5][256];
static const word32 Td[5][256];
static const byte CTd4[256];
static const word32* Te0;
static const word32* Te1;
@ -80,11 +81,68 @@ private:
void ProcessAndXorBlock(const byte*, const byte*, byte*) const;
word32 PreFetchTe() const;
word32 PreFetchTd() const;
word32 PreFetchCTd4() const;
AES(const AES&); // hide copy
AES& operator=(const AES&); // and assign
};
#if defined(__x86_64__) || defined(_M_X64) || \
(defined(__ILP32__) && (__ILP32__ >= 1))
#define TC_CACHE_LINE_SZ 64
#else
/* default cache line size */
#define TC_CACHE_LINE_SZ 32
#endif
inline word32 AES::PreFetchTe() const
{
word32 x = 0;
/* 4 tables of 256 entries */
for (int i = 0; i < 4; i++) {
/* each entry is 4 bytes */
for (int j = 0; j < 256; j += TC_CACHE_LINE_SZ/4) {
x &= Te[i][j];
}
}
return x;
}
inline word32 AES::PreFetchTd() const
{
word32 x = 0;
/* 4 tables of 256 entries */
for (int i = 0; i < 4; i++) {
/* each entry is 4 bytes */
for (int j = 0; j < 256; j += TC_CACHE_LINE_SZ/4) {
x &= Td[i][j];
}
}
return x;
}
inline word32 AES::PreFetchCTd4() const
{
word32 x = 0;
int i;
for (i = 0; i < 256; i += TC_CACHE_LINE_SZ) {
x &= CTd4[i];
}
return x;
}
typedef BlockCipher<ENCRYPTION, AES, ECB> AES_ECB_Encryption;
typedef BlockCipher<DECRYPTION, AES, ECB> AES_ECB_Decryption;

View file

@ -119,6 +119,9 @@ namespace TaoCrypt {
#ifdef _WIN32
#undef max // avoid name clash
#endif
// general MAX
template<typename T> inline
const T& max(const T& a, const T& b)

View file

@ -109,10 +109,10 @@ void AES::SetKey(const byte* userKey, word32 keylen, CipherDir /*dummy*/)
{
temp = rk[3];
rk[4] = rk[0] ^
(Te4[GETBYTE(temp, 2)] & 0xff000000) ^
(Te4[GETBYTE(temp, 1)] & 0x00ff0000) ^
(Te4[GETBYTE(temp, 0)] & 0x0000ff00) ^
(Te4[GETBYTE(temp, 3)] & 0x000000ff) ^
(Te2[GETBYTE(temp, 2)] & 0xff000000) ^
(Te3[GETBYTE(temp, 1)] & 0x00ff0000) ^
(Te0[GETBYTE(temp, 0)] & 0x0000ff00) ^
(Te1[GETBYTE(temp, 3)] & 0x000000ff) ^
rcon_[i];
rk[5] = rk[1] ^ rk[4];
rk[6] = rk[2] ^ rk[5];
@ -128,10 +128,10 @@ void AES::SetKey(const byte* userKey, word32 keylen, CipherDir /*dummy*/)
{
temp = rk[ 5];
rk[ 6] = rk[ 0] ^
(Te4[GETBYTE(temp, 2)] & 0xff000000) ^
(Te4[GETBYTE(temp, 1)] & 0x00ff0000) ^
(Te4[GETBYTE(temp, 0)] & 0x0000ff00) ^
(Te4[GETBYTE(temp, 3)] & 0x000000ff) ^
(Te2[GETBYTE(temp, 2)] & 0xff000000) ^
(Te3[GETBYTE(temp, 1)] & 0x00ff0000) ^
(Te0[GETBYTE(temp, 0)] & 0x0000ff00) ^
(Te1[GETBYTE(temp, 3)] & 0x000000ff) ^
rcon_[i];
rk[ 7] = rk[ 1] ^ rk[ 6];
rk[ 8] = rk[ 2] ^ rk[ 7];
@ -149,10 +149,10 @@ void AES::SetKey(const byte* userKey, word32 keylen, CipherDir /*dummy*/)
{
temp = rk[ 7];
rk[ 8] = rk[ 0] ^
(Te4[GETBYTE(temp, 2)] & 0xff000000) ^
(Te4[GETBYTE(temp, 1)] & 0x00ff0000) ^
(Te4[GETBYTE(temp, 0)] & 0x0000ff00) ^
(Te4[GETBYTE(temp, 3)] & 0x000000ff) ^
(Te2[GETBYTE(temp, 2)] & 0xff000000) ^
(Te3[GETBYTE(temp, 1)] & 0x00ff0000) ^
(Te0[GETBYTE(temp, 0)] & 0x0000ff00) ^
(Te1[GETBYTE(temp, 3)] & 0x000000ff) ^
rcon_[i];
rk[ 9] = rk[ 1] ^ rk[ 8];
rk[10] = rk[ 2] ^ rk[ 9];
@ -161,10 +161,10 @@ void AES::SetKey(const byte* userKey, word32 keylen, CipherDir /*dummy*/)
break;
temp = rk[11];
rk[12] = rk[ 4] ^
(Te4[GETBYTE(temp, 3)] & 0xff000000) ^
(Te4[GETBYTE(temp, 2)] & 0x00ff0000) ^
(Te4[GETBYTE(temp, 1)] & 0x0000ff00) ^
(Te4[GETBYTE(temp, 0)] & 0x000000ff);
(Te2[GETBYTE(temp, 3)] & 0xff000000) ^
(Te3[GETBYTE(temp, 2)] & 0x00ff0000) ^
(Te0[GETBYTE(temp, 1)] & 0x0000ff00) ^
(Te1[GETBYTE(temp, 0)] & 0x000000ff);
rk[13] = rk[ 5] ^ rk[12];
rk[14] = rk[ 6] ^ rk[13];
rk[15] = rk[ 7] ^ rk[14];
@ -191,25 +191,25 @@ void AES::SetKey(const byte* userKey, word32 keylen, CipherDir /*dummy*/)
for (i = 1; i < rounds_; i++) {
rk += 4;
rk[0] =
Td0[Te4[GETBYTE(rk[0], 3)] & 0xff] ^
Td1[Te4[GETBYTE(rk[0], 2)] & 0xff] ^
Td2[Te4[GETBYTE(rk[0], 1)] & 0xff] ^
Td3[Te4[GETBYTE(rk[0], 0)] & 0xff];
Td0[Te1[GETBYTE(rk[0], 3)] & 0xff] ^
Td1[Te1[GETBYTE(rk[0], 2)] & 0xff] ^
Td2[Te1[GETBYTE(rk[0], 1)] & 0xff] ^
Td3[Te1[GETBYTE(rk[0], 0)] & 0xff];
rk[1] =
Td0[Te4[GETBYTE(rk[1], 3)] & 0xff] ^
Td1[Te4[GETBYTE(rk[1], 2)] & 0xff] ^
Td2[Te4[GETBYTE(rk[1], 1)] & 0xff] ^
Td3[Te4[GETBYTE(rk[1], 0)] & 0xff];
Td0[Te1[GETBYTE(rk[1], 3)] & 0xff] ^
Td1[Te1[GETBYTE(rk[1], 2)] & 0xff] ^
Td2[Te1[GETBYTE(rk[1], 1)] & 0xff] ^
Td3[Te1[GETBYTE(rk[1], 0)] & 0xff];
rk[2] =
Td0[Te4[GETBYTE(rk[2], 3)] & 0xff] ^
Td1[Te4[GETBYTE(rk[2], 2)] & 0xff] ^
Td2[Te4[GETBYTE(rk[2], 1)] & 0xff] ^
Td3[Te4[GETBYTE(rk[2], 0)] & 0xff];
Td0[Te1[GETBYTE(rk[2], 3)] & 0xff] ^
Td1[Te1[GETBYTE(rk[2], 2)] & 0xff] ^
Td2[Te1[GETBYTE(rk[2], 1)] & 0xff] ^
Td3[Te1[GETBYTE(rk[2], 0)] & 0xff];
rk[3] =
Td0[Te4[GETBYTE(rk[3], 3)] & 0xff] ^
Td1[Te4[GETBYTE(rk[3], 2)] & 0xff] ^
Td2[Te4[GETBYTE(rk[3], 1)] & 0xff] ^
Td3[Te4[GETBYTE(rk[3], 0)] & 0xff];
Td0[Te1[GETBYTE(rk[3], 3)] & 0xff] ^
Td1[Te1[GETBYTE(rk[3], 2)] & 0xff] ^
Td2[Te1[GETBYTE(rk[3], 1)] & 0xff] ^
Td3[Te1[GETBYTE(rk[3], 0)] & 0xff];
}
}
}
@ -244,6 +244,7 @@ void AES::encrypt(const byte* inBlock, const byte* xorBlock,
s2 ^= rk[2];
s3 ^= rk[3];
s0 |= PreFetchTe();
/*
* Nr - 1 full rounds:
*/
@ -312,28 +313,28 @@ void AES::encrypt(const byte* inBlock, const byte* xorBlock,
*/
s0 =
(Te4[GETBYTE(t0, 3)] & 0xff000000) ^
(Te4[GETBYTE(t1, 2)] & 0x00ff0000) ^
(Te4[GETBYTE(t2, 1)] & 0x0000ff00) ^
(Te4[GETBYTE(t3, 0)] & 0x000000ff) ^
(Te2[GETBYTE(t0, 3)] & 0xff000000) ^
(Te3[GETBYTE(t1, 2)] & 0x00ff0000) ^
(Te0[GETBYTE(t2, 1)] & 0x0000ff00) ^
(Te1[GETBYTE(t3, 0)] & 0x000000ff) ^
rk[0];
s1 =
(Te4[GETBYTE(t1, 3)] & 0xff000000) ^
(Te4[GETBYTE(t2, 2)] & 0x00ff0000) ^
(Te4[GETBYTE(t3, 1)] & 0x0000ff00) ^
(Te4[GETBYTE(t0, 0)] & 0x000000ff) ^
(Te2[GETBYTE(t1, 3)] & 0xff000000) ^
(Te3[GETBYTE(t2, 2)] & 0x00ff0000) ^
(Te0[GETBYTE(t3, 1)] & 0x0000ff00) ^
(Te1[GETBYTE(t0, 0)] & 0x000000ff) ^
rk[1];
s2 =
(Te4[GETBYTE(t2, 3)] & 0xff000000) ^
(Te4[GETBYTE(t3, 2)] & 0x00ff0000) ^
(Te4[GETBYTE(t0, 1)] & 0x0000ff00) ^
(Te4[GETBYTE(t1, 0)] & 0x000000ff) ^
(Te2[GETBYTE(t2, 3)] & 0xff000000) ^
(Te3[GETBYTE(t3, 2)] & 0x00ff0000) ^
(Te0[GETBYTE(t0, 1)] & 0x0000ff00) ^
(Te1[GETBYTE(t1, 0)] & 0x000000ff) ^
rk[2];
s3 =
(Te4[GETBYTE(t3, 3)] & 0xff000000) ^
(Te4[GETBYTE(t0, 2)] & 0x00ff0000) ^
(Te4[GETBYTE(t1, 1)] & 0x0000ff00) ^
(Te4[GETBYTE(t2, 0)] & 0x000000ff) ^
(Te2[GETBYTE(t3, 3)] & 0xff000000) ^
(Te3[GETBYTE(t0, 2)] & 0x00ff0000) ^
(Te0[GETBYTE(t1, 1)] & 0x0000ff00) ^
(Te1[GETBYTE(t2, 0)] & 0x000000ff) ^
rk[3];
@ -358,6 +359,8 @@ void AES::decrypt(const byte* inBlock, const byte* xorBlock,
s2 ^= rk[2];
s3 ^= rk[3];
s0 |= PreFetchTd();
/*
* Nr - 1 full rounds:
*/
@ -423,29 +426,32 @@ void AES::decrypt(const byte* inBlock, const byte* xorBlock,
* apply last round and
* map cipher state to byte array block:
*/
t0 |= PreFetchCTd4();
s0 =
(Td4[GETBYTE(t0, 3)] & 0xff000000) ^
(Td4[GETBYTE(t3, 2)] & 0x00ff0000) ^
(Td4[GETBYTE(t2, 1)] & 0x0000ff00) ^
(Td4[GETBYTE(t1, 0)] & 0x000000ff) ^
((word32)CTd4[GETBYTE(t0, 3)] << 24) ^
((word32)CTd4[GETBYTE(t3, 2)] << 16) ^
((word32)CTd4[GETBYTE(t2, 1)] << 8) ^
((word32)CTd4[GETBYTE(t1, 0)]) ^
rk[0];
s1 =
(Td4[GETBYTE(t1, 3)] & 0xff000000) ^
(Td4[GETBYTE(t0, 2)] & 0x00ff0000) ^
(Td4[GETBYTE(t3, 1)] & 0x0000ff00) ^
(Td4[GETBYTE(t2, 0)] & 0x000000ff) ^
((word32)CTd4[GETBYTE(t1, 3)] << 24) ^
((word32)CTd4[GETBYTE(t0, 2)] << 16) ^
((word32)CTd4[GETBYTE(t3, 1)] << 8) ^
((word32)CTd4[GETBYTE(t2, 0)]) ^
rk[1];
s2 =
(Td4[GETBYTE(t2, 3)] & 0xff000000) ^
(Td4[GETBYTE(t1, 2)] & 0x00ff0000) ^
(Td4[GETBYTE(t0, 1)] & 0x0000ff00) ^
(Td4[GETBYTE(t3, 0)] & 0x000000ff) ^
((word32)CTd4[GETBYTE(t2, 3)] << 24 ) ^
((word32)CTd4[GETBYTE(t1, 2)] << 16 ) ^
((word32)CTd4[GETBYTE(t0, 1)] << 8 ) ^
((word32)CTd4[GETBYTE(t3, 0)]) ^
rk[2];
s3 =
(Td4[GETBYTE(t3, 3)] & 0xff000000) ^
(Td4[GETBYTE(t2, 2)] & 0x00ff0000) ^
(Td4[GETBYTE(t1, 1)] & 0x0000ff00) ^
(Td4[GETBYTE(t0, 0)] & 0x000000ff) ^
((word32)CTd4[GETBYTE(t3, 3)] << 24) ^
((word32)CTd4[GETBYTE(t2, 2)] << 16) ^
((word32)CTd4[GETBYTE(t1, 1)] << 8) ^
((word32)CTd4[GETBYTE(t0, 0)]) ^
rk[3];
gpBlock::Put(xorBlock, outBlock)(s0)(s1)(s2)(s3);
@ -1826,18 +1832,52 @@ const word32 AES::Td[5][256] = {
}
};
const byte AES::CTd4[256] =
{
0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
};
const word32* AES::Te0 = AES::Te[0];
const word32* AES::Te1 = AES::Te[1];
const word32* AES::Te2 = AES::Te[2];
const word32* AES::Te3 = AES::Te[3];
const word32* AES::Te4 = AES::Te[4];
const word32* AES::Td0 = AES::Td[0];
const word32* AES::Td1 = AES::Td[1];
const word32* AES::Td2 = AES::Td[2];
const word32* AES::Td3 = AES::Td[3];
const word32* AES::Td4 = AES::Td[4];

View file

@ -1219,17 +1219,17 @@ word32 DecodeDSA_Signature(byte* decoded, const byte* encoded, word32 sz)
}
word32 rLen = GetLength(source);
if (rLen != 20) {
if (rLen == 21) { // zero at front, eat
while (rLen > 20 && source.remaining() > 0) { // zero's at front, eat
source.next();
--rLen;
}
else if (rLen == 19) { // add zero to front so 20 bytes
if (rLen < 20) { // add zero's to front so 20 bytes
word32 tmpLen = rLen;
while (tmpLen < 20) {
decoded[0] = 0;
decoded++;
tmpLen++;
}
else {
source.SetError(DSA_SZ_E);
return 0;
}
}
memcpy(decoded, source.get_buffer() + source.get_index(), rLen);
@ -1242,17 +1242,17 @@ word32 DecodeDSA_Signature(byte* decoded, const byte* encoded, word32 sz)
}
word32 sLen = GetLength(source);
if (sLen != 20) {
if (sLen == 21) {
source.next(); // zero at front, eat
while (sLen > 20 && source.remaining() > 0) {
source.next(); // zero's at front, eat
--sLen;
}
else if (sLen == 19) {
decoded[rLen] = 0; // add zero to front so 20 bytes
if (sLen < 20) { // add zero's to front so 20 bytes
word32 tmpLen = sLen;
while (tmpLen < 20) {
decoded[rLen] = 0;
decoded++;
tmpLen++;
}
else {
source.SetError(DSA_SZ_E);
return 0;
}
}
memcpy(decoded + rLen, source.get_buffer() + source.get_index(), sLen);

View file

@ -172,6 +172,7 @@ word32 DSA_Signer::Sign(const byte* sha_digest, byte* sig,
const Integer& q = key_.GetSubGroupOrder();
const Integer& g = key_.GetSubGroupGenerator();
const Integer& x = key_.GetPrivatePart();
byte* tmpPtr = sig; // initial signature output
Integer k(rng, 1, q - 1);
@ -187,22 +188,23 @@ word32 DSA_Signer::Sign(const byte* sha_digest, byte* sig,
return (word32) -1;
int rSz = r_.ByteCount();
int tmpSz = rSz;
if (rSz == 19) {
sig[0] = 0;
sig++;
while (tmpSz++ < SHA::DIGEST_SIZE) {
*sig++ = 0;
}
r_.Encode(sig, rSz);
sig = tmpPtr + SHA::DIGEST_SIZE; // advance sig output to s
int sSz = s_.ByteCount();
tmpSz = sSz;
if (sSz == 19) {
sig[rSz] = 0;
sig++;
while (tmpSz++ < SHA::DIGEST_SIZE) {
*sig++ = 0;
}
s_.Encode(sig + rSz, sSz);
s_.Encode(sig, sSz);
return 40;
}

View file

@ -193,8 +193,9 @@ DWord() {}
"a" (a), "rm" (b) : "cc");
#elif defined(__mips64)
__asm__("dmultu %2,%3" : "=d" (r.halfs_.high), "=l" (r.halfs_.low)
: "r" (a), "r" (b));
unsigned __int128 t = (unsigned __int128) a * b;
r.halfs_.high = t >> 64;
r.halfs_.low = (word) t;
#elif defined(_M_IX86)
// for testing

View file

@ -1281,6 +1281,9 @@ int dsa_test()
if (!verifier.Verify(digest, decoded))
return -90;
if (!verifier.Verify(digest, signature))
return -91;
return 0;
}

View file

@ -22,7 +22,6 @@
#define yaSSL_TEST_HPP
#include "runtime.hpp"
#include "openssl/ssl.h" /* openssl compatibility test */
#include "error.hpp"
#include <stdio.h>
#include <stdlib.h>
@ -56,6 +55,7 @@
#endif
#define SOCKET_T int
#endif /* _WIN32 */
#include "openssl/ssl.h" /* openssl compatibility test */
#ifdef _MSC_VER

View file

@ -27,19 +27,9 @@
((uint32) (uchar) (A)[0])))
#define sint4korr(A) (*((const long *) (A)))
#define uint2korr(A) (*((const uint16 *) (A)))
/*
Attention: Please, note, uint3korr reads 4 bytes (not 3)!
It means, that you have to provide enough allocated space.
*/
#if defined(HAVE_valgrind) && !defined(_WIN32)
#define uint3korr(A) (uint32) (((uint32) ((uchar) (A)[0])) +\
(((uint32) ((uchar) (A)[1])) << 8) +\
(((uint32) ((uchar) (A)[2])) << 16))
#else
#define uint3korr(A) (long) (*((const unsigned int *) (A)) & 0xFFFFFF)
#endif
#define uint4korr(A) (*((const uint32 *) (A)))
#define uint5korr(A) ((ulonglong)(((uint32) ((uchar) (A)[0])) +\
(((uint32) ((uchar) (A)[1])) << 8) +\

View file

@ -27,17 +27,9 @@
((uint32) (uchar) (A)[0])))
#define sint4korr(A) (int32) (*((int32 *) (A)))
#define uint2korr(A) (uint16) (*((uint16 *) (A)))
/*
Attention: Please, note, uint3korr reads 4 bytes (not 3)!
It means, that you have to provide enough allocated space.
*/
#if defined(HAVE_valgrind) && !defined(_WIN32)
#define uint3korr(A) (uint32) (((uint32) ((uchar) (A)[0])) +\
(((uint32) ((uchar) (A)[1])) << 8) +\
(((uint32) ((uchar) (A)[2])) << 16))
#else
#define uint3korr(A) (uint32) (*((unsigned int *) (A)) & 0xFFFFFF)
#endif
#define uint4korr(A) (uint32) (*((uint32 *) (A)))
#define uint5korr(A) ((ulonglong)(((uint32) ((uchar) (A)[0])) +\
(((uint32) ((uchar) (A)[1])) << 8) +\

View file

@ -452,8 +452,9 @@ void read_user_name(char *name)
void read_user_name(char *name)
{
char *str=getenv("USER"); /* ODBC will send user variable */
strmake(name,str ? str : "ODBC", USERNAME_LENGTH);
DWORD len= USERNAME_LENGTH;
if (!GetUserName(name, &len))
strmov(name,"UNKNOWN_USER");
}
#endif

View file

@ -52,7 +52,7 @@ eval SELECT 'hello' INTO OUTFILE 'fake_file.$prefix';
# Use '/' instead of '\' in the error message. On windows platform, dir is
# formed with '\'.
--replace_regex /\\testing_1\\*/\/testing_1\// /66/39/ /17/39/ /247/39/ /File exists/Directory not empty/
--replace_regex /\\testing_1\\*/\/testing_1\// /66/39/ /93/39/ /17/39/ /247/39/ /File exists/Directory not empty/
--error 1010
DROP DATABASE testing_1;
let $wait_binlog_event= DROP TABLE IF EXIST;

View file

@ -2031,6 +2031,64 @@ Warnings:
Note 1061 Multiple primary key defined
DROP TABLE t1;
#
# MDEV-11126 Crash while altering persistent virtual column
#
CREATE TABLE `tab1` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`field2` set('option1','option2','option3','option4') NOT NULL,
`field3` set('option1','option2','option3','option4','option5') NOT NULL,
`field4` set('option1','option2','option3','option4') NOT NULL,
`field5` varchar(32) NOT NULL,
`field6` varchar(32) NOT NULL,
`field7` varchar(32) NOT NULL,
`field8` varchar(32) NOT NULL,
`field9` int(11) NOT NULL DEFAULT '1',
`field10` varchar(16) NOT NULL,
`field11` enum('option1','option2','option3') NOT NULL DEFAULT 'option1',
`v_col` varchar(128) AS (IF(field11='option1',CONCAT_WS(":","field1",field2,field3,field4,field5,field6,field7,field8,field9,field10), CONCAT_WS(":","field1",field11,field2,field3,field4,field5,field6,field7,field8,field9,field10))) PERSISTENT,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=latin1;
ALTER TABLE `tab1` CHANGE COLUMN v_col `v_col` varchar(128);
SHOW CREATE TABLE `tab1`;
Table Create Table
tab1 CREATE TABLE `tab1` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`field2` set('option1','option2','option3','option4') NOT NULL,
`field3` set('option1','option2','option3','option4','option5') NOT NULL,
`field4` set('option1','option2','option3','option4') NOT NULL,
`field5` varchar(32) NOT NULL,
`field6` varchar(32) NOT NULL,
`field7` varchar(32) NOT NULL,
`field8` varchar(32) NOT NULL,
`field9` int(11) NOT NULL DEFAULT '1',
`field10` varchar(16) NOT NULL,
`field11` enum('option1','option2','option3') NOT NULL DEFAULT 'option1',
`v_col` varchar(128) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
ALTER TABLE `tab1` CHANGE COLUMN v_col `v_col` varchar(128) AS (IF(field11='option1',CONCAT_WS(":","field1",field2,field3,field4,field5,field6,field7,field8,field9,field10), CONCAT_WS(":","field1",field11,field2,field3,field4,field5,field6,field7,field8,field9,field10))) PERSISTENT;
SHOW CREATE TABLE `tab1`;
Table Create Table
tab1 CREATE TABLE `tab1` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`field2` set('option1','option2','option3','option4') NOT NULL,
`field3` set('option1','option2','option3','option4','option5') NOT NULL,
`field4` set('option1','option2','option3','option4') NOT NULL,
`field5` varchar(32) NOT NULL,
`field6` varchar(32) NOT NULL,
`field7` varchar(32) NOT NULL,
`field8` varchar(32) NOT NULL,
`field9` int(11) NOT NULL DEFAULT '1',
`field10` varchar(16) NOT NULL,
`field11` enum('option1','option2','option3') NOT NULL DEFAULT 'option1',
`v_col` varchar(128) AS (IF(field11='option1',CONCAT_WS(":","field1",field2,field3,field4,field5,field6,field7,field8,field9,field10), CONCAT_WS(":","field1",field11,field2,field3,field4,field5,field6,field7,field8,field9,field10))) PERSISTENT,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE `tab1`;
#
# Start of 10.1 tests
#
#
# MDEV-7374 : Losing connection to MySQL while running ALTER TABLE
#
CREATE TABLE t1(i INT) ENGINE=INNODB;
@ -2039,9 +2097,6 @@ INSERT INTO t1 SELECT a.* FROM t1 a, t1 b, t1 c, t1 d, t1 e;
ALTER TABLE t1 MODIFY i FLOAT;
DROP TABLE t1;
#
# Start of 10.1 tests
#
#
# MDEV-7816 ALTER with DROP INDEX and ADD INDEX .. COMMENT='comment2' ignores the new comment
#
CREATE TABLE t1(a INT);

View file

@ -440,3 +440,14 @@ KILL QUERY con_id;
ERROR 70100: Query execution was interrupted
drop table t1;
DROP TABLE t2;
#
# MDEV-10824 - Crash in CREATE OR REPLACE TABLE t1 AS SELECT spfunc()
#
CREATE TABLE t1(a INT);
CREATE FUNCTION f1() RETURNS VARCHAR(16383) RETURN 'test';
CREATE OR REPLACE TABLE t1 AS SELECT f1();
LOCK TABLE t1 WRITE;
CREATE OR REPLACE TABLE t1 AS SELECT f1();
UNLOCK TABLES;
DROP FUNCTION f1;
DROP TABLE t1;

View file

@ -209,3 +209,9 @@ INSERT INTO table1 VALUES (1);
ERROR 42S02: Unknown table 't.notable'
DROP TABLE table1,table2;
# End BUG#34750
#
# MDEV-11105 Table named 'db' has weird side effect.
#
CREATE DATABASE mysqltest;
CREATE TABLE mysqltest.db(id INT);
DROP DATABASE mysqltest;

View file

@ -1012,19 +1012,19 @@ show grants;
Grants for user3@localhost
GRANT USAGE ON *.* TO 'user3'@'localhost'
GRANT SELECT ON `mysqltest`.* TO 'user3'@'localhost'
select * from information_schema.column_privileges where grantee like '%user%'
select * from information_schema.column_privileges where grantee like '\'user%'
order by grantee;
GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME PRIVILEGE_TYPE IS_GRANTABLE
'user1'@'localhost' def mysqltest t1 f1 SELECT NO
select * from information_schema.table_privileges where grantee like '%user%'
select * from information_schema.table_privileges where grantee like '\'user%'
order by grantee;
GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PRIVILEGE_TYPE IS_GRANTABLE
'user2'@'localhost' def mysqltest t2 SELECT NO
select * from information_schema.schema_privileges where grantee like '%user%'
select * from information_schema.schema_privileges where grantee like '\'user%'
order by grantee;
GRANTEE TABLE_CATALOG TABLE_SCHEMA PRIVILEGE_TYPE IS_GRANTABLE
'user3'@'localhost' def mysqltest SELECT NO
select * from information_schema.user_privileges where grantee like '%user%'
select * from information_schema.user_privileges where grantee like '\'user%'
order by grantee;
GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_GRANTABLE
'user1'@'localhost' def USAGE NO

View file

@ -514,6 +514,14 @@ DROP DATABASE connected_db;
create database `aa``bb````cc`;
DATABASE()
aa`bb``cc
DATABASE()
test
DATABASE()
aa`bb``cc
DATABASE()
test
DATABASE()
aa`bb``cc
drop database `aa``bb````cc`;
a
>>\ndelimiter\n<<

View file

@ -3,3 +3,9 @@ a
1
End of tests
1
1
2
2
X
3

View file

@ -0,0 +1,126 @@
create database `mysqltest1
1tsetlqsym`;
use `mysqltest1
1tsetlqsym`;
create table `t1
1t` (`foobar
raboof` int);
create view `v1
1v` as select * from `t1
1t`;
create procedure sp() select * from `v1
1v`;
flush tables;
use test;
--
-- Current Database: `mysqltest1
-- 1tsetlqsym`
--
/*!40000 DROP DATABASE IF EXISTS `mysqltest1
1tsetlqsym`*/;
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest1
1tsetlqsym` /*!40100 DEFAULT CHARACTER SET latin1 */;
USE `mysqltest1
1tsetlqsym`;
--
-- Table structure for table `t1
-- 1t`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `t1
1t` (
`foobar
raboof` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `t1
-- 1t`
--
--
-- Temporary table structure for view `v1
-- 1v`
--
SET @saved_cs_client = @@character_set_client;
SET character_set_client = utf8;
/*!50001 CREATE TABLE `v1
1v` (
`foobar
raboof` tinyint NOT NULL
) ENGINE=MyISAM */;
SET character_set_client = @saved_cs_client;
--
-- Dumping routines for database 'mysqltest1
-- 1tsetlqsym'
--
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
/*!50003 SET character_set_client = latin1 */ ;
/*!50003 SET character_set_results = latin1 */ ;
/*!50003 SET collation_connection = latin1_swedish_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = 'NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp`()
select * from `v1
1v` ;;
DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
--
-- Current Database: `mysqltest1
-- 1tsetlqsym`
--
USE `mysqltest1
1tsetlqsym`;
--
-- Final view structure for view `v1
-- 1v`
--
/*!50001 DROP TABLE IF EXISTS `v1
1v`*/;
/*!50001 SET @saved_cs_client = @@character_set_client */;
/*!50001 SET @saved_cs_results = @@character_set_results */;
/*!50001 SET @saved_col_connection = @@collation_connection */;
/*!50001 SET character_set_client = latin1 */;
/*!50001 SET character_set_results = latin1 */;
/*!50001 SET collation_connection = latin1_swedish_ci */;
/*!50001 CREATE ALGORITHM=UNDEFINED */
/*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */
/*!50001 VIEW `v1
1v` AS select `t1
1t`.`foobar
raboof` AS `foobar
raboof` from `t1
1t` */;
/*!50001 SET character_set_client = @saved_cs_client */;
/*!50001 SET character_set_results = @saved_cs_results */;
/*!50001 SET collation_connection = @saved_col_connection */;
show tables from `mysqltest1
1tsetlqsym`;
Tables_in_mysqltest1
1tsetlqsym
t1
1t
v1
1v
drop database `mysqltest1
1tsetlqsym`;

View file

@ -5236,9 +5236,6 @@ SET @@global.log_output="TABLE";
SET @@global.general_log='OFF';
SET @@global.slow_query_log='OFF';
DROP DATABASE mysql;
Warnings:
Error 1146 Table 'mysql.proc' doesn't exist
Error 1146 Table 'mysql.event' doesn't exist
SHOW CREATE TABLE mysql.general_log;
Table Create Table
general_log CREATE TABLE `general_log` (

View file

@ -269,12 +269,6 @@ source database
echo message echo message
mysqltest: At line 1: Missing argument in exec
1
1
2
2
X
3
MySQL
"MySQL"
MySQL: The

View file

@ -1440,3 +1440,75 @@ a b i
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
DROP TABLE t1,t2;
set use_stat_tables=@save_use_stat_tables;
#
# Bug mdev-11096: range condition over column without statistical data
#
set use_stat_tables='preferably';
set optimizer_use_condition_selectivity=3;
create table t1(col1 char(32));
insert into t1 values ('a'),('b'),('c'),('d'), ('e'),('f'),('g'),('h');
analyze table t1 persistent for columns () indexes ();
Table Op Msg_type Msg_text
test.t1 analyze status Engine-independent statistics collected
test.t1 analyze status OK
explain extended
select * from t1 where col1 > 'b' and col1 < 'e';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 8 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`col1` AS `col1` from `test`.`t1` where ((`test`.`t1`.`col1` > 'b') and (`test`.`t1`.`col1` < 'e'))
select * from t1 where col1 > 'b' and col1 < 'e';
col1
c
d
drop table t1;
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
set use_stat_tables=@save_use_stat_tables;
#
# Bug mdev-9628: unindexed blob column without min-max statistics
# with optimizer_use_condition_selectivity=3
#
set use_stat_tables='preferably';
set optimizer_use_condition_selectivity=3;
create table t1(col1 char(32));
insert into t1 values ('a'),('b'),('c'),('d'), ('e'),('f'),('g'),('h');
analyze table t1;
Table Op Msg_type Msg_text
test.t1 analyze status Engine-independent statistics collected
test.t1 analyze status OK
create table t2(col1 text);
insert into t2 values ('a'),('b'),('c'),('d'), ('e'),('f'),('g'),('h');
analyze table t2;
Table Op Msg_type Msg_text
test.t2 analyze status Engine-independent statistics collected
test.t2 analyze Warning Engine-independent statistics are not collected for column 'col1'
test.t2 analyze status OK
select * from t1 where col1 > 'b' and col1 < 'd';
col1
c
explain extended
select * from t1 where col1 > 'b' and col1 < 'd';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 8 28.57 Using where
Warnings:
Note 1003 select `test`.`t1`.`col1` AS `col1` from `test`.`t1` where ((`test`.`t1`.`col1` > 'b') and (`test`.`t1`.`col1` < 'd'))
select * from t2 where col1 > 'b' and col1 < 'd';
col1
c
explain extended
select * from t2 where col1 > 'b' and col1 < 'd';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where
Warnings:
Note 1003 select `test`.`t2`.`col1` AS `col1` from `test`.`t2` where ((`test`.`t2`.`col1` > 'b') and (`test`.`t2`.`col1` < 'd'))
select * from t2 where col1 < 'b' and col1 > 'd';
col1
explain extended
select * from t2 where col1 < 'b' and col1 > 'd';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings:
Note 1003 select `test`.`t2`.`col1` AS `col1` from `test`.`t2` where 0
drop table t1,t2;
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
set use_stat_tables=@save_use_stat_tables;

View file

@ -802,9 +802,9 @@ insert into t2 values (2),(3);
explain extended
select * from t1 where a in ( select b from t2 ) AND ( a > 3 );
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 1 0.00 Using where
1 PRIMARY t1 ALL NULL NULL NULL NULL 1 100.00 Using where
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 0.00
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 100.00
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`a` > 3))
select * from t1 where a in ( select b from t2 ) AND ( a > 3 );
@ -1450,6 +1450,78 @@ a b i
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
DROP TABLE t1,t2;
set use_stat_tables=@save_use_stat_tables;
#
# Bug mdev-11096: range condition over column without statistical data
#
set use_stat_tables='preferably';
set optimizer_use_condition_selectivity=3;
create table t1(col1 char(32));
insert into t1 values ('a'),('b'),('c'),('d'), ('e'),('f'),('g'),('h');
analyze table t1 persistent for columns () indexes ();
Table Op Msg_type Msg_text
test.t1 analyze status Engine-independent statistics collected
test.t1 analyze status OK
explain extended
select * from t1 where col1 > 'b' and col1 < 'e';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 8 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`col1` AS `col1` from `test`.`t1` where ((`test`.`t1`.`col1` > 'b') and (`test`.`t1`.`col1` < 'e'))
select * from t1 where col1 > 'b' and col1 < 'e';
col1
c
d
drop table t1;
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
set use_stat_tables=@save_use_stat_tables;
#
# Bug mdev-9628: unindexed blob column without min-max statistics
# with optimizer_use_condition_selectivity=3
#
set use_stat_tables='preferably';
set optimizer_use_condition_selectivity=3;
create table t1(col1 char(32));
insert into t1 values ('a'),('b'),('c'),('d'), ('e'),('f'),('g'),('h');
analyze table t1;
Table Op Msg_type Msg_text
test.t1 analyze status Engine-independent statistics collected
test.t1 analyze status OK
create table t2(col1 text);
insert into t2 values ('a'),('b'),('c'),('d'), ('e'),('f'),('g'),('h');
analyze table t2;
Table Op Msg_type Msg_text
test.t2 analyze status Engine-independent statistics collected
test.t2 analyze Warning Engine-independent statistics are not collected for column 'col1'
test.t2 analyze status OK
select * from t1 where col1 > 'b' and col1 < 'd';
col1
c
explain extended
select * from t1 where col1 > 'b' and col1 < 'd';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 8 28.57 Using where
Warnings:
Note 1003 select `test`.`t1`.`col1` AS `col1` from `test`.`t1` where ((`test`.`t1`.`col1` > 'b') and (`test`.`t1`.`col1` < 'd'))
select * from t2 where col1 > 'b' and col1 < 'd';
col1
c
explain extended
select * from t2 where col1 > 'b' and col1 < 'd';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where
Warnings:
Note 1003 select `test`.`t2`.`col1` AS `col1` from `test`.`t2` where ((`test`.`t2`.`col1` > 'b') and (`test`.`t2`.`col1` < 'd'))
select * from t2 where col1 < 'b' and col1 > 'd';
col1
explain extended
select * from t2 where col1 < 'b' and col1 > 'd';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings:
Note 1003 select `test`.`t2`.`col1` AS `col1` from `test`.`t2` where 0
drop table t1,t2;
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
set use_stat_tables=@save_use_stat_tables;
set optimizer_switch=@save_optimizer_switch_for_selectivity_test;
set @tmp_ust= @@use_stat_tables;
set @tmp_oucs= @@optimizer_use_condition_selectivity;
@ -1536,6 +1608,45 @@ where t1.child_user_id=t3.id and t1.child_group_id is null and t2.lower_group_na
parent_id child_group_id child_user_id id lower_group_name directory_id id
drop table t1,t2,t3;
#
# MDEV-9187: duplicate of bug mdev-9628
#
set use_stat_tables = preferably;
set optimizer_use_condition_selectivity=3;
CREATE TABLE t1 (f1 char(32)) ENGINE=InnoDB;
INSERT INTO t1 VALUES ('foo'),('bar'),('qux');
ANALYZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 analyze status Engine-independent statistics collected
test.t1 analyze status OK
SELECT * FROM t1 WHERE f1 < 'm';
f1
foo
bar
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE f1 < 'm';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 72.09 Using where
Warnings:
Note 1003 select `test`.`t1`.`f1` AS `f1` from `test`.`t1` where (`test`.`t1`.`f1` < 'm')
CREATE TABLE t2 (f1 TEXT) ENGINE=InnoDB;
INSERT INTO t2 VALUES ('foo'),('bar'),('qux');
ANALYZE TABLE t2;
Table Op Msg_type Msg_text
test.t2 analyze status Engine-independent statistics collected
test.t2 analyze Warning Engine-independent statistics are not collected for column 'f1'
test.t2 analyze status OK
SELECT * FROM t2 WHERE f1 <> 'qux';
f1
foo
bar
EXPLAIN EXTENDED
SELECT * FROM t2 WHERE f1 <> 'qux';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
Note 1003 select `test`.`t2`.`f1` AS `f1` from `test`.`t2` where (`test`.`t2`.`f1` <> 'qux')
DROP TABLE t1,t2;
#
# End of 10.0 tests
#
set use_stat_tables= @tmp_ust;

View file

@ -30,3 +30,5 @@ galera_gcs_fragment : Incorrect arguments to SET
galera_flush_local : Fails sporadically
galera_binlog_stmt_autoinc : TODO: investigate
galera_concurrent_ctas : Test times out, investigate
galera_sst_xtrabackup-v2-options : TODO: Fix test case
mysql-wsrep#33 : TODO: investigate

View file

@ -32,4 +32,10 @@ if ($node_3)
--connection $node_3
--eval SET @@global.auto_increment_offset = $auto_increment_offset_node_3;
}
if ($node_4)
{
--connection $node_4
--eval SET @@global.auto_increment_offset = $auto_increment_offset_node_4;
}
--enable_query_log

View file

@ -13,6 +13,8 @@
# Connection handle for 2nd node
# $node_3 (optional)
# Connection handle for 3rd node
# $node_4 (optional)
# Connection handle for 4th node
if (!$node_1)
{
@ -35,3 +37,9 @@ if ($node_3)
let $auto_increment_offset_node_3 = `SELECT @@global.auto_increment_offset`;
}
if ($node_4)
{
--connection $node_4
let $auto_increment_offset_node_4 = `SELECT @@global.auto_increment_offset`;
}

View file

@ -277,7 +277,7 @@ INSERT INTO t1 VALUES ('node2_committed_before');
INSERT INTO t1 VALUES ('node2_committed_before');
INSERT INTO t1 VALUES ('node2_committed_before');
COMMIT;
SET GLOBAL debug = 'd,sync.alter_opened_table';
SET GLOBAL debug_dbug = 'd,sync.alter_opened_table';
ALTER TABLE t1 ADD COLUMN f2 INTEGER;
SET wsrep_sync_wait = 0;
Killing server ...
@ -356,3 +356,4 @@ COUNT(*) = 0
DROP TABLE t1;
COMMIT;
SET AUTOCOMMIT=ON;
SET GLOBAL debug_dbug = $debug_orig;

View file

@ -3,6 +3,7 @@
#
--source include/big_test.inc
--source include/have_innodb.inc
--source include/galera_cluster.inc
# We perform the shutdown/restart sequence in here. If there was a crash during shutdown, MTR will detect it

View file

@ -2,8 +2,18 @@
--source include/galera_cluster.inc
--source include/have_innodb.inc
# Save original auto_increment_offset values.
--let $node_1=node_1
--let $node_2=node_2
--source include/auto_increment_offset_save.inc
--source suite/galera/include/galera_st_shutdown_slave.inc
--source suite/galera/include/galera_st_clean_slave.inc
--source suite/galera/include/galera_st_kill_slave.inc
--source suite/galera/include/galera_st_kill_slave_ddl.inc
# Restore original auto_increment_offset values.
--source include/auto_increment_offset_restore.inc
--source include/galera_end.inc

View file

@ -12,6 +12,16 @@
--source include/galera_cluster.inc
--source include/have_innodb.inc
--connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3
--connect node_4, 127.0.0.1, root, , test, $NODE_MYPORT_4
# Save original auto_increment_offset values.
--let $node_1=node_1
--let $node_2=node_2
--let $node_3=node_3
--let $node_4=node_4
--source include/auto_increment_offset_save.inc
SELECT VARIABLE_VALUE = 4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
--connection node_1
@ -21,11 +31,9 @@ INSERT INTO t1 VALUES (1);
--connection node_2
INSERT INTO t1 VALUES (2);
--connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3
--connection node_3
INSERT INTO t1 VALUES (3);
--connect node_4, 127.0.0.1, root, , test, $NODE_MYPORT_4
--connection node_4
INSERT INTO t1 VALUES (4);
@ -146,3 +154,8 @@ CALL mtr.add_suppression("Action message in non-primary configuration from membe
--connection node_4
CALL mtr.add_suppression("Action message in non-primary configuration from member 0");
# Restore original auto_increment_offset values.
--source include/auto_increment_offset_restore.inc
--source include/galera_end.inc

View file

@ -3,3 +3,5 @@ galera_evs_suspect_timeout : TODO: investigate
galera_innobackupex_backup : TODO: investigate
galera_slave_options_do :MDEV-8798
galera_slave_options_ignore : MDEV-8798
galera_pc_bootstrap : TODO: Investigate: Timeout in wait_condition.inc
galera_pc_weight : Test times out

View file

@ -0,0 +1,6 @@
include/master-slave.inc
[connection master]
include/stop_slave.inc
NOT FOUND /Error reading packet from server: Lost connection/ in slave_log.err
include/start_slave.inc
include/rpl_end.inc

View file

@ -13,7 +13,7 @@ insert into mysqltest1.t1 values (1);
select * from mysqltest1.t1 into outfile 'mysqltest1/f1.txt';
create table mysqltest1.t2 (n int);
create table mysqltest1.t3 (n int);
--replace_result \\ / 66 39 17 39 247 39 "File exists" "Directory not empty"
--replace_result \\ / 66 39 93 39 17 39 247 39 "File exists" "Directory not empty"
--error 1010
drop database mysqltest1;
use mysqltest1;
@ -30,7 +30,7 @@ while ($1)
}
--enable_query_log
--replace_result \\ / 66 39 17 39 247 39 "File exists" "Directory not empty"
--replace_result \\ / 66 39 93 39 17 39 247 39 "File exists" "Directory not empty"
--error 1010
drop database mysqltest1;
use mysqltest1;

View file

@ -0,0 +1 @@
--log-error=$MYSQLTEST_VARDIR/tmp/slave_log.err

View file

@ -0,0 +1,17 @@
#
# MDEV-8345 STOP SLAVE should not cause an ERROR to be logged to the error log
#
source include/have_binlog_format_mixed.inc; # don't repeat the test three times
source include/master-slave.inc;
connection master;
sync_slave_with_master;
source include/stop_slave.inc;
let SEARCH_FILE=$MYSQLTEST_VARDIR/tmp/slave_log.err;
let SEARCH_PATTERN=Error reading packet from server: Lost connection;
let SEARCH_RANGE= -50000;
source include/search_pattern_in_file.inc;
source include/start_slave.inc;
source include/rpl_end.inc;

View file

@ -288,7 +288,7 @@
+DEFAULT_VALUE assert
+VARIABLE_SCOPE GLOBAL
+VARIABLE_TYPE ENUM
+VARIABLE_COMMENT Warn corruptions of user tables as 'corrupt table' instead of not crashing itself, when used with file_per_table. All file io for the datafile after detected as corrupt are disabled, except for the deletion
+VARIABLE_COMMENT Warn corruptions of user tables as 'corrupt table' instead of not crashing itself, when used with file_per_table. All file io for the datafile after detected as corrupt are disabled, except for the deletion.
+NUMERIC_MIN_VALUE NULL
+NUMERIC_MAX_VALUE NULL
+NUMERIC_BLOCK_SIZE NULL
@ -1228,7 +1228,7 @@
VARIABLE_NAME INNODB_VERSION
SESSION_VALUE NULL
-GLOBAL_VALUE 5.6.33
+GLOBAL_VALUE 5.6.32-78.1
+GLOBAL_VALUE 5.6.32-79.0
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE NULL
VARIABLE_SCOPE GLOBAL

View file

@ -167,7 +167,7 @@
+DEFAULT_VALUE assert
+VARIABLE_SCOPE GLOBAL
+VARIABLE_TYPE ENUM
+VARIABLE_COMMENT Warn corruptions of user tables as 'corrupt table' instead of not crashing itself, when used with file_per_table. All file io for the datafile after detected as corrupt are disabled, except for the deletion
+VARIABLE_COMMENT Warn corruptions of user tables as 'corrupt table' instead of not crashing itself, when used with file_per_table. All file io for the datafile after detected as corrupt are disabled, except for the deletion.
+NUMERIC_MIN_VALUE NULL
+NUMERIC_MAX_VALUE NULL
+NUMERIC_BLOCK_SIZE NULL
@ -662,7 +662,7 @@
VARIABLE_NAME INNODB_VERSION
SESSION_VALUE NULL
-GLOBAL_VALUE 5.6.33
+GLOBAL_VALUE 5.6.32-78.1
+GLOBAL_VALUE 5.6.32-79.0
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE NULL
VARIABLE_SCOPE GLOBAL

View file

@ -1712,6 +1712,35 @@ CREATE TABLE t1 (
ALTER TABLE t1 ADD PRIMARY KEY IF NOT EXISTS event_id (event_id,market_id);
DROP TABLE t1;
--echo #
--echo # MDEV-11126 Crash while altering persistent virtual column
--echo #
CREATE TABLE `tab1` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`field2` set('option1','option2','option3','option4') NOT NULL,
`field3` set('option1','option2','option3','option4','option5') NOT NULL,
`field4` set('option1','option2','option3','option4') NOT NULL,
`field5` varchar(32) NOT NULL,
`field6` varchar(32) NOT NULL,
`field7` varchar(32) NOT NULL,
`field8` varchar(32) NOT NULL,
`field9` int(11) NOT NULL DEFAULT '1',
`field10` varchar(16) NOT NULL,
`field11` enum('option1','option2','option3') NOT NULL DEFAULT 'option1',
`v_col` varchar(128) AS (IF(field11='option1',CONCAT_WS(":","field1",field2,field3,field4,field5,field6,field7,field8,field9,field10), CONCAT_WS(":","field1",field11,field2,field3,field4,field5,field6,field7,field8,field9,field10))) PERSISTENT,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=latin1;
ALTER TABLE `tab1` CHANGE COLUMN v_col `v_col` varchar(128);
SHOW CREATE TABLE `tab1`;
ALTER TABLE `tab1` CHANGE COLUMN v_col `v_col` varchar(128) AS (IF(field11='option1',CONCAT_WS(":","field1",field2,field3,field4,field5,field6,field7,field8,field9,field10), CONCAT_WS(":","field1",field11,field2,field3,field4,field5,field6,field7,field8,field9,field10))) PERSISTENT;
SHOW CREATE TABLE `tab1`;
DROP TABLE `tab1`;
--echo #
--echo # Start of 10.1 tests
--echo #
--echo #
--echo # MDEV-7374 : Losing connection to MySQL while running ALTER TABLE
--echo #
@ -1721,10 +1750,6 @@ INSERT INTO t1 SELECT a.* FROM t1 a, t1 b, t1 c, t1 d, t1 e;
ALTER TABLE t1 MODIFY i FLOAT;
DROP TABLE t1;
--echo #
--echo # Start of 10.1 tests
--echo #
--echo #
--echo # MDEV-7816 ALTER with DROP INDEX and ADD INDEX .. COMMENT='comment2' ignores the new comment
--echo #
@ -1733,4 +1758,3 @@ CREATE INDEX i1 ON t1(a) COMMENT 'comment1';
ALTER TABLE t1 DROP INDEX i1, ADD INDEX i1(a) COMMENT 'comment2';
SHOW CREATE TABLE t1;
DROP TABLE t1;

View file

@ -384,3 +384,15 @@ drop table t1;
# Cleanup
#
DROP TABLE t2;
--echo #
--echo # MDEV-10824 - Crash in CREATE OR REPLACE TABLE t1 AS SELECT spfunc()
--echo #
CREATE TABLE t1(a INT);
CREATE FUNCTION f1() RETURNS VARCHAR(16383) RETURN 'test';
CREATE OR REPLACE TABLE t1 AS SELECT f1();
LOCK TABLE t1 WRITE;
CREATE OR REPLACE TABLE t1 AS SELECT f1();
UNLOCK TABLES;
DROP FUNCTION f1;
DROP TABLE t1;

View file

@ -313,3 +313,12 @@ INSERT INTO table1 VALUES (1);
DROP TABLE table1,table2;
--echo # End BUG#34750
--echo #
--echo # MDEV-11105 Table named 'db' has weird side effect.
--echo #
CREATE DATABASE mysqltest;
CREATE TABLE mysqltest.db(id INT);
DROP DATABASE mysqltest;

View file

@ -620,13 +620,13 @@ select * from information_schema.schema_privileges order by grantee;
select * from information_schema.user_privileges order by grantee;
show grants;
connection con4;
select * from information_schema.column_privileges where grantee like '%user%'
select * from information_schema.column_privileges where grantee like '\'user%'
order by grantee;
select * from information_schema.table_privileges where grantee like '%user%'
select * from information_schema.table_privileges where grantee like '\'user%'
order by grantee;
select * from information_schema.schema_privileges where grantee like '%user%'
select * from information_schema.schema_privileges where grantee like '\'user%'
order by grantee;
select * from information_schema.user_privileges where grantee like '%user%'
select * from information_schema.user_privileges where grantee like '\'user%'
order by grantee;
show grants;
connection default;

View file

@ -588,8 +588,16 @@ DROP DATABASE connected_db;
# USE and names with backticks
#
--write_file $MYSQLTEST_VARDIR/tmp/backticks.sql
\u aa`bb``cc
SELECT DATABASE();
USE test
SELECT DATABASE();
USE aa`bb``cc
SELECT DATABASE();
USE test
SELECT DATABASE();
USE `aa``bb````cc`
SELECT DATABASE();
EOF
create database `aa``bb````cc`;
--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/backticks.sql

View file

@ -13,3 +13,12 @@
--echo
--echo End of tests
# Multi-line exec
exec $MYSQL \
test -e "select 1";
exec $MYSQL test -e "select
2";
let $query = select 3
as X;
exec $MYSQL test -e "$query";

View file

@ -0,0 +1,38 @@
#
# New lines in identifiers
#
# embedded server doesn't support external clients
--source include/not_embedded.inc
# cmd.exe doesn't like new lines on the command line
--source include/not_windows.inc
create database `mysqltest1
1tsetlqsym`;
use `mysqltest1
1tsetlqsym`;
create table `t1
1t` (`foobar
raboof` int);
create view `v1
1v` as select * from `t1
1t`;
create procedure sp() select * from `v1
1v`;
flush tables;
use test;
exec $MYSQL_DUMP --compact --comment --routines --add-drop-database --databases 'mysqltest1
1tsetlqsym';
exec $MYSQL_DUMP --compact --comment --routines --add-drop-database --databases 'mysqltest1
1tsetlqsym' | $MYSQL;
show tables from `mysqltest1
1tsetlqsym`;
drop database `mysqltest1
1tsetlqsym`;

View file

@ -741,15 +741,6 @@ echo ;
--error 1
--exec echo "--exec " | $MYSQL_TEST 2>&1
# Multi-line exec
exec $MYSQL
test -e "select 1";
exec $MYSQL test -e "select
2";
let $query = select 3
as X;
exec $MYSQL test -e "$query";
# ----------------------------------------------------------------------------
# Test let command
# ----------------------------------------------------------------------------

View file

@ -972,6 +972,58 @@ set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivit
DROP TABLE t1,t2;
set use_stat_tables=@save_use_stat_tables;
--echo #
--echo # Bug mdev-11096: range condition over column without statistical data
--echo #
set use_stat_tables='preferably';
set optimizer_use_condition_selectivity=3;
create table t1(col1 char(32));
insert into t1 values ('a'),('b'),('c'),('d'), ('e'),('f'),('g'),('h');
analyze table t1 persistent for columns () indexes ();
explain extended
select * from t1 where col1 > 'b' and col1 < 'e';
select * from t1 where col1 > 'b' and col1 < 'e';
drop table t1;
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
set use_stat_tables=@save_use_stat_tables;
--echo #
--echo # Bug mdev-9628: unindexed blob column without min-max statistics
--echo # with optimizer_use_condition_selectivity=3
--echo #
set use_stat_tables='preferably';
set optimizer_use_condition_selectivity=3;
create table t1(col1 char(32));
insert into t1 values ('a'),('b'),('c'),('d'), ('e'),('f'),('g'),('h');
analyze table t1;
create table t2(col1 text);
insert into t2 values ('a'),('b'),('c'),('d'), ('e'),('f'),('g'),('h');
analyze table t2;
select * from t1 where col1 > 'b' and col1 < 'd';
explain extended
select * from t1 where col1 > 'b' and col1 < 'd';
select * from t2 where col1 > 'b' and col1 < 'd';
explain extended
select * from t2 where col1 > 'b' and col1 < 'd';
select * from t2 where col1 < 'b' and col1 > 'd';
explain extended
select * from t2 where col1 < 'b' and col1 > 'd';
drop table t1,t2;
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
set use_stat_tables=@save_use_stat_tables;

View file

@ -109,6 +109,31 @@ where t1.child_user_id=t3.id and t1.child_group_id is null and t2.lower_group_na
drop table t1,t2,t3;
--echo #
--echo # MDEV-9187: duplicate of bug mdev-9628
--echo #
set use_stat_tables = preferably;
set optimizer_use_condition_selectivity=3;
CREATE TABLE t1 (f1 char(32)) ENGINE=InnoDB;
INSERT INTO t1 VALUES ('foo'),('bar'),('qux');
ANALYZE TABLE t1;
SELECT * FROM t1 WHERE f1 < 'm';
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE f1 < 'm';
CREATE TABLE t2 (f1 TEXT) ENGINE=InnoDB;
INSERT INTO t2 VALUES ('foo'),('bar'),('qux');
ANALYZE TABLE t2;
SELECT * FROM t2 WHERE f1 <> 'qux';
EXPLAIN EXTENDED
SELECT * FROM t2 WHERE f1 <> 'qux';
DROP TABLE t1,t2;
--echo #
--echo # End of 10.0 tests
--echo #

View file

@ -1213,6 +1213,125 @@
fun:dlopen@@GLIBC_2.2.5
}
#
# MDEV-11061: OpenSSL 0.9.8 problems
#
{
MDEV-11061: OpenSSL 0.9.8
Memcheck:Cond
obj:*/libz.so*
...
obj:*/libcrypto.so.0.9.8
...
obj:*/libssl.so.0.9.8
...
}
{
MDEV-11061: OpenSSL 0.9.8
Memcheck:Value8
obj:*/libz.so*
...
obj:*/libcrypto.so.0.9.8
...
obj:*/libssl.so.0.9.8
...
}
{
MDEV-11061: OpenSSL 0.9.8
Memcheck:Cond
obj:*/libcrypto.so.0.9.8
...
obj:*/libssl.so.0.9.8
...
}
{
MDEV-11061: OpenSSL 0.9.8
Memcheck:Value8
obj:*/libcrypto.so.0.9.8
...
obj:*/libssl.so.0.9.8
...
}
{
MDEV-11061: OpenSSL 0.9.8
Memcheck:Cond
obj:*/libssl.so.0.9.8
obj:*/libssl.so.0.9.8
...
}
{
MDEV-11061: OpenSSL 0.9.8
Memcheck:Value8
obj:*/libssl.so.0.9.8
obj:*/libssl.so.0.9.8
...
}
{
MDEV-11061: OpenSSL 0.9.8
Memcheck:Cond
fun:memcpy
obj:*/libcrypto.so.0.9.8
obj:*/libssl.so.0.9.8
...
}
{
MDEV-11061: OpenSSL 0.9.8
Memcheck:Value8
fun:memcpy
obj:*/libcrypto.so.0.9.8
obj:*/libssl.so.0.9.8
...
}
{
MDEV-11061: OpenSSL 0.9.8
Memcheck:Cond
fun:is_overlap
fun:memcpy
obj:*/libcrypto.so.0.9.8
obj:*/libssl.so.0.9.8
...
}
{
MDEV-11061: OpenSSL 0.9.8
Memcheck:Cond
fun:memset
obj:*/libcrypto.so.0.9.8
...
obj:*/libssl.so.0.9.8
...
}
{
MDEV-11061: OpenSSL 0.9.8
Memcheck:Value8
fun:memset
obj:*/libcrypto.so.0.9.8
...
obj:*/libssl.so.0.9.8
...
}
{
MDEV-11061: OpenSSL 0.9.8
Memcheck:Param
write(buf)
obj:*/libpthread-2.9.so*
obj:*/libcrypto.so.0.9.8
...
obj:*/libssl.so.0.9.8
...
}
{
vasprintf in OpenSuse 12.3
Memcheck:Leak

View file

@ -2691,8 +2691,8 @@ static bool check_equality_for_exist2in(Item_func *func,
args[0]->all_used_tables() == OUTER_REF_TABLE_BIT)
{
/* It is Item_field or Item_direct_view_ref) */
DBUG_ASSERT(args[0]->type() == Item::FIELD_ITEM ||
args[0]->type() == Item::REF_ITEM);
DBUG_ASSERT(args[1]->type() == Item::FIELD_ITEM ||
args[1]->type() == Item::REF_ITEM);
*local_field= (Item_ident *)args[1];
*outer_exp= args[0];
return TRUE;

View file

@ -2757,9 +2757,16 @@ bool create_key_parts_for_pseudo_indexes(RANGE_OPT_PARAM *param,
{
Field *field= *field_ptr;
uint16 store_length;
uint16 max_key_part_length= (uint16) table->file->max_key_part_length();
key_part->key= keys;
key_part->part= 0;
key_part->length= (uint16) field->key_length();
if (field->flags & BLOB_FLAG)
key_part->length= max_key_part_length;
else
{
key_part->length= (uint16) field->key_length();
set_if_smaller(key_part->length, max_key_part_length);
}
store_length= key_part->length;
if (field->real_maybe_null())
store_length+= HA_KEY_NULL_LENGTH;

View file

@ -3320,8 +3320,13 @@ static ulong read_event(MYSQL* mysql, Master_info *mi, bool* suppress_warnings)
*suppress_warnings= TRUE;
}
else
sql_print_error("Error reading packet from server: %s ( server_errno=%d)",
mysql_error(mysql), mysql_errno(mysql));
{
if (!mi->rli.abort_slave)
{
sql_print_error("Error reading packet from server: %s (server_errno=%d)",
mysql_error(mysql), mysql_errno(mysql));
}
}
DBUG_RETURN(packet_error);
}

View file

@ -815,7 +815,7 @@ static bool
mysql_rm_db_internal(THD *thd,char *db, bool if_exists, bool silent)
{
ulong deleted_tables= 0;
bool error= true;
bool error= true, rm_mysql_schema;
char path[FN_REFLEN + 16];
MY_DIR *dirp;
uint length;
@ -840,6 +840,18 @@ mysql_rm_db_internal(THD *thd,char *db, bool if_exists, bool silent)
length= build_table_filename(path, sizeof(path) - 1, db, "", "", 0);
strmov(path+length, MY_DB_OPT_FILE); // Append db option file name
del_dbopt(path); // Remove dboption hash entry
/*
Now remove the db.opt file.
The 'find_db_tables_and_rm_known_files' doesn't remove this file
if there exists a table with the name 'db', so let's just do it
separately. We know this file exists and needs to be deleted anyway.
*/
if (my_delete_with_symlink(path, MYF(0)) && my_errno != ENOENT)
{
my_error(EE_DELETE, MYF(0), path, my_errno);
DBUG_RETURN(true);
}
path[length]= '\0'; // Remove file name
/* See if the directory exists */
@ -867,7 +879,8 @@ mysql_rm_db_internal(THD *thd,char *db, bool if_exists, bool silent)
Disable drop of enabled log tables, must be done before name locking.
This check is only needed if we are dropping the "mysql" database.
*/
if ((my_strcasecmp(system_charset_info, MYSQL_SCHEMA_NAME.str, db) == 0))
if ((rm_mysql_schema=
(my_strcasecmp(system_charset_info, MYSQL_SCHEMA_NAME.str, db) == 0)))
{
for (table= tables; table; table= table->next_local)
if (check_if_log_table(table, TRUE, "DROP"))
@ -880,7 +893,7 @@ mysql_rm_db_internal(THD *thd,char *db, bool if_exists, bool silent)
lock_db_routines(thd, dbnorm))
goto exit;
if (!in_bootstrap)
if (!in_bootstrap && !rm_mysql_schema)
{
for (table= tables; table; table= table->next_local)
{
@ -920,10 +933,13 @@ mysql_rm_db_internal(THD *thd,char *db, bool if_exists, bool silent)
ha_drop_database(path);
tmp_disable_binlog(thd);
query_cache_invalidate1(thd, dbnorm);
(void) sp_drop_db_routines(thd, dbnorm); /* @todo Do not ignore errors */
if (!rm_mysql_schema)
{
(void) sp_drop_db_routines(thd, dbnorm); /* @todo Do not ignore errors */
#ifdef HAVE_EVENT_SCHEDULER
Events::drop_schema_events(thd, dbnorm);
Events::drop_schema_events(thd, dbnorm);
#endif
}
reenable_binlog(thd);
/*

View file

@ -3262,12 +3262,6 @@ mysql_execute_command(THD *thd)
create_info.table_charset= 0;
}
/*
For CREATE TABLE we should not open the table even if it exists.
If the table exists, we should either not create it or replace it
*/
lex->query_tables->open_strategy= TABLE_LIST::OPEN_STUB;
/*
If we are a slave, we should add OR REPLACE if we don't have
IF EXISTS. This will help a slave to recover from
@ -8871,12 +8865,6 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables,
if (check_fk_parent_table_access(thd, &lex->create_info, &lex->alter_info, create_table->db))
goto err;
/*
For CREATE TABLE we should not open the table even if it exists.
If the table exists, we should either not create it or replace it
*/
lex->query_tables->open_strategy= TABLE_LIST::OPEN_STUB;
error= FALSE;
err:

View file

@ -1003,11 +1003,13 @@ public:
switch (i) {
case COLUMN_STAT_MIN_VALUE:
table_field->read_stats->min_value->set_notnull();
stat_field->val_str(&val);
table_field->read_stats->min_value->store(val.ptr(), val.length(),
&my_charset_bin);
break;
case COLUMN_STAT_MAX_VALUE:
table_field->read_stats->max_value->set_notnull();
stat_field->val_str(&val);
table_field->read_stats->max_value->store(val.ptr(), val.length(),
&my_charset_bin);
@ -3659,17 +3661,8 @@ double get_column_range_cardinality(Field *field,
{
double avg_frequency= col_stats->get_avg_frequency();
res= avg_frequency;
/*
psergey-todo: what does check for min_value, max_value mean?
min/max_value are set to NULL in alloc_statistics_for_table() and
alloc_statistics_for_table_share(). Both functions will immediately
call create_min_max_statistical_fields_for_table and
create_min_max_statistical_fields_for_table_share() respectively,
which will set min/max_value to be valid pointers, unless OOM
occurs.
*/
if (avg_frequency > 1.0 + 0.000001 &&
col_stats->min_value && col_stats->max_value)
col_stats->min_max_values_are_provided())
{
Histogram *hist= &col_stats->histogram;
if (hist->is_available())
@ -3692,7 +3685,7 @@ double get_column_range_cardinality(Field *field,
}
else
{
if (col_stats->min_value && col_stats->max_value)
if (col_stats->min_max_values_are_provided())
{
double sel, min_mp_pos, max_mp_pos;

View file

@ -388,6 +388,11 @@ public:
avg_frequency= (ulong) (val * Scale_factor_avg_frequency);
}
bool min_max_values_are_provided()
{
return !is_null(COLUMN_STAT_MIN_VALUE) &&
!is_null(COLUMN_STAT_MIN_VALUE);
}
};

View file

@ -2440,7 +2440,8 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
if (table_type && table_type != view_pseudo_hton)
ha_lock_engine(thd, table_type);
if (thd->locked_tables_mode)
if (thd->locked_tables_mode == LTM_LOCK_TABLES ||
thd->locked_tables_mode == LTM_PRELOCKED_UNDER_LOCK_TABLES)
{
if (wait_while_table_is_used(thd, table->table, HA_EXTRA_NOT_USED))
{
@ -6294,6 +6295,7 @@ static bool fill_alter_inplace_info(THD *thd,
(field->stored_in_db || field->vcol_info->is_in_partitioning_expr()))
{
if (is_equal == IS_EQUAL_NO ||
!new_field->vcol_info ||
!field->vcol_info->is_equal(new_field->vcol_info))
ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_COLUMN_VCOL;
else

View file

@ -73,17 +73,16 @@ struct Worker_thread_context
void save()
{
#ifdef HAVE_PSI_INTERFACE
psi_thread= PSI_server?PSI_server->get_thread():0;
#ifdef HAVE_PSI_THREAD_INTERFACE
psi_thread = PSI_THREAD_CALL(get_thread)();
#endif
mysys_var= (st_my_thread_var *)pthread_getspecific(THR_KEY_mysys);
}
void restore()
{
#ifdef HAVE_PSI_INTERFACE
if (PSI_server)
PSI_server->set_thread(psi_thread);
#ifdef HAVE_PSI_THREAD_INTERFACE
PSI_THREAD_CALL(set_thread)(psi_thread);
#endif
pthread_setspecific(THR_KEY_mysys,mysys_var);
pthread_setspecific(THR_THD, 0);
@ -92,6 +91,41 @@ struct Worker_thread_context
};
#ifdef HAVE_PSI_INTERFACE
/*
The following fixes PSI "idle" psi instrumentation.
The server assumes that connection becomes idle
just before net_read_packet() and switches to active after it.
In out setup, server becomes idle when async socket io is made.
*/
extern void net_before_header_psi(struct st_net *net, void *user_data, size_t);
static void dummy_before_header(struct st_net *, void *, size_t)
{
}
static void re_init_net_server_extension(THD *thd)
{
thd->m_net_server_extension.m_before_header = dummy_before_header;
}
#else
#define re_init_net_server_extension(thd)
#endif /* HAVE_PSI_INTERFACE */
static inline void set_thd_idle(THD *thd)
{
thd->net.reading_or_writing= 1;
#ifdef HAVE_PSI_INTERFACE
net_before_header_psi(&thd->net, thd, 0);
#endif
}
/*
Attach/associate the connection with the OS thread,
*/
@ -100,10 +134,10 @@ static bool thread_attach(THD* thd)
pthread_setspecific(THR_KEY_mysys,thd->mysys_var);
thd->thread_stack=(char*)&thd;
thd->store_globals();
#ifdef HAVE_PSI_INTERFACE
if (PSI_server)
PSI_server->set_thread(thd->event_scheduler.m_psi);
#ifdef HAVE_PSI_THREAD_INTERFACE
PSI_THREAD_CALL(set_thread)(thd->event_scheduler.m_psi);
#endif
mysql_socket_set_thread_owner(thd->net.vio->mysql_socket);
return 0;
}
@ -130,39 +164,38 @@ int threadpool_add_connection(THD *thd)
}
/* Create new PSI thread for use with the THD. */
#ifdef HAVE_PSI_INTERFACE
if (PSI_server)
{
thd->event_scheduler.m_psi =
PSI_server->new_thread(key_thread_one_connection, thd, thd->thread_id);
}
#ifdef HAVE_PSI_THREAD_INTERFACE
thd->event_scheduler.m_psi=
PSI_THREAD_CALL(new_thread)(key_thread_one_connection, thd, thd->thread_id);
#endif
/* Login. */
thread_attach(thd);
re_init_net_server_extension(thd);
ulonglong now= microsecond_interval_timer();
thd->prior_thr_create_utime= now;
thd->start_utime= now;
thd->thr_create_utime= now;
if (!setup_connection_thread_globals(thd))
{
if (!thd_prepare_connection(thd))
{
/*
Check if THD is ok, as prepare_new_connection_state()
can fail, for example if init command failed.
*/
if (thd_is_connection_alive(thd))
{
retval= 0;
thd->net.reading_or_writing= 1;
thd->skip_wait_timeout= true;
}
}
}
if (setup_connection_thread_globals(thd))
goto end;
if (thd_prepare_connection(thd))
goto end;
/*
Check if THD is ok, as prepare_new_connection_state()
can fail, for example if init command failed.
*/
if (!thd_is_connection_alive(thd))
goto end;
retval= 0;
thd->skip_wait_timeout= true;
set_thd_idle(thd);
end:
worker_context.restore();
return retval;
}
@ -244,12 +277,13 @@ int threadpool_process_request(THD *thd)
goto end;
}
set_thd_idle(thd);
vio= thd->net.vio;
if (!vio->has_data(vio))
{
/* More info on this debug sync is in sql_parse.cc*/
DEBUG_SYNC(thd, "before_do_command_net_read");
thd->net.reading_or_writing= 1;
goto end;
}
}

View file

@ -340,6 +340,18 @@ public class JdbcInterface {
return m;
} // end of GetMaxValue
public String GetQuoteString() {
String qs = null;
try {
qs = dbmd.getIdentifierQuoteString();
} catch(SQLException se) {
SetErrmsg(se);
} // end try/catch
return qs;
} // end of GetQuoteString
public int GetColumns(String[] parms) {
int ncol = -1;
@ -680,11 +692,11 @@ public class JdbcInterface {
return 0;
} // end of TimestampField
public String ObjectField(int n, String name) {
public Object ObjectField(int n, String name) {
if (rs == null) {
System.out.println("No result set");
} else try {
return (n > 0) ? rs.getObject(n).toString() : rs.getObject(name).toString();
return (n > 0) ? rs.getObject(n) : rs.getObject(name);
} catch (SQLException se) {
SetErrmsg(se);
} //end try/catch

View file

@ -383,7 +383,7 @@ DBFBASE::DBFBASE(DBFBASE *txfp)
/* and header length. Set Records, check that Reclen is equal to lrecl and */
/* return the header length or 0 in case of error. */
/****************************************************************************/
int DBFBASE::ScanHeader(PGLOBAL g, PSZ fname, int lrecl, char *defpath)
int DBFBASE::ScanHeader(PGLOBAL g, PSZ fn, int lrecl, int *rln, char *defpath)
{
int rc;
char filename[_MAX_PATH];
@ -393,7 +393,7 @@ int DBFBASE::ScanHeader(PGLOBAL g, PSZ fname, int lrecl, char *defpath)
/************************************************************************/
/* Open the input file. */
/************************************************************************/
PlugSetPath(filename, fname, defpath);
PlugSetPath(filename, fn, defpath);
if (!(infile= global_fopen(g, MSGID_CANNOT_OPEN, filename, "rb")))
return 0; // Assume file does not exist
@ -410,11 +410,7 @@ int DBFBASE::ScanHeader(PGLOBAL g, PSZ fname, int lrecl, char *defpath)
} else if (rc == RC_FX)
return -1;
if ((int)header.Reclen() != lrecl) {
sprintf(g->Message, MSG(BAD_LRECL), lrecl, header.Reclen());
return -1;
} // endif Lrecl
*rln = (int)header.Reclen();
Records = (int)header.Records();
return (int)header.Headlen();
} // end of ScanHeader
@ -431,9 +427,27 @@ int DBFFAM::Cardinality(PGLOBAL g)
if (!g)
return 1;
if (!Headlen)
if ((Headlen = ScanHeader(g, To_File, Lrecl, Tdbp->GetPath())) < 0)
return -1; // Error in ScanHeader
if (!Headlen) {
int rln = 0; // Record length in the file header
Headlen = ScanHeader(g, To_File, Lrecl, &rln, Tdbp->GetPath());
if (Headlen < 0)
return -1; // Error in ScanHeader
if (rln && Lrecl != rln) {
// This happens always on some Linux platforms
sprintf(g->Message, MSG(BAD_LRECL), Lrecl, rln);
if (Accept) {
Lrecl = rln;
PushWarning(g, Tdbp);
} else
return -1;
} // endif rln
} // endif Headlen
// Set number of blocks for later use
Block = (Records > 0) ? (Records + Nrec - 1) / Nrec : 0;
@ -565,7 +579,13 @@ bool DBFFAM::AllocateBuffer(PGLOBAL g)
if (Lrecl != reclen) {
sprintf(g->Message, MSG(BAD_LRECL), Lrecl, reclen);
return true;
if (Accept) {
Lrecl = reclen;
PushWarning(g, Tdbp);
} else
return true;
} // endif Lrecl
hlen = HEADLEN * (n + 1) + 2;
@ -641,8 +661,14 @@ bool DBFFAM::AllocateBuffer(PGLOBAL g)
if ((rc = dbfhead(g, Stream, Tdbp->GetFile(g), &header)) == RC_OK) {
if (Lrecl != (int)header.Reclen()) {
sprintf(g->Message, MSG(BAD_LRECL), Lrecl, header.Reclen());
return true;
} // endif Lrecl
if (Accept) {
Lrecl = header.Reclen();
PushWarning(g, Tdbp);
} else
return true;
} // endif Lrecl
Records = (int)header.Records();
Headlen = (int)header.Headlen();
@ -916,9 +942,27 @@ int DBMFAM::Cardinality(PGLOBAL g)
if (!g)
return 1;
if (!Headlen)
if ((Headlen = ScanHeader(g, To_File, Lrecl, Tdbp->GetPath())) < 0)
return -1; // Error in ScanHeader
if (!Headlen) {
int rln = 0; // Record length in the file header
Headlen = ScanHeader(g, To_File, Lrecl, &rln, Tdbp->GetPath());
if (Headlen < 0)
return -1; // Error in ScanHeader
if (rln && Lrecl != rln) {
// This happens always on some Linux platforms
sprintf(g->Message, MSG(BAD_LRECL), Lrecl, rln);
if (Accept) {
Lrecl = rln;
PushWarning(g, Tdbp);
} else
return -1;
} // endif rln
} // endif Headlen
// Set number of blocks for later use
Block = (Records > 0) ? (Records + Nrec - 1) / Nrec : 0;
@ -961,8 +1005,14 @@ bool DBMFAM::AllocateBuffer(PGLOBAL g)
if (Lrecl != (int)hp->Reclen()) {
sprintf(g->Message, MSG(BAD_LRECL), Lrecl, hp->Reclen());
return true;
} // endif Lrecl
if (Accept) {
Lrecl = hp->Reclen();
PushWarning(g, Tdbp);
} else
return true;
} // endif Lrecl
Records = (int)hp->Records();
Headlen = (int)hp->Headlen();

View file

@ -31,7 +31,7 @@ class DllExport DBFBASE {
DBFBASE(PDBF txfp);
// Implementation
int ScanHeader(PGLOBAL g, PSZ fname, int lrecl, char *defpath);
int ScanHeader(PGLOBAL g, PSZ fname, int lrecl, int *rlen, char *defpath);
protected:
// Default constructor, not to be used

View file

@ -224,6 +224,7 @@ uint GetWorkSize(void);
void SetWorkSize(uint);
extern "C" const char *msglang(void);
static void PopUser(PCONNECT xp);
static PCONNECT GetUser(THD *thd, PCONNECT xp);
static PGLOBAL GetPlug(THD *thd, PCONNECT& lxp);
@ -831,42 +832,51 @@ ha_connect::~ha_connect(void)
table ? table->s->table_name.str : "<null>",
xp, xp ? xp->count : 0);
if (xp) {
PCONNECT p;
xp->count--;
for (p= user_connect::to_users; p; p= p->next)
if (p == xp)
break;
if (p && !p->count) {
if (p->next)
p->next->previous= p->previous;
if (p->previous)
p->previous->next= p->next;
else
user_connect::to_users= p->next;
} // endif p
if (!xp->count) {
PlugCleanup(xp->g, true);
delete xp;
} // endif count
} // endif xp
PopUser(xp);
} // end of ha_connect destructor
/****************************************************************************/
/* Check whether this user can be removed. */
/****************************************************************************/
static void PopUser(PCONNECT xp)
{
if (xp) {
xp->count--;
if (!xp->count) {
PCONNECT p;
for (p= user_connect::to_users; p; p= p->next)
if (p == xp)
break;
if (p) {
if (p->next)
p->next->previous= p->previous;
if (p->previous)
p->previous->next= p->next;
else
user_connect::to_users= p->next;
} // endif p
PlugCleanup(xp->g, true);
delete xp;
} // endif count
} // endif xp
} // end of PopUser
/****************************************************************************/
/* Get a pointer to the user of this handler. */
/****************************************************************************/
static PCONNECT GetUser(THD *thd, PCONNECT xp)
{
if (!thd)
if (!thd)
return NULL;
if (xp && thd == xp->thdp)
@ -890,7 +900,6 @@ static PCONNECT GetUser(THD *thd, PCONNECT xp)
return xp;
} // end of GetUser
/****************************************************************************/
/* Get the global pointer of the user of this handler. */
/****************************************************************************/
@ -5261,7 +5270,18 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
if (!(shm= (char*)db))
db= table_s->db.str; // Default value
// Check table type
// Save stack and allocation environment and prepare error return
if (g->jump_level == MAX_JUMP) {
strcpy(g->Message, MSG(TOO_MANY_JUMPS));
goto jer;
} // endif jump_level
if ((rc= setjmp(g->jumper[++g->jump_level])) != 0) {
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
goto err;
} // endif rc
// Check table type
if (ttp == TAB_UNDEF) {
topt->type= (src) ? "MYSQL" : (tab) ? "PROXY" : "DOS";
ttp= GetTypeID(topt->type);
@ -5270,20 +5290,9 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
} else if (ttp == TAB_NIY) {
sprintf(g->Message, "Unsupported table type %s", topt->type);
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
return HA_ERR_INTERNAL_ERROR;
goto err;
} // endif ttp
// Save stack and allocation environment and prepare error return
if (g->jump_level == MAX_JUMP) {
strcpy(g->Message, MSG(TOO_MANY_JUMPS));
return HA_ERR_INTERNAL_ERROR;
} // endif jump_level
if ((rc= setjmp(g->jumper[++g->jump_level])) != 0) {
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
goto err;
} // endif rc
if (!tab) {
if (ttp == TAB_TBL) {
// Make tab the first table of the list
@ -5843,6 +5852,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
rc= init_table_share(thd, table_s, create_info, &sql);
g->jump_level--;
PopUser(xp);
return rc;
} // endif ok
@ -5850,7 +5860,9 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
err:
g->jump_level--;
return HA_ERR_INTERNAL_ERROR;
jer:
PopUser(xp);
return HA_ERR_INTERNAL_ERROR;
} // end of connect_assisted_discovery
/**

View file

@ -498,145 +498,6 @@ PQRYRES JDBCDrivers(PGLOBAL g, int maxres, bool info)
return qrp;
} // end of JDBCDrivers
#if 0
/*************************************************************************/
/* JDBCDataSources: constructs the result blocks containing all JDBC */
/* data sources available on the local host. */
/* Called with info=true to have result column names. */
/*************************************************************************/
PQRYRES JDBCDataSources(PGLOBAL g, int maxres, bool info)
{
int buftyp[] ={ TYPE_STRING, TYPE_STRING };
XFLD fldtyp[] ={ FLD_NAME, FLD_REM };
unsigned int length[] ={ 0, 256 };
bool b[] ={ false, true };
int i, n = 0, ncol = 2;
PCOLRES crp;
PQRYRES qrp;
JDBConn *jcp = NULL;
/************************************************************************/
/* Do an evaluation of the result size. */
/************************************************************************/
if (!info) {
jcp = new(g)JDBConn(g, NULL);
n = jcp->GetMaxValue(SQL_MAX_DSN_LENGTH);
length[0] = (n) ? (n + 1) : 256;
if (!maxres)
maxres = 512; // Estimated max number of data sources
} else {
length[0] = 256;
maxres = 0;
} // endif info
if (trace)
htrc("JDBCDataSources: max=%d len=%d\n", maxres, length[0]);
/************************************************************************/
/* Allocate the structures used to refer to the result set. */
/************************************************************************/
qrp = PlgAllocResult(g, ncol, maxres, IDS_DSRC,
buftyp, fldtyp, length, false, true);
for (i = 0, crp = qrp->Colresp; crp; i++, crp = crp->Next)
if (b[i])
crp->Kdata->SetNullable(true);
/************************************************************************/
/* Now get the results into blocks. */
/************************************************************************/
if (!info && qrp && jcp->GetDataSources(qrp))
qrp = NULL;
/************************************************************************/
/* Return the result pointer for use by GetData routines. */
/************************************************************************/
return qrp;
} // end of JDBCDataSources
/**************************************************************************/
/* PrimaryKeys: constructs the result blocks containing all the */
/* JDBC catalog information concerning primary keys. */
/**************************************************************************/
PQRYRES JDBCPrimaryKeys(PGLOBAL g, JDBConn *op, char *dsn, char *table)
{
static int buftyp[] ={ TYPE_STRING, TYPE_STRING, TYPE_STRING,
TYPE_STRING, TYPE_SHORT, TYPE_STRING };
static unsigned int length[] ={ 0, 0, 0, 0, 6, 128 };
int n, ncol = 5;
int maxres;
PQRYRES qrp;
JCATPARM *cap;
JDBConn *jcp = op;
if (!op) {
/**********************************************************************/
/* Open the connection with the JDBC data source. */
/**********************************************************************/
jcp = new(g)JDBConn(g, NULL);
if (jcp->Open(dsn, 2) < 1) // 2 is openReadOnly
return NULL;
} // endif op
/************************************************************************/
/* Do an evaluation of the result size. */
/************************************************************************/
n = jcp->GetMaxValue(SQL_MAX_COLUMNS_IN_TABLE);
maxres = (n) ? (int)n : 250;
n = jcp->GetMaxValue(SQL_MAX_CATALOG_NAME_LEN);
length[0] = (n) ? (n + 1) : 128;
n = jcp->GetMaxValue(SQL_MAX_SCHEMA_NAME_LEN);
length[1] = (n) ? (n + 1) : 128;
n = jcp->GetMaxValue(SQL_MAX_TABLE_NAME_LEN);
length[2] = (n) ? (n + 1) : 128;
n = jcp->GetMaxValue(SQL_MAX_COLUMN_NAME_LEN);
length[3] = (n) ? (n + 1) : 128;
if (trace)
htrc("JDBCPrimaryKeys: max=%d len=%d,%d,%d\n",
maxres, length[0], length[1], length[2]);
/************************************************************************/
/* Allocate the structure used to refer to the result set. */
/************************************************************************/
qrp = PlgAllocResult(g, ncol, maxres, IDS_PKEY,
buftyp, NULL, length, false, true);
if (trace)
htrc("Getting pkey results ncol=%d\n", qrp->Nbcol);
cap = AllocCatInfo(g, CAT_KEY, NULL, table, qrp);
/************************************************************************/
/* Now get the results into blocks. */
/************************************************************************/
if ((n = jcp->GetCatInfo(cap)) >= 0) {
qrp->Nblin = n;
// ResetNullValues(cap);
if (trace)
htrc("PrimaryKeys: NBCOL=%d NBLIN=%d\n", qrp->Nbcol, qrp->Nblin);
} else
qrp = NULL;
/************************************************************************/
/* Close any local connection. */
/************************************************************************/
if (!op)
jcp->Close();
/************************************************************************/
/* Return the result pointer for use by GetData routines. */
/************************************************************************/
return qrp;
} // end of JDBCPrimaryKeys
#endif // 0
/***********************************************************************/
/* JDBConn construction/destruction. */
/***********************************************************************/
@ -651,7 +512,7 @@ JDBConn::JDBConn(PGLOBAL g, TDBJDBC *tdbp)
xqid = xuid = xid = grs = readid = fetchid = typid = errid = nullptr;
prepid = xpid = pcid = nullptr;
chrfldid = intfldid = dblfldid = fltfldid = bigfldid = nullptr;
datfldid = timfldid = tspfldid = nullptr;
objfldid = datfldid = timfldid = tspfldid = nullptr;
//m_LoginTimeout = DEFAULT_LOGIN_TIMEOUT;
//m_QueryTimeout = DEFAULT_QUERY_TIMEOUT;
//m_UpdateOptions = 0;
@ -739,60 +600,6 @@ bool JDBConn::gmID(PGLOBAL g, jmethodID& mid, const char *name, const char *sig
} // end of gmID
#if 0
/***********************************************************************/
/* Utility routine. */
/***********************************************************************/
PSZ JDBConn::GetStringInfo(ushort infotype)
{
//ASSERT(m_hdbc != SQL_NULL_HDBC);
char *p, buffer[MAX_STRING_INFO];
SWORD result;
RETCODE rc;
rc = SQLGetInfo(m_hdbc, infotype, buffer, sizeof(buffer), &result);
if (!Check(rc)) {
ThrowDJX(rc, "SQLGetInfo"); // Temporary
// *buffer = '\0';
} // endif rc
p = PlugDup(m_G, buffer);
return p;
} // end of GetStringInfo
/***********************************************************************/
/* Utility routines. */
/***********************************************************************/
void JDBConn::OnSetOptions(HSTMT hstmt)
{
RETCODE rc;
ASSERT(m_hdbc != SQL_NULL_HDBC);
if ((signed)m_QueryTimeout != -1) {
// Attempt to set query timeout. Ignore failure
rc = SQLSetStmtOption(hstmt, SQL_QUERY_TIMEOUT, m_QueryTimeout);
if (!Check(rc))
// don't attempt it again
m_QueryTimeout = (DWORD)-1;
} // endif m_QueryTimeout
if (m_RowsetSize > 0) {
// Attempt to set rowset size.
// In case of failure reset it to 0 to use Fetch.
rc = SQLSetStmtOption(hstmt, SQL_ROWSET_SIZE, m_RowsetSize);
if (!Check(rc))
// don't attempt it again
m_RowsetSize = 0;
} // endif m_RowsetSize
} // end of OnSetOptions
#endif // 0
/***********************************************************************/
/* Utility routine. */
/***********************************************************************/
@ -1007,7 +814,7 @@ int JDBConn::Open(PJPARM sop)
#define N 1
#endif
// Java source will be compiled as ajar file installed in the plugin dir
// Java source will be compiled as a jar file installed in the plugin dir
jpop->Append(sep);
jpop->Append(GetPluginDir());
jpop->Append("JdbcInterface.jar");
@ -1204,6 +1011,21 @@ int JDBConn::Open(PJPARM sop)
return RC_FX;
} // endif Msg
jmethodID qcid = nullptr;
if (!gmID(g, qcid, "GetQuoteString", "()Ljava/lang/String;")) {
jstring s = (jstring)env->CallObjectMethod(job, qcid);
if (s != nullptr) {
char *qch = (char*)env->GetStringUTFChars(s, (jboolean)false);
m_IDQuoteChar[0] = *qch;
} else {
s = (jstring)env->CallObjectMethod(job, errid);
Msg = (char*)env->GetStringUTFChars(s, (jboolean)false);
} // endif s
} // endif qcid
if (gmID(g, typid, "ColumnType", "(ILjava/lang/String;)I"))
return RC_FX;
else
@ -1345,9 +1167,10 @@ void JDBConn::Close()
/***********************************************************************/
void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
{
PGLOBAL& g = m_G;
jint ctyp;
jstring cn, jn = nullptr;
PGLOBAL& g = m_G;
jint ctyp;
jstring cn, jn = nullptr;
jobject jb = nullptr;
if (rank == 0)
if (!name || (jn = env->NewStringUTF(name)) == nullptr) {
@ -1363,21 +1186,32 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
longjmp(g->jumper[g->jump_level], TYPE_AM_JDBC);
} // endif Check
if (val->GetNullable())
if (!gmID(g, objfldid, "ObjectField", "(ILjava/lang/String;)Ljava/lang/Object;")) {
jb = env->CallObjectMethod(job, objfldid, (jint)rank, jn);
if (jb == nullptr) {
val->Reset();
val->SetNull(true);
goto chk;
} // endif job
} // endif objfldid
switch (ctyp) {
case 12: // VARCHAR
case -1: // LONGVARCHAR
case 1: // CHAR
if (!gmID(g, chrfldid, "StringField", "(ILjava/lang/String;)Ljava/lang/String;")) {
if (jb)
cn = (jstring)jb;
else if (!gmID(g, chrfldid, "StringField", "(ILjava/lang/String;)Ljava/lang/String;"))
cn = (jstring)env->CallObjectMethod(job, chrfldid, (jint)rank, jn);
else
cn = nullptr;
if (cn) {
const char *field = env->GetStringUTFChars(cn, (jboolean)false);
val->SetValue_psz((PSZ)field);
} else {
val->Reset();
val->SetNull(true);
} // endif cn
if (cn) {
const char *field = env->GetStringUTFChars(cn, (jboolean)false);
val->SetValue_psz((PSZ)field);
} else
val->Reset();
@ -1449,6 +1283,7 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
val->Reset();
} // endswitch Type
chk:
if (Check()) {
if (rank == 0)
env->DeleteLocalRef(jn);

View file

@ -165,6 +165,7 @@ protected:
jmethodID xpid; // The ExecutePrep method ID
jmethodID pcid; // The ClosePrepStmt method ID
jmethodID errid; // The GetErrmsg method ID
jmethodID objfldid; // The ObjectField method ID
jmethodID chrfldid; // The StringField method ID
jmethodID intfldid; // The IntField method ID
jmethodID dblfldid; // The DoubleField method ID

View file

@ -294,7 +294,7 @@ int TABDEF::GetColCatInfo(PGLOBAL g)
nlg+= nof;
case TAB_DIR:
case TAB_XML:
poff= loff + 1;
poff= loff + (pcf->Flags & U_VIRTUAL ? 0 : 1);
break;
case TAB_INI:
case TAB_MAC:
@ -440,7 +440,11 @@ int TABDEF::GetColCatInfo(PGLOBAL g)
} // endswitch tc
// lrecl must be at least recln to avoid buffer overflow
recln= MY_MAX(recln, Hc->GetIntegerOption("Lrecl"));
if (trace)
htrc("Lrecl: Calculated=%d defined=%d\n",
recln, Hc->GetIntegerOption("Lrecl"));
recln = MY_MAX(recln, Hc->GetIntegerOption("Lrecl"));
Hc->SetIntegerOption("Lrecl", recln);
((PDOSDEF)this)->SetLrecl(recln);
} // endif Lrecl

View file

@ -686,6 +686,9 @@ bool TDBJDBC::MakeInsert(PGLOBAL g)
else
Prepared = true;
if (trace)
htrc("Insert=%s\n", Query->GetStr());
return false;
} // end of MakeInsert
@ -733,17 +736,18 @@ bool TDBJDBC::MakeCommand(PGLOBAL g)
// If so, it must be quoted in the original query
strlwr(strcat(strcat(strcpy(name, " "), Name), " "));
if (!strstr(" update delete low_priority ignore quick from ", name))
strlwr(strcpy(name, Name)); // Not a keyword
else
if (strstr(" update delete low_priority ignore quick from ", name)) {
strlwr(strcat(strcat(strcpy(name, qc), Name), qc));
k += 2;
} else
strlwr(strcpy(name, Name)); // Not a keyword
if ((p = strstr(qrystr, name))) {
for (i = 0; i < p - qrystr; i++)
stmt[i] = (Qrystr[i] == '`') ? *qc : Qrystr[i];
stmt[i] = 0;
k = i + (int)strlen(Name);
k += i + (int)strlen(Name);
if (qtd && *(p-1) == ' ')
strcat(strcat(strcat(stmt, qc), TableName), qc);
@ -765,6 +769,9 @@ bool TDBJDBC::MakeCommand(PGLOBAL g)
return NULL;
} // endif p
if (trace)
htrc("Command=%s\n", stmt);
Query = new(g)STRING(g, 0, stmt);
return (!Query->GetSize());
} // end of MakeCommand
@ -1214,6 +1221,10 @@ int TDBJDBC::WriteDB(PGLOBAL g)
} // endif oom
Query->RepLast(')');
if (trace > 1)
htrc("Inserting: %s\n", Query->GetStr());
rc = Jcp->ExecuteUpdate(Query->GetStr());
Query->Truncate(len); // Restore query

View file

@ -485,7 +485,7 @@ namespace open_query
optional<Vertex>
oqgraph_share::find_vertex(VertexID id) const
{
return ::boost::find_vertex(id, g);
return oqgraph3::find_vertex(id, g);
}
#if 0

View file

@ -274,6 +274,33 @@ namespace boost
};
#endif
template<>
struct property_map<oqgraph3::graph, edge_weight_t>
{
typedef void type;
typedef oqgraph3::edge_weight_property_map const_type;
};
template<>
struct property_map<oqgraph3::graph, vertex_index_t>
{
typedef void type;
typedef oqgraph3::vertex_index_property_map const_type;
};
template<>
struct property_map<oqgraph3::graph, edge_index_t>
{
typedef void type;
typedef oqgraph3::edge_index_property_map const_type;
};
}
namespace oqgraph3
{
using namespace boost;
inline graph_traits<oqgraph3::graph>::vertex_descriptor
source(
const graph_traits<oqgraph3::graph>::edge_descriptor& e,
@ -401,27 +428,6 @@ namespace boost
return count;
}
template<>
struct property_map<oqgraph3::graph, edge_weight_t>
{
typedef void type;
typedef oqgraph3::edge_weight_property_map const_type;
};
template<>
struct property_map<oqgraph3::graph, vertex_index_t>
{
typedef void type;
typedef oqgraph3::vertex_index_property_map const_type;
};
template<>
struct property_map<oqgraph3::graph, edge_index_t>
{
typedef void type;
typedef oqgraph3::edge_index_property_map const_type;
};
inline property_map<
oqgraph3::graph,
edge_weight_t>::const_type::reference

View file

@ -1,4 +1,4 @@
SET(TOKUDB_VERSION 5.6.32-78.1)
SET(TOKUDB_VERSION 5.6.33-79.0)
# PerconaFT only supports x86-64 and cmake-2.8.9+
IF(CMAKE_VERSION VERSION_LESS "2.8.9")
MESSAGE(STATUS "CMake 2.8.9 or higher is required by TokuDB")

View file

@ -422,6 +422,9 @@ static void print_db_env_struct (void) {
"int (*set_checkpoint_pool_threads)(DB_ENV *, uint32_t)",
"void (*set_check_thp)(DB_ENV *, bool new_val)",
"bool (*get_check_thp)(DB_ENV *)",
"bool (*set_dir_per_db)(DB_ENV *, bool new_val)",
"bool (*get_dir_per_db)(DB_ENV *)",
"const char *(*get_data_dir)(DB_ENV *env)",
NULL};
sort_and_dump_fields("db_env", true, extra);

View file

@ -97,7 +97,7 @@ if (NOT HAVE_BACKTRACE_WITHOUT_EXECINFO)
endif ()
endif ()
if(HAVE_CLOCK_REALTIME)
if(HAVE_CLOCK_REALTIME AND (NOT APPLE))
list(APPEND EXTRA_SYSTEM_LIBS rt)
else()
list(APPEND EXTRA_SYSTEM_LIBS System)
@ -109,6 +109,8 @@ check_function_exists(pthread_rwlockattr_setkind_np HAVE_PTHREAD_RWLOCKATTR_SETK
## check for the right way to yield using pthreads
check_function_exists(pthread_yield HAVE_PTHREAD_YIELD)
check_function_exists(pthread_yield_np HAVE_PTHREAD_YIELD_NP)
## check if we have pthread_threadid_np() (i.e. osx)
check_function_exists(pthread_threadid_np HAVE_PTHREAD_THREADID_NP)
## check if we have pthread_getthreadid_np() (i.e. freebsd)
check_function_exists(pthread_getthreadid_np HAVE_PTHREAD_GETTHREADID_NP)
check_function_exists(sched_getcpu HAVE_SCHED_GETCPU)

View file

@ -66,9 +66,7 @@ set_cflags_if_supported(
-Wno-error=address-of-array-temporary
-Wno-error=tautological-constant-out-of-range-compare
-Wno-error=maybe-uninitialized
-Wno-ignored-attributes
-Wno-error=extern-c-compat
-Wno-pointer-bool-conversion
-fno-rtti
-fno-exceptions
-Wno-error=nonnull-compare

View file

@ -138,6 +138,8 @@ struct cachefile {
// nor attempt to open any cachefile with the same fname (dname)
// until this cachefile has been fully closed and unlinked.
bool unlink_on_close;
// If set then fclose will not be logged in recovery log.
bool skip_log_recover_on_close;
int fd; /* Bug: If a file is opened read-only, then it is stuck in read-only. If it is opened read-write, then subsequent writers can write to it too. */
CACHETABLE cachetable;
struct fileid fileid;

View file

@ -467,6 +467,10 @@ toku_cachefile_fname_in_env (CACHEFILE cf) {
return cf->fname_in_env;
}
void toku_cachefile_set_fname_in_env(CACHEFILE cf, char *new_fname_in_env) {
cf->fname_in_env = new_fname_in_env;
}
int
toku_cachefile_get_fd (CACHEFILE cf) {
return cf->fd;
@ -2903,6 +2907,18 @@ bool toku_cachefile_is_unlink_on_close(CACHEFILE cf) {
return cf->unlink_on_close;
}
void toku_cachefile_skip_log_recover_on_close(CACHEFILE cf) {
cf->skip_log_recover_on_close = true;
}
void toku_cachefile_do_log_recover_on_close(CACHEFILE cf) {
cf->skip_log_recover_on_close = false;
}
bool toku_cachefile_is_skip_log_recover_on_close(CACHEFILE cf) {
return cf->skip_log_recover_on_close;
}
uint64_t toku_cachefile_size(CACHEFILE cf) {
int64_t file_size;
int fd = toku_cachefile_get_fd(cf);

View file

@ -500,12 +500,18 @@ int toku_cachefile_get_fd (CACHEFILE);
// Return the filename
char * toku_cachefile_fname_in_env (CACHEFILE cf);
void toku_cachefile_set_fname_in_env(CACHEFILE cf, char *new_fname_in_env);
// Make it so when the cachefile closes, the underlying file is unlinked
void toku_cachefile_unlink_on_close(CACHEFILE cf);
// is this cachefile marked as unlink on close?
bool toku_cachefile_is_unlink_on_close(CACHEFILE cf);
void toku_cachefile_skip_log_recover_on_close(CACHEFILE cf);
void toku_cachefile_do_log_recover_on_close(CACHEFILE cf);
bool toku_cachefile_is_skip_log_recover_on_close(CACHEFILE cf);
// Return the logger associated with the cachefile
struct tokulogger *toku_cachefile_logger(CACHEFILE cf);

View file

@ -149,22 +149,23 @@ basement nodes, bulk fetch, and partial fetch:
#include "ft/cachetable/checkpoint.h"
#include "ft/cursor.h"
#include "ft/ft.h"
#include "ft/ft-cachetable-wrappers.h"
#include "ft/ft-flusher.h"
#include "ft/ft-internal.h"
#include "ft/msg.h"
#include "ft/ft.h"
#include "ft/leafentry.h"
#include "ft/logger/log-internal.h"
#include "ft/msg.h"
#include "ft/node.h"
#include "ft/serialize/block_table.h"
#include "ft/serialize/sub_block.h"
#include "ft/serialize/ft-serialize.h"
#include "ft/serialize/ft_layout_version.h"
#include "ft/serialize/ft_node-serialize.h"
#include "ft/serialize/sub_block.h"
#include "ft/txn/txn_manager.h"
#include "ft/ule.h"
#include "ft/txn/xids.h"
#include "ft/ule.h"
#include "src/ydb-internal.h"
#include <toku_race_tools.h>
@ -179,6 +180,7 @@ basement nodes, bulk fetch, and partial fetch:
#include <stdint.h>
#include <memory>
/* Status is intended for display to humans to help understand system behavior.
* It does not need to be perfectly thread-safe.
*/
@ -2593,12 +2595,104 @@ static inline int ft_open_maybe_direct(const char *filename, int oflag, int mode
static const mode_t file_mode = S_IRUSR+S_IWUSR+S_IRGRP+S_IWGRP+S_IROTH+S_IWOTH;
inline bool toku_file_is_root(const char *path, const char *last_slash) {
return last_slash == path;
}
static std::unique_ptr<char[], decltype(&toku_free)> toku_file_get_parent_dir(
const char *path) {
std::unique_ptr<char[], decltype(&toku_free)> result(nullptr, &toku_free);
bool has_trailing_slash = false;
/* Find the offset of the last slash */
const char *last_slash = strrchr(path, OS_PATH_SEPARATOR);
if (!last_slash) {
/* No slash in the path, return NULL */
return result;
}
/* Ok, there is a slash. Is there anything after it? */
if (static_cast<size_t>(last_slash - path + 1) == strlen(path)) {
has_trailing_slash = true;
}
/* Reduce repetative slashes. */
while (last_slash > path && last_slash[-1] == OS_PATH_SEPARATOR) {
last_slash--;
}
/* Check for the root of a drive. */
if (toku_file_is_root(path, last_slash)) {
return result;
}
/* If a trailing slash prevented the first strrchr() from trimming
the last component of the path, trim that component now. */
if (has_trailing_slash) {
/* Back up to the previous slash. */
last_slash--;
while (last_slash > path && last_slash[0] != OS_PATH_SEPARATOR) {
last_slash--;
}
/* Reduce repetative slashes. */
while (last_slash > path && last_slash[-1] == OS_PATH_SEPARATOR) {
last_slash--;
}
}
/* Check for the root of a drive. */
if (toku_file_is_root(path, last_slash)) {
return result;
}
result.reset(toku_strndup(path, last_slash - path));
return result;
}
static bool toku_create_subdirs_if_needed(const char *path) {
static const mode_t dir_mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP |
S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH;
toku_struct_stat stat;
bool subdir_exists = true;
auto subdir = toku_file_get_parent_dir(path);
if (!subdir.get())
return true;
if (toku_stat(subdir.get(), &stat) == -1) {
if (ENOENT == get_error_errno())
subdir_exists = false;
else
return false;
}
if (subdir_exists) {
if (!S_ISDIR(stat.st_mode))
return false;
return true;
}
if (!toku_create_subdirs_if_needed(subdir.get()))
return false;
if (toku_os_mkdir(subdir.get(), dir_mode))
return false;
return true;
}
// open a file for use by the ft
// Requires: File does not exist.
static int ft_create_file(FT_HANDLE UU(ft_handle), const char *fname, int *fdp) {
int r;
int fd;
int er;
if (!toku_create_subdirs_if_needed(fname))
return get_error_errno();
fd = ft_open_maybe_direct(fname, O_RDWR | O_BINARY, file_mode);
assert(fd==-1);
if ((er = get_maybe_error_errno()) != ENOENT) {
@ -4427,6 +4521,55 @@ void toku_ft_unlink(FT_HANDLE handle) {
toku_cachefile_unlink_on_close(cf);
}
int toku_ft_rename_iname(DB_TXN *txn,
const char *data_dir,
const char *old_iname,
const char *new_iname,
CACHETABLE ct) {
int r = 0;
std::unique_ptr<char[], decltype(&toku_free)> new_iname_full(nullptr,
&toku_free);
std::unique_ptr<char[], decltype(&toku_free)> old_iname_full(nullptr,
&toku_free);
new_iname_full.reset(toku_construct_full_name(2, data_dir, new_iname));
old_iname_full.reset(toku_construct_full_name(2, data_dir, old_iname));
if (txn) {
BYTESTRING bs_old_name = {static_cast<uint32_t>(strlen(old_iname) + 1),
const_cast<char *>(old_iname)};
BYTESTRING bs_new_name = {static_cast<uint32_t>(strlen(new_iname) + 1),
const_cast<char *>(new_iname)};
FILENUM filenum = FILENUM_NONE;
{
CACHEFILE cf;
r = toku_cachefile_of_iname_in_env(ct, old_iname, &cf);
if (r != ENOENT) {
char *old_fname_in_cf = toku_cachefile_fname_in_env(cf);
toku_cachefile_set_fname_in_env(cf, toku_xstrdup(new_iname));
toku_free(old_fname_in_cf);
filenum = toku_cachefile_filenum(cf);
}
}
toku_logger_save_rollback_frename(
db_txn_struct_i(txn)->tokutxn, &bs_old_name, &bs_new_name);
toku_log_frename(db_txn_struct_i(txn)->tokutxn->logger,
(LSN *)0,
0,
toku_txn_get_txnid(db_txn_struct_i(txn)->tokutxn),
bs_old_name,
filenum,
bs_new_name);
}
r = toku_os_rename(old_iname_full.get(), new_iname_full.get());
if (r != 0)
return r;
r = toku_fsync_directory(new_iname_full.get());
return r;
}
int toku_ft_get_fragmentation(FT_HANDLE ft_handle, TOKU_DB_FRAGMENTATION report) {
int fd = toku_cachefile_get_fd(ft_handle->ft->cf);
toku_ft_lock(ft_handle->ft);

View file

@ -48,6 +48,8 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "ft/msg.h"
#include "util/dbt.h"
#define OS_PATH_SEPARATOR '/'
typedef struct ft_handle *FT_HANDLE;
int toku_open_ft_handle (const char *fname, int is_create, FT_HANDLE *, int nodesize, int basementnodesize, enum toku_compression_method compression_method, CACHETABLE, TOKUTXN, int(*)(DB *,const DBT*,const DBT*)) __attribute__ ((warn_unused_result));

View file

@ -253,7 +253,19 @@ static void ft_close(CACHEFILE cachefile, int fd, void *header_v, bool oplsn_val
char* fname_in_env = toku_cachefile_fname_in_env(cachefile);
assert(fname_in_env);
BYTESTRING bs = {.len=(uint32_t) strlen(fname_in_env), .data=fname_in_env};
toku_log_fclose(logger, &lsn, ft->h->dirty, bs, toku_cachefile_filenum(cachefile)); // flush the log on close (if new header is being written), otherwise it might not make it out.
if (!toku_cachefile_is_skip_log_recover_on_close(cachefile)) {
toku_log_fclose(
logger,
&lsn,
ft->h->dirty,
bs,
toku_cachefile_filenum(cachefile)); // flush the log on
// close (if new header
// is being written),
// otherwise it might
// not make it out.
toku_cachefile_do_log_recover_on_close(cachefile);
}
}
}
if (ft->h->dirty) { // this is the only place this bit is tested (in currentheader)

View file

@ -53,6 +53,12 @@ typedef struct ft_options *FT_OPTIONS;
void toku_ft_unlink(FT_HANDLE handle);
void toku_ft_unlink_on_commit(FT_HANDLE handle, TOKUTXN txn);
int toku_ft_rename_iname(DB_TXN *txn,
const char *data_dir,
const char *old_iname,
const char *new_iname,
CACHETABLE ct);
void toku_ft_init_reflock(FT ft);
void toku_ft_destroy_reflock(FT ft);
void toku_ft_grab_reflock(FT ft);

View file

@ -90,6 +90,10 @@ const struct logtype rollbacks[] = {
{"fcreate", 'F', FA{{"FILENUM", "filenum", 0},
{"BYTESTRING", "iname", 0},
NULLFIELD}, LOG_BEGIN_ACTION_NA},
//rename file
{"frename", 'n', FA{{"BYTESTRING", "old_iname", 0},
{"BYTESTRING", "new_iname", 0},
NULLFIELD}, LOG_BEGIN_ACTION_NA},
// cmdinsert is used to insert a key-value pair into a DB. For rollback we don't need the data.
{"cmdinsert", 'i', FA{
{"FILENUM", "filenum", 0},
@ -195,6 +199,11 @@ const struct logtype logtypes[] = {
{"fdelete", 'U', FA{{"TXNID_PAIR", "xid", 0},
{"FILENUM", "filenum", 0},
NULLFIELD}, SHOULD_LOG_BEGIN},
{"frename", 'n', FA{{"TXNID_PAIR", "xid", 0},
{"BYTESTRING", "old_iname", 0},
{"FILENUM", "old_filenum", 0},
{"BYTESTRING", "new_iname", 0},
NULLFIELD}, IGNORE_LOG_BEGIN},
{"enq_insert", 'I', FA{{"FILENUM", "filenum", 0},
{"TXNID_PAIR", "xid", 0},
{"BYTESTRING", "key", 0},

View file

@ -36,6 +36,7 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved."
#include <memory>
#include "ft/cachetable/cachetable.h"
#include "ft/cachetable/checkpoint.h"
#include "ft/ft.h"
@ -935,6 +936,83 @@ static int toku_recover_backward_fdelete (struct logtype_fdelete *UU(l), RECOVER
return 0;
}
static int toku_recover_frename(struct logtype_frename *l, RECOVER_ENV renv) {
assert(renv);
assert(renv->env);
toku_struct_stat stat;
const char *data_dir = renv->env->get_data_dir(renv->env);
bool old_exist = true;
bool new_exist = true;
assert(data_dir);
struct file_map_tuple *tuple;
std::unique_ptr<char[], decltype(&toku_free)> old_iname_full(
toku_construct_full_name(2, data_dir, l->old_iname.data), &toku_free);
std::unique_ptr<char[], decltype(&toku_free)> new_iname_full(
toku_construct_full_name(2, data_dir, l->new_iname.data), &toku_free);
if (toku_stat(old_iname_full.get(), &stat) == -1) {
if (ENOENT == errno)
old_exist = false;
else
return 1;
}
if (toku_stat(new_iname_full.get(), &stat) == -1) {
if (ENOENT == errno)
new_exist = false;
else
return 1;
}
// Both old and new files can exist if:
// - rename() is not completed
// - fcreate was replayed during recovery
// 'Stalled cachefiles' container cachefile_list::m_stale_fileid contains
// closed but not yet evicted cachefiles and the key of this container is
// fs-dependent file id - (device id, inode number) pair. As it is supposed
// new file have not yet created during recovery process the 'stalled
// cachefile' container can contain only cache file of old file.
// To preserve the old cachefile file's id and keep it in
// 'stalled cachefiles' container the new file is removed
// and the old file is renamed.
if (old_exist && new_exist &&
(toku_os_unlink(new_iname_full.get()) == -1 ||
toku_os_rename(old_iname_full.get(), new_iname_full.get()) == -1 ||
toku_fsync_directory(old_iname_full.get()) == -1 ||
toku_fsync_directory(new_iname_full.get()) == -1))
return 1;
if (old_exist && !new_exist &&
(toku_os_rename(old_iname_full.get(), new_iname_full.get()) == -1 ||
toku_fsync_directory(old_iname_full.get()) == -1 ||
toku_fsync_directory(new_iname_full.get()) == -1))
return 1;
if (file_map_find(&renv->fmap, l->old_filenum, &tuple) != DB_NOTFOUND) {
if (tuple->iname)
toku_free(tuple->iname);
tuple->iname = toku_xstrdup(l->new_iname.data);
}
TOKUTXN txn = NULL;
toku_txnid2txn(renv->logger, l->xid, &txn);
if (txn)
toku_logger_save_rollback_frename(txn, &l->old_iname, &l->new_iname);
return 0;
}
static int toku_recover_backward_frename(struct logtype_frename *UU(l),
RECOVER_ENV UU(renv)) {
// nothing
return 0;
}
static int toku_recover_enq_insert (struct logtype_enq_insert *l, RECOVER_ENV renv) {
int r;
TOKUTXN txn = NULL;

View file

@ -106,6 +106,7 @@ namespace MhsRbTree {
static const uint64_t MHS_MAX_VAL = 0xffffffffffffffff;
OUUInt64() : _value(0) {}
OUUInt64(uint64_t s) : _value(s) {}
OUUInt64(const OUUInt64& o) : _value(o._value) {}
bool operator<(const OUUInt64 &r) const {
invariant(!(_value == MHS_MAX_VAL && r.ToInt() == MHS_MAX_VAL));
return _value < r.ToInt();
@ -182,15 +183,18 @@ namespace MhsRbTree {
class Node {
public:
struct BlockPair {
class BlockPair {
public:
OUUInt64 _offset;
OUUInt64 _size;
BlockPair() : _offset(0), _size(0) {}
BlockPair(uint64_t o, uint64_t s) : _offset(o), _size(s) {}
BlockPair(OUUInt64 o, OUUInt64 s) : _offset(o), _size(s) {}
int operator<(const struct BlockPair &rhs) const {
BlockPair(const BlockPair &o)
: _offset(o._offset), _size(o._size) {}
int operator<(const BlockPair &rhs) const {
return _offset < rhs._offset;
}
int operator<(const uint64_t &o) const { return _offset < o; }
@ -203,15 +207,15 @@ namespace MhsRbTree {
};
EColor _color;
struct BlockPair _hole;
struct Pair _label;
BlockPair _hole;
Pair _label;
Node *_left;
Node *_right;
Node *_parent;
Node(EColor c,
Node::BlockPair h,
struct Pair lb,
Pair lb,
Node *l,
Node *r,
Node *p)

View file

@ -53,9 +53,10 @@ static void generate_random_input() {
std::srand(unsigned(std::time(0)));
// set some values:
for (uint64_t i = 1; i < N; ++i) {
input_vector.push_back({i, 0});
old_vector[i] = {i, 0};
for (uint64_t i = 0; i < N; ++i) {
MhsRbTree::Node::BlockPair bp = {i+1, 0};
input_vector.push_back(bp);
old_vector[i] = bp;
}
// using built-in random generator:
std::random_shuffle(input_vector.begin(), input_vector.end(), myrandom);

View file

@ -38,13 +38,13 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
/* rollback and rollforward routines. */
#include "ft/ft.h"
#include <memory>
#include "ft/ft-ops.h"
#include "ft/ft.h"
#include "ft/log_header.h"
#include "ft/logger/log-internal.h"
#include "ft/txn/xids.h"
#include "ft/txn/rollback-apply.h"
#include "ft/txn/xids.h"
// functionality provided by roll.c is exposed by an autogenerated
// header file, logheader.h
@ -162,10 +162,122 @@ toku_rollback_fcreate (FILENUM filenum,
// directory row lock for its dname) and we would not get this
// far if there were other live handles.
toku_cachefile_unlink_on_close(cf);
toku_cachefile_skip_log_recover_on_close(cf);
done:
return 0;
}
int toku_commit_frename(BYTESTRING /* old_name */,
BYTESTRING /* new_iname */,
TOKUTXN /* txn */,
LSN UU(oplsn)) {
return 0;
}
int toku_rollback_frename(BYTESTRING old_iname,
BYTESTRING new_iname,
TOKUTXN txn,
LSN UU(oplsn)) {
assert(txn);
assert(txn->logger);
assert(txn->logger->ct);
CACHETABLE cachetable = txn->logger->ct;
toku_struct_stat stat;
bool old_exist = true;
bool new_exist = true;
std::unique_ptr<char[], decltype(&toku_free)> old_iname_full(
toku_cachetable_get_fname_in_cwd(cachetable, old_iname.data),
&toku_free);
std::unique_ptr<char[], decltype(&toku_free)> new_iname_full(
toku_cachetable_get_fname_in_cwd(cachetable, new_iname.data),
&toku_free);
if (toku_stat(old_iname_full.get(), &stat) == -1) {
if (ENOENT == errno)
old_exist = false;
else
return 1;
}
if (toku_stat(new_iname_full.get(), &stat) == -1) {
if (ENOENT == errno)
new_exist = false;
else
return 1;
}
// Both old and new files can exist if:
// - rename() is not completed
// - fcreate was replayed during recovery
// 'Stalled cachefiles' container cachefile_list::m_stale_fileid contains
// closed but not yet evicted cachefiles and the key of this container is
// fs-dependent file id - (device id, inode number) pair. To preserve the
// new cachefile
// file's id and keep it in 'stalled cachefiles' container the old file is
// removed
// and the new file is renamed.
if (old_exist && new_exist &&
(toku_os_unlink(old_iname_full.get()) == -1 ||
toku_os_rename(new_iname_full.get(), old_iname_full.get()) == -1 ||
toku_fsync_directory(new_iname_full.get()) == -1 ||
toku_fsync_directory(old_iname_full.get()) == -1))
return 1;
if (!old_exist && new_exist &&
(toku_os_rename(new_iname_full.get(), old_iname_full.get()) == -1 ||
toku_fsync_directory(new_iname_full.get()) == -1 ||
toku_fsync_directory(old_iname_full.get()) == -1))
return 1;
// it's ok if both files do not exist on recovery
if (!old_exist && !new_exist)
assert(txn->for_recovery);
CACHEFILE cf;
int r = toku_cachefile_of_iname_in_env(cachetable, new_iname.data, &cf);
if (r != ENOENT) {
char *old_fname_in_cf = toku_cachefile_fname_in_env(cf);
toku_cachefile_set_fname_in_env(cf, toku_xstrdup(old_iname.data));
toku_free(old_fname_in_cf);
// There is at least one case when fclose logging cause error:
// 1) start transaction
// 2) create ft 'a'(write "fcreate" in recovery log)
// 3) rename ft 'a' to 'b'(write "frename" in recovery log)
// 4) abort transaction:
// a) rollback rename ft (renames 'b' to 'a')
// b) rollback create ft (removes 'a'):
// invokes toku_cachefile_unlink_on_close - lazy unlink on file
// close,
// it just sets corresponding flag in cachefile object
// c) write "unlink" for 'a' in recovery log
// (when transaction is aborted all locks are released,
// when file lock is released the file is closed and unlinked if
// corresponding flag is set in cachefile object)
// 5) crash
//
// After this we have the following records in recovery log:
// - create ft 'a',
// - rename 'a' to 'b',
// - unlink 'a'
//
// On recovery:
// - create 'a'
// - rename 'a' to 'b'
// - unlink 'a' - as 'a' file does not exist we have crash on assert
// here
//
// There is no need to write "unlink" in recovery log in (4a) because
// 'a' will be removed
// on transaction rollback on recovery.
toku_cachefile_skip_log_recover_on_close(cf);
}
return 0;
}
int find_ft_from_filenum (const FT &ft, const FILENUM &filenum);
int find_ft_from_filenum (const FT &ft, const FILENUM &filenum) {
FILENUM thisfnum = toku_cachefile_filenum(ft->cf);

View file

@ -356,6 +356,12 @@ toku_os_close(int fd) { // if EINTR, retry until success
return r;
}
int toku_os_rename(const char *old_name, const char *new_name) {
return rename(old_name, new_name);
}
int toku_os_unlink(const char *path) { return unlink(path); }
ssize_t
toku_os_read(int fd, void *buf, size_t count) {
ssize_t r;

View file

@ -313,6 +313,15 @@ toku_strdup(const char *s) {
return (char *) toku_memdup(s, strlen(s)+1);
}
char *toku_strndup(const char *s, size_t n) {
size_t s_size = strlen(s);
size_t bytes_to_copy = n > s_size ? s_size : n;
++bytes_to_copy;
char *result = (char *)toku_memdup(s, bytes_to_copy);
result[bytes_to_copy - 1] = 0;
return result;
}
void
toku_free(void *p) {
if (p) {

View file

@ -125,7 +125,9 @@ size_t toku_malloc_usable_size(void *p) __attribute__((__visibility__("default")
void *toku_memdup (const void *v, size_t len);
/* Toku-version of strdup. Use this so that it calls toku_malloc() */
char *toku_strdup (const char *s) __attribute__((__visibility__("default")));
/* Toku-version of strndup. Use this so that it calls toku_malloc() */
char *toku_strndup(const char *s, size_t n)
__attribute__((__visibility__("default")));
/* Copy memory. Analogous to strdup() Crashes instead of returning NULL */
void *toku_xmemdup (const void *v, size_t len) __attribute__((__visibility__("default")));
/* Toku-version of strdup. Use this so that it calls toku_xmalloc() Crashes instead of returning NULL */

View file

@ -63,6 +63,9 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#if defined(HAVE_SYS_SYSCTL_H)
# include <sys/sysctl.h>
#endif
#if defined(HAVE_PTHREAD_H)
# include <pthread.h>
#endif
#if defined(HAVE_PTHREAD_NP_H)
# include <pthread_np.h>
#endif
@ -102,7 +105,11 @@ toku_os_getpid(void) {
int
toku_os_gettid(void) {
#if defined(__NR_gettid)
#if defined(HAVE_PTHREAD_THREADID_NP)
uint64_t result;
pthread_threadid_np(NULL, &result);
return (int) result; // Used for instrumentation so overflow is ok here.
#elif defined(__NR_gettid)
return syscall(__NR_gettid);
#elif defined(SYS_gettid)
return syscall(SYS_gettid);

View file

@ -51,11 +51,18 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#if defined(HAVE_PTHREAD_NP_H)
# include <pthread_np.h>
#endif
#if defined(HAVE_PTHREAD_H)
# include <pthread.h>
#endif
// since we implement the same thing here as in toku_os_gettid, this test
// is pretty pointless
static int gettid(void) {
#if defined(__NR_gettid)
#if defined(HAVE_PTHREAD_THREADID_NP)
uint64_t result;
pthread_threadid_np(NULL, &result);
return (int) result;
#elif defined(__NR_gettid)
return syscall(__NR_gettid);
#elif defined(SYS_gettid)
return syscall(SYS_gettid);

View file

@ -87,6 +87,7 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#cmakedefine HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP 1
#cmakedefine HAVE_PTHREAD_YIELD 1
#cmakedefine HAVE_PTHREAD_YIELD_NP 1
#cmakedefine HAVE_PTHREAD_THREADID_NP 1
#cmakedefine HAVE_PTHREAD_GETTHREADID_NP 1
#cmakedefine PTHREAD_YIELD_RETURNS_INT 1

View file

@ -246,6 +246,8 @@ int toku_os_open(const char *path, int oflag, int mode);
int toku_os_open_direct(const char *path, int oflag, int mode);
int toku_os_close(int fd);
int toku_os_fclose(FILE * stream);
int toku_os_rename(const char *old_name, const char *new_name);
int toku_os_unlink(const char *path);
ssize_t toku_os_read(int fd, void *buf, size_t count);
ssize_t toku_os_pread(int fd, void *buf, size_t count, off_t offset);
void toku_os_recursive_delete(const char *path);

View file

@ -108,11 +108,11 @@ if(BUILD_TESTING OR BUILD_SRC_TESTS)
foreach(ov c d r)
if (ov STREQUAL c)
set(gset 0)
set(hset 0)
set(iset 0)
else ()
set(gset 0 1 2 3 4 5)
set(hset 0 1)
set(hset 0 1 2 3 4 5)
set(iset 0 1)
endif ()
foreach(av 0 1)
@ -130,25 +130,27 @@ if(BUILD_TESTING OR BUILD_SRC_TESTS)
foreach(dv ${dset})
foreach(ev ${eset})
foreach(fv 0 1)
foreach(gv ${gset})
foreach(gv 0 1)
foreach(hv ${hset})
if ((NOT ov STREQUAL c) AND (NOT cv) AND ((NOT bv) OR (NOT ev) OR (dv)))
set(iset 0 1)
else ()
set(iset 0)
endif ()
foreach(iv ${iset})
set(testname "ydb/recovery_fileops_unit.${ov}${av}${bv}${cv}${dv}${ev}${fv}${gv}${hv}${iv}")
set(envdir "recovery_fileops_unit_dir/${ov}${av}${bv}${cv}${dv}${ev}${fv}${gv}${hv}${iv}")
set(errfile "recovery_fileops_unit_dir/${ov}${av}${bv}${cv}${dv}${ev}${fv}${gv}${hv}${iv}.ctest-errors")
add_test(NAME ${testname}
COMMAND run_recovery_fileops_unit.sh $<TARGET_FILE:recovery_fileops_unit.tdb> ${errfile} 137
-O ${ov} -A ${av} -B ${bv} -C ${cv} -D ${dv} -E ${ev} -F ${fv} -G ${gv} -H ${hv} -I ${iv}
)
setup_toku_test_properties(${testname} ${envdir})
set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${errfile}")
if ((NOT ov STREQUAL c) AND (NOT cv) AND ((NOT bv) OR (NOT ev) OR (dv)))
set(jset 0 1)
else ()
set(jset 0)
endif ()
foreach(jv ${jset})
set(testname "ydb/recovery_fileops_unit.${ov}${av}${bv}${cv}${dv}${ev}${fv}${gv}${hv}${iv}${jv}")
set(envdir "recovery_fileops_unit_dir/${ov}${av}${bv}${cv}${dv}${ev}${fv}${gv}${hv}${iv}${jv}")
set(errfile "recovery_fileops_unit_dir/${ov}${av}${bv}${cv}${dv}${ev}${fv}${gv}${hv}${iv}${jv}.ctest-errors")
add_test(NAME ${testname}
COMMAND run_recovery_fileops_unit.sh $<TARGET_FILE:recovery_fileops_unit.tdb> ${errfile} 137
-O ${ov} -A ${av} -B ${bv} -C ${cv} -D ${dv} -E ${ev} -F ${fv} -G ${gv} -H ${hv} -I ${iv} -J ${jv}
)
setup_toku_test_properties(${testname} ${envdir})
set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${errfile}")
endforeach(jv)
endforeach(iv)
endforeach(hv)
endforeach(gv)

Some files were not shown because too many files have changed in this diff Show more