summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2011-05-21 18:41:56 +0200
committerSergei Golubchik <sergii@pisem.net>2011-05-21 18:41:56 +0200
commitdda9577d553c9969415bc5f3d45f287e3dd6de39 (patch)
tree06124b3cf34e6947f74d357f185626d583e845dc /sql
parent7c459960ece917dcdc4dedc9f3dd0c9f5d07c3b8 (diff)
downloadmariadb-git-dda9577d553c9969415bc5f3d45f287e3dd6de39.tar.gz
comments
Diffstat (limited to 'sql')
-rw-r--r--sql/field.cc12
-rw-r--r--sql/field.h4
-rw-r--r--sql/item.cc1
-rw-r--r--sql/item.h5
-rw-r--r--sql/item_func.cc8
-rw-r--r--sql/log_event.h1
-rw-r--r--sql/sql_select.cc40
7 files changed, 43 insertions, 28 deletions
diff --git a/sql/field.cc b/sql/field.cc
index 0f1a8a2cdb6..87fd7317e9b 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -4473,7 +4473,7 @@ timestamp_auto_set_type Field_timestamp::get_auto_set_type() const
}
}
-long Field_timestamp::get_timestamp(ulong *sec_part) const
+my_time_t Field_timestamp::get_timestamp(ulong *sec_part) const
{
ASSERT_COLUMN_MARKED_FOR_READ;
*sec_part= 0;
@@ -4592,7 +4592,7 @@ longlong Field_timestamp::val_int(void)
thd->time_zone_used= 1;
ulong sec_part;
- uint32 temp= get_timestamp(&sec_part);
+ my_time_t temp= get_timestamp(&sec_part);
/*
Field_timestamp() and Field_timestamp_hres() shares this code.
@@ -4622,7 +4622,7 @@ String *Field_timestamp::val_str(String *val_buffer, String *val_ptr)
thd->time_zone_used= 1;
ulong sec_part;
- uint32 temp= get_timestamp(&sec_part);
+ my_time_t temp= get_timestamp(&sec_part);
if (temp == 0 && sec_part == 0)
{ /* Zero time is "000000" */
@@ -4682,7 +4682,7 @@ bool Field_timestamp::get_date(MYSQL_TIME *ltime, uint fuzzydate)
THD *thd= table->in_use;
thd->time_zone_used= 1;
ulong sec_part;
- uint32 temp= get_timestamp(&sec_part);
+ my_time_t temp= get_timestamp(&sec_part);
if (temp == 0 && sec_part == 0)
{ /* Zero time is "000000" */
if (fuzzydate & TIME_NO_ZERO_DATE)
@@ -4830,7 +4830,7 @@ void Field_timestamp_hires::store_TIME(my_time_t timestamp, ulong sec_part)
store_bigendian(sec_part_shift(sec_part, dec), ptr+4, sec_part_bytes[dec]);
}
-long Field_timestamp_hires::get_timestamp(ulong *sec_part) const
+my_time_t Field_timestamp_hires::get_timestamp(ulong *sec_part) const
{
ASSERT_COLUMN_MARKED_FOR_READ;
*sec_part= (long)sec_part_unshift(read_bigendian(ptr+4, sec_part_bytes[dec]), dec);
@@ -4844,7 +4844,7 @@ double Field_timestamp_hires::val_real(void)
thd->time_zone_used= 1;
ulong sec_part;
- uint32 temp= get_timestamp(&sec_part);
+ my_time_t temp= get_timestamp(&sec_part);
if (temp == 0 && sec_part == 0)
return(0);
diff --git a/sql/field.h b/sql/field.h
index 95c2fd30559..a976d8b5ce5 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -1137,7 +1137,7 @@ public:
Field::set_default();
}
/* Get TIMESTAMP field value as seconds since begging of Unix Epoch */
- virtual long get_timestamp(ulong *sec_part) const;
+ virtual my_time_t get_timestamp(ulong *sec_part) const;
virtual void store_TIME(my_time_t timestamp, ulong sec_part)
{
int4store(ptr,timestamp);
@@ -1172,7 +1172,7 @@ public:
DBUG_ASSERT(dec <= TIME_SECOND_PART_DIGITS);
}
void sql_type(String &str) const;
- long get_timestamp(ulong *sec_part) const;
+ my_time_t get_timestamp(ulong *sec_part) const;
void store_TIME(my_time_t timestamp, ulong sec_part);
int store_decimal(const my_decimal *d);
double val_real(void);
diff --git a/sql/item.cc b/sql/item.cc
index fd0be90c216..520386b90fa 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -7106,6 +7106,7 @@ Item_cache* Item_cache::get_cache(const Item *item, const Item_result type)
case ROW_RESULT:
return new Item_cache_row();
case TIME_RESULT:
+ /* this item will store a packed datetime value as an integer */
return new Item_cache_int(MYSQL_TYPE_DATETIME);
}
return 0;
diff --git a/sql/item.h b/sql/item.h
index 3be654abdd8..16f0857958d 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -3041,6 +3041,11 @@ public:
bool cache_value();
bool get_date(MYSQL_TIME *ltime, uint fuzzydate);
int save_in_field(Field *field, bool no_conversions);
+ /*
+ Having a clone_item method tells optimizer that this object
+ is a constant and need not be optimized further.
+ Important when storing packed datetime values.
+ */
Item *clone_item()
{
Item_cache_int *item= new Item_cache_int(cached_field_type);
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 870a481ce85..5a8e8a4defd 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -2282,6 +2282,14 @@ bool Item_func_min_max::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
{
longlong UNINIT_VAR(min_max);
DBUG_ASSERT(fixed == 1);
+
+ /*
+ just like ::val_int() method of an string item can be called,
+ for example, SELECT CONCAT("10", "12") + 1,
+ ::get_date() can be called for non-temporal values,
+ for example, SELECT MONTH(GREATEST("2011-11-21", "2010-10-09"))
+
+ */
if (!compare_as_dates)
return Item_func::get_date(ltime, fuzzy_date);
diff --git a/sql/log_event.h b/sql/log_event.h
index 6327a53844d..79e3c1e2f15 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -1015,6 +1015,7 @@ public:
when_sec_part= thd->start_time_sec_part;
return when;
}
+ /* thd will only be 0 here at time of log creation */
if ((tmp_thd= current_thd))
{
when= tmp_thd->start_time;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index cda934cd549..aa5c1f7668d 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -9417,36 +9417,36 @@ remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
return cond; // Point at next and level
}
-/*
+/**
Check if equality can be used in removing components of GROUP BY/DISTINCT
- SYNOPSIS
- test_if_equality_guarantees_uniqueness()
- l the left comparison argument (a field if any)
- r the right comparison argument (a const of any)
+ @param l the left comparison argument (a field if any)
+ @param r the right comparison argument (a const of any)
- DESCRIPTION
- Checks if an equality predicate can be used to take away
- DISTINCT/GROUP BY because it is known to be true for exactly one
- distinct value (e.g. <expr> == <const>).
- Arguments must be of the same type because e.g.
- <string_field> = <int_const> may match more than 1 distinct value from
- the column.
- We must take into consideration and the optimization done for various
- string constants when compared to dates etc (see Item_int_with_ref) as
- well as the collation of the arguments.
+ @details
+ Checks if an equality predicate can be used to take away
+ DISTINCT/GROUP BY because it is known to be true for exactly one
+ distinct value (e.g. <expr> == <const>).
+ Arguments must be of the same type because e.g.
+ <string_field> = <int_const> may match more than 1 distinct value from
+ the column.
+ Additionally, strings must have the same collation.
+ Or the *field* must be a datetime - if the constant is a datetime
+ and a field is not - this is not enough, consider:
+ create table t1 (a varchar(100));
+ insert t1 values ('2010-01-02'), ('2010-1-2'), ('20100102');
+ select distinct t1 from t1 where a=date('2010-01-02');
- RETURN VALUE
- TRUE can be used
- FALSE cannot be used
+ @retval true can be used
+ @retval false cannot be used
*/
static bool
test_if_equality_guarantees_uniqueness(Item *l, Item *r)
{
return r->const_item() &&
- /* elements must be compared as dates */
+ /* the field is a date (the const will be converted to a date) */
(l->cmp_type() == TIME_RESULT ||
- /* or of the same result type */
+ /* or arguments are of the same result type */
(r->result_type() == l->result_type() &&
/* and must have the same collation if compared as strings */
(l->result_type() != STRING_RESULT ||