summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.org>2014-09-03 01:56:21 +0400
committerAlexander Barkov <bar@mariadb.org>2014-09-03 01:56:21 +0400
commitfbaaf3688d5fac4b1b867155a9f09575367c0f98 (patch)
tree0e36d7dca37e6775e113c0547823dcd12ee502fe
parent658a1e9420b062f767316ecf1dcb4b2837dfa27a (diff)
downloadmariadb-git-fbaaf3688d5fac4b1b867155a9f09575367c0f98.tar.gz
Moving Item::str_value from public to protected.
-rw-r--r--sql/item.cc9
-rw-r--r--sql/item.h60
-rw-r--r--sql/item_cmpfunc.h2
-rw-r--r--sql/item_create.cc4
-rw-r--r--sql/item_create.h9
-rw-r--r--sql/item_strfunc.cc2
-rw-r--r--sql/item_timefunc.cc2
-rw-r--r--sql/sql_select.cc2
-rw-r--r--sql/sql_string.cc2
-rw-r--r--sql/sql_string.h2
-rw-r--r--sql/sql_yacc.yy29
-rw-r--r--storage/sphinx/ha_sphinx.cc6
12 files changed, 86 insertions, 43 deletions
diff --git a/sql/item.cc b/sql/item.cc
index 64d6e8dd9c9..5e6409caf67 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1280,16 +1280,13 @@ Item *Item_param::safe_charset_converter(CHARSET_INFO *tocs)
String *ostr= val_str(&cnvstr);
if (!needs_charset_converter(tocs))
return this;
- cnvitem->str_value.copy(ostr->ptr(), ostr->length(),
- ostr->charset(), tocs, &cnv_errors);
+ cnvitem->copy_value(ostr->ptr(), ostr->length(),
+ ostr->charset(), tocs, &cnv_errors);
if (cnv_errors)
return NULL;
if (ostr->charset() == &my_charset_bin && tocs != &my_charset_bin &&
- !cnvitem->check_well_formed_result(&cnvitem->str_value, true))
+ !cnvitem->check_well_formed_result(true))
return NULL;
- cnvitem->str_value.mark_as_const();
- cnvitem->collation.set(tocs);
- cnvitem->max_length= cnvitem->str_value.numchars() * tocs->mbmaxlen;
return cnvitem;
}
return this;
diff --git a/sql/item.h b/sql/item.h
index 41e382bd0db..3d60794061b 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -614,11 +614,20 @@ public:
/* Reuse size, only used by SP local variable assignment, otherwize 0 */
uint rsize;
+protected:
/*
str_values's main purpose is to be used to cache the value in
save_in_field
*/
String str_value;
+
+public:
+ /*
+ Cache val_str() into the own buffer, e.g. to evaluate constant
+ expressions with subqueries in the ORDER/GROUP clauses.
+ */
+ String *val_str() { return val_str(&str_value); }
+
char * name; /* Name from select */
/* Original item name (if it was renamed)*/
char * orig_name;
@@ -1662,6 +1671,7 @@ public:
};
class sp_head;
+class Item_string;
/**
@@ -2366,7 +2376,7 @@ class Item_param :public Item_basic_value,
{
char cnvbuf[MAX_FIELD_WIDTH];
String cnvstr;
- Item *cnvitem;
+ Item_string *cnvitem;
public:
enum enum_item_param_state
@@ -2758,6 +2768,24 @@ public:
// it is constant => can be used without fix_fields (and frequently used)
fixed= 1;
}
+ void set_value(const String *str)
+ {
+ str_value= *str;
+ collation.set(str->charset());
+ }
+ void copy_value(const char *str, uint32 length, CHARSET_INFO *fromcs,
+ CHARSET_INFO *tocs, uint *cnv_errors)
+ {
+ str_value.copy(str, length, fromcs, tocs, cnv_errors);
+ str_value.mark_as_const();
+ collation.set(tocs);
+ fix_char_length(str_value.numchars());
+ }
+
+ void print_value(String *to) const
+ {
+ str_value.print(to);
+ }
/*
This is used in stored procedures to avoid memory leaks and
does a deep copy of its argument.
@@ -2850,6 +2878,34 @@ public:
String *check_well_formed_result(bool send_error)
{ return Item::check_well_formed_result(&str_value, send_error); }
+ enum_field_types odbc_temporal_literal_type(const LEX_STRING *type_str) const
+ {
+ /*
+ If string is a reasonably short pure ASCII string literal,
+ try to parse known ODBC style date, time or timestamp literals,
+ e.g:
+ SELECT {d'2001-01-01'};
+ SELECT {t'10:20:30'};
+ SELECT {ts'2001-01-01 10:20:30'};
+ */
+ if (collation.repertoire == MY_REPERTOIRE_ASCII &&
+ str_value.length() < MAX_DATE_STRING_REP_LENGTH * 4)
+ {
+ if (type_str->length == 1)
+ {
+ if (type_str->str[0] == 'd') /* {d'2001-01-01'} */
+ return MYSQL_TYPE_DATE;
+ else if (type_str->str[0] == 't') /* {t'10:20:30'} */
+ return MYSQL_TYPE_TIME;
+ }
+ else if (type_str->length == 2) /* {ts'2001-01-01 10:20:30'} */
+ {
+ if (type_str->str[0] == 't' && type_str->str[1] == 's')
+ return MYSQL_TYPE_DATETIME;
+ }
+ }
+ return MYSQL_TYPE_STRING; // Not a temporal literal
+ }
private:
bool m_cs_specified;
};
@@ -2995,7 +3051,7 @@ public:
{
return item->basic_const_item() && item->type() == type() &&
item->cast_to_int_type() == cast_to_int_type() &&
- str_value.bin_eq(&item->str_value);
+ str_value.bin_eq(&((Item_hex_constant*)item)->str_value);
}
String *val_str(String*) { DBUG_ASSERT(fixed == 1); return &str_value; }
};
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index bf28b00c908..2ff0a4e5e2f 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -896,7 +896,7 @@ public:
{
String *str=((String*) base)+pos;
Item_string *to= (Item_string*)item;
- to->str_value= *str;
+ to->set_value(str);
}
Item_result result_type() { return STRING_RESULT; }
};
diff --git a/sql/item_create.cc b/sql/item_create.cc
index 532654910e2..35716937f12 100644
--- a/sql/item_create.cc
+++ b/sql/item_create.cc
@@ -5241,13 +5241,13 @@ Create_func_space::create_1_arg(THD *thd, Item *arg1)
<code>thd->variables.collation_connection</code>.
*/
CHARSET_INFO *cs= thd->variables.collation_connection;
- Item *sp;
+ Item_string *sp;
if (cs->mbminlen > 1)
{
uint dummy_errors;
sp= new (thd->mem_root) Item_string("", 0, cs, DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII);
- sp->str_value.copy(" ", 1, &my_charset_latin1, cs, &dummy_errors);
+ sp->copy_value(" ", 1, &my_charset_latin1, cs, &dummy_errors);
}
else
{
diff --git a/sql/item_create.h b/sql/item_create.h
index 5f1a8c6006d..05fe48f656a 100644
--- a/sql/item_create.h
+++ b/sql/item_create.h
@@ -173,6 +173,15 @@ Item *create_temporal_literal(THD *thd,
CHARSET_INFO *cs,
enum_field_types type,
bool send_error);
+inline
+Item *create_temporal_literal(THD *thd, const String *str,
+ enum_field_types type,
+ bool send_error)
+{
+ return create_temporal_literal(thd,
+ str->ptr(), str->length(), str->charset(),
+ type, send_error);
+}
int item_create_init();
void item_create_cleanup();
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 78cb5badc65..c3e765e21b5 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -3397,7 +3397,7 @@ void Item_func_set_collation::print(String *str, enum_query_type query_type)
str->append(STRING_WITH_LEN(" collate "));
DBUG_ASSERT(args[1]->basic_const_item() &&
args[1]->type() == Item::STRING_ITEM);
- args[1]->str_value.print(str);
+ ((Item_string *)args[1])->print_value(str);
str->append(')');
}
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 5fddad56028..4a8bb4cc77d 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -1816,7 +1816,7 @@ void Item_func_date_format::fix_length_and_dec()
if (arg1->type() == STRING_ITEM)
{ // Optimize the normal case
fixed_length=1;
- max_length= format_length(&arg1->str_value) *
+ max_length= format_length(arg1->val_str(NULL)) *
collation.collation->mbmaxlen;
}
else
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 160ffe11abc..8146eb7a909 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -2521,7 +2521,7 @@ void JOIN::exec_inner()
Item *cur_const_item;
while ((cur_const_item= const_item_it++))
{
- cur_const_item->val_str(&cur_const_item->str_value);
+ cur_const_item->val_str(); // This caches val_str() to Item::str_value
if (thd->is_error())
{
error= thd->is_error();
diff --git a/sql/sql_string.cc b/sql/sql_string.cc
index f8348cfb30e..a573de13bdf 100644
--- a/sql/sql_string.cc
+++ b/sql/sql_string.cc
@@ -1074,7 +1074,7 @@ bool String::append_for_single_quote(const char *st, uint len)
return 0;
}
-void String::print(String *str)
+void String::print(String *str) const
{
str->append_for_single_quote(Ptr, str_length);
}
diff --git a/sql/sql_string.h b/sql/sql_string.h
index dbc1df0aaaf..4360e360590 100644
--- a/sql/sql_string.h
+++ b/sql/sql_string.h
@@ -502,7 +502,7 @@ public:
str_length+= arg_length;
return FALSE;
}
- void print(String *print);
+ void print(String *print) const;
bool append_for_single_quote(const char *st, uint len);
bool append_for_single_quote(const String *s)
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 19df69289ac..ef71369ac66 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -9195,7 +9195,6 @@ simple_expr:
}
| '{' ident expr '}'
{
- Item_string *item;
$$= NULL;
/*
If "expr" is reasonably short pure ASCII string literal,
@@ -9205,31 +9204,13 @@ simple_expr:
SELECT {t'10:20:30'};
SELECT {ts'2001-01-01 10:20:30'};
*/
- if ($3->type() == Item::STRING_ITEM &&
- (item= (Item_string *) $3) &&
- item->collation.repertoire == MY_REPERTOIRE_ASCII &&
- item->str_value.length() < MAX_DATE_STRING_REP_LENGTH * 4)
- {
- enum_field_types type= MYSQL_TYPE_STRING;
- LEX_STRING *ls= &$2;
- if (ls->length == 1)
- {
- if (ls->str[0] == 'd') /* {d'2001-01-01'} */
- type= MYSQL_TYPE_DATE;
- else if (ls->str[0] == 't') /* {t'10:20:30'} */
- type= MYSQL_TYPE_TIME;
- }
- else if (ls->length == 2) /* {ts'2001-01-01 10:20:30'} */
- {
- if (ls->str[0] == 't' && ls->str[1] == 's')
- type= MYSQL_TYPE_DATETIME;
- }
+ if ($3->type() == Item::STRING_ITEM)
+ {
+ Item_string *item= (Item_string *) $3;
+ enum_field_types type= item->odbc_temporal_literal_type(&$2);
if (type != MYSQL_TYPE_STRING)
{
- $$= create_temporal_literal(thd,
- item->str_value.ptr(),
- item->str_value.length(),
- item->str_value.charset(),
+ $$= create_temporal_literal(thd, item->val_str(NULL),
type, false);
}
}
diff --git a/storage/sphinx/ha_sphinx.cc b/storage/sphinx/ha_sphinx.cc
index f31669e931c..dacf5d5bde6 100644
--- a/storage/sphinx/ha_sphinx.cc
+++ b/storage/sphinx/ha_sphinx.cc
@@ -2719,11 +2719,11 @@ const Item * ha_sphinx::cond_push ( const Item *cond )
break;
// copy the query, and let know that we intercepted this condition
- Item_string * pString = (Item_string *) args[1];
+ String *pString= args[1]->val_str(NULL);
pTls->m_bQuery = true;
- strncpy ( pTls->m_sQuery, pString->str_value.c_ptr(), sizeof(pTls->m_sQuery) );
+ strncpy ( pTls->m_sQuery, pString->c_ptr(), sizeof(pTls->m_sQuery) );
pTls->m_sQuery[sizeof(pTls->m_sQuery)-1] = '\0';
- pTls->m_pQueryCharset = pString->str_value.charset();
+ pTls->m_pQueryCharset = pString->charset();
} else
{