summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <serg@serg.mylan>2004-02-27 20:30:08 +0100
committerunknown <serg@serg.mylan>2004-02-27 20:30:08 +0100
commit83c04153bc02af520925a290f95b163ed047ffdb (patch)
treed0f8d063fcdfa4d4c0549be6ee8d1a3d49393175 /sql
parent4e468f66cc48c1ede186103594fb8a4a00ce010e (diff)
downloadmariadb-git-83c04153bc02af520925a290f95b163ed047ffdb.tar.gz
my_gethwaddr() for linux/freebsd
UUID() function BitKeeper/etc/ignore: Added mysys/test_gethwaddr to the ignore list include/my_sys.h: my_gethwaddr() mysys/Makefile.am: my_gethwaddr sql/item_create.cc: UUID() function sql/item_create.h: UUID() function sql/item_strfunc.cc: UUID() function sql/item_strfunc.h: UUID() function sql/lex.h: UUID() function sql/mysql_priv.h: UUID() function sql/mysqld.cc: UUID() function sql/sql_class.cc: cleanup
Diffstat (limited to 'sql')
-rw-r--r--sql/item_create.cc11
-rw-r--r--sql/item_create.h1
-rw-r--r--sql/item_strfunc.cc109
-rw-r--r--sql/item_strfunc.h22
-rw-r--r--sql/lex.h3
-rw-r--r--sql/mysql_priv.h12
-rw-r--r--sql/mysqld.cc3
-rw-r--r--sql/sql_class.cc8
8 files changed, 149 insertions, 20 deletions
diff --git a/sql/item_create.cc b/sql/item_create.cc
index 4ed8182305d..eda3d43afdc 100644
--- a/sql/item_create.cc
+++ b/sql/item_create.cc
@@ -34,14 +34,14 @@ Item *create_func_acos(Item* a)
Item *create_func_aes_encrypt(Item* a, Item* b)
{
- return new Item_func_aes_encrypt(a, b);
+ return new Item_func_aes_encrypt(a, b);
}
-
+
Item *create_func_aes_decrypt(Item* a, Item* b)
{
return new Item_func_aes_decrypt(a, b);
}
-
+
Item *create_func_ascii(Item* a)
{
return new Item_func_ascii(a);
@@ -426,6 +426,11 @@ Item *create_func_ucase(Item* a)
return new Item_func_ucase(a);
}
+Item *create_func_uuid(void)
+{
+ return new Item_func_uuid();
+}
+
Item *create_func_version(void)
{
return new Item_string(NullS,server_version,
diff --git a/sql/item_create.h b/sql/item_create.h
index 773fdffbaf2..a6a3c9e1841 100644
--- a/sql/item_create.h
+++ b/sql/item_create.h
@@ -92,6 +92,7 @@ Item *create_func_time_format(Item *a, Item *b);
Item *create_func_time_to_sec(Item* a);
Item *create_func_to_days(Item* a);
Item *create_func_ucase(Item* a);
+Item *create_func_uuid(void);
Item *create_func_version(void);
Item *create_func_weekday(Item* a);
Item *create_load_file(Item* a);
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index ed6e44262c7..bd21e38479c 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -2632,3 +2632,112 @@ err:
return 0;
}
#endif
+
+/*
+ UUID, as in
+ DCE 1.1: Remote Procedure Call,
+ Open Group Technical Standard Document Number C706, August 1997,
+ (supersedes C309 DCE: Remote Procedure Call 8/1994,
+ which was basis for ISO/IEC 11578:1996 specification)
+*/
+
+static struct rand_struct uuid_rand;
+static uint nanoseq;
+static ulonglong uuid_time=0;
+static char clock_seq_and_node_str[]="-0000-000000000000";
+
+/* we cannot use _dig_vec[] as letters should be lowercase */
+static const char hex[] = "0123456789abcdef";
+
+/* number of 100-nanosecond intervals between
+ 1582-10-15 00:00:00.00 and 1970-01-01 00:00:00.00 */
+#define UUID_TIME_OFFSET ((ulonglong) 141427 * 24 * 60 * 60 * 1000 * 10 )
+
+#define UUID_VERSION 0x1000
+#define UUID_VARIANT 0x8000
+
+static ulonglong get_uuid_time()
+{
+ struct timeval tv;
+ gettimeofday(&tv,NULL);
+ return (ulonglong)tv.tv_sec*10000000 +
+ (ulonglong)tv.tv_usec*10 + UUID_TIME_OFFSET + nanoseq;
+}
+
+static void tohex(char *to, uint from, uint len)
+{
+ to+= len;
+ while (len--)
+ {
+ *--to= hex[from & 15];
+ from >>= 4;
+ }
+}
+
+static void set_clock_seq_str()
+{
+ uint16 clock_seq= ((uint)(my_rnd(&uuid_rand)*16383)) | UUID_VARIANT;
+ tohex(clock_seq_and_node_str+1, clock_seq, 4);
+ nanoseq= 0;
+}
+
+String *Item_func_uuid::val_str(String *str)
+{
+ char *s;
+ pthread_mutex_lock(&LOCK_uuid_generator);
+ if (! uuid_time) /* first UUID() call. initializing data */
+ {
+ ulong tmp=sql_rnd_with_mutex();
+ uchar mac[6];
+ int i;
+ if (my_gethwaddr(mac))
+ {
+ /*
+ generating random "hardware addr"
+ and because specs explicitly specify that it should NOT correlate
+ with a clock_seq value (initialized random below), we use a separate
+ randominit() here
+ */
+ randominit(&uuid_rand, tmp + (ulong)current_thd, tmp + query_id);
+ for (i=0; i < sizeof(mac); i++)
+ mac[i]=(uchar)(my_rnd(&uuid_rand)*255);
+ }
+ s=clock_seq_and_node_str+sizeof(clock_seq_and_node_str)-1;
+ for (i=sizeof(mac)-1 ; i>=0 ; i--)
+ {
+ *--s=hex[mac[i] & 15];
+ *--s=hex[mac[i] >> 4];
+ }
+ randominit(&uuid_rand, tmp + (ulong)start_time, tmp + bytes_sent);
+ set_clock_seq_str();
+ }
+
+ ulonglong tv=get_uuid_time();
+ if (unlikely(tv < uuid_time))
+ set_clock_seq_str();
+ else
+ if (unlikely(tv == uuid_time))
+ { /* special protection from low-res system clocks */
+ nanoseq++;
+ tv++;
+ }
+ else
+ nanoseq=0;
+ uuid_time=tv;
+ pthread_mutex_unlock(&LOCK_uuid_generator);
+
+ uint32 time_low= tv & 0xFFFFFFFF;
+ uint16 time_mid= (tv >> 32) & 0xFFFF;
+ uint16 time_hi_and_version= (tv >> 48) | UUID_VERSION;
+
+ str->realloc(UUID_LENGTH+1);
+ str->length(UUID_LENGTH);
+ s=(char *) str->ptr();
+ s[8]=s[13]='-';
+ tohex(s, time_low, 8);
+ tohex(s+9, time_mid, 4);
+ tohex(s+14, time_hi_and_version, 4);
+ strmov(s+18, clock_seq_and_node_str);
+ return str;
+}
+
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index 4832ddbd1b1..859983f443d 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -153,7 +153,7 @@ class Item_str_conv :public Item_str_func
public:
Item_str_conv(Item *item) :Item_str_func(item) {}
void fix_length_and_dec()
- {
+ {
collation.set(args[0]->collation);
max_length = args[0]->max_length;
}
@@ -589,10 +589,10 @@ public:
Item_func_quote(Item *a) :Item_str_func(a) {}
const char *func_name() const { return "quote"; }
String *val_str(String *);
- void fix_length_and_dec()
- {
+ void fix_length_and_dec()
+ {
collation.set(args[0]->collation);
- max_length= args[0]->max_length * 2 + 2;
+ max_length= args[0]->max_length * 2 + 2;
}
};
@@ -600,7 +600,7 @@ class Item_func_conv_charset :public Item_str_func
{
CHARSET_INFO *conv_charset;
public:
- Item_func_conv_charset(Item *a, CHARSET_INFO *cs) :Item_str_func(a)
+ Item_func_conv_charset(Item *a, CHARSET_INFO *cs) :Item_str_func(a)
{ conv_charset=cs; }
String *val_str(String *);
void fix_length_and_dec();
@@ -625,7 +625,7 @@ public:
Item_func_charset(Item *a) :Item_str_func(a) {}
String *val_str(String *);
const char *func_name() const { return "charset"; }
- void fix_length_and_dec()
+ void fix_length_and_dec()
{
collation.set(system_charset_info);
max_length= 64 * collation.collation->mbmaxlen; // should be enough
@@ -691,3 +691,13 @@ public:
String *val_str(String *) ZLIB_DEPENDED_FUNCTION
};
+#define UUID_LENGTH (8+1+4+1+4+1+4+1+12)
+class Item_func_uuid: public Item_str_func
+{
+public:
+ Item_func_uuid(): Item_str_func() {}
+ void fix_length_and_dec() {max_length= UUID_LENGTH; }
+ const char *func_name() const{ return "uuid"; }
+ String *val_str(String *);
+};
+
diff --git a/sql/lex.h b/sql/lex.h
index 029a8ac4218..9cdb1067d91 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -654,7 +654,7 @@ static SYMBOL sql_functions[] = {
{ "STDDEV", SYM(STD_SYM)},
{ "STR_TO_DATE", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_str_to_date)},
{ "STRCMP", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_strcmp)},
- { "SUBSTR", SYM(SUBSTRING)},
+ { "SUBSTR", SYM(SUBSTRING)},
{ "SUBSTRING", SYM(SUBSTRING)},
{ "SUBSTRING_INDEX", SYM(SUBSTRING_INDEX)},
{ "SUBTIME", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_subtime)},
@@ -674,6 +674,7 @@ static SYMBOL sql_functions[] = {
{ "UNIQUE_USERS", SYM(UNIQUE_USERS)},
{ "UNIX_TIMESTAMP", SYM(UNIX_TIMESTAMP)},
{ "UPPER", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ucase)},
+ { "UUID", F_SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_uuid)},
{ "VARIANCE", SYM(VARIANCE_SYM)},
{ "VERSION", F_SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_version)},
{ "WEEK", SYM(WEEK_SYM)},
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index f5031f926af..535c1cb16be 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -802,7 +802,7 @@ extern char log_error_file[FN_REFLEN];
extern double log_10[32];
extern ulonglong keybuff_size;
extern ulong refresh_version,flush_version, thread_id,query_id,opened_tables;
-extern ulong created_tmp_tables, created_tmp_disk_tables;
+extern ulong created_tmp_tables, created_tmp_disk_tables, bytes_sent;
extern ulong aborted_threads,aborted_connects;
extern ulong delayed_insert_timeout;
extern ulong delayed_insert_limit, delayed_queue_size;
@@ -857,7 +857,7 @@ extern FILE *bootstrap_file;
extern pthread_key(MEM_ROOT*,THR_MALLOC);
extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open,
LOCK_thread_count,LOCK_mapped_file,LOCK_user_locks, LOCK_status,
- LOCK_error_log, LOCK_delayed_insert,
+ LOCK_error_log, LOCK_delayed_insert, LOCK_uuid_generator,
LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone,
LOCK_slave_list, LOCK_active_mi, LOCK_manager,
LOCK_global_system_variables, LOCK_user_conn;
@@ -1085,6 +1085,14 @@ inline const char *table_case_name(HA_CREATE_INFO *info, const char *name)
return ((lower_case_table_names == 2 && info->alias) ? info->alias : name);
}
+inline ulong sql_rnd_with_mutex()
+{
+ pthread_mutex_lock(&LOCK_thread_count);
+ ulong tmp=(ulong) (my_rnd(&sql_rand) * 0xffffffff); /* make all bits random */
+ pthread_mutex_unlock(&LOCK_thread_count);
+ return tmp;
+}
+
Comp_creator *comp_eq_creator(bool invert);
Comp_creator *comp_ge_creator(bool invert);
Comp_creator *comp_gt_creator(bool invert);
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 634f24203c4..07e07e97781 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -369,7 +369,7 @@ pthread_key(MEM_ROOT*,THR_MALLOC);
pthread_key(THD*, THR_THD);
pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count,
LOCK_mapped_file, LOCK_status,
- LOCK_error_log,
+ LOCK_error_log, LOCK_uuid_generator,
LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create,
LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received,
LOCK_global_system_variables,
@@ -2206,6 +2206,7 @@ static int init_thread_environment()
(void) pthread_mutex_init(&LOCK_user_conn, MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_active_mi, MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_global_system_variables, MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_uuid_generator, MY_MUTEX_INIT_FAST);
(void) my_rwlock_init(&LOCK_sys_init_connect, NULL);
(void) my_rwlock_init(&LOCK_sys_init_slave, NULL);
(void) my_rwlock_init(&LOCK_grant, NULL);
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 9ed604033ab..6fe0521b07a 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -179,14 +179,8 @@ THD::THD():user_time(0), current_statement(0), is_fatal_error(0),
transaction.trans_log.end_of_file= max_binlog_cache_size;
}
#endif
- /*
- We need good random number initialization for new thread
- Just coping global one will not work
- */
{
- pthread_mutex_lock(&LOCK_thread_count);
- ulong tmp=(ulong) (my_rnd(&sql_rand) * 0xffffffff); /* make all bits random */
- pthread_mutex_unlock(&LOCK_thread_count);
+ ulong tmp=sql_rnd_with_mutex();
randominit(&rand, tmp + (ulong) &rand, tmp + (ulong) ::query_id);
}
}