Commit 2d21917e authored by Sergei Krivonos's avatar Sergei Krivonos

MDEV-27036: re-enable my_json_writer-t unit test

parent 9feaa6be
...@@ -142,6 +142,7 @@ IF (NOT CPACK_GENERATOR) ...@@ -142,6 +142,7 @@ IF (NOT CPACK_GENERATOR)
ENDIF(WIN32) ENDIF(WIN32)
ENDIF(NOT CPACK_GENERATOR) ENDIF(NOT CPACK_GENERATOR)
INCLUDE(build_depends)
INCLUDE(FeatureSummary) INCLUDE(FeatureSummary)
INCLUDE(misc) INCLUDE(misc)
INCLUDE(mysql_version) INCLUDE(mysql_version)
...@@ -538,8 +539,6 @@ IF(UNIX) ...@@ -538,8 +539,6 @@ IF(UNIX)
INSTALL_DOCUMENTATION(Docs/INSTALL-BINARY Docs/README-wsrep COMPONENT Readme) INSTALL_DOCUMENTATION(Docs/INSTALL-BINARY Docs/README-wsrep COMPONENT Readme)
ENDIF() ENDIF()
INCLUDE(build_depends)
INCLUDE(CPack) INCLUDE(CPack)
IF(WIN32 AND SIGNCODE) IF(WIN32 AND SIGNCODE)
......
...@@ -22,3 +22,4 @@ MACRO(MY_ADD_TESTS) ...@@ -22,3 +22,4 @@ MACRO(MY_ADD_TESTS)
ENDFOREACH() ENDFOREACH()
ENDMACRO() ENDMACRO()
FIND_PACKAGE(Boost COMPONENTS unit_test_framework)
...@@ -17,6 +17,9 @@ ...@@ -17,6 +17,9 @@
#define MY_DIR_H #define MY_DIR_H
#include <sys/stat.h> #include <sys/stat.h>
#include <stddef.h>
#include "my_global.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
......
...@@ -206,7 +206,7 @@ RECOMPILE_FOR_EMBEDDED) ...@@ -206,7 +206,7 @@ RECOMPILE_FOR_EMBEDDED)
ADD_LIBRARY(sql STATIC ${SQL_SOURCE}) ADD_LIBRARY(sql STATIC ${SQL_SOURCE})
MAYBE_DISABLE_IPO(sql) MAYBE_DISABLE_IPO(sql)
DTRACE_INSTRUMENT(sql) DTRACE_INSTRUMENT(sql)
TARGET_LINK_LIBRARIES(sql TARGET_LINK_LIBRARIES(sql PUBLIC
mysys mysys_ssl dbug strings vio pcre2-8 mysys mysys_ssl dbug strings vio pcre2-8
${FMT_LIBRARIES} ${FMT_LIBRARIES}
tpool tpool
...@@ -221,7 +221,7 @@ ENDIF() ...@@ -221,7 +221,7 @@ ENDIF()
FOREACH(se aria partition perfschema sql_sequence wsrep) FOREACH(se aria partition perfschema sql_sequence wsrep)
# These engines are used directly in sql sources. # These engines are used directly in sql sources.
IF(TARGET ${se}) IF(TARGET ${se})
TARGET_LINK_LIBRARIES(sql ${se}) TARGET_LINK_LIBRARIES(sql PUBLIC ${se})
ENDIF() ENDIF()
ENDFOREACH() ENDFOREACH()
......
...@@ -13,10 +13,14 @@ ...@@ -13,10 +13,14 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
#include "my_json_writer.h"
#include "sql_class.h"
#include "mariadb.h" #include "mariadb.h"
#include "sql_priv.h" #include "sql_priv.h"
#include "sql_string.h" #include "sql_string.h"
#include "my_json_writer.h" #include "log.h"
#if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST) #if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST)
#include <iostream> #include <iostream>
...@@ -328,6 +332,7 @@ Json_writer_temp_disable::Json_writer_temp_disable(THD *thd_arg) ...@@ -328,6 +332,7 @@ Json_writer_temp_disable::Json_writer_temp_disable(THD *thd_arg)
thd= thd_arg; thd= thd_arg;
thd->opt_trace.disable_tracing_if_required(); thd->opt_trace.disable_tracing_if_required();
} }
Json_writer_temp_disable::~Json_writer_temp_disable() Json_writer_temp_disable::~Json_writer_temp_disable()
{ {
thd->opt_trace.enable_tracing_if_required(); thd->opt_trace.enable_tracing_if_required();
...@@ -497,3 +502,18 @@ void Single_line_formatting_helper::disable_and_flush() ...@@ -497,3 +502,18 @@ void Single_line_formatting_helper::disable_and_flush()
state= INACTIVE; state= INACTIVE;
} }
Json_writer_struct::Json_writer_struct(THD *thd)
: Json_writer_struct(thd->opt_trace.get_current_json())
{
}
Json_writer_object::Json_writer_object(THD *thd, const char *str)
: Json_writer_object(thd->opt_trace.get_current_json(), str)
{
}
Json_writer_array::Json_writer_array(THD *thd, const char *str)
: Json_writer_array(thd->opt_trace.get_current_json(), str)
{
}
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#define JSON_WRITER_INCLUDED #define JSON_WRITER_INCLUDED
#include "my_base.h" #include "my_base.h"
#include "sql_select.h"
#if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST) || defined ENABLED_JSON_WRITER_CONSISTENCY_CHECKS #if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST) || defined ENABLED_JSON_WRITER_CONSISTENCY_CHECKS
#include <set> #include <set>
...@@ -32,6 +31,7 @@ constexpr uint FAKE_SELECT_LEX_ID= UINT_MAX; ...@@ -32,6 +31,7 @@ constexpr uint FAKE_SELECT_LEX_ID= UINT_MAX;
// Also, mock objects are defined in my_json_writer-t.cc // 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 #else
#include "sql_select.h"
#define VALIDITY_ASSERT(x) DBUG_ASSERT(x) #define VALIDITY_ASSERT(x) DBUG_ASSERT(x)
#endif #endif
...@@ -40,8 +40,11 @@ constexpr uint FAKE_SELECT_LEX_ID= UINT_MAX; ...@@ -40,8 +40,11 @@ constexpr uint FAKE_SELECT_LEX_ID= UINT_MAX;
class Opt_trace_stmt; class Opt_trace_stmt;
class Opt_trace_context; class Opt_trace_context;
class Json_writer; class Json_writer;
struct TABLE;
struct TABLE_LIST; struct TABLE_LIST;
struct st_join_table;
using JOIN_TAB= struct st_join_table;
/* /*
Single_line_formatting_helper is used by Json_writer to do better formatting Single_line_formatting_helper is used by Json_writer to do better formatting
...@@ -387,10 +390,7 @@ class Json_writer_struct ...@@ -387,10 +390,7 @@ class Json_writer_struct
named_items_expectation.push_back(expect_named_children); named_items_expectation.push_back(expect_named_children);
#endif #endif
} }
explicit Json_writer_struct(THD *thd) explicit Json_writer_struct(THD *thd);
: Json_writer_struct(thd->opt_trace.get_current_json())
{
}
public: public:
...@@ -446,10 +446,7 @@ class Json_writer_object : public Json_writer_struct ...@@ -446,10 +446,7 @@ class Json_writer_object : public Json_writer_struct
} }
} }
explicit Json_writer_object(THD* thd, const char *str= nullptr) explicit Json_writer_object(THD* thd, const char *str= nullptr);
: Json_writer_object(thd->opt_trace.get_current_json(), str)
{
}
~Json_writer_object() ~Json_writer_object()
{ {
...@@ -619,10 +616,7 @@ class Json_writer_array : public Json_writer_struct ...@@ -619,10 +616,7 @@ class Json_writer_array : public Json_writer_struct
} }
} }
explicit Json_writer_array(THD *thd, const char *str= nullptr) explicit Json_writer_array(THD *thd, const char *str= nullptr);
: Json_writer_array(thd->opt_trace.get_current_json(), str)
{
}
~Json_writer_array() ~Json_writer_array()
{ {
......
...@@ -1254,6 +1254,14 @@ void SQL_SELECT::cleanup() ...@@ -1254,6 +1254,14 @@ void SQL_SELECT::cleanup()
close_cached_file(&file); close_cached_file(&file);
} }
int SQL_SELECT::skip_record(THD *thd)
{
int rc= MY_TEST(!cond || cond->val_int());
if (thd->is_error())
rc= -1;
return rc;
}
SQL_SELECT::~SQL_SELECT() SQL_SELECT::~SQL_SELECT()
{ {
...@@ -1872,6 +1880,20 @@ QUICK_RANGE::QUICK_RANGE() ...@@ -1872,6 +1880,20 @@ QUICK_RANGE::QUICK_RANGE()
min_keypart_map(0), max_keypart_map(0) min_keypart_map(0), max_keypart_map(0)
{} {}
QUICK_RANGE::QUICK_RANGE(THD *thd, const uchar *min_key_arg, uint min_length_arg, key_part_map min_keypart_map_arg, const uchar *max_key_arg, uint max_length_arg, key_part_map max_keypart_map_arg, uint flag_arg)
: min_key((uchar*) thd->memdup(min_key_arg, min_length_arg + 1)),
max_key((uchar*) thd->memdup(max_key_arg, max_length_arg + 1)),
min_length((uint16) min_length_arg),
max_length((uint16) max_length_arg),
flag((uint16) flag_arg),
min_keypart_map(min_keypart_map_arg),
max_keypart_map(max_keypart_map_arg)
{
#ifdef HAVE_valgrind
dummy=0;
#endif
}
SEL_ARG::SEL_ARG(SEL_ARG &arg) :Sql_alloc() SEL_ARG::SEL_ARG(SEL_ARG &arg) :Sql_alloc()
{ {
type=arg.type; type=arg.type;
...@@ -10848,6 +10870,31 @@ uint SEL_ARG::get_max_key_part() const ...@@ -10848,6 +10870,31 @@ uint SEL_ARG::get_max_key_part() const
return max_part; return max_part;
} }
SEL_ARG *SEL_ARG::clone_and(THD *thd, SEL_ARG *arg)
{ // Get overlapping range
uchar *new_min,*new_max;
uint8 flag_min,flag_max;
if (cmp_min_to_min(arg) >= 0)
{
new_min=min_value; flag_min=min_flag;
}
else
{
new_min=arg->min_value; flag_min=arg->min_flag; /* purecov: deadcode */
}
if (cmp_max_to_max(arg) <= 0)
{
new_max=max_value; flag_max=max_flag;
}
else
{
new_max=arg->max_value; flag_max=arg->max_flag;
}
return new (thd->mem_root) SEL_ARG(field, part, new_min, new_max, flag_min,
flag_max,
MY_TEST(maybe_flag && arg->maybe_flag));
}
/* /*
Remove the SEL_ARG graph elements which have part > max_part. Remove the SEL_ARG graph elements which have part > max_part.
...@@ -16568,3 +16615,11 @@ void print_keyparts_name(String *out, const KEY_PART_INFO *key_part, ...@@ -16568,3 +16615,11 @@ void print_keyparts_name(String *out, const KEY_PART_INFO *key_part,
} }
out->append(STRING_WITH_LEN(")")); out->append(STRING_WITH_LEN(")"));
} }
bool RANGE_OPT_PARAM::statement_should_be_aborted() const
{
return thd->killed
|| thd->is_fatal_error
|| thd->is_error()
|| alloced_sel_args > SEL_ARG::MAX_SEL_ARGS;
}
...@@ -36,8 +36,9 @@ ...@@ -36,8 +36,9 @@
#include "sql_class.h" // set_var.h: THD #include "sql_class.h" // set_var.h: THD
#include "set_var.h" /* Item */ #include "set_var.h" /* Item */
class JOIN;
class Item_sum; class Item_sum;
class JOIN;
class Unique;
struct KEY_PART { struct KEY_PART {
uint16 key,part; uint16 key,part;
...@@ -389,30 +390,7 @@ class SEL_ARG :public Sql_alloc ...@@ -389,30 +390,7 @@ class SEL_ARG :public Sql_alloc
{ {
return sel_cmp(field,max_value, arg->min_value, max_flag, arg->min_flag); return sel_cmp(field,max_value, arg->min_value, max_flag, arg->min_flag);
} }
SEL_ARG *clone_and(THD *thd, SEL_ARG* arg) SEL_ARG *clone_and(THD *thd, SEL_ARG* arg);
{ // Get overlapping range
uchar *new_min,*new_max;
uint8 flag_min,flag_max;
if (cmp_min_to_min(arg) >= 0)
{
new_min=min_value; flag_min=min_flag;
}
else
{
new_min=arg->min_value; flag_min=arg->min_flag; /* purecov: deadcode */
}
if (cmp_max_to_max(arg) <= 0)
{
new_max=max_value; flag_max=max_flag;
}
else
{
new_max=arg->max_value; flag_max=arg->max_flag;
}
return new (thd->mem_root) SEL_ARG(field, part, new_min, new_max, flag_min,
flag_max,
MY_TEST(maybe_flag && arg->maybe_flag));
}
SEL_ARG *clone_first(SEL_ARG *arg) SEL_ARG *clone_first(SEL_ARG *arg)
{ // min <= X < arg->min { // min <= X < arg->min
return new SEL_ARG(field,part, min_value, arg->min_value, return new SEL_ARG(field,part, min_value, arg->min_value,
...@@ -733,14 +711,7 @@ class RANGE_OPT_PARAM ...@@ -733,14 +711,7 @@ class RANGE_OPT_PARAM
bool force_default_mrr; bool force_default_mrr;
KEY_PART *key[MAX_KEY]; /* First key parts of keys used in the query */ KEY_PART *key[MAX_KEY]; /* First key parts of keys used in the query */
bool statement_should_be_aborted() const bool statement_should_be_aborted() const;
{
return
thd->killed ||
thd->is_fatal_error ||
thd->is_error() ||
alloced_sel_args > SEL_ARG::MAX_SEL_ARGS;
}
}; };
...@@ -763,21 +734,9 @@ class QUICK_RANGE :public Sql_alloc { ...@@ -763,21 +734,9 @@ class QUICK_RANGE :public Sql_alloc {
QUICK_RANGE(); /* Full range */ QUICK_RANGE(); /* Full range */
QUICK_RANGE(THD *thd, const uchar *min_key_arg, uint min_length_arg, QUICK_RANGE(THD *thd, const uchar *min_key_arg, uint min_length_arg,
key_part_map min_keypart_map_arg, key_part_map min_keypart_map_arg,
const uchar *max_key_arg, uint max_length_arg, const uchar *max_key_arg, uint max_length_arg,
key_part_map max_keypart_map_arg, key_part_map max_keypart_map_arg,
uint flag_arg) uint flag_arg);
: min_key((uchar*) thd->memdup(min_key_arg, min_length_arg + 1)),
max_key((uchar*) thd->memdup(max_key_arg, max_length_arg + 1)),
min_length((uint16) min_length_arg),
max_length((uint16) max_length_arg),
flag((uint16) flag_arg),
min_keypart_map(min_keypart_map_arg),
max_keypart_map(max_keypart_map_arg)
{
#ifdef HAVE_valgrind
dummy=0;
#endif
}
/** /**
Initalizes a key_range object for communication with storage engine. Initalizes a key_range object for communication with storage engine.
...@@ -1724,13 +1683,7 @@ class SQL_SELECT :public Sql_alloc { ...@@ -1724,13 +1683,7 @@ class SQL_SELECT :public Sql_alloc {
-1 if error -1 if error
1 otherwise 1 otherwise
*/ */
inline int skip_record(THD *thd) int skip_record(THD *thd);
{
int rc= MY_TEST(!cond || cond->val_int());
if (thd->is_error())
rc= -1;
return rc;
}
int test_quick_select(THD *thd, key_map keys, table_map prev_tables, int test_quick_select(THD *thd, key_map keys, table_map prev_tables,
ha_rows limit, bool force_quick_range, ha_rows limit, bool force_quick_range,
bool ordered_output, bool remove_false_parts_of_where, bool ordered_output, bool remove_false_parts_of_where,
......
...@@ -241,6 +241,11 @@ const uchar *sys_var::global_value_ptr(THD *thd, const LEX_CSTRING *base) const ...@@ -241,6 +241,11 @@ const uchar *sys_var::global_value_ptr(THD *thd, const LEX_CSTRING *base) const
return global_var_ptr(); return global_var_ptr();
} }
uchar *sys_var::session_var_ptr(THD *thd) const
{
return ((uchar*)&(thd->variables)) + offset;
}
bool sys_var::check(THD *thd, set_var *var) bool sys_var::check(THD *thd, set_var *var)
{ {
if (unlikely((var->value && do_check(thd, var)) || if (unlikely((var->value && do_check(thd, var)) ||
......
...@@ -247,8 +247,7 @@ class sys_var: protected Value_source // for double_from_string_with_check ...@@ -247,8 +247,7 @@ class sys_var: protected Value_source // for double_from_string_with_check
Typically it's the same as session_value_ptr(), but it's different, Typically it's the same as session_value_ptr(), but it's different,
for example, for ENUM, that is printed as a string, but stored as a number. for example, for ENUM, that is printed as a string, but stored as a number.
*/ */
uchar *session_var_ptr(THD *thd) const uchar *session_var_ptr(THD *thd) const;
{ return ((uchar*)&(thd->variables)) + offset; }
uchar *global_var_ptr() const uchar *global_var_ptr() const
{ return ((uchar*)&global_system_variables) + offset; } { return ((uchar*)&global_system_variables) + offset; }
......
...@@ -54,6 +54,8 @@ it into the slow query log. ...@@ -54,6 +54,8 @@ it into the slow query log.
#ifndef SQL_EXPLAIN_INCLUDED #ifndef SQL_EXPLAIN_INCLUDED
#define SQL_EXPLAIN_INCLUDED #define SQL_EXPLAIN_INCLUDED
class select_result_sink;
class String_list: public List<char> class String_list: public List<char>
{ {
public: public:
......
...@@ -12569,6 +12569,13 @@ inline void JOIN::eval_select_list_used_tables() ...@@ -12569,6 +12569,13 @@ inline void JOIN::eval_select_list_used_tables()
} }
} }
JOIN_TAB *JOIN::get_sort_by_join_tab()
{
return (need_tmp || !sort_by_table || skip_sort_order
|| ((group || tmp_table_param.sum_func_count) && !group_list))
? nullptr : join_tab+const_tables;
}
/* /*
Determine {after which table we'll produce ordered set} Determine {after which table we'll produce ordered set}
...@@ -13991,6 +13998,17 @@ bool JOIN_TAB::pfs_batch_update(JOIN *join) ...@@ -13991,6 +13998,17 @@ bool JOIN_TAB::pfs_batch_update(JOIN *join)
(!select_cond || !select_cond->with_subquery()); // 3 (!select_cond || !select_cond->with_subquery()); // 3
} }
int st_join_table::get_non_merged_semijoin_select() const
{
Item_in_subselect *subq;
if (table->pos_in_table_list &&
(subq= table->pos_in_table_list->jtbm_subselect))
{
return subq->unit->first_select()->select_number;
}
return 0; /* Not a merged semi-join */
}
/** /**
Build a TABLE_REF structure for index lookup in the temporary table Build a TABLE_REF structure for index lookup in the temporary table
...@@ -30240,3 +30258,48 @@ static bool process_direct_rownum_comparison(THD *thd, SELECT_LEX_UNIT *unit, ...@@ -30240,3 +30258,48 @@ static bool process_direct_rownum_comparison(THD *thd, SELECT_LEX_UNIT *unit,
/** /**
@} (end of group Query_Optimizer) @} (end of group Query_Optimizer)
*/ */
store_key::store_key_result store_key_item::copy_inner()
{
TABLE *table= to_field->table;
MY_BITMAP *old_map= dbug_tmp_use_all_columns(table,
&table->write_set);
int res= FALSE;
/*
It looks like the next statement is needed only for a simplified
hash function over key values used now in BNLH join.
When the implementation of this function will be replaced for a proper
full version this statement probably should be removed.
*/
to_field->reset();
if (use_value)
item->save_val(to_field);
else
res= item->save_in_field(to_field, 1);
/*
Item::save_in_field() may call Item::val_xxx(). And if this is a subquery
we need to check for errors executing it and react accordingly
*/
if (!res && table->in_use->is_error())
res= 1; /* STORE_KEY_FATAL */
dbug_tmp_restore_column_map(&table->write_set, old_map);
null_key= to_field->is_null() || item->null_value;
return ((err != 0 || res < 0 || res > 2)
? STORE_KEY_FATAL : (store_key_result) res);
}
store_key::store_key_result store_key::copy(THD *thd)
{
enum store_key_result result;
enum_check_fields org_count_cuted_fields= thd->count_cuted_fields;
sql_mode_t org_sql_mode= thd->variables.sql_mode;
thd->variables.sql_mode&= ~(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE);
thd->variables.sql_mode|= MODE_INVALID_DATES;
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
result= copy_inner();
thd->count_cuted_fields= org_count_cuted_fields;
thd->variables.sql_mode= org_sql_mode;
return result;
}
...@@ -30,11 +30,17 @@ ...@@ -30,11 +30,17 @@
#include "procedure.h" #include "procedure.h"
#include "sql_array.h" /* Array */ #include "sql_array.h" /* Array */
#include "sql_class.h"
#include "sql_lex.h"
#include "records.h" /* READ_RECORD */ #include "records.h" /* READ_RECORD */
#include "opt_range.h" /* SQL_SELECT, QUICK_SELECT_I */ #include "opt_range.h" /* SQL_SELECT, QUICK_SELECT_I */
#include "filesort.h" #include "filesort.h"
typedef struct st_join_table JOIN_TAB; class POSITION;
#ifndef TMP_ENGINE_COLUMNDEF
class TMP_ENGINE_COLUMNDEF;
#endif
/* Values in optimize */ /* Values in optimize */
#define KEY_OPTIMIZE_EXISTS 1U #define KEY_OPTIMIZE_EXISTS 1U
#define KEY_OPTIMIZE_REF_OR_NULL 2U #define KEY_OPTIMIZE_REF_OR_NULL 2U
...@@ -199,6 +205,8 @@ enum join_type { JT_UNKNOWN,JT_SYSTEM,JT_CONST,JT_EQ_REF,JT_REF,JT_MAYBE_REF, ...@@ -199,6 +205,8 @@ enum join_type { JT_UNKNOWN,JT_SYSTEM,JT_CONST,JT_EQ_REF,JT_REF,JT_MAYBE_REF,
JT_HASH, JT_HASH_RANGE, JT_HASH_NEXT, JT_HASH_INDEX_MERGE}; JT_HASH, JT_HASH_RANGE, JT_HASH_NEXT, JT_HASH_INDEX_MERGE};
class JOIN; class JOIN;
struct st_join_table;
using JOIN_TAB= struct st_join_table;
enum enum_nested_loop_state enum enum_nested_loop_state
{ {
...@@ -250,7 +258,7 @@ class Filesort; ...@@ -250,7 +258,7 @@ class Filesort;
struct SplM_plan_info; struct SplM_plan_info;
class SplM_opt_info; class SplM_opt_info;
typedef struct st_join_table { struct st_join_table {
TABLE *table; TABLE *table;
TABLE_LIST *tab_list; TABLE_LIST *tab_list;
KEYUSE *keyuse; /**< pointer to first used key */ KEYUSE *keyuse; /**< pointer to first used key */
...@@ -649,16 +657,7 @@ typedef struct st_join_table { ...@@ -649,16 +657,7 @@ typedef struct st_join_table {
If this join_tab reads a non-merged semi-join (also called jtbm), return If this join_tab reads a non-merged semi-join (also called jtbm), return
the select's number. Otherwise, return 0. the select's number. Otherwise, return 0.
*/ */
int get_non_merged_semijoin_select() const int get_non_merged_semijoin_select() const;
{
Item_in_subselect *subq;
if (table->pos_in_table_list &&
(subq= table->pos_in_table_list->jtbm_subselect))
{
return subq->unit->first_select()->select_number;
}
return 0; /* Not a merged semi-join */
}
bool access_from_tables_is_allowed(table_map used_tables, bool access_from_tables_is_allowed(table_map used_tables,
table_map sjm_lookup_tables) table_map sjm_lookup_tables)
...@@ -686,7 +685,7 @@ typedef struct st_join_table { ...@@ -686,7 +685,7 @@ typedef struct st_join_table {
table_map remaining_tables); table_map remaining_tables);
bool fix_splitting(SplM_plan_info *spl_plan, table_map remaining_tables, bool fix_splitting(SplM_plan_info *spl_plan, table_map remaining_tables,
bool is_const_table); bool is_const_table);
} JOIN_TAB; };
#include "sql_join_cache.h" #include "sql_join_cache.h"
...@@ -1663,12 +1662,7 @@ class JOIN :public Sql_alloc ...@@ -1663,12 +1662,7 @@ class JOIN :public Sql_alloc
Return the table for which an index scan can be used to satisfy Return the table for which an index scan can be used to satisfy
the sort order needed by the ORDER BY/(implicit) GROUP BY clause the sort order needed by the ORDER BY/(implicit) GROUP BY clause
*/ */
JOIN_TAB *get_sort_by_join_tab() JOIN_TAB *get_sort_by_join_tab();
{
return (need_tmp || !sort_by_table || skip_sort_order ||
((group || tmp_table_param.sum_func_count) && !group_list)) ?
NULL : join_tab+const_tables;
}
bool setup_subquery_caches(); bool setup_subquery_caches();
bool shrink_join_buffers(JOIN_TAB *jt, bool shrink_join_buffers(JOIN_TAB *jt,
ulonglong curr_space, ulonglong curr_space,
...@@ -1839,19 +1833,7 @@ class store_key :public Sql_alloc ...@@ -1839,19 +1833,7 @@ class store_key :public Sql_alloc
@details this function makes sure truncation warnings when preparing the @details this function makes sure truncation warnings when preparing the
key buffers don't end up as errors (because of an enclosing INSERT/UPDATE). key buffers don't end up as errors (because of an enclosing INSERT/UPDATE).
*/ */
enum store_key_result copy(THD *thd) enum store_key_result copy(THD *thd);
{
enum store_key_result result;
enum_check_fields org_count_cuted_fields= thd->count_cuted_fields;
sql_mode_t org_sql_mode= thd->variables.sql_mode;
thd->variables.sql_mode&= ~(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE);
thd->variables.sql_mode|= MODE_INVALID_DATES;
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
result= copy_inner();
thd->count_cuted_fields= org_count_cuted_fields;
thd->variables.sql_mode= org_sql_mode;
return result;
}
protected: protected:
Field *to_field; // Store data here Field *to_field; // Store data here
...@@ -1937,36 +1919,7 @@ class store_key_item :public store_key ...@@ -1937,36 +1919,7 @@ class store_key_item :public store_key
const char *name() const override { return "func"; } const char *name() const override { return "func"; }
protected: protected:
enum store_key_result copy_inner() override enum store_key_result copy_inner() override;
{
TABLE *table= to_field->table;
MY_BITMAP *old_map= dbug_tmp_use_all_columns(table,
&table->write_set);
int res= FALSE;
/*
It looks like the next statement is needed only for a simplified
hash function over key values used now in BNLH join.
When the implementation of this function will be replaced for a proper
full version this statement probably should be removed.
*/
to_field->reset();
if (use_value)
item->save_val(to_field);
else
res= item->save_in_field(to_field, 1);
/*
Item::save_in_field() may call Item::val_xxx(). And if this is a subquery
we need to check for errors executing it and react accordingly
*/
if (!res && table->in_use->is_error())
res= 1; /* STORE_KEY_FATAL */
dbug_tmp_restore_column_map(&table->write_set, old_map);
null_key= to_field->is_null() || item->null_value;
return ((err != 0 || res < 0 || res > 2) ? STORE_KEY_FATAL :
(store_key_result) res);
}
}; };
......
...@@ -6794,3 +6794,9 @@ static Sys_var_ulonglong Sys_max_rowid_filter_size( ...@@ -6794,3 +6794,9 @@ static Sys_var_ulonglong Sys_max_rowid_filter_size(
SESSION_VAR(max_rowid_filter_size), CMD_LINE(REQUIRED_ARG), SESSION_VAR(max_rowid_filter_size), CMD_LINE(REQUIRED_ARG),
VALID_RANGE(1024, (ulonglong)~(intptr)0), DEFAULT(128*1024), VALID_RANGE(1024, (ulonglong)~(intptr)0), DEFAULT(128*1024),
BLOCK_SIZE(1)); BLOCK_SIZE(1));
bool Sys_var_mybool::session_update(THD *thd, set_var *var)
{
session_var(thd, my_bool)= var->save_result.ulonglong_value != 0;
return false;
}
...@@ -460,11 +460,7 @@ public: ...@@ -460,11 +460,7 @@ public:
SYSVAR_ASSERT(getopt.arg_type == OPT_ARG || getopt.id < 0); SYSVAR_ASSERT(getopt.arg_type == OPT_ARG || getopt.id < 0);
SYSVAR_ASSERT(size == sizeof(my_bool)); SYSVAR_ASSERT(size == sizeof(my_bool));
} }
bool session_update(THD *thd, set_var *var) bool session_update(THD *thd, set_var *var);
{
session_var(thd, my_bool)= var->save_result.ulonglong_value != 0;
return false;
}
bool global_update(THD *thd, set_var *var) bool global_update(THD *thd, set_var *var)
{ {
global_var(my_bool)= var->save_result.ulonglong_value != 0; global_var(my_bool)= var->save_result.ulonglong_value != 0;
......
...@@ -31,6 +31,7 @@ ADD_DEPENDENCIES(mf_iocache-t GenError) ...@@ -31,6 +31,7 @@ ADD_DEPENDENCIES(mf_iocache-t GenError)
MY_ADD_TEST(mf_iocache) MY_ADD_TEST(mf_iocache)
# Json writer needs String which needs sql library # Json writer needs String which needs sql library
#ADD_EXECUTABLE(my_json_writer-t my_json_writer-t.cc dummy_builtins.cc) ADD_EXECUTABLE(my_json_writer-t my_json_writer-t.cc dummy_builtins.cc)
#TARGET_LINK_LIBRARIES(my_json_writer-t sql mytap) TARGET_LINK_LIBRARIES(my_json_writer-t PUBLIC sql mytap)
#MY_ADD_TEST(my_json_writer) TARGET_COMPILE_DEFINITIONS(my_json_writer-t PUBLIC JSON_WRITER_UNIT_TEST)
MY_ADD_TEST(my_json_writer)
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
*/ */
struct TABLE; struct TABLE;
struct JOIN_TAB;
class Json_writer; class Json_writer;
...@@ -39,13 +38,15 @@ class Opt_trace ...@@ -39,13 +38,15 @@ class Opt_trace
Json_writer *get_current_json() { return nullptr; } Json_writer *get_current_json() { return nullptr; }
}; };
class THD class THD
{ {
public: public:
Opt_trace opt_trace; Opt_trace opt_trace;
}; };
#ifndef JSON_WRITER_UNIT_TEST
#define JSON_WRITER_UNIT_TEST #define JSON_WRITER_UNIT_TEST
#endif
#include "../sql/my_json_writer.h" #include "../sql/my_json_writer.h"
#include "../sql/my_json_writer.cc" #include "../sql/my_json_writer.cc"
...@@ -124,19 +125,15 @@ int main(int args, char **argv) ...@@ -124,19 +125,15 @@ int main(int args, char **argv)
w.start_object(); w.start_object();
w.add_member("name").add_ll(1); w.add_member("name").add_ll(1);
w.add_member("name").add_ll(2); w.add_member("name").add_ll(2);
w.end_object();
ok(w.invalid_json, "JSON object member name collision"); ok(w.invalid_json, "JSON object member name collision");
} }
{ {
Json_writer w; Json_writer w;
w.start_object(); w.start_object();
w.add_member("name").add_ll(1); w.add_member("name").start_object();
w.start_object();
w.add_member("name").add_ll(2); w.add_member("name").add_ll(2);
w.end_object(); ok(!w.invalid_json, "This must be valid JSON: nested object member has the same name");
w.end_object();
ok(!w.invalid_json, "Valid JSON: nested object member name is the same");
} }
diag("Done"); diag("Done");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment