mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Merge remote-tracking branch 'origin/10.2' into bb-10.2-ext
This commit is contained in:
@ -117,6 +117,7 @@ xb_mysql_connect()
|
||||
mysql_options(connection, MYSQL_PLUGIN_DIR, xb_plugin_dir);
|
||||
}
|
||||
mysql_options(connection, MYSQL_OPT_PROTOCOL, &opt_protocol);
|
||||
mysql_options(connection,MYSQL_SET_CHARSET_NAME, "utf8");
|
||||
|
||||
msg_ts("Connecting to MySQL server host: %s, user: %s, password: %s, "
|
||||
"port: %s, socket: %s\n", opt_host ? opt_host : "localhost",
|
||||
@ -1629,3 +1630,96 @@ backup_cleanup()
|
||||
mysql_close(mysql_connection);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static pthread_mutex_t mdl_lock_con_mutex;
|
||||
static MYSQL *mdl_con = NULL;
|
||||
|
||||
void
|
||||
mdl_lock_init()
|
||||
{
|
||||
pthread_mutex_init(&mdl_lock_con_mutex, NULL);
|
||||
mdl_con = xb_mysql_connect();
|
||||
if (mdl_con)
|
||||
{
|
||||
xb_mysql_query(mdl_con, "BEGIN", false, true);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef DBUF_OFF
|
||||
/* Test that table is really locked, if lock_ddl_per_table is set.
|
||||
The test is executed in DBUG_EXECUTE_IF block inside mdl_lock_table().
|
||||
*/
|
||||
static void check_mdl_lock_works(const char *table_name)
|
||||
{
|
||||
MYSQL *test_con= xb_mysql_connect();
|
||||
char *query;
|
||||
xb_a(asprintf(&query,
|
||||
"SET STATEMENT max_statement_time=1 FOR ALTER TABLE %s"
|
||||
" ADD COLUMN mdl_lock_column int", table_name));
|
||||
int err = mysql_query(test_con, query);
|
||||
DBUG_ASSERT(err);
|
||||
int err_no = mysql_errno(test_con);
|
||||
DBUG_ASSERT(err_no == ER_STATEMENT_TIMEOUT);
|
||||
mysql_close(test_con);
|
||||
}
|
||||
#endif
|
||||
|
||||
extern void
|
||||
dict_fs2utf8(const char*, char*, size_t, char*, size_t);
|
||||
|
||||
void
|
||||
mdl_lock_table(ulint space_id)
|
||||
{
|
||||
char *query;
|
||||
|
||||
pthread_mutex_lock(&mdl_lock_con_mutex);
|
||||
|
||||
xb_a(asprintf(&query,
|
||||
"SELECT NAME FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES "
|
||||
"WHERE SPACE = %llu AND NAME LIKE '%%/%%'", (ulonglong)space_id));
|
||||
|
||||
xb_mysql_query(mdl_con, query, true, true);
|
||||
|
||||
MYSQL_RES *mysql_result = xb_mysql_query(mdl_con, query, true);
|
||||
|
||||
MYSQL_ROW row;
|
||||
while ((row = mysql_fetch_row(mysql_result))) {
|
||||
char full_table_name[2*FN_REFLEN +2];
|
||||
char db_utf8[FN_REFLEN];
|
||||
char table_utf8[FN_REFLEN];
|
||||
|
||||
dict_fs2utf8(row[0], db_utf8, sizeof(db_utf8),table_utf8,sizeof(table_utf8));
|
||||
snprintf(full_table_name,sizeof(full_table_name),"`%s`.`%s`",db_utf8,table_utf8);
|
||||
|
||||
char *lock_query;
|
||||
|
||||
msg_ts("Locking MDL for %s\n", full_table_name);
|
||||
|
||||
xb_a(asprintf(&lock_query,
|
||||
"SELECT * FROM %s LIMIT 0",
|
||||
full_table_name));
|
||||
|
||||
xb_mysql_query(mdl_con, lock_query, false, false);
|
||||
|
||||
free(lock_query);
|
||||
|
||||
DBUG_EXECUTE_IF("check_mdl_lock_works",
|
||||
check_mdl_lock_works(full_table_name););
|
||||
}
|
||||
|
||||
mysql_free_result(mysql_result);
|
||||
free(query);
|
||||
pthread_mutex_unlock(&mdl_lock_con_mutex);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mdl_unlock_all()
|
||||
{
|
||||
msg_ts("Unlocking MDL for all tables");
|
||||
xb_mysql_query(mdl_con, "COMMIT", false, true);
|
||||
mysql_close(mdl_con);
|
||||
pthread_mutex_destroy(&mdl_lock_con_mutex);
|
||||
}
|
||||
|
||||
|
@ -296,6 +296,8 @@ my_bool opt_noversioncheck = FALSE;
|
||||
my_bool opt_no_backup_locks = FALSE;
|
||||
my_bool opt_decompress = FALSE;
|
||||
|
||||
my_bool opt_lock_ddl_per_table = FALSE;
|
||||
|
||||
static const char *binlog_info_values[] = {"off", "lockless", "on", "auto",
|
||||
NullS};
|
||||
static TYPELIB binlog_info_typelib = {array_elements(binlog_info_values)-1, "",
|
||||
@ -537,7 +539,8 @@ enum options_xtrabackup
|
||||
|
||||
OPT_XTRA_TABLES_EXCLUDE,
|
||||
OPT_XTRA_DATABASES_EXCLUDE,
|
||||
OPT_PROTOCOL
|
||||
OPT_PROTOCOL,
|
||||
OPT_LOCK_DDL_PER_TABLE
|
||||
};
|
||||
|
||||
struct my_option xb_client_options[] =
|
||||
@ -1072,6 +1075,11 @@ struct my_option xb_server_options[] =
|
||||
(G_PTR*) &xb_open_files_limit, (G_PTR*) &xb_open_files_limit, 0, GET_ULONG,
|
||||
REQUIRED_ARG, 0, 0, UINT_MAX, 0, 1, 0},
|
||||
|
||||
{"lock-ddl-per-table", OPT_LOCK_DDL_PER_TABLE, "Lock DDL for each table "
|
||||
"before xtrabackup starts to copy it and until the backup is completed.",
|
||||
(uchar*) &opt_lock_ddl_per_table, (uchar*) &opt_lock_ddl_per_table, 0,
|
||||
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
|
||||
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
@ -2205,6 +2213,10 @@ xtrabackup_copy_datafile(fil_node_t* node, uint thread_n)
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
if (opt_lock_ddl_per_table) {
|
||||
mdl_lock_table(node->space->id);
|
||||
}
|
||||
|
||||
if (!changed_page_bitmap) {
|
||||
read_filter = &rf_pass_through;
|
||||
}
|
||||
@ -2347,10 +2359,18 @@ xtrabackup_copy_log(copy_logfile copy, lsn_t start_lsn, lsn_t end_lsn)
|
||||
|
||||
scanned_checkpoint = checkpoint;
|
||||
ulint data_len = log_block_get_data_len(log_block);
|
||||
scanned_lsn += data_len;
|
||||
|
||||
if (data_len != OS_FILE_LOG_BLOCK_SIZE) {
|
||||
/* The current end of the log was reached. */
|
||||
if (data_len == OS_FILE_LOG_BLOCK_SIZE) {
|
||||
/* We got a full log block. */
|
||||
scanned_lsn += data_len;
|
||||
} else if (data_len
|
||||
>= OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE
|
||||
|| data_len <= LOG_BLOCK_HDR_SIZE) {
|
||||
/* We got a garbage block (abrupt end of the log). */
|
||||
break;
|
||||
} else {
|
||||
/* We got a partial block (abrupt end of the log). */
|
||||
scanned_lsn += data_len;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2363,7 +2383,7 @@ xtrabackup_copy_log(copy_logfile copy, lsn_t start_lsn, lsn_t end_lsn)
|
||||
|
||||
if (ulint write_size = ulint(end_lsn - start_lsn)) {
|
||||
if (srv_encrypt_log) {
|
||||
log_crypt(log_sys->buf, write_size);
|
||||
log_crypt(log_sys->buf, start_lsn, write_size);
|
||||
}
|
||||
|
||||
if (ds_write(dst_log_file, log_sys->buf, write_size)) {
|
||||
@ -3552,6 +3572,10 @@ xtrabackup_backup_func()
|
||||
"or RENAME TABLE during the backup, inconsistent backup will be "
|
||||
"produced.\n");
|
||||
|
||||
if (opt_lock_ddl_per_table) {
|
||||
mdl_lock_init();
|
||||
}
|
||||
|
||||
/* initialize components */
|
||||
if(innodb_init_param()) {
|
||||
fail:
|
||||
@ -3741,10 +3765,10 @@ old_format:
|
||||
|
||||
const byte* buf = log_sys->checkpoint_buf;
|
||||
|
||||
checkpoint_lsn_start = mach_read_from_8(buf + LOG_CHECKPOINT_LSN);
|
||||
checkpoint_no_start = mach_read_from_8(buf + LOG_CHECKPOINT_NO);
|
||||
|
||||
reread_log_header:
|
||||
checkpoint_lsn_start = log_sys->log.lsn;
|
||||
checkpoint_no_start = log_sys->next_checkpoint_no;
|
||||
|
||||
err = recv_find_max_checkpoint(&max_cp_field);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
@ -3758,10 +3782,9 @@ reread_log_header:
|
||||
ut_ad(!((log_sys->log.format ^ LOG_HEADER_FORMAT_CURRENT)
|
||||
& ~LOG_HEADER_FORMAT_ENCRYPTED));
|
||||
|
||||
if (checkpoint_no_start != mach_read_from_8(buf + LOG_CHECKPOINT_NO)) {
|
||||
log_group_header_read(&log_sys->log, max_cp_field);
|
||||
|
||||
checkpoint_lsn_start = mach_read_from_8(buf + LOG_CHECKPOINT_LSN);
|
||||
checkpoint_no_start = mach_read_from_8(buf + LOG_CHECKPOINT_NO);
|
||||
if (checkpoint_no_start != mach_read_from_8(buf + LOG_CHECKPOINT_NO)) {
|
||||
goto reread_log_header;
|
||||
}
|
||||
|
||||
@ -3930,6 +3953,10 @@ reread_log_header:
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (opt_lock_ddl_per_table) {
|
||||
mdl_unlock_all();
|
||||
}
|
||||
|
||||
xtrabackup_destroy_datasinks();
|
||||
|
||||
msg("xtrabackup: Redo log (from LSN " LSN_PF " to " LSN_PF
|
||||
|
@ -193,4 +193,8 @@ xb_get_one_option(int optid,
|
||||
const char*
|
||||
xb_get_copy_action(const char *dflt = "Copying");
|
||||
|
||||
void mdl_lock_init();
|
||||
void mdl_lock_table(ulint space_id);
|
||||
void mdl_unlock_all();
|
||||
|
||||
#endif /* XB_XTRABACKUP_H */
|
||||
|
@ -669,6 +669,36 @@ JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = 1
|
||||
select JSON_EXTRACT('{\"input1\":\"\\u00f6\"}', '$.\"input1\"');
|
||||
JSON_EXTRACT('{\"input1\":\"\\u00f6\"}', '$.\"input1\"')
|
||||
"\u00f6"
|
||||
select JSON_EXTRACT('{"foo": "bar" foobar foo invalid ', '$.foo');
|
||||
JSON_EXTRACT('{"foo": "bar" foobar foo invalid ', '$.foo')
|
||||
NULL
|
||||
Warnings:
|
||||
Warning 4038 Syntax error in JSON text in argument 1 to function 'json_extract' at position 15
|
||||
SELECT JSON_OBJECT('foo', '`');
|
||||
JSON_OBJECT('foo', '`')
|
||||
{"foo": "`"}
|
||||
SELECT JSON_OBJECT("foo", "bar`bar");
|
||||
JSON_OBJECT("foo", "bar`bar")
|
||||
{"foo": "bar`bar"}
|
||||
SELECT JSON_SET('{}', '$.age', 87);
|
||||
JSON_SET('{}', '$.age', 87)
|
||||
{"age": 87}
|
||||
SELECT JSON_MERGE('[]', '{"c":"d"}');
|
||||
JSON_MERGE('[]', '{"c":"d"}')
|
||||
[{"c": "d"}]
|
||||
SET @str = "{\"\\u00e4\\u00f6\":\"yes\"}";
|
||||
SET @path = "$.\"\\u00e4\\u00f6\"";
|
||||
select @str, @path, JSON_EXTRACT(@str, @path);
|
||||
@str @path JSON_EXTRACT(@str, @path)
|
||||
{"\u00e4\u00f6":"yes"} $."\u00e4\u00f6" "yes"
|
||||
SET @str = "{\"\\u00e4\":\"yes\"}";
|
||||
SET @path = "$.\"\\u00e4\"";
|
||||
select @str, @path, JSON_EXTRACT(@str, @path);
|
||||
@str @path JSON_EXTRACT(@str, @path)
|
||||
{"\u00e4":"yes"} $."\u00e4" "yes"
|
||||
select json_array(5,json_query('[1,2]','$'));
|
||||
json_array(5,json_query('[1,2]','$'))
|
||||
[5, [1,2]]
|
||||
#
|
||||
# Start of 10.3 tests
|
||||
#
|
||||
|
@ -6638,6 +6638,29 @@ drop table procViewTable;
|
||||
use test;
|
||||
drop database bugTest;
|
||||
#
|
||||
# MDEV-13436: PREPARE doesn't work as expected & throws errors but
|
||||
# MySQL is working fine
|
||||
#
|
||||
create table t1 (a int);
|
||||
insert into t1 values (1),(2);
|
||||
SET @sql_query = "
|
||||
CREATE VIEW v1 AS
|
||||
SELECT * FROM (
|
||||
SELECT CASE WHEN 1 IN (SELECT a from t1 where a < 2) THEN TRUE END AS testcase
|
||||
) testalias
|
||||
";
|
||||
PREPARE stmt FROM @sql_query;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
show create view v1;
|
||||
View Create View character_set_client collation_connection
|
||||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `testalias`.`testcase` AS `testcase` from (select case when 1 in (select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` < 2) then 1 end AS `testcase`) `testalias` latin1 latin1_swedish_ci
|
||||
SELECT * FROM v1;
|
||||
testcase
|
||||
1
|
||||
drop view v1;
|
||||
drop table t1;
|
||||
#
|
||||
# End of 10.2 tests
|
||||
#
|
||||
#
|
||||
|
@ -56,6 +56,7 @@ INSERT INTO t1 VALUES("left3", ST_GeomFromText('POLYGON (( -3 0, -3 2, -1 2, -1
|
||||
SET @p = ST_GeomFromText('POLYGON (( 0 0, 0 2, 2 2, 2 0, 0 0))');
|
||||
SELECT name, ST_AsText(square) from t1 where MBRContains(@p, square);
|
||||
name ST_AsText(square)
|
||||
small POLYGON((0 0,0 1,1 1,1 0,0 0))
|
||||
SELECT name, ST_AsText(square) from t1 where MBRDisjoint(@p, square);
|
||||
name ST_AsText(square)
|
||||
up3 POLYGON((0 3,0 5,2 5,2 3,0 3))
|
||||
@ -90,6 +91,7 @@ down2 POLYGON((0 -2,0 0,2 0,2 -2,0 -2))
|
||||
left2 POLYGON((-2 0,-2 2,0 2,0 0,-2 0))
|
||||
SELECT name, ST_AsText(square) from t1 where MBRWithin(@p, square);
|
||||
name ST_AsText(square)
|
||||
big POLYGON((0 0,0 3,3 3,3 0,0 0))
|
||||
SET @vert1 = ST_GeomFromText('POLYGON ((0 -2, 0 2, 0 -2))');
|
||||
SET @horiz1 = ST_GeomFromText('POLYGON ((-2 0, 2 0, -2 0))');
|
||||
SET @horiz2 = ST_GeomFromText('POLYGON ((-1 0, 3 0, -1 0))');
|
||||
@ -217,7 +219,7 @@ SELECT COUNT(*)
|
||||
FROM t1
|
||||
WHERE ST_CONTAINS(ST_GeomFromText('POLYGON((2 2,4 2, 4 4, 2 4, 2 2))'),way);
|
||||
COUNT(*)
|
||||
0
|
||||
9
|
||||
OPTIMIZE TABLE t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
|
||||
@ -226,7 +228,7 @@ SELECT COUNT(*)
|
||||
FROM t1
|
||||
WHERE ST_CONTAINS(ST_GeomFromText('POLYGON((2 2,4 2, 4 4, 2 4, 2 2))'),way);
|
||||
COUNT(*)
|
||||
0
|
||||
9
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1( i INT, g GEOMETRY NOT NULL, SPATIAL INDEX (g)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES(1, LINESTRING(POINT(1,1), POINT(4, 4)));
|
||||
|
@ -2109,10 +2109,9 @@ ERROR 42000: Incorrect parameter count in the call to native function 'json_set'
|
||||
error ER_INVALID_JSON_TEXT_IN_PARAM
|
||||
SELECT JSON_SET('{}', '$.name', JSON_EXTRACT('', '$'));
|
||||
JSON_SET('{}', '$.name', JSON_EXTRACT('', '$'))
|
||||
NULL
|
||||
{"name": null}
|
||||
Warnings:
|
||||
Warning 4037 Unexpected end of JSON text in argument 1 to function 'json_extract'
|
||||
Warning 4038 Syntax error in JSON text in argument 1 to function 'json_set' at position 2
|
||||
select json_set('[1,2,3]', '$[2]', 4);
|
||||
json_set('[1,2,3]', '$[2]', 4)
|
||||
[1, 2, 4]
|
||||
|
4
mysql-test/suite/mariabackup/lock_ddl_per_table.result
Normal file
4
mysql-test/suite/mariabackup/lock_ddl_per_table.result
Normal file
@ -0,0 +1,4 @@
|
||||
CREATE TABLE t(i INT) ENGINE INNODB;
|
||||
INSERT INTO t VALUES(1);
|
||||
# xtrabackup backup
|
||||
DROP TABLE t;
|
12
mysql-test/suite/mariabackup/lock_ddl_per_table.test
Normal file
12
mysql-test/suite/mariabackup/lock_ddl_per_table.test
Normal file
@ -0,0 +1,12 @@
|
||||
--source include/have_debug.inc
|
||||
|
||||
CREATE TABLE t(i INT) ENGINE INNODB;
|
||||
INSERT INTO t VALUES(1);
|
||||
echo # xtrabackup backup;
|
||||
let $targetdir=$MYSQLTEST_VARDIR/tmp/backup;
|
||||
|
||||
--disable_result_log
|
||||
exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir --lock-ddl-per-table=1 --dbug=+d,check_mdl_lock_works;
|
||||
--enable_result_log
|
||||
DROP TABLE t;
|
||||
rmdir $targetdir;
|
@ -1 +1 @@
|
||||
--innodb --loose-changed_page_bitmaps --innodb-file-format=Barracuda
|
||||
--innodb --loose-changed_page_bitmaps --innodb-file-format=Barracuda --innodb-sys-tables
|
@ -317,6 +317,44 @@ select JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = false;
|
||||
select JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = 1;
|
||||
select JSON_EXTRACT('{\"input1\":\"\\u00f6\"}', '$.\"input1\"');
|
||||
|
||||
#
|
||||
# MDEV-129892 JSON_EXTRACT returns data for invalid JSON
|
||||
#
|
||||
select JSON_EXTRACT('{"foo": "bar" foobar foo invalid ', '$.foo');
|
||||
|
||||
#
|
||||
# MDEV-13138 JSON_OBJECT returns null with strings containing backticks.
|
||||
#
|
||||
SELECT JSON_OBJECT('foo', '`');
|
||||
SELECT JSON_OBJECT("foo", "bar`bar");
|
||||
|
||||
#
|
||||
# MDEV-13324 JSON_SET returns NULL instead of object.
|
||||
#
|
||||
SELECT JSON_SET('{}', '$.age', 87);
|
||||
|
||||
#
|
||||
# MDEV-13104 Json functions.
|
||||
#
|
||||
SELECT JSON_MERGE('[]', '{"c":"d"}');
|
||||
|
||||
#
|
||||
# MDEV-12774 JSON_EXTRACT fails with some escaped unicode as key.
|
||||
#
|
||||
|
||||
SET @str = "{\"\\u00e4\\u00f6\":\"yes\"}";
|
||||
SET @path = "$.\"\\u00e4\\u00f6\"";
|
||||
select @str, @path, JSON_EXTRACT(@str, @path);
|
||||
SET @str = "{\"\\u00e4\":\"yes\"}";
|
||||
SET @path = "$.\"\\u00e4\"";
|
||||
select @str, @path, JSON_EXTRACT(@str, @path);
|
||||
|
||||
#
|
||||
# MDEV-12877 Wrong result from JSON native function.
|
||||
#
|
||||
select json_array(5,json_query('[1,2]','$'));
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Start of 10.3 tests
|
||||
--echo #
|
||||
|
@ -6350,6 +6350,27 @@ drop table procViewTable;
|
||||
use test;
|
||||
drop database bugTest;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-13436: PREPARE doesn't work as expected & throws errors but
|
||||
--echo # MySQL is working fine
|
||||
--echo #
|
||||
|
||||
create table t1 (a int);
|
||||
insert into t1 values (1),(2);
|
||||
SET @sql_query = "
|
||||
CREATE VIEW v1 AS
|
||||
SELECT * FROM (
|
||||
SELECT CASE WHEN 1 IN (SELECT a from t1 where a < 2) THEN TRUE END AS testcase
|
||||
) testalias
|
||||
";
|
||||
PREPARE stmt FROM @sql_query;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
show create view v1;
|
||||
SELECT * FROM v1;
|
||||
drop view v1;
|
||||
drop table t1;
|
||||
|
||||
--echo #
|
||||
--echo # End of 10.2 tests
|
||||
--echo #
|
||||
|
@ -550,7 +550,18 @@ public:
|
||||
maybe_null= true;
|
||||
}
|
||||
enum Functype functype() const { return spatial_rel; }
|
||||
enum Functype rev_functype() const { return spatial_rel; }
|
||||
enum Functype rev_functype() const
|
||||
{
|
||||
switch (spatial_rel)
|
||||
{
|
||||
case SP_CONTAINS_FUNC:
|
||||
return SP_WITHIN_FUNC;
|
||||
case SP_WITHIN_FUNC:
|
||||
return SP_CONTAINS_FUNC;
|
||||
default:
|
||||
return spatial_rel;
|
||||
}
|
||||
}
|
||||
bool is_null() { (void) val_int(); return null_value; }
|
||||
void add_key_fields(JOIN *join, KEY_FIELD **key_fields,
|
||||
uint *and_level, table_map usable_tables,
|
||||
|
@ -650,6 +650,7 @@ static int alloc_tmp_paths(THD *thd, uint n_paths,
|
||||
if (*tmp_paths == 0)
|
||||
{
|
||||
MEM_ROOT *root= thd->stmt_arena->mem_root;
|
||||
|
||||
*paths= (json_path_with_flags *) alloc_root(root,
|
||||
sizeof(json_path_with_flags) * n_paths);
|
||||
*tmp_paths= (String *) alloc_root(root, sizeof(String) * n_paths);
|
||||
@ -657,6 +658,8 @@ static int alloc_tmp_paths(THD *thd, uint n_paths,
|
||||
return 1;
|
||||
|
||||
bzero(*tmp_paths, sizeof(String) * n_paths);
|
||||
for (uint c_path=0; c_path < n_paths; c_path++)
|
||||
(*tmp_paths)[c_path].set_charset(&my_charset_utf8_general_ci);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -821,8 +824,12 @@ String *Item_func_json_extract::read_json(String *str,
|
||||
not_first_value= 1;
|
||||
|
||||
if (!possible_multiple_values)
|
||||
{
|
||||
/* Loop to the end of the JSON just to make sure it's valid. */
|
||||
while (json_get_path_next(&je, &p) == 0) {}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (je.s.error)
|
||||
goto error;
|
||||
@ -869,7 +876,7 @@ longlong Item_func_json_extract::val_int()
|
||||
json_value_types type;
|
||||
char *value;
|
||||
int value_len;
|
||||
longlong i;
|
||||
longlong i= 0;
|
||||
|
||||
if (read_json(NULL, &type, &value, &value_len) != NULL)
|
||||
{
|
||||
@ -1968,14 +1975,25 @@ continue_j2:
|
||||
else
|
||||
{
|
||||
const uchar *end1, *beg1, *end2, *beg2;
|
||||
int empty_array= 0;
|
||||
|
||||
beg1= je1->value_begin;
|
||||
|
||||
/* Merge as a single array. */
|
||||
if (je1->value_type == JSON_VALUE_ARRAY)
|
||||
{
|
||||
if (json_skip_level(je1))
|
||||
int cur_level= je1->stack_p;
|
||||
empty_array= 1;
|
||||
while (json_scan_next(je1) == 0)
|
||||
{
|
||||
if (je1->stack_p < cur_level)
|
||||
break;
|
||||
empty_array= 0;
|
||||
}
|
||||
|
||||
if (je1->s.error)
|
||||
return 1;
|
||||
|
||||
end1= je1->s.c_str - je1->sav_c_len;
|
||||
}
|
||||
else
|
||||
@ -1992,8 +2010,8 @@ continue_j2:
|
||||
end1= je1->value_end;
|
||||
}
|
||||
|
||||
if (str->append((const char*) beg1, end1 - beg1),
|
||||
str->append(", ", 2))
|
||||
if (str->append((const char*) beg1, end1 - beg1) ||
|
||||
(!empty_array && str->append(", ", 2)))
|
||||
return 3;
|
||||
|
||||
if (json_value_scalar(je2))
|
||||
@ -2449,6 +2467,8 @@ String *Item_func_json_insert::val_str(String *str)
|
||||
}
|
||||
else /*JSON_PATH_KEY*/
|
||||
{
|
||||
uint n_key= 0;
|
||||
|
||||
if (je.value_type != JSON_VALUE_OBJECT)
|
||||
continue;
|
||||
|
||||
@ -2460,6 +2480,7 @@ String *Item_func_json_insert::val_str(String *str)
|
||||
json_string_set_str(&key_name, lp->key, lp->key_end);
|
||||
if (json_key_matches(&je, &key_name))
|
||||
goto v_found;
|
||||
n_key++;
|
||||
if (json_skip_key(&je))
|
||||
goto js_error;
|
||||
break;
|
||||
@ -2477,7 +2498,8 @@ String *Item_func_json_insert::val_str(String *str)
|
||||
v_to= (const char *) (je.s.c_str - je.sav_c_len);
|
||||
str->length(0);
|
||||
if (append_simple(str, js->ptr(), v_to - js->ptr()) ||
|
||||
str->append(", \"", 3) ||
|
||||
(n_key > 0 && str->append(", ", 2)) ||
|
||||
str->append("\"", 1) ||
|
||||
append_simple(str, lp->key, lp->key_end - lp->key) ||
|
||||
str->append("\":", 2) ||
|
||||
append_json_value(str, args[n_arg+1], &tmp_val) ||
|
||||
|
@ -99,6 +99,7 @@ class Item_func_json_query: public Item_func_json_value
|
||||
public:
|
||||
Item_func_json_query(THD *thd, Item *js, Item *i_path):
|
||||
Item_func_json_value(thd, js, i_path) {}
|
||||
bool is_json_type() { return true; }
|
||||
const char *func_name() const { return "json_query"; }
|
||||
bool check_and_get_value(json_engine_t *je, String *res, int *error);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
|
@ -2085,11 +2085,11 @@ static bool mysql_test_create_view(Prepared_statement *stmt)
|
||||
if (thd->open_temporary_tables(tables))
|
||||
goto err;
|
||||
|
||||
lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW;
|
||||
if (open_normal_and_derived_tables(thd, tables, MYSQL_OPEN_FORCE_SHARED_MDL,
|
||||
DT_PREPARE))
|
||||
goto err;
|
||||
|
||||
lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW;
|
||||
res= select_like_stmt_test(stmt, 0, 0);
|
||||
|
||||
err:
|
||||
|
@ -32,7 +32,11 @@ MDEV-11782: Rewritten for MariaDB 10.2 by Marko Mäkelä, MariaDB Corporation.
|
||||
/** innodb_encrypt_log: whether to encrypt the redo log */
|
||||
extern my_bool srv_encrypt_log;
|
||||
|
||||
/** Initialize the redo log encryption key.
|
||||
/** Initialize the redo log encryption key and random parameters
|
||||
when creating a new redo log.
|
||||
The random parameters will be persisted in the log checkpoint pages.
|
||||
@see log_crypt_write_checkpoint_buf()
|
||||
@see log_crypt_read_checkpoint_buf()
|
||||
@return whether the operation succeeded */
|
||||
UNIV_INTERN
|
||||
bool
|
||||
@ -71,10 +75,11 @@ log_crypt_read_checkpoint_buf(const byte* buf);
|
||||
|
||||
/** Encrypt or decrypt log blocks.
|
||||
@param[in,out] buf log blocks to encrypt or decrypt
|
||||
@param[in] lsn log sequence number of the start of the buffer
|
||||
@param[in] size size of the buffer, in bytes
|
||||
@param[in] decrypt whether to decrypt instead of encrypting */
|
||||
UNIV_INTERN
|
||||
void
|
||||
log_crypt(byte* buf, ulint size, bool decrypt = false);
|
||||
log_crypt(byte* buf, lsn_t lsn, ulint size, bool decrypt = false);
|
||||
|
||||
#endif // log0crypt.h
|
||||
|
@ -103,11 +103,12 @@ get_crypt_info(ulint checkpoint_no)
|
||||
|
||||
/** Encrypt or decrypt log blocks.
|
||||
@param[in,out] buf log blocks to encrypt or decrypt
|
||||
@param[in] lsn log sequence number of the start of the buffer
|
||||
@param[in] size size of the buffer, in bytes
|
||||
@param[in] decrypt whether to decrypt instead of encrypting */
|
||||
UNIV_INTERN
|
||||
void
|
||||
log_crypt(byte* buf, ulint size, bool decrypt)
|
||||
log_crypt(byte* buf, lsn_t lsn, ulint size, bool decrypt)
|
||||
{
|
||||
ut_ad(size % OS_FILE_LOG_BLOCK_SIZE == 0);
|
||||
ut_a(info.key_version);
|
||||
@ -117,12 +118,12 @@ log_crypt(byte* buf, ulint size, bool decrypt)
|
||||
compile_time_assert(sizeof(uint32_t) == 4);
|
||||
|
||||
#define LOG_CRYPT_HDR_SIZE 4
|
||||
lsn &= ~lsn_t(OS_FILE_LOG_BLOCK_SIZE - 1);
|
||||
|
||||
for (const byte* const end = buf + size; buf != end;
|
||||
buf += OS_FILE_LOG_BLOCK_SIZE) {
|
||||
buf += OS_FILE_LOG_BLOCK_SIZE, lsn += OS_FILE_LOG_BLOCK_SIZE) {
|
||||
uint32_t dst[(OS_FILE_LOG_BLOCK_SIZE - LOG_CRYPT_HDR_SIZE)
|
||||
/ sizeof(uint32_t)];
|
||||
const ulint log_block_no = log_block_get_hdr_no(buf);
|
||||
|
||||
/* The log block number is not encrypted. */
|
||||
*aes_ctr_iv =
|
||||
@ -137,10 +138,10 @@ log_crypt(byte* buf, ulint size, bool decrypt)
|
||||
# error "LOG_BLOCK_HDR_NO has been moved; redo log format affected!"
|
||||
#endif
|
||||
aes_ctr_iv[1] = info.crypt_nonce.word;
|
||||
mach_write_to_8(reinterpret_cast<byte*>(aes_ctr_iv + 2),
|
||||
log_block_get_start_lsn(
|
||||
decrypt ? srv_start_lsn : log_sys->lsn,
|
||||
log_block_no));
|
||||
mach_write_to_8(reinterpret_cast<byte*>(aes_ctr_iv + 2), lsn);
|
||||
ut_ad(log_block_get_start_lsn(lsn,
|
||||
log_block_get_hdr_no(buf))
|
||||
== lsn);
|
||||
|
||||
int rc = encryption_crypt(
|
||||
buf + LOG_CRYPT_HDR_SIZE, sizeof dst,
|
||||
@ -206,7 +207,11 @@ init_crypt_key(crypt_info_t* info, bool upgrade = false)
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Initialize the redo log encryption key.
|
||||
/** Initialize the redo log encryption key and random parameters
|
||||
when creating a new redo log.
|
||||
The random parameters will be persisted in the log checkpoint pages.
|
||||
@see log_crypt_write_checkpoint_buf()
|
||||
@see log_crypt_read_checkpoint_buf()
|
||||
@return whether the operation succeeded */
|
||||
UNIV_INTERN
|
||||
bool
|
||||
|
@ -997,10 +997,6 @@ loop:
|
||||
|| log_block_get_hdr_no(buf)
|
||||
== log_block_convert_lsn_to_no(start_lsn));
|
||||
|
||||
if (log_sys->is_encrypted()) {
|
||||
log_crypt(buf, write_len);
|
||||
}
|
||||
|
||||
/* Calculate the checksums for each log block and write them to
|
||||
the trailer fields of the log blocks */
|
||||
|
||||
@ -1264,6 +1260,12 @@ loop:
|
||||
::memset(write_buf + area_end, 0, pad_size);
|
||||
}
|
||||
}
|
||||
|
||||
if (log_sys->is_encrypted()) {
|
||||
log_crypt(write_buf + area_start, log_sys->write_lsn,
|
||||
area_end - area_start);
|
||||
}
|
||||
|
||||
/* Do the write to the log files */
|
||||
log_group_write_buf(
|
||||
&log_sys->log, write_buf + area_start,
|
||||
|
@ -715,7 +715,8 @@ loop:
|
||||
}
|
||||
|
||||
if (group->is_encrypted()) {
|
||||
log_crypt(buf, OS_FILE_LOG_BLOCK_SIZE, true);
|
||||
log_crypt(buf, start_lsn,
|
||||
OS_FILE_LOG_BLOCK_SIZE, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1016,6 +1017,7 @@ recv_find_max_checkpoint(ulint* max_field)
|
||||
buf + LOG_CHECKPOINT_LSN);
|
||||
group->lsn_offset = mach_read_from_8(
|
||||
buf + LOG_CHECKPOINT_OFFSET);
|
||||
log_sys->next_checkpoint_no = checkpoint_no;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2223,14 +2223,6 @@ files_checked:
|
||||
|
||||
recv_sys->dblwr.pages.clear();
|
||||
|
||||
if (err == DB_SUCCESS && !srv_read_only_mode) {
|
||||
log_mutex_enter();
|
||||
if (log_sys->is_encrypted() && !log_crypt_init()) {
|
||||
err = DB_ERROR;
|
||||
}
|
||||
log_mutex_exit();
|
||||
}
|
||||
|
||||
if (err == DB_SUCCESS) {
|
||||
/* Initialize the change buffer. */
|
||||
err = dict_boot();
|
||||
@ -2733,13 +2725,6 @@ files_checked:
|
||||
fil_crypt_threads_init();
|
||||
fil_system_exit();
|
||||
|
||||
/*
|
||||
Create a checkpoint before logging anything new, so that
|
||||
the current encryption key in use is definitely logged
|
||||
before any log blocks encrypted with that key.
|
||||
*/
|
||||
log_make_checkpoint_at(LSN_MAX, TRUE);
|
||||
|
||||
/* Initialize online defragmentation. */
|
||||
btr_defragment_init();
|
||||
btr_defragment_thread_active = true;
|
||||
|
@ -619,6 +619,7 @@ trx_free_prepared(
|
||||
|| (trx_state_eq(trx, TRX_STATE_ACTIVE)
|
||||
&& trx->is_recovered
|
||||
&& (!srv_was_started
|
||||
|| srv_operation == SRV_OPERATION_RESTORE
|
||||
|| srv_read_only_mode
|
||||
|| srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO)));
|
||||
ut_a(trx->magic_n == TRX_MAGIC_N);
|
||||
|
@ -402,12 +402,20 @@ analyze table t1;
|
||||
-- enable_query_log
|
||||
|
||||
# index_merge on first table in join
|
||||
if ($index_merge_random_rows_in_EXPLAIN)
|
||||
{
|
||||
--replace_column 9 #
|
||||
}
|
||||
explain select * from t0 left join t1 on (t0.key1=t1.key1)
|
||||
where t0.key1=3 or t0.key2=4;
|
||||
|
||||
select * from t0 left join t1 on (t0.key1=t1.key1)
|
||||
where t0.key1=3 or t0.key2=4;
|
||||
|
||||
if ($index_merge_random_rows_in_EXPLAIN)
|
||||
{
|
||||
--replace_column 9 #
|
||||
}
|
||||
explain
|
||||
select * from t0,t1 where (t0.key1=t1.key1) and ( t0.key1=3 or t0.key2=4);
|
||||
|
||||
|
@ -250,8 +250,8 @@ insert into t1 select * from t0;
|
||||
explain select * from t0 left join t1 on (t0.key1=t1.key1)
|
||||
where t0.key1=3 or t0.key2=4;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL 2 Using union(i1,i2); Using where
|
||||
1 SIMPLE t1 ref i1 i1 4 test.t0.key1 2
|
||||
1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL # Using union(i1,i2); Using where
|
||||
1 SIMPLE t1 ref i1 i1 4 test.t0.key1 #
|
||||
select * from t0 left join t1 on (t0.key1=t1.key1)
|
||||
where t0.key1=3 or t0.key2=4;
|
||||
key1 key2 key3 key4 key5 key6 key7 key8 key1 key2 key3 key4 key5 key6 key7 key8
|
||||
@ -260,8 +260,8 @@ key1 key2 key3 key4 key5 key6 key7 key8 key1 key2 key3 key4 key5 key6 key7 key8
|
||||
explain
|
||||
select * from t0,t1 where (t0.key1=t1.key1) and ( t0.key1=3 or t0.key2=4);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL 2 Using union(i1,i2); Using where
|
||||
1 SIMPLE t1 ref i1 i1 4 test.t0.key1 2
|
||||
1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL # Using union(i1,i2); Using where
|
||||
1 SIMPLE t1 ref i1 i1 4 test.t0.key1 #
|
||||
explain
|
||||
select * from t0,t1 where (t0.key1=t1.key1) and
|
||||
(t0.key1=3 or t0.key2<4) and t1.key1=2;
|
||||
|
@ -1586,7 +1586,7 @@ int json_escape(CHARSET_INFO *str_cs,
|
||||
enum json_esc_char_classes c_class;
|
||||
|
||||
str+= c_len;
|
||||
if (c_chr > 0x60 || (c_class= json_escape_chr_map[c_chr]) == ESC_)
|
||||
if (c_chr >= 0x60 || (c_class= json_escape_chr_map[c_chr]) == ESC_)
|
||||
{
|
||||
if ((c_len= json_cs->cset->wc_mb(json_cs, c_chr, json, json_end)) > 0)
|
||||
{
|
||||
|
Reference in New Issue
Block a user