From 1f1ee085fb65ed98c7adecd61f4e7bd9abb6ae26 Mon Sep 17 00:00:00 2001 From: Sergei Krivonos Date: Fri, 29 Oct 2021 01:32:21 +0300 Subject: MDEV-23766: Fix fix_semijoin_strategies_for_picked_join_order by assert --- sql/opt_subselect.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 7bd778e339f..cef6cd9c160 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -3819,9 +3819,9 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join) Json_writer_array semijoin_plan(thd, "join_order"); for (i= first + sjm->tables; i <= tablenr; i++) { + Json_writer_object trace_one_table(thd); if (unlikely(thd->trace_started())) { - Json_writer_object trace_one_table(thd); trace_one_table.add_table_name(join->best_positions[i].table); } best_access_path(join, join->best_positions[i].table, rem_tables, @@ -3858,9 +3858,9 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join) Json_writer_array semijoin_plan(thd, "join_order"); for (idx= first; idx <= tablenr; idx++) { + Json_writer_object trace_one_table(thd); if (unlikely(thd->trace_started())) { - Json_writer_object trace_one_table(thd); trace_one_table.add_table_name(join->best_positions[idx].table); } if (join->best_positions[idx].use_join_buffer) @@ -3897,9 +3897,9 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join) Json_writer_array semijoin_plan(thd, "join_order"); for (idx= first; idx <= tablenr; idx++) { + Json_writer_object trace_one_table(thd); if (unlikely(thd->trace_started())) { - Json_writer_object trace_one_table(thd); trace_one_table.add_table_name(join->best_positions[idx].table); } if (join->best_positions[idx].use_join_buffer || (idx == first)) -- cgit v1.2.1 From cf047efd42ab64d730e2b84c7482e56b695678ef Mon Sep 17 00:00:00 2001 From: Sergei Krivonos Date: Tue, 2 Nov 2021 14:01:54 +0200 Subject: MDEV-23766: Fix get_best_disjunct_quick by assert: in test main.range_vs_index_merge one path requires named JSON object: assert.c:0(.annobin_assert.c_end)[0x7fe9d2270a76] sql/my_json_writer.cc:43(Json_writer::on_start_object())[0x555e284f048a] sql/my_json_writer.cc:59(Json_writer::start_object())[0x555e284ee6e8] sql/my_json_writer.h:377(Json_writer_object::Json_writer_object(THD*))[0x555e281dce11] sql/opt_range.cc:5137(get_best_disjunct_quick(PARAM*, SEL_IMERGE*, double))[0x555e287c576b] sql/opt_range.cc:5492(merge_same_index_scans(PARAM*, SEL_IMERGE*, TRP_INDEX_MERGE*, double))[0x555e287c6cf6] sql/opt_range.cc:5287(get_best_disjunct_quick(PARAM*, SEL_IMERGE*, double))[0x555e287c607a] sql/opt_range.cc:3000(SQL_SELECT::test_quick_select another one requires unnamed JSON: mariadbd: /home/name/server/sql/my_json_writer.cc:379: bool Single_line_formatting_helper::on_add_member(const char*, size_t): Assertion `state== INACTIVE || state == assert.c:0(.annobin_assert.c_end)[0x7f33d8df8a76] sql/my_json_writer.cc:380(Single_line_formatting_helper::on_add_member(char const*, unsigned long))[0x558362f6a717] sql/my_json_writer.cc:150(Json_writer::add_member(char const*, unsigned long))[0x558362f69a91] sql/my_json_writer.cc:146(Json_writer::add_member(char const*))[0x558362f69a5f] sql/my_json_writer.h:383(Json_writer_object::Json_writer_object(THD*, char const*))[0x558362ceccaa] sql/opt_range.cc:5139(get_best_disjunct_quick(PARAM*, SEL_IMERGE*, double))[0x5583632407d0] sql/opt_range.cc:3000(SQL_SELECT::test_quick_select --- sql/opt_range.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'sql') diff --git a/sql/opt_range.cc b/sql/opt_range.cc index d47aa1ee41e..122b00f4d57 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -371,7 +371,7 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param, double read_time); static TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge, - double read_time); + double read_time, bool named_trace= false); static TABLE_READ_PLAN *merge_same_index_scans(PARAM *param, SEL_IMERGE *imerge, TRP_INDEX_MERGE *imerge_trp, @@ -5052,7 +5052,7 @@ double get_sweep_read_cost(const PARAM *param, ha_rows records) static TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge, - double read_time) + double read_time, bool named_trace) { SEL_TREE **ptree; TRP_INDEX_MERGE *imerge_trp= NULL; @@ -5101,7 +5101,9 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge, n_child_scans))) DBUG_RETURN(NULL); - Json_writer_object trace_best_disjunct(thd); + Json_writer_object trace_best_disjunct = named_trace + ? Json_writer_object(thd, "best_disjunct_quick") + : Json_writer_object(thd); Json_writer_array to_merge(thd, "indexes_to_merge"); /* Collect best 'range' scan for each of disjuncts, and, while doing so, @@ -5459,7 +5461,7 @@ TABLE_READ_PLAN *merge_same_index_scans(PARAM *param, SEL_IMERGE *imerge, DBUG_ASSERT(imerge->trees_next>imerge->trees); if (imerge->trees_next-imerge->trees > 1) - trp= get_best_disjunct_quick(param, imerge, read_time); + trp= get_best_disjunct_quick(param, imerge, read_time, true); else { /* -- cgit v1.2.1 From b17576322b600f53c7a0b74cf14830ad5bbad98e Mon Sep 17 00:00:00 2001 From: Sergei Krivonos Date: Mon, 25 Oct 2021 00:19:37 +0300 Subject: MDEV-23766: add Json_writer consistency asserts to check array/object sequence --- sql/my_json_writer.cc | 138 +++++++++++++++++++++++++++++++++++--------------- sql/my_json_writer.h | 20 ++++++++ 2 files changed, 116 insertions(+), 42 deletions(-) (limited to 'sql') diff --git a/sql/my_json_writer.cc b/sql/my_json_writer.cc index f4cf8204d61..ea20854eb1e 100644 --- a/sql/my_json_writer.cc +++ b/sql/my_json_writer.cc @@ -18,6 +18,14 @@ #include "sql_string.h" #include "my_json_writer.h" +#ifndef NDEBUG +bool Json_writer::named_item_expected() const +{ + return named_items_expectation.size() + && named_items_expectation.back(); +} +#endif + void Json_writer::append_indent() { if (!document_start) @@ -26,9 +34,27 @@ void Json_writer::append_indent() output.append(' '); } -void Json_writer::start_object() +inline void Json_writer::on_start_object() { +#ifndef NDEBUG + if(!is_on_fmt_helper_call) + { + DBUG_ASSERT(got_name == named_item_expected()); + named_items_expectation.push_back(true); + } + + bool was_on_fmt_helper_call= is_on_fmt_helper_call; + is_on_fmt_helper_call= true; +#endif fmt_helper.on_start_object(); +#ifndef NDEBUG + is_on_fmt_helper_call= was_on_fmt_helper_call; +#endif +} + +void Json_writer::start_object() +{ + on_start_object(); if (!element_started) start_element(); @@ -38,11 +64,36 @@ void Json_writer::start_object() first_child=true; element_started= false; document_start= false; +#ifndef NDEBUG + got_name= false; +#endif +} + +bool Json_writer::on_start_array() +{ +#ifndef NDEBUG + bool was_on_fmt_helper_call= is_on_fmt_helper_call; + is_on_fmt_helper_call= true; +#endif + bool helped= fmt_helper.on_start_array(); +#ifndef NDEBUG + is_on_fmt_helper_call= was_on_fmt_helper_call; +#endif + return helped; } void Json_writer::start_array() { - if (fmt_helper.on_start_array()) +#ifndef NDEBUG + if(!is_on_fmt_helper_call) + { + DBUG_ASSERT(got_name == named_item_expected()); + named_items_expectation.push_back(false); + got_name= false; + } +#endif + + if (on_start_array()) return; if (!element_started) @@ -58,6 +109,11 @@ void Json_writer::start_array() void Json_writer::end_object() { +#ifndef NDEBUG + named_items_expectation.pop_back(); + DBUG_ASSERT(!got_name); + got_name= false; +#endif indent_level-=INDENT_SIZE; if (!first_child) append_indent(); @@ -68,6 +124,10 @@ void Json_writer::end_object() void Json_writer::end_array() { +#ifndef NDEBUG + named_items_expectation.pop_back(); + got_name= false; +#endif if (fmt_helper.on_end_array()) return; indent_level-=INDENT_SIZE; @@ -80,31 +140,25 @@ void Json_writer::end_array() Json_writer& Json_writer::add_member(const char *name) { size_t len= strlen(name); - if (fmt_helper.on_add_member(name, len)) - return *this; // handled - - // assert that we are in an object - DBUG_ASSERT(!element_started); - start_element(); - - output.append('"'); - output.append(name, len); - output.append("\": ", 3); - return *this; + return add_member(name, len); } Json_writer& Json_writer::add_member(const char *name, size_t len) { - if (fmt_helper.on_add_member(name, len)) - return *this; // handled - - // assert that we are in an object - DBUG_ASSERT(!element_started); - start_element(); + if (!fmt_helper.on_add_member(name, len)) + { + // assert that we are in an object + DBUG_ASSERT(!element_started); + start_element(); - output.append('"'); - output.append(name, len); - output.append("\": "); + output.append('"'); + output.append(name, len); + output.append("\": ", 3); + } +#ifndef NDEBUG + if (!is_on_fmt_helper_call) + got_name= true; +#endif return *this; } @@ -200,19 +254,13 @@ void Json_writer::add_null() void Json_writer::add_unquoted_str(const char* str) { size_t len= strlen(str); - if (fmt_helper.on_add_str(str, len)) - return; - - if (!element_started) - start_element(); - - output.append(str, len); - element_started= false; + add_unquoted_str(str, len); } void Json_writer::add_unquoted_str(const char* str, size_t len) { - if (fmt_helper.on_add_str(str, len)) + DBUG_ASSERT(is_on_fmt_helper_call || got_name == named_item_expected()); + if (on_add_str(str, len)) return; if (!element_started) @@ -222,19 +270,24 @@ void Json_writer::add_unquoted_str(const char* str, size_t len) element_started= false; } +inline bool Json_writer::on_add_str(const char *str, size_t num_bytes) +{ +#ifndef NDEBUG + got_name= false; + bool was_on_fmt_helper_call= is_on_fmt_helper_call; + is_on_fmt_helper_call= true; +#endif + bool helped= fmt_helper.on_add_str(str, num_bytes); +#ifndef NDEBUG + is_on_fmt_helper_call= was_on_fmt_helper_call; +#endif + return helped; +} + void Json_writer::add_str(const char *str) { size_t len= strlen(str); - if (fmt_helper.on_add_str(str, len)) - return; - - if (!element_started) - start_element(); - - output.append('"'); - output.append(str, len); - output.append('"'); - element_started= false; + add_str(str, len); } /* @@ -243,7 +296,8 @@ void Json_writer::add_str(const char *str) void Json_writer::add_str(const char* str, size_t num_bytes) { - if (fmt_helper.on_add_str(str, num_bytes)) + DBUG_ASSERT(is_on_fmt_helper_call || got_name == named_item_expected()); + if (on_add_str(str, num_bytes)) return; if (!element_started) diff --git a/sql/my_json_writer.h b/sql/my_json_writer.h index bc8002de529..94cd438bbb0 100644 --- a/sql/my_json_writer.h +++ b/sql/my_json_writer.h @@ -181,6 +181,17 @@ private: class Json_writer { +#ifndef NDEBUG + + std::vector named_items_expectation; + + bool named_item_expected() const; + + bool got_name; + bool is_on_fmt_helper_call; + +#endif + public: /* Add a member. We must be in an object. */ Json_writer& add_member(const char *name); @@ -204,6 +215,11 @@ public: private: void add_unquoted_str(const char* val); void add_unquoted_str(const char* val, size_t len); + + bool on_add_str(const char *str, size_t num_bytes); + bool on_start_array(); + void on_start_object(); + public: /* Start a child object */ void start_object(); @@ -221,6 +237,10 @@ public: size_t get_truncated_bytes() { return output.get_truncated_bytes(); } Json_writer() : +#ifndef NDEBUG + got_name(false), + is_on_fmt_helper_call(false), +#endif indent_level(0), document_start(true), element_started(false), first_child(true) { -- cgit v1.2.1 From 1a3570dec35733e725cc6000a06ec666facf4235 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Fri, 28 Jun 2019 13:21:39 +0200 Subject: improve build, allow sql library to be built in parallel with builtins --- sql/CMakeLists.txt | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 7154e3dbe44..4dd34e80f2d 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -145,11 +145,11 @@ SET (SQL_SOURCE ${WSREP_SOURCES} table_cache.cc encryption.cc temporary_tables.cc proxy_protocol.cc backup.cc xa.cc - ${CMAKE_CURRENT_BINARY_DIR}/sql_builtin.cc ${CMAKE_CURRENT_BINARY_DIR}/sql_yacc.cc ${CMAKE_CURRENT_BINARY_DIR}/sql_yacc_ora.cc ${CMAKE_CURRENT_BINARY_DIR}/lex_hash.h ${CMAKE_CURRENT_BINARY_DIR}/lex_token.h + ${GEN_SOURCES} ${MYSYS_LIBWRAP_SOURCE} ) @@ -177,13 +177,20 @@ RECOMPILE_FOR_EMBEDDED) ADD_LIBRARY(sql STATIC ${SQL_SOURCE}) DTRACE_INSTRUMENT(sql) -TARGET_LINK_LIBRARIES(sql ${MYSQLD_STATIC_PLUGIN_LIBS} +TARGET_LINK_LIBRARIES(sql mysys mysys_ssl dbug strings vio pcre ${LIBWRAP} ${LIBCRYPT} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT} ${WSREP_LIB} ${SSL_LIBRARIES} ${LIBSYSTEMD}) +FOREACH(se aria partition perfschema sql_sequence) + # These engines are used directly in sql sources. + IF(TARGET ${se}) + TARGET_LINK_LIBRARIES(sql ${se}) + ENDIF() +ENDFOREACH() + IF(WIN32) SET(MYSQLD_SOURCE main.cc nt_servc.cc message.rc) TARGET_LINK_LIBRARIES(sql psapi) @@ -267,6 +274,9 @@ IF(MSVC AND NOT WITHOUT_DYNAMIC_PLUGINS) SET_TARGET_PROPERTIES(mysqld_import_lib PROPERTIES IMPORTED_LOCATION ${MYSQLD_LIB}) ENDIF() +ADD_LIBRARY( sql_builtins ${CMAKE_CURRENT_BINARY_DIR}/sql_builtin.cc) +TARGET_LINK_LIBRARIES(sql_builtins ${MYSQLD_STATIC_PLUGIN_LIBS}) + MYSQL_ADD_EXECUTABLE(mysqld ${MYSQLD_SOURCE} DESTINATION ${INSTALL_SBINDIR} COMPONENT Server) IF(APPLE) @@ -294,7 +304,8 @@ IF(NOT WITHOUT_DYNAMIC_PLUGINS) ENDIF() ENDIF(NOT WITHOUT_DYNAMIC_PLUGINS) -TARGET_LINK_LIBRARIES(mysqld LINK_PRIVATE sql) +TARGET_LINK_LIBRARIES(mysqld LINK_PRIVATE sql sql_builtins) + # Provide plugins with minimal set of libraries SET(INTERFACE_LIBS ${LIBRT}) -- cgit v1.2.1 From e45f7f485a4c8133962a4082636412745ed07093 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Sat, 29 Jun 2019 15:28:20 +0300 Subject: =?UTF-8?q?In=20case=20WITH=5FWSREP=20is=20enabled,=20build=20wsre?= =?UTF-8?q?p=20as=20plugin=20If=20it=20is=20not=20enabled,=20build=20wsrep?= =?UTF-8?q?=20as=20static=20"stub"=20library=20from=20wsrep=5Fdummy.cc=20?= =?UTF-8?q?=C2=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allow static plugins to export symbols (on Unix) wsrep_info relies on wsrep defined symbols (e.g LOCK_wsrep_config_state) exported from mysqld --- sql/CMakeLists.txt | 9 ++++----- sql/sql_builtin.cc.in | 6 ------ 2 files changed, 4 insertions(+), 11 deletions(-) (limited to 'sql') diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 4dd34e80f2d..ec3b0c528bb 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -36,9 +36,10 @@ IF(WITH_WSREP AND NOT EMBEDDED_LIBRARY) wsrep_plugin.cc service_wsrep.cc ) - SET(WSREP_LIB wsrep-lib wsrep_api_v26) + MYSQL_ADD_PLUGIN(wsrep ${WSREP_SOURCES} MANDATORY EXPORT_SYMBOLS LINK_LIBRARIES wsrep-lib wsrep_api_v26) ELSE() - SET(WSREP_SOURCES wsrep_dummy.cc) + ADD_LIBRARY(wsrep STATIC wsrep_dummy.cc) + ADD_DEPENDENCIES(wsrep GenError) ENDIF() INCLUDE_DIRECTORIES( @@ -142,7 +143,6 @@ SET (SQL_SOURCE opt_split.cc rowid_filter.cc rowid_filter.h opt_trace.cc - ${WSREP_SOURCES} table_cache.cc encryption.cc temporary_tables.cc proxy_protocol.cc backup.cc xa.cc ${CMAKE_CURRENT_BINARY_DIR}/sql_yacc.cc @@ -180,11 +180,10 @@ DTRACE_INSTRUMENT(sql) TARGET_LINK_LIBRARIES(sql mysys mysys_ssl dbug strings vio pcre ${LIBWRAP} ${LIBCRYPT} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT} - ${WSREP_LIB} ${SSL_LIBRARIES} ${LIBSYSTEMD}) -FOREACH(se aria partition perfschema sql_sequence) +FOREACH(se aria partition perfschema sql_sequence wsrep) # These engines are used directly in sql sources. IF(TARGET ${se}) TARGET_LINK_LIBRARIES(sql ${se}) diff --git a/sql/sql_builtin.cc.in b/sql/sql_builtin.cc.in index 5ac044afd5d..810f98a876c 100644 --- a/sql/sql_builtin.cc.in +++ b/sql/sql_builtin.cc.in @@ -32,9 +32,6 @@ extern builtin_maria_plugin @mysql_mandatory_plugins@ @mysql_optional_plugins@ builtin_maria_binlog_plugin, -#ifdef WITH_WSREP - builtin_maria_wsrep_plugin, -#endif /* WITH_WSREP */ builtin_maria_mysql_password_plugin; struct st_maria_plugin *mysql_optional_plugins[]= @@ -45,8 +42,5 @@ struct st_maria_plugin *mysql_optional_plugins[]= struct st_maria_plugin *mysql_mandatory_plugins[]= { builtin_maria_binlog_plugin, builtin_maria_mysql_password_plugin, -#ifdef WITH_WSREP - builtin_maria_wsrep_plugin, -#endif /* WITH_WSREP */ @mysql_mandatory_plugins@ 0 }; -- cgit v1.2.1 From c9b5b9321f383ff05536466e6aaad7cab7c7ccd0 Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Fri, 5 Nov 2021 14:36:59 +0300 Subject: MDEV-23766: Make Json_writer assert when one tries to author invalid JSON Code cleanup: Remove Json_writer::is_on_fmt_helper_call. We already maintain this state in fmt_helper. --- sql/my_json_writer.cc | 30 +++++++----------------------- sql/my_json_writer.h | 14 ++++++++++---- 2 files changed, 17 insertions(+), 27 deletions(-) (limited to 'sql') diff --git a/sql/my_json_writer.cc b/sql/my_json_writer.cc index ea20854eb1e..1c02ca39e22 100644 --- a/sql/my_json_writer.cc +++ b/sql/my_json_writer.cc @@ -37,19 +37,13 @@ void Json_writer::append_indent() inline void Json_writer::on_start_object() { #ifndef NDEBUG - if(!is_on_fmt_helper_call) + if(!fmt_helper.is_making_writer_calls()) { DBUG_ASSERT(got_name == named_item_expected()); named_items_expectation.push_back(true); } - - bool was_on_fmt_helper_call= is_on_fmt_helper_call; - is_on_fmt_helper_call= true; #endif fmt_helper.on_start_object(); -#ifndef NDEBUG - is_on_fmt_helper_call= was_on_fmt_helper_call; -#endif } void Json_writer::start_object() @@ -71,21 +65,14 @@ void Json_writer::start_object() bool Json_writer::on_start_array() { -#ifndef NDEBUG - bool was_on_fmt_helper_call= is_on_fmt_helper_call; - is_on_fmt_helper_call= true; -#endif bool helped= fmt_helper.on_start_array(); -#ifndef NDEBUG - is_on_fmt_helper_call= was_on_fmt_helper_call; -#endif return helped; } void Json_writer::start_array() { #ifndef NDEBUG - if(!is_on_fmt_helper_call) + if(!fmt_helper.is_making_writer_calls()) { DBUG_ASSERT(got_name == named_item_expected()); named_items_expectation.push_back(false); @@ -156,7 +143,7 @@ Json_writer& Json_writer::add_member(const char *name, size_t len) output.append("\": ", 3); } #ifndef NDEBUG - if (!is_on_fmt_helper_call) + if (!fmt_helper.is_making_writer_calls()) got_name= true; #endif return *this; @@ -259,7 +246,8 @@ void Json_writer::add_unquoted_str(const char* str) void Json_writer::add_unquoted_str(const char* str, size_t len) { - DBUG_ASSERT(is_on_fmt_helper_call || got_name == named_item_expected()); + DBUG_ASSERT(fmt_helper.is_making_writer_calls() || + got_name == named_item_expected()); if (on_add_str(str, len)) return; @@ -274,13 +262,8 @@ inline bool Json_writer::on_add_str(const char *str, size_t num_bytes) { #ifndef NDEBUG got_name= false; - bool was_on_fmt_helper_call= is_on_fmt_helper_call; - is_on_fmt_helper_call= true; #endif bool helped= fmt_helper.on_add_str(str, num_bytes); -#ifndef NDEBUG - is_on_fmt_helper_call= was_on_fmt_helper_call; -#endif return helped; } @@ -296,7 +279,8 @@ void Json_writer::add_str(const char *str) void Json_writer::add_str(const char* str, size_t num_bytes) { - DBUG_ASSERT(is_on_fmt_helper_call || got_name == named_item_expected()); + DBUG_ASSERT(fmt_helper.is_making_writer_calls() || + got_name == named_item_expected()); if (on_add_str(str, num_bytes)) return; diff --git a/sql/my_json_writer.h b/sql/my_json_writer.h index 94cd438bbb0..50b277a5052 100644 --- a/sql/my_json_writer.h +++ b/sql/my_json_writer.h @@ -92,9 +92,18 @@ public: bool on_end_array(); void on_start_object(); // on_end_object() is not needed. - + bool on_add_str(const char *str, size_t num_bytes); + /* + Returns true if the helper is flushing its buffer and is probably + making calls back to its Json_writer. (The Json_writer uses this + function to avoid re-doing the processing that it has already done + before making a call to fmt_helper) + */ + bool is_making_writer_calls() const { return state == DISABLED; } + +private: void flush_on_one_line(); void disable_and_flush(); }; @@ -188,8 +197,6 @@ class Json_writer bool named_item_expected() const; bool got_name; - bool is_on_fmt_helper_call; - #endif public: @@ -239,7 +246,6 @@ public: Json_writer() : #ifndef NDEBUG got_name(false), - is_on_fmt_helper_call(false), #endif indent_level(0), document_start(true), element_started(false), first_child(true) -- cgit v1.2.1 From 5e988ff80f51e80f4d74477c4a22a065472317d4 Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Fri, 5 Nov 2021 20:01:43 +0300 Subject: MDEV-23766: Make Json_writer assert when one tries to author invalid JSON - Add unit test. --- sql/my_json_writer.cc | 14 +++++++------- sql/my_json_writer.h | 22 +++++++++++++++++++++- 2 files changed, 28 insertions(+), 8 deletions(-) (limited to 'sql') diff --git a/sql/my_json_writer.cc b/sql/my_json_writer.cc index 1c02ca39e22..81f7593c23f 100644 --- a/sql/my_json_writer.cc +++ b/sql/my_json_writer.cc @@ -39,7 +39,7 @@ inline void Json_writer::on_start_object() #ifndef NDEBUG if(!fmt_helper.is_making_writer_calls()) { - DBUG_ASSERT(got_name == named_item_expected()); + VALIDITY_ASSERT(got_name == named_item_expected()); named_items_expectation.push_back(true); } #endif @@ -74,7 +74,7 @@ void Json_writer::start_array() #ifndef NDEBUG if(!fmt_helper.is_making_writer_calls()) { - DBUG_ASSERT(got_name == named_item_expected()); + VALIDITY_ASSERT(got_name == named_item_expected()); named_items_expectation.push_back(false); got_name= false; } @@ -98,7 +98,7 @@ void Json_writer::end_object() { #ifndef NDEBUG named_items_expectation.pop_back(); - DBUG_ASSERT(!got_name); + VALIDITY_ASSERT(!got_name); got_name= false; #endif indent_level-=INDENT_SIZE; @@ -246,8 +246,8 @@ void Json_writer::add_unquoted_str(const char* str) void Json_writer::add_unquoted_str(const char* str, size_t len) { - DBUG_ASSERT(fmt_helper.is_making_writer_calls() || - got_name == named_item_expected()); + VALIDITY_ASSERT(fmt_helper.is_making_writer_calls() || + got_name == named_item_expected()); if (on_add_str(str, len)) return; @@ -279,8 +279,8 @@ void Json_writer::add_str(const char *str) void Json_writer::add_str(const char* str, size_t num_bytes) { - DBUG_ASSERT(fmt_helper.is_making_writer_calls() || - got_name == named_item_expected()); + VALIDITY_ASSERT(fmt_helper.is_making_writer_calls() || + got_name == named_item_expected()); if (on_add_str(str, num_bytes)) return; diff --git a/sql/my_json_writer.h b/sql/my_json_writer.h index 50b277a5052..6f9ae73c5ee 100644 --- a/sql/my_json_writer.h +++ b/sql/my_json_writer.h @@ -16,7 +16,17 @@ #ifndef JSON_WRITER_INCLUDED #define JSON_WRITER_INCLUDED #include "my_base.h" + +#ifdef JSON_WRITER_UNIT_TEST +#include "sql_string.h" +#include +// Also, mock objects are defined in my_json_writer-t.cc +#define VALIDITY_ASSERT(x) if ((!x)) this->invalid_json= true; +#else #include "sql_select.h" +#define VALIDITY_ASSERT(x) DBUG_ASSERT(x) +#endif + class Opt_trace_stmt; class Opt_trace_context; class Json_writer; @@ -191,12 +201,22 @@ private: class Json_writer { #ifndef NDEBUG - + /* + In debug mode, Json_writer will fail and assertion if one attempts to + produce an invalid JSON document (e.g. JSON array having named elements). + */ std::vector named_items_expectation; bool named_item_expected() const; bool got_name; + +#ifdef JSON_WRITER_UNIT_TEST +public: + // When compiled for unit test, creating invalid JSON will set this to true + // instead of an assertion. + bool invalid_json= false; +#endif #endif public: -- cgit v1.2.1 From e9b76b896a5cec9804e653f7df117c49284cabba Mon Sep 17 00:00:00 2001 From: Sergei Krivonos Date: Mon, 8 Nov 2021 21:11:05 +0200 Subject: MDEV-23766: fix by my_json_writer test --- sql/my_json_writer.cc | 26 +++++++++++--------------- sql/my_json_writer.h | 10 ++++++---- 2 files changed, 17 insertions(+), 19 deletions(-) (limited to 'sql') diff --git a/sql/my_json_writer.cc b/sql/my_json_writer.cc index 81f7593c23f..8e35b25b822 100644 --- a/sql/my_json_writer.cc +++ b/sql/my_json_writer.cc @@ -18,7 +18,7 @@ #include "sql_string.h" #include "my_json_writer.h" -#ifndef NDEBUG +#if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST) bool Json_writer::named_item_expected() const { return named_items_expectation.size() @@ -36,7 +36,7 @@ void Json_writer::append_indent() inline void Json_writer::on_start_object() { -#ifndef NDEBUG +#if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST) if(!fmt_helper.is_making_writer_calls()) { VALIDITY_ASSERT(got_name == named_item_expected()); @@ -58,20 +58,14 @@ void Json_writer::start_object() first_child=true; element_started= false; document_start= false; -#ifndef NDEBUG +#if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST) got_name= false; #endif } -bool Json_writer::on_start_array() -{ - bool helped= fmt_helper.on_start_array(); - return helped; -} - void Json_writer::start_array() { -#ifndef NDEBUG +#if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST) if(!fmt_helper.is_making_writer_calls()) { VALIDITY_ASSERT(got_name == named_item_expected()); @@ -80,7 +74,7 @@ void Json_writer::start_array() } #endif - if (on_start_array()) + if (fmt_helper.on_start_array()) return; if (!element_started) @@ -96,7 +90,8 @@ void Json_writer::start_array() void Json_writer::end_object() { -#ifndef NDEBUG +#if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST) + VALIDITY_ASSERT(named_item_expected()); named_items_expectation.pop_back(); VALIDITY_ASSERT(!got_name); got_name= false; @@ -111,7 +106,8 @@ void Json_writer::end_object() void Json_writer::end_array() { -#ifndef NDEBUG +#if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST) + VALIDITY_ASSERT(!named_item_expected()); named_items_expectation.pop_back(); got_name= false; #endif @@ -142,7 +138,7 @@ Json_writer& Json_writer::add_member(const char *name, size_t len) output.append(name, len); output.append("\": ", 3); } -#ifndef NDEBUG +#if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST) if (!fmt_helper.is_making_writer_calls()) got_name= true; #endif @@ -260,7 +256,7 @@ void Json_writer::add_unquoted_str(const char* str, size_t len) inline bool Json_writer::on_add_str(const char *str, size_t num_bytes) { -#ifndef NDEBUG +#if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST) got_name= false; #endif bool helped= fmt_helper.on_add_str(str, num_bytes); diff --git a/sql/my_json_writer.h b/sql/my_json_writer.h index 6f9ae73c5ee..c8bd7f5b8fa 100644 --- a/sql/my_json_writer.h +++ b/sql/my_json_writer.h @@ -17,9 +17,12 @@ #define JSON_WRITER_INCLUDED #include "my_base.h" +#if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST) +#include +#endif + #ifdef JSON_WRITER_UNIT_TEST #include "sql_string.h" -#include // Also, mock objects are defined in my_json_writer-t.cc #define VALIDITY_ASSERT(x) if ((!x)) this->invalid_json= true; #else @@ -200,7 +203,7 @@ private: class Json_writer { -#ifndef NDEBUG +#if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST) /* In debug mode, Json_writer will fail and assertion if one attempts to produce an invalid JSON document (e.g. JSON array having named elements). @@ -244,7 +247,6 @@ private: void add_unquoted_str(const char* val, size_t len); bool on_add_str(const char *str, size_t num_bytes); - bool on_start_array(); void on_start_object(); public: @@ -264,7 +266,7 @@ public: size_t get_truncated_bytes() { return output.get_truncated_bytes(); } Json_writer() : -#ifndef NDEBUG +#if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST) got_name(false), #endif indent_level(0), document_start(true), element_started(false), -- cgit v1.2.1 From ff08e948d3708a3e9ab40bb492d6d18b8914ecff Mon Sep 17 00:00:00 2001 From: Sergei Krivonos Date: Tue, 9 Nov 2021 15:40:50 +0200 Subject: Revert "In case WITH_WSREP is enabled, build wsrep as plugin" This reverts commit e45f7f485a4c8133962a4082636412745ed07093. --- sql/CMakeLists.txt | 9 +++++---- sql/sql_builtin.cc.in | 6 ++++++ 2 files changed, 11 insertions(+), 4 deletions(-) (limited to 'sql') diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index ec3b0c528bb..4dd34e80f2d 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -36,10 +36,9 @@ IF(WITH_WSREP AND NOT EMBEDDED_LIBRARY) wsrep_plugin.cc service_wsrep.cc ) - MYSQL_ADD_PLUGIN(wsrep ${WSREP_SOURCES} MANDATORY EXPORT_SYMBOLS LINK_LIBRARIES wsrep-lib wsrep_api_v26) + SET(WSREP_LIB wsrep-lib wsrep_api_v26) ELSE() - ADD_LIBRARY(wsrep STATIC wsrep_dummy.cc) - ADD_DEPENDENCIES(wsrep GenError) + SET(WSREP_SOURCES wsrep_dummy.cc) ENDIF() INCLUDE_DIRECTORIES( @@ -143,6 +142,7 @@ SET (SQL_SOURCE opt_split.cc rowid_filter.cc rowid_filter.h opt_trace.cc + ${WSREP_SOURCES} table_cache.cc encryption.cc temporary_tables.cc proxy_protocol.cc backup.cc xa.cc ${CMAKE_CURRENT_BINARY_DIR}/sql_yacc.cc @@ -180,10 +180,11 @@ DTRACE_INSTRUMENT(sql) TARGET_LINK_LIBRARIES(sql mysys mysys_ssl dbug strings vio pcre ${LIBWRAP} ${LIBCRYPT} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT} + ${WSREP_LIB} ${SSL_LIBRARIES} ${LIBSYSTEMD}) -FOREACH(se aria partition perfschema sql_sequence wsrep) +FOREACH(se aria partition perfschema sql_sequence) # These engines are used directly in sql sources. IF(TARGET ${se}) TARGET_LINK_LIBRARIES(sql ${se}) diff --git a/sql/sql_builtin.cc.in b/sql/sql_builtin.cc.in index 810f98a876c..5ac044afd5d 100644 --- a/sql/sql_builtin.cc.in +++ b/sql/sql_builtin.cc.in @@ -32,6 +32,9 @@ extern builtin_maria_plugin @mysql_mandatory_plugins@ @mysql_optional_plugins@ builtin_maria_binlog_plugin, +#ifdef WITH_WSREP + builtin_maria_wsrep_plugin, +#endif /* WITH_WSREP */ builtin_maria_mysql_password_plugin; struct st_maria_plugin *mysql_optional_plugins[]= @@ -42,5 +45,8 @@ struct st_maria_plugin *mysql_optional_plugins[]= struct st_maria_plugin *mysql_mandatory_plugins[]= { builtin_maria_binlog_plugin, builtin_maria_mysql_password_plugin, +#ifdef WITH_WSREP + builtin_maria_wsrep_plugin, +#endif /* WITH_WSREP */ @mysql_mandatory_plugins@ 0 }; -- cgit v1.2.1 From f7c6c02a06149aa4f41dd01173f2020a0756f8db Mon Sep 17 00:00:00 2001 From: Sergei Krivonos Date: Tue, 9 Nov 2021 15:43:10 +0200 Subject: Revert "improve build, allow sql library to be built in parallel with builtins" This reverts commit 1a3570dec35733e725cc6000a06ec666facf4235. --- sql/CMakeLists.txt | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) (limited to 'sql') diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 4dd34e80f2d..7154e3dbe44 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -145,11 +145,11 @@ SET (SQL_SOURCE ${WSREP_SOURCES} table_cache.cc encryption.cc temporary_tables.cc proxy_protocol.cc backup.cc xa.cc + ${CMAKE_CURRENT_BINARY_DIR}/sql_builtin.cc ${CMAKE_CURRENT_BINARY_DIR}/sql_yacc.cc ${CMAKE_CURRENT_BINARY_DIR}/sql_yacc_ora.cc ${CMAKE_CURRENT_BINARY_DIR}/lex_hash.h ${CMAKE_CURRENT_BINARY_DIR}/lex_token.h - ${GEN_SOURCES} ${MYSYS_LIBWRAP_SOURCE} ) @@ -177,20 +177,13 @@ RECOMPILE_FOR_EMBEDDED) ADD_LIBRARY(sql STATIC ${SQL_SOURCE}) DTRACE_INSTRUMENT(sql) -TARGET_LINK_LIBRARIES(sql +TARGET_LINK_LIBRARIES(sql ${MYSQLD_STATIC_PLUGIN_LIBS} mysys mysys_ssl dbug strings vio pcre ${LIBWRAP} ${LIBCRYPT} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT} ${WSREP_LIB} ${SSL_LIBRARIES} ${LIBSYSTEMD}) -FOREACH(se aria partition perfschema sql_sequence) - # These engines are used directly in sql sources. - IF(TARGET ${se}) - TARGET_LINK_LIBRARIES(sql ${se}) - ENDIF() -ENDFOREACH() - IF(WIN32) SET(MYSQLD_SOURCE main.cc nt_servc.cc message.rc) TARGET_LINK_LIBRARIES(sql psapi) @@ -274,9 +267,6 @@ IF(MSVC AND NOT WITHOUT_DYNAMIC_PLUGINS) SET_TARGET_PROPERTIES(mysqld_import_lib PROPERTIES IMPORTED_LOCATION ${MYSQLD_LIB}) ENDIF() -ADD_LIBRARY( sql_builtins ${CMAKE_CURRENT_BINARY_DIR}/sql_builtin.cc) -TARGET_LINK_LIBRARIES(sql_builtins ${MYSQLD_STATIC_PLUGIN_LIBS}) - MYSQL_ADD_EXECUTABLE(mysqld ${MYSQLD_SOURCE} DESTINATION ${INSTALL_SBINDIR} COMPONENT Server) IF(APPLE) @@ -304,8 +294,7 @@ IF(NOT WITHOUT_DYNAMIC_PLUGINS) ENDIF() ENDIF(NOT WITHOUT_DYNAMIC_PLUGINS) -TARGET_LINK_LIBRARIES(mysqld LINK_PRIVATE sql sql_builtins) - +TARGET_LINK_LIBRARIES(mysqld LINK_PRIVATE sql) # Provide plugins with minimal set of libraries SET(INTERFACE_LIBS ${LIBRT}) -- cgit v1.2.1 From 009f3e06f3e74303559df59db404b300a12241d3 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Fri, 28 Jun 2019 13:21:39 +0200 Subject: improve build, allow sql library to be built in parallel with builtins --- sql/CMakeLists.txt | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 7154e3dbe44..4dd34e80f2d 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -145,11 +145,11 @@ SET (SQL_SOURCE ${WSREP_SOURCES} table_cache.cc encryption.cc temporary_tables.cc proxy_protocol.cc backup.cc xa.cc - ${CMAKE_CURRENT_BINARY_DIR}/sql_builtin.cc ${CMAKE_CURRENT_BINARY_DIR}/sql_yacc.cc ${CMAKE_CURRENT_BINARY_DIR}/sql_yacc_ora.cc ${CMAKE_CURRENT_BINARY_DIR}/lex_hash.h ${CMAKE_CURRENT_BINARY_DIR}/lex_token.h + ${GEN_SOURCES} ${MYSYS_LIBWRAP_SOURCE} ) @@ -177,13 +177,20 @@ RECOMPILE_FOR_EMBEDDED) ADD_LIBRARY(sql STATIC ${SQL_SOURCE}) DTRACE_INSTRUMENT(sql) -TARGET_LINK_LIBRARIES(sql ${MYSQLD_STATIC_PLUGIN_LIBS} +TARGET_LINK_LIBRARIES(sql mysys mysys_ssl dbug strings vio pcre ${LIBWRAP} ${LIBCRYPT} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT} ${WSREP_LIB} ${SSL_LIBRARIES} ${LIBSYSTEMD}) +FOREACH(se aria partition perfschema sql_sequence) + # These engines are used directly in sql sources. + IF(TARGET ${se}) + TARGET_LINK_LIBRARIES(sql ${se}) + ENDIF() +ENDFOREACH() + IF(WIN32) SET(MYSQLD_SOURCE main.cc nt_servc.cc message.rc) TARGET_LINK_LIBRARIES(sql psapi) @@ -267,6 +274,9 @@ IF(MSVC AND NOT WITHOUT_DYNAMIC_PLUGINS) SET_TARGET_PROPERTIES(mysqld_import_lib PROPERTIES IMPORTED_LOCATION ${MYSQLD_LIB}) ENDIF() +ADD_LIBRARY( sql_builtins ${CMAKE_CURRENT_BINARY_DIR}/sql_builtin.cc) +TARGET_LINK_LIBRARIES(sql_builtins ${MYSQLD_STATIC_PLUGIN_LIBS}) + MYSQL_ADD_EXECUTABLE(mysqld ${MYSQLD_SOURCE} DESTINATION ${INSTALL_SBINDIR} COMPONENT Server) IF(APPLE) @@ -294,7 +304,8 @@ IF(NOT WITHOUT_DYNAMIC_PLUGINS) ENDIF() ENDIF(NOT WITHOUT_DYNAMIC_PLUGINS) -TARGET_LINK_LIBRARIES(mysqld LINK_PRIVATE sql) +TARGET_LINK_LIBRARIES(mysqld LINK_PRIVATE sql sql_builtins) + # Provide plugins with minimal set of libraries SET(INTERFACE_LIBS ${LIBRT}) -- cgit v1.2.1 From c1e1ca20f48b30c8a754bd42274385065d89060e Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Sat, 29 Jun 2019 15:28:20 +0300 Subject: =?UTF-8?q?In=20case=20WITH=5FWSREP=20is=20enabled,=20build=20wsre?= =?UTF-8?q?p=20as=20plugin=20If=20it=20is=20not=20enabled,=20build=20wsrep?= =?UTF-8?q?=20as=20static=20"stub"=20library=20from=20wsrep=5Fdummy.cc=20?= =?UTF-8?q?=C2=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allow static plugins to export symbols (on Unix) wsrep_info relies on wsrep defined symbols (e.g LOCK_wsrep_config_state) exported from mysqld --- sql/CMakeLists.txt | 9 ++++----- sql/sql_builtin.cc.in | 6 ------ 2 files changed, 4 insertions(+), 11 deletions(-) (limited to 'sql') diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 4dd34e80f2d..5f6ccddfe16 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -36,9 +36,10 @@ IF(WITH_WSREP AND NOT EMBEDDED_LIBRARY) wsrep_plugin.cc service_wsrep.cc ) - SET(WSREP_LIB wsrep-lib wsrep_api_v26) + MYSQL_ADD_PLUGIN(wsrep ${WSREP_SOURCES} MANDATORY NOT_EMBEDDED EXPORT_SYMBOLS LINK_LIBRARIES wsrep-lib wsrep_api_v26) ELSE() - SET(WSREP_SOURCES wsrep_dummy.cc) + ADD_LIBRARY(wsrep STATIC wsrep_dummy.cc) + ADD_DEPENDENCIES(wsrep GenError) ENDIF() INCLUDE_DIRECTORIES( @@ -142,7 +143,6 @@ SET (SQL_SOURCE opt_split.cc rowid_filter.cc rowid_filter.h opt_trace.cc - ${WSREP_SOURCES} table_cache.cc encryption.cc temporary_tables.cc proxy_protocol.cc backup.cc xa.cc ${CMAKE_CURRENT_BINARY_DIR}/sql_yacc.cc @@ -180,11 +180,10 @@ DTRACE_INSTRUMENT(sql) TARGET_LINK_LIBRARIES(sql mysys mysys_ssl dbug strings vio pcre ${LIBWRAP} ${LIBCRYPT} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT} - ${WSREP_LIB} ${SSL_LIBRARIES} ${LIBSYSTEMD}) -FOREACH(se aria partition perfschema sql_sequence) +FOREACH(se aria partition perfschema sql_sequence wsrep) # These engines are used directly in sql sources. IF(TARGET ${se}) TARGET_LINK_LIBRARIES(sql ${se}) diff --git a/sql/sql_builtin.cc.in b/sql/sql_builtin.cc.in index 5ac044afd5d..810f98a876c 100644 --- a/sql/sql_builtin.cc.in +++ b/sql/sql_builtin.cc.in @@ -32,9 +32,6 @@ extern builtin_maria_plugin @mysql_mandatory_plugins@ @mysql_optional_plugins@ builtin_maria_binlog_plugin, -#ifdef WITH_WSREP - builtin_maria_wsrep_plugin, -#endif /* WITH_WSREP */ builtin_maria_mysql_password_plugin; struct st_maria_plugin *mysql_optional_plugins[]= @@ -45,8 +42,5 @@ struct st_maria_plugin *mysql_optional_plugins[]= struct st_maria_plugin *mysql_mandatory_plugins[]= { builtin_maria_binlog_plugin, builtin_maria_mysql_password_plugin, -#ifdef WITH_WSREP - builtin_maria_wsrep_plugin, -#endif /* WITH_WSREP */ @mysql_mandatory_plugins@ 0 }; -- cgit v1.2.1 From 94ef277b5b98afb25400fdb1b3b4917ef16172da Mon Sep 17 00:00:00 2001 From: Sergei Krivonos Date: Tue, 9 Nov 2021 20:06:22 +0200 Subject: MDEV-23766: fix by assert (Windows) --- sql/my_json_writer.h | 20 ++++++++++---------- sql/opt_range.cc | 7 +++---- 2 files changed, 13 insertions(+), 14 deletions(-) (limited to 'sql') diff --git a/sql/my_json_writer.h b/sql/my_json_writer.h index c8bd7f5b8fa..7d209501a87 100644 --- a/sql/my_json_writer.h +++ b/sql/my_json_writer.h @@ -24,7 +24,7 @@ #ifdef JSON_WRITER_UNIT_TEST #include "sql_string.h" // Also, mock objects are defined in my_json_writer-t.cc -#define VALIDITY_ASSERT(x) if ((!x)) this->invalid_json= true; +#define VALIDITY_ASSERT(x) if (!(x)) this->invalid_json= true; #else #include "sql_select.h" #define VALIDITY_ASSERT(x) DBUG_ASSERT(x) @@ -356,6 +356,9 @@ public: /* A common base for Json_writer_object and Json_writer_array */ class Json_writer_struct { + Json_writer_struct(const Json_writer_struct&)= delete; + Json_writer_struct& operator=(const Json_writer_struct&)= delete; + protected: Json_writer* my_writer; Json_value_helper context; @@ -394,18 +397,15 @@ private: my_writer->add_member(name); } public: - explicit Json_writer_object(THD *thd) - : Json_writer_struct(thd) - { - if (unlikely(my_writer)) - my_writer->start_object(); - } - - explicit Json_writer_object(THD* thd, const char *str) + explicit Json_writer_object(THD* thd, const char *str= nullptr) : Json_writer_struct(thd) { if (unlikely(my_writer)) - my_writer->add_member(str).start_object(); + { + if (str) + my_writer->add_member(str); + my_writer->start_object(); + } } ~Json_writer_object() diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 122b00f4d57..47bf8f1682f 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -5101,9 +5101,8 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge, n_child_scans))) DBUG_RETURN(NULL); - Json_writer_object trace_best_disjunct = named_trace - ? Json_writer_object(thd, "best_disjunct_quick") - : Json_writer_object(thd); + const char* trace_best_disjunct_obj_name= named_trace ? "best_disjunct_quick" : nullptr; + Json_writer_object trace_best_disjunct(thd, trace_best_disjunct_obj_name); Json_writer_array to_merge(thd, "indexes_to_merge"); /* Collect best 'range' scan for each of disjuncts, and, while doing so, @@ -5649,7 +5648,7 @@ void print_keyparts(THD *thd, KEY *key, uint key_parts) DBUG_ASSERT(thd->trace_started()); KEY_PART_INFO *part= key->key_part; - Json_writer_array keyparts= Json_writer_array(thd, "keyparts"); + Json_writer_array keyparts(thd, "keyparts"); for(uint i= 0; i < key_parts; i++, part++) keyparts.add(part->field->field_name); } -- cgit v1.2.1 From d270525dfde86bcb92a2327234a0954083e14a94 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Fri, 12 Nov 2021 17:46:35 +0530 Subject: MDEV-23805 Make Online DDL to Instant DDL when table is empty - In ha_innobase::prepare_inplace_alter_table(), InnoDB should check whether the table is empty. If the table is empty then server should avoid downgrading the MDL after prepare phase. It is more like instant alter, does change only in dicationary and metadata. - Changed few debug test case to make non-empty DDL table --- sql/handler.h | 3 +++ sql/sql_table.cc | 7 ++++--- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/handler.h b/sql/handler.h index 94ac56c3073..9b44b3fd297 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -2493,6 +2493,9 @@ public: /** true when InnoDB should abort the alter when table is not empty */ bool error_if_not_empty; + /** True when DDL should avoid downgrading the MDL */ + bool mdl_exclusive_after_prepare= false; + Alter_inplace_info(HA_CREATE_INFO *create_info_arg, Alter_info *alter_info_arg, KEY *key_info_arg, uint key_count_arg, diff --git a/sql/sql_table.cc b/sql/sql_table.cc index e46a13ce7a9..4409360cd8f 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -7709,15 +7709,16 @@ static bool mysql_inplace_alter_table(THD *thd, lock for prepare phase under LOCK TABLES in the same way as when exclusive lock is required for duration of the whole statement. */ - if (inplace_supported == HA_ALTER_INPLACE_EXCLUSIVE_LOCK || - ((inplace_supported == HA_ALTER_INPLACE_COPY_NO_LOCK || + if (!ha_alter_info->mdl_exclusive_after_prepare && + (inplace_supported == HA_ALTER_INPLACE_EXCLUSIVE_LOCK || + ((inplace_supported == HA_ALTER_INPLACE_COPY_NO_LOCK || inplace_supported == HA_ALTER_INPLACE_COPY_LOCK || inplace_supported == HA_ALTER_INPLACE_NOCOPY_NO_LOCK || inplace_supported == HA_ALTER_INPLACE_NOCOPY_LOCK || inplace_supported == HA_ALTER_INPLACE_INSTANT) && (thd->locked_tables_mode == LTM_LOCK_TABLES || thd->locked_tables_mode == LTM_PRELOCKED_UNDER_LOCK_TABLES)) || - alter_info->requested_lock == Alter_info::ALTER_TABLE_LOCK_EXCLUSIVE) + alter_info->requested_lock == Alter_info::ALTER_TABLE_LOCK_EXCLUSIVE)) { if (wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN)) goto cleanup; -- cgit v1.2.1 From 72afeaf8a5016256d9ed7b16c73d521b45aa5e85 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Sat, 13 Nov 2021 10:29:26 +0100 Subject: MDEV-18439 Windows builds should have core_file=1 by default reapply patch 96b472c0ae798da43ca9f4735dfafe35b2f38fda It was not merged correctly into 10.5+ --- sql/mysqld.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/mysqld.cc b/sql/mysqld.cc index f1521f4fe1c..e7a40b6eaa4 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -7695,7 +7695,7 @@ static int mysql_init_variables(void) disable_log_notes= 0; mqh_used= 0; cleanup_done= 0; - test_flags= select_errors= dropping_tables= ha_open_options=0; + select_errors= dropping_tables= ha_open_options=0; THD_count::count= CONNECT::count= 0; slave_open_temp_tables= 0; opt_endinfo= using_udf_functions= 0; -- cgit v1.2.1 From 0269d491eaf02556817654e6365ebf50eb4616fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 16 Nov 2021 13:58:22 +0200 Subject: MDEV-27047: Replication fails to remove affected queries from query cache Rows_log_event::do_apply_event(): Correct the mistake that was made in the merge 5f8561a6bcdb66e05ca539365cce33a9fc1817a2. In Galera, the query cache will be invalidated near the end of the function. --- sql/log_event_server.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/log_event_server.cc b/sql/log_event_server.cc index 79f197d4ec3..093adebf536 100644 --- a/sql/log_event_server.cc +++ b/sql/log_event_server.cc @@ -5573,14 +5573,16 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi) } } -#if defined(WITH_WSREP) && defined(HAVE_QUERY_CACHE) +#ifdef HAVE_QUERY_CACHE /* Moved invalidation right before the call to rows_event_stmt_cleanup(), to avoid query cache being polluted with stale entries, */ - if (WSREP(thd) && wsrep_thd_is_applying(thd)) +# ifdef WITH_WSREP + if (!WSREP(thd) && !wsrep_thd_is_applying(thd)) +# endif /* WITH_WSREP */ query_cache.invalidate_locked_for_write(thd, rgi->tables_to_lock); -#endif /* WITH_WSREP && HAVE_QUERY_CACHE */ +#endif /* HAVE_QUERY_CACHE */ } table= m_table= rgi->m_table_map.get_table(m_table_id); -- cgit v1.2.1 From 8f24f5fee267706c0a5f475140a19a9304e224b4 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Mon, 15 Nov 2021 22:21:05 -0800 Subject: MDEV-26825 Bogus error for query with two usage of CTE referring another CTE This bug affected queries with two or more references to a CTE referring another CTE if the definition of the latter contained an invocation of a stored function that used a base table. The bug could lead to a bogus error message or to an assertion failure. For any non-first reference to CTE cte1 With_element::clone_parsed_spec() is called that parses the specification of cte1 to construct the unit structure for this usage of cte1. If cte1 refers to another CTE cte2 outside of the specification of cte1 then With_element::clone_parsed_spec() has to be called for cte2 as well. This call is made by the function LEX::resolve_references_to_cte() within the invocation of the function With_element::clone_parsed_spec() for cte1. When the specification of a CTE is parsed all table references encountered in it must be added to the global list of table references for the query. As the specification for the non-first usage of a CTE is parsed at a recursive call of the parser the function With_element::clone_parsed_spec() invoked at this recursive call should takes care of appending the list of table references encountered in the specification of this CTE cte1 to the list of table references created for the query. And it should do it after the call of LEX::resolve_references_to_cte() that resolves references to CTEs defined outside of the specification of cte1 because this call may invoke the parser again for specifications of other CTEs and the table references from their specifications must ultimately appear in the global list of table references of the query. The code of With_element::clone_parsed_spec() misplaced the call of LEX::resolve_references_to_cte(). As a result LEX::query_tables_last used for the query that was supposed to point to the field 'next_global' of the last element in the global list of table references actually pointed to 'next_global' of the previous element. The above inconsistency certainly caused serious problems when table references used in the stored functions invoked in cloned specifications of CTEs were added to the global list of table references. --- sql/sql_cte.cc | 57 ++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 34 insertions(+), 23 deletions(-) (limited to 'sql') diff --git a/sql/sql_cte.cc b/sql/sql_cte.cc index 22a99842f6a..e6b868d09da 100644 --- a/sql/sql_cte.cc +++ b/sql/sql_cte.cc @@ -1021,6 +1021,15 @@ st_select_lex_unit *With_element::clone_parsed_spec(LEX *old_lex, lex_start(thd); lex->clone_spec_offset= unparsed_spec_offset; lex->with_cte_resolution= true; + /* + There's no need to add SPs/SFs referenced in the clone to the global + list of the SPs/SFs used in the query as they were added when the first + reference to the cloned CTE was parsed. Yet the recursive call of the + parser must to know that they were already included into the list. + */ + lex->sroutines= old_lex->sroutines; + lex->sroutines_list_own_last= old_lex->sroutines_list_own_last; + lex->sroutines_list_own_elements= old_lex->sroutines_list_own_elements; /* The specification of a CTE is to be parsed as a regular query. @@ -1066,6 +1075,29 @@ st_select_lex_unit *With_element::clone_parsed_spec(LEX *old_lex, if (parse_status) goto err; + /* + The unit of the specification that just has been parsed is included + as a slave of the select that contained in its from list the table + reference for which the unit has been created. + */ + lex->unit.include_down(with_table->select_lex); + lex->unit.set_slave(with_select); + lex->unit.cloned_from= spec; + + /* + Now all references to the CTE defined outside of the cloned specification + has to be resolved. Additionally if old_lex->only_cte_resolution == false + for the table references that has not been resolved requests for mdl_locks + has to be set. + */ + lex->only_cte_resolution= old_lex->only_cte_resolution; + if (lex->resolve_references_to_cte(lex->query_tables, + lex->query_tables_last)) + { + res= NULL; + goto err; + } + /* The global chain of TABLE_LIST objects created for the specification that just has been parsed is added to such chain that contains the reference @@ -1090,32 +1122,11 @@ st_select_lex_unit *With_element::clone_parsed_spec(LEX *old_lex, old_lex->query_tables_last= lex->query_tables_last; } } + old_lex->sroutines_list_own_last= lex->sroutines_list_own_last; + old_lex->sroutines_list_own_elements= lex->sroutines_list_own_elements; res= &lex->unit; res->with_element= this; - /* - The unit of the specification that just has been parsed is included - as a slave of the select that contained in its from list the table - reference for which the unit has been created. - */ - lex->unit.include_down(with_table->select_lex); - lex->unit.set_slave(with_select); - lex->unit.cloned_from= spec; - - /* - Now all references to the CTE defined outside of the cloned specification - has to be resolved. Additionally if old_lex->only_cte_resolution == false - for the table references that has not been resolved requests for mdl_locks - has to be set. - */ - lex->only_cte_resolution= old_lex->only_cte_resolution; - if (lex->resolve_references_to_cte(lex->query_tables, - lex->query_tables_last)) - { - res= NULL; - goto err; - } - last_clone_select= lex->all_selects_list; while (last_clone_select->next_select_in_list()) last_clone_select= last_clone_select->next_select_in_list(); -- cgit v1.2.1