lists.mariadb.org
Sign In Sign Up
Manage this list Sign In Sign Up

Keyboard Shortcuts

Thread View

  • j: Next unread message
  • k: Previous unread message
  • j a: Jump to all threads
  • j l: Jump to MailingList overview

commits

Thread Start a new thread
Threads by month
  • ----- 2025 -----
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2024 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2023 -----
  • December
  • November
  • October
  • September
  • August
  • July
commits@lists.mariadb.org

  • 14605 discussions
[Commits] MDEV-15127 AddressSanitizer: stack-buffer-overflow in base_list::push_back ..
by Sachin Setiya 07 Aug '18

07 Aug '18
commit 482d4da0a7a7f76e8ea9026978d49565f57a4192 Author: Sachin <sachin.setiya(a)mariadb.com> Date: Tue Aug 7 16:05:48 2018 +0530 MDEV-15127 AddressSanitizer: stack-buffer-overflow in base_list::push_back .. Problem:- If we try to run this query with -WITH_ASAN=ON compiled server CREATE TABLE t1 (i INT); SET debug_dbug="+d,test_completely_invisible,test_invisible_index"; CREATE TABLE t2 LIKE t1; This will generate a stack buffer overflow error. ==8922==ERROR: AddressSanitizer: stack-buffer-overflow on address #ADDR Analyze:- Error is generated on this line if (((*last)=new list_node(info, &end_of_list))) So info is our Key*, &end_of_list is global variable and last == #ADDR So last is suspicious variable. And last is the variable present in alter_info ->key_list. Now the question is how this key_list->last gets wrong/ different stack variable. In the backtrace, we can see that key_list is generated in mysql_create_table_like_table by calling mysql_preapre_alter_table_function and dummy key_list is created by mysql_create_like_table. In the end on mysql_prepare_alter_table we call alter_info->key_list.swap(new_key_list); So there is two options either key_list is empty or not empty , IF it is not empty then there is no issues last ptr is replaced by thd->mem_root (allocated ptr) So problem arises when key_list is empty. It swaps the dummy last ptr by mysql_prepare_alter_table declared ptr. which is wrong. Solution:- We wont swap variable if list does not have any element. diff --git a/mysql-test/main/invisible_field_debug.result b/mysql-test/main/invisible_field_debug.result index 4c4ebffbdfc..b3c84d18333 100644 --- a/mysql-test/main/invisible_field_debug.result +++ b/mysql-test/main/invisible_field_debug.result @@ -369,3 +369,8 @@ t1 1 invisible 1 c A NULL NULL NULL YES BTREE t1 1 invisible_2 1 invisible A NULL NULL NULL YES BTREE drop table t1; set @old_debug= @@debug_dbug; +CREATE TABLE t1 (i INT ); +SET debug_dbug="+d,test_completely_invisible,test_invisible_index"; +CREATE TABLE t2 LIKE t1; +SET debug_dbug= DEFAULT; +DROP TABLE t1, t2; diff --git a/mysql-test/main/invisible_field_debug.test b/mysql-test/main/invisible_field_debug.test index 8674620e055..c1d6899d16e 100644 --- a/mysql-test/main/invisible_field_debug.test +++ b/mysql-test/main/invisible_field_debug.test @@ -270,3 +270,9 @@ explain select * from t1 where invisible =9; show indexes in t1; drop table t1; set @old_debug= @@debug_dbug; +## MDEV 15127 +CREATE TABLE t1 (i INT ); +SET debug_dbug="+d,test_completely_invisible,test_invisible_index"; +CREATE TABLE t2 LIKE t1; +SET debug_dbug= DEFAULT; +DROP TABLE t1, t2; diff --git a/sql/sql_list.h b/sql/sql_list.h index 0219c226803..39a1c3375e0 100644 --- a/sql/sql_list.h +++ b/sql/sql_list.h @@ -278,10 +278,13 @@ class base_list :public Sql_alloc */ inline void swap(base_list &rhs) { + list_node **rhs_last=rhs.last; swap_variables(list_node *, first, rhs.first); - swap_variables(list_node **, last, rhs.last); swap_variables(uint, elements, rhs.elements); + rhs.last= last == &first ? &rhs.first : last; + last = rhs_last == &rhs.first ? &first : rhs_last; } + inline list_node* last_node() { return *last; } inline list_node* first_node() { return first;} inline void *head() { return first->info; }
1 0
0 0
[Commits] 1e8b79d966f: MDEV-16217: Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed in Field_num::get_date
by Oleksandr Byelkin 07 Aug '18

