summaryrefslogtreecommitdiff
path: root/sql/item_strfunc.cc
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2013-04-22 20:55:22 -0700
committerIgor Babaev <igor@askmonty.org>2013-04-22 20:55:22 -0700
commitcd0e834d12627189910c4231e69b7ac5c01a3ddf (patch)
treea2a310ff9413a04e839a908a685afcedc4285e1a /sql/item_strfunc.cc
parent16c3fbab034f42d0aabf182c1fe056b1da39f3f7 (diff)
parentbb5b0a9f5bea18711cd849cbd8d4114764b505b8 (diff)
downloadmariadb-git-cd0e834d12627189910c4231e69b7ac5c01a3ddf.tar.gz
Merge 10.0-base -> 10.0
Diffstat (limited to 'sql/item_strfunc.cc')
-rw-r--r--sql/item_strfunc.cc77
1 files changed, 77 insertions, 0 deletions
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 532c6d7ff08..e5c3c48b3bb 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -60,6 +60,7 @@ C_MODE_START
C_MODE_END
#include "sql_show.h" // append_identifier
#include <sql_repl.h>
+#include "sql_statistics.h"
/**
@todo Remove this. It is not safe to use a shared String object.
@@ -471,6 +472,82 @@ void Item_func_aes_decrypt::fix_length_and_dec()
set_persist_maybe_null(1);
}
+///////////////////////////////////////////////////////////////////////////////
+
+
+const char *histogram_types[] =
+ {"SINGLE_PREC_HB", "DOUBLE_PREC_HB", 0};
+static TYPELIB hystorgam_types_typelib=
+ { array_elements(histogram_types),
+ "histogram_types",
+ histogram_types, NULL};
+const char *representation_by_type[]= {"%.3f", "%.5f"};
+
+String *Item_func_decode_histogram::val_str(String *str)
+{
+ DBUG_ASSERT(fixed == 1);
+ char buff[STRING_BUFFER_USUAL_SIZE];
+ String *res, tmp(buff, sizeof(buff), &my_charset_bin);
+ int type;
+
+ tmp.length(0);
+ if (!(res= args[1]->val_str(&tmp)) ||
+ (type= find_type(res->c_ptr_safe(),
+ &hystorgam_types_typelib, MYF(0))) <= 0)
+ {
+ null_value= 1;
+ return 0;
+ }
+ type--;
+
+ tmp.length(0);
+ if (!(res= args[0]->val_str(&tmp)))
+ {
+ null_value= 1;
+ return 0;
+ }
+ if (type == DOUBLE_PREC_HB && res->length() % 2 != 0)
+ res->length(res->length() - 1); // one byte is unused
+
+ double prev= 0.0;
+ uint i;
+ str->length(0);
+ char numbuf[32];
+ const uchar *p= (uchar*)res->c_ptr();
+ for (i= 0; i < res->length(); i++)
+ {
+ double val;
+ switch (type)
+ {
+ case SINGLE_PREC_HB:
+ val= p[i] / ((double)((1 << 8) - 1));
+ break;
+ case DOUBLE_PREC_HB:
+ val= ((uint16 *)(p + i))[0] / ((double)((1 << 16) - 1));
+ i++;
+ break;
+ default:
+ val= 0;
+ DBUG_ASSERT(0);
+ }
+ /* show delta with previous value */
+ int size= my_snprintf(numbuf, sizeof(numbuf),
+ representation_by_type[type], val - prev);
+ str->append(numbuf, size);
+ str->append(",");
+ prev= val;
+ }
+ /* show delta with max */
+ int size= my_snprintf(numbuf, sizeof(numbuf),
+ representation_by_type[type], 1.0 - prev);
+ str->append(numbuf, size);
+
+ null_value=0;
+ return str;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
/**
Concatenate args with the following premises: