diff options
author | gkodinov/kgeorge@magare.gmz <> | 2007-07-18 15:56:29 +0300 |
---|---|---|
committer | gkodinov/kgeorge@magare.gmz <> | 2007-07-18 15:56:29 +0300 |
commit | f6225e20486ec17d86992973923db81511c2700e (patch) | |
tree | 41c1dde4a4218d15c8b9a50136bece1db3b96eaa /sql | |
parent | bec9500ec074c0349868fc69504b71bd7fcee0fe (diff) | |
parent | 4f579b8d0e3e8bc3d8eb57eca7d3c656c77cb10b (diff) | |
download | mariadb-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.cc | 3 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 80 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 2 | ||||
-rw-r--r-- | sql/opt_range.cc | 40 |
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(<ime); + value= !*is_null ? TIME_to_ulonglong_datetime(<ime) : 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) |