07 Aug '18
revision-id: 1e8b79d966fca2ae541477972ac759be5ee60c4e (mariadb-10.2.16-66-g1e8b79d966f) parent(s): 4ddcb4eb46c62cf459936554d43351db740ba14d author: Oleksandr Byelkin committer: Oleksandr Byelkin timestamp: 2018-08-07 15:28:58 +0200 message: MDEV-16217: Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed in Field_num::get_date Provide possibility for constant function like DEFAULT() still mark tables as being read. --- mysql-test/r/func_time.result | 28 ++++++++++++++++++++++++++++ mysql-test/t/func_time.test | 21 +++++++++++++++++++++ sql/item.h | 9 +++++++++ 3 files changed, 58 insertions(+) diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index 55c2c93eb56..d3e81a8f2ee 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -3260,3 +3260,31 @@ DROP TABLE t1,t2; # # End of 10.1 tests # +# +# MDEV-16217: Assertion `!table || (!table->read_set || +# bitmap_is_set(table->read_set, field_index))' +# failed in Field_num::get_date +# +CREATE TABLE t1 (pk int default 0, a1 date); +INSERT INTO t1 VALUES (1,'1900-01-01'),(2,NULL),(3,NULL),(4,NULL); +CREATE VIEW v1 AS +SELECT t1.pk AS pk, t1.a1 AS a1 FROM t1; +SELECT a1 BETWEEN (('2018-08-24')) AND (DEFAULT(pk)) FROM v1; +a1 BETWEEN (('2018-08-24')) AND (DEFAULT(pk)) +0 +NULL +NULL +NULL +SELECT a1 BETWEEN (('2018-08-24')) AND (~ DEFAULT(pk)) FROM v1; +a1 BETWEEN (('2018-08-24')) AND (~ DEFAULT(pk)) +0 +NULL +NULL +NULL +Warnings: +Warning 1292 Incorrect datetime value: '18446744073709551615' +DROP VIEW v1; +DROP TABLE t1; +# +# End of 10.2 tests +# diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index 3503b6d5bc6..98b5f968fe0 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -1857,3 +1857,24 @@ DROP TABLE t1,t2; --echo # --echo # End of 10.1 tests --echo # + +--echo # +--echo # MDEV-16217: Assertion `!table || (!table->read_set || +--echo # bitmap_is_set(table->read_set, field_index))' +--echo # failed in Field_num::get_date +--echo # +CREATE TABLE t1 (pk int default 0, a1 date); +INSERT INTO t1 VALUES (1,'1900-01-01'),(2,NULL),(3,NULL),(4,NULL); + +CREATE VIEW v1 AS +SELECT t1.pk AS pk, t1.a1 AS a1 FROM t1; + +SELECT a1 BETWEEN (('2018-08-24')) AND (DEFAULT(pk)) FROM v1; +SELECT a1 BETWEEN (('2018-08-24')) AND (~ DEFAULT(pk)) FROM v1; + +DROP VIEW v1; +DROP TABLE t1; + +--echo # +--echo # End of 10.2 tests +--echo # diff --git a/sql/item.h b/sql/item.h index 8fad8dadf22..54cd358112d 100644 --- a/sql/item.h +++ b/sql/item.h @@ -5649,6 +5649,15 @@ class Item_cache: public Item_basic_constant, example->split_sum_func2(thd, ref_pointer_array, fields, &example, flags); } Item *get_example() const { return example; } + /* + Functiuons like DEFAULT() are constant but still read from tables and + update them, so we should gave that chance to them in case of caching. + */ + virtual void update_used_tables() + { + if (example) + return example->update_used_tables(); + } virtual Item *convert_to_basic_const_item(THD *thd) { return 0; }; Item *derived_field_transformer_for_having(THD *thd, uchar *arg)
1 0
0 0
[Commits] 517009ca0fa: MDEV-16548: Innodb fails to start on older kernels that don't support F_DUPFD_CLOEXEC
by jan 07 Aug '18

07 Aug '18
revision-id: 517009ca0fa5f0e5b48b3d244a0b5bb0c44e90a8 (mariadb-10.1.34-47-g517009ca0fa) parent(s): 3b37edee1a5121e9523fa8a7f483185f402905e2 author: Jan Lindström committer: Jan Lindström timestamp: 2018-08-07 11:35:39 +0300 message: MDEV-16548: Innodb fails to start on older kernels that don't support F_DUPFD_CLOEXEC Add runtime check that fcntl() system call really supports F_DUPFD_CLOEXEC directive. --- storage/innobase/CMakeLists.txt | 27 +++++++++++++++++++++++++++ storage/innobase/handler/ha_innodb.cc | 2 +- storage/xtradb/CMakeLists.txt | 27 +++++++++++++++++++++++++++ storage/xtradb/handler/ha_innodb.cc | 2 +- 4 files changed, 56 insertions(+), 2 deletions(-) diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt index 2a45f05c463..7470f2985c0 100644 --- a/storage/innobase/CMakeLists.txt +++ b/storage/innobase/CMakeLists.txt @@ -246,6 +246,33 @@ IF(HAVE_IB_ATOMIC_PTHREAD_T_GCC) ADD_DEFINITIONS(-DHAVE_IB_ATOMIC_PTHREAD_T_GCC=1) ENDIF() +CHECK_C_SOURCE( +" +#include <unistd.h> +#include <fcntl.h> +#include <stdlib.h> +int main() { + char filename[] = "/tmp/mytemp.XXXXXX"; + int fd = mkstemp(filename); + if (fd != -1) { + int fd2=fcntl(fd, F_DUPFD_CLOEXEC, 0); + if (fd2 != -1) { + close(fd2); + close(fd); + unlink(filename); + return (0); + } + close (fd); + unlink(filename); + } + return (1); +}" +HAVE_IB_F_DUPFD_CLOEXEC) + +IF (HAVE_IB_F_DUPFD_CLOEXEC) + ADD_DEFINITIONS(-DHAVE_IB_F_DUPFD_CLOEXEC=1) +ENDIF() + CHECK_C_SOURCE_COMPILES("struct t1{ int a; char *b; }; struct t1 c= { .a=1, .b=0 }; main() { }" HAVE_C99_INITIALIZERS) ENDIF(NOT MSVC) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 5667efea5df..6843d90b0a9 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -2414,7 +2414,7 @@ innobase_mysql_tmpfile( } } #else -#ifdef F_DUPFD_CLOEXEC +#if defined(F_DUPFD_CLOEXEC) && defined(HAVE_IB_F_DUPFD_CLOEXEC) fd2 = fcntl(fd, F_DUPFD_CLOEXEC, 0); #else fd2 = dup(fd); diff --git a/storage/xtradb/CMakeLists.txt b/storage/xtradb/CMakeLists.txt index f5ec6fd746d..5ec5881a247 100644 --- a/storage/xtradb/CMakeLists.txt +++ b/storage/xtradb/CMakeLists.txt @@ -255,6 +255,33 @@ IF(HAVE_IB_ATOMIC_PTHREAD_T_GCC) ADD_DEFINITIONS(-DHAVE_IB_ATOMIC_PTHREAD_T_GCC=1) ENDIF() +CHECK_C_SOURCE( +" +#include <unistd.h> +#include <fcntl.h> +#include <stdlib.h> +int main() { + char filename[] = "/tmp/mytemp.XXXXXX"; + int fd = mkstemp(filename); + if (fd != -1) { + int fd2=fcntl(fd, F_DUPFD_CLOEXEC, 0); + if (fd2 != -1) { + close(fd2); + close(fd); + unlink(filename); + return (0); + } + close (fd); + unlink(filename); + } + return (1); +}" +HAVE_IB_F_DUPFD_CLOEXEC) + +IF (HAVE_IB_F_DUPFD_CLOEXEC) + ADD_DEFINITIONS(-DHAVE_IB_F_DUPFD_CLOEXEC=1) +ENDIF() + CHECK_C_SOURCE_COMPILES("struct t1{ int a; char *b; }; struct t1 c= { .a=1, .b=0 }; main() { }" HAVE_C99_INITIALIZERS) ENDIF(NOT MSVC) diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 3cd7cb6977b..fd62bc00ca4 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -2738,7 +2738,7 @@ innobase_mysql_tmpfile( } } #else -#ifdef F_DUPFD_CLOEXEC +#if defined(F_DUPFD_CLOEXEC) && defined(HAVE_IB_F_DUPFD_CLOEXEC) fd2 = fcntl(fd, F_DUPFD_CLOEXEC, 0); #else fd2 = dup(fd);
1 0
0 0
[Commits] d1c90870ed1: MDEV-15475: Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed on EXPLAIN EXTENDED with constant table and view
by Oleksandr Byelkin 06 Aug '18

