diff options
-rw-r--r-- | libmysqld/CMakeLists.txt | 1 | ||||
-rw-r--r-- | sql/CMakeLists.txt | 2 | ||||
-rw-r--r-- | sql/item_create.cc | 1 | ||||
-rw-r--r-- | sql/item_func.cc | 55 | ||||
-rw-r--r-- | sql/item_func.h | 10 | ||||
-rw-r--r-- | sql/item_inetfunc.cc | 126 | ||||
-rw-r--r-- | sql/item_inetfunc.h | 57 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 42 | ||||
-rw-r--r-- | sql/item_strfunc.h | 15 |
9 files changed, 186 insertions, 123 deletions
diff --git a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt index d0c3fafdf69..0920be53baf 100644 --- a/libmysqld/CMakeLists.txt +++ b/libmysqld/CMakeLists.txt @@ -104,6 +104,7 @@ SET(SQL_EMBEDDED_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc ../sql/sql_explain.cc ../sql/sql_explain.h ../sql/compat56.cc ../sql/table_cache.cc + ../sql/item_inetfunc.cc ${GEN_SOURCES} ${MYSYS_LIBWRAP_SOURCE} ) diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 0665323285a..965f25cbb13 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -78,7 +78,7 @@ SET (SQL_SOURCE sql_profile.cc event_parse_data.cc sql_alter.cc sql_signal.cc rpl_handler.cc mdl.cc sql_admin.cc transaction.cc sys_vars.cc sql_truncate.cc datadict.cc - sql_reload.cc sql_cmd.h + sql_reload.cc sql_cmd.h item_inetfunc.cc # added in MariaDB: sql_explain.h sql_explain.cc diff --git a/sql/item_create.cc b/sql/item_create.cc index a3e0dc6012b..af44dcfea6e 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -32,6 +32,7 @@ #include "set_var.h" #include "sp_head.h" #include "sp.h" +#include "item_inetfunc.h" #include "sql_time.h" /* diff --git a/sql/item_func.cc b/sql/item_func.cc index be5dcd070a1..41eb9257149 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -6098,61 +6098,6 @@ void Item_func_get_system_var::cleanup() } -longlong Item_func_inet_aton::val_int() -{ - DBUG_ASSERT(fixed == 1); - uint byte_result = 0; - ulonglong result = 0; // We are ready for 64 bit addresses - const char *p,* end; - char c = '.'; // we mark c to indicate invalid IP in case length is 0 - char buff[36]; - int dot_count= 0; - - String *s, tmp(buff, sizeof(buff), &my_charset_latin1); - if (!(s = args[0]->val_str_ascii(&tmp))) // If null value - goto err; - null_value=0; - - end= (p = s->ptr()) + s->length(); - while (p < end) - { - c = *p++; - int digit = (int) (c - '0'); - if (digit >= 0 && digit <= 9) - { - if ((byte_result = byte_result * 10 + digit) > 255) - goto err; // Wrong address - } - else if (c == '.') - { - dot_count++; - result= (result << 8) + (ulonglong) byte_result; - byte_result = 0; - } - else - goto err; // Invalid character - } - if (c != '.') // IP number can't end on '.' - { - /* - Handle short-forms addresses according to standard. Examples: - 127 -> 0.0.0.127 - 127.1 -> 127.0.0.1 - 127.2.1 -> 127.2.0.1 - */ - switch (dot_count) { - case 1: result<<= 8; /* Fall through */ - case 2: result<<= 8; /* Fall through */ - } - return (result << 8) + (ulonglong) byte_result; - } - -err: - null_value=1; - return 0; -} - - void Item_func_match::init_search(bool no_order) { DBUG_ENTER("Item_func_match::init_search"); diff --git a/sql/item_func.h b/sql/item_func.h index 69abecc5f39..1696898812d 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1871,16 +1871,6 @@ public: }; -class Item_func_inet_aton : public Item_int_func -{ -public: - Item_func_inet_aton(Item *a) :Item_int_func(a) {} - longlong val_int(); - const char *func_name() const { return "inet_aton"; } - void fix_length_and_dec() { decimals= 0; max_length= 21; maybe_null= 1; unsigned_flag= 1;} -}; - - /* for fulltext search */ class Item_func_match :public Item_real_func diff --git a/sql/item_inetfunc.cc b/sql/item_inetfunc.cc new file mode 100644 index 00000000000..9b2f1292db5 --- /dev/null +++ b/sql/item_inetfunc.cc @@ -0,0 +1,126 @@ +/* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2014 MariaDB Foundation + + 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 + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#include "item_inetfunc.h" + + +longlong Item_func_inet_aton::val_int() +{ + DBUG_ASSERT(fixed); + + uint byte_result= 0; + ulonglong result= 0; // We are ready for 64 bit addresses + const char *p,* end; + char c= '.'; // we mark c to indicate invalid IP in case length is 0 + int dot_count= 0; + + StringBuffer<36> tmp; + String *s= args[0]->val_str_ascii(&tmp); + + if (!s) // If null value + goto err; + + null_value= 0; + + end= (p = s->ptr()) + s->length(); + while (p < end) + { + c= *p++; + int digit= (int) (c - '0'); + if (digit >= 0 && digit <= 9) + { + if ((byte_result= byte_result * 10 + digit) > 255) + goto err; // Wrong address + } + else if (c == '.') + { + dot_count++; + result= (result << 8) + (ulonglong) byte_result; + byte_result= 0; + } + else + goto err; // Invalid character + } + if (c != '.') // IP number can't end on '.' + { + /* + Attempt to support short forms of IP-addresses. It's however pretty + basic one comparing to the BSD support. + Examples: + 127 -> 0.0.0.127 + 127.255 -> 127.0.0.255 + 127.256 -> NULL (should have been 127.0.1.0) + 127.2.1 -> 127.2.0.1 + */ + switch (dot_count) { + case 1: result<<= 8; /* Fall through */ + case 2: result<<= 8; /* Fall through */ + } + return (result << 8) + (ulonglong) byte_result; + } + +err: + null_value=1; + return 0; +} + +/////////////////////////////////////////////////////////////////////////// + +String* Item_func_inet_ntoa::val_str(String* str) +{ + DBUG_ASSERT(fixed); + + ulonglong n= (ulonglong) args[0]->val_int(); + + /* + We do not know if args[0] is NULL until we have called + some val function on it if args[0] is not a constant! + + Also return null if n > 255.255.255.255 + */ + if ((null_value= (args[0]->null_value || n > 0xffffffff))) + return 0; // Null value + + str->set_charset(collation.collation); + str->length(0); + + uchar buf[8]; + int4store(buf, n); + + /* Now we can assume little endian. */ + + char num[4]; + num[3]= '.'; + + for (uchar *p= buf + 4; p-- > buf;) + { + uint c= *p; + uint n1, n2; // Try to avoid divisions + n1= c / 100; // 100 digits + c-= n1 * 100; + n2= c / 10; // 10 digits + c-= n2 * 10; // last digit + num[0]= (char) n1 + '0'; + num[1]= (char) n2 + '0'; + num[2]= (char) c + '0'; + uint length= (n1 ? 4 : n2 ? 3 : 2); // Remove pre-zero + uint dot_length= (p <= buf) ? 1 : 0; + (void) str->append(num + 4 - length, length - dot_length, + &my_charset_latin1); + } + + return str; +} diff --git a/sql/item_inetfunc.h b/sql/item_inetfunc.h new file mode 100644 index 00000000000..cebe36e34eb --- /dev/null +++ b/sql/item_inetfunc.h @@ -0,0 +1,57 @@ +#ifndef ITEM_INETFUNC_INCLUDED +#define ITEM_INETFUNC_INCLUDED + +/* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2014 MariaDB Foundation + + 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 + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + + +#include "item.h" + +/************************************************************************* + Item_func_inet_aton implements INET_ATON() SQL-function. +*************************************************************************/ + +class Item_func_inet_aton : public Item_int_func +{ +public: + Item_func_inet_aton(Item *a) :Item_int_func(a) {} + longlong val_int(); + const char *func_name() const { return "inet_aton"; } + void fix_length_and_dec() { decimals= 0; max_length= 21; maybe_null= 1; unsigned_flag= 1;} +}; + + +/************************************************************************* + Item_func_inet_ntoa implements INET_NTOA() SQL-function. +*************************************************************************/ + +class Item_func_inet_ntoa : public Item_str_func +{ +public: + Item_func_inet_ntoa(Item *a) :Item_str_func(a) + { + } + String* val_str(String* str); + const char *func_name() const { return "inet_ntoa"; } + void fix_length_and_dec() + { + decimals= 0; + fix_length_and_charset(3 * 8 + 7, default_charset()); + maybe_null= 1; + } +}; + +#endif // ITEM_INETFUNC_INCLUDED diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 100d54133dd..2c7fc455d41 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -3861,48 +3861,6 @@ void Item_func_export_set::fix_length_and_dec() fix_char_length(length * 64 + sep_length * 63); } -String* Item_func_inet_ntoa::val_str(String* str) -{ - DBUG_ASSERT(fixed == 1); - uchar buf[8], *p; - ulonglong n = (ulonglong) args[0]->val_int(); - char num[4]; - - /* - We do not know if args[0] is NULL until we have called - some val function on it if args[0] is not a constant! - - Also return null if n > 255.255.255.255 - */ - if ((null_value= (args[0]->null_value || n > 0xffffffff))) - return 0; // Null value - - str->set_charset(collation.collation); - str->length(0); - int4store(buf,n); - - /* Now we can assume little endian. */ - - num[3]='.'; - for (p=buf+4 ; p-- > buf ; ) - { - uint c = *p; - uint n1,n2; // Try to avoid divisions - n1= c / 100; // 100 digits - c-= n1*100; - n2= c / 10; // 10 digits - c-=n2*10; // last digit - num[0]=(char) n1+'0'; - num[1]=(char) n2+'0'; - num[2]=(char) c+'0'; - uint length= (n1 ? 4 : n2 ? 3 : 2); // Remove pre-zero - uint dot_length= (p <= buf) ? 1 : 0; - (void) str->append(num + 4 - length, length - dot_length, - &my_charset_latin1); - } - return str; -} - #define get_esc_bit(mask, num) (1 & (*((mask) + ((num) >> 3))) >> ((num) & 7)) diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index ff8a916d200..f3d5c064423 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -880,21 +880,6 @@ class Item_func_export_set: public Item_str_func const char *func_name() const { return "export_set"; } }; -class Item_func_inet_ntoa : public Item_str_func -{ -public: - Item_func_inet_ntoa(Item *a) :Item_str_func(a) - { - } - String* val_str(String* str); - const char *func_name() const { return "inet_ntoa"; } - void fix_length_and_dec() - { - decimals= 0; - fix_length_and_charset(3 * 8 + 7, default_charset()); - maybe_null= 1; - } -}; class Item_func_quote :public Item_str_func { |