mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 02:05:57 +01:00
Merge branch '10.0-galera' into 10.1
This commit is contained in:
commit
a98c85bb50
162 changed files with 5637 additions and 870 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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-----
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include "rsa.h"
|
||||
|
||||
|
||||
#define YASSL_VERSION "2.3.9b"
|
||||
#define YASSL_VERSION "2.4.2"
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1281,6 +1281,9 @@ int dsa_test()
|
|||
if (!verifier.Verify(digest, decoded))
|
||||
return -90;
|
||||
|
||||
if (!verifier.Verify(digest, signature))
|
||||
return -91;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) +\
|
||||
|
|
|
@ -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) +\
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<<
|
||||
|
|
|
@ -3,3 +3,9 @@ a
|
|||
1
|
||||
|
||||
End of tests
|
||||
1
|
||||
1
|
||||
2
|
||||
2
|
||||
X
|
||||
3
|
||||
|
|
126
mysql-test/r/mysqldump-nl.result
Normal file
126
mysql-test/r/mysqldump-nl.result
Normal 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`;
|
|
@ -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` (
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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`;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
6
mysql-test/suite/rpl/r/rpl_stop_slave_error.result
Normal file
6
mysql-test/suite/rpl/r/rpl_stop_slave_error.result
Normal 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
|
|
@ -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;
|
||||
|
|
1
mysql-test/suite/rpl/t/rpl_stop_slave_error-slave.opt
Normal file
1
mysql-test/suite/rpl/t/rpl_stop_slave_error-slave.opt
Normal file
|
@ -0,0 +1 @@
|
|||
--log-error=$MYSQLTEST_VARDIR/tmp/slave_log.err
|
17
mysql-test/suite/rpl/t/rpl_stop_slave_error.test
Normal file
17
mysql-test/suite/rpl/t/rpl_stop_slave_error.test
Normal 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;
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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";
|
||||
|
|
38
mysql-test/t/mysqldump-nl.test
Normal file
38
mysql-test/t/mysqldump-nl.test
Normal 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`;
|
|
@ -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
|
||||
# ----------------------------------------------------------------------------
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 #
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
/*
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
Loading…
Add table
Reference in a new issue