diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/field.cc | 14 | ||||
-rw-r--r-- | sql/item_func.cc | 33 | ||||
-rw-r--r-- | sql/log_event.cc | 15 | ||||
-rw-r--r-- | sql/mysqld.cc | 6 | ||||
-rw-r--r-- | sql/rpl_gtid.cc | 4 | ||||
-rw-r--r-- | sql/spatial.cc | 92 | ||||
-rw-r--r-- | sql/spatial.h | 7 | ||||
-rw-r--r-- | sql/sql_class.h | 6 | ||||
-rw-r--r-- | sql/sql_type_int.h | 20 |
9 files changed, 147 insertions, 50 deletions
diff --git a/sql/field.cc b/sql/field.cc index 3a9b2257748..196041c979e 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2017, Oracle and/or its affiliates. - Copyright (c) 2008, 2019, MariaDB + Copyright (c) 2008, 2020, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -9033,18 +9033,26 @@ int Field_geom::store(const char *from, size_t length, CHARSET_INFO *cs) { const char *db= table->s->db.str; const char *tab_name= table->s->table_name.str; + Geometry_buffer buffer; + Geometry *geom= NULL; + String wkt; + const char *dummy; if (!db) db= ""; if (!tab_name) tab_name= ""; + wkt.set_charset(&my_charset_latin1); + if (!(geom= Geometry::construct(&buffer, from, length)) || + geom->as_wkt(&wkt, &dummy)) + goto err; my_error(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, MYF(0), Geometry::ci_collection[geom_type]->m_name.str, - Geometry::ci_collection[wkb_type]->m_name.str, - db, tab_name, field_name.str, + wkt.c_ptr(), db, tab_name, field_name.str, (ulong) table->in_use->get_stmt_da()-> current_row_for_warning()); + goto err_exit; } diff --git a/sql/item_func.cc b/sql/item_func.cc index e7be4211d19..007f63ed90e 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1740,11 +1740,9 @@ longlong Item_func_int_div::val_int() raise_integer_overflow(); return res; } - - longlong val0=args[0]->val_int(); - longlong val1=args[1]->val_int(); - bool val0_negative, val1_negative, res_negative; - ulonglong uval0, uval1, res; + + Longlong_hybrid val0= args[0]->to_longlong_hybrid(); + Longlong_hybrid val1= args[1]->to_longlong_hybrid(); if ((null_value= (args[0]->null_value || args[1]->null_value))) return 0; if (val1 == 0) @@ -1753,12 +1751,8 @@ longlong Item_func_int_div::val_int() return 0; } - val0_negative= !args[0]->unsigned_flag && val0 < 0; - val1_negative= !args[1]->unsigned_flag && val1 < 0; - res_negative= val0_negative != val1_negative; - uval0= (ulonglong) (val0_negative ? -val0 : val0); - uval1= (ulonglong) (val1_negative ? -val1 : val1); - res= uval0 / uval1; + bool res_negative= val0.neg() != val1.neg(); + ulonglong res= val0.abs() / val1.abs(); if (res_negative) { if (res > (ulonglong) LONGLONG_MAX) @@ -1783,11 +1777,8 @@ bool Item_func_int_div::fix_length_and_dec() longlong Item_func_mod::int_op() { DBUG_ASSERT(fixed == 1); - longlong val0= args[0]->val_int(); - longlong val1= args[1]->val_int(); - bool val0_negative, val1_negative; - ulonglong uval0, uval1; - ulonglong res; + Longlong_hybrid val0= args[0]->to_longlong_hybrid(); + Longlong_hybrid val1= args[1]->to_longlong_hybrid(); if ((null_value= args[0]->null_value || args[1]->null_value)) return 0; /* purecov: inspected */ @@ -1802,13 +1793,9 @@ longlong Item_func_mod::int_op() LONGLONG_MIN by -1 generates SIGFPE, we calculate using unsigned values and then adjust the sign appropriately. */ - val0_negative= !args[0]->unsigned_flag && val0 < 0; - val1_negative= !args[1]->unsigned_flag && val1 < 0; - uval0= (ulonglong) (val0_negative ? -val0 : val0); - uval1= (ulonglong) (val1_negative ? -val1 : val1); - res= uval0 % uval1; - return check_integer_overflow(val0_negative ? -(longlong) res : res, - !val0_negative); + ulonglong res= val0.abs() % val1.abs(); + return check_integer_overflow(val0.neg() ? -(longlong) res : res, + !val0.neg()); } double Item_func_mod::real_op() diff --git a/sql/log_event.cc b/sql/log_event.cc index d7113b12743..26939d78343 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2019, Oracle and/or its affiliates. - Copyright (c) 2009, 2019, MariaDB + Copyright (c) 2009, 2020, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -3239,7 +3239,7 @@ void Rows_log_event::change_to_flashback_event(PRINT_EVENT_INFO *print_event_inf Table_map_log_event *map; table_def *td; DYNAMIC_ARRAY rows_arr; - uchar *swap_buff1, *swap_buff2; + uchar *swap_buff1; uchar *rows_pos= rows_buff + m_rows_before_size; if (!(map= print_event_info->m_table_map.get_table(m_table_id)) || @@ -3288,7 +3288,7 @@ void Rows_log_event::change_to_flashback_event(PRINT_EVENT_INFO *print_event_inf } value+= length2; - swap_buff2= (uchar *) my_malloc(length2, MYF(0)); + void *swap_buff2= my_malloc(length2, MYF(0)); if (!swap_buff2) { fprintf(stderr, "\nError: Out of memory. " @@ -3296,21 +3296,14 @@ void Rows_log_event::change_to_flashback_event(PRINT_EVENT_INFO *print_event_inf exit(1); } memcpy(swap_buff2, start_pos + length1, length2); // WHERE part - } - if (ev_type == UPDATE_ROWS_EVENT || - ev_type == UPDATE_ROWS_EVENT_V1) - { /* Swap SET and WHERE part */ memcpy(start_pos, swap_buff2, length2); memcpy(start_pos + length2, swap_buff1, length1); + my_free(swap_buff2); } - /* Free tmp buffers */ my_free(swap_buff1); - if (ev_type == UPDATE_ROWS_EVENT || - ev_type == UPDATE_ROWS_EVENT_V1) - my_free(swap_buff2); /* Copying one row into a buff, and pushing into the array */ LEX_STRING one_row; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 60b87b60be4..5e8fdf2266a 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -8650,9 +8650,9 @@ SHOW_VAR status_vars[]= { {"Key", (char*) &show_default_keycache, SHOW_FUNC}, {"Last_query_cost", (char*) offsetof(STATUS_VAR, last_query_cost), SHOW_DOUBLE_STATUS}, {"Max_statement_time_exceeded", (char*) offsetof(STATUS_VAR, max_statement_time_exceeded), SHOW_LONG_STATUS}, - {"Master_gtid_wait_count", (char*) offsetof(STATUS_VAR, master_gtid_wait_count), SHOW_LONGLONG_STATUS}, - {"Master_gtid_wait_timeouts", (char*) offsetof(STATUS_VAR, master_gtid_wait_timeouts), SHOW_LONGLONG_STATUS}, - {"Master_gtid_wait_time", (char*) offsetof(STATUS_VAR, master_gtid_wait_time), SHOW_LONGLONG_STATUS}, + {"Master_gtid_wait_count", (char*) offsetof(STATUS_VAR, master_gtid_wait_count), SHOW_LONG_STATUS}, + {"Master_gtid_wait_timeouts", (char*) offsetof(STATUS_VAR, master_gtid_wait_timeouts), SHOW_LONG_STATUS}, + {"Master_gtid_wait_time", (char*) offsetof(STATUS_VAR, master_gtid_wait_time), SHOW_LONG_STATUS}, {"Max_used_connections", (char*) &max_used_connections, SHOW_LONG}, {"Memory_used", (char*) &show_memory_used, SHOW_SIMPLE_FUNC}, {"Memory_used_initial", (char*) &start_memory_used, SHOW_LONGLONG}, diff --git a/sql/rpl_gtid.cc b/sql/rpl_gtid.cc index b34942ba091..a8b39d6d15b 100644 --- a/sql/rpl_gtid.cc +++ b/sql/rpl_gtid.cc @@ -1,4 +1,5 @@ /* Copyright (c) 2013, Kristian Nielsen and MariaDB Services Ab. + Copyright (c) 2020, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -2432,7 +2433,8 @@ gtid_waiting::wait_for_pos(THD *thd, String *gtid_str, longlong timeout_us) /* fall through */ case 0: status_var_add(thd->status_var.master_gtid_wait_time, - microsecond_interval_timer() - before); + static_cast<ulong> + (microsecond_interval_timer() - before)); } my_free(wait_pos); return err; diff --git a/sql/spatial.cc b/sql/spatial.cc index bba9ae45f58..2b36468e158 100644 --- a/sql/spatial.cc +++ b/sql/spatial.cc @@ -50,6 +50,98 @@ double my_double_round(double value, longlong dec, bool dec_unsigned, #define MAX_DIGITS_IN_DOUBLE MY_GCVT_MAX_FIELD_WIDTH +int MBR::within(const MBR *mbr) +{ + /* + We have to take into account the 'dimension' of + the MBR, where the dimension of a single point is 0, + the dimesion of an vertical or horizontal line is 1, + and finally the dimension of the solid rectangle is 2. + */ + + int dim1= dimension(); + int dim2= mbr->dimension(); + + DBUG_ASSERT(dim1 >= 0 && dim1 <= 2 && dim2 >= 0 && dim2 <= 2); + + /* + Either/both of the two operands can degrade to a point or a + horizontal/vertical line segment, and we have to treat such cases + separately. + */ + switch (dim1) + { + case 0: + DBUG_ASSERT(xmin == xmax && ymin == ymax); + switch (dim2) + { + case 0: + DBUG_ASSERT(mbr->xmin == mbr->xmax && mbr->ymin == mbr->ymax); + return equals(mbr); + break; + case 1: + DBUG_ASSERT((mbr->xmin == mbr->xmax && mbr->ymin != mbr->ymax) || + (mbr->ymin == mbr->ymax && mbr->xmin != mbr->xmax)); + return ((xmin > mbr->xmin && xmin < mbr->xmax && ymin == mbr->ymin) || + (ymin > mbr->ymin && ymin < mbr->ymax && xmin == mbr->xmin)); + break; + case 2: + DBUG_ASSERT(mbr->xmin != mbr->xmax && mbr->ymin != mbr->ymax); + return (xmin > mbr->xmin && xmax < mbr->xmax && + ymin > mbr->ymin && ymax < mbr->ymax); + break; + } + break; + case 1: + DBUG_ASSERT((xmin == xmax && ymin != ymax) || + (ymin == ymax && xmin != xmax)); + switch (dim2) + { + case 0: + DBUG_ASSERT(mbr->xmin == mbr->xmax && mbr->ymin == mbr->ymax); + return 0; + break; + case 1: + DBUG_ASSERT((mbr->xmin == mbr->xmax && mbr->ymin != mbr->ymax) || + (mbr->ymin == mbr->ymax && mbr->xmin != mbr->xmax)); + return ((xmin == xmax && mbr->xmin == mbr->xmax && mbr->xmin == xmin && + mbr->ymin <= ymin && mbr->ymax >= ymax) || + (ymin == ymax && mbr->ymin == mbr->ymax && mbr->ymin == ymin && + mbr->xmin <= xmin && mbr->xmax >= xmax)); + break; + case 2: + DBUG_ASSERT(mbr->xmin != mbr->xmax && mbr->ymin != mbr->ymax); + return ((xmin == xmax && xmin > mbr->xmin && xmax < mbr->xmax && + ymin >= mbr->ymin && ymax <= mbr->ymax) || + (ymin == ymax && ymin > mbr->ymin && ymax < mbr->ymax && + xmin >= mbr->xmin && xmax <= mbr->xmax)); + break; + } + break; + case 2: + DBUG_ASSERT(xmin != xmax && ymin != ymax); + switch (dim2) + { + case 0: + case 1: + return 0; + break; + case 2: + DBUG_ASSERT(mbr->xmin != mbr->xmax && mbr->ymin != mbr->ymax); + return ((mbr->xmin <= xmin) && (mbr->ymin <= ymin) && + (mbr->xmax >= xmax) && (mbr->ymax >= ymax)); + break; + + } + break; + } + + // Never reached. + DBUG_ASSERT(false); + return 0; +} + + /***************************** Gis_class_info *******************************/ String Geometry::bad_geometry_data("Bad object", &my_charset_bin); diff --git a/sql/spatial.h b/sql/spatial.h index fa4e40b5aa5..55f450b1b1b 100644 --- a/sql/spatial.h +++ b/sql/spatial.h @@ -145,12 +145,7 @@ struct MBR (mbr->xmax >= xmin && mbr->xmax <= xmax))); } - int within(const MBR *mbr) - { - /* The following should be safe, even if we compare doubles */ - return ((mbr->xmin <= xmin) && (mbr->ymin <= ymin) && - (mbr->xmax >= xmax) && (mbr->ymax >= ymax)); - } + int within(const MBR *mbr); int contains(const MBR *mbr) { diff --git a/sql/sql_class.h b/sql/sql_class.h index 6bec4dafd74..cce6a0783ac 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -842,9 +842,9 @@ typedef struct system_status_var ulong feature_window_functions; /* +1 when window functions are used */ /* From MASTER_GTID_WAIT usage */ - ulonglong master_gtid_wait_timeouts; /* Number of timeouts */ - ulonglong master_gtid_wait_time; /* Time in microseconds */ - ulonglong master_gtid_wait_count; + ulong master_gtid_wait_timeouts; /* Number of timeouts */ + ulong master_gtid_wait_time; /* Time in microseconds */ + ulong master_gtid_wait_count; ulong empty_queries; ulong access_denied_errors; diff --git a/sql/sql_type_int.h b/sql/sql_type_int.h index e43d9b4398c..3e5e6a345fa 100644 --- a/sql/sql_type_int.h +++ b/sql/sql_type_int.h @@ -83,6 +83,26 @@ public: */ return cmp_signed(other); } + bool operator==(const Longlong_hybrid &nr) const + { + return cmp(nr) == 0; + } + bool operator==(ulonglong nr) const + { + return cmp(Longlong_hybrid((longlong) nr, true)) == 0; + } + bool operator==(uint nr) const + { + return cmp(Longlong_hybrid((longlong) nr, true)) == 0; + } + bool operator==(longlong nr) const + { + return cmp(Longlong_hybrid(nr, false)) == 0; + } + bool operator==(int nr) const + { + return cmp(Longlong_hybrid(nr, false)) == 0; + } }; #endif // SQL_TYPE_INT_INCLUDED |