1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-01 03:47:19 +03:00

Merge 10.2 into bb-10.2-ext

This commit is contained in:
Marko Mäkelä
2017-08-09 12:35:21 +03:00
14 changed files with 234 additions and 51 deletions

View File

@ -356,6 +356,12 @@ json_keys('foo')
NULL NULL
Warnings: Warnings:
Warning 4038 Syntax error in JSON text in argument 1 to function 'json_keys' at position 1 Warning 4038 Syntax error in JSON text in argument 1 to function 'json_keys' at position 1
select json_keys('{"a":{"c":1, "d":2}, "b":2, "c":1, "a":3, "b":1, "c":2}');
json_keys('{"a":{"c":1, "d":2}, "b":2, "c":1, "a":3, "b":1, "c":2}')
["a", "b", "c"]
select json_keys('{"c1": "value 1", "c1": "value 2"}');
json_keys('{"c1": "value 1", "c1": "value 2"}')
["c1"]
SET @j = '["abc", [{"k": "10"}, "def"], {"x":"abc"}, {"y":"bcd"}]'; SET @j = '["abc", [{"k": "10"}, "def"], {"x":"abc"}, {"y":"bcd"}]';
select json_search(@j, 'one', 'abc'); select json_search(@j, 'one', 'abc');
json_search(@j, 'one', 'abc') json_search(@j, 'one', 'abc')
@ -648,6 +654,21 @@ NULL
SELECT JSON_EXTRACT( '{"foo":"bar"}', '$[*]' ); SELECT JSON_EXTRACT( '{"foo":"bar"}', '$[*]' );
JSON_EXTRACT( '{"foo":"bar"}', '$[*]' ) JSON_EXTRACT( '{"foo":"bar"}', '$[*]' )
NULL NULL
select JSON_EXTRACT('{"name":"value"}', '$.name') = 'value';
JSON_EXTRACT('{"name":"value"}', '$.name') = 'value'
1
select JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = true;
JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = true
1
select JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = false;
JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = false
0
select JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = 1;
JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = 1
1
select JSON_EXTRACT('{\"input1\":\"\\u00f6\"}', '$.\"input1\"');
JSON_EXTRACT('{\"input1\":\"\\u00f6\"}', '$.\"input1\"')
"\u00f6"
# #
# Start of 10.3 tests # Start of 10.3 tests
# #

View File

@ -25,6 +25,7 @@ CREATE TEMPORARY TABLE t LIKE t0;
INSERT INTO t VALUES INSERT INTO t VALUES
(NULL,1,1,'private','secret'),(NULL,2,2,'sacred','success'), (NULL,1,1,'private','secret'),(NULL,2,2,'sacred','success'),
(NULL,3,3,'story','secure'),(NULL,4,4,'security','sacrament'); (NULL,3,3,'story','secure'),(NULL,4,4,'security','sacrament');
SET GLOBAL innodb_change_buffering=none;
SET GLOBAL innodb_flush_log_at_trx_commit=1; SET GLOBAL innodb_flush_log_at_trx_commit=1;
INSERT INTO t0 INSERT INTO t0
SELECT NULL, t1.col_int, t1.col_int_key, t1.col_char, t1.col_char_key SELECT NULL, t1.col_int, t1.col_int_key, t1.col_char, t1.col_char_key

View File

@ -32,6 +32,11 @@ INSERT INTO t VALUES
(NULL,1,1,'private','secret'),(NULL,2,2,'sacred','success'), (NULL,1,1,'private','secret'),(NULL,2,2,'sacred','success'),
(NULL,3,3,'story','secure'),(NULL,4,4,'security','sacrament'); (NULL,3,3,'story','secure'),(NULL,4,4,'security','sacrament');
# Prevent change buffering of key(col_char_key), so that
# after the restart, the data ('secret','success','secure','sacrament')
# cannot be emitted to the unencrypted redo log by change buffer merge.
SET GLOBAL innodb_change_buffering=none;
# Force a redo log flush at the next commit. # Force a redo log flush at the next commit.
SET GLOBAL innodb_flush_log_at_trx_commit=1; SET GLOBAL innodb_flush_log_at_trx_commit=1;
INSERT INTO t0 INSERT INTO t0

