MySQL 8.3.0
Source Code Documentation
item_cmpfunc.cc File Reference

This file defines all Items that compare values (e.g. More...

#include "sql/item_cmpfunc.h"
#include <algorithm>
#include <array>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdint>
#include <cstring>
#include <type_traits>
#include <utility>
#include "decimal.h"
#include "mf_wcomp.h"
#include "my_alloc.h"
#include "my_bitmap.h"
#include "my_dbug.h"
#include "my_sqlcommand.h"
#include "my_sys.h"
#include "mysql/strings/dtoa.h"
#include "mysql/strings/m_ctype.h"
#include "mysql/udf_registration_types.h"
#include "mysql_com.h"
#include "mysql_time.h"
#include "mysqld_error.h"
#include "sql-common/json_dom.h"
#include "sql/aggregate_check.h"
#include "sql/check_stack.h"
#include "sql/current_thd.h"
#include "sql/derror.h"
#include "sql/error_handler.h"
#include "sql/field.h"
#include "sql/histograms/histogram.h"
#include "sql/item_func.h"
#include "sql/item_json_func.h"
#include "sql/item_subselect.h"
#include "sql/item_sum.h"
#include "sql/item_timefunc.h"
#include "sql/join_optimizer/bit_utils.h"
#include "sql/key.h"
#include "sql/mysqld.h"
#include "sql/nested_join.h"
#include "sql/opt_trace.h"
#include "sql/opt_trace_context.h"
#include "sql/parse_tree_helpers.h"
#include "sql/parse_tree_node_base.h"
#include "sql/query_options.h"
#include "sql/sql_array.h"
#include "sql/sql_base.h"
#include "sql/sql_bitmap.h"
#include "sql/sql_class.h"
#include "sql/sql_const.h"
#include "sql/sql_error.h"
#include "sql/sql_executor.h"
#include "sql/sql_lex.h"
#include "sql/sql_opt_exec_shared.h"
#include "sql/sql_optimizer.h"
#include "sql/sql_select.h"
#include "sql/sql_time.h"
#include "sql/system_variables.h"
#include "sql/thd_raii.h"
#include "string_with_len.h"

Classes

class  Cmp_longlong
 
class  Cmp_row
 
class  anonymous_namespace{item_cmpfunc.cc}::Cmp_string
 

Namespaces

namespace  anonymous_namespace{item_cmpfunc.cc}
 

Macros

#define OLD_CMP
 

Functions

static bool convert_constant_item (THD *thd, Item_field *field_item, Item **item, bool *converted)
 Convert a constant item to an int and replace the original item. More...
 
static longlong get_year_value (THD *thd, Item ***item_arg, Item **cache_arg, const Item *warn_item, bool *is_null)
 
static Item ** cache_converted_constant (THD *thd, Item **value, Item **cache_item, Item_result type)
 Convert and cache a constant. More...
 
static bool row_types_are_compatible (Item *item1, Item *item2)
 Compare row signature of two expressions. More...
 
static Item_result agg_cmp_type (Item **items, uint nitems)
 Aggregates result types from the array of items. More...
 
static void write_histogram_to_trace (THD *thd, const Item_func *item, const double selectivity)
 
enum_field_types agg_field_type (Item **items, uint nitems)
 Aggregates field types from the array of items. More...
 
static uint collect_cmp_types (Item **items, uint nitems, bool skip_nulls=false)
 Collects different types for comparison of first item with each other items. More...
 
static void my_coll_agg_error (DTCollation &c1, DTCollation &c2, const char *fname)
 
static double get_histogram_selectivity (THD *thd, const Field &field, histograms::enum_operator op, const Item_func &item_func)
 Try to find the selectivity of an Item_func (predicate) using a histogram. More...
 
static double IndexSelectivityOfUnknownValue (const Field &field)
 Estimate the selectivity of a predicate of type field=expression, using an index containing 'field'. More...
 
static Itemmake_year_constant (Field *field)
 Return an an unsigned Item_int containing the value of the year as stored in field. More...
 
bool get_mysql_time_from_str_no_warn (THD *thd, String *str, MYSQL_TIME *l_time, MYSQL_TIME_STATUS *status)
 A minion of get_mysql_time_from_str, see its description. More...
 
bool get_mysql_time_from_str (THD *thd, String *str, enum_mysql_timestamp_type warn_type, const char *warn_name, MYSQL_TIME *l_time)
 Parse date provided in a string to a MYSQL_TIME. More...
 
static ulonglong get_date_from_str (THD *thd, String *str, enum_mysql_timestamp_type warn_type, const char *warn_name, bool *error_arg)
 Convert date provided in a string to its packed temporal int representation. More...
 
static longlong get_time_value (THD *, Item ***item_arg, Item **, const Item *, bool *is_null)
 Retrieves correct TIME value from the given item. More...
 
bool wrap_in_cast (Item **item, enum_field_types type)
 Wraps the item into a CAST function to the type provided as argument. More...
 
bool is_non_const_field_or_function (const Item &item)
 Checks that the argument is an aggregation function, window function, a built-in non-constant function or a non-constant field. More...
 
longlong get_datetime_value (THD *thd, Item ***item_arg, Item **, const Item *warn_item, bool *is_null)
 Retrieve correct DATETIME value from given item. More...
 
static bool get_json_arg (Item *arg, String *value, String *tmp, Json_wrapper *result, Json_scalar_holder **scalar)
 Get one of the arguments to the comparator as a JSON value. More...
 
static bool compare_pair_for_nulls (Item *a, Item *b, bool *result)
 Compare two argument items, or a pair of elements from two argument rows, for NULL values. More...
 
static double GetEqualSelectivity (THD *thd, Item_eq_base *equal, const Item_field &field, double rows_in_table)
 Compute selectivity for field=expression and field<=>expression, where 'expression' is not Item_null. More...
 
template<typename LLorULL >
static longlong compare_between_int_result (bool compare_as_temporal_dates, bool compare_as_temporal_times, bool negated, Item **args, bool *null_value)
 A helper function for Item_func_between::val_int() to avoid over/underflow when comparing large values. More...
 
static void change_item_tree_if_needed (Item **place, Item *new_value)
 Check if (*place) and new_value points to different Items and call THD::change_item_tree() if needed. More...
 
static int cmp_longs (longlong a_val, longlong b_val)
 
static int cmp_ulongs (ulonglong a_val, ulonglong b_val)
 
static int cmp_longlong (const in_longlong::packed_longlong *a, const in_longlong::packed_longlong *b)
 
static int srtcmp_in (const CHARSET_INFO *cs, const String *x, const String *y)
 
static cmp_item_jsonmake_cmp_item_json (MEM_ROOT *mem_root)
 Create a cmp_item_json object on a MEM_ROOT. More...
 
Itemmake_condition (Parse_context *pc, Item *item)
 Ensure that all expressions involved in conditions are boolean functions. More...
 
static bool append_string_value (Item *comparand, const CHARSET_INFO *character_set, size_t max_char_length, bool pad_char_to_full_length, bool is_multi_column_key, String *join_key_buffer)
 
static bool append_double_value (double value, bool is_null, String *join_key_buffer)
 
static bool append_int_value (longlong value, bool is_null, bool unsigned_flag, String *join_key_buffer)
 
static bool append_hash_for_string_value (Item *comparand, const CHARSET_INFO *character_set, String *join_key_buffer)
 
static bool append_hash_for_json_value (Item *comparand, String *join_key_buffer)
 
static bool append_decimal_value (Item *comparand, bool is_multi_column_key, String *join_key_buffer)
 
static bool extract_value_for_hash_join (THD *thd, const HashJoinCondition &join_condition, const Arg_comparator *comparator, bool is_left_argument, bool is_multi_column_key, String *join_key_buffer)
 Extract the value from the item and append it to the output buffer "join_key_buffer" in a memcmp-able format. More...
 
void find_and_adjust_equal_fields (Item *item, table_map available_tables, bool replace, bool *found)
 
static void ensure_multi_equality_fields_are_available (Item **args, int arg_idx, table_map available_tables, bool replace, bool *found)
 

Variables

static const enum_walk walk_options
 
static constexpr double kUndefinedSelectivity {-1.0}
 This is used to indicate that the selectivity of a predicate has not been determined. More...
 

Detailed Description

This file defines all Items that compare values (e.g.

>=, ==, LIKE, etc.)

Macro Definition Documentation

◆ OLD_CMP

#define OLD_CMP

Function Documentation

◆ agg_cmp_type()

static Item_result agg_cmp_type ( Item **  items,
uint  nitems 
)
static

Aggregates result types from the array of items.

This function aggregates result types from the array of items. Found type supposed to be used later for comparison of values of these items. Aggregation itself is performed by the item_cmp_type() function.

Parameters
itemsarray of items to aggregate the type from
nitemsnumber of items in the array
Returns
the aggregated type

◆ agg_field_type()

enum_field_types agg_field_type ( Item **  items,
uint  nitems 
)

Aggregates field types from the array of items.

Parameters
[in]itemsarray of items to aggregate the type from
[in]nitemsnumber of items in the array

This function aggregates field types from the array of items. Found type is supposed to be used later as the result field type of a multi-argument function. Aggregation itself is performed by the Field::field_type_merge() function.

Note
The term "aggregation" is used here in the sense of inferring the result type of a function from its argument types.
Returns
aggregated field type.

◆ append_decimal_value()

static bool append_decimal_value ( Item comparand,
bool  is_multi_column_key,
String join_key_buffer 
)
static

◆ append_double_value()

static bool append_double_value ( double  value,
bool  is_null,
String join_key_buffer 
)
static

◆ append_hash_for_json_value()

static bool append_hash_for_json_value ( Item comparand,
String join_key_buffer 
)
static

◆ append_hash_for_string_value()

static bool append_hash_for_string_value ( Item comparand,
const CHARSET_INFO character_set,
String join_key_buffer 
)
static

◆ append_int_value()

static bool append_int_value ( longlong  value,
bool  is_null,
bool  unsigned_flag,
String join_key_buffer 
)
static

◆ append_string_value()

static bool append_string_value ( Item comparand,
const CHARSET_INFO character_set,
size_t  max_char_length,
bool  pad_char_to_full_length,
bool  is_multi_column_key,
String join_key_buffer 
)
static

◆ cache_converted_constant()

static Item ** cache_converted_constant ( THD thd,
Item **  value,
Item **  cache_item,
Item_result  type 
)
static

Convert and cache a constant.

Parameters
thdThe current session.
valueAn item to cache
[out]cache_itemPlaceholder for the cache item
typeComparison type

When given item is a constant and its type differs from comparison type then cache its value to avoid type conversion of this constant on each evaluation. In this case the value is cached and the reference to the cache is returned. Original value is returned otherwise.

Returns
cache item or original value.

◆ change_item_tree_if_needed()

static void change_item_tree_if_needed ( Item **  place,
Item new_value 
)
static

Check if (*place) and new_value points to different Items and call THD::change_item_tree() if needed.

This function is a workaround for implementation deficiency in Item_func_case. The problem there is that the 'args' attribute contains Items from different expressions.

The function must not be used elsewhere and will be remove eventually.

◆ cmp_longlong()

static int cmp_longlong ( const in_longlong::packed_longlong a,
const in_longlong::packed_longlong b 
)
static

◆ cmp_longs()

static int cmp_longs ( longlong  a_val,
longlong  b_val 
)
inlinestatic

◆ cmp_ulongs()

static int cmp_ulongs ( ulonglong  a_val,
ulonglong  b_val 
)
inlinestatic

◆ collect_cmp_types()

static uint collect_cmp_types ( Item **  items,
uint  nitems,
bool  skip_nulls = false 
)
static

Collects different types for comparison of first item with each other items.

Parameters
itemsArray of items to collect types from
nitemsNumber of items in the array
skip_nullsDon't collect types of NULL items if true
Note
This function collects different result types for comparison of the first item in the list with each of the remaining items in the 'items' array.
Return values
0Error, row type incompatibility has been detected
<>0 Bitmap of collected types - otherwise

◆ compare_between_int_result()

template<typename LLorULL >
static longlong compare_between_int_result ( bool  compare_as_temporal_dates,
bool  compare_as_temporal_times,
bool  negated,
Item **  args,
bool *  null_value 
)
inlinestatic

A helper function for Item_func_between::val_int() to avoid over/underflow when comparing large values.

Template Parameters
LLorULLulonglong or longlong
Parameters
compare_as_temporal_datescopy of Item_func_between member variable
compare_as_temporal_timescopy of Item_func_between member variable
negatedcopy of Item_func_between member variable
argscopy of Item_func_between member variable
[out]null_valueset to true if result is not true/false
Return values
trueif: args[1] <= args[0] <= args[2]

◆ compare_pair_for_nulls()

static bool compare_pair_for_nulls ( Item a,
Item b,
bool *  result 
)
static

Compare two argument items, or a pair of elements from two argument rows, for NULL values.

Parameters
aFirst item
bSecond item
[out]resultTrue if both items are NULL, false otherwise, when return value is true.
Returns
true if at least one of the items is NULL

◆ convert_constant_item()

static bool convert_constant_item ( THD thd,
Item_field field_item,
Item **  item,
bool *  converted 
)
static

Convert a constant item to an int and replace the original item.

The function converts a constant expression or string to an integer. On successful conversion the original item is substituted for the result of the item evaluation. This is done when comparing DATE/TIME of different formats and also when comparing bigint to strings (in which case strings are converted to bigints).

Parameters
thdthread handle
field_itemitem will be converted using the type of this field
[in,out]itemreference to the item to convert
[out]convertedTrue if a replacement was done.
Note
This function may be called both at prepare and optimize stages. When called at optimize stage, ensure that we record transient changes.
Returns
false if success, true if error

◆ ensure_multi_equality_fields_are_available()

static void ensure_multi_equality_fields_are_available ( Item **  args,
int  arg_idx,
table_map  available_tables,
bool  replace,
bool *  found 
)
static

◆ extract_value_for_hash_join()

static bool extract_value_for_hash_join ( THD thd,
const HashJoinCondition join_condition,
const Arg_comparator comparator,
bool  is_left_argument,
bool  is_multi_column_key,
String join_key_buffer 
)
static

Extract the value from the item and append it to the output buffer "join_key_buffer" in a memcmp-able format.

The value extracted here will be used as the key in the hash table structure, where comparisons between keys are based on memcmp. Thus, it is important that the values extracted are memcmp-able, so for string values, we are basically creating a sort key. Other types (DECIMAL and FLOAT(M,N) and DOUBLE(M, N)) may be wrapped in a typecast in order to get a memcmp-able format from both sides of the condition. See Item_eq_base::create_cast_if_needed for more details.

Parameters
thdthe thread handler
join_conditionThe hash join condition from which to get the value to write into the buffer.
comparatorthe comparator set up by Item_cmpfunc. This gives us the context in which the comparison is done. It is also needed for extracting the value in case of DATE/TIME/DATETIME/YEAR values in some cases
is_left_argumentwhether or not the provided item is the left argument of the condition. This is needed in case the comparator has set up a custom function for extracting the value from the item, as there are two separate functions for each side of the condition
is_multi_column_keytrue if the hash join key has multiple columns (that is, the hash join condition is a conjunction)
[out]join_key_bufferthe output buffer where the extracted value is appended
Returns
true if a SQL NULL value was found

◆ find_and_adjust_equal_fields()

void find_and_adjust_equal_fields ( Item item,
table_map  available_tables,
bool  replace,
bool *  found 
)

◆ get_date_from_str()

static ulonglong get_date_from_str ( THD thd,
String str,
enum_mysql_timestamp_type  warn_type,
const char *  warn_name,
bool *  error_arg 
)
static

Convert date provided in a string to its packed temporal int representation.

Parameters
[in]thdthread handle
[in]stra string to convert
[in]warn_typetype of the timestamp for issuing the warning
[in]warn_namefield name for issuing the warning
[out]error_argcould not extract a DATE or DATETIME

Convert date provided in the string str to the int representation. If the string contains wrong date or doesn't contain it at all then a warning is issued. The warn_type and the warn_name arguments are used as the name and the type of the field when issuing the warning.

Returns
converted value. 0 on error and on zero-dates – check 'failure'

◆ get_datetime_value()

longlong get_datetime_value ( THD thd,
Item ***  item_arg,
Item **  ,
const Item warn_item,
bool *  is_null 
)

Retrieve correct DATETIME value from given item.

Parameters
thdthread handle
item_argitem to retrieve DATETIME value from
warn_itemitem for issuing the conversion warning
[out]is_nulltrue <=> the item_arg is null

Retrieves the correct DATETIME value from given item for comparison by the compare_datetime() function. If item's result can be compared as longlong then its int value is used and its string value is used otherwise. Strings are always parsed and converted to int values by the get_date_from_str() function. This allows us to compare correctly string dates with missed insignificant zeros. In order to compare correctly DATE and DATETIME items the result of the former are treated as a DATETIME with zero time (00:00:00).

Returns
the DATETIME value, all ones if Item is NULL

◆ get_histogram_selectivity()

static double get_histogram_selectivity ( THD thd,
const Field field,
histograms::enum_operator  op,
const Item_func item_func 
)
static

Try to find the selectivity of an Item_func (predicate) using a histogram.

Parameters
thdThe current thread.
fieldThe field for which we will look for a histogram.
opThe comparison operator of item_func.
item_funcThe predicate.
Returns
The selectivity if a histogram was found and the arguments of item_func allowed use of a histogram. Otherwise, kUndefinedSelectivity.

◆ get_json_arg()

static bool get_json_arg ( Item arg,
String value,
String tmp,
Json_wrapper result,
Json_scalar_holder **  scalar 
)
static

Get one of the arguments to the comparator as a JSON value.

Parameters
[in]argpointer to the argument
[in,out]valuebuffer used for reading the JSON value
[in,out]tmpbuffer used for converting string values to the correct charset, if necessary
[out]resultwhere to store the result
[in,out]scalarpointer to a location with pre-allocated memory used for JSON scalars that are converted from SQL scalars
Return values
falseon success
trueon failure

◆ get_mysql_time_from_str()

bool get_mysql_time_from_str ( THD thd,
String str,
enum_mysql_timestamp_type  warn_type,
const char *  warn_name,
MYSQL_TIME l_time 
)

Parse date provided in a string to a MYSQL_TIME.

Parameters
[in]thdThread handle
[in]strA string to convert
[in]warn_typeType of the timestamp for issuing the warning
[in]warn_nameField name for issuing the warning
[out]l_timeThe MYSQL_TIME objects is initialized.

Parses a date provided in the string str into a MYSQL_TIME object. If the string contains an incorrect date or doesn't correspond to a date at all then a warning is issued. The warn_type and the warn_name arguments are used as the name and the type of the field when issuing the warning. If any input was discarded (trailing or non-timestamp-y characters), return value will be true.

Returns
Status flag
Return values
falseSuccess.
TrueIndicates failure.

◆ get_mysql_time_from_str_no_warn()

bool get_mysql_time_from_str_no_warn ( THD thd,
String str,
MYSQL_TIME l_time,
MYSQL_TIME_STATUS status 
)

A minion of get_mysql_time_from_str, see its description.

This version doesn't issue any warnings, leaving that to its parent. This method has one extra argument which return warnings.

Parameters
[in]thdThread handle
[in]strA string to convert
[out]l_timeThe MYSQL_TIME objects is initialized.
[in,out]statusAny warnings given are returned here
Returns
true if error

◆ get_time_value()

static longlong get_time_value ( THD ,
Item ***  item_arg,
Item **  ,
const Item ,
bool *  is_null 
)
static

Retrieves correct TIME value from the given item.

Parameters
[in,out]item_argitem to retrieve TIME value from
[out]is_nulltrue <=> the item_arg is null
Returns
obtained value

Retrieves the correct TIME value from given item for comparison by the compare_datetime() function. If item's result can be compared as longlong then its int value is used and a value returned by get_time function is used otherwise.

◆ get_year_value()

static longlong get_year_value ( THD thd,
Item ***  item_arg,
Item **  cache_arg,
const Item warn_item,
bool *  is_null 
)
static

◆ GetEqualSelectivity()

static double GetEqualSelectivity ( THD thd,
Item_eq_base equal,
const Item_field field,
double  rows_in_table 
)
static

Compute selectivity for field=expression and field<=>expression, where 'expression' is not Item_null.

Parameters
thdThe current thread.
equalThe '=' or '<=>' term.
fieldThe field we compare with 'expression'.
rows_in_tableNumber of rows in the table of 'field'.
Returns
Selectivity estimate.

◆ IndexSelectivityOfUnknownValue()

static double IndexSelectivityOfUnknownValue ( const Field field)
static

Estimate the selectivity of a predicate of type field=expression, using an index containing 'field'.

('expression' is assumed to be independent of the table that 'field' belongs to, meaning that this function should not be called for e.g. "t1.f1=t1.f2+1").

Parameters
fieldThe field for which we estimate the selectivity.
Returns
The selectivity estimate, or kUndefinedSelectivity if no suitable index was found.

◆ is_non_const_field_or_function()

bool is_non_const_field_or_function ( const Item item)
inline

Checks that the argument is an aggregation function, window function, a built-in non-constant function or a non-constant field.

WL#12108: it excludes stored procedures and functions, user defined functions and also does not update the content of expressions inside Value_generator since Optimize is not called after the expression is unpacked.

Parameters
itemto be checked
Returns
true for non-const field or functions, false otherwise

◆ make_cmp_item_json()

static cmp_item_json * make_cmp_item_json ( MEM_ROOT mem_root)
static

Create a cmp_item_json object on a MEM_ROOT.

◆ make_condition()

Item * make_condition ( Parse_context pc,
Item item 
)

Ensure that all expressions involved in conditions are boolean functions.

Specifically, change <non-bool-expr> to (0 <> <non-bool-expr>)

Parameters
pcParse context, including memroot for Item construction
itemAny expression, if not a boolean expression, convert it
Returns
= NULL Error <> NULL A boolean expression, possibly constructed as described above
Note
Due to the special conditions of a MATCH expression (it is both a function returning a floating point value and it may be used standalone in the WHERE clause), it is wrapped inside a special Item_func_match_predicate, instead of forming a non-equality.

◆ make_year_constant()

static Item * make_year_constant ( Field field)
static

Return an an unsigned Item_int containing the value of the year as stored in field.

The item is typed as a YEAR.

Parameters
fieldthe field containign the year value
Returns
the year wrapped in an Item in as described above, or nullptr on error.

◆ my_coll_agg_error()

static void my_coll_agg_error ( DTCollation c1,
DTCollation c2,
const char *  fname 
)
static

◆ row_types_are_compatible()

static bool row_types_are_compatible ( Item item1,
Item item2 
)
static

Compare row signature of two expressions.

Parameters
item1first expression
item2second expression
Returns
true if row types are compatible, false otherwise.

The function checks that two expressions have compatible row signatures i.e. that the number of columns they return are the same and that if they are both row expressions then each component from the first expression has a row signature compatible with the signature of the corresponding component of the second expression.

◆ srtcmp_in()

static int srtcmp_in ( const CHARSET_INFO cs,
const String x,
const String y 
)
static

◆ wrap_in_cast()

bool wrap_in_cast ( Item **  item,
enum_field_types  type 
)
inline

Wraps the item into a CAST function to the type provided as argument.

Parameters
item- the item to be wrapped
type- the type to wrap the item to
Returns
true if error (OOM), false otherwise.

◆ write_histogram_to_trace()

static void write_histogram_to_trace ( THD thd,
const Item_func item,
const double  selectivity 
)
static

Variable Documentation

◆ kUndefinedSelectivity

constexpr double kUndefinedSelectivity {-1.0}
staticconstexpr

This is used to indicate that the selectivity of a predicate has not been determined.

◆ walk_options

const enum_walk walk_options
static