summaryrefslogtreecommitdiff
path: root/sql/item_strfunc.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/item_strfunc.cc')
-rw-r--r--sql/item_strfunc.cc169
1 files changed, 16 insertions, 153 deletions
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index ed14f7f01e9..60d5d2f1341 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
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
@@ -120,7 +120,6 @@ String *Item_func_md5::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
String * sptr= args[0]->val_str(str);
- str->set_charset(&my_charset_bin);
if (sptr)
{
uchar digest[16];
@@ -133,6 +132,7 @@ String *Item_func_md5::val_str(String *str)
return 0;
}
array_to_hex((char *) str->ptr(), (const char*) digest, 16);
+ str->set_charset(&my_charset_bin);
str->length((uint) 32);
return str;
}
@@ -159,7 +159,6 @@ String *Item_func_sha::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
String * sptr= args[0]->val_str(str);
- str->set_charset(&my_charset_bin);
if (sptr) /* If we got value different from NULL */
{
SHA1_CONTEXT context; /* Context used to generate SHA1 hash */
@@ -169,11 +168,13 @@ String *Item_func_sha::val_str(String *str)
/* No need to check error as the only case would be too long message */
mysql_sha1_input(&context,
(const uchar *) sptr->ptr(), sptr->length());
+
/* Ensure that memory is free and we got result */
if (!( str->alloc(SHA1_HASH_SIZE*2) ||
(mysql_sha1_result(&context,digest))))
{
array_to_hex((char *) str->ptr(), (const char*) digest, SHA1_HASH_SIZE);
+ str->set_charset(&my_charset_bin);
str->length((uint) SHA1_HASH_SIZE*2);
null_value=0;
return str;
@@ -511,7 +512,8 @@ String *Item_func_des_encrypt::val_str(String *str)
tail= 8 - (res_length % 8); // 1..8 marking extra length
res_length+=tail;
- tmp_arg.realloc(res_length);
+ if (tmp_arg.realloc(res_length))
+ goto error;
tmp_arg.length(0);
tmp_arg.append(res->ptr(), res->length());
code= ER_OUT_OF_RESOURCES;
@@ -646,7 +648,7 @@ String *Item_func_concat_ws::val_str(String *str)
use_as_buff= &tmp_value;
str->length(0); // QQ; Should be removed
- res=str;
+ res=str; // If 0 arg_count
// Skip until non-null argument is found.
// If not, return the empty string
@@ -3375,7 +3377,7 @@ longlong Item_func_crc32::val_int()
String *Item_func_compress::val_str(String *str)
{
int err= Z_OK, code;
- ulong new_size;
+ size_t new_size;
String *res;
Byte *body;
char *tmp, *last_char;
@@ -3411,8 +3413,8 @@ String *Item_func_compress::val_str(String *str)
body= ((Byte*)buffer.ptr()) + 4;
// As far as we have checked res->is_empty() we can use ptr()
- if ((err= compress(body, &new_size,
- (const Bytef*)res->ptr(), res->length())) != Z_OK)
+ if ((err= my_compress_buffer(body, &new_size, (const uchar *)res->ptr(),
+ res->length())) != Z_OK)
{
code= err==Z_MEM_ERROR ? ER_ZLIB_Z_MEM_ERROR : ER_ZLIB_Z_BUF_ERROR;
push_warning(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR,code,ER(code));
@@ -3490,156 +3492,17 @@ err:
}
#endif
-/*
- UUID, as in
- DCE 1.1: Remote Procedure Call,
- Open Group Technical Standard Document Number C706, October 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";
-
-/**
- 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 * 1000 * 10)
-
-#define UUID_VERSION 0x1000
-#define UUID_VARIANT 0x8000
-
-static void tohex(char *to, uint from, uint len)
-{
- to+= len;
- while (len--)
- {
- *--to= _dig_vec_lower[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)
{
DBUG_ASSERT(fixed == 1);
- char *s;
- THD *thd= current_thd;
+ uchar guid[MY_UUID_SIZE];
- 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))
- {
- /* purecov: begin inspected */
- /*
- 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) thd, tmp + (ulong)global_query_id);
- for (i=0; i < (int)sizeof(mac); i++)
- mac[i]=(uchar)(my_rnd(&uuid_rand)*255);
- /* purecov: end */
- }
- s=clock_seq_and_node_str+sizeof(clock_seq_and_node_str)-1;
- for (i=sizeof(mac)-1 ; i>=0 ; i--)
- {
- *--s=_dig_vec_lower[mac[i] & 15];
- *--s=_dig_vec_lower[mac[i] >> 4];
- }
- randominit(&uuid_rand, tmp + (ulong) server_start_time,
- tmp + (ulong) thd->status_var.bytes_sent);
- set_clock_seq_str();
- }
-
- ulonglong tv= my_getsystime() + UUID_TIME_OFFSET + nanoseq;
-
- if (likely(tv > uuid_time))
- {
- /*
- Current time is ahead of last timestamp, as it should be.
- If we "borrowed time", give it back, just as long as we
- stay ahead of the previous timestamp.
- */
- if (nanoseq)
- {
- DBUG_ASSERT((tv > uuid_time) && (nanoseq > 0));
- /*
- -1 so we won't make tv= uuid_time for nanoseq >= (tv - uuid_time)
- */
- ulong delta= min(nanoseq, (ulong) (tv - uuid_time -1));
- tv-= delta;
- nanoseq-= delta;
- }
- }
- else
- {
- if (unlikely(tv == uuid_time))
- {
- /*
- For low-res system clocks. If several requests for UUIDs
- end up on the same tick, we add a nano-second to make them
- different.
- ( current_timestamp + nanoseq * calls_in_this_period )
- may end up > next_timestamp; this is OK. Nonetheless, we'll
- try to unwind nanoseq when we get a chance to.
- If nanoseq overflows, we'll start over with a new numberspace
- (so the if() below is needed so we can avoid the ++tv and thus
- match the follow-up if() if nanoseq overflows!).
- */
- if (likely(++nanoseq))
- ++tv;
- }
-
- if (unlikely(tv <= uuid_time))
- {
- /*
- If the admin changes the system clock (or due to Daylight
- Saving Time), the system clock may be turned *back* so we
- go through a period once more for which we already gave out
- UUIDs. To avoid duplicate UUIDs despite potentially identical
- times, we make a new random component.
- We also come here if the nanoseq "borrowing" overflows.
- In either case, we throw away any nanoseq borrowing since it's
- irrelevant in the new numberspace.
- */
- set_clock_seq_str();
- tv= my_getsystime() + UUID_TIME_OFFSET;
- nanoseq= 0;
- DBUG_PRINT("uuid",("making new numberspace"));
- }
- }
-
- uuid_time=tv;
- pthread_mutex_unlock(&LOCK_uuid_generator);
-
- uint32 time_low= (uint32) (tv & 0xFFFFFFFF);
- uint16 time_mid= (uint16) ((tv >> 32) & 0xFFFF);
- uint16 time_hi_and_version= (uint16) ((tv >> 48) | UUID_VERSION);
-
- str->realloc(UUID_LENGTH+1);
- str->length(UUID_LENGTH);
+ str->realloc(MY_UUID_STRING_LENGTH+1);
+ str->length(MY_UUID_STRING_LENGTH);
str->set_charset(system_charset_info);
- 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);
+ my_uuid(guid);
+ my_uuid2str(guid, (char *)str->ptr());
+
return str;
}