diff options
author | Alexander Barkov <bar@mariadb.org> | 2014-09-03 01:56:21 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2014-09-03 01:56:21 +0400 |
commit | fbaaf3688d5fac4b1b867155a9f09575367c0f98 (patch) | |
tree | 0e36d7dca37e6775e113c0547823dcd12ee502fe | |
parent | 658a1e9420b062f767316ecf1dcb4b2837dfa27a (diff) | |
download | mariadb-git-fbaaf3688d5fac4b1b867155a9f09575367c0f98.tar.gz |
Moving Item::str_value from public to protected.
-rw-r--r-- | sql/item.cc | 9 | ||||
-rw-r--r-- | sql/item.h | 60 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 2 | ||||
-rw-r--r-- | sql/item_create.cc | 4 | ||||
-rw-r--r-- | sql/item_create.h | 9 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 2 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 2 | ||||
-rw-r--r-- | sql/sql_select.cc | 2 | ||||
-rw-r--r-- | sql/sql_string.cc | 2 | ||||
-rw-r--r-- | sql/sql_string.h | 2 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 29 | ||||
-rw-r--r-- | storage/sphinx/ha_sphinx.cc | 6 |
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 { |