summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorgkodinov/kgeorge@magare.gmz <>2007-07-18 15:56:29 +0300
committergkodinov/kgeorge@magare.gmz <>2007-07-18 15:56:29 +0300
commitf6225e20486ec17d86992973923db81511c2700e (patch)
tree41c1dde4a4218d15c8b9a50136bece1db3b96eaa /sql
parentbec9500ec074c0349868fc69504b71bd7fcee0fe (diff)
parent4f579b8d0e3e8bc3d8eb57eca7d3c656c77cb10b (diff)
downloadmariadb-git-f6225e20486ec17d86992973923db81511c2700e.tar.gz
Merge magare.gmz:/home/kgeorge/mysql/work/mysql-5.0-opt
into magare.gmz:/home/kgeorge/mysql/work/merge-5.0-5.1-opt
Diffstat (limited to 'sql')
-rw-r--r--sql/field.cc3
-rw-r--r--sql/item_cmpfunc.cc80
-rw-r--r--sql/item_cmpfunc.h2
-rw-r--r--sql/opt_range.cc40
4 files changed, 102 insertions, 23 deletions
diff --git a/sql/field.cc b/sql/field.cc
index 2cd81afca49..a970a6e4318 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -5406,7 +5406,8 @@ int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs)
else
{
tmp= l_time.day + l_time.month*32 + l_time.year*16*32;
- if (!error && (ret != MYSQL_TIMESTAMP_DATE))
+ if (!error && (ret != MYSQL_TIMESTAMP_DATE) &&
+ thd->count_cuted_fields != CHECK_FIELD_IGNORE)
error= 3; // Datetime was cut (note)
}
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 299e0435122..755e711e383 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -719,6 +719,67 @@ Arg_comparator::can_compare_as_dates(Item *a, Item *b, ulonglong *const_value)
}
+/*
+ Retrieves correct TIME value from the given item.
+
+ SYNOPSIS
+ get_time_value()
+ thd thread handle
+ item_arg [in/out] item to retrieve TIME value from
+ cache_arg [in/out] pointer to place to store the cache item to
+ warn_item [in] unused
+ is_null [out] TRUE <=> the item_arg is null
+
+ DESCRIPTION
+ Retrieves the correct TIME value from given item for comparison by the
+ compare_datetime() function.
+ If item's result can be compared as longlong then its int value is used
+ and a value returned by get_time function is used otherwise.
+ If an item is a constant one then its value is cached and it isn't
+ get parsed again. An Item_cache_int object is used for for cached values.
+ It seamlessly substitutes the original item. The cache item is marked as
+ non-constant to prevent re-caching it again.
+
+ RETURN
+ obtained value
+*/
+
+ulonglong
+get_time_value(THD *thd, Item ***item_arg, Item **cache_arg,
+ Item *warn_item, bool *is_null)
+{
+ ulonglong value;
+ Item *item= **item_arg;
+ MYSQL_TIME ltime;
+
+ if (item->result_as_longlong())
+ {
+ value= item->val_int();
+ *is_null= item->null_value;
+ }
+ else
+ {
+ *is_null= item->get_time(&ltime);
+ value= !*is_null ? TIME_to_ulonglong_datetime(&ltime) : 0;
+ }
+ /*
+ Do not cache GET_USER_VAR() function as its const_item() may return TRUE
+ for the current thread but it still may change during the execution.
+ */
+ if (item->const_item() && cache_arg && (item->type() != Item::FUNC_ITEM ||
+ ((Item_func*)item)->functype() != Item_func::GUSERVAR_FUNC))
+ {
+ Item_cache_int *cache= new Item_cache_int();
+ /* Mark the cache as non-const to prevent re-caching. */
+ cache->set_used_tables(1);
+ cache->store(item, value);
+ *cache_arg= cache;
+ *item_arg= cache_arg;
+ }
+ return value;
+}
+
+
int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
Item **a1, Item **a2,
Item_result type)
@@ -757,6 +818,7 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
}
is_nulls_eq= test(owner && owner->functype() == Item_func::EQUAL_FUNC);
func= &Arg_comparator::compare_datetime;
+ get_value_func= &get_datetime_value;
return 0;
}
else if (type == STRING_RESULT && (*a)->field_type() == MYSQL_TYPE_TIME &&
@@ -765,9 +827,11 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
/* Compare TIME values as integers. */
thd= current_thd;
owner= owner_arg;
- func= ((test(owner && owner->functype() == Item_func::EQUAL_FUNC)) ?
- &Arg_comparator::compare_e_int :
- &Arg_comparator::compare_int_unsigned);
+ a_cache= 0;
+ b_cache= 0;
+ is_nulls_eq= test(owner && owner->functype() == Item_func::EQUAL_FUNC);
+ func= &Arg_comparator::compare_datetime;
+ get_value_func= &get_time_value;
return 0;
}
@@ -788,8 +852,10 @@ void Arg_comparator::set_datetime_cmp_func(Item **a1, Item **b1)
b_cache= 0;
is_nulls_eq= FALSE;
func= &Arg_comparator::compare_datetime;
+ get_value_func= &get_datetime_value;
}
+
/*
Retrieves correct DATETIME value from given item.
@@ -903,8 +969,8 @@ int Arg_comparator::compare_datetime()
bool is_null= FALSE;
ulonglong a_value, b_value;
- /* Get DATE/DATETIME value of the 'a' item. */
- a_value= get_datetime_value(thd, &a, &a_cache, *b, &is_null);
+ /* Get DATE/DATETIME/TIME value of the 'a' item. */
+ a_value= (*get_value_func)(thd, &a, &a_cache, *b, &is_null);
if (!is_nulls_eq && is_null)
{
if (owner)
@@ -912,8 +978,8 @@ int Arg_comparator::compare_datetime()
return -1;
}
- /* Get DATE/DATETIME value of the 'b' item. */
- b_value= get_datetime_value(thd, &b, &b_cache, *a, &is_null);
+ /* Get DATE/DATETIME/TIME value of the 'b' item. */
+ b_value= (*get_value_func)(thd, &b, &b_cache, *a, &is_null);
if (is_null)
{
if (owner)
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index ee36aca069d..fcbacc32d88 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -42,6 +42,8 @@ class Arg_comparator: public Sql_alloc
bool is_nulls_eq; // TRUE <=> compare for the EQUAL_FUNC
enum enum_date_cmp_type { CMP_DATE_DFLT= 0, CMP_DATE_WITH_DATE,
CMP_DATE_WITH_STR, CMP_STR_WITH_DATE };
+ ulonglong (*get_value_func)(THD *thd, Item ***item_arg, Item **cache_arg,
+ Item *warn_item, bool *is_null);
public:
DTCollation cmp_collation;
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 4944c994d3d..948b268d9a3 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -1264,8 +1264,16 @@ int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler)
thd= head->in_use;
if (!(file= head->file->clone(thd->mem_root)))
{
+ /*
+ Manually set the error flag. Note: there seems to be quite a few
+ places where a failure could cause the server to "hang" the client by
+ sending no response to a query. ATM those are not real errors because
+ the storage engine calls in question happen to never fail with the
+ existing storage engines.
+ */
+ thd->net.report_error= 1; /* purecov: inspected */
/* Caller will free the memory */
- goto failure;
+ goto failure; /* purecov: inspected */
}
head->column_bitmaps_set(&column_bitmap, &column_bitmap);
@@ -7244,6 +7252,11 @@ check_quick_select(PARAM *param,uint idx,SEL_ARG *tree, bool update_tbl_stats)
param->is_ror_scan is cleared if the function detects that the key scan is
not a Rowid-Ordered Retrieval scan ( see comments for is_key_scan_ror
function for description of which key scans are ROR scans)
+
+ RETURN
+ #records E(#records) for given subtree
+ HA_POS_ERROR if subtree cannot be used for record retrieval
+
*/
static ha_rows
@@ -7445,27 +7458,24 @@ check_quick_keys(PARAM *param, uint idx, SEL_ARG *key_tree,
ROR (Rowid Ordered Retrieval) key scan is a key scan that produces
ordered sequence of rowids (ha_xxx::cmp_ref is the comparison function)
- An index scan is a ROR scan if it is done using a condition in form
+ This function is needed to handle a practically-important special case:
+ an index scan is a ROR scan if it is done using a condition in form
- "key1_1=c_1 AND ... AND key1_n=c_n" (1)
+ "key1_1=c_1 AND ... AND key1_n=c_n"
where the index is defined on (key1_1, ..., key1_N [,a_1, ..., a_n])
- and the table has a clustered Primary Key
-
- PRIMARY KEY(a_1, ..., a_n, b1, ..., b_k) with first key parts being
- identical to uncovered parts ot the key being scanned (2)
-
- Scans on HASH indexes are not ROR scans,
- any range scan on clustered primary key is ROR scan (3)
+ and the table has a clustered Primary Key defined as
- Check (1) is made in check_quick_keys()
- Check (3) is made check_quick_select()
- Check (2) is made by this function.
+ PRIMARY KEY(a_1, ..., a_n, b1, ..., b_k)
+
+ i.e. the first key parts of it are identical to uncovered parts ot the
+ key being scanned. This function assumes that the index flags do not
+ include HA_KEY_SCAN_NOT_ROR flag (that is checked elsewhere).
RETURN
- TRUE If the scan is ROR-scan
- FALSE otherwise
+ TRUE The scan is ROR-scan
+ FALSE Otherwise
*/
static bool is_key_scan_ror(PARAM *param, uint keynr, uint8 nparts)