summaryrefslogtreecommitdiff
path: root/sql/item.h
diff options
context:
space:
mode:
Diffstat (limited to 'sql/item.h')
-rw-r--r--sql/item.h1669
1 files changed, 1152 insertions, 517 deletions
diff --git a/sql/item.h b/sql/item.h
index 2adc111db03..b0d3666ead7 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -100,7 +100,10 @@ class sp_head;
class Protocol;
struct TABLE_LIST;
void item_init(void); /* Init item functions */
+class Item_basic_value;
+class Item_result_field;
class Item_field;
+class Item_ref;
class Item_param;
class user_var_entry;
class JOIN;
@@ -108,6 +111,7 @@ struct KEY_FIELD;
struct SARGABLE_PARAM;
class RANGE_OPT_PARAM;
class SEL_TREE;
+class With_sum_func_cache;
enum precedence {
LOWEST_PRECEDENCE,
@@ -147,8 +151,9 @@ bool mark_unsupported_function(const char *w1, const char *w2,
#define NO_EXTRACTION_FL (1 << 6)
#define FULL_EXTRACTION_FL (1 << 7)
-#define SUBSTITUTION_FL (1 << 8)
-#define EXTRACTION_MASK (NO_EXTRACTION_FL | FULL_EXTRACTION_FL)
+#define DELETION_FL (1 << 8)
+#define SUBSTITUTION_FL (1 << 9)
+#define EXTRACTION_MASK (NO_EXTRACTION_FL | FULL_EXTRACTION_FL | DELETION_FL)
extern const char *item_empty_name;
@@ -597,6 +602,7 @@ typedef bool (Item::*Item_processor) (void *arg);
typedef bool (Item::*Item_analyzer) (uchar **argp);
typedef Item* (Item::*Item_transformer) (THD *thd, uchar *arg);
typedef void (*Cond_traverser) (const Item *item, void *arg);
+typedef bool (Item::*Pushdown_checker) (uchar *arg);
struct st_cond_statistic;
@@ -629,6 +635,87 @@ public:
String_copier_for_item(THD *thd): m_thd(thd) { }
};
+
+/**
+ A helper class describing what kind of Item created a temporary field.
+ - If m_field is set, then the temporary field was created from Field
+ (e.g. when the Item was Item_field, or Item_ref pointing to Item_field)
+ - If m_default_field is set, then there is a usable DEFAULT value.
+ (e.g. when the Item is Item_field)
+ - If m_item_result_field is set, then the temporary field was created
+ from certain sub-types of Item_result_field (e.g. Item_func)
+ See create_tmp_field() in sql_select.cc for details.
+*/
+
+class Tmp_field_src
+{
+ Field *m_field;
+ Field *m_default_field;
+ Item_result_field *m_item_result_field;
+public:
+ Tmp_field_src()
+ :m_field(0),
+ m_default_field(0),
+ m_item_result_field(0)
+ { }
+ Field *field() const { return m_field; }
+ Field *default_field() const { return m_default_field; }
+ Item_result_field *item_result_field() const { return m_item_result_field; }
+ void set_field(Field *field) { m_field= field; }
+ void set_default_field(Field *field) { m_default_field= field; }
+ void set_item_result_field(Item_result_field *item)
+ { m_item_result_field= item; }
+};
+
+
+/**
+ Parameters for create_tmp_field_ex().
+ See create_tmp_field() in sql_select.cc for details.
+*/
+
+class Tmp_field_param
+{
+ bool m_group;
+ bool m_modify_item;
+ bool m_table_cant_handle_bit_fields;
+ bool m_make_copy_field;
+public:
+ Tmp_field_param(bool group,
+ bool modify_item,
+ bool table_cant_handle_bit_fields,
+ bool make_copy_field)
+ :m_group(group),
+ m_modify_item(modify_item),
+ m_table_cant_handle_bit_fields(table_cant_handle_bit_fields),
+ m_make_copy_field(make_copy_field)
+ { }
+ bool group() const { return m_group; }
+ bool modify_item() const { return m_modify_item; }
+ bool table_cant_handle_bit_fields() const
+ { return m_table_cant_handle_bit_fields; }
+ bool make_copy_field() const { return m_make_copy_field; }
+ void set_modify_item(bool to) { m_modify_item= to; }
+};
+
+
+class Item_const
+{
+public:
+ virtual ~Item_const() {}
+ virtual const Type_all_attributes *get_type_all_attributes_from_const() const= 0;
+ virtual bool const_is_null() const { return false; }
+ virtual const longlong *const_ptr_longlong() const { return NULL; }
+ virtual const double *const_ptr_double() const { return NULL; }
+ virtual const my_decimal *const_ptr_my_decimal() const { return NULL; }
+ virtual const MYSQL_TIME *const_ptr_mysql_time() const { return NULL; }
+ virtual const String *const_ptr_string() const { return NULL; }
+};
+
+
+/****************************************************************************/
+
+#define STOP_PTR ((void *) 1)
+
class Item: public Value_source,
public Type_all_attributes
{
@@ -653,16 +740,26 @@ public:
static void operator delete(void *ptr, MEM_ROOT *mem_root) {}
enum Type {FIELD_ITEM= 0, FUNC_ITEM, SUM_FUNC_ITEM,
- WINDOW_FUNC_ITEM, STRING_ITEM,
- INT_ITEM, REAL_ITEM, NULL_ITEM, VARBIN_ITEM,
- COPY_STR_ITEM, FIELD_AVG_ITEM, DEFAULT_VALUE_ITEM,
- PROC_ITEM,COND_ITEM, REF_ITEM, FIELD_STD_ITEM,
- FIELD_VARIANCE_ITEM, INSERT_VALUE_ITEM,
+ WINDOW_FUNC_ITEM,
+ /*
+ NOT NULL literal-alike constants, which do not change their
+ value during an SQL statement execution, but can optionally
+ change their value between statements:
+ - Item_literal - real NOT NULL constants
+ - Item_param - can change between statements
+ - Item_splocal - can change between statements
+ - Item_user_var_as_out_param - hack
+ Note, Item_user_var_as_out_param actually abuses the type code.
+ It should be moved out of the Item tree eventually.
+ */
+ CONST_ITEM,
+ NULL_ITEM, // Item_null or Item_param bound to NULL
+ COPY_STR_ITEM, FIELD_AVG_ITEM, DEFAULT_VALUE_ITEM,
+ PROC_ITEM,COND_ITEM, REF_ITEM, FIELD_STD_ITEM,
+ FIELD_VARIANCE_ITEM, INSERT_VALUE_ITEM,
SUBSELECT_ITEM, ROW_ITEM, CACHE_ITEM, TYPE_HOLDER,
- PARAM_ITEM, TRIGGER_FIELD_ITEM, DECIMAL_ITEM,
- XPATH_NODESET, XPATH_NODESET_CMP,
- VIEW_FIXER_ITEM, EXPR_CACHE_ITEM,
- DATE_ITEM};
+ PARAM_ITEM, TRIGGER_FIELD_ITEM,
+ EXPR_CACHE_ITEM};
enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE };
@@ -704,11 +801,34 @@ protected:
*/
Field *tmp_table_field_from_field_type(TABLE *table)
{
+ DBUG_ASSERT(is_fixed());
const Type_handler *h= type_handler()->type_handler_for_tmp_table(this);
return h->make_and_init_table_field(&name, Record_addr(maybe_null),
*this, table);
}
+ /**
+ Create a temporary field for a simple Item, which does not
+ need any special action after the field creation:
+ - is not an Item_field descendant (and not a reference to Item_field)
+ - is not an Item_result_field descendant
+ - does not need to copy any DEFAULT value to the result Field
+ - does not need to set Field::is_created_from_null_item for the result
+ See create_tmp_field_ex() for details on parameters and return values.
+ */
+ Field *create_tmp_field_ex_simple(TABLE *table,
+ Tmp_field_src *src,
+ const Tmp_field_param *param)
+ {
+ DBUG_ASSERT(!param->make_copy_field());
+ DBUG_ASSERT(!is_result_field());
+ DBUG_ASSERT(type() != NULL_ITEM);
+ return tmp_table_field_from_field_type(table);
+ }
Field *create_tmp_field_int(TABLE *table, uint convert_int_length);
+ Field *tmp_table_field_from_field_type_maybe_null(TABLE *table,
+ Tmp_field_src *src,
+ const Tmp_field_param *param,
+ bool is_explicit_null);
void push_note_converted_to_negative_complement(THD *thd);
void push_note_converted_to_positive_complement(THD *thd);
@@ -716,21 +836,21 @@ protected:
/* Helper methods, to get an Item value from another Item */
double val_real_from_item(Item *item)
{
- DBUG_ASSERT(fixed == 1);
+ DBUG_ASSERT(is_fixed());
double value= item->val_real();
null_value= item->null_value;
return value;
}
longlong val_int_from_item(Item *item)
{
- DBUG_ASSERT(fixed == 1);
+ DBUG_ASSERT(is_fixed());
longlong value= item->val_int();
null_value= item->null_value;
return value;
}
String *val_str_from_item(Item *item, String *str)
{
- DBUG_ASSERT(fixed == 1);
+ DBUG_ASSERT(is_fixed());
String *res= item->val_str(str);
if (res)
res->set_charset(collation.collation);
@@ -738,33 +858,48 @@ protected:
res= NULL;
return res;
}
+ bool val_native_from_item(THD *thd, Item *item, Native *to)
+ {
+ DBUG_ASSERT(is_fixed());
+ null_value= item->val_native(thd, to);
+ DBUG_ASSERT(null_value == item->null_value);
+ return null_value;
+ }
+ bool val_native_from_field(Field *field, Native *to)
+ {
+ if ((null_value= field->is_null()))
+ return true;
+ return (null_value= field->val_native(to));
+ }
+ bool val_native_with_conversion_from_item(THD *thd, Item *item, Native *to,
+ const Type_handler *handler)
+ {
+ DBUG_ASSERT(is_fixed());
+ return null_value= item->val_native_with_conversion(thd, to, handler);
+ }
my_decimal *val_decimal_from_item(Item *item, my_decimal *decimal_value)
{
- DBUG_ASSERT(fixed == 1);
+ DBUG_ASSERT(is_fixed());
my_decimal *value= item->val_decimal(decimal_value);
if ((null_value= item->null_value))
value= NULL;
return value;
}
- bool get_date_from_item(Item *item, MYSQL_TIME *ltime, ulonglong fuzzydate)
+ bool get_date_from_item(THD *thd, Item *item,
+ MYSQL_TIME *ltime, date_mode_t fuzzydate)
{
- bool rc= item->get_date(ltime, fuzzydate);
+ bool rc= item->get_date(thd, ltime, fuzzydate);
null_value= MY_TEST(rc || item->null_value);
return rc;
}
- /*
- This method is used if the item was not null but convertion to
- TIME/DATE/DATETIME failed. We return a zero date if allowed,
- otherwise - null.
- */
- bool make_zero_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
-
public:
+
/*
Cache val_str() into the own buffer, e.g. to evaluate constant
expressions with subqueries in the ORDER/GROUP clauses.
*/
String *val_str() { return val_str(&str_value); }
+ virtual Item_func *get_item_func() { return NULL; }
const MY_LOCALE *locale_from_val_str();
@@ -784,14 +919,12 @@ public:
bool in_rollup; /* If used in GROUP BY list
of a query with ROLLUP */
bool null_value; /* if item is null */
- bool with_sum_func; /* True if item contains a sum func */
bool with_param; /* True if contains an SP parameter */
bool with_window_func; /* True if item contains a window func */
/**
True if any item except Item_sum contains a field. Set during parsing.
*/
bool with_field;
- bool fixed; /* If item fixed with fix_fields */
bool is_autogenerated_name; /* indicate was name of this Item
autogenerated or set by user */
// alloc & destruct is done as start of select on THD::mem_root
@@ -815,13 +948,13 @@ public:
void set_name(THD *thd, const char *str, size_t length, CHARSET_INFO *cs);
void set_name_no_truncate(THD *thd, const char *str, uint length,
CHARSET_INFO *cs);
- void init_make_send_field(Send_field *tmp_field,enum enum_field_types type);
+ void init_make_send_field(Send_field *tmp_field, const Type_handler *h);
virtual void cleanup();
virtual void make_send_field(THD *thd, Send_field *field);
bool fix_fields_if_needed(THD *thd, Item **ref)
{
- return fixed ? false : fix_fields(thd, ref);
+ return is_fixed() ? false : fix_fields(thd, ref);
}
bool fix_fields_if_needed_for_scalar(THD *thd, Item **ref)
{
@@ -835,7 +968,27 @@ public:
{
return fix_fields_if_needed_for_scalar(thd, ref);
}
- virtual bool fix_fields(THD *, Item **);
+ /*
+ By default we assume that an Item is fixed by the contstructor.
+ */
+ virtual bool fix_fields(THD *, Item **)
+ {
+ /*
+ This should not normally be called, because usually before
+ fix_fields() we check is_fixed() to be false.
+ But historically we allow fix_fields() to be called for Items
+ who return basic_const_item()==true.
+ */
+ DBUG_ASSERT(is_fixed());
+ DBUG_ASSERT(basic_const_item());
+ return false;
+ }
+ virtual bool is_fixed() const { return true; }
+ virtual void unfix_fields()
+ {
+ DBUG_ASSERT(0);
+ }
+
/*
Fix after some tables has been pulled out. Basically re-calculate all
attributes that are dependent on the tables.
@@ -855,11 +1008,14 @@ public:
but rather uses intermediate type conversion items. Then the method is
supposed to be applied recursively.
*/
- virtual inline void quick_fix_field() { fixed= 1; }
+ virtual void quick_fix_field()
+ {
+ DBUG_ASSERT(0);
+ }
- bool save_in_value(struct st_value *value)
+ bool save_in_value(THD *thd, struct st_value *value)
{
- return type_handler()->Item_save_in_value(this, value);
+ return type_handler()->Item_save_in_value(thd, this, value);
}
/* Function returns 1 on overflow and -1 on fatal errors */
@@ -884,6 +1040,21 @@ public:
return type_handler()->field_type();
}
virtual const Type_handler *type_handler() const= 0;
+ /**
+ Detects if an Item has a fixed data type which is known
+ even before fix_fields().
+ Currently it's important only to find Items with a fixed boolean
+ data type. More item types can be marked in the future as having
+ a fixed data type (e.g. all literals, all fixed type functions, etc).
+
+ @retval NULL if the Item type is not known before fix_fields()
+ @retval the pointer to the data type handler, if the data type
+ is known before fix_fields().
+ */
+ virtual const Type_handler *fixed_type_handler() const
+ {
+ return NULL;
+ }
const Type_handler *type_handler_for_comparison() const
{
return type_handler()->type_handler_for_comparison();
@@ -892,13 +1063,9 @@ public:
{
return type_handler();
}
- virtual const Type_handler *cast_to_int_type_handler() const
- {
- return type_handler();
- }
- virtual const Type_handler *type_handler_for_system_time() const
+ const Type_handler *cast_to_int_type_handler() const
{
- return real_type_handler();
+ return real_type_handler()->cast_to_int_type_handler();
}
/* result_type() of an item specifies how the value should be returned */
Item_result result_type() const
@@ -954,6 +1121,10 @@ public:
return type_handler()->Item_get_cache(thd, this);
}
virtual enum Type type() const =0;
+ bool is_of_type(Type t, Item_result cmp) const
+ {
+ return type() == t && cmp_type() == cmp;
+ }
/*
real_type() is the type of base item. This is same as type() for
most items, except Item_ref() and Item_cache_wrapper() where it
@@ -1018,6 +1189,12 @@ public:
If value is not null null_value flag will be reset to FALSE.
*/
virtual double val_real()=0;
+ Double_null to_double_null()
+ {
+ // val_real() must be caleed on a separate line. See to_longlong_null()
+ double nr= val_real();
+ return Double_null(nr, null_value);
+ }
/*
Return integer representation of item.
@@ -1033,6 +1210,20 @@ public:
{
return Longlong_hybrid(val_int(), unsigned_flag);
}
+ Longlong_null to_longlong_null()
+ {
+ longlong nr= val_int();
+ /*
+ C++ does not guarantee the order of parameter evaluation,
+ so to make sure "null_value" is passed to the constructor
+ after the val_int() call, val_int() is caled on a separate line.
+ */
+ return Longlong_null(nr, null_value);
+ }
+ Longlong_hybrid_null to_longlong_hybrid_null()
+ {
+ return Longlong_hybrid_null(to_longlong_null(), unsigned_flag);
+ }
/**
Get a value for CAST(x AS SIGNED).
Too large positive unsigned integer values are converted
@@ -1054,15 +1245,16 @@ public:
{
return cast_to_int_type_handler()->Item_val_int_unsigned_typecast(this);
}
- longlong val_int_unsigned_typecast_from_decimal();
longlong val_int_unsigned_typecast_from_int();
longlong val_int_unsigned_typecast_from_str();
+ longlong val_int_unsigned_typecast_from_real();
/**
Get a value for CAST(x AS UNSIGNED).
Huge positive unsigned values are converted to negative complements.
*/
longlong val_int_signed_typecast_from_int();
+ longlong val_int_signed_typecast_from_real();
/*
This is just a shortcut to avoid the cast. You should still use
@@ -1101,6 +1293,59 @@ public:
*/
virtual String *val_str(String *str)=0;
+
+ bool val_native_with_conversion(THD *thd, Native *to, const Type_handler *th)
+ {
+ return th->Item_val_native_with_conversion(thd, this, to);
+ }
+ bool val_native_with_conversion_result(THD *thd, Native *to,
+ const Type_handler *th)
+ {
+ return th->Item_val_native_with_conversion_result(thd, this, to);
+ }
+
+ virtual bool val_native(THD *thd, Native *to)
+ {
+ /*
+ The default implementation for the Items that do not need native format:
+ - Item_basic_value
+ - Item_copy
+ - Item_exists_subselect
+ - Item_sum_field
+ - Item_sum_or_func (default implementation)
+ - Item_proc
+ - Item_type_holder (as val_xxx() are never called for it);
+ - TODO: Item_name_const will need val_native() in the future,
+ when we add this syntax:
+ TIMESTAMP WITH LOCAL TIMEZONE'2001-01-01 00:00:00'
+
+ These hybrid Item types override val_native():
+ - Item_field
+ - Item_param
+ - Item_sp_variable
+ - Item_ref
+ - Item_cache_wrapper
+ - Item_direct_ref
+ - Item_direct_view_ref
+ - Item_ref_null_helper
+ - Item_sum_or_func
+ Note, these hybrid type Item_sum_or_func descendants
+ override the default implementation:
+ * Item_sum_hybrid
+ * Item_func_hybrid_field_type
+ * Item_func_min_max
+ * Item_func_sp
+ * Item_func_last_value
+ * Item_func_rollup_const
+ */
+ DBUG_ASSERT(0);
+ return null_value= true;
+ }
+ virtual bool val_native_result(THD *thd, Native *to)
+ {
+ return val_native(thd, to);
+ }
+
/*
Returns string representation of this item in ASCII format.
@@ -1213,7 +1458,7 @@ public:
{
return type_handler()->Item_val_bool(this);
}
- virtual String *val_nodeset(String*) { return 0; }
+ virtual String *val_raw(String*) { return 0; }
bool eval_const_cond()
{
@@ -1235,28 +1480,15 @@ public:
/* Helper functions, see item_sum.cc */
String *val_string_from_real(String *str);
String *val_string_from_int(String *str);
- String *val_string_from_decimal(String *str);
- String *val_string_from_date(String *str);
my_decimal *val_decimal_from_real(my_decimal *decimal_value);
my_decimal *val_decimal_from_int(my_decimal *decimal_value);
my_decimal *val_decimal_from_string(my_decimal *decimal_value);
- my_decimal *val_decimal_from_date(my_decimal *decimal_value);
- my_decimal *val_decimal_from_time(my_decimal *decimal_value);
- longlong val_int_from_decimal();
- longlong val_int_from_date();
longlong val_int_from_real()
{
- DBUG_ASSERT(fixed == 1);
+ DBUG_ASSERT(is_fixed());
return Converter_double_to_longlong_with_warn(val_real(), false).result();
}
longlong val_int_from_str(int *error);
- double val_real_from_decimal();
- double val_real_from_date();
-
- // Get TIME, DATE or DATETIME using proper sql_mode flags for the field type
- bool get_temporal_with_sql_mode(MYSQL_TIME *ltime);
- // Check NULL value for a TIME, DATE or DATETIME expression
- bool is_null_from_temporal();
int save_time_in_field(Field *field, bool no_conversions);
int save_date_in_field(Field *field, bool no_conversions);
@@ -1317,6 +1549,14 @@ public:
a constant expression. Used in the optimizer to propagate basic constants.
*/
virtual bool basic_const_item() const { return 0; }
+ /*
+ Test if "this" is an ORDER position (rather than an expression).
+ Notes:
+ - can be called before fix_fields().
+ - local SP variables (even of integer types) are always expressions, not
+ positions. (And they can't be used before fix_fields is called for them).
+ */
+ virtual bool is_order_clause_position() const { return false; }
/* cloning of constant items (0 if it is not const) */
virtual Item *clone_item(THD *thd) { return 0; }
virtual Item* build_clone(THD *thd) { return get_copy(thd); }
@@ -1364,14 +1604,14 @@ public:
/**
TIME or DATETIME precision of the item: 0..6
*/
- uint time_precision()
+ uint time_precision(THD *thd)
{
- return const_item() ? type_handler()->Item_time_precision(this) :
+ return const_item() ? type_handler()->Item_time_precision(thd, this) :
MY_MIN(decimals, TIME_SECOND_PART_DIGITS);
}
- uint datetime_precision()
+ uint datetime_precision(THD *thd)
{
- return const_item() ? type_handler()->Item_datetime_precision(this) :
+ return const_item() ? type_handler()->Item_datetime_precision(thd, this) :
MY_MIN(decimals, TIME_SECOND_PART_DIGITS);
}
virtual longlong val_int_min() const
@@ -1479,78 +1719,28 @@ public:
void split_sum_func2(THD *thd, Ref_ptr_array ref_pointer_array,
List<Item> &fields,
Item **ref, uint flags);
- virtual bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)= 0;
- bool get_date_from_int(MYSQL_TIME *ltime, ulonglong fuzzydate);
- bool get_date_from_year(MYSQL_TIME *ltime, ulonglong fuzzydate);
- bool get_date_from_real(MYSQL_TIME *ltime, ulonglong fuzzydate);
- bool get_date_from_decimal(MYSQL_TIME *ltime, ulonglong fuzzydate);
- bool get_date_from_string(MYSQL_TIME *ltime, ulonglong fuzzydate);
- bool get_time(MYSQL_TIME *ltime)
- { return get_date(ltime, Time::flags_for_get_date()); }
- /*
- Get time with automatic DATE/DATETIME to TIME conversion,
- by subtracting CURRENT_DATE.
-
- Performce a reverse operation to CAST(time AS DATETIME)
- Suppose:
- - we have a set of items (typically with the native MYSQL_TYPE_TIME type)
- whose item->get_date() return TIME1 value, and
- - CAST(AS DATETIME) for the same Items return DATETIME1,
- after applying time-to-datetime conversion to TIME1.
-
- then all items (typically of the native MYSQL_TYPE_{DATE|DATETIME} types)
- whose get_date() return DATETIME1 must also return TIME1 from
- get_time_with_conversion()
-
- @param thd - the thread, its variables.old_mode is checked
- to decide if use simple YYYYMMDD truncation (old mode),
- or perform full DATETIME-to-TIME conversion with
- CURRENT_DATE subtraction.
- @param[out] ltime - store the result here
- @param fuzzydate - flags to be used for the get_date() call.
- Normally, should include TIME_TIME_ONLY, to let
- the called low-level routines, e.g. str_to_date(),
- know that we prefer TIME rather that DATE/DATETIME
- and do less conversion outside of the low-level
- routines.
-
- @returns true - on error, e.g. get_date() returned NULL value,
- or get_date() returned DATETIME/DATE with non-zero
- YYYYMMDD part.
- @returns false - on success
- */
- bool get_time_with_conversion(THD *thd, MYSQL_TIME *ltime,
- ulonglong fuzzydate);
+ virtual bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)= 0;
+ bool get_date_from_int(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate);
+ bool get_date_from_real(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate);
+ bool get_date_from_string(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate);
+ bool get_time(THD *thd, MYSQL_TIME *ltime)
+ { return get_date(thd, ltime, Time::Options(thd)); }
// Get a DATE or DATETIME value in numeric packed format for comparison
- virtual longlong val_datetime_packed()
+ virtual longlong val_datetime_packed(THD *thd)
{
- ulonglong fuzzydate= TIME_FUZZY_DATES | TIME_INVALID_DATES;
- Datetime dt(current_thd, this, fuzzydate);
- return dt.is_valid_datetime() ? pack_time(dt.get_mysql_time()) : 0;
+ return Datetime(thd, this, Datetime::Options_cmp(thd)).to_packed();
}
// Get a TIME value in numeric packed format for comparison
- virtual longlong val_time_packed()
- {
- Time tm(this, Time::comparison_flags_for_get_date());
- return tm.is_valid_time() ? pack_time(tm.get_mysql_time()) : 0;
- }
- longlong val_datetime_packed_result();
- longlong val_time_packed_result()
+ virtual longlong val_time_packed(THD *thd)
{
- MYSQL_TIME ltime;
- ulonglong fuzzydate= Time::comparison_flags_for_get_date();
- return get_date_result(&ltime, fuzzydate) ? 0 : pack_time(&ltime);
+ return Time(thd, this, Time::Options_cmp(thd)).to_packed();
}
+ longlong val_datetime_packed_result(THD *thd);
+ longlong val_time_packed_result(THD *thd);
+
+ virtual bool get_date_result(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
+ { return get_date(thd, ltime,fuzzydate); }
- // Get a temporal value in packed DATE/DATETIME or TIME format
- longlong val_temporal_packed(enum_field_types f_type)
- {
- return f_type == MYSQL_TYPE_TIME ? val_time_packed() :
- val_datetime_packed();
- }
- bool get_seconds(ulonglong *sec, ulong *sec_part);
- virtual bool get_date_result(MYSQL_TIME *ltime, ulonglong fuzzydate)
- { return get_date(ltime,fuzzydate); }
/*
The method allows to determine nullness of a complex expression
without fully evaluating it, instead of calling val/result*() then
@@ -1565,35 +1755,7 @@ public:
*/
virtual void update_null_value ()
{
- switch (cmp_type()) {
- case INT_RESULT:
- (void) val_int();
- break;
- case REAL_RESULT:
- (void) val_real();
- break;
- case DECIMAL_RESULT:
- {
- my_decimal tmp;
- (void) val_decimal(&tmp);
- }
- break;
- case TIME_RESULT:
- {
- MYSQL_TIME ltime;
- (void) get_temporal_with_sql_mode(&ltime);
- }
- break;
- case STRING_RESULT:
- {
- StringBuffer<MAX_FIELD_WIDTH> tmp;
- (void) val_str(&tmp);
- }
- break;
- case ROW_RESULT:
- DBUG_ASSERT(0);
- null_value= true;
- }
+ return type_handler()->Item_update_null_value(this);
}
/*
@@ -1611,10 +1773,9 @@ public:
set field of temporary table for Item which can be switched on temporary
table during query processing (grouping and so on)
*/
- virtual void set_result_field(Field *field) {}
virtual bool is_result_field() { return 0; }
- virtual bool is_bool_type() { return false; }
virtual bool is_json_type() { return false; }
+ virtual bool is_bool_literal() const { return false; }
/* This is to handle printing of default values */
virtual bool need_parentheses_in_default() { return false; }
virtual void save_in_result_field(bool no_conversions) {}
@@ -1679,8 +1840,10 @@ public:
/*========= Item processors, to be used with Item::walk() ========*/
virtual bool remove_dependence_processor(void *arg) { return 0; }
virtual bool cleanup_processor(void *arg);
- virtual bool cleanup_excluding_fields_processor(void *arg) { return cleanup_processor(arg); }
- virtual bool cleanup_excluding_const_fields_processor(void *arg) { return cleanup_processor(arg); }
+ virtual bool cleanup_excluding_fields_processor (void *arg)
+ { return cleanup_processor(arg); }
+ virtual bool cleanup_excluding_const_fields_processor (void *arg)
+ { return cleanup_processor(arg); }
virtual bool collect_item_field_processor(void *arg) { return 0; }
virtual bool collect_outer_ref_processor(void *arg) {return 0; }
virtual bool check_inner_refs_processor(void *arg) { return 0; }
@@ -1720,12 +1883,22 @@ public:
Not to be used for AND/OR formulas.
*/
virtual bool excl_dep_on_table(table_map tab_map) { return false; }
- /*
+ /*
TRUE if the expression depends only on grouping fields of sel
- or can be converted to such an exression using equalities.
+ or can be converted to such an expression using equalities.
+ It also checks if the expression doesn't contain stored procedures,
+ subqueries or randomly generated elements.
+ Not to be used for AND/OR formulas.
+ */
+ virtual bool excl_dep_on_grouping_fields(st_select_lex *sel)
+ { return false; }
+ /*
+ TRUE if the expression depends only on fields from the left part of
+ IN subquery or can be converted to such an expression using equalities.
Not to be used for AND/OR formulas.
*/
- virtual bool excl_dep_on_grouping_fields(st_select_lex *sel) { return false; }
+ virtual bool excl_dep_on_in_subq_left_part(Item_in_subselect *subq_pred)
+ { return false; }
virtual bool switch_to_nullable_fields_processor(void *arg) { return 0; }
virtual bool find_function_processor (void *arg) { return 0; }
@@ -1783,6 +1956,12 @@ public:
virtual bool check_partition_func_processor(void *arg) { return 1;}
virtual bool post_fix_fields_part_expr_processor(void *arg) { return 0; }
virtual bool rename_fields_processor(void *arg) { return 0; }
+ /*
+ TRUE if the function is knowingly TRUE or FALSE.
+ Not to be used for AND/OR formulas.
+ */
+ virtual bool is_simplified_cond_processor(void *arg) { return false; }
+
/** Processor used to check acceptability of an item in the defining
expression for a virtual column
@@ -1816,6 +1995,12 @@ public:
virtual bool check_valid_arguments_processor(void *arg) { return 0; }
virtual bool update_vcol_processor(void *arg) { return 0; }
virtual bool set_fields_as_dependent_processor(void *arg) { return 0; }
+ /*
+ Find if some of the key parts of table keys (the reference on table is
+ passed as an argument) participate in the expression.
+ If there is some, sets a bit for this key in the proper key map.
+ */
+ virtual bool check_index_dependence(void *arg) { return 0; }
/*============== End of Item processor list ======================*/
virtual Item *get_copy(THD *thd)=0;
@@ -1885,11 +2070,17 @@ public:
return Type_handler::type_handler_long_or_longlong(max_char_length());
}
- virtual Field *create_tmp_field(bool group, TABLE *table)
- {
- return tmp_table_field_from_field_type(table);
- }
-
+ /**
+ Create field for temporary table.
+ @param table Temporary table
+ @param [OUT] src Who created the fields
+ @param param Create parameters
+ @retval NULL (on error)
+ @retval a pointer to a newly create Field (on success)
+ */
+ virtual Field *create_tmp_field_ex(TABLE *table,
+ Tmp_field_src *src,
+ const Tmp_field_param *param)= 0;
virtual Item_field *field_for_view_update() { return 0; }
virtual Item *neg_transformer(THD *thd) { return NULL; }
@@ -1901,11 +2092,19 @@ public:
{ return this; }
virtual Item *derived_field_transformer_for_where(THD *thd, uchar *arg)
{ return this; }
- virtual Item *derived_grouping_field_transformer_for_where(THD *thd,
- uchar *arg)
+ virtual Item *grouping_field_transformer_for_where(THD *thd, uchar *arg)
+ { return this; }
+ /* Now is not used. */
+ virtual Item *in_subq_field_transformer_for_where(THD *thd, uchar *arg)
+ { return this; }
+ virtual Item *in_subq_field_transformer_for_having(THD *thd, uchar *arg)
{ return this; }
virtual Item *in_predicate_to_in_subs_transformer(THD *thd, uchar *arg)
{ return this; }
+ virtual Item *field_transformer_for_having_pushdown(THD *thd, uchar *arg)
+ { return this; }
+ virtual Item *multiple_equality_transformer(THD *thd, uchar *arg)
+ { return this; }
virtual bool expr_cache_is_needed(THD *) { return FALSE; }
virtual Item *safe_charset_converter(THD *thd, CHARSET_INFO *tocs);
bool needs_charset_converter(uint32 length, CHARSET_INFO *tocs) const
@@ -1956,6 +2155,7 @@ public:
delete this;
}
+ virtual const Item_const *get_item_const() const { return NULL; }
virtual Item_splocal *get_item_splocal() { return 0; }
virtual Rewritable_query_parameter *get_rewritable_query_parameter()
{ return 0; }
@@ -2029,13 +2229,16 @@ public:
/*
Return TRUE if the item points to a column of an outer-joined table.
*/
- virtual bool is_outer_field() const { DBUG_ASSERT(fixed); return FALSE; }
+ virtual bool is_outer_field() const { DBUG_ASSERT(is_fixed()); return FALSE; }
/**
Checks if this item or any of its decendents contains a subquery. This is a
replacement of the former Item::has_subquery() and Item::with_subselect.
*/
- virtual bool with_subquery() const { DBUG_ASSERT(fixed); return false; }
+ virtual bool with_subquery() const { DBUG_ASSERT(is_fixed()); return false; }
+
+ virtual bool with_sum_func() const { return false; }
+ virtual With_sum_func_cache* get_with_sum_func_cache() { return NULL; }
Item* set_expr_cache(THD *thd);
@@ -2082,6 +2285,11 @@ public:
*/
virtual void under_not(Item_func_not * upper
__attribute__((unused))) {};
+ /*
+ If Item_field is wrapped in Item_direct_wrep remove this Item_direct_ref
+ wrapper.
+ */
+ virtual Item *remove_item_direct_ref() { return this; }
void register_in(THD *thd);
@@ -2099,6 +2307,29 @@ public:
{
marker &= ~EXTRACTION_MASK;
}
+ void check_pushable_cond(Pushdown_checker excl_dep_func, uchar *arg);
+ bool pushable_cond_checker_for_derived(uchar *arg)
+ {
+ return excl_dep_on_table(*((table_map *)arg));
+ }
+ bool pushable_cond_checker_for_subquery(uchar *arg)
+ {
+ return excl_dep_on_in_subq_left_part((Item_in_subselect *)arg);
+ }
+ Item *build_pushable_cond(THD *thd,
+ Pushdown_checker checker,
+ uchar *arg);
+ /*
+ Checks if this item depends only on the arg table
+ */
+ bool pushable_equality_checker_for_derived(uchar *arg)
+ {
+ return (used_tables() == *((table_map *)arg));
+ }
+ /*
+ Checks if this item consists in the left part of arg IN subquery predicate
+ */
+ bool pushable_equality_checker_for_subquery(uchar *arg);
};
MEM_ROOT *get_thd_memroot(THD *thd);
@@ -2113,6 +2344,66 @@ inline Item* get_item_copy (THD *thd, T* item)
}
+#ifndef DBUG_OFF
+/**
+ A helper class to print the data type and the value for an Item
+ in debug builds.
+*/
+class DbugStringItemTypeValue: public StringBuffer<128>
+{
+public:
+ DbugStringItemTypeValue(THD *thd, const Item *item)
+ {
+ append('(');
+ append(item->type_handler()->name().ptr());
+ append(')');
+ const_cast<Item*>(item)->print(this, QT_EXPLAIN);
+ }
+};
+#endif
+
+class With_sum_func_cache
+{
+protected:
+ bool m_with_sum_func; // True if the owner item contains a sum func
+public:
+ With_sum_func_cache()
+ :m_with_sum_func(false)
+ { }
+ With_sum_func_cache(const Item *a)
+ :m_with_sum_func(a->with_sum_func())
+ { }
+ With_sum_func_cache(const Item *a, const Item *b)
+ :m_with_sum_func(a->with_sum_func() || b->with_sum_func())
+ { }
+ With_sum_func_cache(const Item *a, const Item *b, const Item *c)
+ :m_with_sum_func(a->with_sum_func() || b->with_sum_func() ||
+ c->with_sum_func())
+ { }
+ With_sum_func_cache(const Item *a, const Item *b, const Item *c,
+ const Item *d)
+ :m_with_sum_func(a->with_sum_func() || b->with_sum_func() ||
+ c->with_sum_func() || d->with_sum_func())
+ { }
+ With_sum_func_cache(const Item *a, const Item *b, const Item *c,
+ const Item *d, const Item *e)
+ :m_with_sum_func(a->with_sum_func() || b->with_sum_func() ||
+ c->with_sum_func() || d->with_sum_func() ||
+ e->with_sum_func())
+ { }
+ void set_with_sum_func() { m_with_sum_func= true; }
+ void reset_with_sum_func() { m_with_sum_func= false; }
+ void copy_with_sum_func(const Item *item)
+ {
+ m_with_sum_func= item->with_sum_func();
+ }
+ void join_with_sum_func(const Item *item)
+ {
+ m_with_sum_func|= item->with_sum_func();
+ }
+};
+
+
/*
This class is a replacement for the former member Item::with_subselect.
Determines if the descendant Item is a subselect or some of
@@ -2216,22 +2507,23 @@ protected:
}
return true;
}
- bool excl_dep_on_grouping_fields(st_select_lex *sel)
+ bool excl_dep_on_grouping_fields(st_select_lex *sel);
+ bool eq(const Item_args *other, bool binary_cmp) const
{
- for (uint i= 0; i < arg_count; i++)
+ for (uint i= 0; i < arg_count ; i++)
{
- if (args[i]->const_item())
- continue;
- if (!args[i]->excl_dep_on_grouping_fields(sel))
+ if (!args[i]->eq(other->args[i], binary_cmp))
return false;
}
return true;
}
- bool eq(const Item_args *other, bool binary_cmp) const
+ bool excl_dep_on_in_subq_left_part(Item_in_subselect *subq_pred)
{
- for (uint i= 0; i < arg_count ; i++)
+ for (uint i= 0; i < arg_count; i++)
{
- if (!args[i]->eq(other->args[i], binary_cmp))
+ if (args[i]->const_item())
+ continue;
+ if (!args[i]->excl_dep_on_in_subq_left_part(subq_pred))
return false;
}
return true;
@@ -2287,6 +2579,30 @@ public:
{
args[arg_count++]= item;
}
+ /**
+ Extract row elements from the given position.
+ For example, for this input: (1,2),(3,4),(5,6)
+ pos=0 will extract (1,3,5)
+ pos=1 will extract (2,4,6)
+ @param thd - current thread, to allocate memory on its mem_root
+ @param rows - an array of compatible ROW-type items
+ @param pos - the element position to extract
+ */
+ bool alloc_and_extract_row_elements(THD *thd, const Item_args *rows, uint pos)
+ {
+ DBUG_ASSERT(rows->argument_count() > 0);
+ DBUG_ASSERT(rows->arguments()[0]->cols() > pos);
+ if (alloc_arguments(thd, rows->argument_count()))
+ return true;
+ for (uint i= 0; i < rows->argument_count(); i++)
+ {
+ DBUG_ASSERT(rows->arguments()[0]->cols() == rows->arguments()[i]->cols());
+ Item *arg= rows->arguments()[i]->element_index(pos);
+ add_argument(arg);
+ }
+ DBUG_ASSERT(argument_count() == rows->argument_count());
+ return false;
+ }
inline Item **arguments() const { return args; }
inline uint argument_count() const { return arg_count; }
inline void remove_arguments() { arg_count=0; }
@@ -2321,27 +2637,39 @@ public:
class Item_string;
-/**
- A common class for Item_basic_constant and Item_param
-*/
-class Item_basic_value :public Item
+class Item_fixed_hybrid: public Item
{
- bool is_basic_value(const Item *item, Type type_arg) const
- {
- return item->basic_const_item() && item->type() == type_arg;
- }
- bool is_basic_value(Type type_arg) const
+public:
+ bool fixed; // If item was fixed with fix_fields
+public:
+ Item_fixed_hybrid(THD *thd): Item(thd), fixed(false)
+ { }
+ Item_fixed_hybrid(THD *thd, Item_fixed_hybrid *item)
+ :Item(thd, item), fixed(item->fixed)
+ { }
+ bool fix_fields(THD *thd, Item **ref)
{
- return basic_const_item() && type() == type_arg;
+ DBUG_ASSERT(!fixed);
+ fixed= true;
+ return false;
}
- bool str_eq(const String *value,
- const String *other, CHARSET_INFO *cs, bool binary_cmp) const
+ void cleanup()
{
- return binary_cmp ?
- value->bin_eq(other) :
- collation.collation == cs && value->eq(other, collation.collation);
+ Item::cleanup();
+ fixed= false;
}
+ void quick_fix_field() { fixed= true; }
+ void unfix_fields() { fixed= false; }
+ bool is_fixed() const { return fixed; }
+};
+
+/**
+ A common class for Item_basic_constant and Item_param
+*/
+class Item_basic_value :public Item,
+ public Item_const
+{
protected:
// Value metadata, e.g. to make string processing easier
class Metadata: private MY_STRING_METADATA
@@ -2378,66 +2706,40 @@ protected:
fix_charset_and_length(str.charset(), dv, Metadata(&str));
}
Item_basic_value(THD *thd): Item(thd) {}
- /*
- In the xxx_eq() methods below we need to cast off "const" to
- call val_xxx(). This is OK for Item_basic_constant and Item_param.
- */
- bool null_eq(const Item *item) const
- {
- DBUG_ASSERT(is_basic_value(NULL_ITEM));
- return item->type() == NULL_ITEM;
- }
- bool str_eq(const String *value, const Item *item, bool binary_cmp) const
- {
- DBUG_ASSERT(is_basic_value(STRING_ITEM));
- return is_basic_value(item, STRING_ITEM) &&
- str_eq(value, ((Item_basic_value*)item)->val_str(NULL),
- item->collation.collation, binary_cmp);
- }
- bool real_eq(double value, const Item *item) const
- {
- DBUG_ASSERT(is_basic_value(REAL_ITEM));
- return is_basic_value(item, REAL_ITEM) &&
- value == ((Item_basic_value*)item)->val_real();
- }
- bool int_eq(longlong value, const Item *item) const
+public:
+ Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src,
+ const Tmp_field_param *param)
{
- DBUG_ASSERT(is_basic_value(INT_ITEM));
- return is_basic_value(item, INT_ITEM) &&
- value == ((Item_basic_value*)item)->val_int() &&
- (value >= 0 || item->unsigned_flag == unsigned_flag);
+
+ /*
+ create_tmp_field_ex() for this type of Items is called for:
+ - CREATE TABLE ... SELECT
+ - In ORDER BY: SELECT max(a) FROM t1 GROUP BY a ORDER BY 'const';
+ - In CURSORS:
+ DECLARE c CURSOR FOR SELECT 'test';
+ OPEN c;
+ */
+ return tmp_table_field_from_field_type_maybe_null(table, src, param,
+ type() == Item::NULL_ITEM);
}
+ bool eq(const Item *item, bool binary_cmp) const;
+ const Type_all_attributes *get_type_all_attributes_from_const() const
+ { return this; }
};
class Item_basic_constant :public Item_basic_value
{
- table_map used_table_map;
public:
- Item_basic_constant(THD *thd): Item_basic_value(thd), used_table_map(0) {};
- void set_used_tables(table_map map) { used_table_map= map; }
- table_map used_tables() const { return used_table_map; }
- bool check_vcol_func_processor(void *arg) { return FALSE;}
+ Item_basic_constant(THD *thd): Item_basic_value(thd) {};
+ bool check_vcol_func_processor(void *arg) { return false; }
+ const Item_const *get_item_const() const { return this; }
virtual Item_basic_constant *make_string_literal_concat(THD *thd,
const LEX_CSTRING *)
{
DBUG_ASSERT(0);
return this;
}
- /* to prevent drop fixed flag (no need parent cleanup call) */
- void cleanup()
- {
- /*
- Restore the original field name as it might not have been allocated
- in the statement memory. If the name is auto generated, it must be
- done again between subsequent executions of a prepared statement.
- */
- if (orig_name)
- {
- name.str= orig_name;
- name.length= strlen(orig_name);
- }
- }
};
@@ -2448,7 +2750,7 @@ public:
- CASE expression (Item_case_expr);
*****************************************************************************/
-class Item_sp_variable :public Item
+class Item_sp_variable :public Item_fixed_hybrid
{
protected:
/*
@@ -2480,7 +2782,8 @@ public:
longlong val_int();
String *val_str(String *sp);
my_decimal *val_decimal(my_decimal *decimal_value);
- bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
+ bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate);
+ bool val_native(THD *thd, Native *to);
bool is_null();
public:
@@ -2488,6 +2791,11 @@ public:
inline bool const_item() const;
+ Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src,
+ const Tmp_field_param *param)
+ {
+ return create_tmp_field_ex_simple(table, src, param);
+ }
inline int save_in_field(Field *field, bool no_conversions);
inline bool send(Protocol *protocol, st_value *buffer);
bool check_vcol_func_processor(void *arg)
@@ -2591,6 +2899,20 @@ public:
*/
Field *create_field_for_create_select(TABLE *table)
{ return create_table_field_from_handler(table); }
+
+ bool is_valid_limit_clause_variable_with_error() const
+ {
+ /*
+ In case if the variable has an anchored data type, e.g.:
+ DECLARE a TYPE OF t1.a;
+ type_handler() is set to &type_handler_null and this
+ function detects such variable as not valid in LIMIT.
+ */
+ if (type_handler()->is_limit_clause_valid_type())
+ return true;
+ my_error(ER_WRONG_SPVAR_TYPE_IN_LIMIT, MYF(0));
+ return false;
+ }
};
@@ -2737,11 +3059,10 @@ inline enum Item::Type Item_case_expr::type() const
extract a common base with class Item_ref, too.
*/
-class Item_name_const : public Item
+class Item_name_const : public Item_fixed_hybrid
{
Item *value_item;
Item *name_item;
- bool valid_args;
public:
Item_name_const(THD *thd, Item *name_arg, Item *val);
@@ -2752,7 +3073,7 @@ public:
longlong val_int();
String *val_str(String *sp);
my_decimal *val_decimal(my_decimal *);
- bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
+ bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate);
bool is_null();
virtual void print(String *str, enum_query_type query_type);
@@ -2766,6 +3087,17 @@ public:
return TRUE;
}
+ Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src,
+ const Tmp_field_param *param)
+ {
+ /*
+ We can get to here when using a CURSOR for a query with NAME_CONST():
+ DECLARE c CURSOR FOR SELECT NAME_CONST('x','y') FROM t1;
+ OPEN c;
+ */
+ return tmp_table_field_from_field_type_maybe_null(table, src, param,
+ type() == Item::NULL_ITEM);
+ }
int save_in_field(Field *field, bool no_conversions)
{
return value_item->save_in_field(field, no_conversions);
@@ -2783,15 +3115,27 @@ public:
{ return get_item_copy<Item_name_const>(thd, this); }
};
-class Item_num: public Item_basic_constant
+
+class Item_literal: public Item_basic_constant
+{
+public:
+ Item_literal(THD *thd): Item_basic_constant(thd)
+ { }
+ enum Type type() const { return CONST_ITEM; }
+ bool check_partition_func_processor(void *int_arg) { return false;}
+ bool const_item() const { return true; }
+ bool basic_const_item() const { return true; }
+};
+
+
+class Item_num: public Item_literal
{
public:
- Item_num(THD *thd): Item_basic_constant(thd) { collation.set_numeric(); }
+ Item_num(THD *thd): Item_literal(thd) { collation.set_numeric(); }
Item *safe_charset_converter(THD *thd, CHARSET_INFO *tocs);
- bool check_partition_func_processor(void *int_arg) { return FALSE;}
- bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
{
- return type_handler()->Item_get_date(this, ltime, fuzzydate);
+ return type_handler()->Item_get_date_with_warn(thd, this, ltime, fuzzydate);
}
};
@@ -2800,24 +3144,26 @@ public:
class st_select_lex;
-class Item_result_field :public Item /* Item with result field */
+class Item_result_field :public Item_fixed_hybrid /* Item with result field */
{
public:
Field *result_field; /* Save result here */
- Item_result_field(THD *thd): Item(thd), result_field(0) {}
+ Item_result_field(THD *thd): Item_fixed_hybrid(thd), result_field(0) {}
// Constructor used for Item_sum/Item_cond_and/or (see Item comment)
Item_result_field(THD *thd, Item_result_field *item):
- Item(thd, item), result_field(item->result_field)
+ Item_fixed_hybrid(thd, item), result_field(item->result_field)
{}
~Item_result_field() {} /* Required with gcc 2.95 */
Field *get_tmp_table_field() { return result_field; }
+ Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src,
+ const Tmp_field_param *param);
+ void get_tmp_field_src(Tmp_field_src *src, const Tmp_field_param *param);
/*
This implementation of used_tables() used by Item_avg_field and
Item_variance_field which work when only temporary table left, so theu
return table map of the temporary table.
*/
table_map used_tables() const { return 1; }
- void set_result_field(Field *field) { result_field= field; }
bool is_result_field() { return true; }
void save_in_result_field(bool no_conversions)
{
@@ -2896,39 +3242,6 @@ public:
};
-class Item_ident_for_show :public Item
-{
-public:
- Field *field;
- const char *db_name;
- const char *table_name;
-
- Item_ident_for_show(THD *thd, Field *par_field, const char *db_arg,
- const char *table_name_arg):
- Item(thd), field(par_field), db_name(db_arg), table_name(table_name_arg)
- {
- Type_std_attributes::set(par_field->type_std_attributes());
- }
- enum Type type() const { return FIELD_ITEM; }
- double val_real() { return field->val_real(); }
- longlong val_int() { return field->val_int(); }
- String *val_str(String *str) { return field->val_str(str); }
- my_decimal *val_decimal(my_decimal *dec) { return field->val_decimal(dec); }
- bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
- {
- return field->get_date(ltime, fuzzydate);
- }
- void make_send_field(THD *thd, Send_field *tmp_field);
- const Type_handler *type_handler() const
- {
- const Type_handler *handler= field->type_handler();
- return handler->type_handler_for_item_field();
- }
- Item* get_copy(THD *thd)
- { return get_item_copy<Item_ident_for_show>(thd, this); }
-};
-
-
class Item_field :public Item_ident,
public Load_data_outvar
{
@@ -2972,6 +3285,8 @@ public:
void save_result(Field *to);
double val_result();
longlong val_int_result();
+ bool val_native(THD *thd, Native *to);
+ bool val_native_result(THD *thd, Native *to);
String *str_result(String* tmp);
my_decimal *val_decimal_result(my_decimal *);
bool val_bool_result();
@@ -3015,24 +3330,25 @@ public:
const Type_handler *handler= field->type_handler();
return handler->type_handler_for_item_field();
}
- const Type_handler *cast_to_int_type_handler() const
- {
- return field->type_handler()->cast_to_int_type_handler();
- }
const Type_handler *real_type_handler() const
{
if (field->is_created_from_null_item)
return &type_handler_null;
return field->type_handler();
}
+ Field *create_tmp_field_from_item_field(TABLE *new_table,
+ Item_ref *orig_item,
+ const Tmp_field_param *param);
+ Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src,
+ const Tmp_field_param *param);
TYPELIB *get_typelib() const { return field->get_typelib(); }
enum_monotonicity_info get_monotonicity_info() const
{
return MONOTONIC_STRICT_INCREASING;
}
longlong val_int_endpoint(bool left_endp, bool *incl_endp);
- bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
- bool get_date_result(MYSQL_TIME *ltime,ulonglong fuzzydate);
+ bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate);
+ bool get_date_result(THD *thd, MYSQL_TIME *ltime,date_mode_t fuzzydate);
bool is_null() { return field->is_null(); }
void update_null_value();
void update_table_bitmaps()
@@ -3042,13 +3358,7 @@ public:
TABLE *tab= field->table;
tab->covering_keys.intersect(field->part_of_key);
if (tab->read_set)
- bitmap_fast_test_and_set(tab->read_set, field->field_index);
- /*
- Do not mark a self-referecing virtual column.
- Such virtual columns are reported as invalid.
- */
- if (field->vcol_info && tab->vcol_set)
- tab->mark_virtual_col(field);
+ tab->mark_column_with_deps(field);
}
}
void update_used_tables()
@@ -3125,10 +3435,13 @@ public:
virtual Item *update_value_transformer(THD *thd, uchar *select_arg);
Item *derived_field_transformer_for_having(THD *thd, uchar *arg);
Item *derived_field_transformer_for_where(THD *thd, uchar *arg);
- Item *derived_grouping_field_transformer_for_where(THD *thd, uchar *arg);
+ Item *grouping_field_transformer_for_where(THD *thd, uchar *arg);
+ Item *in_subq_field_transformer_for_where(THD *thd, uchar *arg);
+ Item *in_subq_field_transformer_for_having(THD *thd, uchar *arg);
virtual void print(String *str, enum_query_type query_type);
bool excl_dep_on_table(table_map tab_map);
bool excl_dep_on_grouping_fields(st_select_lex *sel);
+ bool excl_dep_on_in_subq_left_part(Item_in_subselect *subq_pred);
bool cleanup_excluding_fields_processor(void *arg)
{ return field ? 0 : cleanup_processor(arg); }
bool cleanup_excluding_const_fields_processor(void *arg)
@@ -3146,6 +3459,7 @@ public:
DBUG_ASSERT(field_type() == MYSQL_TYPE_GEOMETRY);
return field->get_geometry_type();
}
+ bool check_index_dependence(void *arg);
friend class Item_default_value;
friend class Item_insert_value;
friend class st_select_lex_unit;
@@ -3233,22 +3547,21 @@ public:
max_length= 0;
name.str= name_par ? name_par : "NULL";
name.length= strlen(name.str);
- fixed= 1;
collation.set(cs, DERIVATION_IGNORABLE, MY_REPERTOIRE_ASCII);
}
enum Type type() const { return NULL_ITEM; }
- bool eq(const Item *item, bool binary_cmp) const { return null_eq(item); }
double val_real();
longlong val_int();
String *val_str(String *str);
my_decimal *val_decimal(my_decimal *);
- bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
+ bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate);
int save_in_field(Field *field, bool no_conversions);
int save_safe_in_field(Field *field);
bool send(Protocol *protocol, st_value *buffer);
const Type_handler *type_handler() const { return &type_handler_null; }
bool basic_const_item() const { return 1; }
Item *clone_item(THD *thd);
+ bool const_is_null() const { return true; }
bool is_null() { return 1; }
virtual inline void print(String *str, enum_query_type query_type)
@@ -3274,6 +3587,12 @@ public:
{
return result_field->type();
}
+ Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src,
+ const Tmp_field_param *param)
+ {
+ DBUG_ASSERT(0);
+ return NULL;
+ }
void save_in_result_field(bool no_conversions)
{
save_in_field(result_field, no_conversions);
@@ -3341,8 +3660,8 @@ class Item_param :public Item_basic_value,
All Item_param::set_xxx() make sure to do so.
In the state with an assigned value:
- Item_param::basic_const_item() returns true
- - Item::type() returns NULL_ITEM, INT_ITEM, REAL_ITEM, DECIMAL_ITEM,
- DATE_ITEM, STRING_ITEM, depending on the value assigned.
+ - Item::type() returns NULL_ITEM or CONST_ITEM,
+ depending on the value assigned.
So in this state Item_param behaves in many cases like a literal.
When Item_param::cleanup() is called:
@@ -3365,14 +3684,6 @@ class Item_param :public Item_basic_value,
DEFAULT_VALUE, IGNORE_VALUE
} state;
- enum Type item_type;
-
- void fix_type(Type type)
- {
- item_type= type;
- fixed= true;
- }
-
void fix_temporal(uint32 max_length_arg, uint decimals_arg);
struct CONVERSION_INFO
@@ -3471,7 +3782,6 @@ class Item_param :public Item_basic_value,
PValue value;
const String *value_query_val_str(THD *thd, String* str) const;
- bool value_eq(const Item *item, bool binary_cmp) const;
Item *value_clone_item(THD *thd);
bool can_return_value() const;
@@ -3495,10 +3805,58 @@ public:
enum Type type() const
{
- DBUG_ASSERT(fixed || state == NO_VALUE);
- return item_type;
+ // Don't pretend to be a constant unless value for this item is set.
+ switch (state) {
+ case NO_VALUE: return PARAM_ITEM;
+ case NULL_VALUE: return NULL_ITEM;
+ case SHORT_DATA_VALUE: return CONST_ITEM;
+ case LONG_DATA_VALUE: return CONST_ITEM;
+ case DEFAULT_VALUE: return PARAM_ITEM;
+ case IGNORE_VALUE: return PARAM_ITEM;
+ }
+ DBUG_ASSERT(0);
+ return PARAM_ITEM;
}
+ bool is_order_clause_position() const
+ {
+ return state == SHORT_DATA_VALUE &&
+ type_handler()->is_order_clause_position_type();
+ }
+
+ const Item_const *get_item_const() const
+ {
+ switch (state) {
+ case SHORT_DATA_VALUE:
+ case LONG_DATA_VALUE:
+ case NULL_VALUE:
+ return this;
+ case IGNORE_VALUE:
+ case DEFAULT_VALUE:
+ case NO_VALUE:
+ break;
+ }
+ return NULL;
+ }
+
+ bool const_is_null() const { return state == NULL_VALUE; }
+ bool can_return_const_value(Item_result type) const
+ {
+ return can_return_value() &&
+ value.type_handler()->cmp_type() == type &&
+ type_handler()->cmp_type() == type;
+ }
+ const longlong *const_ptr_longlong() const
+ { return can_return_const_value(INT_RESULT) ? &value.integer : NULL; }
+ const double *const_ptr_double() const
+ { return can_return_const_value(REAL_RESULT) ? &value.real : NULL; }
+ const my_decimal *const_ptr_my_decimal() const
+ { return can_return_const_value(DECIMAL_RESULT) ? &value.m_decimal : NULL; }
+ const MYSQL_TIME *const_ptr_mysql_time() const
+ { return can_return_const_value(TIME_RESULT) ? &value.time : NULL; }
+ const String *const_ptr_string() const
+ { return can_return_const_value(STRING_RESULT) ? &value.m_string : NULL; }
+
double val_real()
{
return can_return_value() ? value.val_real() : 0e0;
@@ -3515,7 +3873,12 @@ public:
{
return can_return_value() ? value.val_str(str, this) : NULL;
}
- bool get_date(MYSQL_TIME *tm, ulonglong fuzzydate);
+ bool get_date(THD *thd, MYSQL_TIME *tm, date_mode_t fuzzydate);
+ bool val_native(THD *thd, Native *to)
+ {
+ return Item_param::type_handler()->Item_param_val_native(thd, this, to);
+ }
+
int save_in_field(Field *field, bool no_conversions);
void set_default();
@@ -3592,8 +3955,14 @@ public:
so no one will use parameters value in fix_fields still
parameter is constant during execution.
*/
+ bool const_item() const
+ {
+ return state != NO_VALUE;
+ }
virtual table_map used_tables() const
- { return state != NO_VALUE ? (table_map)0 : PARAM_TABLE_BIT; }
+ {
+ return state != NO_VALUE ? (table_map)0 : PARAM_TABLE_BIT;
+ }
virtual void print(String *str, enum_query_type query_type);
bool is_null()
{ DBUG_ASSERT(state != NO_VALUE); return state == NULL_VALUE; }
@@ -3623,12 +3992,6 @@ public:
*/
Item *safe_charset_converter(THD *thd, CHARSET_INFO *tocs);
Item *clone_item(THD *thd);
- /*
- Implement by-value equality evaluation if parameter value
- is set and is a basic constant (integer, real or string).
- Otherwise return FALSE.
- */
- bool eq(const Item *item, bool binary_cmp) const;
void set_param_type_and_swap_value(Item_param *from);
Rewritable_query_parameter *get_rewritable_query_parameter()
@@ -3676,50 +4039,44 @@ public:
longlong value;
Item_int(THD *thd, int32 i,size_t length= MY_INT32_NUM_DECIMAL_DIGITS):
Item_num(thd), value((longlong) i)
- { max_length=(uint32)length; fixed= 1; }
+ { max_length=(uint32)length; }
Item_int(THD *thd, longlong i,size_t length= MY_INT64_NUM_DECIMAL_DIGITS):
Item_num(thd), value(i)
- { max_length=(uint32)length; fixed= 1; }
+ { max_length=(uint32)length; }
Item_int(THD *thd, ulonglong i, size_t length= MY_INT64_NUM_DECIMAL_DIGITS):
Item_num(thd), value((longlong)i)
- { max_length=(uint32)length; fixed= 1; unsigned_flag= 1; }
+ { max_length=(uint32)length; unsigned_flag= 1; }
Item_int(THD *thd, const char *str_arg,longlong i,size_t length):
Item_num(thd), value(i)
{
max_length=(uint32)length;
name.str= str_arg; name.length= safe_strlen(name.str);
- fixed= 1;
}
Item_int(THD *thd, const char *str_arg,longlong i,size_t length, bool flag):
Item_num(thd), value(i)
{
max_length=(uint32)length;
name.str= str_arg; name.length= safe_strlen(name.str);
- fixed= 1;
unsigned_flag= flag;
}
Item_int(THD *thd, const char *str_arg, size_t length=64);
- enum Type type() const { return INT_ITEM; }
const Type_handler *type_handler() const
{ return type_handler_long_or_longlong(); }
- Field *create_tmp_field(bool group, TABLE *table)
- { return tmp_table_field_from_field_type(table); }
Field *create_field_for_create_select(TABLE *table)
{ return tmp_table_field_from_field_type(table); }
- longlong val_int() { DBUG_ASSERT(fixed == 1); return value; }
- longlong val_int_min() const { DBUG_ASSERT(fixed == 1); return value; }
- double val_real() { DBUG_ASSERT(fixed == 1); return (double) value; }
+ const longlong *const_ptr_longlong() const { return &value; }
+ longlong val_int() { return value; }
+ longlong val_int_min() const { return value; }
+ double val_real() { return (double) value; }
my_decimal *val_decimal(my_decimal *);
String *val_str(String*);
int save_in_field(Field *field, bool no_conversions);
- bool basic_const_item() const { return 1; }
+ bool is_order_clause_position() const { return true; }
Item *clone_item(THD *thd);
virtual void print(String *str, enum_query_type query_type);
Item *neg(THD *thd);
uint decimal_precision() const
{ return (uint) (max_length - MY_TEST(value < 0)); }
- bool eq(const Item *item, bool binary_cmp) const
- { return int_eq(value, item); }
Item *get_copy(THD *thd)
{ return get_item_copy<Item_int>(thd, this); }
};
@@ -3735,8 +4092,20 @@ class Item_bool :public Item_int
public:
Item_bool(THD *thd, const char *str_arg, longlong i):
Item_int(thd, str_arg, i, 1) {}
- bool is_bool_type() { return true; }
+ Item_bool(THD *thd, bool i) :Item_int(thd, (longlong) i, 1) { }
+ bool is_bool_literal() const { return true; }
Item *neg_transformer(THD *thd);
+ const Type_handler *type_handler() const
+ { return &type_handler_bool; }
+ const Type_handler *fixed_type_handler() const
+ { return &type_handler_bool; }
+ void quick_fix_field()
+ {
+ /*
+ We can get here when Item_bool is created instead of a constant
+ predicate at various condition optimization stages in sql_select.
+ */
+ }
};
@@ -3746,8 +4115,7 @@ public:
Item_uint(THD *thd, const char *str_arg, size_t length);
Item_uint(THD *thd, ulonglong i): Item_int(thd, i, 10) {}
Item_uint(THD *thd, const char *str_arg, longlong i, uint length);
- double val_real()
- { DBUG_ASSERT(fixed == 1); return ulonglong2double((ulonglong)value); }
+ double val_real() { return ulonglong2double((ulonglong)value); }
String *val_str(String*);
Item *clone_item(THD *thd);
virtual void print(String *str, enum_query_type query_type);
@@ -3768,7 +4136,7 @@ public:
longlong val_int();
double val_real() { return (double)val_int(); }
void set(longlong packed, enum_mysql_timestamp_type ts_type);
- bool get_date(MYSQL_TIME *to, ulonglong fuzzydate)
+ bool get_date(THD *thd, MYSQL_TIME *to, date_mode_t fuzzydate)
{
*to= ltime;
return false;
@@ -3786,24 +4154,26 @@ public:
CHARSET_INFO *charset);
Item_decimal(THD *thd, const char *str, const my_decimal *val_arg,
uint decimal_par, uint length);
- Item_decimal(THD *thd, my_decimal *value_par);
+ Item_decimal(THD *thd, const my_decimal *value_par);
Item_decimal(THD *thd, longlong val, bool unsig);
Item_decimal(THD *thd, double val, int precision, int scale);
Item_decimal(THD *thd, const uchar *bin, int precision, int scale);
- enum Type type() const { return DECIMAL_ITEM; }
const Type_handler *type_handler() const { return &type_handler_newdecimal; }
- longlong val_int();
- double val_real();
- String *val_str(String*);
+ longlong val_int() { return decimal_value.to_longlong(unsigned_flag); }
+ double val_real() { return decimal_value.to_double(); }
+ String *val_str(String *to) { return decimal_value.to_string(to); }
my_decimal *val_decimal(my_decimal *val) { return &decimal_value; }
+ const my_decimal *const_ptr_my_decimal() const { return &decimal_value; }
int save_in_field(Field *field, bool no_conversions);
- bool basic_const_item() const { return 1; }
Item *clone_item(THD *thd);
- virtual void print(String *str, enum_query_type query_type);
+ virtual void print(String *str, enum_query_type query_type)
+ {
+ decimal_value.to_string(&str_value);
+ str->append(str_value);
+ }
Item *neg(THD *thd);
uint decimal_precision() const { return decimal_value.precision(); }
- bool eq(const Item *, bool binary_cmp) const;
void set_decimal_value(my_decimal *value_par);
Item *get_copy(THD *thd)
{ return get_item_copy<Item_decimal>(thd, this); }
@@ -3823,21 +4193,18 @@ public:
name.length= safe_strlen(str);
decimals=(uint8) decimal_par;
max_length= length;
- fixed= 1;
}
Item_float(THD *thd, double value_par, uint decimal_par):
Item_num(thd), presentation(0), value(value_par)
{
decimals= (uint8) decimal_par;
- fixed= 1;
}
int save_in_field(Field *field, bool no_conversions);
- enum Type type() const { return REAL_ITEM; }
const Type_handler *type_handler() const { return &type_handler_double; }
- double val_real() { DBUG_ASSERT(fixed == 1); return value; }
+ const double *const_ptr_double() const { return &value; }
+ double val_real() { return value; }
longlong val_int()
{
- DBUG_ASSERT(fixed == 1);
if (value <= (double) LONGLONG_MIN)
{
return LONGLONG_MIN;
@@ -3850,12 +4217,9 @@ public:
}
String *val_str(String*);
my_decimal *val_decimal(my_decimal *);
- bool basic_const_item() const { return 1; }
Item *clone_item(THD *thd);
Item *neg(THD *thd);
virtual void print(String *str, enum_query_type query_type);
- bool eq(const Item *item, bool binary_cmp) const
- { return real_eq(value, item); }
Item *get_copy(THD *thd)
{ return get_item_copy<Item_float>(thd, this); }
};
@@ -3882,14 +4246,12 @@ public:
};
-class Item_string :public Item_basic_constant
+class Item_string :public Item_literal
{
protected:
void fix_from_value(Derivation dv, const Metadata metadata)
{
fix_charset_and_length(str_value.charset(), dv, metadata);
- // it is constant => can be used without fix_fields (and frequently used)
- fixed= 1;
}
void fix_and_set_name_from_value(THD *thd, Derivation dv,
const Metadata metadata)
@@ -3900,41 +4262,41 @@ protected:
protected:
/* Just create an item and do not fill string representation */
Item_string(THD *thd, CHARSET_INFO *cs, Derivation dv= DERIVATION_COERCIBLE):
- Item_basic_constant(thd)
+ Item_literal(thd)
{
collation.set(cs, dv);
max_length= 0;
set_name(thd, NULL, 0, system_charset_info);
decimals= NOT_FIXED_DEC;
- fixed= 1;
}
public:
- Item_string(THD *thd, CHARSET_INFO *csi, const char *str_arg, uint length_arg):
- Item_basic_constant(thd)
+ Item_string(THD *thd, CHARSET_INFO *csi, const char *str_arg, uint length_arg)
+ :Item_literal(thd)
{
collation.set(csi, DERIVATION_COERCIBLE);
set_name(thd, NULL, 0, system_charset_info);
decimals= NOT_FIXED_DEC;
- fixed= 1;
str_value.copy(str_arg, length_arg, csi);
max_length= str_value.numchars() * csi->mbmaxlen;
}
// Constructors with the item name set from its value
Item_string(THD *thd, const char *str, uint length, CHARSET_INFO *cs,
- Derivation dv, uint repertoire): Item_basic_constant(thd)
+ Derivation dv, uint repertoire)
+ :Item_literal(thd)
{
str_value.set_or_copy_aligned(str, length, cs);
fix_and_set_name_from_value(thd, dv, Metadata(&str_value, repertoire));
}
Item_string(THD *thd, const char *str, size_t length,
- CHARSET_INFO *cs, Derivation dv= DERIVATION_COERCIBLE):
- Item_basic_constant(thd)
+ CHARSET_INFO *cs, Derivation dv= DERIVATION_COERCIBLE)
+ :Item_literal(thd)
{
str_value.set_or_copy_aligned(str, length, cs);
fix_and_set_name_from_value(thd, dv, Metadata(&str_value));
}
Item_string(THD *thd, const String *str, CHARSET_INFO *tocs, uint *conv_errors,
- Derivation dv, uint repertoire): Item_basic_constant(thd)
+ Derivation dv, uint repertoire)
+ :Item_literal(thd)
{
if (str_value.copy(str, tocs, conv_errors))
str_value.set("", 0, tocs); // EOM ?
@@ -3943,16 +4305,16 @@ public:
}
// Constructors with an externally provided item name
Item_string(THD *thd, const char *name_par, const char *str, size_t length,
- CHARSET_INFO *cs, Derivation dv= DERIVATION_COERCIBLE):
- Item_basic_constant(thd)
+ CHARSET_INFO *cs, Derivation dv= DERIVATION_COERCIBLE)
+ :Item_literal(thd)
{
str_value.set_or_copy_aligned(str, length, cs);
fix_from_value(dv, Metadata(&str_value));
set_name(thd, name_par,safe_strlen(name_par), system_charset_info);
}
Item_string(THD *thd, const char *name_par, const char *str, size_t length,
- CHARSET_INFO *cs, Derivation dv, uint repertoire):
- Item_basic_constant(thd)
+ CHARSET_INFO *cs, Derivation dv, uint repertoire)
+ :Item_literal(thd)
{
str_value.set_or_copy_aligned(str, length, cs);
fix_from_value(dv, Metadata(&str_value, repertoire));
@@ -3962,26 +4324,23 @@ public:
{
str_value.print(to);
}
- enum Type type() const { return STRING_ITEM; }
double val_real();
longlong val_int();
+ const String *const_ptr_string() const
+ {
+ return &str_value;
+ }
String *val_str(String*)
{
- DBUG_ASSERT(fixed == 1);
return (String*) &str_value;
}
my_decimal *val_decimal(my_decimal *);
- bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
{
- return get_date_from_string(ltime, fuzzydate);
+ return get_date_from_string(thd, ltime, fuzzydate);
}
int save_in_field(Field *field, bool no_conversions);
const Type_handler *type_handler() const { return &type_handler_varchar; }
- bool basic_const_item() const { return 1; }
- bool eq(const Item *item, bool binary_cmp) const
- {
- return str_eq(&str_value, item, binary_cmp);
- }
Item *clone_item(THD *thd);
Item *safe_charset_converter(THD *thd, CHARSET_INFO *tocs)
{
@@ -3993,7 +4352,6 @@ public:
max_length= str_value.numchars() * collation.collation->mbmaxlen;
}
virtual void print(String *str, enum_query_type query_type);
- bool check_partition_func_processor(void *int_arg) {return FALSE;}
/**
Return TRUE if character-set-introducer was explicitly specified in the
@@ -4022,34 +4380,6 @@ public:
String *check_well_formed_result(bool send_error)
{ return Item::check_well_formed_result(&str_value, send_error); }
- enum_field_types odbc_temporal_literal_type(const LEX_CSTRING *type_str) const
- {
- /*
- If string is a reasonably short pure ASCII string literal,
- try to parse known ODBC style date, time or timestamp literals,
- e.g:
- SELECT {d'2001-01-01'};
- SELECT {t'10:20:30'};
- SELECT {ts'2001-01-01 10:20:30'};
- */
- if (collation.repertoire == MY_REPERTOIRE_ASCII &&
- str_value.length() < MAX_DATE_STRING_REP_LENGTH * 4)
- {
- if (type_str->length == 1)
- {
- if (type_str->str[0] == 'd') /* {d'2001-01-01'} */
- return MYSQL_TYPE_DATE;
- else if (type_str->str[0] == 't') /* {t'10:20:30'} */
- return MYSQL_TYPE_TIME;
- }
- else if (type_str->length == 2) /* {ts'2001-01-01 10:20:30'} */
- {
- if (type_str->str[0] == 't' && type_str->str[1] == 's')
- return MYSQL_TYPE_DATETIME;
- }
- }
- return MYSQL_TYPE_STRING; // Not a temporal literal
- }
Item_basic_constant *make_string_literal_concat(THD *thd,
const LEX_CSTRING *);
Item *make_odbc_literal(THD *thd, const LEX_CSTRING *typestr);
@@ -4236,38 +4566,30 @@ public:
/**
Item_hex_constant -- a common class for hex literals: X'HHHH' and 0xHHHH
*/
-class Item_hex_constant: public Item_basic_constant
+class Item_hex_constant: public Item_literal
{
private:
void hex_string_init(THD *thd, const char *str, size_t str_length);
public:
- Item_hex_constant(THD *thd): Item_basic_constant(thd)
+ Item_hex_constant(THD *thd): Item_literal(thd)
{
hex_string_init(thd, "", 0);
}
Item_hex_constant(THD *thd, const char *str, size_t str_length):
- Item_basic_constant(thd)
+ Item_literal(thd)
{
hex_string_init(thd, str, str_length);
}
- enum Type type() const { return VARBIN_ITEM; }
const Type_handler *type_handler() const { return &type_handler_varchar; }
virtual Item *safe_charset_converter(THD *thd, CHARSET_INFO *tocs)
{
return const_charset_converter(thd, tocs, true);
}
- bool check_partition_func_processor(void *int_arg) {return FALSE;}
- bool basic_const_item() const { return 1; }
- bool eq(const Item *item, bool binary_cmp) const
- {
- return item->basic_const_item() && item->type() == type() &&
- item->cast_to_int_type_handler() == cast_to_int_type_handler() &&
- str_value.bin_eq(&((Item_hex_constant*)item)->str_value);
- }
- String *val_str(String*) { DBUG_ASSERT(fixed == 1); return &str_value; }
- bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ const String *const_ptr_string() const { return &str_value; }
+ String *val_str(String*) { return &str_value; }
+ bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
{
- return type_handler()->Item_get_date(this, ltime, fuzzydate);
+ return type_handler()->Item_get_date_with_warn(thd, this, ltime, fuzzydate);
}
};
@@ -4283,22 +4605,18 @@ public:
Item_hex_hybrid(THD *thd): Item_hex_constant(thd) {}
Item_hex_hybrid(THD *thd, const char *str, size_t str_length):
Item_hex_constant(thd, str, str_length) {}
+ const Type_handler *type_handler() const { return &type_handler_hex_hybrid; }
uint decimal_precision() const;
double val_real()
{
- DBUG_ASSERT(fixed == 1);
return (double) (ulonglong) Item_hex_hybrid::val_int();
}
longlong val_int()
{
- // following assert is redundant, because fixed=1 assigned in constructor
- DBUG_ASSERT(fixed == 1);
return longlong_from_hex_hybrid(str_value.ptr(), str_value.length());
}
my_decimal *val_decimal(my_decimal *decimal_value)
{
- // following assert is redundant, because fixed=1 assigned in constructor
- DBUG_ASSERT(fixed == 1);
longlong value= Item_hex_hybrid::val_int();
int2my_decimal(E_DEC_FATAL_ERROR, value, TRUE, decimal_value);
return decimal_value;
@@ -4308,14 +4626,6 @@ public:
field->set_notnull();
return field->store_hex_hybrid(str_value.ptr(), str_value.length());
}
- const Type_handler *cast_to_int_type_handler() const
- {
- return &type_handler_longlong;
- }
- const Type_handler *type_handler_for_system_time() const
- {
- return &type_handler_longlong;
- }
void print(String *str, enum_query_type query_type);
Item *get_copy(THD *thd)
{ return get_item_copy<Item_hex_hybrid>(thd, this); }
@@ -4339,12 +4649,10 @@ public:
Item_hex_constant(thd, str, str_length) {}
longlong val_int()
{
- DBUG_ASSERT(fixed == 1);
return longlong_from_string_with_check(&str_value);
}
double val_real()
{
- DBUG_ASSERT(fixed == 1);
return double_from_string_with_check(&str_value);
}
my_decimal *val_decimal(my_decimal *decimal_value)
@@ -4370,7 +4678,55 @@ public:
};
-class Item_temporal_literal :public Item_basic_constant
+class Item_timestamp_literal: public Item_literal
+{
+ Timestamp_or_zero_datetime m_value;
+public:
+ Item_timestamp_literal(THD *thd)
+ :Item_literal(thd)
+ { }
+ const Type_handler *type_handler() const { return &type_handler_timestamp2; }
+ int save_in_field(Field *field, bool no_conversions)
+ {
+ Timestamp_or_zero_datetime_native native(m_value, decimals);
+ return native.save_in_field(field, decimals);
+ }
+ longlong val_int()
+ {
+ return m_value.to_datetime(current_thd).to_longlong();
+ }
+ double val_real()
+ {
+ return m_value.to_datetime(current_thd).to_double();
+ }
+ String *val_str(String *to)
+ {
+ return m_value.to_datetime(current_thd).to_string(to, decimals);
+ }
+ my_decimal *val_decimal(my_decimal *to)
+ {
+ return m_value.to_datetime(current_thd).to_decimal(to);
+ }
+ bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
+ {
+ bool res= m_value.to_TIME(thd, ltime, fuzzydate);
+ DBUG_ASSERT(!res);
+ return res;
+ }
+ bool val_native(THD *thd, Native *to)
+ {
+ return m_value.to_native(to, decimals);
+ }
+ void set_value(const Timestamp_or_zero_datetime &value)
+ {
+ m_value= value;
+ }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_timestamp_literal>(thd, this); }
+};
+
+
+class Item_temporal_literal :public Item_literal
{
protected:
MYSQL_TIME cached_time;
@@ -4380,37 +4736,21 @@ public:
@param ltime DATE value.
*/
Item_temporal_literal(THD *thd, const MYSQL_TIME *ltime)
- :Item_basic_constant(thd)
+ :Item_literal(thd)
{
collation.set(&my_charset_numeric, DERIVATION_NUMERIC, MY_REPERTOIRE_ASCII);
decimals= 0;
cached_time= *ltime;
}
Item_temporal_literal(THD *thd, const MYSQL_TIME *ltime, uint dec_arg):
- Item_basic_constant(thd)
+ Item_literal(thd)
{
collation.set(&my_charset_numeric, DERIVATION_NUMERIC, MY_REPERTOIRE_ASCII);
decimals= dec_arg;
cached_time= *ltime;
}
- bool basic_const_item() const { return true; }
- bool const_item() const { return true; }
- enum Type type() const { return DATE_ITEM; }
- bool eq(const Item *item, bool binary_cmp) const;
- bool check_partition_func_processor(void *int_arg) {return FALSE;}
-
- bool is_null()
- { return is_null_from_temporal(); }
- bool get_date_with_sql_mode(MYSQL_TIME *to);
- String *val_str(String *str)
- { return val_string_from_date(str); }
- longlong val_int()
- { return val_int_from_date(); }
- double val_real()
- { return val_real_from_date(); }
- my_decimal *val_decimal(my_decimal *decimal_value)
- { return val_decimal_from_date(decimal_value); }
+ const MYSQL_TIME *const_ptr_mysql_time() const { return &cached_time; }
int save_in_field(Field *field, bool no_conversions)
{ return save_date_in_field(field, no_conversions); }
};
@@ -4426,7 +4766,6 @@ public:
:Item_temporal_literal(thd, ltime)
{
max_length= MAX_DATE_WIDTH;
- fixed= 1;
/*
If date has zero month or day, it can return NULL in case of
NO_ZERO_DATE or NO_ZERO_IN_DATE.
@@ -4439,7 +4778,11 @@ public:
const Type_handler *type_handler() const { return &type_handler_newdate; }
void print(String *str, enum_query_type query_type);
Item *clone_item(THD *thd);
- bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
+ longlong val_int() { return Date(this).to_longlong(); }
+ double val_real() { return Date(this).to_double(); }
+ String *val_str(String *to) { return Date(this).to_string(to); }
+ my_decimal *val_decimal(my_decimal *to) { return Date(this).to_decimal(to); }
+ bool get_date(THD *thd, MYSQL_TIME *res, date_mode_t fuzzydate);
Item *get_copy(THD *thd)
{ return get_item_copy<Item_date_literal>(thd, this); }
};
@@ -4455,12 +4798,15 @@ public:
Item_temporal_literal(thd, ltime, dec_arg)
{
max_length= MIN_TIME_WIDTH + (decimals ? decimals + 1 : 0);
- fixed= 1;
}
const Type_handler *type_handler() const { return &type_handler_time2; }
void print(String *str, enum_query_type query_type);
Item *clone_item(THD *thd);
- bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
+ longlong val_int() { return Time(this).to_longlong(); }
+ double val_real() { return Time(this).to_double(); }
+ String *val_str(String *to) { return Time(this).to_string(to, decimals); }
+ my_decimal *val_decimal(my_decimal *to) { return Time(this).to_decimal(to); }
+ bool get_date(THD *thd, MYSQL_TIME *res, date_mode_t fuzzydate);
Item *get_copy(THD *thd)
{ return get_item_copy<Item_time_literal>(thd, this); }
};
@@ -4476,14 +4822,23 @@ public:
Item_temporal_literal(thd, ltime, dec_arg)
{
max_length= MAX_DATETIME_WIDTH + (decimals ? decimals + 1 : 0);
- fixed= 1;
// See the comment on maybe_null in Item_date_literal
maybe_null= !ltime->month || !ltime->day;
}
const Type_handler *type_handler() const { return &type_handler_datetime2; }
void print(String *str, enum_query_type query_type);
Item *clone_item(THD *thd);
- bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
+ longlong val_int() { return Datetime(this).to_longlong(); }
+ double val_real() { return Datetime(this).to_double(); }
+ String *val_str(String *to)
+ {
+ return Datetime(this).to_string(to, decimals);
+ }
+ my_decimal *val_decimal(my_decimal *to)
+ {
+ return Datetime(this).to_decimal(to);
+ }
+ bool get_date(THD *thd, MYSQL_TIME *res, date_mode_t fuzzydate);
Item *get_copy(THD *thd)
{ return get_item_copy<Item_datetime_literal>(thd, this); }
};
@@ -4520,7 +4875,7 @@ class Item_date_literal_for_invalid_dates: public Item_date_literal
public:
Item_date_literal_for_invalid_dates(THD *thd, const MYSQL_TIME *ltime)
:Item_date_literal(thd, ltime) { }
- bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
+ bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
{
*ltime= cached_time;
return (null_value= false);
@@ -4538,7 +4893,7 @@ public:
Item_datetime_literal_for_invalid_dates(THD *thd,
const MYSQL_TIME *ltime, uint dec_arg)
:Item_datetime_literal(thd, ltime, dec_arg) { }
- bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
+ bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
{
*ltime= cached_time;
return (null_value= false);
@@ -4733,8 +5088,10 @@ struct st_sp_security_context;
class Item_sp
{
-public:
+protected:
+ // Can be NULL in some non-SELECT queries
Name_resolution_context *context;
+public:
sp_name *m_name;
sp_head *m_sp;
TABLE *dummy_table;
@@ -4756,9 +5113,15 @@ public:
bool execute_impl(THD *thd, Item **args, uint arg_count);
bool init_result_field(THD *thd, uint max_length, uint maybe_null,
bool *null_value, LEX_CSTRING *name);
+ void process_error(THD *thd)
+ {
+ if (context)
+ context->process_error(thd);
+ }
};
-class Item_ref :public Item_ident
+class Item_ref :public Item_ident,
+ protected With_sum_func_cache
{
protected:
void set_properties();
@@ -4794,7 +5157,8 @@ public:
/* Constructor need to process subselect with temporary tables (see Item) */
Item_ref(THD *thd, Item_ref *item)
- :Item_ident(thd, item), set_properties_only(0), ref(item->ref) {}
+ :Item_ident(thd, item), With_sum_func_cache(*item),
+ set_properties_only(0), ref(item->ref) {}
enum Type type() const { return REF_ITEM; }
enum Type real_type() const { return ref ? (*ref)->type() :
REF_ITEM; }
@@ -4810,11 +5174,13 @@ public:
my_decimal *val_decimal(my_decimal *);
bool val_bool();
String *val_str(String* tmp);
+ bool val_native(THD *thd, Native *to);
bool is_null();
- bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
+ bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate);
double val_result();
longlong val_int_result();
String *str_result(String* tmp);
+ bool val_native_result(THD *thd, Native *to);
my_decimal *val_decimal_result(my_decimal *);
bool val_bool_result();
bool is_null_result();
@@ -4832,6 +5198,9 @@ public:
Field *get_tmp_table_field()
{ return result_field ? result_field : (*ref)->get_tmp_table_field(); }
Item *get_tmp_table_item(THD *thd);
+ Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src,
+ const Tmp_field_param *param);
+ Item* propagate_equal_fields(THD *, const Context &, COND_EQUAL *);
table_map used_tables() const;
void update_used_tables();
COND *build_equal_items(THD *thd, COND_EQUAL *inherited,
@@ -4961,6 +5330,8 @@ public:
}
bool excl_dep_on_grouping_fields(st_select_lex *sel)
{ return (*ref)->excl_dep_on_grouping_fields(sel); }
+ bool excl_dep_on_in_subq_left_part(Item_in_subselect *subq_pred)
+ { return (*ref)->excl_dep_on_in_subq_left_part(subq_pred); }
bool cleanup_excluding_fields_processor(void *arg)
{
Item *item= real_item();
@@ -4977,6 +5348,15 @@ public:
return 0;
return cleanup_processor(arg);
}
+ bool with_sum_func() const { return m_with_sum_func; }
+ With_sum_func_cache* get_with_sum_func_cache() { return this; }
+ Item *field_transformer_for_having_pushdown(THD *thd, uchar *arg)
+ { return (*ref)->field_transformer_for_having_pushdown(thd, arg); }
+ Item *remove_item_direct_ref()
+ {
+ *ref= (*ref)->remove_item_direct_ref();
+ return this;
+ }
};
@@ -5013,13 +5393,16 @@ public:
double val_real();
longlong val_int();
String *val_str(String* tmp);
+ bool val_native(THD *thd, Native *to);
my_decimal *val_decimal(my_decimal *);
bool val_bool();
bool is_null();
- bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
+ bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate);
virtual Ref_Type ref_type() { return DIRECT_REF; }
Item *get_copy(THD *thd)
{ return get_item_copy<Item_direct_ref>(thd, this); }
+ Item *remove_item_direct_ref()
+ { return (*ref)->remove_item_direct_ref(); }
};
@@ -5064,7 +5447,8 @@ class Expression_cache_tracker;
*/
class Item_cache_wrapper :public Item_result_field,
- public With_subquery_cache
+ public With_subquery_cache,
+ protected With_sum_func_cache
{
private:
/* Pointer on the cached expression */
@@ -5092,6 +5476,8 @@ public:
enum Type type() const { return EXPR_CACHE_ITEM; }
enum Type real_type() const { return orig_item->type(); }
bool with_subquery() const { DBUG_ASSERT(fixed); return m_with_subquery; }
+ bool with_sum_func() const { return m_with_sum_func; }
+ With_sum_func_cache* get_with_sum_func_cache() { return this; }
bool set_cache(THD *thd);
Expression_cache_tracker* init_tracker(MEM_ROOT *mem_root);
@@ -5106,10 +5492,11 @@ public:
double val_real();
longlong val_int();
String *val_str(String* tmp);
+ bool val_native(THD *thd, Native *to);
my_decimal *val_decimal(my_decimal *);
bool val_bool();
bool is_null();
- bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
+ bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate);
bool send(Protocol *protocol, st_value *buffer);
void save_org_in_field(Field *field,
fast_field_copier data __attribute__ ((__unused__)))
@@ -5267,10 +5654,12 @@ public:
}
bool excl_dep_on_table(table_map tab_map);
bool excl_dep_on_grouping_fields(st_select_lex *sel);
+ bool excl_dep_on_in_subq_left_part(Item_in_subselect *subq_pred);
Item *derived_field_transformer_for_having(THD *thd, uchar *arg);
Item *derived_field_transformer_for_where(THD *thd, uchar *arg);
- Item *derived_grouping_field_transformer_for_where(THD *thd,
- uchar *arg);
+ Item *grouping_field_transformer_for_where(THD *thd, uchar *arg);
+ Item *in_subq_field_transformer_for_where(THD *thd, uchar *arg);
+ Item *in_subq_field_transformer_for_having(THD *thd, uchar *arg);
void save_val(Field *to)
{
@@ -5300,6 +5689,12 @@ public:
else
return Item_direct_ref::val_str(tmp);
}
+ bool val_native(THD *thd, Native *to)
+ {
+ if (check_null_ref())
+ return true;
+ return Item_direct_ref::val_native(thd, to);
+ }
my_decimal *val_decimal(my_decimal *tmp)
{
if (check_null_ref())
@@ -5321,14 +5716,14 @@ public:
else
return Item_direct_ref::is_null();
}
- bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
{
if (check_null_ref())
{
bzero((char*) ltime,sizeof(*ltime));
return 1;
}
- return Item_direct_ref::get_date(ltime, fuzzydate);
+ return Item_direct_ref::get_date(thd, ltime, fuzzydate);
}
bool send(Protocol *protocol, st_value *buffer);
void save_org_in_field(Field *field,
@@ -5355,6 +5750,9 @@ public:
}
Item *get_copy(THD *thd)
{ return get_item_copy<Item_direct_view_ref>(thd, this); }
+ Item *field_transformer_for_having_pushdown(THD *thd, uchar *arg)
+ { return this; }
+ Item *remove_item_direct_ref() { return this; }
};
@@ -5444,7 +5842,8 @@ public:
String* val_str(String* s);
my_decimal *val_decimal(my_decimal *);
bool val_bool();
- bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
+ bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate);
+ bool val_native(THD *thd, Native *to);
virtual void print(String *str, enum_query_type query_type);
table_map used_tables() const;
Item *get_copy(THD *thd)
@@ -5536,12 +5935,12 @@ protected:
*/
Item_copy(THD *thd, Item *i): Item(thd)
{
+ DBUG_ASSERT(i->is_fixed());
item= i;
null_value=maybe_null=item->maybe_null;
Type_std_attributes::set(item);
name= item->name;
set_handler(item->type_handler());
- fixed= item->fixed;
}
public:
@@ -5562,6 +5961,12 @@ public:
const Type_handler *type_handler() const
{ return Type_handler_hybrid_field_type::type_handler(); }
+ Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src,
+ const Tmp_field_param *param)
+ {
+ DBUG_ASSERT(0);
+ return NULL;
+ }
void make_send_field(THD *thd, Send_field *field)
{ item->make_send_field(thd, field); }
table_map used_tables() const { return (table_map) 1L; }
@@ -5603,8 +6008,8 @@ public:
my_decimal *val_decimal(my_decimal *);
double val_real();
longlong val_int();
- bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
- { return get_date_from_string(ltime, fuzzydate); }
+ bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
+ { return get_date_from_string(thd, ltime, fuzzydate); }
void copy();
int save_in_field(Field *field, bool no_conversions);
Item *get_copy(THD *thd)
@@ -5612,6 +6017,76 @@ public:
};
+/**
+ We need a separate class Item_copy_timestamp because
+ TIMESTAMP->string->TIMESTAMP conversion is not round trip safe
+ near the DST change, e.g. '2010-10-31 02:25:26' can mean:
+ - my_time_t(1288477526) - summer time in Moscow
+ - my_time_t(1288481126) - winter time in Moscow, one hour later
+*/
+class Item_copy_timestamp: public Item_copy
+{
+ Timestamp_or_zero_datetime m_value;
+ bool sane() const { return !null_value || m_value.is_zero_datetime(); }
+public:
+ Item_copy_timestamp(THD *thd, Item *arg): Item_copy(thd, arg) { }
+ const Type_handler *type_handler() const { return &type_handler_timestamp2; }
+ void copy()
+ {
+ Timestamp_or_zero_datetime_native_null tmp(current_thd, item, false);
+ null_value= tmp.is_null();
+ m_value= tmp.is_null() ? Timestamp_or_zero_datetime() :
+ Timestamp_or_zero_datetime(tmp);
+ }
+ int save_in_field(Field *field, bool no_conversions)
+ {
+ DBUG_ASSERT(sane());
+ if (null_value)
+ return set_field_to_null(field);
+ Timestamp_or_zero_datetime_native native(m_value, decimals);
+ return native.save_in_field(field, decimals);
+ }
+ longlong val_int()
+ {
+ DBUG_ASSERT(sane());
+ return null_value ? 0 :
+ m_value.to_datetime(current_thd).to_longlong();
+ }
+ double val_real()
+ {
+ DBUG_ASSERT(sane());
+ return null_value ? 0e0 :
+ m_value.to_datetime(current_thd).to_double();
+ }
+ String *val_str(String *to)
+ {
+ DBUG_ASSERT(sane());
+ return null_value ? NULL :
+ m_value.to_datetime(current_thd).to_string(to, decimals);
+ }
+ my_decimal *val_decimal(my_decimal *to)
+ {
+ DBUG_ASSERT(sane());
+ return null_value ? NULL :
+ m_value.to_datetime(current_thd).to_decimal(to);
+ }
+ bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
+ {
+ DBUG_ASSERT(sane());
+ bool res= m_value.to_TIME(thd, ltime, fuzzydate);
+ DBUG_ASSERT(!res);
+ return null_value || res;
+ }
+ bool val_native(THD *thd, Native *to)
+ {
+ DBUG_ASSERT(sane());
+ return null_value || m_value.to_native(to, decimals);
+ }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_copy_timestamp>(thd, this); }
+};
+
+
/*
Cached_item_XXX objects are not exactly caches. They do the following:
@@ -5745,7 +6220,7 @@ public:
double val_real();
longlong val_int();
my_decimal *val_decimal(my_decimal *decimal_value);
- bool get_date(MYSQL_TIME *ltime,ulonglong fuzzydate);
+ bool get_date(THD *thd, MYSQL_TIME *ltime,date_mode_t fuzzydate);
bool send(Protocol *protocol, st_value *buffer);
int save_in_field(Field *field_arg, bool no_conversions);
bool save_in_param(THD *thd, Item_param *param)
@@ -5802,7 +6277,7 @@ public:
double val_real();
longlong val_int();
my_decimal *val_decimal(my_decimal *decimal_value);
- bool get_date(MYSQL_TIME *ltime,ulonglong fuzzydate);
+ bool get_date(THD *thd, MYSQL_TIME *ltime,date_mode_t fuzzydate);
bool send(Protocol *protocol, st_value *buffer);
};
@@ -5948,7 +6423,7 @@ public:
for any value.
*/
-class Item_cache: public Item_basic_constant,
+class Item_cache: public Item,
public Type_handler_hybrid_field_type
{
protected:
@@ -5967,25 +6442,27 @@ protected:
cache_value() will set this flag to TRUE.
*/
bool value_cached;
+
+ table_map used_table_map;
public:
Item_cache(THD *thd):
- Item_basic_constant(thd),
+ Item(thd),
Type_handler_hybrid_field_type(&type_handler_string),
example(0), cached_field(0),
- value_cached(0)
+ value_cached(0),
+ used_table_map(0)
{
- fixed= 1;
maybe_null= 1;
null_value= 1;
}
protected:
Item_cache(THD *thd, const Type_handler *handler):
- Item_basic_constant(thd),
+ Item(thd),
Type_handler_hybrid_field_type(handler),
example(0), cached_field(0),
- value_cached(0)
+ value_cached(0),
+ used_table_map(0)
{
- fixed= 1;
maybe_null= 1;
null_value= 1;
}
@@ -6000,10 +6477,18 @@ public:
cached_field= ((Item_field *)item)->field;
return 0;
};
+
+ void set_used_tables(table_map map) { used_table_map= map; }
+ table_map used_tables() const { return used_table_map; }
enum Type type() const { return CACHE_ITEM; }
const Type_handler *type_handler() const
{ return Type_handler_hybrid_field_type::type_handler(); }
+ Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src,
+ const Tmp_field_param *param)
+ {
+ return create_tmp_field_ex_simple(table, src, param);
+ }
virtual void keep_array() {}
virtual void print(String *str, enum_query_type query_type);
@@ -6034,7 +6519,7 @@ public:
void cleanup()
{
clear();
- Item_basic_constant::cleanup();
+ Item::cleanup();
}
/**
Check if saved item has a non-NULL value.
@@ -6069,6 +6554,8 @@ public:
virtual void set_null();
bool walk(Item_processor processor, bool walk_subquery, void *arg)
{
+ if (arg == STOP_PTR)
+ return FALSE;
if (example && example->walk(processor, walk_subquery, arg))
return TRUE;
return (this->*processor)(arg);
@@ -6086,7 +6573,11 @@ public:
{ return convert_to_basic_const_item(thd); }
Item *derived_field_transformer_for_where(THD *thd, uchar *arg)
{ return convert_to_basic_const_item(thd); }
- Item *derived_grouping_field_transformer_for_where(THD *thd, uchar *arg)
+ Item *grouping_field_transformer_for_where(THD *thd, uchar *arg)
+ { return convert_to_basic_const_item(thd); }
+ Item *in_subq_field_transformer_for_where(THD *thd, uchar *arg)
+ { return convert_to_basic_const_item(thd); }
+ Item *in_subq_field_transformer_for_having(THD *thd, uchar *arg)
{ return convert_to_basic_const_item(thd); }
};
@@ -6105,8 +6596,8 @@ public:
longlong val_int();
String* val_str(String *str);
my_decimal *val_decimal(my_decimal *);
- bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
- { return get_date_from_int(ltime, fuzzydate); }
+ bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
+ { return get_date_from_int(thd, ltime, fuzzydate); }
bool cache_value();
int save_in_field(Field *field, bool no_conversions);
Item *convert_to_basic_const_item(THD *thd);
@@ -6118,9 +6609,12 @@ public:
class Item_cache_year: public Item_cache_int
{
public:
- Item_cache_year(THD *thd): Item_cache_int(thd, &type_handler_year) { }
- bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
- { return get_date_from_year(ltime, fuzzydate); }
+ Item_cache_year(THD *thd, const Type_handler *handler)
+ :Item_cache_int(thd, handler) { }
+ bool get_date(THD *thd, MYSQL_TIME *to, date_mode_t mode)
+ {
+ return type_handler_year.Item_get_date_with_warn(thd, this, to, mode);
+ }
};
@@ -6129,14 +6623,8 @@ class Item_cache_temporal: public Item_cache_int
protected:
Item_cache_temporal(THD *thd, const Type_handler *handler);
public:
- String* val_str(String *str);
- my_decimal *val_decimal(my_decimal *);
- longlong val_int();
- longlong val_datetime_packed();
- longlong val_time_packed();
- double val_real();
bool cache_value();
- bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
+ bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate);
int save_in_field(Field *field, bool no_conversions);
void store_packed(longlong val_arg, Item *example);
/*
@@ -6159,6 +6647,31 @@ public:
Item *get_copy(THD *thd)
{ return get_item_copy<Item_cache_time>(thd, this); }
Item *make_literal(THD *);
+ longlong val_datetime_packed(THD *thd)
+ {
+ Datetime::Options_cmp opt(thd);
+ return has_value() ? Datetime(thd, this, opt).to_packed() : 0;
+ }
+ longlong val_time_packed(THD *thd)
+ {
+ return has_value() ? value : 0;
+ }
+ longlong val_int()
+ {
+ return has_value() ? Time(this).to_longlong() : 0;
+ }
+ double val_real()
+ {
+ return has_value() ? Time(this).to_double() : 0;
+ }
+ String *val_str(String *to)
+ {
+ return has_value() ? Time(this).to_string(to, decimals) : NULL;
+ }
+ my_decimal *val_decimal(my_decimal *to)
+ {
+ return has_value() ? Time(this).to_decimal(to) : NULL;
+ }
};
@@ -6170,6 +6683,30 @@ public:
Item *get_copy(THD *thd)
{ return get_item_copy<Item_cache_datetime>(thd, this); }
Item *make_literal(THD *);
+ longlong val_datetime_packed(THD *thd)
+ {
+ return has_value() ? value : 0;
+ }
+ longlong val_time_packed(THD *thd)
+ {
+ return Time(thd, this, Time::Options_cmp(thd)).to_packed();
+ }
+ longlong val_int()
+ {
+ return has_value() ? Datetime(this).to_longlong() : 0;
+ }
+ double val_real()
+ {
+ return has_value() ? Datetime(this).to_double() : 0;
+ }
+ String *val_str(String *to)
+ {
+ return has_value() ? Datetime(this).to_string(to, decimals) : NULL;
+ }
+ my_decimal *val_decimal(my_decimal *to)
+ {
+ return has_value() ? Datetime(this).to_decimal(to) : NULL;
+ }
};
@@ -6181,6 +6718,65 @@ public:
Item *get_copy(THD *thd)
{ return get_item_copy<Item_cache_date>(thd, this); }
Item *make_literal(THD *);
+ longlong val_datetime_packed(THD *thd)
+ {
+ return has_value() ? value : 0;
+ }
+ longlong val_time_packed(THD *thd)
+ {
+ return Time(thd, this, Time::Options_cmp(thd)).to_packed();
+ }
+ longlong val_int() { return has_value() ? Date(this).to_longlong() : 0; }
+ double val_real() { return has_value() ? Date(this).to_double() : 0; }
+ String *val_str(String *to)
+ {
+ return has_value() ? Date(this).to_string(to) : NULL;
+ }
+ my_decimal *val_decimal(my_decimal *to)
+ {
+ return has_value() ? Date(this).to_decimal(to) : NULL;
+ }
+};
+
+
+class Item_cache_timestamp: public Item_cache
+{
+ Timestamp_or_zero_datetime_native m_native;
+ Datetime to_datetime(THD *thd);
+public:
+ Item_cache_timestamp(THD *thd)
+ :Item_cache(thd, &type_handler_timestamp2) { }
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_cache_timestamp>(thd, this); }
+ bool cache_value();
+ String* val_str(String *to)
+ {
+ return to_datetime(current_thd).to_string(to, decimals);
+ }
+ my_decimal *val_decimal(my_decimal *to)
+ {
+ return to_datetime(current_thd).to_decimal(to);
+ }
+ longlong val_int()
+ {
+ return to_datetime(current_thd).to_longlong();
+ }
+ double val_real()
+ {
+ return to_datetime(current_thd).to_double();
+ }
+ longlong val_datetime_packed(THD *thd)
+ {
+ return to_datetime(current_thd).to_packed();
+ }
+ longlong val_time_packed(THD *thd)
+ {
+ DBUG_ASSERT(0);
+ return 0;
+ }
+ bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate);
+ int save_in_field(Field *field, bool no_conversions);
+ bool val_native(THD *thd, Native *to);
};
@@ -6196,8 +6792,8 @@ public:
double val_real();
longlong val_int();
my_decimal *val_decimal(my_decimal *);
- bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
- { return get_date_from_real(ltime, fuzzydate); }
+ bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
+ { return get_date_from_real(thd, ltime, fuzzydate); }
bool cache_value();
Item *convert_to_basic_const_item(THD *thd);
};
@@ -6238,8 +6834,11 @@ public:
longlong val_int();
String* val_str(String *str);
my_decimal *val_decimal(my_decimal *);
- bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
- { return get_date_from_decimal(ltime, fuzzydate); }
+ bool get_date(THD *thd, MYSQL_TIME *to, date_mode_t mode)
+ {
+ return decimal_to_datetime_with_warn(thd, VDec(this).ptr(), to, mode,
+ NULL, NULL);
+ }
bool cache_value();
Item *convert_to_basic_const_item(THD *thd);
Item *get_copy(THD *thd)
@@ -6266,8 +6865,8 @@ public:
longlong val_int();
String* val_str(String *);
my_decimal *val_decimal(my_decimal *);
- bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
- { return get_date_from_string(ltime, fuzzydate); }
+ bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
+ { return get_date_from_string(thd, ltime, fuzzydate); }
CHARSET_INFO *charset() const { return value->charset(); };
int save_in_field(Field *field, bool no_conversions);
bool cache_value();
@@ -6348,7 +6947,7 @@ public:
illegal_method_call((const char*)"val_decimal");
return 0;
};
- bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
{
illegal_method_call((const char*)"val_decimal");
return true;
@@ -6397,7 +6996,7 @@ public:
Type_handler_hybrid_field_type(item->real_type_handler()),
enum_set_typelib(0)
{
- DBUG_ASSERT(item->fixed);
+ DBUG_ASSERT(item->is_fixed());
maybe_null= item->maybe_null;
}
Item_type_holder(THD *thd,
@@ -6431,8 +7030,9 @@ public:
longlong val_int();
my_decimal *val_decimal(my_decimal *);
String *val_str(String*);
- bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
- Field *create_tmp_field(bool group, TABLE *table)
+ bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate);
+ Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src,
+ const Tmp_field_param *param)
{
return Item_type_holder::real_type_handler()->
make_and_init_table_field(&name, Record_addr(maybe_null),
@@ -6562,7 +7162,7 @@ bool fix_escape_item(THD *thd, Item *escape_item, String *tmp_str,
inline bool Virtual_column_info::is_equal(const Virtual_column_info* vcol) const
{
- return field_type == vcol->get_real_type()
+ return type_handler() == vcol->type_handler()
&& stored_in_db == vcol->is_stored()
&& expr->eq(vcol->expr, true);
}
@@ -6572,4 +7172,39 @@ inline void Virtual_column_info::print(String* str)
expr->print_for_table_def(str);
}
+inline bool TABLE::mark_column_with_deps(Field *field)
+{
+ bool res;
+ if (!(res= bitmap_fast_test_and_set(read_set, field->field_index)))
+ {
+ if (field->vcol_info)
+ mark_virtual_column_deps(field);
+ }
+ return res;
+}
+
+inline bool TABLE::mark_virtual_column_with_deps(Field *field)
+{
+ bool res;
+ DBUG_ASSERT(field->vcol_info);
+ if (!(res= bitmap_fast_test_and_set(read_set, field->field_index)))
+ mark_virtual_column_deps(field);
+ return res;
+}
+
+inline void TABLE::mark_virtual_column_deps(Field *field)
+{
+ DBUG_ASSERT(field->vcol_info);
+ DBUG_ASSERT(field->vcol_info->expr);
+ field->vcol_info->expr->walk(&Item::register_field_in_read_map, 1, 0);
+}
+
+inline void TABLE::use_all_stored_columns()
+{
+ bitmap_set_all(read_set);
+ if (Field **vf= vfield)
+ for (; *vf; vf++)
+ bitmap_clear_bit(read_set, (*vf)->field_index);
+}
+
#endif /* SQL_ITEM_INCLUDED */