06 Aug '18
revision-id: d1c90870ed114da62de8b12a71e2fba62724baa9 (mariadb-5.5.61-3-gd1c90870ed1) parent(s): 68ebfb31f215247d2fa08c8ed97a320191afc179 author: Oleksandr Byelkin committer: Oleksandr Byelkin timestamp: 2018-08-06 15:50:22 +0200 message: MDEV-15475: Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed on EXPLAIN EXTENDED with constant table and view Do not try to print value of the field in table if it is optimized out. EXPLAIN output still looks a bit strange (field from dual table, because table optimized out) but we do not indicate optimisations of ISNULL. --- mysql-test/r/func_isnull.result | 15 +++++++++++++++ mysql-test/t/func_isnull.test | 15 +++++++++++++++ sql/item.cc | 5 ++++- 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/func_isnull.result b/mysql-test/r/func_isnull.result index 88c5bfd5468..fd55b7be26c 100644 --- a/mysql-test/r/func_isnull.result +++ b/mysql-test/r/func_isnull.result @@ -106,5 +106,20 @@ Note 1003 select `test`.`t2`.`d1` AS `d1`,`test`.`t1`.`d1` AS `d1` from `test`.` DROP VIEW v1; DROP TABLE t1,t2; # +# MDEV-15475: Assertion `!table || (!table->read_set || +# bitmap_is_set(table->read_set, field_index))' +# failed on EXPLAIN EXTENDED with constant table and view +# +CREATE TABLE t1 (pk INT PRIMARY KEY) ENGINE=MyISAM; +CREATE VIEW v1 AS SELECT * FROM t1; +INSERT INTO t1 VALUES (1); +EXPLAIN EXTENDED SELECT ISNULL(pk) FROM v1; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00 +Warnings: +Note 1003 select isnull(`test`.`t1`.`pk`) AS `ISNULL(pk)` from dual +DROP VIEW v1; +DROP TABLE t1; +# # End of 5.5 tests # diff --git a/mysql-test/t/func_isnull.test b/mysql-test/t/func_isnull.test index 4c59fa3cbe8..2111b8f16bc 100644 --- a/mysql-test/t/func_isnull.test +++ b/mysql-test/t/func_isnull.test @@ -83,6 +83,21 @@ SELECT * FROM t2 LEFT JOIN v1 ON t2.d1=v1.d1 WHERE v1.d1 IS NULL; DROP VIEW v1; DROP TABLE t1,t2; + +--echo # +--echo # MDEV-15475: Assertion `!table || (!table->read_set || +--echo # bitmap_is_set(table->read_set, field_index))' +--echo # failed on EXPLAIN EXTENDED with constant table and view +--echo # + +CREATE TABLE t1 (pk INT PRIMARY KEY) ENGINE=MyISAM; +CREATE VIEW v1 AS SELECT * FROM t1; +INSERT INTO t1 VALUES (1); +EXPLAIN EXTENDED SELECT ISNULL(pk) FROM v1; +# Cleanup +DROP VIEW v1; +DROP TABLE t1; + --echo # --echo # End of 5.5 tests --echo # diff --git a/sql/item.cc b/sql/item.cc index 33c35f8c3e0..77be702bac5 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -6845,7 +6845,10 @@ Item *Item_field::update_value_transformer(uchar *select_arg) void Item_field::print(String *str, enum_query_type query_type) { if (field && field->table->const_table && - !(query_type & QT_NO_DATA_EXPANSION)) + !(query_type & QT_NO_DATA_EXPANSION) && + // and we was gping to read field value (it is not optimised out) + field->table->read_set && + bitmap_is_set(field->table->read_set, field->field_index)) { print_value(str); return;
1 0
0 0
[Commits] 3b37edee1a5: MDEV-13333: Deadlock failure that does not occur elsewhere
by jan 06 Aug '18

06 Aug '18
revision-id: 3b37edee1a5121e9523fa8a7f483185f402905e2 (mariadb-10.1.34-46-g3b37edee1a5) parent(s): 998b1c0e75a9512bfec308da19096cbced4150ad author: Jan Lindström committer: Jan Lindström timestamp: 2018-08-06 15:45:44 +0300 message: MDEV-13333: Deadlock failure that does not occur elsewhere InnoDB executed code that is mean to execute only when Galera is used and in bad luck one of the transactions is selected incorrectly as deadlock victim. Fixed by adding wsrep_on_trx() condition before entering actual Galera transaction handling. No always repeatable test case for this issue is known. --- storage/innobase/lock/lock0lock.cc | 5 +++-- storage/xtradb/lock/lock0lock.cc | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index 441fcace7c3..3970a559a4c 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -4963,7 +4963,7 @@ lock_table_create( UT_LIST_ADD_LAST(trx_locks, trx->lock.trx_locks, lock); #ifdef WITH_WSREP - if (c_lock) { + if (c_lock && wsrep_on_trx(trx)) { if (wsrep_thd_is_wsrep(trx->mysql_thd) && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { UT_LIST_INSERT_AFTER( @@ -5202,9 +5202,10 @@ lock_table_enqueue_waiting( /* Enqueue the lock request that will wait to be granted */ #ifdef WITH_WSREP - if (trx->lock.was_chosen_as_deadlock_victim) { + if (trx->lock.was_chosen_as_deadlock_victim && wsrep_on_trx(trx)) { return(DB_DEADLOCK); } + lock = lock_table_create(c_lock, table, mode | LOCK_WAIT, trx); #else lock = lock_table_create(table, mode | LOCK_WAIT, trx); diff --git a/storage/xtradb/lock/lock0lock.cc b/storage/xtradb/lock/lock0lock.cc index 549cc411f69..2183d281b78 100644 --- a/storage/xtradb/lock/lock0lock.cc +++ b/storage/xtradb/lock/lock0lock.cc @@ -5003,7 +5003,7 @@ lock_table_create( UT_LIST_ADD_LAST(trx_locks, trx->lock.trx_locks, lock); #ifdef WITH_WSREP - if (c_lock) { + if (c_lock && wsrep_on_trx(trx)) { if (wsrep_thd_is_wsrep(trx->mysql_thd) && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { UT_LIST_INSERT_AFTER( @@ -5244,9 +5244,10 @@ lock_table_enqueue_waiting( /* Enqueue the lock request that will wait to be granted */ #ifdef WITH_WSREP - if (trx->lock.was_chosen_as_deadlock_victim) { + if (trx->lock.was_chosen_as_deadlock_victim && wsrep_on_trx(trx)) { return(DB_DEADLOCK); } + lock = lock_table_create(c_lock, table, mode | LOCK_WAIT, trx); #else lock = lock_table_create(table, mode | LOCK_WAIT, trx);
1 0
0 0
[Commits] 422506fdd56: MDEV-13333: Deadlock failure that does not occur elsewhere
by jan 06 Aug '18

06 Aug '18
revision-id: 422506fdd5605eca6e23a35bd115ee5d40409f11 (mariadb-10.1.34-46-g422506fdd56) parent(s): 998b1c0e75a9512bfec308da19096cbced4150ad author: Jan Lindström committer: Jan Lindström timestamp: 2018-08-06 15:32:19 +0300 message: MDEV-13333: Deadlock failure that does not occur elsewhere InnoDB executed code that is mean to execute only when Galera is used and in bad luck one of the transactions is selected incorrectly as deadlock victim. Fixed by adding wsrep_on_trx() condition before entering actual Galera transaction handling. No always repeatable test case for this issue is known. --- storage/innobase/lock/lock0lock.cc | 5 +++-- storage/xtradb/lock/lock0lock.cc | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index 441fcace7c3..381127bf74e 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -4963,7 +4963,7 @@ lock_table_create( UT_LIST_ADD_LAST(trx_locks, trx->lock.trx_locks, lock); #ifdef WITH_WSREP - if (c_lock) { + if (c_lock && wsrep_on_trx(trx)) { if (wsrep_thd_is_wsrep(trx->mysql_thd) && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { UT_LIST_INSERT_AFTER( @@ -5202,9 +5202,10 @@ lock_table_enqueue_waiting( /* Enqueue the lock request that will wait to be granted */ #ifdef WITH_WSREP - if (trx->lock.was_chosen_as_deadlock_victim) { + if (wsrep_on_trx(trx) && trx->lock.was_chosen_as_deadlock_victim) { return(DB_DEADLOCK); } + lock = lock_table_create(c_lock, table, mode | LOCK_WAIT, trx); #else lock = lock_table_create(table, mode | LOCK_WAIT, trx); diff --git a/storage/xtradb/lock/lock0lock.cc b/storage/xtradb/lock/lock0lock.cc index 549cc411f69..87df0e8a75e 100644 --- a/storage/xtradb/lock/lock0lock.cc +++ b/storage/xtradb/lock/lock0lock.cc @@ -5003,7 +5003,7 @@ lock_table_create( UT_LIST_ADD_LAST(trx_locks, trx->lock.trx_locks, lock); #ifdef WITH_WSREP - if (c_lock) { + if (c_lock && wsrep_on_trx(trx)) { if (wsrep_thd_is_wsrep(trx->mysql_thd) && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { UT_LIST_INSERT_AFTER( @@ -5244,9 +5244,10 @@ lock_table_enqueue_waiting( /* Enqueue the lock request that will wait to be granted */ #ifdef WITH_WSREP - if (trx->lock.was_chosen_as_deadlock_victim) { + if (wsrep_on_trx(trx) && trx->lock.was_chosen_as_deadlock_victim) { return(DB_DEADLOCK); } + lock = lock_table_create(c_lock, table, mode | LOCK_WAIT, trx); #else lock = lock_table_create(table, mode | LOCK_WAIT, trx);
1 0
0 0
[Commits] 4a9686a91a7: Prevent reporting an error when performing table discovery
by vicentiu@mariadb.org 06 Aug '18

06 Aug '18
revision-id: 4a9686a91a7459a7476e36195fab0de8852e43b6 (mariadb-10.3.7-101-g4a9686a91a7) parent(s): 0c745c743c65ceb6533babdf21556b633e81566c author: Anel Husakovic committer: Vicențiu Ciorbaru timestamp: 2018-08-06 15:18:22 +0300 message: Prevent reporting an error when performing table discovery When performing table creation we check if a table exists. If storage engines that support table discovery are loaded, we also perform table discovery with those. Normally when a table is not found, my_error is called to signal this. However for this case a "table doesn't exist error" is not an actual problem so the error is caught and silenced. Avoid this entire juggling of errors by preventing a my_error call in the first place, with an additional flag when attempting to fetch the table share. --- sql/handler.cc | 78 ++++++++++++++-------------------------------------------- sql/table.cc | 12 ++++----- sql/table.h | 3 ++- 3 files changed, 26 insertions(+), 67 deletions(-) diff --git a/sql/handler.cc b/sql/handler.cc index 4f152cfd99c..a8e6b08cf42 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -5113,22 +5113,19 @@ static my_bool discover_handlerton(THD *thd, plugin_ref plugin, int ha_discover_table(THD *thd, TABLE_SHARE *share) { DBUG_ENTER("ha_discover_table"); - int found; - DBUG_ASSERT(share->error == OPEN_FRM_OPEN_ERROR); // share is not OK yet + int found = 0; - if (!engines_with_discover) - found= FALSE; - else if (share->db_plugin) - found= discover_handlerton(thd, share->db_plugin, share); - else - found= plugin_foreach(thd, discover_handlerton, - MYSQL_STORAGE_ENGINE_PLUGIN, share); - - if (!found) - open_table_error(share, OPEN_FRM_OPEN_ERROR, ENOENT); // not found + if (engines_with_discover) + { + if (share->db_plugin) + found = discover_handlerton(thd, share->db_plugin, share); + else + found = plugin_foreach(thd, discover_handlerton, + MYSQL_STORAGE_ENGINE_PLUGIN, share); + } - DBUG_RETURN(share->error != OPEN_FRM_OK); + DBUG_RETURN(found); } static my_bool file_ext_exists(char *path, size_t path_len, const char *ext) @@ -5163,43 +5160,6 @@ static my_bool discover_existence(THD *thd, plugin_ref plugin, return ht->discover_table_existence(ht, args->db, args->table_name); } -class Table_exists_error_handler : public Internal_error_handler -{ -public: - Table_exists_error_handler() - : m_handled_errors(0), m_unhandled_errors(0) - {} - - bool handle_condition(THD *thd, - uint sql_errno, - const char* sqlstate, - Sql_condition::enum_warning_level *level, - const char* msg, - Sql_condition ** cond_hdl) - { - *cond_hdl= NULL; - if (sql_errno == ER_NO_SUCH_TABLE || - sql_errno == ER_NO_SUCH_TABLE_IN_ENGINE || - sql_errno == ER_WRONG_OBJECT) - { - m_handled_errors++; - return TRUE; - } - - if (*level == Sql_condition::WARN_LEVEL_ERROR) - m_unhandled_errors++; - return FALSE; - } - - bool safely_trapped_errors() - { - return ((m_handled_errors > 0) && (m_unhandled_errors == 0)); - } - -private: - int m_handled_errors; - int m_unhandled_errors; -}; /** Check if a given table exists, without doing a full discover, if possible @@ -5298,24 +5258,24 @@ bool ha_table_exists(THD *thd, const LEX_CSTRING *db, const LEX_CSTRING *table_n if (need_full_discover_for_existence) { TABLE_LIST table; - uint flags = GTS_TABLE | GTS_VIEW; + uint flags = GTS_TABLE | GTS_VIEW | GTS_NO_ERROR_IF_MISSING; if (!hton) flags|= GTS_NOLOCK; - Table_exists_error_handler no_such_table_handler; - thd->push_internal_handler(&no_such_table_handler); table.init_one_table(db, table_name, 0, TL_READ); TABLE_SHARE *share= tdc_acquire_share(thd, &table, flags); - thd->pop_internal_handler(); - if (hton && share) + // Share returned, table exists. + if (share) { - *hton= share->db_type(); + if (hton) + *hton= share->db_type(); tdc_release_share(share); + DBUG_RETURN(TRUE); } - - // the table doesn't exist if we've caught ER_NO_SUCH_TABLE and nothing else - DBUG_RETURN(!no_such_table_handler.safely_trapped_errors()); + // No share, if errors have been reported, we assume the table exists. + if (thd->is_error()) + DBUG_RETURN(TRUE); } DBUG_RETURN(FALSE); diff --git a/sql/table.cc b/sql/table.cc index 8dedb926141..3c11ea6d918 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -573,7 +573,6 @@ inline bool is_system_table_name(const char *name, size_t length) enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags) { - bool error_given= false; File file; uchar *buf; uchar head[FRM_HEADER_SIZE]; @@ -602,8 +601,9 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags) { if ((flags & GTS_TABLE) && (flags & GTS_USE_DISCOVERY)) { - ha_discover_table(thd, share); - error_given= true; + if (!ha_discover_table(thd, share) && !(flags & GTS_NO_ERROR_IF_MISSING)) + open_table_error(share, OPEN_FRM_OPEN_ERROR, ENOENT); + DBUG_RETURN(share->error); } goto err_not_open; } @@ -668,16 +668,14 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags) frmlen= read_length + sizeof(head); share->init_from_binary_frm_image(thd, false, buf, frmlen); - error_given= true; // init_from_binary_frm_image has already called my_error() my_free(buf); - - goto err_not_open; + DBUG_RETURN(share->error); err: mysql_file_close(file, MYF(MY_WME)); err_not_open: - if (unlikely(share->error && !error_given)) + if (unlikely(share->error)) { share->open_errno= my_errno; open_table_error(share, share->error, share->open_errno); diff --git a/sql/table.h b/sql/table.h index 80f5e1283a3..df97b9ffbde 100644 --- a/sql/table.h +++ b/sql/table.h @@ -2876,7 +2876,8 @@ enum get_table_share_flags { GTS_VIEW = 2, GTS_NOLOCK = 4, GTS_USE_DISCOVERY = 8, - GTS_FORCE_DISCOVERY = 16 + GTS_FORCE_DISCOVERY = 16, + GTS_NO_ERROR_IF_MISSING = 32, }; size_t max_row_length(TABLE *table, MY_BITMAP const *cols, const uchar *data);
1 0
0 0
[Commits] 3e9d70e131b: MDEV-16765: Missing rows with pushdown condition defined with CASE using Item_cond
by Galina 06 Aug '18

06 Aug '18
revision-id: 3e9d70e131b3af88799cbc069e07f46b6f33ea67 (mariadb-10.2.16-66-g3e9d70e131b) parent(s): 4ddcb4eb46c62cf459936554d43351db740ba14d author: Galina Shalygina committer: Galina Shalygina timestamp: 2018-08-06 15:10:27 +0300 message: MDEV-16765: Missing rows with pushdown condition defined with CASE using Item_cond The bug appears because of the wrong pushdown into the WHERE clause of the materialized derived table/view work. For the excl_dep_on_grouping_fields() method that checks if the condition can be pushed into the WHERE clause the case when Item_cond is used is missing. For Item_cond elements this method always returns positive result (that condition can be pushed). So this condition is pushed even if is shouldn't be pushed. To fix it new Item_cond::excl_dep_on_grouping_fields() method is added. --- mysql-test/r/derived_cond_pushdown.result | 203 ++++++++++++++++++++++++++++++ mysql-test/t/derived_cond_pushdown.test | 58 +++++++++ sql/item_cmpfunc.cc | 13 ++ sql/item_cmpfunc.h | 1 + 4 files changed, 275 insertions(+) diff --git a/mysql-test/r/derived_cond_pushdown.result b/mysql-test/r/derived_cond_pushdown.result index 22b81ef48a5..9b64de41856 100644 --- a/mysql-test/r/derived_cond_pushdown.result +++ b/mysql-test/r/derived_cond_pushdown.result @@ -9874,3 +9874,206 @@ SELECT a FROM (SELECT "aa" a) t WHERE f1(t.a, (SELECT MAX('aa') FROM DUAL LIMIT a aa DROP FUNCTION f1; +# +# MDEV-16765: pushdown condition with the CASE structure +# defined with Item_cond item +# +CREATE TABLE t1(a INT, b INT); +INSERT INTO t1 VALUES (1,2), (3,4), (2,3); +SELECT * +FROM +( +SELECT CASE WHEN ((tab2.max_a=1) OR (tab2.max_a=2)) +THEN 1 ELSE 0 END AS max_a,b +FROM (SELECT MAX(a) as max_a,b FROM t1 GROUP BY t1.b) AS tab2 +) AS tab1 +WHERE (tab1.max_a=1); +max_a b +1 2 +1 3 +EXPLAIN FORMAT=JSON SELECT * +FROM +( +SELECT CASE WHEN ((tab2.max_a=1) OR (tab2.max_a=2)) +THEN 1 ELSE 0 END AS max_a,b +FROM (SELECT MAX(a) as max_a,b FROM t1 GROUP BY t1.b) AS tab2 +) AS tab1 +WHERE (tab1.max_a=1); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "<derived3>", + "access_type": "ALL", + "rows": 3, + "filtered": 100, + "attached_condition": "case when (tab2.max_a = 1 or tab2.max_a = 2) then 1 else 0 end = 1", + "materialized": { + "query_block": { + "select_id": 3, + "having_condition": "case when (max_a = 1 or max_a = 2) then 1 else 0 end = 1", + "filesort": { + "sort_key": "t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 3, + "filtered": 100 + } + } + } + } + } + } + } +} +SELECT * +FROM +( +SELECT CASE WHEN ((tab2.max_a=1) OR ((tab2.max_a>2) AND (tab2.max_a<4))) +THEN 1 ELSE 0 END AS max_a,b +FROM (SELECT MAX(a) as max_a,b FROM t1 GROUP BY t1.b) AS tab2 +) AS tab1 +WHERE (tab1.max_a=1); +max_a b +1 2 +1 4 +EXPLAIN FORMAT=JSON SELECT * +FROM +( +SELECT CASE WHEN ((tab2.max_a=1) OR ((tab2.max_a>2) AND (tab2.max_a<4))) +THEN 1 ELSE 0 END AS max_a,b +FROM (SELECT MAX(a) as max_a,b FROM t1 GROUP BY t1.b) AS tab2 +) AS tab1 +WHERE (tab1.max_a=1); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "<derived3>", + "access_type": "ALL", + "rows": 3, + "filtered": 100, + "attached_condition": "case when (tab2.max_a = 1 or tab2.max_a > 2 and tab2.max_a < 4) then 1 else 0 end = 1", + "materialized": { + "query_block": { + "select_id": 3, + "having_condition": "case when (max_a = 1 or max_a > 2 and max_a < 4) then 1 else 0 end = 1", + "filesort": { + "sort_key": "t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 3, + "filtered": 100 + } + } + } + } + } + } + } +} +SELECT * +FROM +( +SELECT CASE WHEN ((tab2.max_a>1) AND ((tab2.max_a=2) OR (tab2.max_a>2))) +THEN 1 ELSE 0 END AS max_a,b +FROM (SELECT MAX(a) as max_a,b FROM t1 GROUP BY t1.b) AS tab2 +) AS tab1 +WHERE (tab1.max_a=1); +max_a b +1 3 +1 4 +EXPLAIN FORMAT=JSON SELECT * +FROM +( +SELECT CASE WHEN ((tab2.max_a>1) AND ((tab2.max_a=2) OR (tab2.max_a>2))) +THEN 1 ELSE 0 END AS max_a,b +FROM (SELECT MAX(a) as max_a,b FROM t1 GROUP BY t1.b) AS tab2 +) AS tab1 +WHERE (tab1.max_a=1); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "<derived3>", + "access_type": "ALL", + "rows": 3, + "filtered": 100, + "attached_condition": "case when (tab2.max_a > 1 and (tab2.max_a = 2 or tab2.max_a > 2)) then 1 else 0 end = 1", + "materialized": { + "query_block": { + "select_id": 3, + "having_condition": "case when (max_a > 1 and (max_a = 2 or max_a > 2)) then 1 else 0 end = 1", + "filesort": { + "sort_key": "t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 3, + "filtered": 100 + } + } + } + } + } + } + } +} +SELECT * +FROM +( +SELECT CASE WHEN ((tab2.b=2) OR (tab2.b=4)) +THEN 1 ELSE 0 END AS max_a,b +FROM (SELECT MAX(a) as max_a,b FROM t1 GROUP BY t1.b) AS tab2 +) AS tab1 +WHERE (tab1.max_a=1); +max_a b +1 2 +1 4 +EXPLAIN FORMAT=JSON SELECT * +FROM +( +SELECT CASE WHEN ((tab2.b=2) OR (tab2.b=4)) +THEN 1 ELSE 0 END AS max_a,b +FROM (SELECT MAX(a) as max_a,b FROM t1 GROUP BY t1.b) AS tab2 +) AS tab1 +WHERE (tab1.max_a=1); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "<derived3>", + "access_type": "ALL", + "rows": 3, + "filtered": 100, + "attached_condition": "case when (tab2.b = 2 or tab2.b = 4) then 1 else 0 end = 1", + "materialized": { + "query_block": { + "select_id": 3, + "filesort": { + "sort_key": "t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 3, + "filtered": 100, + "attached_condition": "case when (t1.b = 2 or t1.b = 4) then 1 else 0 end = 1" + } + } + } + } + } + } + } +} +DROP TABLE t1; diff --git a/mysql-test/t/derived_cond_pushdown.test b/mysql-test/t/derived_cond_pushdown.test index d9d767f53ed..a8211ddd3e1 100644 --- a/mysql-test/t/derived_cond_pushdown.test +++ b/mysql-test/t/derived_cond_pushdown.test @@ -1920,3 +1920,61 @@ END;$$ DELIMITER ;$$ SELECT a FROM (SELECT "aa" a) t WHERE f1(t.a, (SELECT MAX('aa') FROM DUAL LIMIT 1)); DROP FUNCTION f1; + +--echo # +--echo # MDEV-16765: pushdown condition with the CASE structure +--echo # defined with Item_cond item +--echo # + +CREATE TABLE t1(a INT, b INT); +INSERT INTO t1 VALUES (1,2), (3,4), (2,3); + +LET $query= +SELECT * +FROM +( + SELECT CASE WHEN ((tab2.max_a=1) OR (tab2.max_a=2)) + THEN 1 ELSE 0 END AS max_a,b + FROM (SELECT MAX(a) as max_a,b FROM t1 GROUP BY t1.b) AS tab2 +) AS tab1 +WHERE (tab1.max_a=1); +EVAL $query; +EVAL EXPLAIN FORMAT=JSON $query; + +LET $query= +SELECT * +FROM +( + SELECT CASE WHEN ((tab2.max_a=1) OR ((tab2.max_a>2) AND (tab2.max_a<4))) + THEN 1 ELSE 0 END AS max_a,b + FROM (SELECT MAX(a) as max_a,b FROM t1 GROUP BY t1.b) AS tab2 +) AS tab1 +WHERE (tab1.max_a=1); +EVAL $query; +EVAL EXPLAIN FORMAT=JSON $query; + +LET $query= +SELECT * +FROM +( + SELECT CASE WHEN ((tab2.max_a>1) AND ((tab2.max_a=2) OR (tab2.max_a>2))) + THEN 1 ELSE 0 END AS max_a,b + FROM (SELECT MAX(a) as max_a,b FROM t1 GROUP BY t1.b) AS tab2 +) AS tab1 +WHERE (tab1.max_a=1); +EVAL $query; +EVAL EXPLAIN FORMAT=JSON $query; + +LET $query= +SELECT * +FROM +( + SELECT CASE WHEN ((tab2.b=2) OR (tab2.b=4)) + THEN 1 ELSE 0 END AS max_a,b + FROM (SELECT MAX(a) as max_a,b FROM t1 GROUP BY t1.b) AS tab2 +) AS tab1 +WHERE (tab1.max_a=1); +EVAL $query; +EVAL EXPLAIN FORMAT=JSON $query; + +DROP TABLE t1; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index f176a0a8193..6834820c0b5 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -4970,6 +4970,19 @@ Item *Item_cond::build_clone(THD *thd, MEM_ROOT *mem_root) } +bool Item_cond::excl_dep_on_grouping_fields(st_select_lex *sel) +{ + List_iterator_fast<Item> li(list); + Item *item; + while ((item= li++)) + { + if (!item->excl_dep_on_grouping_fields(sel)) + return false; + } + return true; +} + + void Item_cond_and::mark_as_condition_AND_part(TABLE_LIST *embedding) { List_iterator<Item> li(list); diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 41a51ee8d12..59ac5f56fe1 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -2224,6 +2224,7 @@ class Item_cond :public Item_bool_func Item_transformer transformer, uchar *arg_t); bool eval_not_null_tables(void *opt_arg); Item *build_clone(THD *thd, MEM_ROOT *mem_root); + bool excl_dep_on_grouping_fields(st_select_lex *sel); }; template <template<class> class LI, class T> class Item_equal_iterator;
1 0
0 0
[Commits] 4ddcb4e: MDEV-16750 JSON_SET mishandles unicode every second pair of arguments.
by holyfoot@askmonty.org 06 Aug '18

06 Aug '18
revision-id: 4ddcb4eb46c62cf459936554d43351db740ba14d (mariadb-10.2.16-65-g4ddcb4e) parent(s): fc324a5f87827e43f51d1a75e60b3d5abcd807e5 committer: Alexey Botchkov timestamp: 2018-08-06 13:37:09 +0400 message: MDEV-16750 JSON_SET mishandles unicode every second pair of arguments. The charset of temporary storage (Item_func_json_insert::tmp_js) was not properly set. --- mysql-test/r/func_json.result | 12 ++++++++++++ mysql-test/t/func_json.test | 8 ++++++++ sql/item_jsonfunc.cc | 6 +++--- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/func_json.result b/mysql-test/r/func_json.result index 2a2df00..e8b2fac 100644 --- a/mysql-test/r/func_json.result +++ b/mysql-test/r/func_json.result @@ -778,3 +778,15 @@ select REPLACE(JSON_VALUE(json_col, '$.key1'), 'null', '') = _latin1 X'53EC' fro REPLACE(JSON_VALUE(json_col, '$.key1'), 'null', '') = _latin1 X'53EC' 1 drop table t1; +# +# MDEV-16750 JSON_SET mishandles unicode every second pair of arguments. +# +SELECT JSON_SET('{}', '$.a', _utf8 0xC3B6); +JSON_SET('{}', '$.a', _utf8 0xC3B6) +{"a": "�"} +SELECT JSON_SET('{}', '$.a', _utf8 0xC3B6, '$.b', _utf8 0xC3B6); +JSON_SET('{}', '$.a', _utf8 0xC3B6, '$.b', _utf8 0xC3B6) +{"a": "�", "b": "�"} +SELECT JSON_SET('{}', '$.a', _utf8 X'C3B6', '$.x', 1, '$.b', _utf8 X'C3B6'); +JSON_SET('{}', '$.a', _utf8 X'C3B6', '$.x', 1, '$.b', _utf8 X'C3B6') +{"a": "�", "x": 1, "b": "�"} diff --git a/mysql-test/t/func_json.test b/mysql-test/t/func_json.test index 41e5204..fd5e3d7 100644 --- a/mysql-test/t/func_json.test +++ b/mysql-test/t/func_json.test @@ -440,3 +440,11 @@ select JSON_VALUE(json_col, '$.key1')= _latin1 X'53EC' from t1; select REPLACE(JSON_VALUE(json_col, '$.key1'), 'null', '') = _latin1 X'53EC' from t1; drop table t1; +--echo # +--echo # MDEV-16750 JSON_SET mishandles unicode every second pair of arguments. +--echo # + +SELECT JSON_SET('{}', '$.a', _utf8 0xC3B6); +SELECT JSON_SET('{}', '$.a', _utf8 0xC3B6, '$.b', _utf8 0xC3B6); +SELECT JSON_SET('{}', '$.a', _utf8 X'C3B6', '$.x', 1, '$.b', _utf8 X'C3B6'); + diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc index e9d38b7..4a83764 100644 --- a/sql/item_jsonfunc.cc +++ b/sql/item_jsonfunc.cc @@ -2384,8 +2384,9 @@ String *Item_func_json_insert::val_str(String *str) if ((null_value= args[0]->null_value)) return 0; - str->set_charset(js->charset()); - json_string_set_cs(&key_name, js->charset()); + str->set_charset(collation.collation); + tmp_js.set_charset(collation.collation); + json_string_set_cs(&key_name, collation.collation); for (n_arg=1, n_path=0; n_arg < arg_count; n_arg+=2, n_path++) { @@ -2599,7 +2600,6 @@ String *Item_func_json_insert::val_str(String *str) json_scan_start(&je, js->charset(),(const uchar *) js->ptr(), (const uchar *) js->ptr() + js->length()); str->length(0); - str->set_charset(js->charset()); if (json_nice(&je, str, Item_func_json_format::LOOSE)) goto js_error;
1 0
0 0
[Commits] fc324a5: MDEV-16869 String functions don't respect character set of JSON_VALUE.
by holyfoot@askmonty.org 05 Aug '18

05 Aug '18
revision-id: fc324a5f87827e43f51d1a75e60b3d5abcd807e5 (mariadb-10.2.16-64-gfc324a5) parent(s): affdd79c69dfe443cb9fda06ef156243e1967ac3 committer: Alexey Botchkov timestamp: 2018-08-05 18:33:17 +0400 message: MDEV-16869 String functions don't respect character set of JSON_VALUE. Item_func_json_value::val_str() produced string of wrong charset. --- mysql-test/r/func_json.result | 12 ++++++++++++ mysql-test/t/func_json.test | 11 +++++++++++ sql/item_jsonfunc.cc | 2 +- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/func_json.result b/mysql-test/r/func_json.result index 206f745..2a2df00 100644 --- a/mysql-test/r/func_json.result +++ b/mysql-test/r/func_json.result @@ -766,3 +766,15 @@ DROP TABLE t1; select json_array(1,uuid(),compress(5.140264e+307)); json_array(1,uuid(),compress(5.140264e+307)) NULL +# +# MDEV-16869 String functions don't respect character set of JSON_VALUE. +# +create table t1(json_col TEXT) DEFAULT CHARSET=latin1; +insert into t1 values (_latin1 X'7B226B657931223A2253EC227D'); +select JSON_VALUE(json_col, '$.key1')= _latin1 X'53EC' from t1; +JSON_VALUE(json_col, '$.key1')= _latin1 X'53EC' +1 +select REPLACE(JSON_VALUE(json_col, '$.key1'), 'null', '') = _latin1 X'53EC' from t1; +REPLACE(JSON_VALUE(json_col, '$.key1'), 'null', '') = _latin1 X'53EC' +1 +drop table t1; diff --git a/mysql-test/t/func_json.test b/mysql-test/t/func_json.test index c2cc00d..41e5204 100644 --- a/mysql-test/t/func_json.test +++ b/mysql-test/t/func_json.test @@ -429,3 +429,14 @@ DROP TABLE t1; select json_array(1,uuid(),compress(5.140264e+307)); + +--echo # +--echo # MDEV-16869 String functions don't respect character set of JSON_VALUE. +--echo # + +create table t1(json_col TEXT) DEFAULT CHARSET=latin1; +insert into t1 values (_latin1 X'7B226B657931223A2253EC227D'); +select JSON_VALUE(json_col, '$.key1')= _latin1 X'53EC' from t1; +select REPLACE(JSON_VALUE(json_col, '$.key1'), 'null', '') = _latin1 X'53EC' from t1; +drop table t1; + diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc index ac0d7e9..e9d38b7 100644 --- a/sql/item_jsonfunc.cc +++ b/sql/item_jsonfunc.cc @@ -479,7 +479,7 @@ String *Item_func_json_value::val_str(String *str) (const uchar *) js->ptr() + js->length()); str->length(0); - str->set_charset(&my_charset_utf8mb4_bin); + str->set_charset(collation.collation); path.cur_step= path.p.steps; continue_search:
1 0
0 0
  • ← Newer
  • 1
  • ...
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • ...
  • 1461
  • Older →

HyperKitty Powered by HyperKitty version 1.3.12.