diff options
author | Sergei Golubchik <sergii@pisem.net> | 2013-03-27 10:03:28 +0100 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2013-03-27 10:03:28 +0100 |
commit | 6599fd3e9c23a8957a63146cbe6a0ffc4c292a3d (patch) | |
tree | 5a7e05e0a9abb5f5cc2672bc3d545ac3f5f7fa43 /sql | |
parent | 102a7a2a763dc5f2da8dd1f9ca9a53664c5aad6a (diff) | |
parent | e308d7417bc4ceb1b3b72cac2642015b88f310ff (diff) | |
download | mariadb-git-6599fd3e9c23a8957a63146cbe6a0ffc4c292a3d.tar.gz |
5.3 merge
Diffstat (limited to 'sql')
-rw-r--r-- | sql/filesort.cc | 5 | ||||
-rw-r--r-- | sql/item.cc | 8 | ||||
-rw-r--r-- | sql/item_create.cc | 3 | ||||
-rw-r--r-- | sql/item_func.cc | 4 | ||||
-rw-r--r-- | sql/item_func.h | 7 | ||||
-rw-r--r-- | sql/item_geofunc.cc | 29 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 78 | ||||
-rw-r--r-- | sql/item_strfunc.h | 20 | ||||
-rw-r--r-- | sql/item_sum.cc | 5 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 18 | ||||
-rw-r--r-- | sql/spatial.cc | 99 | ||||
-rw-r--r-- | sql/spatial.h | 5 | ||||
-rw-r--r-- | sql/sql_select.cc | 1 |
13 files changed, 131 insertions, 151 deletions
diff --git a/sql/filesort.cc b/sql/filesort.cc index 9af57f669e4..ef5ef5357de 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -875,7 +875,10 @@ static void make_sortkey(register SORTPARAM *param, { MYSQL_TIME buf; if (item->get_date_result(&buf, TIME_FUZZY_DATE | TIME_INVALID_DATES)) - DBUG_ASSERT(maybe_null && item->null_value); + { + DBUG_ASSERT(maybe_null); + DBUG_ASSERT(item->null_value); + } else value= pack_time(&buf); } diff --git a/sql/item.cc b/sql/item.cc index 15f1645b151..9bd9056f3ce 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1272,11 +1272,15 @@ bool Item::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate) DBUG_ASSERT(0); } - return 0; + return null_value= 0; err: + /* + if the item was not null and convertion failed, we return a zero date + if allowed, otherwise - null. + */ bzero((char*) ltime,sizeof(*ltime)); - return 1; + return null_value|= (fuzzydate & (TIME_NO_ZERO_DATE|TIME_NO_ZERO_IN_DATE)); } bool Item::get_seconds(ulonglong *sec, ulong *sec_part) diff --git a/sql/item_create.cc b/sql/item_create.cc index 96837a8f262..45de3850fcd 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -4373,8 +4373,7 @@ Create_func_make_set::create_native(THD *thd, LEX_STRING name, return NULL; } - Item *param_1= item_list->pop(); - return new (thd->mem_root) Item_func_make_set(param_1, *item_list); + return new (thd->mem_root) Item_func_make_set(*item_list); } diff --git a/sql/item_func.cc b/sql/item_func.cc index 2bc1cdba326..84161021a2b 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -769,13 +769,14 @@ void Item_num_op::find_num_type(void) { hybrid_type= DECIMAL_RESULT; result_precision(); + fix_decimals(); } else { DBUG_ASSERT(r0 == INT_RESULT && r1 == INT_RESULT); - decimals= 0; hybrid_type=INT_RESULT; result_precision(); + decimals= 0; } DBUG_PRINT("info", ("Type: %s", (hybrid_type == REAL_RESULT ? "REAL_RESULT" : @@ -1708,6 +1709,7 @@ void Item_func_div::fix_length_and_dec() break; case DECIMAL_RESULT: result_precision(); + fix_decimals(); break; case STRING_RESULT: case ROW_RESULT: diff --git a/sql/item_func.h b/sql/item_func.h index 7b6b60b2914..ed01591cba5 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -431,6 +431,13 @@ public: void fix_num_length_and_dec(); virtual void find_num_type()= 0; /* To be called from fix_length_and_dec */ + inline void fix_decimals() + { + DBUG_ASSERT(result_type() == DECIMAL_RESULT); + if (decimals == NOT_FIXED_DEC) + set_if_smaller(decimals, max_length - 1); + } + double val_real(); longlong val_int(); my_decimal *val_decimal(my_decimal *); diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc index e3e80bdf59f..0a7f18e6546 100644 --- a/sql/item_geofunc.cc +++ b/sql/item_geofunc.cc @@ -561,8 +561,8 @@ longlong Item_func_spatial_mbr_rel::val_int() args[1]->null_value || !(g1= Geometry::construct(&buffer1, res1->ptr(), res1->length())) || !(g2= Geometry::construct(&buffer2, res2->ptr(), res2->length())) || - g1->get_mbr(&mbr1, &dummy) || - g2->get_mbr(&mbr2, &dummy)))) + g1->get_mbr(&mbr1, &dummy) || !mbr1.valid() || + g2->get_mbr(&mbr2, &dummy) || !mbr2.valid()))) return 0; switch (spatial_rel) { @@ -687,12 +687,11 @@ longlong Item_func_spatial_rel::val_int() if ((null_value= (args[0]->null_value || args[1]->null_value || !(g1= Geometry::construct(&buffer1, res1->ptr(), res1->length())) || - !(g2= Geometry::construct(&buffer2, res2->ptr(), res2->length()))))) + !(g2= Geometry::construct(&buffer2, res2->ptr(), res2->length())) || + g1->get_mbr(&mbr1, &c_end) || !mbr1.valid() || + g2->get_mbr(&mbr2, &c_end) || !mbr2.valid()))) goto exit; - g1->get_mbr(&mbr1, &c_end); - g2->get_mbr(&mbr2, &c_end); - umbr= mbr1; umbr.add_mbr(&mbr2); collector.set_extent(umbr.xmin, umbr.xmax, umbr.ymin, umbr.ymax); @@ -826,14 +825,14 @@ String *Item_func_spatial_operation::val_str(String *str_value) if ((null_value= (args[0]->null_value || args[1]->null_value || !(g1= Geometry::construct(&buffer1, res1->ptr(), res1->length())) || - !(g2= Geometry::construct(&buffer2, res2->ptr(), res2->length()))))) + !(g2= Geometry::construct(&buffer2, res2->ptr(), res2->length())) || + g1->get_mbr(&mbr1, &c_end) || !mbr1.valid() || + g2->get_mbr(&mbr2, &c_end) || !mbr2.valid()))) { str_value= 0; goto exit; } - g1->get_mbr(&mbr1, &c_end); - g2->get_mbr(&mbr2, &c_end); mbr1.add_mbr(&mbr2); collector.set_extent(mbr1.xmin, mbr1.xmax, mbr1.ymin, mbr1.ymax); @@ -1358,11 +1357,11 @@ longlong Item_func_issimple::val_int() DBUG_ENTER("Item_func_issimple::val_int"); DBUG_ASSERT(fixed == 1); - if ((null_value= args[0]->null_value) || - !(g= Geometry::construct(&buffer, swkb->ptr(), swkb->length()))) + if ((null_value= (args[0]->null_value || + !(g= Geometry::construct(&buffer, swkb->ptr(), swkb->length())) || + g->get_mbr(&mbr, &c_end)))) DBUG_RETURN(0); - g->get_mbr(&mbr, &c_end); collector.set_extent(mbr.xmin, mbr.xmax, mbr.ymin, mbr.ymax); if (g->get_class_info()->m_type_id == Geometry::wkb_point) @@ -1598,11 +1597,11 @@ double Item_func_distance::val_real() if ((null_value= (args[0]->null_value || args[1]->null_value || !(g1= Geometry::construct(&buffer1, res1->ptr(), res1->length())) || - !(g2= Geometry::construct(&buffer2, res2->ptr(), res2->length()))))) + !(g2= Geometry::construct(&buffer2, res2->ptr(), res2->length())) || + g1->get_mbr(&mbr1, &c_end) || + g2->get_mbr(&mbr2, &c_end)))) goto mem_error; - g1->get_mbr(&mbr1, &c_end); - g2->get_mbr(&mbr2, &c_end); mbr1.add_mbr(&mbr2); collector.set_extent(mbr1.xmin, mbr1.xmax, mbr1.ymin, mbr1.ymax); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index e71663a2559..b1f351696b7 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2460,38 +2460,16 @@ String *Item_func_elt::val_str(String *str) } -void Item_func_make_set::split_sum_func(THD *thd, Item **ref_pointer_array, - List<Item> &fields) -{ - item->split_sum_func2(thd, ref_pointer_array, fields, &item, TRUE); - Item_str_func::split_sum_func(thd, ref_pointer_array, fields); -} - - void Item_func_make_set::fix_length_and_dec() { - uint32 char_length= arg_count - 1; /* Separators */ + uint32 char_length= arg_count - 2; /* Separators */ - if (agg_arg_charsets_for_string_result(collation, args, arg_count)) + if (agg_arg_charsets_for_string_result(collation, args + 1, arg_count - 1)) return; - for (uint i=0 ; i < arg_count ; i++) + for (uint i=1 ; i < arg_count ; i++) char_length+= args[i]->max_char_length(); fix_char_length(char_length); - used_tables_cache|= item->used_tables(); - not_null_tables_cache&= item->not_null_tables(); - const_item_cache&= item->const_item(); - with_sum_func= with_sum_func || item->with_sum_func; - with_field= with_field || item->with_field; -} - - -void Item_func_make_set::update_used_tables() -{ - Item_func::update_used_tables(); - item->update_used_tables(); - used_tables_cache|=item->used_tables(); - const_item_cache&=item->const_item(); } @@ -2500,15 +2478,15 @@ String *Item_func_make_set::val_str(String *str) DBUG_ASSERT(fixed == 1); ulonglong bits; bool first_found=0; - Item **ptr=args; + Item **ptr=args+1; String *result=&my_empty_string; - bits=item->val_int(); - if ((null_value=item->null_value)) + bits=args[0]->val_int(); + if ((null_value=args[0]->null_value)) return NULL; - if (arg_count < 64) - bits &= ((ulonglong) 1 << arg_count)-1; + if (arg_count < 65) + bits &= ((ulonglong) 1 << (arg_count-1))-1; for (; bits; bits >>= 1, ptr++) { @@ -2548,39 +2526,6 @@ String *Item_func_make_set::val_str(String *str) } -Item *Item_func_make_set::transform(Item_transformer transformer, uchar *arg) -{ - DBUG_ASSERT(!current_thd->stmt_arena->is_stmt_prepare()); - - Item *new_item= item->transform(transformer, arg); - if (!new_item) - return 0; - - /* - THD::change_item_tree() should be called only if the tree was - really transformed, i.e. when a new item has been created. - Otherwise we'll be allocating a lot of unnecessary memory for - change records at each execution. - */ - if (item != new_item) - current_thd->change_item_tree(&item, new_item); - return Item_str_func::transform(transformer, arg); -} - - -void Item_func_make_set::print(String *str, enum_query_type query_type) -{ - str->append(STRING_WITH_LEN("make_set(")); - item->print(str, query_type); - if (arg_count) - { - str->append(','); - print_args(str, 0, query_type); - } - str->append(')'); -} - - String *Item_func_char::val_str(String *str) { DBUG_ASSERT(fixed == 1); @@ -4497,11 +4442,16 @@ null: void Item_dyncol_get::print(String *str, enum_query_type query_type) { + /* see create_func_dyncol_get */ + DBUG_ASSERT(str->length() >= 5); + DBUG_ASSERT(strncmp(str->ptr() + str->length() - 5, "cast(", 5) == 0); + + str->length(str->length() - 5); // removing "cast(" str->append(STRING_WITH_LEN("column_get(")); args[0]->print(str, query_type); str->append(','); args[1]->print(str, query_type); - str->append(')'); + /* let the parent cast item add " as <type>)" */ } diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 3f2de5fd6f1..13c1a399230 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -544,31 +544,13 @@ public: class Item_func_make_set :public Item_str_func { - Item *item; String tmp_str; public: - Item_func_make_set(Item *a,List<Item> &list) :Item_str_func(list),item(a) {} + Item_func_make_set(List<Item> &list) :Item_str_func(list) {} String *val_str(String *str); - bool fix_fields(THD *thd, Item **ref) - { - DBUG_ASSERT(fixed == 0); - return ((!item->fixed && item->fix_fields(thd, &item)) || - item->check_cols(1) || - Item_func::fix_fields(thd, ref)); - } - void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields); void fix_length_and_dec(); - void update_used_tables(); const char *func_name() const { return "make_set"; } - - bool walk(Item_processor processor, bool walk_subquery, uchar *arg) - { - return item->walk(processor, walk_subquery, arg) || - Item_str_func::walk(processor, walk_subquery, arg); - } - Item *transform(Item_transformer transformer, uchar *arg); - virtual void print(String *str, enum_query_type query_type); }; diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 72e0e637d38..224c6e7b857 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1581,9 +1581,10 @@ void Item_sum_avg::fix_length_and_dec() f_scale= args[0]->decimals; dec_bin_size= my_decimal_get_binary_size(f_precision, f_scale); } - else { + else + { decimals= min(args[0]->decimals + prec_increment, NOT_FIXED_DEC); - max_length= args[0]->max_length + prec_increment; + max_length= min(args[0]->max_length + prec_increment, float_length(decimals)); } } diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 02a7b8511af..69a6dac5381 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -923,16 +923,14 @@ longlong Item_func_dayofmonth::val_int() { DBUG_ASSERT(fixed == 1); MYSQL_TIME ltime; - (void) get_arg0_date(<ime, TIME_FUZZY_DATE); - return (longlong) ltime.day; + return get_arg0_date(<ime, TIME_FUZZY_DATE) ? 0 : (longlong) ltime.day; } longlong Item_func_month::val_int() { DBUG_ASSERT(fixed == 1); MYSQL_TIME ltime; - (void) get_arg0_date(<ime, TIME_FUZZY_DATE); - return (longlong) ltime.month; + return get_arg0_date(<ime, TIME_FUZZY_DATE) ? 0 : (longlong) ltime.month; } @@ -983,16 +981,14 @@ longlong Item_func_hour::val_int() { DBUG_ASSERT(fixed == 1); MYSQL_TIME ltime; - (void) get_arg0_time(<ime); - return ltime.hour; + return get_arg0_time(<ime) ? 0 : ltime.hour; } longlong Item_func_minute::val_int() { DBUG_ASSERT(fixed == 1); MYSQL_TIME ltime; - (void) get_arg0_time(<ime); - return ltime.minute; + return get_arg0_time(<ime) ? 0 : ltime.minute; } /** @@ -1002,8 +998,7 @@ longlong Item_func_second::val_int() { DBUG_ASSERT(fixed == 1); MYSQL_TIME ltime; - (void) get_arg0_time(<ime); - return ltime.second; + return get_arg0_time(<ime) ? 0 : ltime.second; } @@ -1120,8 +1115,7 @@ longlong Item_func_year::val_int() { DBUG_ASSERT(fixed == 1); MYSQL_TIME ltime; - (void) get_arg0_date(<ime, TIME_FUZZY_DATE); - return (longlong) ltime.year; + return get_arg0_date(<ime, TIME_FUZZY_DATE) ? 0 : (longlong) ltime.year; } diff --git a/sql/spatial.cc b/sql/spatial.cc index 267e038c5b8..2359f4fa271 100644 --- a/sql/spatial.cc +++ b/sql/spatial.cc @@ -312,6 +312,9 @@ bool Geometry::envelope(String *result) const const char *end; if (get_mbr(&mbr, &end)) + return 1; + + if (!mbr.valid()) { /* Empty geometry */ if (result->reserve(1 + 4*2)) @@ -444,18 +447,19 @@ const char *Geometry::append_points(String *txt, uint32 n_points, const char *Geometry::get_mbr_for_points(MBR *mbr, const char *data, uint offset) const { - uint32 points; + uint32 n_points; /* read number of points */ if (no_data(data, 4)) return 0; - points= uint4korr(data); + n_points= uint4korr(data); data+= 4; - if (no_data(data, (POINT_DATA_SIZE + offset) * points)) + if (n_points > max_n_points || + no_data(data, (POINT_DATA_SIZE + offset) * n_points)) return 0; /* Calculate MBR for points */ - while (points--) + while (n_points--) { data+= offset; mbr->add_xy(data, data + SIZEOF_STORED_DOUBLE); @@ -559,9 +563,12 @@ const Geometry::Class_info *Gis_point::get_class_info() const uint32 Gis_line_string::get_data_size() const { - if (no_data(m_data, 4)) + uint32 n_points, size; + if (no_data(m_data, 4) || + (n_points= uint4korr(m_data)) > max_n_points || + no_data(m_data, (size= 4 + n_points * POINT_DATA_SIZE))) return GET_SIZE_ERROR; - return 4 + uint4korr(m_data) * POINT_DATA_SIZE; + return size; } @@ -754,6 +761,9 @@ int Gis_line_string::end_point(String *result) const if (no_data(m_data, 4)) return 1; n_points= uint4korr(m_data); + if (n_points == 0 || n_points > max_n_points || + no_data(m_data, POINT_DATA_SIZE * n_points)) + return 1; return create_point(result, m_data + 4 + (n_points - 1) * POINT_DATA_SIZE); } @@ -763,11 +773,14 @@ int Gis_line_string::point_n(uint32 num, String *result) const uint32 n_points; if (no_data(m_data, 4)) return 1; + num--; n_points= uint4korr(m_data); - if ((uint32) (num - 1) >= n_points) // means (num > n_points || num < 1) + if (num >= n_points || + num > max_n_points || // means (num > n_points || num < 1) + no_data(m_data, num * POINT_DATA_SIZE)) return 1; - return create_point(result, m_data + 4 + (num - 1) * POINT_DATA_SIZE); + return create_point(result, m_data + 4 + num*POINT_DATA_SIZE); } @@ -817,6 +830,7 @@ const Geometry::Class_info *Gis_line_string::get_class_info() const uint32 Gis_polygon::get_data_size() const { uint32 n_linear_rings; + uint32 n_points; const char *data= m_data; if (no_data(data, 4)) @@ -826,10 +840,13 @@ uint32 Gis_polygon::get_data_size() const while (n_linear_rings--) { - if (no_data(data, 4)) + if (no_data(data, 4) || + (n_points= uint4korr(data)) > max_n_points) return GET_SIZE_ERROR; - data+= 4 + uint4korr(data)*POINT_DATA_SIZE; + data+= 4 + n_points*POINT_DATA_SIZE; } + if (no_data(data, 0)) + return GET_SIZE_ERROR; return (uint32) (data - m_data); } @@ -1022,7 +1039,8 @@ int Gis_polygon::area(double *ar, const char **end_of_data) const if (no_data(data, 4)) return 1; n_points= uint4korr(data); - if (n_points > max_n_points || no_data(data, POINT_DATA_SIZE * n_points)) + if (n_points == 0 || n_points > max_n_points || + no_data(data, POINT_DATA_SIZE * n_points)) return 1; get_point(&prev_x, &prev_y, data+4); data+= (4+POINT_DATA_SIZE); @@ -1126,13 +1144,11 @@ int Gis_polygon::centroid_xy(double *x, double *y) const const char *data= m_data; bool first_loop= 1; - if (no_data(data, 4)) + if (no_data(data, 4) || + (n_linear_rings= uint4korr(data)) == 0) return 1; - n_linear_rings= uint4korr(data); data+= 4; - DBUG_ASSERT(n_linear_rings > 0); - while (n_linear_rings--) { uint32 n_points, org_n_points; @@ -1145,7 +1161,8 @@ int Gis_polygon::centroid_xy(double *x, double *y) const return 1; org_n_points= n_points= uint4korr(data); data+= 4; - if (n_points > max_n_points || no_data(data, POINT_DATA_SIZE * n_points)) + if (n_points == 0 || n_points > max_n_points || + no_data(data, POINT_DATA_SIZE * n_points)) return 1; get_point(&prev_x, &prev_y, data); data+= POINT_DATA_SIZE; @@ -1273,9 +1290,14 @@ const Geometry::Class_info *Gis_polygon::get_class_info() const uint32 Gis_multi_point::get_data_size() const { - if (no_data(m_data, 4)) - return GET_SIZE_ERROR; - return 4 + uint4korr(m_data)*(POINT_DATA_SIZE + WKB_HEADER_SIZE); + uint32 n_points; + uint32 size; + + if (no_data(m_data, 4) || + (n_points= uint4korr(m_data)) > max_n_points || + no_data(m_data, (size= 4 + n_points*(POINT_DATA_SIZE + WKB_HEADER_SIZE)))) + return GET_SIZE_ERROR; + return size; } @@ -1369,8 +1391,8 @@ bool Gis_multi_point::get_data_as_wkt(String *txt, const char **end) const return 1; n_points= uint4korr(m_data); - if (no_data(m_data+4, - n_points * (POINT_DATA_SIZE + WKB_HEADER_SIZE)) || + if (n_points > max_n_points || + no_data(m_data+4, n_points * (POINT_DATA_SIZE + WKB_HEADER_SIZE)) || txt->reserve(((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points)) return 1; *end= append_points(txt, n_points, m_data+4, WKB_HEADER_SIZE); @@ -1451,6 +1473,7 @@ const Geometry::Class_info *Gis_multi_point::get_class_info() const uint32 Gis_multi_line_string::get_data_size() const { uint32 n_line_strings; + uint32 n_points; const char *data= m_data; if (no_data(data, 4)) @@ -1460,11 +1483,13 @@ uint32 Gis_multi_line_string::get_data_size() const while (n_line_strings--) { - if (no_data(data, WKB_HEADER_SIZE + 4)) + if (no_data(data, WKB_HEADER_SIZE + 4) || + (n_points= uint4korr(data + WKB_HEADER_SIZE)) > max_n_points) return GET_SIZE_ERROR; - data+= (WKB_HEADER_SIZE + 4 + uint4korr(data + WKB_HEADER_SIZE) * - POINT_DATA_SIZE); + data+= (WKB_HEADER_SIZE + 4 + n_points*POINT_DATA_SIZE); } + if (no_data(data, 0)) + return GET_SIZE_ERROR; return (uint32) (data - m_data); } @@ -1649,7 +1674,7 @@ int Gis_multi_line_string::geometry_n(uint32 num, String *result) const return 1; n_points= uint4korr(data + WKB_HEADER_SIZE); length= WKB_HEADER_SIZE + 4+ POINT_DATA_SIZE * n_points; - if (no_data(data, length)) + if (n_points > max_n_points || no_data(data, length)) return 1; if (!--num) break; @@ -1760,6 +1785,7 @@ const Geometry::Class_info *Gis_multi_line_string::get_class_info() const uint32 Gis_multi_polygon::get_data_size() const { uint32 n_polygons; + uint32 n_points; const char *data= m_data; if (no_data(data, 4)) @@ -1778,11 +1804,14 @@ uint32 Gis_multi_polygon::get_data_size() const while (n_linear_rings--) { - if (no_data(data, 4)) + if (no_data(data, 4) || + (n_points= uint4korr(data)) > max_n_points) return GET_SIZE_ERROR; - data+= 4 + uint4korr(data) * POINT_DATA_SIZE; + data+= 4 + n_points * POINT_DATA_SIZE; } } + if (no_data(data, 0)) + return GET_SIZE_ERROR; return (uint32) (data - m_data); } @@ -2325,7 +2354,7 @@ bool Gis_geometry_collection::get_mbr(MBR *mbr, const char **end) const n_objects= uint4korr(data); data+= 4; if (n_objects == 0) - return 1; + goto exit; while (n_objects--) { @@ -2342,6 +2371,7 @@ bool Gis_geometry_collection::get_mbr(MBR *mbr, const char **end) const if (geom->get_mbr(mbr, &data)) return 1; } +exit: *end= data; return 0; } @@ -2359,10 +2389,11 @@ int Gis_geometry_collection::area(double *ar, const char **end) const return 1; n_objects= uint4korr(data); data+= 4; - if (n_objects == 0) - return 1; result= 0.0; + if (n_objects == 0) + goto exit; + while (n_objects--) { uint32 wkb_type; @@ -2379,6 +2410,7 @@ int Gis_geometry_collection::area(double *ar, const char **end) const return 1; result+= *ar; } +exit: *end= data; *ar= result; return 0; @@ -2397,10 +2429,11 @@ int Gis_geometry_collection::geom_length(double *len, const char **end) const return 1; n_objects= uint4korr(data); data+= 4; + result= 0.0; + if (n_objects == 0) - return 1; + goto exit; - result= 0.0; while (n_objects--) { uint32 wkb_type; @@ -2417,6 +2450,8 @@ int Gis_geometry_collection::geom_length(double *len, const char **end) const return 1; result+= *len; } + +exit: *end= data; *len= result; return 0; diff --git a/sql/spatial.h b/sql/spatial.h index f55d1ccba8e..9aaedfe8a20 100644 --- a/sql/spatial.h +++ b/sql/spatial.h @@ -200,6 +200,9 @@ struct MBR return (d == intersection.dimension()); } + + int valid() const + { return xmin <= xmax && ymin <= ymax; } }; @@ -212,7 +215,7 @@ class Geometry public: // Maximum number of points in feature that can fit into String static const uint32 max_n_points= - (uint32) (UINT_MAX32 - WKB_HEADER_SIZE - 4 /* n_points */) / + (uint32) (INT_MAX32 - WKB_HEADER_SIZE - 4 /* n_points */) / POINT_DATA_SIZE; Geometry() {} /* Remove gcc warning */ diff --git a/sql/sql_select.cc b/sql/sql_select.cc index e1397b05bff..73759c9a0ce 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -14076,6 +14076,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, } case Item::FIELD_ITEM: case Item::DEFAULT_VALUE_ITEM: + case Item::INSERT_VALUE_ITEM: { Item_field *field= (Item_field*) item; bool orig_modify= modify_item; |