View File

@ -138,6 +138,11 @@ select json_keys('{"a":{"c":1, "d":2}, "b":2}');
select json_keys('{"a":{"c":1, "d":2}, "b":2}', "$.a"); select json_keys('{"a":{"c":1, "d":2}, "b":2}', "$.a");
select json_keys('{"a":{"c":1, "d":2}, "b":2}', "$.b"); select json_keys('{"a":{"c":1, "d":2}, "b":2}', "$.b");
select json_keys('foo'); select json_keys('foo');
#
# mdev-12789 JSON_KEYS returns duplicate keys twice
#
select json_keys('{"a":{"c":1, "d":2}, "b":2, "c":1, "a":3, "b":1, "c":2}');
select json_keys('{"c1": "value 1", "c1": "value 2"}');
SET @j = '["abc", [{"k": "10"}, "def"], {"x":"abc"}, {"y":"bcd"}]'; SET @j = '["abc", [{"k": "10"}, "def"], {"x":"abc"}, {"y":"bcd"}]';
select json_search(@j, 'one', 'abc'); select json_search(@j, 'one', 'abc');
@ -302,6 +307,16 @@ DROP TABLE t1;
SELECT JSON_EXTRACT( '{"foo":"bar"}', '$[*].*' ); SELECT JSON_EXTRACT( '{"foo":"bar"}', '$[*].*' );
SELECT JSON_EXTRACT( '{"foo":"bar"}', '$[*]' ); SELECT JSON_EXTRACT( '{"foo":"bar"}', '$[*]' );
#
# MDEV-12604 Comparison of JSON_EXTRACT result differs with Mysql.
#
select JSON_EXTRACT('{"name":"value"}', '$.name') = 'value';
select JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = true;
select JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = false;
select JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = 1;
select JSON_EXTRACT('{\"input1\":\"\\u00f6\"}', '$.\"input1\"');
--echo # --echo #
--echo # Start of 10.3 tests --echo # Start of 10.3 tests
--echo # --echo #

View File

@ -3356,6 +3356,12 @@ void handler::print_error(int error, myf errflag)
DBUG_ENTER("handler::print_error"); DBUG_ENTER("handler::print_error");
DBUG_PRINT("enter",("error: %d",error)); DBUG_PRINT("enter",("error: %d",error));
if (ha_thd()->transaction_rollback_request)
{
/* Ensure this becomes a true error */
errflag&= ~(ME_JUST_WARNING | ME_JUST_INFO);
}
int textno= -1; // impossible value int textno= -1; // impossible value
switch (error) { switch (error) {
case EACCES: case EACCES:
@ -3504,9 +3510,6 @@ void handler::print_error(int error, myf errflag)
{ {
String str, full_err_msg(ER_DEFAULT(ER_LOCK_DEADLOCK), system_charset_info); String str, full_err_msg(ER_DEFAULT(ER_LOCK_DEADLOCK), system_charset_info);
/* cannot continue. the statement was already aborted in the engine */
SET_FATAL_ERROR;
get_error_message(error, &str); get_error_message(error, &str);
full_err_msg.append(str); full_err_msg.append(str);
my_printf_error(ER_LOCK_DEADLOCK, "%s", errflag, full_err_msg.c_ptr_safe()); my_printf_error(ER_LOCK_DEADLOCK, "%s", errflag, full_err_msg.c_ptr_safe());

View File

@ -545,6 +545,16 @@ bool Arg_comparator::set_cmp_func_string()
if (owner->agg_arg_charsets_for_comparison(&m_compare_collation, a, b)) if (owner->agg_arg_charsets_for_comparison(&m_compare_collation, a, b))
return true; return true;
} }
if ((*a)->is_json_type() ^ (*b)->is_json_type())
{
Item **j_item= (*a)->is_json_type() ? a : b;
Item *uf= new(thd->mem_root) Item_func_json_unquote(thd, *j_item);
if (!uf || uf->fix_fields(thd, &uf))
return 1;
*j_item= uf;
}
a= cache_converted_constant(thd, a, &a_cache, compare_type_handler()); a= cache_converted_constant(thd, a, &a_cache, compare_type_handler());
b= cache_converted_constant(thd, b, &b_cache, compare_type_handler()); b= cache_converted_constant(thd, b, &b_cache, compare_type_handler());
return false; return false;

View File

@ -587,24 +587,40 @@ void Item_func_json_unquote::fix_length_and_dec()
} }
String *Item_func_json_unquote::val_str(String *str) String *Item_func_json_unquote::read_json(json_engine_t *je)
{ {
String *js= args[0]->val_json(&tmp_s); String *js= args[0]->val_json(&tmp_s);
json_engine_t je;
int c_len;
if ((null_value= args[0]->null_value)) if ((null_value= args[0]->null_value))
return NULL; return 0;
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(), json_scan_start(je, js->charset(),(const uchar *) js->ptr(),
(const uchar *) js->ptr() + js->length()); (const uchar *) js->ptr() + js->length());
je.value_type= (enum json_value_types) -1; /* To report errors right. */ je->value_type= (enum json_value_types) -1; /* To report errors right. */
if (json_read_value(&je)) if (json_read_value(je))
goto error; goto error;
if (je.value_type != JSON_VALUE_STRING) return js;
error:
if (je->value_type == JSON_VALUE_STRING)
report_json_error(js, je, 0);
return js;
}
String *Item_func_json_unquote::val_str(String *str)
{
json_engine_t je;
int c_len;
String *js;
if (!(js= read_json(&je)))
return NULL;
if (je.s.error || je.value_type != JSON_VALUE_STRING)
return js; return js;
str->length(0); str->length(0);
@ -621,13 +637,86 @@ String *Item_func_json_unquote::val_str(String *str)
return str; return str;
error: error:
if (je.value_type == JSON_VALUE_STRING)
report_json_error(js, &je, 0); report_json_error(js, &je, 0);
/* We just return the argument's value in the case of error. */
return js; return js;
} }
double Item_func_json_unquote::val_real()
{
json_engine_t je;
double d= 0.0;
String *js;
if ((js= read_json(&je)) != NULL)
{
switch (je.value_type)
{
case JSON_VALUE_NUMBER:
{
char *end;
int err;
d= my_strntod(je.s.cs, (char *) je.value, je.value_len, &end, &err);
break;
}
case JSON_VALUE_TRUE:
d= 1.0;
break;
case JSON_VALUE_STRING:
{
char *end;
int err;
d= my_strntod(js->charset(), (char *) js->ptr(), js->length(),
&end, &err);
break;
}
default:
break;
};
}
return d;
}
longlong Item_func_json_unquote::val_int()
{
json_engine_t je;
longlong i= 0;
String *js;
if ((js= read_json(&je)) != NULL)
{
switch (je.value_type)
{
case JSON_VALUE_NUMBER:
{
char *end;
int err;
i= my_strntoll(je.s.cs, (char *) je.value, je.value_len, 10,
&end, &err);
break;
}
case JSON_VALUE_TRUE:
i= 1;
break;
case JSON_VALUE_STRING:
{
char *end;
int err;
i= my_strntoll(js->charset(), (char *) js->ptr(), js->length(), 10,
&end, &err);
break;
}
default:
break;
};
}
return i;
}
static int alloc_tmp_paths(THD *thd, uint n_paths, static int alloc_tmp_paths(THD *thd, uint n_paths,
json_path_with_flags **paths,String **tmp_paths) json_path_with_flags **paths,String **tmp_paths)
{ {
@ -1397,6 +1486,8 @@ void Item_func_json_array::fix_length_and_dec()
ulonglong char_length= 2; ulonglong char_length= 2;
uint n_arg; uint n_arg;
result_limit= 0;
if (arg_count == 0) if (arg_count == 0)
{ {
collation.set(&my_charset_utf8_general_ci); collation.set(&my_charset_utf8_general_ci);
@ -1413,7 +1504,6 @@ void Item_func_json_array::fix_length_and_dec()
fix_char_length_ulonglong(char_length); fix_char_length_ulonglong(char_length);
tmp_val.set_charset(collation.collation); tmp_val.set_charset(collation.collation);
result_limit= 0;
} }
@ -2692,6 +2782,41 @@ void Item_func_json_keys::fix_length_and_dec()
} }
/*
That function is for Item_func_json_keys::val_str exclusively.
It utilizes the fact the resulting string is in specific format:
["key1", "key2"...]
*/
static int check_key_in_list(String *res,
const uchar *key, int key_len)
{
const uchar *c= (const uchar *) res->ptr() + 2; /* beginning '["' */
const uchar *end= (const uchar *) res->end() - 1; /* ending '"' */
while (c < end)
{
int n_char;
for (n_char=0; c[n_char] != '"' && n_char < key_len; n_char++)
{
if (c[n_char] != key[n_char])
break;
}
if (c[n_char] == '"')
{
if (n_char == key_len)
return 1;
}
else
{
while (c[n_char] != '"')
n_char++;
}
c+= n_char + 4; /* skip ', "' */
}
return 0;
}
String *Item_func_json_keys::val_str(String *str) String *Item_func_json_keys::val_str(String *str)
{ {
json_engine_t je; json_engine_t je;
@ -2748,6 +2873,7 @@ skip_search:
while (json_scan_next(&je) == 0 && je.state != JST_OBJ_END) while (json_scan_next(&je) == 0 && je.state != JST_OBJ_END)
{ {
const uchar *key_start, *key_end; const uchar *key_start, *key_end;
int key_len;
switch (je.state) switch (je.state)
{ {
@ -2757,13 +2883,19 @@ skip_search:
{ {
key_end= je.s.c_str; key_end= je.s.c_str;
} while (json_read_keyname_chr(&je) == 0); } while (json_read_keyname_chr(&je) == 0);
if (je.s.error || if (je.s.error)
(n_keys > 0 && str->append(", ", 2)) || goto err_return;
key_len= key_end - key_start;
if (!check_key_in_list(str, key_start, key_len))
{
if ((n_keys > 0 && str->append(", ", 2)) ||
str->append("\"", 1) || str->append("\"", 1) ||
append_simple(str, key_start, key_end - key_start) || append_simple(str, key_start, key_len) ||
str->append("\"", 1)) str->append("\"", 1))
goto err_return; goto err_return;
n_keys++; n_keys++;
}
break; break;
case JST_OBJ_START: case JST_OBJ_START:
case JST_ARRAY_START: case JST_ARRAY_START:

View File

@ -125,12 +125,14 @@ class Item_func_json_unquote: public Item_str_func
{ {
protected: protected:
String tmp_s; String tmp_s;
String *read_json(json_engine_t *je);
public: public:
Item_func_json_unquote(THD *thd, Item *s): Item_str_func(thd, s) {} Item_func_json_unquote(THD *thd, Item *s): Item_str_func(thd, s) {}
const char *func_name() const { return "json_unquote"; } const char *func_name() const { return "json_unquote"; }
void fix_length_and_dec(); void fix_length_and_dec();
String *val_str(String *); String *val_str(String *);
double val_real();
longlong val_int();
Item *get_copy(THD *thd, MEM_ROOT *mem_root) Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_json_unquote>(thd, mem_root, this); } { return get_item_copy<Item_func_json_unquote>(thd, mem_root, this); }
}; };

View File

@ -9420,7 +9420,7 @@ ha_innobase::update_row(
innobase_srv_conc_enter_innodb(m_prebuilt); innobase_srv_conc_enter_innodb(m_prebuilt);
error = row_update_for_mysql((byte*) old_row, m_prebuilt); error = row_update_for_mysql(m_prebuilt);
if (error == DB_SUCCESS && autoinc) { if (error == DB_SUCCESS && autoinc) {
/* A value for an AUTO_INCREMENT column /* A value for an AUTO_INCREMENT column
@ -9535,7 +9535,7 @@ ha_innobase::delete_row(
innobase_srv_conc_enter_innodb(m_prebuilt); innobase_srv_conc_enter_innodb(m_prebuilt);
error = row_update_for_mysql((byte*) record, m_prebuilt); error = row_update_for_mysql(m_prebuilt);
innobase_srv_conc_exit_innodb(m_prebuilt); innobase_srv_conc_exit_innodb(m_prebuilt);

View File

@ -272,13 +272,10 @@ row_table_got_default_clust_index(
const dict_table_t* table); /*!< in: table */ const dict_table_t* table); /*!< in: table */
/** Does an update or delete of a row for MySQL. /** Does an update or delete of a row for MySQL.
@param[in] mysql_rec row in the MySQL format
@param[in,out] prebuilt prebuilt struct in MySQL handle @param[in,out] prebuilt prebuilt struct in MySQL handle
@return error code or DB_SUCCESS */ @return error code or DB_SUCCESS */
dberr_t dberr_t
row_update_for_mysql( row_update_for_mysql(row_prebuilt_t* prebuilt)
const byte* mysql_rec,
row_prebuilt_t* prebuilt)
MY_ATTRIBUTE((warn_unused_result)); MY_ATTRIBUTE((warn_unused_result));
/** This can only be used when srv_locks_unsafe_for_binlog is TRUE or this /** This can only be used when srv_locks_unsafe_for_binlog is TRUE or this

View File

@ -740,6 +740,8 @@ row_mysql_handle_errors(
{ {
dberr_t err; dberr_t err;
DBUG_ENTER("row_mysql_handle_errors");
handle_new_error: handle_new_error:
err = trx->error_state; err = trx->error_state;
@ -747,6 +749,9 @@ handle_new_error:
trx->error_state = DB_SUCCESS; trx->error_state = DB_SUCCESS;
DBUG_LOG("trx", "handle error: " << ut_strerr(err)
<< ";id=" << ib::hex(trx->id) << ", " << trx);
switch (err) { switch (err) {
case DB_LOCK_WAIT_TIMEOUT: case DB_LOCK_WAIT_TIMEOUT:
if (row_rollback_on_timeout) { if (row_rollback_on_timeout) {
@ -795,7 +800,7 @@ handle_new_error:
*new_err = err; *new_err = err;
return(true); DBUG_RETURN(true);
case DB_DEADLOCK: case DB_DEADLOCK:
case DB_LOCK_TABLE_FULL: case DB_LOCK_TABLE_FULL:
@ -840,7 +845,7 @@ handle_new_error:
trx->error_state = DB_SUCCESS; trx->error_state = DB_SUCCESS;
return(false); DBUG_RETURN(false);
} }
/********************************************************************//** /********************************************************************//**
@ -1806,14 +1811,10 @@ public:
/** Does an update or delete of a row for MySQL. /** Does an update or delete of a row for MySQL.
@param[in] mysql_rec row in the MySQL format
@param[in,out] prebuilt prebuilt struct in MySQL handle @param[in,out] prebuilt prebuilt struct in MySQL handle
@return error code or DB_SUCCESS */ @return error code or DB_SUCCESS */
static
dberr_t dberr_t
row_update_for_mysql_using_upd_graph( row_update_for_mysql(row_prebuilt_t* prebuilt)
const byte* mysql_rec,
row_prebuilt_t* prebuilt)
{ {
trx_savept_t savept; trx_savept_t savept;
dberr_t err; dberr_t err;
@ -1829,13 +1830,13 @@ row_update_for_mysql_using_upd_graph(
upd_cascade_t* processed_cascades; upd_cascade_t* processed_cascades;
bool got_s_lock = false; bool got_s_lock = false;
DBUG_ENTER("row_update_for_mysql_using_upd_graph"); DBUG_ENTER("row_update_for_mysql");
ut_ad(trx); ut_ad(trx);
ut_a(prebuilt->magic_n == ROW_PREBUILT_ALLOCATED); ut_a(prebuilt->magic_n == ROW_PREBUILT_ALLOCATED);
ut_a(prebuilt->magic_n2 == ROW_PREBUILT_ALLOCATED); ut_a(prebuilt->magic_n2 == ROW_PREBUILT_ALLOCATED);
ut_a(prebuilt->template_type == ROW_MYSQL_WHOLE_ROW);
ut_ad(table->stat_initialized); ut_ad(table->stat_initialized);
UT_NOT_USED(mysql_rec);
if (!table->is_readable()) { if (!table->is_readable()) {
return(row_mysql_get_table_status(table, trx, true)); return(row_mysql_get_table_status(table, trx, true));
@ -2154,19 +2155,6 @@ error:
DBUG_RETURN(err); DBUG_RETURN(err);
} }
/** Does an update or delete of a row for MySQL.
@param[in] mysql_rec row in the MySQL format
@param[in,out] prebuilt prebuilt struct in MySQL handle
@return error code or DB_SUCCESS */
dberr_t
row_update_for_mysql(
const byte* mysql_rec,
row_prebuilt_t* prebuilt)
{
ut_a(prebuilt->template_type == ROW_MYSQL_WHOLE_ROW);
return(row_update_for_mysql_using_upd_graph(mysql_rec, prebuilt));
}
/** This can only be used when srv_locks_unsafe_for_binlog is TRUE or this /** This can only be used when srv_locks_unsafe_for_binlog is TRUE or this
session is using a READ COMMITTED or READ UNCOMMITTED isolation level. session is using a READ COMMITTED or READ UNCOMMITTED isolation level.
Before calling this function row_search_for_mysql() must have Before calling this function row_search_for_mysql() must have

View File

@ -293,14 +293,16 @@ trx_purge_add_update_undo_to_history(
After the purge thread has been given permission to exit, After the purge thread has been given permission to exit,
in fast shutdown, we may roll back transactions (trx->undo_no==0) in fast shutdown, we may roll back transactions (trx->undo_no==0)
in THD::cleanup() invoked from unlink_thd(). */ in THD::cleanup() invoked from unlink_thd(), and we may also
continue to execute user transactions. */
ut_ad(srv_undo_sources ut_ad(srv_undo_sources
|| ((srv_startup_is_before_trx_rollback_phase || ((srv_startup_is_before_trx_rollback_phase
|| trx_rollback_or_clean_is_active) || trx_rollback_or_clean_is_active)
&& purge_sys->state == PURGE_STATE_INIT) && purge_sys->state == PURGE_STATE_INIT)
|| (srv_force_recovery >= SRV_FORCE_NO_BACKGROUND || (srv_force_recovery >= SRV_FORCE_NO_BACKGROUND
&& purge_sys->state == PURGE_STATE_DISABLED) && purge_sys->state == PURGE_STATE_DISABLED)
|| (trx->undo_no == 0 && srv_fast_shutdown)); || ((trx->undo_no == 0 || trx->in_mysql_trx_list)
&& srv_fast_shutdown));
/* Add the log as the first in the history list */ /* Add the log as the first in the history list */
flst_add_first(rseg_header + TRX_RSEG_HISTORY, flst_add_first(rseg_header + TRX_RSEG_HISTORY,

View File

@ -238,6 +238,7 @@ struct TrxFactory {
trx_init(trx); trx_init(trx);
DBUG_LOG("trx", "Init: " << trx);
trx->state = TRX_STATE_NOT_STARTED; trx->state = TRX_STATE_NOT_STARTED;
trx->dict_operation_lock_mode = 0; trx->dict_operation_lock_mode = 0;
@ -452,6 +453,7 @@ trx_create_low()
/* Trx state can be TRX_STATE_FORCED_ROLLBACK if /* Trx state can be TRX_STATE_FORCED_ROLLBACK if
the trx was forced to rollback before it's reused.*/ the trx was forced to rollback before it's reused.*/
DBUG_LOG("trx", "Create: " << trx);
trx->state = TRX_STATE_NOT_STARTED; trx->state = TRX_STATE_NOT_STARTED;
heap = mem_heap_create(sizeof(ib_vector_t) + sizeof(void*) * 8); heap = mem_heap_create(sizeof(ib_vector_t) + sizeof(void*) * 8);
@ -630,6 +632,7 @@ trx_free_prepared(
ut_d(trx->in_rw_trx_list = FALSE); ut_d(trx->in_rw_trx_list = FALSE);
DBUG_LOG("trx", "Free prepared: " << trx);
trx->state = TRX_STATE_NOT_STARTED; trx->state = TRX_STATE_NOT_STARTED;
/* Undo trx_resurrect_table_locks(). */ /* Undo trx_resurrect_table_locks(). */
@ -1753,6 +1756,7 @@ trx_commit_in_memory(
ut_ad(!(trx->in_innodb ut_ad(!(trx->in_innodb
& (TRX_FORCE_ROLLBACK | TRX_FORCE_ROLLBACK_ASYNC))); & (TRX_FORCE_ROLLBACK | TRX_FORCE_ROLLBACK_ASYNC)));
DBUG_LOG("trx", "Autocommit in memory: " << trx);
trx->state = TRX_STATE_NOT_STARTED; trx->state = TRX_STATE_NOT_STARTED;
} else { } else {
@ -1888,8 +1892,10 @@ trx_commit_in_memory(
if (trx->abort) { if (trx->abort) {
trx->abort = false; trx->abort = false;
DBUG_LOG("trx", "Abort: " << trx);
trx->state = TRX_STATE_FORCED_ROLLBACK; trx->state = TRX_STATE_FORCED_ROLLBACK;
} else { } else {
DBUG_LOG("trx", "Commit in memory: " << trx);
trx->state = TRX_STATE_NOT_STARTED; trx->state = TRX_STATE_NOT_STARTED;
} }
@ -2061,6 +2067,7 @@ trx_cleanup_at_db_startup(
ut_ad(trx->is_recovered); ut_ad(trx->is_recovered);
ut_ad(!trx->in_rw_trx_list); ut_ad(!trx->in_rw_trx_list);
ut_ad(!trx->in_mysql_trx_list); ut_ad(!trx->in_mysql_trx_list);
DBUG_LOG("trx", "Cleanup at startup: " << trx);
trx->state = TRX_STATE_NOT_STARTED; trx->state = TRX_STATE_NOT_STARTED;
} }

View File

@ -253,7 +253,7 @@ static int read_4_hexdigits(json_string_t *s, uchar *dest)
if ((c_len= json_next_char(s)) <= 0) if ((c_len= json_next_char(s)) <= 0)
return s->error= json_eos(s) ? JE_EOS : JE_BAD_CHR; return s->error= json_eos(s) ? JE_EOS : JE_BAD_CHR;
if (s->c_next >= 128 || (t= json_instr_chr_map[s->c_next]) >= S_F) if (s->c_next >= 128 || (t= json_instr_chr_map[s->c_next]) > S_F)
return s->error= JE_SYN; return s->error= JE_SYN;
s->c_str+= c_len; s->c_str+= c_len;