summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/field.cc7
-rw-r--r--sql/item.cc1
-rw-r--r--sql/item_create.cc24
-rw-r--r--sql/item_func.cc37
-rw-r--r--sql/item_func.h15
-rw-r--r--sql/mysql_priv.h2
-rw-r--r--sql/mysqld.cc6
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 };