diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/field.cc | 7 | ||||
-rw-r--r-- | sql/item.cc | 1 | ||||
-rw-r--r-- | sql/item_create.cc | 24 | ||||
-rw-r--r-- | sql/item_func.cc | 37 | ||||
-rw-r--r-- | sql/item_func.h | 15 | ||||
-rw-r--r-- | sql/mysql_priv.h | 2 | ||||
-rw-r--r-- | sql/mysqld.cc | 6 |
7 files changed, 90 insertions, 2 deletions
diff --git a/sql/field.cc b/sql/field.cc index e8718c9e407..5624294d012 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -6195,9 +6195,14 @@ String *Field_string::val_str(String *val_buffer __attribute__((unused)), String *val_ptr) { ASSERT_COLUMN_MARKED_FOR_READ; - uint length= field_charset->cset->lengthsp(field_charset, ptr, field_length); /* See the comment for Field_long::store(long long) */ DBUG_ASSERT(table->in_use == current_thd); + uint length; + if (table->in_use->variables.sql_mode & + MODE_PAD_CHAR_TO_FULL_LENGTH) + length= my_charpos(field_charset, ptr, ptr + field_length, field_length); + else + length= field_charset->cset->lengthsp(field_charset, ptr, field_length); val_ptr->set((const char*) ptr, length, field_charset); return val_ptr; } diff --git a/sql/item.cc b/sql/item.cc index f339bad78e4..3f4751a4753 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -161,6 +161,7 @@ Hybrid_type_traits_integer::fix_length_and_dec(Item *item, Item *arg) const void item_init(void) { item_user_lock_init(); + uuid_short_init(); } diff --git a/sql/item_create.cc b/sql/item_create.cc index 8ff78ef1b48..8c97b596336 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -2141,6 +2141,19 @@ protected: }; +class Create_func_uuid_short : public Create_func_arg0 +{ +public: + virtual Item *create(THD *thd); + + static Create_func_uuid_short s_singleton; + +protected: + Create_func_uuid_short() {} + virtual ~Create_func_uuid_short() {} +}; + + class Create_func_version : public Create_func_arg0 { public: @@ -4532,6 +4545,16 @@ Create_func_uuid::create(THD *thd) } +Create_func_uuid_short Create_func_uuid_short::s_singleton; + +Item* +Create_func_uuid_short::create(THD *thd) +{ + thd->lex->binlog_row_based_if_mixed= TRUE; + return new (thd->mem_root) Item_func_uuid_short(); +} + + Create_func_version Create_func_version::s_singleton; Item* @@ -4871,6 +4894,7 @@ static Native_func_registry func_array[] = { C_STRING_WITH_LEN("UPDATEXML"), BUILDER(Create_func_xml_update)}, { C_STRING_WITH_LEN("UPPER"), BUILDER(Create_func_ucase)}, { C_STRING_WITH_LEN("UUID"), BUILDER(Create_func_uuid)}, + { C_STRING_WITH_LEN("UUID_SHORT"), BUILDER(Create_func_uuid_short)}, { C_STRING_WITH_LEN("VERSION"), BUILDER(Create_func_version)}, { C_STRING_WITH_LEN("WEEKDAY"), BUILDER(Create_func_weekday)}, { C_STRING_WITH_LEN("WEEKOFYEAR"), BUILDER(Create_func_weekofyear)}, diff --git a/sql/item_func.cc b/sql/item_func.cc index 732c4403ca2..ab57b047201 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -5399,3 +5399,40 @@ Item_func_sp::fix_fields(THD *thd, Item **ref) } DBUG_RETURN(res); } + + +/* + uuid_short handling. + + The short uuid is defined as a longlong that contains the following bytes: + + Bytes Comment + 1 Server_id & 255 + 4 Startup time of server in seconds + 3 Incrementor + + This means that an uuid is guaranteed to be unique + even in a replication environment if the following holds: + + - The last byte of the server id is unique + - If you between two shutdown of the server don't get more than + an average of 2^24 = 16M calls to uuid_short() per second. +*/ + +ulonglong uuid_value; + +void uuid_short_init() +{ + uuid_value= (((ulonglong) server_id << 56) + + (ulonglong) server_start_time << 24); +} + + +longlong Item_func_uuid_short::val_int() +{ + ulonglong val; + pthread_mutex_lock(&LOCK_uuid_generator); + val= uuid_value++; + pthread_mutex_unlock(&LOCK_uuid_generator); + return (longlong) val; +} diff --git a/sql/item_func.h b/sql/item_func.h index 6457013b160..21dce696d61 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1551,3 +1551,18 @@ public: const char *func_name() const { return "found_rows"; } void fix_length_and_dec() { decimals= 0; maybe_null=0; } }; + + +void uuid_short_init(); + +class Item_func_uuid_short :public Item_int_func +{ +public: + Item_func_uuid_short() :Item_int_func() {} + const char *func_name() const { return "uuid_short"; } + longlong val_int(); + void fix_length_and_dec() + { max_length= 21; unsigned_flag=1; } + bool check_partition_func_processor(byte *int_arg) {return FALSE;} +}; + diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 93f290b12e7..ffe180fd474 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -399,6 +399,8 @@ MY_LOCALE *my_locale_by_number(uint number); #define MODE_NO_AUTO_CREATE_USER (MODE_TRADITIONAL*2) #define MODE_HIGH_NOT_PRECEDENCE (MODE_NO_AUTO_CREATE_USER*2) #define MODE_NO_ENGINE_SUBSTITUTION (MODE_HIGH_NOT_PRECEDENCE*2) +#define MODE_PAD_CHAR_TO_FULL_LENGTH (MODE_NO_ENGINE_SUBSTITUTION*2) + /* Replication uses 8 bytes to store SQL_MODE in the binary log. The day you use strictly more than 64 bits by adding one more define above, you should diff --git a/sql/mysqld.cc b/sql/mysqld.cc index d6efebd32c4..796dc72a98d 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -225,8 +225,10 @@ static const char *sql_mode_names[]= "ERROR_FOR_DIVISION_BY_ZERO", "TRADITIONAL", "NO_AUTO_CREATE_USER", "HIGH_NOT_PRECEDENCE", "NO_ENGINE_SUBSTITUTION", + "PAD_CHAR_TO_FULL_LENGTH", NullS }; + static const unsigned int sql_mode_names_len[]= { /*REAL_AS_FLOAT*/ 13, @@ -259,8 +261,10 @@ static const unsigned int sql_mode_names_len[]= /*TRADITIONAL*/ 11, /*NO_AUTO_CREATE_USER*/ 19, /*HIGH_NOT_PRECEDENCE*/ 19, - /*NO_ENGINE_SUBSTITUTION*/ 22 + /*NO_ENGINE_SUBSTITUTION*/ 22, + /*PAD_CHAR_TO_FULL_LENGTH*/ 23 }; + TYPELIB sql_mode_typelib= { array_elements(sql_mode_names)-1,"", sql_mode_names, (unsigned int *)sql_mode_names_len }; |