2010-01-07 06:42:07 +01:00
|
|
|
/* Copyright (C) 2000-2006 MySQL AB, 2008-2009 Sun Microsystems, Inc
|
2001-12-06 13:10:51 +01:00
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
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
|
2006-12-23 20:17:15 +01:00
|
|
|
the Free Software Foundation; version 2 of the License.
|
2001-12-06 13:10:51 +01:00
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
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.
|
2001-12-06 13:10:51 +01:00
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
|
|
|
|
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
/**
|
|
|
|
@file
|
|
|
|
|
|
|
|
@brief
|
|
|
|
This file defines all string functions
|
|
|
|
|
|
|
|
@warning
|
|
|
|
Some string functions don't always put and end-null on a String.
|
|
|
|
(This shouldn't be needed)
|
2000-07-31 21:29:14 +02:00
|
|
|
*/
|
|
|
|
|
2005-05-26 12:09:14 +02:00
|
|
|
#ifdef USE_PRAGMA_IMPLEMENTATION
|
2000-07-31 21:29:14 +02:00
|
|
|
#pragma implementation // gcc: Class implementation
|
|
|
|
#endif
|
|
|
|
|
Backport of:
ChangeSet@1.2703, 2007-12-07 09:35:28-05:00, cmiller@zippy.cornsilk.net +40 -0
Bug#13174: SHA2 function
Patch contributed from Bill Karwin, paper unnumbered CLA in Seattle
Implement SHA2 functions.
Chad added code to make it work with YaSSL. Also, he removed the
(probable) bug of embedded server never using SSL-dependent
functions. (libmysqld/Makefile.am didn't read ANY autoconf defs.)
Function specification:
SHA2( string cleartext, integer hash_length )
-> string hash, or NULL
where hash_length is one of 224, 256, 384, or 512. If either is
NULL or a length is unsupported, then the result is NULL. The
resulting string is always the length of the hash_length parameter
or is NULL.
Include the canonical hash examples from the NIST in the test
results.
---
Polish and address concerns of reviewers.
2010-04-13 17:04:45 +02:00
|
|
|
/* May include caustic 3rd-party defs. Use early, so it can override nothing. */
|
|
|
|
#include "sha2.h"
|
2010-03-31 16:05:33 +02:00
|
|
|
#include "my_global.h" // HAVE_*
|
|
|
|
|
|
|
|
|
|
|
|
#include "sql_priv.h"
|
|
|
|
/*
|
|
|
|
It is necessary to include set_var.h instead of item.h because there
|
|
|
|
are dependencies on include order for set_var.h and item.h. This
|
|
|
|
will be resolved later.
|
|
|
|
*/
|
|
|
|
#include "sql_class.h" // set_var.h: THD
|
|
|
|
#include "set_var.h"
|
|
|
|
#include "mysqld.h" // LOCK_uuid_generator
|
|
|
|
#include "sql_acl.h" // SUPER_ACL
|
|
|
|
#include "des_key_file.h" // st_des_keyschedule, st_des_keyblock
|
|
|
|
#include "password.h" // my_make_scrambled_password,
|
|
|
|
// my_make_scrambled_password_323
|
2000-07-31 21:29:14 +02:00
|
|
|
#include <m_ctype.h>
|
2007-07-19 14:14:03 +02:00
|
|
|
#include "my_md5.h"
|
2002-06-11 11:37:48 +02:00
|
|
|
#include "sha1.h"
|
|
|
|
#include "my_aes.h"
|
WL#3817: Simplify string / memory area types and make things more consistent (first part)
The following type conversions was done:
- Changed byte to uchar
- Changed gptr to uchar*
- Change my_string to char *
- Change my_size_t to size_t
- Change size_s to size_t
Removed declaration of byte, gptr, my_string, my_size_t and size_s.
Following function parameter changes was done:
- All string functions in mysys/strings was changed to use size_t
instead of uint for string lengths.
- All read()/write() functions changed to use size_t (including vio).
- All protocoll functions changed to use size_t instead of uint
- Functions that used a pointer to a string length was changed to use size_t*
- Changed malloc(), free() and related functions from using gptr to use void *
as this requires fewer casts in the code and is more in line with how the
standard functions work.
- Added extra length argument to dirname_part() to return the length of the
created string.
- Changed (at least) following functions to take uchar* as argument:
- db_dump()
- my_net_write()
- net_write_command()
- net_store_data()
- DBUG_DUMP()
- decimal2bin() & bin2decimal()
- Changed my_compress() and my_uncompress() to use size_t. Changed one
argument to my_uncompress() from a pointer to a value as we only return
one value (makes function easier to use).
- Changed type of 'pack_data' argument to packfrm() to avoid casts.
- Changed in readfrm() and writefrom(), ha_discover and handler::discover()
the type for argument 'frmdata' to uchar** to avoid casts.
- Changed most Field functions to use uchar* instead of char* (reduced a lot of
casts).
- Changed field->val_xxx(xxx, new_ptr) to take const pointers.
Other changes:
- Removed a lot of not needed casts
- Added a few new cast required by other changes
- Added some cast to my_multi_malloc() arguments for safety (as string lengths
needs to be uint, not size_t).
- Fixed all calls to hash-get-key functions to use size_t*. (Needed to be done
explicitely as this conflict was often hided by casting the function to
hash_get_key).
- Changed some buffers to memory regions to uchar* to avoid casts.
- Changed some string lengths from uint to size_t.
- Changed field->ptr to be uchar* instead of char*. This allowed us to
get rid of a lot of casts.
- Some changes from true -> TRUE, false -> FALSE, unsigned char -> uchar
- Include zlib.h in some files as we needed declaration of crc32()
- Changed MY_FILE_ERROR to be (size_t) -1.
- Changed many variables to hold the result of my_read() / my_write() to be
size_t. This was needed to properly detect errors (which are
returned as (size_t) -1).
- Removed some very old VMS code
- Changed packfrm()/unpackfrm() to not be depending on uint size
(portability fix)
- Removed windows specific code to restore cursor position as this
causes slowdown on windows and we should not mix read() and pread()
calls anyway as this is not thread safe. Updated function comment to
reflect this. Changed function that depended on original behavior of
my_pwrite() to itself restore the cursor position (one such case).
- Added some missing checking of return value of malloc().
- Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid 'long' overflow.
- Changed type of table_def::m_size from my_size_t to ulong to reflect that
m_size is the number of elements in the array, not a string/memory
length.
- Moved THD::max_row_length() to table.cc (as it's not depending on THD).
Inlined max_row_length_blob() into this function.
- More function comments
- Fixed some compiler warnings when compiled without partitions.
- Removed setting of LEX_STRING() arguments in declaration (portability fix).
- Some trivial indentation/variable name changes.
- Some trivial code simplifications:
- Replaced some calls to alloc_root + memcpy to use
strmake_root()/strdup_root().
- Changed some calls from memdup() to strmake() (Safety fix)
- Simpler loops in client-simple.c
2007-05-10 11:59:39 +02:00
|
|
|
#include <zlib.h>
|
2003-10-15 21:40:36 +02:00
|
|
|
C_MODE_START
|
2003-09-13 10:35:29 +02:00
|
|
|
#include "../mysys/my_static.h" // For soundex_map
|
2003-10-15 21:40:36 +02:00
|
|
|
C_MODE_END
|
2000-07-31 21:29:14 +02:00
|
|
|
|
2003-09-18 15:58:02 +02:00
|
|
|
String my_empty_string("",default_charset_info);
|
2000-07-31 21:29:14 +02:00
|
|
|
|
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
2010-02-11 05:17:25 +01:00
|
|
|
/*
|
|
|
|
For the Items which have only val_str_ascii() method
|
|
|
|
and don't have their own "native" val_str(),
|
|
|
|
we provide a "wrapper" method to convert from ASCII
|
|
|
|
to Item character set when it's necessary.
|
|
|
|
Conversion happens only in case of "tricky" Item character set (e.g. UCS2).
|
|
|
|
Normally conversion does not happen, and val_str_ascii() is immediately
|
|
|
|
returned instead.
|
|
|
|
*/
|
|
|
|
String *Item_str_ascii_func::val_str(String *str)
|
|
|
|
{
|
|
|
|
DBUG_ASSERT(fixed == 1);
|
|
|
|
|
|
|
|
if (!(collation.collation->state & MY_CS_NONASCII))
|
|
|
|
return val_str_ascii(str);
|
|
|
|
|
|
|
|
DBUG_ASSERT(str != &ascii_buf);
|
|
|
|
|
|
|
|
uint errors;
|
|
|
|
String *res= val_str_ascii(&ascii_buf);
|
|
|
|
if (!res)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if ((null_value= str->copy(res->ptr(), res->length(),
|
|
|
|
&my_charset_latin1, collation.collation,
|
|
|
|
&errors)))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-01-15 11:28:38 +01:00
|
|
|
|
2010-01-26 18:05:19 +01:00
|
|
|
/*
|
|
|
|
Convert an array of bytes to a hexadecimal representation.
|
|
|
|
|
|
|
|
Used to generate a hexadecimal representation of a message digest.
|
|
|
|
*/
|
Backport of:
ChangeSet@1.2703, 2007-12-07 09:35:28-05:00, cmiller@zippy.cornsilk.net +40 -0
Bug#13174: SHA2 function
Patch contributed from Bill Karwin, paper unnumbered CLA in Seattle
Implement SHA2 functions.
Chad added code to make it work with YaSSL. Also, he removed the
(probable) bug of embedded server never using SSL-dependent
functions. (libmysqld/Makefile.am didn't read ANY autoconf defs.)
Function specification:
SHA2( string cleartext, integer hash_length )
-> string hash, or NULL
where hash_length is one of 224, 256, 384, or 512. If either is
NULL or a length is unsupported, then the result is NULL. The
resulting string is always the length of the hash_length parameter
or is NULL.
Include the canonical hash examples from the NIST in the test
results.
---
Polish and address concerns of reviewers.
2010-04-13 17:04:45 +02:00
|
|
|
static void array_to_hex(char *to, const unsigned char *str, uint len)
|
2010-01-26 18:05:19 +01:00
|
|
|
{
|
Backport of:
ChangeSet@1.2703, 2007-12-07 09:35:28-05:00, cmiller@zippy.cornsilk.net +40 -0
Bug#13174: SHA2 function
Patch contributed from Bill Karwin, paper unnumbered CLA in Seattle
Implement SHA2 functions.
Chad added code to make it work with YaSSL. Also, he removed the
(probable) bug of embedded server never using SSL-dependent
functions. (libmysqld/Makefile.am didn't read ANY autoconf defs.)
Function specification:
SHA2( string cleartext, integer hash_length )
-> string hash, or NULL
where hash_length is one of 224, 256, 384, or 512. If either is
NULL or a length is unsupported, then the result is NULL. The
resulting string is always the length of the hash_length parameter
or is NULL.
Include the canonical hash examples from the NIST in the test
results.
---
Polish and address concerns of reviewers.
2010-04-13 17:04:45 +02:00
|
|
|
const unsigned char *str_end= str + len;
|
2010-01-26 18:05:19 +01:00
|
|
|
for (; str != str_end; ++str)
|
|
|
|
{
|
|
|
|
*to++= _dig_vec_lower[((uchar) *str) >> 4];
|
|
|
|
*to++= _dig_vec_lower[((uchar) *str) & 0x0F];
|
|
|
|
}
|
|
|
|
}
|
2005-11-07 09:34:19 +01:00
|
|
|
|
|
|
|
|
2006-11-16 12:06:51 +01:00
|
|
|
bool Item_str_func::fix_fields(THD *thd, Item **ref)
|
|
|
|
{
|
|
|
|
bool res= Item_func::fix_fields(thd, ref);
|
|
|
|
/*
|
|
|
|
In Item_str_func::check_well_formed_result() we may set null_value
|
|
|
|
flag on the same condition as in test() below.
|
|
|
|
*/
|
|
|
|
maybe_null= (maybe_null ||
|
|
|
|
test(thd->variables.sql_mode &
|
|
|
|
(MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES)));
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-03-14 11:04:43 +01:00
|
|
|
my_decimal *Item_str_func::val_decimal(my_decimal *decimal_value)
|
|
|
|
{
|
|
|
|
DBUG_ASSERT(fixed == 1);
|
|
|
|
char buff[64];
|
|
|
|
String *res, tmp(buff,sizeof(buff), &my_charset_bin);
|
|
|
|
res= val_str(&tmp);
|
|
|
|
if (!res)
|
|
|
|
return 0;
|
|
|
|
(void)str2my_decimal(E_DEC_FATAL_ERROR, (char*) res->ptr(),
|
|
|
|
res->length(), res->charset(), decimal_value);
|
|
|
|
return decimal_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-11-11 19:39:35 +01:00
|
|
|
double Item_str_func::val_real()
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2005-01-15 11:28:38 +01:00
|
|
|
int err_not_used;
|
|
|
|
char *end_not_used, buff[64];
|
2004-08-26 17:26:38 +02:00
|
|
|
String *res, tmp(buff,sizeof(buff), &my_charset_bin);
|
|
|
|
res= val_str(&tmp);
|
2005-01-15 11:28:38 +01:00
|
|
|
return res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(),
|
|
|
|
&end_not_used, &err_not_used) : 0.0;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
2005-01-15 11:28:38 +01:00
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
longlong Item_str_func::val_int()
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2003-01-16 14:17:07 +01:00
|
|
|
int err;
|
2004-08-26 17:26:38 +02:00
|
|
|
char buff[22];
|
|
|
|
String *res, tmp(buff,sizeof(buff), &my_charset_bin);
|
|
|
|
res= val_str(&tmp);
|
2004-03-20 12:36:26 +01:00
|
|
|
return (res ?
|
|
|
|
my_strntoll(res->charset(), res->ptr(), res->length(), 10, NULL,
|
|
|
|
&err) :
|
|
|
|
(longlong) 0);
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
2010-02-11 05:17:25 +01:00
|
|
|
String *Item_func_md5::val_str_ascii(String *str)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2000-07-31 21:29:14 +02:00
|
|
|
String * sptr= args[0]->val_str(str);
|
2006-08-12 01:09:19 +02:00
|
|
|
str->set_charset(&my_charset_bin);
|
2000-07-31 21:29:14 +02:00
|
|
|
if (sptr)
|
|
|
|
{
|
2006-06-19 11:45:34 +02:00
|
|
|
uchar digest[16];
|
2000-07-31 21:29:14 +02:00
|
|
|
|
|
|
|
null_value=0;
|
2009-03-11 17:13:42 +01:00
|
|
|
MY_MD5_HASH(digest,(uchar *) sptr->ptr(), sptr->length());
|
2001-12-13 01:31:19 +01:00
|
|
|
if (str->alloc(32)) // Ensure that memory is free
|
|
|
|
{
|
|
|
|
null_value=1;
|
|
|
|
return 0;
|
|
|
|
}
|
Backport of:
ChangeSet@1.2703, 2007-12-07 09:35:28-05:00, cmiller@zippy.cornsilk.net +40 -0
Bug#13174: SHA2 function
Patch contributed from Bill Karwin, paper unnumbered CLA in Seattle
Implement SHA2 functions.
Chad added code to make it work with YaSSL. Also, he removed the
(probable) bug of embedded server never using SSL-dependent
functions. (libmysqld/Makefile.am didn't read ANY autoconf defs.)
Function specification:
SHA2( string cleartext, integer hash_length )
-> string hash, or NULL
where hash_length is one of 224, 256, 384, or 512. If either is
NULL or a length is unsupported, then the result is NULL. The
resulting string is always the length of the hash_length parameter
or is NULL.
Include the canonical hash examples from the NIST in the test
results.
---
Polish and address concerns of reviewers.
2010-04-13 17:04:45 +02:00
|
|
|
array_to_hex((char *) str->ptr(), digest, 16);
|
2000-07-31 21:29:14 +02:00
|
|
|
str->length((uint) 32);
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
null_value=1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Item_func_md5::fix_length_and_dec()
|
|
|
|
{
|
2006-05-28 20:01:38 +02:00
|
|
|
/*
|
|
|
|
The MD5() function treats its parameter as being a case sensitive. Thus
|
|
|
|
we set binary collation on it so different instances of MD5() will be
|
|
|
|
compared properly.
|
|
|
|
*/
|
|
|
|
args[0]->collation.set(
|
|
|
|
get_charset_by_csname(args[0]->collation.collation->csname,
|
|
|
|
MY_CS_BINSORT,MYF(0)), DERIVATION_COERCIBLE);
|
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
2010-02-11 05:17:25 +01:00
|
|
|
fix_length_and_charset(32, default_charset());
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
2002-06-11 11:37:48 +02:00
|
|
|
|
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
2010-02-11 05:17:25 +01:00
|
|
|
String *Item_func_sha::val_str_ascii(String *str)
|
2002-06-11 11:37:48 +02:00
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2002-06-11 11:37:48 +02:00
|
|
|
String * sptr= args[0]->val_str(str);
|
2006-08-12 01:09:19 +02:00
|
|
|
str->set_charset(&my_charset_bin);
|
2002-06-11 11:37:48 +02:00
|
|
|
if (sptr) /* If we got value different from NULL */
|
|
|
|
{
|
|
|
|
SHA1_CONTEXT context; /* Context used to generate SHA1 hash */
|
2002-06-14 13:14:30 +02:00
|
|
|
/* Temporary buffer to store 160bit digest */
|
2002-06-22 09:44:46 +02:00
|
|
|
uint8 digest[SHA1_HASH_SIZE];
|
2006-01-11 15:31:52 +01:00
|
|
|
mysql_sha1_reset(&context); /* We do not have to check for error here */
|
2002-06-11 11:37:48 +02:00
|
|
|
/* No need to check error as the only case would be too long message */
|
2006-01-11 15:31:52 +01:00
|
|
|
mysql_sha1_input(&context,
|
2006-06-19 11:45:34 +02:00
|
|
|
(const uchar *) sptr->ptr(), sptr->length());
|
2002-06-14 13:14:30 +02:00
|
|
|
/* Ensure that memory is free and we got result */
|
2006-01-11 15:31:52 +01:00
|
|
|
if (!( str->alloc(SHA1_HASH_SIZE*2) ||
|
|
|
|
(mysql_sha1_result(&context,digest))))
|
2002-06-11 11:37:48 +02:00
|
|
|
{
|
Backport of:
ChangeSet@1.2703, 2007-12-07 09:35:28-05:00, cmiller@zippy.cornsilk.net +40 -0
Bug#13174: SHA2 function
Patch contributed from Bill Karwin, paper unnumbered CLA in Seattle
Implement SHA2 functions.
Chad added code to make it work with YaSSL. Also, he removed the
(probable) bug of embedded server never using SSL-dependent
functions. (libmysqld/Makefile.am didn't read ANY autoconf defs.)
Function specification:
SHA2( string cleartext, integer hash_length )
-> string hash, or NULL
where hash_length is one of 224, 256, 384, or 512. If either is
NULL or a length is unsupported, then the result is NULL. The
resulting string is always the length of the hash_length parameter
or is NULL.
Include the canonical hash examples from the NIST in the test
results.
---
Polish and address concerns of reviewers.
2010-04-13 17:04:45 +02:00
|
|
|
array_to_hex((char *) str->ptr(), digest, SHA1_HASH_SIZE);
|
2002-06-14 13:14:30 +02:00
|
|
|
str->length((uint) SHA1_HASH_SIZE*2);
|
|
|
|
null_value=0;
|
|
|
|
return str;
|
|
|
|
}
|
2002-12-04 23:14:51 +01:00
|
|
|
}
|
2002-06-11 11:37:48 +02:00
|
|
|
null_value=1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Item_func_sha::fix_length_and_dec()
|
|
|
|
{
|
2006-05-28 20:01:38 +02:00
|
|
|
/*
|
|
|
|
The SHA() function treats its parameter as being a case sensitive. Thus
|
|
|
|
we set binary collation on it so different instances of MD5() will be
|
|
|
|
compared properly.
|
|
|
|
*/
|
|
|
|
args[0]->collation.set(
|
|
|
|
get_charset_by_csname(args[0]->collation.collation->csname,
|
|
|
|
MY_CS_BINSORT,MYF(0)), DERIVATION_COERCIBLE);
|
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
2010-02-11 05:17:25 +01:00
|
|
|
// size of hex representation of hash
|
|
|
|
fix_length_and_charset(SHA1_HASH_SIZE * 2, default_charset());
|
2002-06-11 11:37:48 +02:00
|
|
|
}
|
2002-06-14 13:14:30 +02:00
|
|
|
|
2010-07-07 08:38:11 +02:00
|
|
|
String *Item_func_sha2::val_str_ascii(String *str)
|
Backport of:
ChangeSet@1.2703, 2007-12-07 09:35:28-05:00, cmiller@zippy.cornsilk.net +40 -0
Bug#13174: SHA2 function
Patch contributed from Bill Karwin, paper unnumbered CLA in Seattle
Implement SHA2 functions.
Chad added code to make it work with YaSSL. Also, he removed the
(probable) bug of embedded server never using SSL-dependent
functions. (libmysqld/Makefile.am didn't read ANY autoconf defs.)
Function specification:
SHA2( string cleartext, integer hash_length )
-> string hash, or NULL
where hash_length is one of 224, 256, 384, or 512. If either is
NULL or a length is unsupported, then the result is NULL. The
resulting string is always the length of the hash_length parameter
or is NULL.
Include the canonical hash examples from the NIST in the test
results.
---
Polish and address concerns of reviewers.
2010-04-13 17:04:45 +02:00
|
|
|
{
|
|
|
|
DBUG_ASSERT(fixed == 1);
|
2010-04-22 20:53:26 +02:00
|
|
|
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
|
Backport of:
ChangeSet@1.2703, 2007-12-07 09:35:28-05:00, cmiller@zippy.cornsilk.net +40 -0
Bug#13174: SHA2 function
Patch contributed from Bill Karwin, paper unnumbered CLA in Seattle
Implement SHA2 functions.
Chad added code to make it work with YaSSL. Also, he removed the
(probable) bug of embedded server never using SSL-dependent
functions. (libmysqld/Makefile.am didn't read ANY autoconf defs.)
Function specification:
SHA2( string cleartext, integer hash_length )
-> string hash, or NULL
where hash_length is one of 224, 256, 384, or 512. If either is
NULL or a length is unsupported, then the result is NULL. The
resulting string is always the length of the hash_length parameter
or is NULL.
Include the canonical hash examples from the NIST in the test
results.
---
Polish and address concerns of reviewers.
2010-04-13 17:04:45 +02:00
|
|
|
unsigned char digest_buf[SHA512_DIGEST_LENGTH];
|
|
|
|
String *input_string;
|
|
|
|
unsigned char *input_ptr;
|
|
|
|
size_t input_len;
|
|
|
|
uint digest_length= 0;
|
|
|
|
|
|
|
|
str->set_charset(&my_charset_bin);
|
|
|
|
|
|
|
|
input_string= args[0]->val_str(str);
|
|
|
|
if (input_string == NULL)
|
|
|
|
{
|
|
|
|
null_value= TRUE;
|
|
|
|
return (String *) NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
null_value= args[0]->null_value;
|
|
|
|
if (null_value)
|
|
|
|
return (String *) NULL;
|
|
|
|
|
|
|
|
input_ptr= (unsigned char *) input_string->ptr();
|
|
|
|
input_len= input_string->length();
|
|
|
|
|
|
|
|
switch ((uint) args[1]->val_int()) {
|
|
|
|
#ifndef OPENSSL_NO_SHA512
|
|
|
|
case 512:
|
|
|
|
digest_length= SHA512_DIGEST_LENGTH;
|
|
|
|
(void) SHA512(input_ptr, input_len, digest_buf);
|
|
|
|
break;
|
|
|
|
case 384:
|
|
|
|
digest_length= SHA384_DIGEST_LENGTH;
|
|
|
|
(void) SHA384(input_ptr, input_len, digest_buf);
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
#ifndef OPENSSL_NO_SHA256
|
|
|
|
case 224:
|
|
|
|
digest_length= SHA224_DIGEST_LENGTH;
|
|
|
|
(void) SHA224(input_ptr, input_len, digest_buf);
|
|
|
|
break;
|
|
|
|
case 256:
|
|
|
|
case 0: // SHA-256 is the default
|
|
|
|
digest_length= SHA256_DIGEST_LENGTH;
|
|
|
|
(void) SHA256(input_ptr, input_len, digest_buf);
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
default:
|
|
|
|
if (!args[1]->const_item())
|
|
|
|
push_warning_printf(current_thd,
|
|
|
|
MYSQL_ERROR::WARN_LEVEL_WARN,
|
|
|
|
ER_WRONG_PARAMETERS_TO_NATIVE_FCT,
|
|
|
|
ER(ER_WRONG_PARAMETERS_TO_NATIVE_FCT), "sha2");
|
|
|
|
null_value= TRUE;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
Since we're subverting the usual String methods, we must make sure that
|
|
|
|
the destination has space for the bytes we're about to write.
|
|
|
|
*/
|
|
|
|
str->realloc((uint) digest_length*2 + 1); /* Each byte as two nybbles */
|
|
|
|
|
|
|
|
/* Convert the large number to a string-hex representation. */
|
|
|
|
array_to_hex((char *) str->ptr(), digest_buf, digest_length);
|
|
|
|
|
|
|
|
/* We poked raw bytes in. We must inform the the String of its length. */
|
|
|
|
str->length((uint) digest_length*2); /* Each byte as two nybbles */
|
|
|
|
|
|
|
|
null_value= FALSE;
|
|
|
|
return str;
|
|
|
|
|
|
|
|
#else
|
|
|
|
push_warning_printf(current_thd,
|
|
|
|
MYSQL_ERROR::WARN_LEVEL_WARN,
|
|
|
|
ER_FEATURE_DISABLED,
|
|
|
|
ER(ER_FEATURE_DISABLED),
|
|
|
|
"sha2", "--with-ssl");
|
|
|
|
null_value= TRUE;
|
|
|
|
return (String *) NULL;
|
2010-04-22 20:53:26 +02:00
|
|
|
#endif /* defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) */
|
Backport of:
ChangeSet@1.2703, 2007-12-07 09:35:28-05:00, cmiller@zippy.cornsilk.net +40 -0
Bug#13174: SHA2 function
Patch contributed from Bill Karwin, paper unnumbered CLA in Seattle
Implement SHA2 functions.
Chad added code to make it work with YaSSL. Also, he removed the
(probable) bug of embedded server never using SSL-dependent
functions. (libmysqld/Makefile.am didn't read ANY autoconf defs.)
Function specification:
SHA2( string cleartext, integer hash_length )
-> string hash, or NULL
where hash_length is one of 224, 256, 384, or 512. If either is
NULL or a length is unsupported, then the result is NULL. The
resulting string is always the length of the hash_length parameter
or is NULL.
Include the canonical hash examples from the NIST in the test
results.
---
Polish and address concerns of reviewers.
2010-04-13 17:04:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Item_func_sha2::fix_length_and_dec()
|
|
|
|
{
|
|
|
|
maybe_null = 1;
|
|
|
|
max_length = 0;
|
|
|
|
|
2010-04-22 20:53:26 +02:00
|
|
|
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
|
Backport of:
ChangeSet@1.2703, 2007-12-07 09:35:28-05:00, cmiller@zippy.cornsilk.net +40 -0
Bug#13174: SHA2 function
Patch contributed from Bill Karwin, paper unnumbered CLA in Seattle
Implement SHA2 functions.
Chad added code to make it work with YaSSL. Also, he removed the
(probable) bug of embedded server never using SSL-dependent
functions. (libmysqld/Makefile.am didn't read ANY autoconf defs.)
Function specification:
SHA2( string cleartext, integer hash_length )
-> string hash, or NULL
where hash_length is one of 224, 256, 384, or 512. If either is
NULL or a length is unsupported, then the result is NULL. The
resulting string is always the length of the hash_length parameter
or is NULL.
Include the canonical hash examples from the NIST in the test
results.
---
Polish and address concerns of reviewers.
2010-04-13 17:04:45 +02:00
|
|
|
int sha_variant= args[1]->const_item() ? args[1]->val_int() : 512;
|
|
|
|
|
|
|
|
switch (sha_variant) {
|
|
|
|
#ifndef OPENSSL_NO_SHA512
|
|
|
|
case 512:
|
2010-07-07 08:38:11 +02:00
|
|
|
fix_length_and_charset(SHA512_DIGEST_LENGTH * 2, default_charset());
|
Backport of:
ChangeSet@1.2703, 2007-12-07 09:35:28-05:00, cmiller@zippy.cornsilk.net +40 -0
Bug#13174: SHA2 function
Patch contributed from Bill Karwin, paper unnumbered CLA in Seattle
Implement SHA2 functions.
Chad added code to make it work with YaSSL. Also, he removed the
(probable) bug of embedded server never using SSL-dependent
functions. (libmysqld/Makefile.am didn't read ANY autoconf defs.)
Function specification:
SHA2( string cleartext, integer hash_length )
-> string hash, or NULL
where hash_length is one of 224, 256, 384, or 512. If either is
NULL or a length is unsupported, then the result is NULL. The
resulting string is always the length of the hash_length parameter
or is NULL.
Include the canonical hash examples from the NIST in the test
results.
---
Polish and address concerns of reviewers.
2010-04-13 17:04:45 +02:00
|
|
|
break;
|
|
|
|
case 384:
|
2010-07-07 08:38:11 +02:00
|
|
|
fix_length_and_charset(SHA384_DIGEST_LENGTH * 2, default_charset());
|
Backport of:
ChangeSet@1.2703, 2007-12-07 09:35:28-05:00, cmiller@zippy.cornsilk.net +40 -0
Bug#13174: SHA2 function
Patch contributed from Bill Karwin, paper unnumbered CLA in Seattle
Implement SHA2 functions.
Chad added code to make it work with YaSSL. Also, he removed the
(probable) bug of embedded server never using SSL-dependent
functions. (libmysqld/Makefile.am didn't read ANY autoconf defs.)
Function specification:
SHA2( string cleartext, integer hash_length )
-> string hash, or NULL
where hash_length is one of 224, 256, 384, or 512. If either is
NULL or a length is unsupported, then the result is NULL. The
resulting string is always the length of the hash_length parameter
or is NULL.
Include the canonical hash examples from the NIST in the test
results.
---
Polish and address concerns of reviewers.
2010-04-13 17:04:45 +02:00
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
#ifndef OPENSSL_NO_SHA256
|
|
|
|
case 256:
|
|
|
|
case 0: // SHA-256 is the default
|
2010-07-07 08:38:11 +02:00
|
|
|
fix_length_and_charset(SHA256_DIGEST_LENGTH * 2, default_charset());
|
Backport of:
ChangeSet@1.2703, 2007-12-07 09:35:28-05:00, cmiller@zippy.cornsilk.net +40 -0
Bug#13174: SHA2 function
Patch contributed from Bill Karwin, paper unnumbered CLA in Seattle
Implement SHA2 functions.
Chad added code to make it work with YaSSL. Also, he removed the
(probable) bug of embedded server never using SSL-dependent
functions. (libmysqld/Makefile.am didn't read ANY autoconf defs.)
Function specification:
SHA2( string cleartext, integer hash_length )
-> string hash, or NULL
where hash_length is one of 224, 256, 384, or 512. If either is
NULL or a length is unsupported, then the result is NULL. The
resulting string is always the length of the hash_length parameter
or is NULL.
Include the canonical hash examples from the NIST in the test
results.
---
Polish and address concerns of reviewers.
2010-04-13 17:04:45 +02:00
|
|
|
break;
|
|
|
|
case 224:
|
2010-07-07 08:38:11 +02:00
|
|
|
fix_length_and_charset(SHA224_DIGEST_LENGTH * 2, default_charset());
|
Backport of:
ChangeSet@1.2703, 2007-12-07 09:35:28-05:00, cmiller@zippy.cornsilk.net +40 -0
Bug#13174: SHA2 function
Patch contributed from Bill Karwin, paper unnumbered CLA in Seattle
Implement SHA2 functions.
Chad added code to make it work with YaSSL. Also, he removed the
(probable) bug of embedded server never using SSL-dependent
functions. (libmysqld/Makefile.am didn't read ANY autoconf defs.)
Function specification:
SHA2( string cleartext, integer hash_length )
-> string hash, or NULL
where hash_length is one of 224, 256, 384, or 512. If either is
NULL or a length is unsupported, then the result is NULL. The
resulting string is always the length of the hash_length parameter
or is NULL.
Include the canonical hash examples from the NIST in the test
results.
---
Polish and address concerns of reviewers.
2010-04-13 17:04:45 +02:00
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
default:
|
|
|
|
push_warning_printf(current_thd,
|
|
|
|
MYSQL_ERROR::WARN_LEVEL_WARN,
|
|
|
|
ER_WRONG_PARAMETERS_TO_NATIVE_FCT,
|
|
|
|
ER(ER_WRONG_PARAMETERS_TO_NATIVE_FCT), "sha2");
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
The SHA2() function treats its parameter as being a case sensitive.
|
|
|
|
Thus we set binary collation on it so different instances of SHA2()
|
|
|
|
will be compared properly.
|
|
|
|
*/
|
|
|
|
|
|
|
|
args[0]->collation.set(
|
|
|
|
get_charset_by_csname(
|
|
|
|
args[0]->collation.collation->csname,
|
|
|
|
MY_CS_BINSORT,
|
|
|
|
MYF(0)),
|
|
|
|
DERIVATION_COERCIBLE);
|
|
|
|
#else
|
|
|
|
push_warning_printf(current_thd,
|
|
|
|
MYSQL_ERROR::WARN_LEVEL_WARN,
|
|
|
|
ER_FEATURE_DISABLED,
|
|
|
|
ER(ER_FEATURE_DISABLED),
|
|
|
|
"sha2", "--with-ssl");
|
2010-04-22 20:53:26 +02:00
|
|
|
#endif /* defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) */
|
Backport of:
ChangeSet@1.2703, 2007-12-07 09:35:28-05:00, cmiller@zippy.cornsilk.net +40 -0
Bug#13174: SHA2 function
Patch contributed from Bill Karwin, paper unnumbered CLA in Seattle
Implement SHA2 functions.
Chad added code to make it work with YaSSL. Also, he removed the
(probable) bug of embedded server never using SSL-dependent
functions. (libmysqld/Makefile.am didn't read ANY autoconf defs.)
Function specification:
SHA2( string cleartext, integer hash_length )
-> string hash, or NULL
where hash_length is one of 224, 256, 384, or 512. If either is
NULL or a length is unsupported, then the result is NULL. The
resulting string is always the length of the hash_length parameter
or is NULL.
Include the canonical hash examples from the NIST in the test
results.
---
Polish and address concerns of reviewers.
2010-04-13 17:04:45 +02:00
|
|
|
}
|
2002-06-14 13:14:30 +02:00
|
|
|
|
|
|
|
/* Implementation of AES encryption routines */
|
|
|
|
|
2002-06-11 11:37:48 +02:00
|
|
|
String *Item_func_aes_encrypt::val_str(String *str)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2002-09-17 22:46:53 +02:00
|
|
|
char key_buff[80];
|
2002-10-03 15:54:26 +02:00
|
|
|
String tmp_key_value(key_buff, sizeof(key_buff), system_charset_info);
|
2002-09-17 22:46:53 +02:00
|
|
|
String *sptr= args[0]->val_str(str); // String to encrypt
|
|
|
|
String *key= args[1]->val_str(&tmp_key_value); // key
|
2002-06-11 11:37:48 +02:00
|
|
|
int aes_length;
|
|
|
|
if (sptr && key) // we need both arguments to be not NULL
|
|
|
|
{
|
|
|
|
null_value=0;
|
2002-09-17 22:46:53 +02:00
|
|
|
aes_length=my_aes_get_size(sptr->length()); // Calculate result length
|
2002-12-04 23:14:51 +01:00
|
|
|
|
2002-09-17 22:46:53 +02:00
|
|
|
if (!str_value.alloc(aes_length)) // Ensure that memory is free
|
2002-06-11 11:37:48 +02:00
|
|
|
{
|
|
|
|
// finally encrypt directly to allocated buffer.
|
2002-09-17 22:46:53 +02:00
|
|
|
if (my_aes_encrypt(sptr->ptr(),sptr->length(), (char*) str_value.ptr(),
|
2002-06-18 23:22:30 +02:00
|
|
|
key->ptr(), key->length()) == aes_length)
|
2002-12-04 23:14:51 +01:00
|
|
|
{
|
2002-06-18 23:22:30 +02:00
|
|
|
// We got the expected result length
|
2002-09-17 22:46:53 +02:00
|
|
|
str_value.length((uint) aes_length);
|
|
|
|
return &str_value;
|
2002-06-11 11:37:48 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
null_value=1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-06-18 23:22:30 +02:00
|
|
|
|
2002-06-11 11:37:48 +02:00
|
|
|
void Item_func_aes_encrypt::fix_length_and_dec()
|
|
|
|
{
|
2002-06-18 23:22:30 +02:00
|
|
|
max_length=my_aes_get_size(args[0]->max_length);
|
2002-06-11 11:37:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
String *Item_func_aes_decrypt::val_str(String *str)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2002-09-17 22:46:53 +02:00
|
|
|
char key_buff[80];
|
2002-10-03 15:54:26 +02:00
|
|
|
String tmp_key_value(key_buff, sizeof(key_buff), system_charset_info);
|
|
|
|
String *sptr, *key;
|
2002-09-17 22:46:53 +02:00
|
|
|
DBUG_ENTER("Item_func_aes_decrypt::val_str");
|
|
|
|
|
|
|
|
sptr= args[0]->val_str(str); // String to decrypt
|
|
|
|
key= args[1]->val_str(&tmp_key_value); // Key
|
|
|
|
if (sptr && key) // Need to have both arguments not NULL
|
2002-06-11 11:37:48 +02:00
|
|
|
{
|
|
|
|
null_value=0;
|
2002-09-17 22:46:53 +02:00
|
|
|
if (!str_value.alloc(sptr->length())) // Ensure that memory is free
|
2002-06-11 11:37:48 +02:00
|
|
|
{
|
2002-06-18 23:22:30 +02:00
|
|
|
// finally decrypt directly to allocated buffer.
|
2002-09-17 22:46:53 +02:00
|
|
|
int length;
|
|
|
|
length=my_aes_decrypt(sptr->ptr(), sptr->length(),
|
|
|
|
(char*) str_value.ptr(),
|
2002-06-18 23:22:30 +02:00
|
|
|
key->ptr(), key->length());
|
|
|
|
if (length >= 0) // if we got correct data data
|
2002-12-04 23:14:51 +01:00
|
|
|
{
|
2002-09-17 22:46:53 +02:00
|
|
|
str_value.length((uint) length);
|
|
|
|
DBUG_RETURN(&str_value);
|
2002-06-14 13:14:30 +02:00
|
|
|
}
|
2002-06-11 11:37:48 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// Bad parameters. No memory or bad data will all go here
|
|
|
|
null_value=1;
|
2002-09-17 22:46:53 +02:00
|
|
|
DBUG_RETURN(0);
|
2002-06-11 11:37:48 +02:00
|
|
|
}
|
|
|
|
|
2002-09-17 22:46:53 +02:00
|
|
|
|
2002-06-11 11:37:48 +02:00
|
|
|
void Item_func_aes_decrypt::fix_length_and_dec()
|
|
|
|
{
|
|
|
|
max_length=args[0]->max_length;
|
2005-03-09 09:15:51 +01:00
|
|
|
maybe_null= 1;
|
2002-06-11 11:37:48 +02:00
|
|
|
}
|
2002-06-14 13:14:30 +02:00
|
|
|
|
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
/**
|
2002-06-18 23:22:30 +02:00
|
|
|
Concatenate args with the following premises:
|
2007-10-11 19:29:09 +02:00
|
|
|
If only one arg (which is ok), return value of arg;
|
2002-06-18 23:22:30 +02:00
|
|
|
Don't reallocate val_str() if not absolute necessary.
|
2000-07-31 21:29:14 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
String *Item_func_concat::val_str(String *str)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2000-07-31 21:29:14 +02:00
|
|
|
String *res,*res2,*use_as_buff;
|
|
|
|
uint i;
|
2006-05-25 23:24:14 +02:00
|
|
|
bool is_const= 0;
|
2000-07-31 21:29:14 +02:00
|
|
|
|
|
|
|
null_value=0;
|
|
|
|
if (!(res=args[0]->val_str(str)))
|
|
|
|
goto null;
|
|
|
|
use_as_buff= &tmp_value;
|
2006-06-16 21:46:37 +02:00
|
|
|
/* Item_subselect in --ps-protocol mode will state it as a non-const */
|
|
|
|
is_const= args[0]->const_item() || !args[0]->used_tables();
|
2000-07-31 21:29:14 +02:00
|
|
|
for (i=1 ; i < arg_count ; i++)
|
|
|
|
{
|
|
|
|
if (res->length() == 0)
|
|
|
|
{
|
|
|
|
if (!(res=args[i]->val_str(str)))
|
|
|
|
goto null;
|
2008-05-13 17:27:46 +02:00
|
|
|
/*
|
|
|
|
CONCAT accumulates its result in the result of its the first
|
|
|
|
non-empty argument. Because of this we need is_const to be
|
|
|
|
evaluated only for it.
|
|
|
|
*/
|
|
|
|
is_const= args[i]->const_item() || !args[i]->used_tables();
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!(res2=args[i]->val_str(use_as_buff)))
|
|
|
|
goto null;
|
|
|
|
if (res2->length() == 0)
|
|
|
|
continue;
|
2002-07-23 17:31:22 +02:00
|
|
|
if (res->length()+res2->length() >
|
|
|
|
current_thd->variables.max_allowed_packet)
|
2004-06-29 16:55:13 +02:00
|
|
|
{
|
|
|
|
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
|
|
|
ER_WARN_ALLOWED_PACKET_OVERFLOWED,
|
2004-07-21 18:27:45 +02:00
|
|
|
ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED), func_name(),
|
|
|
|
current_thd->variables.max_allowed_packet);
|
2004-06-29 16:55:13 +02:00
|
|
|
goto null;
|
|
|
|
}
|
2006-05-25 23:24:14 +02:00
|
|
|
if (!is_const && res->alloced_length() >= res->length()+res2->length())
|
2000-07-31 21:29:14 +02:00
|
|
|
{ // Use old buffer
|
|
|
|
res->append(*res2);
|
|
|
|
}
|
|
|
|
else if (str->alloced_length() >= res->length()+res2->length())
|
|
|
|
{
|
2010-04-02 22:30:22 +02:00
|
|
|
if (str->ptr() == res2->ptr())
|
2000-07-31 21:29:14 +02:00
|
|
|
str->replace(0,0,*res);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
str->copy(*res);
|
|
|
|
str->append(*res2);
|
|
|
|
}
|
2004-09-15 12:13:17 +02:00
|
|
|
res= str;
|
|
|
|
use_as_buff= &tmp_value;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
else if (res == &tmp_value)
|
|
|
|
{
|
|
|
|
if (res->append(*res2)) // Must be a blob
|
|
|
|
goto null;
|
|
|
|
}
|
|
|
|
else if (res2 == &tmp_value)
|
|
|
|
{ // This can happend only 1 time
|
|
|
|
if (tmp_value.replace(0,0,*res))
|
|
|
|
goto null;
|
|
|
|
res= &tmp_value;
|
|
|
|
use_as_buff=str; // Put next arg here
|
|
|
|
}
|
|
|
|
else if (tmp_value.is_alloced() && res2->ptr() >= tmp_value.ptr() &&
|
|
|
|
res2->ptr() <= tmp_value.ptr() + tmp_value.alloced_length())
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
This happens really seldom:
|
|
|
|
In this case res2 is sub string of tmp_value. We will
|
|
|
|
now work in place in tmp_value to set it to res | res2
|
|
|
|
*/
|
|
|
|
/* Chop the last characters in tmp_value that isn't in res2 */
|
|
|
|
tmp_value.length((uint32) (res2->ptr() - tmp_value.ptr()) +
|
|
|
|
res2->length());
|
|
|
|
/* Place res2 at start of tmp_value, remove chars before res2 */
|
|
|
|
if (tmp_value.replace(0,(uint32) (res2->ptr() - tmp_value.ptr()),
|
|
|
|
*res))
|
|
|
|
goto null;
|
|
|
|
res= &tmp_value;
|
|
|
|
use_as_buff=str; // Put next arg here
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // Two big const strings
|
2007-11-12 12:44:17 +01:00
|
|
|
/*
|
|
|
|
NOTE: We should be prudent in the initial allocation unit -- the
|
|
|
|
size of the arguments is a function of data distribution, which
|
|
|
|
can be any. Instead of overcommitting at the first row, we grow
|
|
|
|
the allocated amount by the factor of 2. This ensures that no
|
|
|
|
more than 25% of memory will be overcommitted on average.
|
|
|
|
*/
|
|
|
|
|
|
|
|
uint concat_len= res->length() + res2->length();
|
|
|
|
|
|
|
|
if (tmp_value.alloced_length() < concat_len)
|
|
|
|
{
|
|
|
|
if (tmp_value.alloced_length() == 0)
|
|
|
|
{
|
|
|
|
if (tmp_value.alloc(concat_len))
|
|
|
|
goto null;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
uint new_len = max(tmp_value.alloced_length() * 2, concat_len);
|
|
|
|
|
|
|
|
if (tmp_value.realloc(new_len))
|
|
|
|
goto null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (tmp_value.copy(*res) || tmp_value.append(*res2))
|
2000-07-31 21:29:14 +02:00
|
|
|
goto null;
|
2007-11-12 12:44:17 +01:00
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
res= &tmp_value;
|
|
|
|
use_as_buff=str;
|
|
|
|
}
|
2006-05-25 23:24:14 +02:00
|
|
|
is_const= 0;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
}
|
2003-08-05 09:52:37 +02:00
|
|
|
res->set_charset(collation.collation);
|
2000-07-31 21:29:14 +02:00
|
|
|
return res;
|
|
|
|
|
|
|
|
null:
|
|
|
|
null_value=1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Item_func_concat::fix_length_and_dec()
|
|
|
|
{
|
2005-07-19 18:25:05 +02:00
|
|
|
ulonglong max_result_length= 0;
|
2003-03-19 12:55:17 +01:00
|
|
|
|
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
2010-02-11 05:17:25 +01:00
|
|
|
if (agg_arg_charsets_for_string_result(collation, args, arg_count))
|
2003-07-04 15:12:23 +02:00
|
|
|
return;
|
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
for (uint i=0 ; i < arg_count ; i++)
|
2006-06-06 23:10:23 +02:00
|
|
|
{
|
|
|
|
if (args[i]->collation.collation->mbmaxlen != collation.collation->mbmaxlen)
|
|
|
|
max_result_length+= (args[i]->max_length /
|
|
|
|
args[i]->collation.collation->mbmaxlen) *
|
|
|
|
collation.collation->mbmaxlen;
|
|
|
|
else
|
|
|
|
max_result_length+= args[i]->max_length;
|
|
|
|
}
|
2003-03-19 12:55:17 +01:00
|
|
|
|
2005-07-19 18:25:05 +02:00
|
|
|
if (max_result_length >= MAX_BLOB_WIDTH)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2005-07-19 18:25:05 +02:00
|
|
|
max_result_length= MAX_BLOB_WIDTH;
|
|
|
|
maybe_null= 1;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
2005-07-19 18:25:05 +02:00
|
|
|
max_length= (ulong) max_result_length;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
/**
|
|
|
|
@details
|
2001-12-13 01:31:19 +01:00
|
|
|
Function des_encrypt() by tonu@spam.ee & monty
|
|
|
|
Works only if compiled with OpenSSL library support.
|
2007-10-11 19:29:09 +02:00
|
|
|
@return
|
|
|
|
A binary string where first character is CHAR(128 | key-number).
|
|
|
|
If one uses a string key key_number is 127.
|
|
|
|
Encryption result is longer than original by formula:
|
|
|
|
@code new_length= org_length + (8-(org_length % 8))+1 @endcode
|
2001-11-26 14:54:33 +01:00
|
|
|
*/
|
|
|
|
|
2001-11-06 21:57:14 +01:00
|
|
|
String *Item_func_des_encrypt::val_str(String *str)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2010-04-22 20:53:26 +02:00
|
|
|
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
|
2005-06-17 18:07:46 +02:00
|
|
|
uint code= ER_WRONG_PARAMETERS_TO_PROCEDURE;
|
2003-09-12 20:33:43 +02:00
|
|
|
DES_cblock ivec;
|
2001-12-10 10:02:26 +01:00
|
|
|
struct st_des_keyblock keyblock;
|
|
|
|
struct st_des_keyschedule keyschedule;
|
2001-12-13 02:36:36 +01:00
|
|
|
const char *append_str="********";
|
|
|
|
uint key_number, res_length, tail;
|
2001-12-13 01:31:19 +01:00
|
|
|
String *res= args[0]->val_str(str);
|
2001-11-06 21:57:14 +01:00
|
|
|
|
2005-06-27 19:31:00 +02:00
|
|
|
if ((null_value= args[0]->null_value))
|
|
|
|
return 0; // ENCRYPT(NULL) == NULL
|
2001-12-13 14:53:18 +01:00
|
|
|
if ((res_length=res->length()) == 0)
|
2003-09-18 15:58:02 +02:00
|
|
|
return &my_empty_string;
|
2001-12-13 01:31:19 +01:00
|
|
|
if (arg_count == 1)
|
2001-12-13 14:53:18 +01:00
|
|
|
{
|
|
|
|
/* Protect against someone doing FLUSH DES_KEY_FILE */
|
2010-01-07 06:42:07 +01:00
|
|
|
mysql_mutex_lock(&LOCK_des_key_file);
|
2001-12-13 14:53:18 +01:00
|
|
|
keyschedule= des_keyschedule[key_number=des_default_key];
|
2010-01-07 06:42:07 +01:00
|
|
|
mysql_mutex_unlock(&LOCK_des_key_file);
|
2001-12-13 14:53:18 +01:00
|
|
|
}
|
2001-12-13 02:36:36 +01:00
|
|
|
else if (args[1]->result_type() == INT_RESULT)
|
2001-12-13 01:31:19 +01:00
|
|
|
{
|
|
|
|
key_number= (uint) args[1]->val_int();
|
|
|
|
if (key_number > 9)
|
|
|
|
goto error;
|
2010-01-07 06:42:07 +01:00
|
|
|
mysql_mutex_lock(&LOCK_des_key_file);
|
2001-12-13 14:53:18 +01:00
|
|
|
keyschedule= des_keyschedule[key_number];
|
2010-01-07 06:42:07 +01:00
|
|
|
mysql_mutex_unlock(&LOCK_des_key_file);
|
2001-11-26 14:54:33 +01:00
|
|
|
}
|
2001-12-13 01:31:19 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
String *keystr=args[1]->val_str(&tmp_value);
|
|
|
|
if (!keystr)
|
|
|
|
goto error;
|
2001-12-13 14:53:18 +01:00
|
|
|
key_number=127; // User key string
|
2001-12-13 01:31:19 +01:00
|
|
|
|
|
|
|
/* We make good 24-byte (168 bit) key from given plaintext key with MD5 */
|
2001-12-13 14:53:18 +01:00
|
|
|
bzero((char*) &ivec,sizeof(ivec));
|
2001-12-13 01:31:19 +01:00
|
|
|
EVP_BytesToKey(EVP_des_ede3_cbc(),EVP_md5(),NULL,
|
|
|
|
(uchar*) keystr->ptr(), (int) keystr->length(),
|
|
|
|
1, (uchar*) &keyblock,ivec);
|
2003-09-12 20:33:43 +02:00
|
|
|
DES_set_key_unchecked(&keyblock.key1,&keyschedule.ks1);
|
|
|
|
DES_set_key_unchecked(&keyblock.key2,&keyschedule.ks2);
|
|
|
|
DES_set_key_unchecked(&keyblock.key3,&keyschedule.ks3);
|
2001-12-13 01:31:19 +01:00
|
|
|
}
|
|
|
|
|
2002-12-04 23:14:51 +01:00
|
|
|
/*
|
2001-12-13 01:31:19 +01:00
|
|
|
The problem: DES algorithm requires original data to be in 8-bytes
|
2002-12-04 23:14:51 +01:00
|
|
|
chunks. Missing bytes get filled with '*'s and result of encryption
|
|
|
|
can be up to 8 bytes longer than original string. When decrypted,
|
2001-12-13 01:31:19 +01:00
|
|
|
we do not know the size of original string :(
|
2001-12-13 14:53:18 +01:00
|
|
|
We add one byte with value 0x1..0x8 as the last byte of the padded
|
|
|
|
string marking change of string length.
|
2001-12-13 01:31:19 +01:00
|
|
|
*/
|
|
|
|
|
2009-04-17 17:52:57 +02:00
|
|
|
tail= 8 - (res_length % 8); // 1..8 marking extra length
|
2001-12-13 14:53:18 +01:00
|
|
|
res_length+=tail;
|
2009-04-17 17:52:57 +02:00
|
|
|
tmp_arg.realloc(res_length);
|
|
|
|
tmp_arg.length(0);
|
|
|
|
tmp_arg.append(res->ptr(), res->length());
|
2005-06-17 18:07:46 +02:00
|
|
|
code= ER_OUT_OF_RESOURCES;
|
2009-04-17 17:52:57 +02:00
|
|
|
if (tmp_arg.append(append_str, tail) || tmp_value.alloc(res_length+1))
|
2001-12-13 02:36:36 +01:00
|
|
|
goto error;
|
2009-04-17 17:52:57 +02:00
|
|
|
tmp_arg[res_length-1]=tail; // save extra length
|
|
|
|
tmp_value.realloc(res_length+1);
|
2001-12-13 14:53:18 +01:00
|
|
|
tmp_value.length(res_length+1);
|
|
|
|
tmp_value[0]=(char) (128 | key_number);
|
2001-12-13 01:31:19 +01:00
|
|
|
// Real encryption
|
2001-12-13 14:53:18 +01:00
|
|
|
bzero((char*) &ivec,sizeof(ivec));
|
2009-04-17 17:52:57 +02:00
|
|
|
DES_ede3_cbc_encrypt((const uchar*) (tmp_arg.ptr()),
|
2001-12-13 02:36:36 +01:00
|
|
|
(uchar*) (tmp_value.ptr()+1),
|
2001-12-13 14:53:18 +01:00
|
|
|
res_length,
|
2003-09-12 20:33:43 +02:00
|
|
|
&keyschedule.ks1,
|
|
|
|
&keyschedule.ks2,
|
|
|
|
&keyschedule.ks3,
|
2001-12-13 01:31:19 +01:00
|
|
|
&ivec, TRUE);
|
|
|
|
return &tmp_value;
|
|
|
|
|
|
|
|
error:
|
2009-09-10 11:18:29 +02:00
|
|
|
push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_WARN,
|
2005-06-17 18:07:46 +02:00
|
|
|
code, ER(code),
|
|
|
|
"des_encrypt");
|
|
|
|
#else
|
2009-09-10 11:18:29 +02:00
|
|
|
push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_WARN,
|
2005-06-17 18:07:46 +02:00
|
|
|
ER_FEATURE_DISABLED, ER(ER_FEATURE_DISABLED),
|
Backport of:
ChangeSet@1.2703, 2007-12-07 09:35:28-05:00, cmiller@zippy.cornsilk.net +40 -0
Bug#13174: SHA2 function
Patch contributed from Bill Karwin, paper unnumbered CLA in Seattle
Implement SHA2 functions.
Chad added code to make it work with YaSSL. Also, he removed the
(probable) bug of embedded server never using SSL-dependent
functions. (libmysqld/Makefile.am didn't read ANY autoconf defs.)
Function specification:
SHA2( string cleartext, integer hash_length )
-> string hash, or NULL
where hash_length is one of 224, 256, 384, or 512. If either is
NULL or a length is unsupported, then the result is NULL. The
resulting string is always the length of the hash_length parameter
or is NULL.
Include the canonical hash examples from the NIST in the test
results.
---
Polish and address concerns of reviewers.
2010-04-13 17:04:45 +02:00
|
|
|
"des_encrypt", "--with-ssl");
|
2010-04-22 20:53:26 +02:00
|
|
|
#endif /* defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) */
|
2001-11-06 21:57:14 +01:00
|
|
|
null_value=1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2001-12-13 01:31:19 +01:00
|
|
|
|
2001-11-06 21:57:14 +01:00
|
|
|
String *Item_func_des_decrypt::val_str(String *str)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2010-04-22 20:53:26 +02:00
|
|
|
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
|
2005-06-17 18:07:46 +02:00
|
|
|
uint code= ER_WRONG_PARAMETERS_TO_PROCEDURE;
|
2003-09-12 20:33:43 +02:00
|
|
|
DES_cblock ivec;
|
2001-12-10 10:02:26 +01:00
|
|
|
struct st_des_keyblock keyblock;
|
|
|
|
struct st_des_keyschedule keyschedule;
|
2001-12-13 01:31:19 +01:00
|
|
|
String *res= args[0]->val_str(str);
|
2005-08-25 21:34:42 +02:00
|
|
|
uint length,tail;
|
2001-11-06 21:57:14 +01:00
|
|
|
|
2005-08-25 21:34:42 +02:00
|
|
|
if ((null_value= args[0]->null_value))
|
2005-06-27 19:31:00 +02:00
|
|
|
return 0;
|
2005-08-25 21:34:42 +02:00
|
|
|
length= res->length();
|
2001-12-13 14:53:18 +01:00
|
|
|
if (length < 9 || (length % 8) != 1 || !((*res)[0] & 128))
|
2001-12-13 01:31:19 +01:00
|
|
|
return res; // Skip decryption if not encrypted
|
2001-12-06 13:10:51 +01:00
|
|
|
|
2001-12-13 01:31:19 +01:00
|
|
|
if (arg_count == 1) // If automatic uncompression
|
2001-11-26 14:54:33 +01:00
|
|
|
{
|
2001-12-13 14:53:18 +01:00
|
|
|
uint key_number=(uint) (*res)[0] & 127;
|
2001-12-13 01:31:19 +01:00
|
|
|
// Check if automatic key and that we have privilege to uncompress using it
|
2005-09-15 21:29:07 +02:00
|
|
|
if (!(current_thd->security_ctx->master_access & SUPER_ACL) ||
|
|
|
|
key_number > 9)
|
2001-12-13 01:31:19 +01:00
|
|
|
goto error;
|
2005-07-07 20:49:44 +02:00
|
|
|
|
2010-01-07 06:42:07 +01:00
|
|
|
mysql_mutex_lock(&LOCK_des_key_file);
|
2001-12-13 14:53:18 +01:00
|
|
|
keyschedule= des_keyschedule[key_number];
|
2010-01-07 06:42:07 +01:00
|
|
|
mysql_mutex_unlock(&LOCK_des_key_file);
|
2001-11-26 14:54:33 +01:00
|
|
|
}
|
2001-12-13 01:31:19 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
// We make good 24-byte (168 bit) key from given plaintext key with MD5
|
|
|
|
String *keystr=args[1]->val_str(&tmp_value);
|
2001-12-13 02:36:36 +01:00
|
|
|
if (!keystr)
|
2001-12-13 01:31:19 +01:00
|
|
|
goto error;
|
2001-12-13 02:36:36 +01:00
|
|
|
|
2001-12-13 14:53:18 +01:00
|
|
|
bzero((char*) &ivec,sizeof(ivec));
|
2001-12-13 01:31:19 +01:00
|
|
|
EVP_BytesToKey(EVP_des_ede3_cbc(),EVP_md5(),NULL,
|
|
|
|
(uchar*) keystr->ptr(),(int) keystr->length(),
|
|
|
|
1,(uchar*) &keyblock,ivec);
|
|
|
|
// Here we set all 64-bit keys (56 effective) one by one
|
2003-09-12 20:33:43 +02:00
|
|
|
DES_set_key_unchecked(&keyblock.key1,&keyschedule.ks1);
|
|
|
|
DES_set_key_unchecked(&keyblock.key2,&keyschedule.ks2);
|
2003-10-07 14:42:26 +02:00
|
|
|
DES_set_key_unchecked(&keyblock.key3,&keyschedule.ks3);
|
2001-12-13 01:31:19 +01:00
|
|
|
}
|
2005-06-17 18:07:46 +02:00
|
|
|
code= ER_OUT_OF_RESOURCES;
|
2001-12-13 14:53:18 +01:00
|
|
|
if (tmp_value.alloc(length-1))
|
2001-12-13 02:36:36 +01:00
|
|
|
goto error;
|
2001-12-13 14:53:18 +01:00
|
|
|
|
|
|
|
bzero((char*) &ivec,sizeof(ivec));
|
2003-09-12 20:33:43 +02:00
|
|
|
DES_ede3_cbc_encrypt((const uchar*) res->ptr()+1,
|
2001-12-13 02:36:36 +01:00
|
|
|
(uchar*) (tmp_value.ptr()),
|
2001-12-13 14:53:18 +01:00
|
|
|
length-1,
|
2003-09-12 20:33:43 +02:00
|
|
|
&keyschedule.ks1,
|
|
|
|
&keyschedule.ks2,
|
|
|
|
&keyschedule.ks3,
|
2001-12-13 01:31:19 +01:00
|
|
|
&ivec, FALSE);
|
2001-12-13 14:53:18 +01:00
|
|
|
/* Restore old length of key */
|
|
|
|
if ((tail=(uint) (uchar) tmp_value[length-2]) > 8)
|
2005-06-17 18:07:46 +02:00
|
|
|
goto wrong_key; // Wrong key
|
2001-12-13 14:53:18 +01:00
|
|
|
tmp_value.length(length-1-tail);
|
2001-12-13 01:31:19 +01:00
|
|
|
return &tmp_value;
|
|
|
|
|
|
|
|
error:
|
2009-09-10 11:18:29 +02:00
|
|
|
push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_WARN,
|
2005-06-17 18:07:46 +02:00
|
|
|
code, ER(code),
|
|
|
|
"des_decrypt");
|
|
|
|
wrong_key:
|
|
|
|
#else
|
2009-09-10 11:18:29 +02:00
|
|
|
push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_WARN,
|
2005-06-17 18:07:46 +02:00
|
|
|
ER_FEATURE_DISABLED, ER(ER_FEATURE_DISABLED),
|
Backport of:
ChangeSet@1.2703, 2007-12-07 09:35:28-05:00, cmiller@zippy.cornsilk.net +40 -0
Bug#13174: SHA2 function
Patch contributed from Bill Karwin, paper unnumbered CLA in Seattle
Implement SHA2 functions.
Chad added code to make it work with YaSSL. Also, he removed the
(probable) bug of embedded server never using SSL-dependent
functions. (libmysqld/Makefile.am didn't read ANY autoconf defs.)
Function specification:
SHA2( string cleartext, integer hash_length )
-> string hash, or NULL
where hash_length is one of 224, 256, 384, or 512. If either is
NULL or a length is unsupported, then the result is NULL. The
resulting string is always the length of the hash_length parameter
or is NULL.
Include the canonical hash examples from the NIST in the test
results.
---
Polish and address concerns of reviewers.
2010-04-13 17:04:45 +02:00
|
|
|
"des_decrypt", "--with-ssl");
|
2010-04-22 20:53:26 +02:00
|
|
|
#endif /* defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) */
|
2001-11-06 21:57:14 +01:00
|
|
|
null_value=1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
/**
|
2001-12-13 01:31:19 +01:00
|
|
|
concat with separator. First arg is the separator
|
|
|
|
concat_ws takes at least two arguments.
|
2000-07-31 21:29:14 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
String *Item_func_concat_ws::val_str(String *str)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2000-07-31 21:29:14 +02:00
|
|
|
char tmp_str_buff[10];
|
2002-05-17 13:29:52 +02:00
|
|
|
String tmp_sep_str(tmp_str_buff, sizeof(tmp_str_buff),default_charset_info),
|
2000-07-31 21:29:14 +02:00
|
|
|
*sep_str, *res, *res2,*use_as_buff;
|
|
|
|
uint i;
|
2009-09-10 12:24:07 +02:00
|
|
|
bool is_const= 0;
|
2000-07-31 21:29:14 +02:00
|
|
|
|
|
|
|
null_value=0;
|
2004-10-28 08:43:31 +02:00
|
|
|
if (!(sep_str= args[0]->val_str(&tmp_sep_str)))
|
2000-07-31 21:29:14 +02:00
|
|
|
goto null;
|
|
|
|
|
|
|
|
use_as_buff= &tmp_value;
|
2001-03-21 00:02:22 +01:00
|
|
|
str->length(0); // QQ; Should be removed
|
2000-07-31 21:29:14 +02:00
|
|
|
res=str;
|
|
|
|
|
2003-06-05 14:06:19 +02:00
|
|
|
// Skip until non-null argument is found.
|
2000-07-31 21:29:14 +02:00
|
|
|
// If not, return the empty string
|
2004-10-28 08:43:31 +02:00
|
|
|
for (i=1; i < arg_count; i++)
|
2003-06-05 14:06:19 +02:00
|
|
|
if ((res= args[i]->val_str(str)))
|
2009-09-10 12:24:07 +02:00
|
|
|
{
|
|
|
|
is_const= args[i]->const_item() || !args[i]->used_tables();
|
2001-03-23 19:38:42 +01:00
|
|
|
break;
|
2009-09-10 12:24:07 +02:00
|
|
|
}
|
|
|
|
|
2001-03-21 00:02:22 +01:00
|
|
|
if (i == arg_count)
|
2003-09-18 15:58:02 +02:00
|
|
|
return &my_empty_string;
|
2000-07-31 21:29:14 +02:00
|
|
|
|
|
|
|
for (i++; i < arg_count ; i++)
|
|
|
|
{
|
2003-06-05 14:06:19 +02:00
|
|
|
if (!(res2= args[i]->val_str(use_as_buff)))
|
|
|
|
continue; // Skip NULL
|
2001-03-21 00:02:22 +01:00
|
|
|
|
|
|
|
if (res->length() + sep_str->length() + res2->length() >
|
2002-07-23 17:31:22 +02:00
|
|
|
current_thd->variables.max_allowed_packet)
|
2004-06-29 16:55:13 +02:00
|
|
|
{
|
|
|
|
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
|
|
|
ER_WARN_ALLOWED_PACKET_OVERFLOWED,
|
2004-07-21 18:27:45 +02:00
|
|
|
ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED), func_name(),
|
|
|
|
current_thd->variables.max_allowed_packet);
|
2004-06-29 16:55:13 +02:00
|
|
|
goto null;
|
|
|
|
}
|
2009-09-10 12:24:07 +02:00
|
|
|
if (!is_const && res->alloced_length() >=
|
2001-03-21 00:02:22 +01:00
|
|
|
res->length() + sep_str->length() + res2->length())
|
|
|
|
{ // Use old buffer
|
|
|
|
res->append(*sep_str); // res->length() > 0 always
|
|
|
|
res->append(*res2);
|
|
|
|
}
|
|
|
|
else if (str->alloced_length() >=
|
|
|
|
res->length() + sep_str->length() + res2->length())
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2001-03-23 19:38:42 +01:00
|
|
|
/* We have room in str; We can't get any errors here */
|
2010-01-13 05:16:36 +01:00
|
|
|
if (str->ptr() == res2->ptr())
|
|
|
|
{ // This is quite uncommon!
|
2001-03-23 19:38:42 +01:00
|
|
|
str->replace(0,0,*sep_str);
|
|
|
|
str->replace(0,0,*res);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
str->copy(*res);
|
|
|
|
str->append(*sep_str);
|
|
|
|
str->append(*res2);
|
|
|
|
}
|
2001-03-21 00:02:22 +01:00
|
|
|
res=str;
|
|
|
|
use_as_buff= &tmp_value;
|
|
|
|
}
|
|
|
|
else if (res == &tmp_value)
|
|
|
|
{
|
2001-03-23 19:38:42 +01:00
|
|
|
if (res->append(*sep_str) || res->append(*res2))
|
2001-03-21 00:02:22 +01:00
|
|
|
goto null; // Must be a blob
|
|
|
|
}
|
2001-03-23 19:38:42 +01:00
|
|
|
else if (res2 == &tmp_value)
|
|
|
|
{ // This can happend only 1 time
|
|
|
|
if (tmp_value.replace(0,0,*sep_str) || tmp_value.replace(0,0,*res))
|
|
|
|
goto null;
|
|
|
|
res= &tmp_value;
|
|
|
|
use_as_buff=str; // Put next arg here
|
|
|
|
}
|
2001-03-21 00:02:22 +01:00
|
|
|
else if (tmp_value.is_alloced() && res2->ptr() >= tmp_value.ptr() &&
|
2001-03-23 19:38:42 +01:00
|
|
|
res2->ptr() < tmp_value.ptr() + tmp_value.alloced_length())
|
2001-03-21 00:02:22 +01:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
This happens really seldom:
|
|
|
|
In this case res2 is sub string of tmp_value. We will
|
2001-03-23 19:38:42 +01:00
|
|
|
now work in place in tmp_value to set it to res | sep_str | res2
|
2001-03-21 00:02:22 +01:00
|
|
|
*/
|
|
|
|
/* Chop the last characters in tmp_value that isn't in res2 */
|
|
|
|
tmp_value.length((uint32) (res2->ptr() - tmp_value.ptr()) +
|
|
|
|
res2->length());
|
|
|
|
/* Place res2 at start of tmp_value, remove chars before res2 */
|
|
|
|
if (tmp_value.replace(0,(uint32) (res2->ptr() - tmp_value.ptr()),
|
2001-03-23 19:38:42 +01:00
|
|
|
*res) ||
|
|
|
|
tmp_value.replace(res->length(),0, *sep_str))
|
2001-03-21 00:02:22 +01:00
|
|
|
goto null;
|
|
|
|
res= &tmp_value;
|
|
|
|
use_as_buff=str; // Put next arg here
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // Two big const strings
|
2007-11-12 12:44:17 +01:00
|
|
|
/*
|
|
|
|
NOTE: We should be prudent in the initial allocation unit -- the
|
|
|
|
size of the arguments is a function of data distribution, which can
|
|
|
|
be any. Instead of overcommitting at the first row, we grow the
|
|
|
|
allocated amount by the factor of 2. This ensures that no more than
|
|
|
|
25% of memory will be overcommitted on average.
|
|
|
|
*/
|
|
|
|
|
|
|
|
uint concat_len= res->length() + sep_str->length() + res2->length();
|
|
|
|
|
|
|
|
if (tmp_value.alloced_length() < concat_len)
|
|
|
|
{
|
|
|
|
if (tmp_value.alloced_length() == 0)
|
|
|
|
{
|
|
|
|
if (tmp_value.alloc(concat_len))
|
|
|
|
goto null;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
uint new_len = max(tmp_value.alloced_length() * 2, concat_len);
|
|
|
|
|
|
|
|
if (tmp_value.realloc(new_len))
|
|
|
|
goto null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (tmp_value.copy(*res) ||
|
2001-03-21 00:02:22 +01:00
|
|
|
tmp_value.append(*sep_str) ||
|
|
|
|
tmp_value.append(*res2))
|
|
|
|
goto null;
|
|
|
|
res= &tmp_value;
|
|
|
|
use_as_buff=str;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
}
|
2003-08-05 09:52:37 +02:00
|
|
|
res->set_charset(collation.collation);
|
2000-07-31 21:29:14 +02:00
|
|
|
return res;
|
|
|
|
|
|
|
|
null:
|
|
|
|
null_value=1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Item_func_concat_ws::fix_length_and_dec()
|
|
|
|
{
|
2005-07-19 18:25:05 +02:00
|
|
|
ulonglong max_result_length;
|
2004-10-28 08:43:31 +02:00
|
|
|
|
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
2010-02-11 05:17:25 +01:00
|
|
|
if (agg_arg_charsets_for_string_result(collation, args, arg_count))
|
2004-10-28 08:43:31 +02:00
|
|
|
return;
|
|
|
|
|
2004-10-29 13:06:51 +02:00
|
|
|
/*
|
|
|
|
arg_count cannot be less than 2,
|
|
|
|
it is done on parser level in sql_yacc.yy
|
|
|
|
so, (arg_count - 2) is safe here.
|
|
|
|
*/
|
2005-07-19 18:25:05 +02:00
|
|
|
max_result_length= (ulonglong) args[0]->max_length * (arg_count - 2);
|
2004-10-28 08:43:31 +02:00
|
|
|
for (uint i=1 ; i < arg_count ; i++)
|
2005-07-19 18:25:05 +02:00
|
|
|
max_result_length+=args[i]->max_length;
|
2004-10-28 08:43:31 +02:00
|
|
|
|
2005-07-19 18:25:05 +02:00
|
|
|
if (max_result_length >= MAX_BLOB_WIDTH)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2005-07-19 18:25:05 +02:00
|
|
|
max_result_length= MAX_BLOB_WIDTH;
|
|
|
|
maybe_null= 1;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
2005-07-19 18:25:05 +02:00
|
|
|
max_length= (ulong) max_result_length;
|
2000-11-07 03:39:13 +01:00
|
|
|
}
|
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
|
|
|
|
String *Item_func_reverse::val_str(String *str)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2000-07-31 21:29:14 +02:00
|
|
|
String *res = args[0]->val_str(str);
|
2006-07-06 20:11:49 +02:00
|
|
|
char *ptr, *end, *tmp;
|
2000-07-31 21:29:14 +02:00
|
|
|
|
|
|
|
if ((null_value=args[0]->null_value))
|
|
|
|
return 0;
|
|
|
|
/* An empty string is a special case as the string pointer may be null */
|
|
|
|
if (!res->length())
|
2003-09-18 15:58:02 +02:00
|
|
|
return &my_empty_string;
|
2006-07-06 20:11:49 +02:00
|
|
|
if (tmp_value.alloced_length() < res->length() &&
|
|
|
|
tmp_value.realloc(res->length()))
|
|
|
|
{
|
|
|
|
null_value= 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
tmp_value.length(res->length());
|
|
|
|
tmp_value.set_charset(res->charset());
|
|
|
|
ptr= (char *) res->ptr();
|
|
|
|
end= ptr + res->length();
|
|
|
|
tmp= (char *) tmp_value.ptr() + tmp_value.length();
|
2000-07-31 21:29:14 +02:00
|
|
|
#ifdef USE_MB
|
2003-03-13 12:34:46 +01:00
|
|
|
if (use_mb(res->charset()))
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
|
|
|
register uint32 l;
|
|
|
|
while (ptr < end)
|
|
|
|
{
|
2006-07-06 20:11:49 +02:00
|
|
|
if ((l= my_ismbchar(res->charset(),ptr,end)))
|
|
|
|
{
|
|
|
|
tmp-= l;
|
|
|
|
memcpy(tmp,ptr,l);
|
|
|
|
ptr+= l;
|
|
|
|
}
|
2000-07-31 21:29:14 +02:00
|
|
|
else
|
2006-07-06 20:11:49 +02:00
|
|
|
*--tmp= *ptr++;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif /* USE_MB */
|
|
|
|
{
|
|
|
|
while (ptr < end)
|
2006-07-06 20:11:49 +02:00
|
|
|
*--tmp= *ptr++;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
2006-07-06 20:11:49 +02:00
|
|
|
return &tmp_value;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Item_func_reverse::fix_length_and_dec()
|
|
|
|
{
|
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
2010-02-11 05:17:25 +01:00
|
|
|
agg_arg_charsets_for_string_result(collation, args, 1);
|
|
|
|
fix_char_length(args[0]->max_char_length());
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
/**
|
|
|
|
Replace all occurences of string2 in string1 with string3.
|
|
|
|
|
|
|
|
Don't reallocate val_str() if not needed.
|
2000-07-31 21:29:14 +02:00
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
@todo
|
|
|
|
Fix that this works with binary strings when using USE_MB
|
|
|
|
*/
|
2000-07-31 21:29:14 +02:00
|
|
|
|
|
|
|
String *Item_func_replace::val_str(String *str)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2000-07-31 21:29:14 +02:00
|
|
|
String *res,*res2,*res3;
|
2001-05-09 22:02:36 +02:00
|
|
|
int offset;
|
2000-07-31 21:29:14 +02:00
|
|
|
uint from_length,to_length;
|
|
|
|
bool alloced=0;
|
|
|
|
#ifdef USE_MB
|
|
|
|
const char *ptr,*end,*strend,*search,*search_end;
|
|
|
|
register uint32 l;
|
2003-02-12 20:55:37 +01:00
|
|
|
bool binary_cmp;
|
2000-07-31 21:29:14 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
null_value=0;
|
|
|
|
res=args[0]->val_str(str);
|
|
|
|
if (args[0]->null_value)
|
|
|
|
goto null;
|
|
|
|
res2=args[1]->val_str(&tmp_value);
|
|
|
|
if (args[1]->null_value)
|
|
|
|
goto null;
|
|
|
|
|
2003-06-26 12:45:04 +02:00
|
|
|
res->set_charset(collation.collation);
|
|
|
|
|
2002-03-14 17:52:48 +01:00
|
|
|
#ifdef USE_MB
|
2003-07-02 15:34:43 +02:00
|
|
|
binary_cmp = ((res->charset()->state & MY_CS_BINSORT) || !use_mb(res->charset()));
|
2002-03-14 17:52:48 +01:00
|
|
|
#endif
|
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
if (res2->length() == 0)
|
|
|
|
return res;
|
|
|
|
#ifndef USE_MB
|
|
|
|
if ((offset=res->strstr(*res2)) < 0)
|
|
|
|
return res;
|
|
|
|
#else
|
2001-05-09 22:02:36 +02:00
|
|
|
offset=0;
|
2003-02-12 20:55:37 +01:00
|
|
|
if (binary_cmp && (offset=res->strstr(*res2)) < 0)
|
2000-07-31 21:29:14 +02:00
|
|
|
return res;
|
|
|
|
#endif
|
|
|
|
if (!(res3=args[2]->val_str(&tmp_value2)))
|
|
|
|
goto null;
|
|
|
|
from_length= res2->length();
|
|
|
|
to_length= res3->length();
|
|
|
|
|
|
|
|
#ifdef USE_MB
|
2003-02-12 20:55:37 +01:00
|
|
|
if (!binary_cmp)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
|
|
|
search=res2->ptr();
|
|
|
|
search_end=search+from_length;
|
|
|
|
redo:
|
|
|
|
ptr=res->ptr()+offset;
|
|
|
|
strend=res->ptr()+res->length();
|
|
|
|
end=strend-from_length+1;
|
|
|
|
while (ptr < end)
|
|
|
|
{
|
|
|
|
if (*ptr == *search)
|
|
|
|
{
|
|
|
|
register char *i,*j;
|
|
|
|
i=(char*) ptr+1; j=(char*) search+1;
|
|
|
|
while (j != search_end)
|
2004-02-02 17:25:39 +01:00
|
|
|
if (*i++ != *j++) goto skip;
|
2000-08-23 14:02:27 +02:00
|
|
|
offset= (int) (ptr-res->ptr());
|
2002-07-23 17:31:22 +02:00
|
|
|
if (res->length()-from_length + to_length >
|
|
|
|
current_thd->variables.max_allowed_packet)
|
2004-06-29 16:55:13 +02:00
|
|
|
{
|
|
|
|
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
|
|
|
ER_WARN_ALLOWED_PACKET_OVERFLOWED,
|
|
|
|
ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
|
2004-07-21 18:27:45 +02:00
|
|
|
func_name(),
|
|
|
|
current_thd->variables.max_allowed_packet);
|
2004-06-29 16:55:13 +02:00
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
goto null;
|
2004-06-29 16:55:13 +02:00
|
|
|
}
|
2000-07-31 21:29:14 +02:00
|
|
|
if (!alloced)
|
|
|
|
{
|
|
|
|
alloced=1;
|
|
|
|
res=copy_if_not_alloced(str,res,res->length()+to_length);
|
|
|
|
}
|
|
|
|
res->replace((uint) offset,from_length,*res3);
|
2001-05-09 22:02:36 +02:00
|
|
|
offset+=(int) to_length;
|
2000-07-31 21:29:14 +02:00
|
|
|
goto redo;
|
|
|
|
}
|
2004-02-02 17:25:39 +01:00
|
|
|
skip:
|
2002-03-19 17:03:10 +01:00
|
|
|
if ((l=my_ismbchar(res->charset(), ptr,strend))) ptr+=l;
|
2000-07-31 21:29:14 +02:00
|
|
|
else ++ptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif /* USE_MB */
|
|
|
|
do
|
|
|
|
{
|
2002-07-23 17:31:22 +02:00
|
|
|
if (res->length()-from_length + to_length >
|
|
|
|
current_thd->variables.max_allowed_packet)
|
2004-06-29 16:55:13 +02:00
|
|
|
{
|
|
|
|
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
|
|
|
ER_WARN_ALLOWED_PACKET_OVERFLOWED,
|
2004-07-21 18:27:45 +02:00
|
|
|
ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED), func_name(),
|
|
|
|
current_thd->variables.max_allowed_packet);
|
2000-07-31 21:29:14 +02:00
|
|
|
goto null;
|
2004-06-29 16:55:13 +02:00
|
|
|
}
|
2000-07-31 21:29:14 +02:00
|
|
|
if (!alloced)
|
|
|
|
{
|
|
|
|
alloced=1;
|
|
|
|
res=copy_if_not_alloced(str,res,res->length()+to_length);
|
|
|
|
}
|
|
|
|
res->replace((uint) offset,from_length,*res3);
|
|
|
|
offset+=(int) to_length;
|
|
|
|
}
|
2000-10-16 23:47:15 +02:00
|
|
|
while ((offset=res->strstr(*res2,(uint) offset)) >= 0);
|
2000-07-31 21:29:14 +02:00
|
|
|
return res;
|
|
|
|
|
|
|
|
null:
|
|
|
|
null_value=1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Item_func_replace::fix_length_and_dec()
|
|
|
|
{
|
2005-07-19 18:25:05 +02:00
|
|
|
ulonglong max_result_length= args[0]->max_length;
|
2000-07-31 21:29:14 +02:00
|
|
|
int diff=(int) (args[2]->max_length - args[1]->max_length);
|
|
|
|
if (diff > 0 && args[1]->max_length)
|
|
|
|
{ // Calculate of maxreplaces
|
2005-07-19 18:25:05 +02:00
|
|
|
ulonglong max_substrs= max_result_length/args[1]->max_length;
|
|
|
|
max_result_length+= max_substrs * (uint) diff;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
2005-07-19 18:25:05 +02:00
|
|
|
if (max_result_length >= MAX_BLOB_WIDTH)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2005-07-19 18:25:05 +02:00
|
|
|
max_result_length= MAX_BLOB_WIDTH;
|
|
|
|
maybe_null= 1;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
2005-07-19 18:25:05 +02:00
|
|
|
max_length= (ulong) max_result_length;
|
2003-06-19 08:36:44 +02:00
|
|
|
|
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
2010-02-11 05:17:25 +01:00
|
|
|
if (agg_arg_charsets_for_comparison(collation, args, 3))
|
2003-07-04 15:12:23 +02:00
|
|
|
return;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
String *Item_func_insert::val_str(String *str)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2000-07-31 21:29:14 +02:00
|
|
|
String *res,*res2;
|
2006-11-08 16:11:02 +01:00
|
|
|
longlong start, length; /* must be longlong to avoid truncation */
|
2000-07-31 21:29:14 +02:00
|
|
|
|
|
|
|
null_value=0;
|
|
|
|
res=args[0]->val_str(str);
|
|
|
|
res2=args[3]->val_str(&tmp_value);
|
2006-11-08 16:11:02 +01:00
|
|
|
start= args[1]->val_int() - 1;
|
|
|
|
length= args[2]->val_int();
|
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
if (args[0]->null_value || args[1]->null_value || args[2]->null_value ||
|
|
|
|
args[3]->null_value)
|
|
|
|
goto null; /* purecov: inspected */
|
2006-11-08 16:11:02 +01:00
|
|
|
|
2007-03-09 11:47:12 +01:00
|
|
|
if ((start < 0) || (start > res->length()))
|
2006-11-08 16:11:02 +01:00
|
|
|
return res; // Wrong param; skip insert
|
2007-03-09 11:47:12 +01:00
|
|
|
if ((length < 0) || (length > res->length()))
|
|
|
|
length= res->length();
|
2006-11-08 16:11:02 +01:00
|
|
|
|
|
|
|
/* start and length are now sufficiently valid to pass to charpos function */
|
2006-11-30 02:40:42 +01:00
|
|
|
start= res->charpos((int) start);
|
|
|
|
length= res->charpos((int) length, (uint32) start);
|
2006-11-08 16:11:02 +01:00
|
|
|
|
|
|
|
/* Re-testing with corrected params */
|
2007-03-09 11:47:12 +01:00
|
|
|
if (start > res->length())
|
|
|
|
return res; /* purecov: inspected */ // Wrong param; skip insert
|
2006-11-08 16:11:02 +01:00
|
|
|
if (length > res->length() - start)
|
|
|
|
length= res->length() - start;
|
|
|
|
|
2006-11-27 17:16:08 +01:00
|
|
|
if ((ulonglong) (res->length() - length + res2->length()) >
|
|
|
|
(ulonglong) current_thd->variables.max_allowed_packet)
|
2004-06-29 16:55:13 +02:00
|
|
|
{
|
|
|
|
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
|
|
|
ER_WARN_ALLOWED_PACKET_OVERFLOWED,
|
2004-07-21 18:27:45 +02:00
|
|
|
ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
|
|
|
|
func_name(), current_thd->variables.max_allowed_packet);
|
2004-06-29 16:55:13 +02:00
|
|
|
goto null;
|
|
|
|
}
|
2000-07-31 21:29:14 +02:00
|
|
|
res=copy_if_not_alloced(str,res,res->length());
|
2006-11-30 02:40:42 +01:00
|
|
|
res->replace((uint32) start,(uint32) length,*res2);
|
2000-07-31 21:29:14 +02:00
|
|
|
return res;
|
|
|
|
null:
|
|
|
|
null_value=1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Item_func_insert::fix_length_and_dec()
|
|
|
|
{
|
2005-07-19 18:25:05 +02:00
|
|
|
ulonglong max_result_length;
|
|
|
|
|
2006-06-30 09:26:36 +02:00
|
|
|
// Handle character set for args[0] and args[3].
|
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
2010-02-11 05:17:25 +01:00
|
|
|
if (agg_arg_charsets_for_string_result(collation, args, 2, 3))
|
2004-11-02 13:02:12 +01:00
|
|
|
return;
|
2005-07-19 18:25:05 +02:00
|
|
|
max_result_length= ((ulonglong) args[0]->max_length+
|
|
|
|
(ulonglong) args[3]->max_length);
|
|
|
|
if (max_result_length >= MAX_BLOB_WIDTH)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2005-07-19 18:25:05 +02:00
|
|
|
max_result_length= MAX_BLOB_WIDTH;
|
|
|
|
maybe_null= 1;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
2005-07-19 18:25:05 +02:00
|
|
|
max_length= (ulong) max_result_length;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-06-06 13:54:15 +02:00
|
|
|
String *Item_str_conv::val_str(String *str)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2000-07-31 21:29:14 +02:00
|
|
|
String *res;
|
|
|
|
if (!(res=args[0]->val_str(str)))
|
|
|
|
{
|
|
|
|
null_value=1; /* purecov: inspected */
|
|
|
|
return 0; /* purecov: inspected */
|
|
|
|
}
|
|
|
|
null_value=0;
|
2005-06-06 13:54:15 +02:00
|
|
|
if (multiply == 1)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2005-06-06 13:54:15 +02:00
|
|
|
uint len;
|
|
|
|
res= copy_if_not_alloced(str,res,res->length());
|
|
|
|
len= converter(collation.collation, (char*) res->ptr(), res->length(),
|
|
|
|
(char*) res->ptr(), res->length());
|
|
|
|
DBUG_ASSERT(len <= res->length());
|
|
|
|
res->length(len);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
uint len= res->length() * multiply;
|
|
|
|
tmp_value.alloc(len);
|
|
|
|
tmp_value.set_charset(collation.collation);
|
|
|
|
len= converter(collation.collation, (char*) res->ptr(), res->length(),
|
|
|
|
(char*) tmp_value.ptr(), len);
|
|
|
|
tmp_value.length(len);
|
|
|
|
res= &tmp_value;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-08-13 15:11:25 +02:00
|
|
|
void Item_func_lcase::fix_length_and_dec()
|
|
|
|
{
|
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
2010-02-11 05:17:25 +01:00
|
|
|
agg_arg_charsets_for_string_result(collation, args, 1);
|
2007-08-13 15:11:25 +02:00
|
|
|
multiply= collation.collation->casedn_multiply;
|
|
|
|
converter= collation.collation->cset->casedn;
|
|
|
|
max_length= args[0]->max_length * multiply;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Item_func_ucase::fix_length_and_dec()
|
|
|
|
{
|
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
2010-02-11 05:17:25 +01:00
|
|
|
agg_arg_charsets_for_string_result(collation, args, 1);
|
2007-08-13 15:11:25 +02:00
|
|
|
multiply= collation.collation->caseup_multiply;
|
|
|
|
converter= collation.collation->cset->caseup;
|
|
|
|
max_length= args[0]->max_length * multiply;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
String *Item_func_left::val_str(String *str)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2006-11-08 16:11:02 +01:00
|
|
|
String *res= args[0]->val_str(str);
|
|
|
|
|
|
|
|
/* must be longlong to avoid truncation */
|
|
|
|
longlong length= args[1]->val_int();
|
2004-08-13 12:04:10 +02:00
|
|
|
uint char_pos;
|
2000-07-31 21:29:14 +02:00
|
|
|
|
2006-07-07 14:06:30 +02:00
|
|
|
if ((null_value=(args[0]->null_value || args[1]->null_value)))
|
2000-07-31 21:29:14 +02:00
|
|
|
return 0;
|
2006-11-08 16:11:02 +01:00
|
|
|
|
|
|
|
/* if "unsigned_flag" is set, we have a *huge* positive number. */
|
|
|
|
if ((length <= 0) && (!args[1]->unsigned_flag))
|
2003-09-18 15:58:02 +02:00
|
|
|
return &my_empty_string;
|
2006-11-08 16:11:02 +01:00
|
|
|
|
|
|
|
if ((res->length() <= (ulonglong) length) ||
|
2006-11-30 02:40:42 +01:00
|
|
|
(res->length() <= (char_pos= res->charpos((int) length))))
|
2004-06-08 15:01:15 +02:00
|
|
|
return res;
|
2004-12-09 23:17:43 +01:00
|
|
|
|
|
|
|
tmp_value.set(*res, 0, char_pos);
|
|
|
|
return &tmp_value;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Item_str_func::left_right_max_length()
|
|
|
|
{
|
|
|
|
max_length=args[0]->max_length;
|
|
|
|
if (args[1]->const_item())
|
|
|
|
{
|
2003-08-05 09:52:37 +02:00
|
|
|
int length=(int) args[1]->val_int()*collation.collation->mbmaxlen;
|
2000-07-31 21:29:14 +02:00
|
|
|
if (length <= 0)
|
|
|
|
max_length=0;
|
|
|
|
else
|
|
|
|
set_if_smaller(max_length,(uint) length);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Item_func_left::fix_length_and_dec()
|
|
|
|
{
|
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
2010-02-11 05:17:25 +01:00
|
|
|
agg_arg_charsets_for_string_result(collation, args, 1);
|
2000-07-31 21:29:14 +02:00
|
|
|
left_right_max_length();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
String *Item_func_right::val_str(String *str)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2006-11-08 16:11:02 +01:00
|
|
|
String *res= args[0]->val_str(str);
|
|
|
|
/* must be longlong to avoid truncation */
|
|
|
|
longlong length= args[1]->val_int();
|
2000-07-31 21:29:14 +02:00
|
|
|
|
2006-07-07 14:06:30 +02:00
|
|
|
if ((null_value=(args[0]->null_value || args[1]->null_value)))
|
2000-07-31 21:29:14 +02:00
|
|
|
return 0; /* purecov: inspected */
|
2006-11-08 16:11:02 +01:00
|
|
|
|
|
|
|
/* if "unsigned_flag" is set, we have a *huge* positive number. */
|
|
|
|
if ((length <= 0) && (!args[1]->unsigned_flag))
|
2003-09-18 15:58:02 +02:00
|
|
|
return &my_empty_string; /* purecov: inspected */
|
2006-11-08 16:11:02 +01:00
|
|
|
|
|
|
|
if (res->length() <= (ulonglong) length)
|
2000-07-31 21:29:14 +02:00
|
|
|
return res; /* purecov: inspected */
|
2003-01-31 14:37:28 +01:00
|
|
|
|
2004-01-15 09:12:55 +01:00
|
|
|
uint start=res->numchars();
|
|
|
|
if (start <= (uint) length)
|
2004-01-14 14:26:30 +01:00
|
|
|
return res;
|
2004-01-15 09:12:55 +01:00
|
|
|
start=res->charpos(start - (uint) length);
|
2003-01-31 14:37:28 +01:00
|
|
|
tmp_value.set(*res,start,res->length()-start);
|
2000-07-31 21:29:14 +02:00
|
|
|
return &tmp_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Item_func_right::fix_length_and_dec()
|
|
|
|
{
|
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
2010-02-11 05:17:25 +01:00
|
|
|
agg_arg_charsets_for_string_result(collation, args, 1);
|
2000-07-31 21:29:14 +02:00
|
|
|
left_right_max_length();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
String *Item_func_substr::val_str(String *str)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2000-07-31 21:29:14 +02:00
|
|
|
String *res = args[0]->val_str(str);
|
2006-11-08 16:11:02 +01:00
|
|
|
/* must be longlong to avoid truncation */
|
|
|
|
longlong start= args[1]->val_int();
|
|
|
|
/* Assumes that the maximum length of a String is < INT_MAX32. */
|
|
|
|
/* Limit so that code sees out-of-bound value properly. */
|
|
|
|
longlong length= arg_count == 3 ? args[2]->val_int() : INT_MAX32;
|
|
|
|
longlong tmp_length;
|
2000-07-31 21:29:14 +02:00
|
|
|
|
|
|
|
if ((null_value=(args[0]->null_value || args[1]->null_value ||
|
|
|
|
(arg_count == 3 && args[2]->null_value))))
|
|
|
|
return 0; /* purecov: inspected */
|
2006-11-08 16:11:02 +01:00
|
|
|
|
2007-06-17 20:23:19 +02:00
|
|
|
/* Negative or zero length, will return empty string. */
|
|
|
|
if ((arg_count == 3) && (length <= 0) &&
|
|
|
|
(length == 0 || !args[2]->unsigned_flag))
|
2003-09-18 15:58:02 +02:00
|
|
|
return &my_empty_string;
|
2000-07-31 21:29:14 +02:00
|
|
|
|
2006-11-08 16:11:02 +01:00
|
|
|
/* Assumes that the maximum length of a String is < INT_MAX32. */
|
|
|
|
/* Set here so that rest of code sees out-of-bound value as such. */
|
|
|
|
if ((length <= 0) || (length > INT_MAX32))
|
|
|
|
length= INT_MAX32;
|
|
|
|
|
|
|
|
/* if "unsigned_flag" is set, we have a *huge* positive number. */
|
|
|
|
/* Assumes that the maximum length of a String is < INT_MAX32. */
|
2006-12-19 23:54:12 +01:00
|
|
|
if ((!args[1]->unsigned_flag && (start < INT_MIN32 || start > INT_MAX32)) ||
|
|
|
|
(args[1]->unsigned_flag && ((ulonglong) start > INT_MAX32)))
|
2006-11-08 16:11:02 +01:00
|
|
|
return &my_empty_string;
|
2000-07-31 21:29:14 +02:00
|
|
|
|
2006-11-08 16:11:02 +01:00
|
|
|
start= ((start < 0) ? res->numchars() + start : start - 1);
|
2006-11-30 02:40:42 +01:00
|
|
|
start= res->charpos((int) start);
|
2006-11-08 16:11:02 +01:00
|
|
|
if ((start < 0) || ((uint) start + 1 > res->length()))
|
|
|
|
return &my_empty_string;
|
|
|
|
|
2006-11-30 02:40:42 +01:00
|
|
|
length= res->charpos((int) length, (uint32) start);
|
2006-11-08 16:11:02 +01:00
|
|
|
tmp_length= res->length() - start;
|
|
|
|
length= min(length, tmp_length);
|
|
|
|
|
2006-11-30 02:40:42 +01:00
|
|
|
if (!start && (longlong) res->length() == length)
|
2000-07-31 21:29:14 +02:00
|
|
|
return res;
|
2006-11-30 02:40:42 +01:00
|
|
|
tmp_value.set(*res, (uint32) start, (uint32) length);
|
2000-07-31 21:29:14 +02:00
|
|
|
return &tmp_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Item_func_substr::fix_length_and_dec()
|
|
|
|
{
|
|
|
|
max_length=args[0]->max_length;
|
|
|
|
|
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
2010-02-11 05:17:25 +01:00
|
|
|
agg_arg_charsets_for_string_result(collation, args, 1);
|
2000-07-31 21:29:14 +02:00
|
|
|
if (args[1]->const_item())
|
|
|
|
{
|
2005-06-28 20:45:11 +02:00
|
|
|
int32 start= (int32) args[1]->val_int();
|
2007-03-10 17:55:34 +01:00
|
|
|
if (start < 0)
|
|
|
|
max_length= ((uint)(-start) > max_length) ? 0 : (uint)(-start);
|
2000-07-31 21:29:14 +02:00
|
|
|
else
|
2007-03-10 17:55:34 +01:00
|
|
|
max_length-= min((uint)(start - 1), max_length);
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
if (arg_count == 3 && args[2]->const_item())
|
|
|
|
{
|
2006-09-21 13:05:01 +02:00
|
|
|
int32 length= (int32) args[2]->val_int();
|
2000-07-31 21:29:14 +02:00
|
|
|
if (length <= 0)
|
|
|
|
max_length=0; /* purecov: inspected */
|
|
|
|
else
|
|
|
|
set_if_smaller(max_length,(uint) length);
|
|
|
|
}
|
2006-09-21 13:05:01 +02:00
|
|
|
max_length*= collation.collation->mbmaxlen;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-06-25 12:07:20 +02:00
|
|
|
void Item_func_substr_index::fix_length_and_dec()
|
|
|
|
{
|
|
|
|
max_length= args[0]->max_length;
|
2003-07-04 15:12:23 +02:00
|
|
|
|
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
2010-02-11 05:17:25 +01:00
|
|
|
if (agg_arg_charsets_for_comparison(collation, args, 2))
|
2003-07-04 15:12:23 +02:00
|
|
|
return;
|
2003-06-25 12:07:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
String *Item_func_substr_index::val_str(String *str)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2005-11-24 01:49:07 +01:00
|
|
|
String *res= args[0]->val_str(str);
|
|
|
|
String *delimiter= args[1]->val_str(&tmp_value);
|
|
|
|
int32 count= (int32) args[2]->val_int();
|
2000-07-31 21:29:14 +02:00
|
|
|
uint offset;
|
|
|
|
|
|
|
|
if (args[0]->null_value || args[1]->null_value || args[2]->null_value)
|
|
|
|
{ // string and/or delim are null
|
|
|
|
null_value=1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
null_value=0;
|
2005-11-24 01:49:07 +01:00
|
|
|
uint delimiter_length= delimiter->length();
|
|
|
|
if (!res->length() || !delimiter_length || !count)
|
2003-09-18 15:58:02 +02:00
|
|
|
return &my_empty_string; // Wrong parameters
|
2000-07-31 21:29:14 +02:00
|
|
|
|
2003-06-25 12:07:20 +02:00
|
|
|
res->set_charset(collation.collation);
|
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
#ifdef USE_MB
|
2003-03-13 12:34:46 +01:00
|
|
|
if (use_mb(res->charset()))
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2005-11-24 01:49:07 +01:00
|
|
|
const char *ptr= res->ptr();
|
|
|
|
const char *strend= ptr+res->length();
|
|
|
|
const char *end= strend-delimiter_length+1;
|
|
|
|
const char *search= delimiter->ptr();
|
|
|
|
const char *search_end= search+delimiter_length;
|
2000-07-31 21:29:14 +02:00
|
|
|
int32 n=0,c=count,pass;
|
|
|
|
register uint32 l;
|
|
|
|
for (pass=(count>0);pass<2;++pass)
|
|
|
|
{
|
|
|
|
while (ptr < end)
|
|
|
|
{
|
|
|
|
if (*ptr == *search)
|
|
|
|
{
|
|
|
|
register char *i,*j;
|
|
|
|
i=(char*) ptr+1; j=(char*) search+1;
|
|
|
|
while (j != search_end)
|
2004-02-02 17:25:39 +01:00
|
|
|
if (*i++ != *j++) goto skip;
|
2000-07-31 21:29:14 +02:00
|
|
|
if (pass==0) ++n;
|
|
|
|
else if (!--c) break;
|
2005-11-24 01:49:07 +01:00
|
|
|
ptr+= delimiter_length;
|
2000-07-31 21:29:14 +02:00
|
|
|
continue;
|
|
|
|
}
|
2004-02-02 17:25:39 +01:00
|
|
|
skip:
|
2002-03-19 17:03:10 +01:00
|
|
|
if ((l=my_ismbchar(res->charset(), ptr,strend))) ptr+=l;
|
2000-07-31 21:29:14 +02:00
|
|
|
else ++ptr;
|
|
|
|
} /* either not found or got total number when count<0 */
|
|
|
|
if (pass == 0) /* count<0 */
|
|
|
|
{
|
|
|
|
c+=n+1;
|
|
|
|
if (c<=0) return res; /* not found, return original string */
|
|
|
|
ptr=res->ptr();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (c) return res; /* Not found, return original string */
|
|
|
|
if (count>0) /* return left part */
|
|
|
|
{
|
2000-08-23 14:02:27 +02:00
|
|
|
tmp_value.set(*res,0,(ulong) (ptr-res->ptr()));
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
else /* return right part */
|
|
|
|
{
|
2005-11-24 01:49:07 +01:00
|
|
|
ptr+= delimiter_length;
|
2000-08-23 14:02:27 +02:00
|
|
|
tmp_value.set(*res,(ulong) (ptr-res->ptr()), (ulong) (strend-ptr));
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif /* USE_MB */
|
|
|
|
{
|
|
|
|
if (count > 0)
|
|
|
|
{ // start counting from the beginning
|
2005-11-24 01:49:07 +01:00
|
|
|
for (offset=0; ; offset+= delimiter_length)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2005-11-24 01:49:07 +01:00
|
|
|
if ((int) (offset= res->strstr(*delimiter, offset)) < 0)
|
2000-07-31 21:29:14 +02:00
|
|
|
return res; // Didn't find, return org string
|
|
|
|
if (!--count)
|
|
|
|
{
|
|
|
|
tmp_value.set(*res,0,offset);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2005-08-01 06:28:52 +02:00
|
|
|
{
|
item_strfunc.cc:
BUG #11104
Took out the offset-=delimiter_length-1 out of the for loop. It was causing
basically this:
select substring_index('the king of the the hill', 'the', -2) to not work.
The first iteration, offset would be initialised to 24, then strstr would
point at 'the king of the the* hill' ('*'means right before the
character following), returning a offset of 16. The for loop would then
decrement offset by two (3 - 1), to 14, now pointing at
"the king of th*e the hill", _skipping_ past the 'e' in the second to last
'the', and therefore strstr would never have a chance of matching the
second to last 'the', then moving on to the 'the' at the begginning of the
string!
In a nutshell, offset was being decremented by too great a value, preventing
the second to last 'the' from being ever found, hence the result of
'king of the the hill' from the query that is reported in the bug report
func_str.test:
BUG #11104
Added tests to make sure fix addresses issues in original bug report
func_str.result:
BUG #11104
New results for new tests
2005-08-08 22:46:13 +02:00
|
|
|
/*
|
|
|
|
Negative index, start counting at the end
|
|
|
|
*/
|
|
|
|
for (offset=res->length(); offset ;)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
item_strfunc.cc:
BUG #11104
Took out the offset-=delimiter_length-1 out of the for loop. It was causing
basically this:
select substring_index('the king of the the hill', 'the', -2) to not work.
The first iteration, offset would be initialised to 24, then strstr would
point at 'the king of the the* hill' ('*'means right before the
character following), returning a offset of 16. The for loop would then
decrement offset by two (3 - 1), to 14, now pointing at
"the king of th*e the hill", _skipping_ past the 'e' in the second to last
'the', and therefore strstr would never have a chance of matching the
second to last 'the', then moving on to the 'the' at the begginning of the
string!
In a nutshell, offset was being decremented by too great a value, preventing
the second to last 'the' from being ever found, hence the result of
'king of the the hill' from the query that is reported in the bug report
func_str.test:
BUG #11104
Added tests to make sure fix addresses issues in original bug report
func_str.result:
BUG #11104
New results for new tests
2005-08-08 22:46:13 +02:00
|
|
|
/*
|
|
|
|
this call will result in finding the position pointing to one
|
|
|
|
address space less than where the found substring is located
|
|
|
|
in res
|
|
|
|
*/
|
2005-11-24 01:49:07 +01:00
|
|
|
if ((int) (offset= res->strrstr(*delimiter, offset)) < 0)
|
2000-07-31 21:29:14 +02:00
|
|
|
return res; // Didn't find, return org string
|
item_strfunc.cc:
BUG #11104
Took out the offset-=delimiter_length-1 out of the for loop. It was causing
basically this:
select substring_index('the king of the the hill', 'the', -2) to not work.
The first iteration, offset would be initialised to 24, then strstr would
point at 'the king of the the* hill' ('*'means right before the
character following), returning a offset of 16. The for loop would then
decrement offset by two (3 - 1), to 14, now pointing at
"the king of th*e the hill", _skipping_ past the 'e' in the second to last
'the', and therefore strstr would never have a chance of matching the
second to last 'the', then moving on to the 'the' at the begginning of the
string!
In a nutshell, offset was being decremented by too great a value, preventing
the second to last 'the' from being ever found, hence the result of
'king of the the hill' from the query that is reported in the bug report
func_str.test:
BUG #11104
Added tests to make sure fix addresses issues in original bug report
func_str.result:
BUG #11104
New results for new tests
2005-08-08 22:46:13 +02:00
|
|
|
/*
|
|
|
|
At this point, we've searched for the substring
|
|
|
|
the number of times as supplied by the index value
|
|
|
|
*/
|
2000-07-31 21:29:14 +02:00
|
|
|
if (!++count)
|
|
|
|
{
|
2005-11-24 01:49:07 +01:00
|
|
|
offset+= delimiter_length;
|
2000-07-31 21:29:14 +02:00
|
|
|
tmp_value.set(*res,offset,res->length()- offset);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2005-11-24 01:49:07 +01:00
|
|
|
/*
|
|
|
|
We always mark tmp_value as const so that if val_str() is called again
|
|
|
|
on this object, we don't disrupt the contents of tmp_value when it was
|
|
|
|
derived from another String.
|
|
|
|
*/
|
|
|
|
tmp_value.mark_as_const();
|
2000-07-31 21:29:14 +02:00
|
|
|
return (&tmp_value);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** The trim functions are extension to ANSI SQL because they trim substrings
|
|
|
|
** They ltrim() and rtrim() functions are optimized for 1 byte strings
|
|
|
|
** They also return the original string if possible, else they return
|
|
|
|
** a substring that points at the original string.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
String *Item_func_ltrim::val_str(String *str)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2005-01-02 22:31:37 +01:00
|
|
|
char buff[MAX_FIELD_WIDTH], *ptr, *end;
|
|
|
|
String tmp(buff,sizeof(buff),system_charset_info);
|
|
|
|
String *res, *remove_str;
|
2000-07-31 21:29:14 +02:00
|
|
|
uint remove_length;
|
|
|
|
LINT_INIT(remove_length);
|
|
|
|
|
2005-01-02 22:31:37 +01:00
|
|
|
res= args[0]->val_str(str);
|
|
|
|
if ((null_value=args[0]->null_value))
|
|
|
|
return 0;
|
|
|
|
remove_str= &remove; /* Default value. */
|
|
|
|
if (arg_count == 2)
|
|
|
|
{
|
|
|
|
remove_str= args[1]->val_str(&tmp);
|
|
|
|
if ((null_value= args[1]->null_value))
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((remove_length= remove_str->length()) == 0 ||
|
2000-07-31 21:29:14 +02:00
|
|
|
remove_length > res->length())
|
|
|
|
return res;
|
|
|
|
|
2005-01-02 22:31:37 +01:00
|
|
|
ptr= (char*) res->ptr();
|
|
|
|
end= ptr+res->length();
|
2000-07-31 21:29:14 +02:00
|
|
|
if (remove_length == 1)
|
|
|
|
{
|
|
|
|
char chr=(*remove_str)[0];
|
|
|
|
while (ptr != end && *ptr == chr)
|
|
|
|
ptr++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
const char *r_ptr=remove_str->ptr();
|
|
|
|
end-=remove_length;
|
2004-09-13 11:25:43 +02:00
|
|
|
while (ptr <= end && !memcmp(ptr, r_ptr, remove_length))
|
2000-07-31 21:29:14 +02:00
|
|
|
ptr+=remove_length;
|
|
|
|
end+=remove_length;
|
|
|
|
}
|
|
|
|
if (ptr == res->ptr())
|
|
|
|
return res;
|
|
|
|
tmp_value.set(*res,(uint) (ptr - res->ptr()),(uint) (end-ptr));
|
|
|
|
return &tmp_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
String *Item_func_rtrim::val_str(String *str)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2005-01-02 22:31:37 +01:00
|
|
|
char buff[MAX_FIELD_WIDTH], *ptr, *end;
|
|
|
|
String tmp(buff, sizeof(buff), system_charset_info);
|
|
|
|
String *res, *remove_str;
|
2000-07-31 21:29:14 +02:00
|
|
|
uint remove_length;
|
|
|
|
LINT_INIT(remove_length);
|
|
|
|
|
2005-01-02 22:31:37 +01:00
|
|
|
res= args[0]->val_str(str);
|
|
|
|
if ((null_value=args[0]->null_value))
|
|
|
|
return 0;
|
|
|
|
remove_str= &remove; /* Default value. */
|
|
|
|
if (arg_count == 2)
|
|
|
|
{
|
|
|
|
remove_str= args[1]->val_str(&tmp);
|
|
|
|
if ((null_value= args[1]->null_value))
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((remove_length= remove_str->length()) == 0 ||
|
2000-07-31 21:29:14 +02:00
|
|
|
remove_length > res->length())
|
|
|
|
return res;
|
|
|
|
|
2005-01-02 22:31:37 +01:00
|
|
|
ptr= (char*) res->ptr();
|
|
|
|
end= ptr+res->length();
|
2000-07-31 21:29:14 +02:00
|
|
|
#ifdef USE_MB
|
|
|
|
char *p=ptr;
|
|
|
|
register uint32 l;
|
|
|
|
#endif
|
|
|
|
if (remove_length == 1)
|
|
|
|
{
|
|
|
|
char chr=(*remove_str)[0];
|
|
|
|
#ifdef USE_MB
|
2003-03-13 12:34:46 +01:00
|
|
|
if (use_mb(res->charset()))
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
|
|
|
while (ptr < end)
|
|
|
|
{
|
2002-03-19 17:03:10 +01:00
|
|
|
if ((l=my_ismbchar(res->charset(), ptr,end))) ptr+=l,p=ptr;
|
2000-07-31 21:29:14 +02:00
|
|
|
else ++ptr;
|
|
|
|
}
|
|
|
|
ptr=p;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
while (ptr != end && end[-1] == chr)
|
|
|
|
end--;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
const char *r_ptr=remove_str->ptr();
|
|
|
|
#ifdef USE_MB
|
2003-03-13 12:34:46 +01:00
|
|
|
if (use_mb(res->charset()))
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
|
|
|
loop:
|
|
|
|
while (ptr + remove_length < end)
|
|
|
|
{
|
2002-03-19 17:03:10 +01:00
|
|
|
if ((l=my_ismbchar(res->charset(), ptr,end))) ptr+=l;
|
2000-07-31 21:29:14 +02:00
|
|
|
else ++ptr;
|
|
|
|
}
|
|
|
|
if (ptr + remove_length == end && !memcmp(ptr,r_ptr,remove_length))
|
|
|
|
{
|
|
|
|
end-=remove_length;
|
|
|
|
ptr=p;
|
|
|
|
goto loop;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif /* USE_MB */
|
|
|
|
{
|
2004-09-13 11:25:43 +02:00
|
|
|
while (ptr + remove_length <= end &&
|
|
|
|
!memcmp(end-remove_length, r_ptr, remove_length))
|
2000-07-31 21:29:14 +02:00
|
|
|
end-=remove_length;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (end == res->ptr()+res->length())
|
|
|
|
return res;
|
|
|
|
tmp_value.set(*res,0,(uint) (end-res->ptr()));
|
|
|
|
return &tmp_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
String *Item_func_trim::val_str(String *str)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2005-01-02 22:31:37 +01:00
|
|
|
char buff[MAX_FIELD_WIDTH], *ptr, *end;
|
|
|
|
const char *r_ptr;
|
|
|
|
String tmp(buff, sizeof(buff), system_charset_info);
|
|
|
|
String *res, *remove_str;
|
2000-07-31 21:29:14 +02:00
|
|
|
uint remove_length;
|
|
|
|
LINT_INIT(remove_length);
|
2004-12-28 10:57:56 +01:00
|
|
|
|
2005-01-02 22:31:37 +01:00
|
|
|
res= args[0]->val_str(str);
|
|
|
|
if ((null_value=args[0]->null_value))
|
|
|
|
return 0;
|
|
|
|
remove_str= &remove; /* Default value. */
|
2004-12-28 10:57:56 +01:00
|
|
|
if (arg_count == 2)
|
|
|
|
{
|
|
|
|
remove_str= args[1]->val_str(&tmp);
|
|
|
|
if ((null_value= args[1]->null_value))
|
|
|
|
return 0;
|
|
|
|
}
|
2000-07-31 21:29:14 +02:00
|
|
|
|
2005-01-02 22:31:37 +01:00
|
|
|
if ((remove_length= remove_str->length()) == 0 ||
|
2000-07-31 21:29:14 +02:00
|
|
|
remove_length > res->length())
|
|
|
|
return res;
|
|
|
|
|
2005-01-02 22:31:37 +01:00
|
|
|
ptr= (char*) res->ptr();
|
|
|
|
end= ptr+res->length();
|
|
|
|
r_ptr= remove_str->ptr();
|
2001-01-19 03:57:29 +01:00
|
|
|
while (ptr+remove_length <= end && !memcmp(ptr,r_ptr,remove_length))
|
2000-07-31 21:29:14 +02:00
|
|
|
ptr+=remove_length;
|
|
|
|
#ifdef USE_MB
|
2003-03-13 12:34:46 +01:00
|
|
|
if (use_mb(res->charset()))
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
|
|
|
char *p=ptr;
|
|
|
|
register uint32 l;
|
|
|
|
loop:
|
|
|
|
while (ptr + remove_length < end)
|
|
|
|
{
|
2002-03-19 17:03:10 +01:00
|
|
|
if ((l=my_ismbchar(res->charset(), ptr,end))) ptr+=l;
|
2000-07-31 21:29:14 +02:00
|
|
|
else ++ptr;
|
|
|
|
}
|
|
|
|
if (ptr + remove_length == end && !memcmp(ptr,r_ptr,remove_length))
|
|
|
|
{
|
|
|
|
end-=remove_length;
|
|
|
|
ptr=p;
|
|
|
|
goto loop;
|
|
|
|
}
|
|
|
|
ptr=p;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif /* USE_MB */
|
|
|
|
{
|
2001-01-19 03:57:29 +01:00
|
|
|
while (ptr + remove_length <= end &&
|
2000-07-31 21:29:14 +02:00
|
|
|
!memcmp(end-remove_length,r_ptr,remove_length))
|
|
|
|
end-=remove_length;
|
|
|
|
}
|
|
|
|
if (ptr == res->ptr() && end == ptr+res->length())
|
|
|
|
return res;
|
|
|
|
tmp_value.set(*res,(uint) (ptr - res->ptr()),(uint) (end-ptr));
|
|
|
|
return &tmp_value;
|
|
|
|
}
|
|
|
|
|
2003-06-03 13:57:14 +02:00
|
|
|
void Item_func_trim::fix_length_and_dec()
|
|
|
|
{
|
|
|
|
max_length= args[0]->max_length;
|
|
|
|
if (arg_count == 1)
|
|
|
|
{
|
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
2010-02-11 05:17:25 +01:00
|
|
|
agg_arg_charsets_for_string_result(collation, args, 1);
|
2003-08-05 09:52:37 +02:00
|
|
|
remove.set_charset(collation.collation);
|
2003-06-03 13:57:14 +02:00
|
|
|
remove.set_ascii(" ",1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-06-30 09:26:36 +02:00
|
|
|
// Handle character set for args[1] and args[0].
|
|
|
|
// Note that we pass args[1] as the first item, and args[0] as the second.
|
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
2010-02-11 05:17:25 +01:00
|
|
|
if (agg_arg_charsets_for_comparison(collation, &args[1], 2, -1))
|
2004-11-02 13:02:12 +01:00
|
|
|
return;
|
2003-06-03 13:57:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-02-22 11:30:33 +01:00
|
|
|
void Item_func_trim::print(String *str, enum_query_type query_type)
|
2006-07-19 21:36:55 +02:00
|
|
|
{
|
|
|
|
if (arg_count == 1)
|
|
|
|
{
|
2008-02-22 11:30:33 +01:00
|
|
|
Item_func::print(str, query_type);
|
2006-07-19 21:36:55 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
str->append(Item_func_trim::func_name());
|
|
|
|
str->append('(');
|
|
|
|
str->append(mode_name());
|
|
|
|
str->append(' ');
|
2008-02-22 11:30:33 +01:00
|
|
|
args[1]->print(str, query_type);
|
2006-07-20 01:42:19 +02:00
|
|
|
str->append(STRING_WITH_LEN(" from "));
|
2008-02-22 11:30:33 +01:00
|
|
|
args[0]->print(str, query_type);
|
2006-07-19 21:36:55 +02:00
|
|
|
str->append(')');
|
|
|
|
}
|
|
|
|
|
2003-06-03 13:57:14 +02:00
|
|
|
|
2003-07-01 21:40:59 +02:00
|
|
|
/* Item_func_password */
|
2000-07-31 21:29:14 +02:00
|
|
|
|
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
2010-02-11 05:17:25 +01:00
|
|
|
String *Item_func_password::val_str_ascii(String *str)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2003-07-01 21:40:59 +02:00
|
|
|
String *res= args[0]->val_str(str);
|
2000-07-31 21:29:14 +02:00
|
|
|
if ((null_value=args[0]->null_value))
|
|
|
|
return 0;
|
2003-07-01 21:40:59 +02:00
|
|
|
if (res->length() == 0)
|
2003-09-18 15:58:02 +02:00
|
|
|
return &my_empty_string;
|
2009-05-27 12:20:57 +02:00
|
|
|
my_make_scrambled_password(tmp_value, res->ptr(), res->length());
|
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
2010-02-11 05:17:25 +01:00
|
|
|
str->set(tmp_value, SCRAMBLED_PASSWORD_CHAR_LENGTH, &my_charset_latin1);
|
2003-07-01 21:40:59 +02:00
|
|
|
return str;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
2009-05-27 12:20:57 +02:00
|
|
|
char *Item_func_password::alloc(THD *thd, const char *password,
|
|
|
|
size_t pass_len)
|
2003-07-04 18:52:04 +02:00
|
|
|
{
|
|
|
|
char *buff= (char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH+1);
|
|
|
|
if (buff)
|
2009-05-27 12:20:57 +02:00
|
|
|
my_make_scrambled_password(buff, password, pass_len);
|
2003-07-04 18:52:04 +02:00
|
|
|
return buff;
|
|
|
|
}
|
|
|
|
|
2003-07-01 21:40:59 +02:00
|
|
|
/* Item_func_old_password */
|
|
|
|
|
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
2010-02-11 05:17:25 +01:00
|
|
|
String *Item_func_old_password::val_str_ascii(String *str)
|
2002-10-06 11:42:16 +02:00
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2003-07-01 21:40:59 +02:00
|
|
|
String *res= args[0]->val_str(str);
|
2002-10-06 11:42:16 +02:00
|
|
|
if ((null_value=args[0]->null_value))
|
|
|
|
return 0;
|
|
|
|
if (res->length() == 0)
|
2003-09-18 15:58:02 +02:00
|
|
|
return &my_empty_string;
|
2009-05-27 12:20:57 +02:00
|
|
|
my_make_scrambled_password_323(tmp_value, res->ptr(), res->length());
|
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
2010-02-11 05:17:25 +01:00
|
|
|
str->set(tmp_value, SCRAMBLED_PASSWORD_CHAR_LENGTH_323, &my_charset_latin1);
|
2002-10-06 11:42:16 +02:00
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2009-05-27 12:20:57 +02:00
|
|
|
char *Item_func_old_password::alloc(THD *thd, const char *password,
|
|
|
|
size_t pass_len)
|
2003-07-04 18:52:04 +02:00
|
|
|
{
|
|
|
|
char *buff= (char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH_323+1);
|
|
|
|
if (buff)
|
2009-05-27 12:20:57 +02:00
|
|
|
my_make_scrambled_password_323(buff, password, pass_len);
|
2003-07-04 18:52:04 +02:00
|
|
|
return buff;
|
|
|
|
}
|
2002-10-06 11:42:16 +02:00
|
|
|
|
|
|
|
|
2001-12-13 01:31:19 +01:00
|
|
|
#define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.')
|
2000-07-31 21:29:14 +02:00
|
|
|
|
|
|
|
String *Item_func_encrypt::val_str(String *str)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2000-07-31 21:29:14 +02:00
|
|
|
String *res =args[0]->val_str(str);
|
|
|
|
|
|
|
|
#ifdef HAVE_CRYPT
|
|
|
|
char salt[3],*salt_ptr;
|
|
|
|
if ((null_value=args[0]->null_value))
|
|
|
|
return 0;
|
|
|
|
if (res->length() == 0)
|
2003-09-18 15:58:02 +02:00
|
|
|
return &my_empty_string;
|
2000-07-31 21:29:14 +02:00
|
|
|
|
|
|
|
if (arg_count == 1)
|
|
|
|
{ // generate random salt
|
|
|
|
time_t timestamp=current_thd->query_start();
|
2001-08-22 00:45:07 +02:00
|
|
|
salt[0] = bin_to_ascii( (ulong) timestamp & 0x3f);
|
|
|
|
salt[1] = bin_to_ascii(( (ulong) timestamp >> 5) & 0x3f);
|
2000-07-31 21:29:14 +02:00
|
|
|
salt[2] = 0;
|
|
|
|
salt_ptr=salt;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // obtain salt from the first two bytes
|
|
|
|
String *salt_str=args[1]->val_str(&tmp_value);
|
|
|
|
if ((null_value= (args[1]->null_value || salt_str->length() < 2)))
|
|
|
|
return 0;
|
2009-04-23 09:47:54 +02:00
|
|
|
salt_ptr= salt_str->c_ptr_safe();
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
2010-01-07 06:42:07 +01:00
|
|
|
mysql_mutex_lock(&LOCK_crypt);
|
2009-04-23 09:47:54 +02:00
|
|
|
char *tmp= crypt(res->c_ptr_safe(),salt_ptr);
|
2005-10-07 01:15:53 +02:00
|
|
|
if (!tmp)
|
|
|
|
{
|
2010-01-07 06:42:07 +01:00
|
|
|
mysql_mutex_unlock(&LOCK_crypt);
|
2005-10-07 01:15:53 +02:00
|
|
|
null_value= 1;
|
|
|
|
return 0;
|
|
|
|
}
|
2006-08-12 01:09:19 +02:00
|
|
|
str->set(tmp, (uint) strlen(tmp), &my_charset_bin);
|
2000-07-31 21:29:14 +02:00
|
|
|
str->copy();
|
2010-01-07 06:42:07 +01:00
|
|
|
mysql_mutex_unlock(&LOCK_crypt);
|
2000-07-31 21:29:14 +02:00
|
|
|
return str;
|
|
|
|
#else
|
|
|
|
null_value=1;
|
|
|
|
return 0;
|
|
|
|
#endif /* HAVE_CRYPT */
|
|
|
|
}
|
|
|
|
|
2009-12-04 16:36:58 +01:00
|
|
|
bool Item_func_encode::seed()
|
|
|
|
{
|
|
|
|
char buf[80];
|
|
|
|
ulong rand_nr[2];
|
|
|
|
String *key, tmp(buf, sizeof(buf), system_charset_info);
|
|
|
|
|
|
|
|
if (!(key= args[1]->val_str(&tmp)))
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
hash_password(rand_nr, key->ptr(), key->length());
|
|
|
|
sql_crypt.init(rand_nr);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
void Item_func_encode::fix_length_and_dec()
|
|
|
|
{
|
|
|
|
max_length=args[0]->max_length;
|
Bug#22684 (BENCHMARK, ENCODE, DECODE and FORMAT are not real functions)
Before this change, the functions BENCHMARK, ENCODE, DECODE and FORMAT could
only accept a constant for some parameters.
After this change, this restriction has been removed. An implication is that
these functions can also be used in prepared statements.
The change consist of changing the following classes:
- Item_func_benchmark
- Item_func_encode
- Item_func_decode
- Item_func_format
to:
- only accept Item* in the constructor,
- and evaluate arguments during calls to val_xxx()
which fits the general design of all the other functions.
The 'TODO' items identified in item_create.cc during the work done for
Bug 21114 are addressed by this fix, as a natural consequence of aligning
the design.
In the 'func_str' test, a single very long test line involving an explain
extended select with many functions has been rewritten into multiple
separate tests, to improve maintainability.
The result of explain extended select decode(encode(...)) has changed,
since the encode and decode functions now print all their parameters.
2006-11-16 17:03:47 +01:00
|
|
|
maybe_null=args[0]->maybe_null || args[1]->maybe_null;
|
2004-06-08 12:36:44 +02:00
|
|
|
collation.set(&my_charset_bin);
|
2009-12-04 16:36:58 +01:00
|
|
|
/* Precompute the seed state if the item is constant. */
|
|
|
|
seeded= args[1]->const_item() &&
|
|
|
|
(args[1]->result_type() == STRING_RESULT) && !seed();
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
String *Item_func_encode::val_str(String *str)
|
|
|
|
{
|
|
|
|
String *res;
|
Bug#22684 (BENCHMARK, ENCODE, DECODE and FORMAT are not real functions)
Before this change, the functions BENCHMARK, ENCODE, DECODE and FORMAT could
only accept a constant for some parameters.
After this change, this restriction has been removed. An implication is that
these functions can also be used in prepared statements.
The change consist of changing the following classes:
- Item_func_benchmark
- Item_func_encode
- Item_func_decode
- Item_func_format
to:
- only accept Item* in the constructor,
- and evaluate arguments during calls to val_xxx()
which fits the general design of all the other functions.
The 'TODO' items identified in item_create.cc during the work done for
Bug 21114 are addressed by this fix, as a natural consequence of aligning
the design.
In the 'func_str' test, a single very long test line involving an explain
extended select with many functions has been rewritten into multiple
separate tests, to improve maintainability.
The result of explain extended select decode(encode(...)) has changed,
since the encode and decode functions now print all their parameters.
2006-11-16 17:03:47 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
if (!(res=args[0]->val_str(str)))
|
|
|
|
{
|
2009-12-04 16:36:58 +01:00
|
|
|
null_value= 1;
|
|
|
|
return NULL;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
Bug#22684 (BENCHMARK, ENCODE, DECODE and FORMAT are not real functions)
Before this change, the functions BENCHMARK, ENCODE, DECODE and FORMAT could
only accept a constant for some parameters.
After this change, this restriction has been removed. An implication is that
these functions can also be used in prepared statements.
The change consist of changing the following classes:
- Item_func_benchmark
- Item_func_encode
- Item_func_decode
- Item_func_format
to:
- only accept Item* in the constructor,
- and evaluate arguments during calls to val_xxx()
which fits the general design of all the other functions.
The 'TODO' items identified in item_create.cc during the work done for
Bug 21114 are addressed by this fix, as a natural consequence of aligning
the design.
In the 'func_str' test, a single very long test line involving an explain
extended select with many functions has been rewritten into multiple
separate tests, to improve maintainability.
The result of explain extended select decode(encode(...)) has changed,
since the encode and decode functions now print all their parameters.
2006-11-16 17:03:47 +01:00
|
|
|
|
2009-12-04 16:36:58 +01:00
|
|
|
if (!seeded && seed())
|
Bug#22684 (BENCHMARK, ENCODE, DECODE and FORMAT are not real functions)
Before this change, the functions BENCHMARK, ENCODE, DECODE and FORMAT could
only accept a constant for some parameters.
After this change, this restriction has been removed. An implication is that
these functions can also be used in prepared statements.
The change consist of changing the following classes:
- Item_func_benchmark
- Item_func_encode
- Item_func_decode
- Item_func_format
to:
- only accept Item* in the constructor,
- and evaluate arguments during calls to val_xxx()
which fits the general design of all the other functions.
The 'TODO' items identified in item_create.cc during the work done for
Bug 21114 are addressed by this fix, as a natural consequence of aligning
the design.
In the 'func_str' test, a single very long test line involving an explain
extended select with many functions has been rewritten into multiple
separate tests, to improve maintainability.
The result of explain extended select decode(encode(...)) has changed,
since the encode and decode functions now print all their parameters.
2006-11-16 17:03:47 +01:00
|
|
|
{
|
2009-12-04 16:36:58 +01:00
|
|
|
null_value= 1;
|
|
|
|
return NULL;
|
Bug#22684 (BENCHMARK, ENCODE, DECODE and FORMAT are not real functions)
Before this change, the functions BENCHMARK, ENCODE, DECODE and FORMAT could
only accept a constant for some parameters.
After this change, this restriction has been removed. An implication is that
these functions can also be used in prepared statements.
The change consist of changing the following classes:
- Item_func_benchmark
- Item_func_encode
- Item_func_decode
- Item_func_format
to:
- only accept Item* in the constructor,
- and evaluate arguments during calls to val_xxx()
which fits the general design of all the other functions.
The 'TODO' items identified in item_create.cc during the work done for
Bug 21114 are addressed by this fix, as a natural consequence of aligning
the design.
In the 'func_str' test, a single very long test line involving an explain
extended select with many functions has been rewritten into multiple
separate tests, to improve maintainability.
The result of explain extended select decode(encode(...)) has changed,
since the encode and decode functions now print all their parameters.
2006-11-16 17:03:47 +01:00
|
|
|
}
|
|
|
|
|
2009-12-04 16:36:58 +01:00
|
|
|
null_value= 0;
|
|
|
|
res= copy_if_not_alloced(str, res, res->length());
|
2010-01-28 22:51:40 +01:00
|
|
|
crypto_transform(res);
|
2009-12-04 16:36:58 +01:00
|
|
|
sql_crypt.reinit();
|
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2010-01-28 22:51:40 +01:00
|
|
|
void Item_func_encode::crypto_transform(String *res)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2009-12-04 16:36:58 +01:00
|
|
|
sql_crypt.encode((char*) res->ptr(),res->length());
|
|
|
|
res->set_charset(&my_charset_bin);
|
|
|
|
}
|
Bug#22684 (BENCHMARK, ENCODE, DECODE and FORMAT are not real functions)
Before this change, the functions BENCHMARK, ENCODE, DECODE and FORMAT could
only accept a constant for some parameters.
After this change, this restriction has been removed. An implication is that
these functions can also be used in prepared statements.
The change consist of changing the following classes:
- Item_func_benchmark
- Item_func_encode
- Item_func_decode
- Item_func_format
to:
- only accept Item* in the constructor,
- and evaluate arguments during calls to val_xxx()
which fits the general design of all the other functions.
The 'TODO' items identified in item_create.cc during the work done for
Bug 21114 are addressed by this fix, as a natural consequence of aligning
the design.
In the 'func_str' test, a single very long test line involving an explain
extended select with many functions has been rewritten into multiple
separate tests, to improve maintainability.
The result of explain extended select decode(encode(...)) has changed,
since the encode and decode functions now print all their parameters.
2006-11-16 17:03:47 +01:00
|
|
|
|
2010-01-28 22:51:40 +01:00
|
|
|
void Item_func_decode::crypto_transform(String *res)
|
2009-12-04 16:36:58 +01:00
|
|
|
{
|
2000-07-31 21:29:14 +02:00
|
|
|
sql_crypt.decode((char*) res->ptr(),res->length());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-03-04 11:20:49 +01:00
|
|
|
Item *Item_func_sysconst::safe_charset_converter(CHARSET_INFO *tocs)
|
|
|
|
{
|
|
|
|
Item_string *conv;
|
|
|
|
uint conv_errors;
|
|
|
|
String tmp, cstr, *ostr= val_str(&tmp);
|
2009-01-09 12:50:18 +01:00
|
|
|
if (null_value)
|
|
|
|
{
|
|
|
|
Item *null_item= new Item_null((char *) fully_qualified_func_name());
|
|
|
|
null_item->collation.set (tocs);
|
|
|
|
return null_item;
|
|
|
|
}
|
2005-03-04 11:20:49 +01:00
|
|
|
cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, &conv_errors);
|
2005-07-15 23:01:44 +02:00
|
|
|
if (conv_errors ||
|
|
|
|
!(conv= new Item_static_string_func(fully_qualified_func_name(),
|
|
|
|
cstr.ptr(), cstr.length(),
|
|
|
|
cstr.charset(),
|
|
|
|
collation.derivation)))
|
2005-03-04 11:20:49 +01:00
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
conv->str_value.copy();
|
2005-08-12 15:13:42 +02:00
|
|
|
conv->str_value.mark_as_const();
|
2005-03-04 11:20:49 +01:00
|
|
|
return conv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
String *Item_func_database::val_str(String *str)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2002-11-25 16:33:51 +01:00
|
|
|
THD *thd= current_thd;
|
A fix and a test case for
Bug#19022 "Memory bug when switching db during trigger execution"
Bug#17199 "Problem when view calls function from another database."
Bug#18444 "Fully qualified stored function names don't work correctly in
SELECT statements"
Documentation note: this patch introduces a change in behaviour of prepared
statements.
This patch adds a few new invariants with regard to how THD::db should
be used. These invariants should be preserved in future:
- one should never refer to THD::db by pointer and always make a deep copy
(strmake, strdup)
- one should never compare two databases by pointer, but use strncmp or
my_strncasecmp
- TABLE_LIST object table->db should be always initialized in the parser or
by creator of the object.
For prepared statements it means that if the current database is changed
after a statement is prepared, the database that was current at prepare
remains active. This also means that you can not prepare a statement that
implicitly refers to the current database if the latter is not set.
This is not documented, and therefore needs documentation. This is NOT a
change in behavior for almost all SQL statements except:
- ALTER TABLE t1 RENAME t2
- OPTIMIZE TABLE t1
- ANALYZE TABLE t1
- TRUNCATE TABLE t1 --
until this patch t1 or t2 could be evaluated at the first execution of
prepared statement.
CURRENT_DATABASE() still works OK and is evaluated at every execution
of prepared statement.
Note, that in stored routines this is not an issue as the default
database is the database of the stored procedure and "use" statement
is prohibited in stored routines.
This patch makes obsolete the use of check_db_used (it was never used in the
old code too) and all other places that check for table->db and assign it
from THD::db if it's NULL, except the parser.
How this patch was created: THD::{db,db_length} were replaced with a
LEX_STRING, THD::db. All the places that refer to THD::{db,db_length} were
manually checked and:
- if the place uses thd->db by pointer, it was fixed to make a deep copy
- if a place compared two db pointers, it was fixed to compare them by value
(via strcmp/my_strcasecmp, whatever was approproate)
Then this intermediate patch was used to write a smaller patch that does the
same thing but without a rename.
TODO in 5.1:
- remove check_db_used
- deploy THD::set_db in mysql_change_db
See also comments to individual files.
2006-06-26 22:47:52 +02:00
|
|
|
if (thd->db == NULL)
|
2003-05-23 07:45:46 +02:00
|
|
|
{
|
2003-09-08 14:30:53 +02:00
|
|
|
null_value= 1;
|
|
|
|
return 0;
|
2003-05-23 07:45:46 +02:00
|
|
|
}
|
2000-07-31 21:29:14 +02:00
|
|
|
else
|
A fix and a test case for
Bug#19022 "Memory bug when switching db during trigger execution"
Bug#17199 "Problem when view calls function from another database."
Bug#18444 "Fully qualified stored function names don't work correctly in
SELECT statements"
Documentation note: this patch introduces a change in behaviour of prepared
statements.
This patch adds a few new invariants with regard to how THD::db should
be used. These invariants should be preserved in future:
- one should never refer to THD::db by pointer and always make a deep copy
(strmake, strdup)
- one should never compare two databases by pointer, but use strncmp or
my_strncasecmp
- TABLE_LIST object table->db should be always initialized in the parser or
by creator of the object.
For prepared statements it means that if the current database is changed
after a statement is prepared, the database that was current at prepare
remains active. This also means that you can not prepare a statement that
implicitly refers to the current database if the latter is not set.
This is not documented, and therefore needs documentation. This is NOT a
change in behavior for almost all SQL statements except:
- ALTER TABLE t1 RENAME t2
- OPTIMIZE TABLE t1
- ANALYZE TABLE t1
- TRUNCATE TABLE t1 --
until this patch t1 or t2 could be evaluated at the first execution of
prepared statement.
CURRENT_DATABASE() still works OK and is evaluated at every execution
of prepared statement.
Note, that in stored routines this is not an issue as the default
database is the database of the stored procedure and "use" statement
is prohibited in stored routines.
This patch makes obsolete the use of check_db_used (it was never used in the
old code too) and all other places that check for table->db and assign it
from THD::db if it's NULL, except the parser.
How this patch was created: THD::{db,db_length} were replaced with a
LEX_STRING, THD::db. All the places that refer to THD::{db,db_length} were
manually checked and:
- if the place uses thd->db by pointer, it was fixed to make a deep copy
- if a place compared two db pointers, it was fixed to compare them by value
(via strcmp/my_strcasecmp, whatever was approproate)
Then this intermediate patch was used to write a smaller patch that does the
same thing but without a rename.
TODO in 5.1:
- remove check_db_used
- deploy THD::set_db in mysql_change_db
See also comments to individual files.
2006-06-26 22:47:52 +02:00
|
|
|
str->copy(thd->db, thd->db_length, system_charset_info);
|
2000-07-31 21:29:14 +02:00
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2003-03-26 17:37:38 +01:00
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
/**
|
2009-11-18 15:50:31 +01:00
|
|
|
@note USER() is replicated correctly if binlog_format=ROW or (as of
|
|
|
|
BUG#28086) binlog_format=MIXED, but is incorrectly replicated to ''
|
|
|
|
if binlog_format=STATEMENT.
|
2006-07-02 12:35:45 +02:00
|
|
|
*/
|
|
|
|
bool Item_func_user::init(const char *user, const char *host)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2003-04-22 21:41:59 +02:00
|
|
|
|
2006-07-02 12:35:45 +02:00
|
|
|
// For system threads (e.g. replication SQL thread) user may be empty
|
|
|
|
if (user)
|
2005-07-15 23:01:44 +02:00
|
|
|
{
|
2006-07-02 12:35:45 +02:00
|
|
|
CHARSET_INFO *cs= str_value.charset();
|
2009-02-10 23:47:54 +01:00
|
|
|
size_t res_length= (strlen(user)+strlen(host)+2) * cs->mbmaxlen;
|
2005-07-15 23:01:44 +02:00
|
|
|
|
2009-02-10 23:47:54 +01:00
|
|
|
if (str_value.alloc((uint) res_length))
|
2006-07-02 12:35:45 +02:00
|
|
|
{
|
|
|
|
null_value=1;
|
|
|
|
return TRUE;
|
|
|
|
}
|
2002-12-04 23:14:51 +01:00
|
|
|
|
2009-02-10 23:47:54 +01:00
|
|
|
res_length=cs->cset->snprintf(cs, (char*)str_value.ptr(), (uint) res_length,
|
2006-07-02 12:35:45 +02:00
|
|
|
"%s@%s", user, host);
|
2009-02-10 23:47:54 +01:00
|
|
|
str_value.length((uint) res_length);
|
2006-07-02 12:35:45 +02:00
|
|
|
str_value.mark_as_const();
|
2002-11-11 15:43:33 +01:00
|
|
|
}
|
2006-07-02 12:35:45 +02:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Item_func_user::fix_fields(THD *thd, Item **ref)
|
|
|
|
{
|
|
|
|
return (Item_func_sysconst::fix_fields(thd, ref) ||
|
|
|
|
init(thd->main_security_ctx.user,
|
|
|
|
thd->main_security_ctx.host_or_ip));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Item_func_current_user::fix_fields(THD *thd, Item **ref)
|
|
|
|
{
|
|
|
|
if (Item_func_sysconst::fix_fields(thd, ref))
|
|
|
|
return TRUE;
|
|
|
|
|
2006-11-13 17:06:45 +01:00
|
|
|
Security_context *ctx=
|
|
|
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
|
|
|
(context->security_ctx
|
2006-07-02 12:35:45 +02:00
|
|
|
? context->security_ctx : thd->security_ctx);
|
2006-11-13 17:06:45 +01:00
|
|
|
#else
|
|
|
|
thd->security_ctx;
|
|
|
|
#endif /*NO_EMBEDDED_ACCESS_CHECKS*/
|
2006-07-02 12:35:45 +02:00
|
|
|
return init(ctx->priv_user, ctx->priv_host);
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
2005-07-15 23:01:44 +02:00
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
void Item_func_soundex::fix_length_and_dec()
|
|
|
|
{
|
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
2010-02-11 05:17:25 +01:00
|
|
|
agg_arg_charsets_for_string_result(collation, args, 1);
|
2000-07-31 21:29:14 +02:00
|
|
|
max_length=args[0]->max_length;
|
2007-03-28 15:57:30 +02:00
|
|
|
set_if_bigger(max_length, 4 * collation.collation->mbminlen);
|
|
|
|
tmp_value.set_charset(collation.collation);
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
/**
|
2003-09-13 10:35:29 +02:00
|
|
|
If alpha, map input letter to soundex code.
|
|
|
|
If not alpha and remove_garbage is set then skip to next char
|
|
|
|
else return 0
|
|
|
|
*/
|
2000-07-31 21:29:14 +02:00
|
|
|
|
2007-03-28 15:57:30 +02:00
|
|
|
static int soundex_toupper(int ch)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2005-01-11 16:58:53 +01:00
|
|
|
return (ch >= 'a' && ch <= 'z') ? ch - 'a' + 'A' : ch;
|
|
|
|
}
|
|
|
|
|
2007-03-28 15:57:30 +02:00
|
|
|
|
|
|
|
static char get_scode(int wc)
|
2005-01-11 16:58:53 +01:00
|
|
|
{
|
2007-03-28 15:57:30 +02:00
|
|
|
int ch= soundex_toupper(wc);
|
2000-07-31 21:29:14 +02:00
|
|
|
if (ch < 'A' || ch > 'Z')
|
|
|
|
{
|
|
|
|
// Thread extended alfa (country spec)
|
|
|
|
return '0'; // as vokal
|
|
|
|
}
|
|
|
|
return(soundex_map[ch-'A']);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-03-28 15:57:30 +02:00
|
|
|
static bool my_uni_isalpha(int wc)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
Return true for all Basic Latin letters: a..z A..Z.
|
|
|
|
Return true for all Unicode characters with code higher than U+00C0:
|
|
|
|
- characters between 'z' and U+00C0 are controls and punctuations.
|
|
|
|
- "U+00C0 LATIN CAPITAL LETTER A WITH GRAVE" is the first letter after 'z'.
|
|
|
|
*/
|
|
|
|
return (wc >= 'a' && wc <= 'z') ||
|
|
|
|
(wc >= 'A' && wc <= 'Z') ||
|
|
|
|
(wc >= 0xC0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
String *Item_func_soundex::val_str(String *str)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2000-07-31 21:29:14 +02:00
|
|
|
String *res =args[0]->val_str(str);
|
|
|
|
char last_ch,ch;
|
2003-08-05 09:52:37 +02:00
|
|
|
CHARSET_INFO *cs= collation.collation;
|
2007-03-28 15:57:30 +02:00
|
|
|
my_wc_t wc;
|
|
|
|
uint nchars;
|
|
|
|
int rc;
|
2002-12-20 14:57:24 +01:00
|
|
|
|
2007-03-28 15:57:30 +02:00
|
|
|
if ((null_value= args[0]->null_value))
|
2000-07-31 21:29:14 +02:00
|
|
|
return 0; /* purecov: inspected */
|
|
|
|
|
2007-03-28 15:57:30 +02:00
|
|
|
if (tmp_value.alloc(max(res->length(), 4 * cs->mbminlen)))
|
2000-07-31 21:29:14 +02:00
|
|
|
return str; /* purecov: inspected */
|
2001-12-13 14:53:18 +01:00
|
|
|
char *to= (char *) tmp_value.ptr();
|
2007-03-28 15:57:30 +02:00
|
|
|
char *to_end= to + tmp_value.alloced_length();
|
|
|
|
char *from= (char *) res->ptr(), *end= from + res->length();
|
2002-12-20 14:57:24 +01:00
|
|
|
|
2007-03-28 15:57:30 +02:00
|
|
|
for ( ; ; ) /* Skip pre-space */
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2007-03-28 15:57:30 +02:00
|
|
|
if ((rc= cs->cset->mb_wc(cs, &wc, (uchar*) from, (uchar*) end)) <= 0)
|
|
|
|
return &my_empty_string; /* EOL or invalid byte sequence */
|
|
|
|
|
|
|
|
if (rc == 1 && cs->ctype)
|
|
|
|
{
|
|
|
|
/* Single byte letter found */
|
|
|
|
if (my_isalpha(cs, *from))
|
|
|
|
{
|
|
|
|
last_ch= get_scode(*from); // Code of the first letter
|
|
|
|
*to++= soundex_toupper(*from++); // Copy first letter
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
from++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
from+= rc;
|
|
|
|
if (my_uni_isalpha(wc))
|
|
|
|
{
|
|
|
|
/* Multibyte letter found */
|
|
|
|
wc= soundex_toupper(wc);
|
|
|
|
last_ch= get_scode(wc); // Code of the first letter
|
|
|
|
if ((rc= cs->cset->wc_mb(cs, wc, (uchar*) to, (uchar*) to_end)) <= 0)
|
|
|
|
{
|
|
|
|
/* Extra safety - should not really happen */
|
|
|
|
DBUG_ASSERT(false);
|
|
|
|
return &my_empty_string;
|
|
|
|
}
|
|
|
|
to+= rc;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
last_ch is now set to the first 'double-letter' check.
|
|
|
|
loop on input letters until end of input
|
|
|
|
*/
|
|
|
|
for (nchars= 1 ; ; )
|
|
|
|
{
|
|
|
|
if ((rc= cs->cset->mb_wc(cs, &wc, (uchar*) from, (uchar*) end)) <= 0)
|
|
|
|
break; /* EOL or invalid byte sequence */
|
|
|
|
|
|
|
|
if (rc == 1 && cs->ctype)
|
|
|
|
{
|
|
|
|
if (!my_isalpha(cs, *from++))
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
from+= rc;
|
|
|
|
if (!my_uni_isalpha(wc))
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
ch= get_scode(wc);
|
2000-07-31 21:29:14 +02:00
|
|
|
if ((ch != '0') && (ch != last_ch)) // if not skipped or double
|
|
|
|
{
|
2007-03-28 15:57:30 +02:00
|
|
|
// letter, copy to output
|
|
|
|
if ((rc= cs->cset->wc_mb(cs, (my_wc_t) ch,
|
|
|
|
(uchar*) to, (uchar*) to_end)) <= 0)
|
|
|
|
{
|
|
|
|
// Extra safety - should not really happen
|
|
|
|
DBUG_ASSERT(false);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
to+= rc;
|
|
|
|
nchars++;
|
|
|
|
last_ch= ch; // save code of last input letter
|
|
|
|
} // for next double-letter check
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
2007-03-28 15:57:30 +02:00
|
|
|
|
|
|
|
/* Pad up to 4 characters with DIGIT ZERO, if the string is shorter */
|
|
|
|
if (nchars < 4)
|
|
|
|
{
|
|
|
|
uint nbytes= (4 - nchars) * cs->mbminlen;
|
|
|
|
cs->cset->fill(cs, to, nbytes, '0');
|
|
|
|
to+= nbytes;
|
|
|
|
}
|
|
|
|
|
2001-12-13 14:53:18 +01:00
|
|
|
tmp_value.length((uint) (to-tmp_value.ptr()));
|
|
|
|
return &tmp_value;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
/**
|
|
|
|
Change a number to format '3,333,333,333.000'.
|
|
|
|
|
|
|
|
This should be 'internationalized' sometimes.
|
2000-07-31 21:29:14 +02:00
|
|
|
*/
|
|
|
|
|
Bug#22684 (BENCHMARK, ENCODE, DECODE and FORMAT are not real functions)
Before this change, the functions BENCHMARK, ENCODE, DECODE and FORMAT could
only accept a constant for some parameters.
After this change, this restriction has been removed. An implication is that
these functions can also be used in prepared statements.
The change consist of changing the following classes:
- Item_func_benchmark
- Item_func_encode
- Item_func_decode
- Item_func_format
to:
- only accept Item* in the constructor,
- and evaluate arguments during calls to val_xxx()
which fits the general design of all the other functions.
The 'TODO' items identified in item_create.cc during the work done for
Bug 21114 are addressed by this fix, as a natural consequence of aligning
the design.
In the 'func_str' test, a single very long test line involving an explain
extended select with many functions has been rewritten into multiple
separate tests, to improve maintainability.
The result of explain extended select decode(encode(...)) has changed,
since the encode and decode functions now print all their parameters.
2006-11-16 17:03:47 +01:00
|
|
|
const int FORMAT_MAX_DECIMALS= 30;
|
|
|
|
|
2009-10-05 17:06:04 +02:00
|
|
|
|
|
|
|
MY_LOCALE *Item_func_format::get_locale(Item *item)
|
Bug#22684 (BENCHMARK, ENCODE, DECODE and FORMAT are not real functions)
Before this change, the functions BENCHMARK, ENCODE, DECODE and FORMAT could
only accept a constant for some parameters.
After this change, this restriction has been removed. An implication is that
these functions can also be used in prepared statements.
The change consist of changing the following classes:
- Item_func_benchmark
- Item_func_encode
- Item_func_decode
- Item_func_format
to:
- only accept Item* in the constructor,
- and evaluate arguments during calls to val_xxx()
which fits the general design of all the other functions.
The 'TODO' items identified in item_create.cc during the work done for
Bug 21114 are addressed by this fix, as a natural consequence of aligning
the design.
In the 'func_str' test, a single very long test line involving an explain
extended select with many functions has been rewritten into multiple
separate tests, to improve maintainability.
The result of explain extended select decode(encode(...)) has changed,
since the encode and decode functions now print all their parameters.
2006-11-16 17:03:47 +01:00
|
|
|
{
|
2009-10-05 17:06:04 +02:00
|
|
|
DBUG_ASSERT(arg_count == 3);
|
|
|
|
String tmp, *locale_name= args[2]->val_str(&tmp);
|
|
|
|
MY_LOCALE *lc;
|
|
|
|
if (!locale_name ||
|
|
|
|
!(lc= my_locale_by_name(locale_name->c_ptr_safe())))
|
|
|
|
{
|
|
|
|
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
|
|
|
ER_UNKNOWN_LOCALE,
|
|
|
|
ER(ER_UNKNOWN_LOCALE),
|
|
|
|
locale_name ? locale_name->c_ptr_safe() : "NULL");
|
|
|
|
lc= &my_locale_en_US;
|
|
|
|
}
|
|
|
|
return lc;
|
Bug#22684 (BENCHMARK, ENCODE, DECODE and FORMAT are not real functions)
Before this change, the functions BENCHMARK, ENCODE, DECODE and FORMAT could
only accept a constant for some parameters.
After this change, this restriction has been removed. An implication is that
these functions can also be used in prepared statements.
The change consist of changing the following classes:
- Item_func_benchmark
- Item_func_encode
- Item_func_decode
- Item_func_format
to:
- only accept Item* in the constructor,
- and evaluate arguments during calls to val_xxx()
which fits the general design of all the other functions.
The 'TODO' items identified in item_create.cc during the work done for
Bug 21114 are addressed by this fix, as a natural consequence of aligning
the design.
In the 'func_str' test, a single very long test line involving an explain
extended select with many functions has been rewritten into multiple
separate tests, to improve maintainability.
The result of explain extended select decode(encode(...)) has changed,
since the encode and decode functions now print all their parameters.
2006-11-16 17:03:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void Item_func_format::fix_length_and_dec()
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
Bug#22684 (BENCHMARK, ENCODE, DECODE and FORMAT are not real functions)
Before this change, the functions BENCHMARK, ENCODE, DECODE and FORMAT could
only accept a constant for some parameters.
After this change, this restriction has been removed. An implication is that
these functions can also be used in prepared statements.
The change consist of changing the following classes:
- Item_func_benchmark
- Item_func_encode
- Item_func_decode
- Item_func_format
to:
- only accept Item* in the constructor,
- and evaluate arguments during calls to val_xxx()
which fits the general design of all the other functions.
The 'TODO' items identified in item_create.cc during the work done for
Bug 21114 are addressed by this fix, as a natural consequence of aligning
the design.
In the 'func_str' test, a single very long test line involving an explain
extended select with many functions has been rewritten into multiple
separate tests, to improve maintainability.
The result of explain extended select decode(encode(...)) has changed,
since the encode and decode functions now print all their parameters.
2006-11-16 17:03:47 +01:00
|
|
|
uint char_length= args[0]->max_length/args[0]->collation.collation->mbmaxlen;
|
2008-12-09 12:16:39 +01:00
|
|
|
uint max_sep_count= char_length/3 + (decimals ? 1 : 0) + /*sign*/1;
|
|
|
|
collation.set(default_charset());
|
|
|
|
max_length= (char_length + max_sep_count + decimals) *
|
|
|
|
collation.collation->mbmaxlen;
|
2009-10-05 17:06:04 +02:00
|
|
|
if (arg_count == 3)
|
|
|
|
locale= args[2]->basic_const_item() ? get_locale(args[2]) : NULL;
|
|
|
|
else
|
|
|
|
locale= &my_locale_en_US; /* Two arguments */
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
/**
|
|
|
|
@todo
|
|
|
|
This needs to be fixed for multi-byte character set where numbers
|
2003-12-19 15:25:50 +01:00
|
|
|
are stored in more than one byte
|
|
|
|
*/
|
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
String *Item_func_format::val_str(String *str)
|
|
|
|
{
|
Bug#22684 (BENCHMARK, ENCODE, DECODE and FORMAT are not real functions)
Before this change, the functions BENCHMARK, ENCODE, DECODE and FORMAT could
only accept a constant for some parameters.
After this change, this restriction has been removed. An implication is that
these functions can also be used in prepared statements.
The change consist of changing the following classes:
- Item_func_benchmark
- Item_func_encode
- Item_func_decode
- Item_func_format
to:
- only accept Item* in the constructor,
- and evaluate arguments during calls to val_xxx()
which fits the general design of all the other functions.
The 'TODO' items identified in item_create.cc during the work done for
Bug 21114 are addressed by this fix, as a natural consequence of aligning
the design.
In the 'func_str' test, a single very long test line involving an explain
extended select with many functions has been rewritten into multiple
separate tests, to improve maintainability.
The result of explain extended select decode(encode(...)) has changed,
since the encode and decode functions now print all their parameters.
2006-11-16 17:03:47 +01:00
|
|
|
uint32 str_length;
|
|
|
|
/* Number of decimal digits */
|
|
|
|
int dec;
|
|
|
|
/* Number of characters used to represent the decimals, including '.' */
|
|
|
|
uint32 dec_length;
|
2009-10-05 17:06:04 +02:00
|
|
|
MY_LOCALE *lc;
|
2005-06-08 12:49:36 +02:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
Bug#22684 (BENCHMARK, ENCODE, DECODE and FORMAT are not real functions)
Before this change, the functions BENCHMARK, ENCODE, DECODE and FORMAT could
only accept a constant for some parameters.
After this change, this restriction has been removed. An implication is that
these functions can also be used in prepared statements.
The change consist of changing the following classes:
- Item_func_benchmark
- Item_func_encode
- Item_func_decode
- Item_func_format
to:
- only accept Item* in the constructor,
- and evaluate arguments during calls to val_xxx()
which fits the general design of all the other functions.
The 'TODO' items identified in item_create.cc during the work done for
Bug 21114 are addressed by this fix, as a natural consequence of aligning
the design.
In the 'func_str' test, a single very long test line involving an explain
extended select with many functions has been rewritten into multiple
separate tests, to improve maintainability.
The result of explain extended select decode(encode(...)) has changed,
since the encode and decode functions now print all their parameters.
2006-11-16 17:03:47 +01:00
|
|
|
|
2007-02-23 12:13:55 +01:00
|
|
|
dec= (int) args[1]->val_int();
|
Bug#22684 (BENCHMARK, ENCODE, DECODE and FORMAT are not real functions)
Before this change, the functions BENCHMARK, ENCODE, DECODE and FORMAT could
only accept a constant for some parameters.
After this change, this restriction has been removed. An implication is that
these functions can also be used in prepared statements.
The change consist of changing the following classes:
- Item_func_benchmark
- Item_func_encode
- Item_func_decode
- Item_func_format
to:
- only accept Item* in the constructor,
- and evaluate arguments during calls to val_xxx()
which fits the general design of all the other functions.
The 'TODO' items identified in item_create.cc during the work done for
Bug 21114 are addressed by this fix, as a natural consequence of aligning
the design.
In the 'func_str' test, a single very long test line involving an explain
extended select with many functions has been rewritten into multiple
separate tests, to improve maintainability.
The result of explain extended select decode(encode(...)) has changed,
since the encode and decode functions now print all their parameters.
2006-11-16 17:03:47 +01:00
|
|
|
if (args[1]->null_value)
|
|
|
|
{
|
|
|
|
null_value=1;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2009-10-05 17:06:04 +02:00
|
|
|
lc= locale ? locale : get_locale(args[2]);
|
|
|
|
|
Bug#22684 (BENCHMARK, ENCODE, DECODE and FORMAT are not real functions)
Before this change, the functions BENCHMARK, ENCODE, DECODE and FORMAT could
only accept a constant for some parameters.
After this change, this restriction has been removed. An implication is that
these functions can also be used in prepared statements.
The change consist of changing the following classes:
- Item_func_benchmark
- Item_func_encode
- Item_func_decode
- Item_func_format
to:
- only accept Item* in the constructor,
- and evaluate arguments during calls to val_xxx()
which fits the general design of all the other functions.
The 'TODO' items identified in item_create.cc during the work done for
Bug 21114 are addressed by this fix, as a natural consequence of aligning
the design.
In the 'func_str' test, a single very long test line involving an explain
extended select with many functions has been rewritten into multiple
separate tests, to improve maintainability.
The result of explain extended select decode(encode(...)) has changed,
since the encode and decode functions now print all their parameters.
2006-11-16 17:03:47 +01:00
|
|
|
dec= set_zone(dec, 0, FORMAT_MAX_DECIMALS);
|
|
|
|
dec_length= dec ? dec+1 : 0;
|
|
|
|
null_value=0;
|
2003-05-13 09:54:07 +02:00
|
|
|
|
2005-06-08 12:49:36 +02:00
|
|
|
if (args[0]->result_type() == DECIMAL_RESULT ||
|
|
|
|
args[0]->result_type() == INT_RESULT)
|
|
|
|
{
|
|
|
|
my_decimal dec_val, rnd_dec, *res;
|
|
|
|
res= args[0]->val_decimal(&dec_val);
|
2005-09-22 20:40:22 +02:00
|
|
|
if ((null_value=args[0]->null_value))
|
|
|
|
return 0; /* purecov: inspected */
|
Bug#22684 (BENCHMARK, ENCODE, DECODE and FORMAT are not real functions)
Before this change, the functions BENCHMARK, ENCODE, DECODE and FORMAT could
only accept a constant for some parameters.
After this change, this restriction has been removed. An implication is that
these functions can also be used in prepared statements.
The change consist of changing the following classes:
- Item_func_benchmark
- Item_func_encode
- Item_func_decode
- Item_func_format
to:
- only accept Item* in the constructor,
- and evaluate arguments during calls to val_xxx()
which fits the general design of all the other functions.
The 'TODO' items identified in item_create.cc during the work done for
Bug 21114 are addressed by this fix, as a natural consequence of aligning
the design.
In the 'func_str' test, a single very long test line involving an explain
extended select with many functions has been rewritten into multiple
separate tests, to improve maintainability.
The result of explain extended select decode(encode(...)) has changed,
since the encode and decode functions now print all their parameters.
2006-11-16 17:03:47 +01:00
|
|
|
my_decimal_round(E_DEC_FATAL_ERROR, res, dec, false, &rnd_dec);
|
2005-06-08 12:49:36 +02:00
|
|
|
my_decimal2string(E_DEC_FATAL_ERROR, &rnd_dec, 0, 0, 0, str);
|
|
|
|
str_length= str->length();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
double nr= args[0]->val_real();
|
|
|
|
if ((null_value=args[0]->null_value))
|
|
|
|
return 0; /* purecov: inspected */
|
2007-04-28 18:04:03 +02:00
|
|
|
nr= my_double_round(nr, (longlong) dec, FALSE, FALSE);
|
2005-06-08 12:49:36 +02:00
|
|
|
/* Here default_charset() is right as this is not an automatic conversion */
|
Bug#22684 (BENCHMARK, ENCODE, DECODE and FORMAT are not real functions)
Before this change, the functions BENCHMARK, ENCODE, DECODE and FORMAT could
only accept a constant for some parameters.
After this change, this restriction has been removed. An implication is that
these functions can also be used in prepared statements.
The change consist of changing the following classes:
- Item_func_benchmark
- Item_func_encode
- Item_func_decode
- Item_func_format
to:
- only accept Item* in the constructor,
- and evaluate arguments during calls to val_xxx()
which fits the general design of all the other functions.
The 'TODO' items identified in item_create.cc during the work done for
Bug 21114 are addressed by this fix, as a natural consequence of aligning
the design.
In the 'func_str' test, a single very long test line involving an explain
extended select with many functions has been rewritten into multiple
separate tests, to improve maintainability.
The result of explain extended select decode(encode(...)) has changed,
since the encode and decode functions now print all their parameters.
2006-11-16 17:03:47 +01:00
|
|
|
str->set_real(nr, dec, default_charset());
|
2005-06-08 12:49:36 +02:00
|
|
|
if (isnan(nr))
|
|
|
|
return str;
|
|
|
|
str_length=str->length();
|
|
|
|
}
|
2009-10-05 17:06:04 +02:00
|
|
|
/* We need this test to handle 'nan' and short values */
|
|
|
|
if (lc->grouping[0] > 0 &&
|
|
|
|
str_length >= dec_length + 1 + lc->grouping[0])
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2009-10-05 17:06:04 +02:00
|
|
|
char buf[DECIMAL_MAX_STR_LENGTH * 2]; /* 2 - in the worst case when grouping=1 */
|
|
|
|
int count;
|
|
|
|
const char *grouping= lc->grouping;
|
|
|
|
char sign_length= *str->ptr() == '-' ? 1 : 0;
|
|
|
|
const char *src= str->ptr() + str_length - dec_length - 1;
|
|
|
|
const char *src_begin= str->ptr() + sign_length;
|
|
|
|
char *dst= buf + sizeof(buf);
|
|
|
|
|
|
|
|
/* Put the fractional part */
|
|
|
|
if (dec)
|
|
|
|
{
|
|
|
|
dst-= (dec + 1);
|
|
|
|
*dst= lc->decimal_point;
|
|
|
|
memcpy(dst + 1, src + 2, dec);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Put the integer part with grouping */
|
|
|
|
for (count= *grouping; src >= src_begin; count--)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2009-10-05 17:06:04 +02:00
|
|
|
/*
|
|
|
|
When *grouping==0x80 (which means "end of grouping")
|
|
|
|
count will be initialized to -1 and
|
|
|
|
we'll never get into this "if" anymore.
|
|
|
|
*/
|
|
|
|
if (!count)
|
|
|
|
{
|
|
|
|
*--dst= lc->thousand_sep;
|
|
|
|
if (grouping[1])
|
|
|
|
grouping++;
|
|
|
|
count= *grouping;
|
|
|
|
}
|
|
|
|
DBUG_ASSERT(dst > buf);
|
|
|
|
*--dst= *src--;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
2009-10-05 17:06:04 +02:00
|
|
|
|
|
|
|
if (sign_length) /* Put '-' */
|
|
|
|
*--dst= *str->ptr();
|
|
|
|
|
|
|
|
/* Put the rest of the integer part without grouping */
|
|
|
|
str->copy(dst, buf + sizeof(buf) - dst, &my_charset_latin1);
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-22 11:30:33 +01:00
|
|
|
void Item_func_format::print(String *str, enum_query_type query_type)
|
2003-10-30 11:57:26 +01:00
|
|
|
{
|
2005-11-20 19:47:07 +01:00
|
|
|
str->append(STRING_WITH_LEN("format("));
|
2008-02-22 11:30:33 +01:00
|
|
|
args[0]->print(str, query_type);
|
Bug#22684 (BENCHMARK, ENCODE, DECODE and FORMAT are not real functions)
Before this change, the functions BENCHMARK, ENCODE, DECODE and FORMAT could
only accept a constant for some parameters.
After this change, this restriction has been removed. An implication is that
these functions can also be used in prepared statements.
The change consist of changing the following classes:
- Item_func_benchmark
- Item_func_encode
- Item_func_decode
- Item_func_format
to:
- only accept Item* in the constructor,
- and evaluate arguments during calls to val_xxx()
which fits the general design of all the other functions.
The 'TODO' items identified in item_create.cc during the work done for
Bug 21114 are addressed by this fix, as a natural consequence of aligning
the design.
In the 'func_str' test, a single very long test line involving an explain
extended select with many functions has been rewritten into multiple
separate tests, to improve maintainability.
The result of explain extended select decode(encode(...)) has changed,
since the encode and decode functions now print all their parameters.
2006-11-16 17:03:47 +01:00
|
|
|
str->append(',');
|
2008-02-22 11:30:33 +01:00
|
|
|
args[1]->print(str, query_type);
|
2003-10-30 11:57:26 +01:00
|
|
|
str->append(')');
|
|
|
|
}
|
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
void Item_func_elt::fix_length_and_dec()
|
|
|
|
{
|
|
|
|
max_length=0;
|
|
|
|
decimals=0;
|
2004-01-22 12:55:37 +01:00
|
|
|
|
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
2010-02-11 05:17:25 +01:00
|
|
|
if (agg_arg_charsets_for_string_result(collation, args + 1, arg_count - 1))
|
2003-07-04 15:12:23 +02:00
|
|
|
return;
|
|
|
|
|
2004-01-22 12:55:37 +01:00
|
|
|
for (uint i= 1 ; i < arg_count ; i++)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
|
|
|
set_if_bigger(max_length,args[i]->max_length);
|
|
|
|
set_if_bigger(decimals,args[i]->decimals);
|
|
|
|
}
|
|
|
|
maybe_null=1; // NULL if wrong first arg
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-11-11 19:39:35 +01:00
|
|
|
double Item_func_elt::val_real()
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2000-07-31 21:29:14 +02:00
|
|
|
uint tmp;
|
2003-06-20 17:04:52 +02:00
|
|
|
null_value=1;
|
2003-07-15 15:11:49 +02:00
|
|
|
if ((tmp=(uint) args[0]->val_int()) == 0 || tmp >= arg_count)
|
2000-07-31 21:29:14 +02:00
|
|
|
return 0.0;
|
2004-11-11 19:39:35 +01:00
|
|
|
double result= args[tmp]->val_real();
|
2003-08-11 21:44:43 +02:00
|
|
|
null_value= args[tmp]->null_value;
|
2003-06-20 17:04:52 +02:00
|
|
|
return result;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
2003-07-01 13:38:38 +02:00
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
longlong Item_func_elt::val_int()
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2000-07-31 21:29:14 +02:00
|
|
|
uint tmp;
|
2003-06-20 17:04:52 +02:00
|
|
|
null_value=1;
|
2003-07-15 15:11:49 +02:00
|
|
|
if ((tmp=(uint) args[0]->val_int()) == 0 || tmp >= arg_count)
|
2000-07-31 21:29:14 +02:00
|
|
|
return 0;
|
2003-08-11 21:44:43 +02:00
|
|
|
|
|
|
|
longlong result= args[tmp]->val_int();
|
|
|
|
null_value= args[tmp]->null_value;
|
2003-06-20 17:04:52 +02:00
|
|
|
return result;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
2003-07-01 13:38:38 +02:00
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
String *Item_func_elt::val_str(String *str)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2000-07-31 21:29:14 +02:00
|
|
|
uint tmp;
|
2003-06-20 17:04:52 +02:00
|
|
|
null_value=1;
|
2003-07-15 15:11:49 +02:00
|
|
|
if ((tmp=(uint) args[0]->val_int()) == 0 || tmp >= arg_count)
|
2000-07-31 21:29:14 +02:00
|
|
|
return NULL;
|
2003-06-20 17:04:52 +02:00
|
|
|
|
2003-08-11 21:44:43 +02:00
|
|
|
String *result= args[tmp]->val_str(str);
|
|
|
|
if (result)
|
|
|
|
result->set_charset(collation.collation);
|
|
|
|
null_value= args[tmp]->null_value;
|
2003-06-20 17:04:52 +02:00
|
|
|
return result;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-10-08 17:13:09 +02:00
|
|
|
void Item_func_make_set::split_sum_func(THD *thd, Item **ref_pointer_array,
|
2003-02-07 14:47:24 +01:00
|
|
|
List<Item> &fields)
|
2003-01-29 09:38:56 +01:00
|
|
|
{
|
2005-10-15 23:32:37 +02:00
|
|
|
item->split_sum_func2(thd, ref_pointer_array, fields, &item, TRUE);
|
2004-10-08 17:13:09 +02:00
|
|
|
Item_str_func::split_sum_func(thd, ref_pointer_array, fields);
|
2003-01-29 09:38:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
void Item_func_make_set::fix_length_and_dec()
|
|
|
|
{
|
|
|
|
max_length=arg_count-1;
|
2003-07-04 15:12:23 +02:00
|
|
|
|
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
2010-02-11 05:17:25 +01:00
|
|
|
if (agg_arg_charsets_for_string_result(collation, args, arg_count))
|
2003-07-04 15:12:23 +02:00
|
|
|
return;
|
|
|
|
|
2003-06-19 10:12:55 +02:00
|
|
|
for (uint i=0 ; i < arg_count ; i++)
|
2000-07-31 21:29:14 +02:00
|
|
|
max_length+=args[i]->max_length;
|
2005-02-08 23:50:45 +01:00
|
|
|
|
2003-06-26 04:38:19 +02:00
|
|
|
used_tables_cache|= item->used_tables();
|
|
|
|
not_null_tables_cache&= item->not_null_tables();
|
|
|
|
const_item_cache&= item->const_item();
|
2003-01-29 09:38:56 +01:00
|
|
|
with_sum_func= with_sum_func || item->with_sum_func;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Item_func_make_set::update_used_tables()
|
|
|
|
{
|
|
|
|
Item_func::update_used_tables();
|
|
|
|
item->update_used_tables();
|
|
|
|
used_tables_cache|=item->used_tables();
|
|
|
|
const_item_cache&=item->const_item();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
String *Item_func_make_set::val_str(String *str)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2000-07-31 21:29:14 +02:00
|
|
|
ulonglong bits;
|
|
|
|
bool first_found=0;
|
|
|
|
Item **ptr=args;
|
2003-09-18 15:58:02 +02:00
|
|
|
String *result=&my_empty_string;
|
2000-07-31 21:29:14 +02:00
|
|
|
|
|
|
|
bits=item->val_int();
|
|
|
|
if ((null_value=item->null_value))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (arg_count < 64)
|
|
|
|
bits &= ((ulonglong) 1 << arg_count)-1;
|
|
|
|
|
|
|
|
for (; bits; bits >>= 1, ptr++)
|
|
|
|
{
|
|
|
|
if (bits & 1)
|
|
|
|
{
|
|
|
|
String *res= (*ptr)->val_str(str);
|
2001-11-06 23:13:29 +01:00
|
|
|
if (res) // Skip nulls
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
|
|
|
if (!first_found)
|
|
|
|
{ // First argument
|
|
|
|
first_found=1;
|
|
|
|
if (res != str)
|
|
|
|
result=res; // Use original string
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (tmp_str.copy(*res)) // Don't use 'str'
|
2003-09-18 15:58:02 +02:00
|
|
|
return &my_empty_string;
|
2000-07-31 21:29:14 +02:00
|
|
|
result= &tmp_str;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (result != &tmp_str)
|
|
|
|
{ // Copy data to tmp_str
|
|
|
|
if (tmp_str.alloc(result->length()+res->length()+1) ||
|
|
|
|
tmp_str.copy(*result))
|
2003-09-18 15:58:02 +02:00
|
|
|
return &my_empty_string;
|
2000-07-31 21:29:14 +02:00
|
|
|
result= &tmp_str;
|
|
|
|
}
|
2006-08-15 02:59:43 +02:00
|
|
|
if (tmp_str.append(STRING_WITH_LEN(","), &my_charset_bin) || tmp_str.append(*res))
|
2003-09-18 15:58:02 +02:00
|
|
|
return &my_empty_string;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
WL#3817: Simplify string / memory area types and make things more consistent (first part)
The following type conversions was done:
- Changed byte to uchar
- Changed gptr to uchar*
- Change my_string to char *
- Change my_size_t to size_t
- Change size_s to size_t
Removed declaration of byte, gptr, my_string, my_size_t and size_s.
Following function parameter changes was done:
- All string functions in mysys/strings was changed to use size_t
instead of uint for string lengths.
- All read()/write() functions changed to use size_t (including vio).
- All protocoll functions changed to use size_t instead of uint
- Functions that used a pointer to a string length was changed to use size_t*
- Changed malloc(), free() and related functions from using gptr to use void *
as this requires fewer casts in the code and is more in line with how the
standard functions work.
- Added extra length argument to dirname_part() to return the length of the
created string.
- Changed (at least) following functions to take uchar* as argument:
- db_dump()
- my_net_write()
- net_write_command()
- net_store_data()
- DBUG_DUMP()
- decimal2bin() & bin2decimal()
- Changed my_compress() and my_uncompress() to use size_t. Changed one
argument to my_uncompress() from a pointer to a value as we only return
one value (makes function easier to use).
- Changed type of 'pack_data' argument to packfrm() to avoid casts.
- Changed in readfrm() and writefrom(), ha_discover and handler::discover()
the type for argument 'frmdata' to uchar** to avoid casts.
- Changed most Field functions to use uchar* instead of char* (reduced a lot of
casts).
- Changed field->val_xxx(xxx, new_ptr) to take const pointers.
Other changes:
- Removed a lot of not needed casts
- Added a few new cast required by other changes
- Added some cast to my_multi_malloc() arguments for safety (as string lengths
needs to be uint, not size_t).
- Fixed all calls to hash-get-key functions to use size_t*. (Needed to be done
explicitely as this conflict was often hided by casting the function to
hash_get_key).
- Changed some buffers to memory regions to uchar* to avoid casts.
- Changed some string lengths from uint to size_t.
- Changed field->ptr to be uchar* instead of char*. This allowed us to
get rid of a lot of casts.
- Some changes from true -> TRUE, false -> FALSE, unsigned char -> uchar
- Include zlib.h in some files as we needed declaration of crc32()
- Changed MY_FILE_ERROR to be (size_t) -1.
- Changed many variables to hold the result of my_read() / my_write() to be
size_t. This was needed to properly detect errors (which are
returned as (size_t) -1).
- Removed some very old VMS code
- Changed packfrm()/unpackfrm() to not be depending on uint size
(portability fix)
- Removed windows specific code to restore cursor position as this
causes slowdown on windows and we should not mix read() and pread()
calls anyway as this is not thread safe. Updated function comment to
reflect this. Changed function that depended on original behavior of
my_pwrite() to itself restore the cursor position (one such case).
- Added some missing checking of return value of malloc().
- Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid 'long' overflow.
- Changed type of table_def::m_size from my_size_t to ulong to reflect that
m_size is the number of elements in the array, not a string/memory
length.
- Moved THD::max_row_length() to table.cc (as it's not depending on THD).
Inlined max_row_length_blob() into this function.
- More function comments
- Fixed some compiler warnings when compiled without partitions.
- Removed setting of LEX_STRING() arguments in declaration (portability fix).
- Some trivial indentation/variable name changes.
- Some trivial code simplifications:
- Replaced some calls to alloc_root + memcpy to use
strmake_root()/strdup_root().
- Changed some calls from memdup() to strmake() (Safety fix)
- Simpler loops in client-simple.c
2007-05-10 11:59:39 +02:00
|
|
|
Item *Item_func_make_set::transform(Item_transformer transformer, uchar *arg)
|
2006-08-24 13:49:12 +02:00
|
|
|
{
|
|
|
|
DBUG_ASSERT(!current_thd->is_stmt_prepare());
|
|
|
|
|
|
|
|
Item *new_item= item->transform(transformer, arg);
|
|
|
|
if (!new_item)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
THD::change_item_tree() should be called only if the tree was
|
|
|
|
really transformed, i.e. when a new item has been created.
|
|
|
|
Otherwise we'll be allocating a lot of unnecessary memory for
|
|
|
|
change records at each execution.
|
|
|
|
*/
|
|
|
|
if (item != new_item)
|
|
|
|
current_thd->change_item_tree(&item, new_item);
|
|
|
|
return Item_str_func::transform(transformer, arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-22 11:30:33 +01:00
|
|
|
void Item_func_make_set::print(String *str, enum_query_type query_type)
|
2003-10-30 11:57:26 +01:00
|
|
|
{
|
2005-11-20 19:47:07 +01:00
|
|
|
str->append(STRING_WITH_LEN("make_set("));
|
2008-02-22 11:30:33 +01:00
|
|
|
item->print(str, query_type);
|
2003-10-30 11:57:26 +01:00
|
|
|
if (arg_count)
|
|
|
|
{
|
|
|
|
str->append(',');
|
2008-02-22 11:30:33 +01:00
|
|
|
print_args(str, 0, query_type);
|
2003-10-30 11:57:26 +01:00
|
|
|
}
|
|
|
|
str->append(')');
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
String *Item_func_char::val_str(String *str)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2000-07-31 21:29:14 +02:00
|
|
|
str->length(0);
|
2007-10-11 13:07:10 +02:00
|
|
|
str->set_charset(collation.collation);
|
2000-07-31 21:29:14 +02:00
|
|
|
for (uint i=0 ; i < arg_count ; i++)
|
|
|
|
{
|
|
|
|
int32 num=(int32) args[i]->val_int();
|
|
|
|
if (!args[i]->null_value)
|
2005-02-23 16:15:45 +01:00
|
|
|
{
|
2010-02-24 10:15:34 +01:00
|
|
|
char tmp[4];
|
|
|
|
if (num & 0xFF000000L)
|
|
|
|
{
|
|
|
|
mi_int4store(tmp, num);
|
|
|
|
str->append(tmp, 4, &my_charset_bin);
|
|
|
|
}
|
|
|
|
else if (num & 0xFF0000L)
|
|
|
|
{
|
|
|
|
mi_int3store(tmp, num);
|
|
|
|
str->append(tmp, 3, &my_charset_bin);
|
|
|
|
}
|
|
|
|
else if (num & 0xFF00L)
|
|
|
|
{
|
|
|
|
mi_int2store(tmp, num);
|
|
|
|
str->append(tmp, 2, &my_charset_bin);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
tmp[0]= (char) num;
|
|
|
|
str->append(tmp, 1, &my_charset_bin);
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
2005-02-23 16:15:45 +01:00
|
|
|
}
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
str->realloc(str->length()); // Add end 0 (for Purify)
|
2005-11-07 09:34:19 +01:00
|
|
|
return check_well_formed_result(str);
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
inline String* alloc_buffer(String *res,String *str,String *tmp_value,
|
|
|
|
ulong length)
|
|
|
|
{
|
|
|
|
if (res->alloced_length() < length)
|
|
|
|
{
|
|
|
|
if (str->alloced_length() >= length)
|
|
|
|
{
|
|
|
|
(void) str->copy(*res);
|
|
|
|
str->length(length);
|
|
|
|
return str;
|
|
|
|
}
|
2003-12-10 20:26:31 +01:00
|
|
|
if (tmp_value->alloc(length))
|
|
|
|
return 0;
|
|
|
|
(void) tmp_value->copy(*res);
|
|
|
|
tmp_value->length(length);
|
|
|
|
return tmp_value;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
res->length(length);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Item_func_repeat::fix_length_and_dec()
|
|
|
|
{
|
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
2010-02-11 05:17:25 +01:00
|
|
|
agg_arg_charsets_for_string_result(collation, args, 1);
|
2000-07-31 21:29:14 +02:00
|
|
|
if (args[1]->const_item())
|
|
|
|
{
|
2006-11-08 16:11:02 +01:00
|
|
|
/* must be longlong to avoid truncation */
|
|
|
|
longlong count= args[1]->val_int();
|
|
|
|
|
|
|
|
/* Assumes that the maximum length of a String is < INT_MAX32. */
|
|
|
|
/* Set here so that rest of code sees out-of-bound value as such. */
|
|
|
|
if (count > INT_MAX32)
|
|
|
|
count= INT_MAX32;
|
|
|
|
|
|
|
|
ulonglong max_result_length= (ulonglong) args[0]->max_length * count;
|
2005-07-19 18:25:05 +02:00
|
|
|
if (max_result_length >= MAX_BLOB_WIDTH)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2005-07-19 18:25:05 +02:00
|
|
|
max_result_length= MAX_BLOB_WIDTH;
|
|
|
|
maybe_null= 1;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
2005-07-19 18:25:05 +02:00
|
|
|
max_length= (ulong) max_result_length;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-07-19 18:25:05 +02:00
|
|
|
max_length= MAX_BLOB_WIDTH;
|
|
|
|
maybe_null= 1;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
/**
|
|
|
|
Item_func_repeat::str is carefully written to avoid reallocs
|
|
|
|
as much as possible at the cost of a local buffer
|
2000-07-31 21:29:14 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
String *Item_func_repeat::val_str(String *str)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2000-07-31 21:29:14 +02:00
|
|
|
uint length,tot_length;
|
|
|
|
char *to;
|
2006-11-08 16:11:02 +01:00
|
|
|
/* must be longlong to avoid truncation */
|
2006-12-19 23:54:12 +01:00
|
|
|
longlong count= args[1]->val_int();
|
2006-11-08 16:11:02 +01:00
|
|
|
String *res= args[0]->val_str(str);
|
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
if (args[0]->null_value || args[1]->null_value)
|
|
|
|
goto err; // string and/or delim are null
|
2006-11-08 16:11:02 +01:00
|
|
|
null_value= 0;
|
2007-02-23 10:28:50 +01:00
|
|
|
|
2007-03-28 09:32:49 +02:00
|
|
|
if (count <= 0 && (count == 0 || !args[1]->unsigned_flag))
|
2003-09-18 15:58:02 +02:00
|
|
|
return &my_empty_string;
|
2007-02-23 10:28:50 +01:00
|
|
|
|
2006-12-19 23:54:12 +01:00
|
|
|
/* Assumes that the maximum length of a String is < INT_MAX32. */
|
|
|
|
/* Bounds check on count: If this is triggered, we will error. */
|
|
|
|
if ((ulonglong) count > INT_MAX32)
|
|
|
|
count= INT_MAX32;
|
2000-07-31 21:29:14 +02:00
|
|
|
if (count == 1) // To avoid reallocs
|
|
|
|
return res;
|
|
|
|
length=res->length();
|
2002-07-23 17:31:22 +02:00
|
|
|
// Safe length check
|
2006-12-19 23:54:12 +01:00
|
|
|
if (length > current_thd->variables.max_allowed_packet / (uint) count)
|
2004-06-29 16:55:13 +02:00
|
|
|
{
|
|
|
|
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
|
|
|
ER_WARN_ALLOWED_PACKET_OVERFLOWED,
|
2004-07-21 18:27:45 +02:00
|
|
|
ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
|
|
|
|
func_name(), current_thd->variables.max_allowed_packet);
|
2004-06-29 16:55:13 +02:00
|
|
|
goto err;
|
|
|
|
}
|
2000-07-31 21:29:14 +02:00
|
|
|
tot_length= length*(uint) count;
|
|
|
|
if (!(res= alloc_buffer(res,str,&tmp_value,tot_length)))
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
to=(char*) res->ptr()+length;
|
|
|
|
while (--count)
|
|
|
|
{
|
|
|
|
memcpy(to,res->ptr(),length);
|
|
|
|
to+=length;
|
|
|
|
}
|
|
|
|
return (res);
|
|
|
|
|
|
|
|
err:
|
|
|
|
null_value=1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Item_func_rpad::fix_length_and_dec()
|
|
|
|
{
|
2006-06-30 09:26:36 +02:00
|
|
|
// Handle character set for args[0] and args[2].
|
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
2010-02-11 05:17:25 +01:00
|
|
|
if (agg_arg_charsets_for_string_result(collation, &args[0], 2, 2))
|
2003-06-24 14:12:07 +02:00
|
|
|
return;
|
2000-07-31 21:29:14 +02:00
|
|
|
if (args[1]->const_item())
|
|
|
|
{
|
2006-11-08 16:11:02 +01:00
|
|
|
ulonglong length= 0;
|
|
|
|
|
|
|
|
if (collation.collation->mbmaxlen > 0)
|
|
|
|
{
|
|
|
|
ulonglong temp= (ulonglong) args[1]->val_int();
|
|
|
|
|
|
|
|
/* Assumes that the maximum length of a String is < INT_MAX32. */
|
|
|
|
/* Set here so that rest of code sees out-of-bound value as such. */
|
|
|
|
if (temp > INT_MAX32)
|
|
|
|
temp = INT_MAX32;
|
|
|
|
|
|
|
|
length= temp * collation.collation->mbmaxlen;
|
|
|
|
}
|
|
|
|
|
2005-07-19 18:25:05 +02:00
|
|
|
if (length >= MAX_BLOB_WIDTH)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2005-07-19 18:25:05 +02:00
|
|
|
length= MAX_BLOB_WIDTH;
|
|
|
|
maybe_null= 1;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
2005-07-19 18:25:05 +02:00
|
|
|
max_length= (ulong) length;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-07-19 18:25:05 +02:00
|
|
|
max_length= MAX_BLOB_WIDTH;
|
|
|
|
maybe_null= 1;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
String *Item_func_rpad::val_str(String *str)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2003-09-25 14:31:20 +02:00
|
|
|
uint32 res_byte_length,res_char_length,pad_char_length,pad_byte_length;
|
2000-07-31 21:29:14 +02:00
|
|
|
char *to;
|
|
|
|
const char *ptr_pad;
|
2006-11-08 16:11:02 +01:00
|
|
|
/* must be longlong to avoid truncation */
|
|
|
|
longlong count= args[1]->val_int();
|
|
|
|
longlong byte_count;
|
|
|
|
String *res= args[0]->val_str(str);
|
|
|
|
String *rpad= args[2]->val_str(&rpad_str);
|
|
|
|
|
2006-12-19 23:54:12 +01:00
|
|
|
if (!res || args[1]->null_value || !rpad ||
|
|
|
|
((count < 0) && !args[1]->unsigned_flag))
|
|
|
|
goto err;
|
|
|
|
null_value=0;
|
2006-11-08 16:11:02 +01:00
|
|
|
/* Assumes that the maximum length of a String is < INT_MAX32. */
|
|
|
|
/* Set here so that rest of code sees out-of-bound value as such. */
|
2006-12-19 23:54:12 +01:00
|
|
|
if ((ulonglong) count > INT_MAX32)
|
2006-11-08 16:11:02 +01:00
|
|
|
count= INT_MAX32;
|
|
|
|
if (count <= (res_char_length= res->numchars()))
|
2000-12-15 09:58:17 +01:00
|
|
|
{ // String to pad is big enough
|
2006-11-30 02:40:42 +01:00
|
|
|
res->length(res->charpos((int) count)); // Shorten result if longer
|
2000-12-15 09:58:17 +01:00
|
|
|
return (res);
|
|
|
|
}
|
2003-09-25 14:31:20 +02:00
|
|
|
pad_char_length= rpad->numchars();
|
2006-11-08 16:11:02 +01:00
|
|
|
|
|
|
|
byte_count= count * collation.collation->mbmaxlen;
|
|
|
|
if ((ulonglong) byte_count > current_thd->variables.max_allowed_packet)
|
2004-06-29 16:55:13 +02:00
|
|
|
{
|
|
|
|
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
|
|
|
ER_WARN_ALLOWED_PACKET_OVERFLOWED,
|
2004-07-21 18:27:45 +02:00
|
|
|
ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
|
|
|
|
func_name(), current_thd->variables.max_allowed_packet);
|
2004-06-29 16:55:13 +02:00
|
|
|
goto err;
|
|
|
|
}
|
2005-07-18 14:33:18 +02:00
|
|
|
if (args[2]->null_value || !pad_char_length)
|
2000-07-31 21:29:14 +02:00
|
|
|
goto err;
|
2003-09-25 14:31:20 +02:00
|
|
|
res_byte_length= res->length(); /* Must be done before alloc_buffer */
|
2006-11-30 02:40:42 +01:00
|
|
|
if (!(res= alloc_buffer(res,str,&tmp_value, (ulong) byte_count)))
|
2000-07-31 21:29:14 +02:00
|
|
|
goto err;
|
|
|
|
|
2003-09-25 14:31:20 +02:00
|
|
|
to= (char*) res->ptr()+res_byte_length;
|
2000-07-31 21:29:14 +02:00
|
|
|
ptr_pad=rpad->ptr();
|
2003-09-25 14:31:20 +02:00
|
|
|
pad_byte_length= rpad->length();
|
|
|
|
count-= res_char_length;
|
|
|
|
for ( ; (uint32) count > pad_char_length; count-= pad_char_length)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2003-09-25 14:31:20 +02:00
|
|
|
memcpy(to,ptr_pad,pad_byte_length);
|
|
|
|
to+= pad_byte_length;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
2003-09-25 14:31:20 +02:00
|
|
|
if (count)
|
|
|
|
{
|
2006-11-30 02:40:42 +01:00
|
|
|
pad_byte_length= rpad->charpos((int) count);
|
2003-09-25 14:31:20 +02:00
|
|
|
memcpy(to,ptr_pad,(size_t) pad_byte_length);
|
|
|
|
to+= pad_byte_length;
|
|
|
|
}
|
2009-02-10 23:47:54 +01:00
|
|
|
res->length((uint) (to- (char*) res->ptr()));
|
2000-07-31 21:29:14 +02:00
|
|
|
return (res);
|
|
|
|
|
|
|
|
err:
|
|
|
|
null_value=1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Item_func_lpad::fix_length_and_dec()
|
|
|
|
{
|
2006-06-30 09:26:36 +02:00
|
|
|
// Handle character set for args[0] and args[2].
|
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
2010-02-11 05:17:25 +01:00
|
|
|
if (agg_arg_charsets_for_string_result(collation, &args[0], 2, 2))
|
2003-06-24 14:12:07 +02:00
|
|
|
return;
|
2003-06-19 10:12:55 +02:00
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
if (args[1]->const_item())
|
|
|
|
{
|
2006-11-08 16:11:02 +01:00
|
|
|
ulonglong length= 0;
|
|
|
|
|
|
|
|
if (collation.collation->mbmaxlen > 0)
|
|
|
|
{
|
|
|
|
ulonglong temp= (ulonglong) args[1]->val_int();
|
|
|
|
|
|
|
|
/* Assumes that the maximum length of a String is < INT_MAX32. */
|
|
|
|
/* Set here so that rest of code sees out-of-bound value as such. */
|
|
|
|
if (temp > INT_MAX32)
|
|
|
|
temp= INT_MAX32;
|
|
|
|
|
|
|
|
length= temp * collation.collation->mbmaxlen;
|
|
|
|
}
|
|
|
|
|
2005-07-19 18:25:05 +02:00
|
|
|
if (length >= MAX_BLOB_WIDTH)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2005-07-19 18:25:05 +02:00
|
|
|
length= MAX_BLOB_WIDTH;
|
|
|
|
maybe_null= 1;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
2005-07-19 18:25:05 +02:00
|
|
|
max_length= (ulong) length;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-07-19 18:25:05 +02:00
|
|
|
max_length= MAX_BLOB_WIDTH;
|
|
|
|
maybe_null= 1;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
String *Item_func_lpad::val_str(String *str)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2003-11-20 21:06:25 +01:00
|
|
|
uint32 res_char_length,pad_char_length;
|
2006-11-08 16:11:02 +01:00
|
|
|
/* must be longlong to avoid truncation */
|
|
|
|
longlong count= args[1]->val_int();
|
|
|
|
longlong byte_count;
|
2003-12-22 16:00:51 +01:00
|
|
|
String *res= args[0]->val_str(&tmp_value);
|
|
|
|
String *pad= args[2]->val_str(&lpad_str);
|
2000-07-31 21:29:14 +02:00
|
|
|
|
2006-12-19 23:54:12 +01:00
|
|
|
if (!res || args[1]->null_value || !pad ||
|
|
|
|
((count < 0) && !args[1]->unsigned_flag))
|
|
|
|
goto err;
|
|
|
|
null_value=0;
|
2006-11-08 16:11:02 +01:00
|
|
|
/* Assumes that the maximum length of a String is < INT_MAX32. */
|
|
|
|
/* Set here so that rest of code sees out-of-bound value as such. */
|
2006-12-19 23:54:12 +01:00
|
|
|
if ((ulonglong) count > INT_MAX32)
|
2006-11-08 16:11:02 +01:00
|
|
|
count= INT_MAX32;
|
2003-09-25 14:31:20 +02:00
|
|
|
|
|
|
|
res_char_length= res->numchars();
|
|
|
|
|
|
|
|
if (count <= res_char_length)
|
|
|
|
{
|
2006-11-30 02:40:42 +01:00
|
|
|
res->length(res->charpos((int) count));
|
2003-09-25 14:31:20 +02:00
|
|
|
return res;
|
2000-12-15 09:58:17 +01:00
|
|
|
}
|
2003-09-25 14:31:20 +02:00
|
|
|
|
|
|
|
pad_char_length= pad->numchars();
|
|
|
|
byte_count= count * collation.collation->mbmaxlen;
|
|
|
|
|
2006-11-27 17:16:08 +01:00
|
|
|
if ((ulonglong) byte_count > current_thd->variables.max_allowed_packet)
|
2004-06-29 16:55:13 +02:00
|
|
|
{
|
|
|
|
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
|
|
|
ER_WARN_ALLOWED_PACKET_OVERFLOWED,
|
2004-07-21 18:27:45 +02:00
|
|
|
ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
|
|
|
|
func_name(), current_thd->variables.max_allowed_packet);
|
2004-06-29 16:55:13 +02:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
2006-11-30 02:40:42 +01:00
|
|
|
if (args[2]->null_value || !pad_char_length ||
|
|
|
|
str->alloc((uint32) byte_count))
|
2000-07-31 21:29:14 +02:00
|
|
|
goto err;
|
2003-09-25 14:31:20 +02:00
|
|
|
|
|
|
|
str->length(0);
|
|
|
|
str->set_charset(collation.collation);
|
|
|
|
count-= res_char_length;
|
|
|
|
while (count >= pad_char_length)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2003-09-25 14:31:20 +02:00
|
|
|
str->append(*pad);
|
|
|
|
count-= pad_char_length;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
2003-09-25 14:31:20 +02:00
|
|
|
if (count > 0)
|
2006-11-30 02:40:42 +01:00
|
|
|
str->append(pad->ptr(), pad->charpos((int) count), collation.collation);
|
2004-06-07 15:39:17 +02:00
|
|
|
|
2003-09-25 14:31:20 +02:00
|
|
|
str->append(*res);
|
|
|
|
null_value= 0;
|
|
|
|
return str;
|
2000-07-31 21:29:14 +02:00
|
|
|
|
2003-09-25 14:31:20 +02:00
|
|
|
err:
|
|
|
|
null_value= 1;
|
2000-07-31 21:29:14 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
String *Item_func_conv::val_str(String *str)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2000-07-31 21:29:14 +02:00
|
|
|
String *res= args[0]->val_str(str);
|
|
|
|
char *endptr,ans[65],*ptr;
|
|
|
|
longlong dec;
|
|
|
|
int from_base= (int) args[1]->val_int();
|
|
|
|
int to_base= (int) args[2]->val_int();
|
2003-01-16 14:17:07 +01:00
|
|
|
int err;
|
2000-07-31 21:29:14 +02:00
|
|
|
|
|
|
|
if (args[0]->null_value || args[1]->null_value || args[2]->null_value ||
|
|
|
|
abs(to_base) > 36 || abs(to_base) < 2 ||
|
|
|
|
abs(from_base) > 36 || abs(from_base) < 2 || !(res->length()))
|
|
|
|
{
|
2006-08-22 17:51:00 +02:00
|
|
|
null_value= 1;
|
|
|
|
return NULL;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
2006-08-22 17:51:00 +02:00
|
|
|
null_value= 0;
|
2005-02-02 08:34:31 +01:00
|
|
|
unsigned_flag= !(from_base < 0);
|
2006-08-22 17:51:00 +02:00
|
|
|
|
|
|
|
if (args[0]->field_type() == MYSQL_TYPE_BIT)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
Special case: The string representation of BIT doesn't resemble the
|
|
|
|
decimal representation, so we shouldn't change it to string and then to
|
|
|
|
decimal.
|
|
|
|
*/
|
|
|
|
dec= args[0]->val_int();
|
|
|
|
}
|
2000-07-31 21:29:14 +02:00
|
|
|
else
|
2006-08-22 17:51:00 +02:00
|
|
|
{
|
|
|
|
if (from_base < 0)
|
|
|
|
dec= my_strntoll(res->charset(), res->ptr(), res->length(),
|
|
|
|
-from_base, &endptr, &err);
|
|
|
|
else
|
|
|
|
dec= (longlong) my_strntoull(res->charset(), res->ptr(), res->length(),
|
|
|
|
from_base, &endptr, &err);
|
|
|
|
}
|
|
|
|
|
|
|
|
ptr= longlong2str(dec, ans, to_base);
|
|
|
|
if (str->copy(ans, (uint32) (ptr-ans), default_charset()))
|
2003-09-18 15:58:02 +02:00
|
|
|
return &my_empty_string;
|
2000-07-31 21:29:14 +02:00
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2001-12-13 14:53:18 +01:00
|
|
|
|
2002-03-29 15:22:21 +01:00
|
|
|
String *Item_func_conv_charset::val_str(String *str)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2005-11-21 14:26:31 +01:00
|
|
|
if (use_cached_value)
|
|
|
|
return null_value ? 0 : &str_value;
|
2009-05-21 10:06:43 +02:00
|
|
|
/*
|
|
|
|
Here we don't pass 'str' as a parameter to args[0]->val_str()
|
2009-06-16 16:36:15 +02:00
|
|
|
as 'str' may point to 'str_value' (e.g. see Item::save_in_field()),
|
2009-05-21 10:06:43 +02:00
|
|
|
which we use below to convert string.
|
|
|
|
Use argument's 'str_value' instead.
|
|
|
|
*/
|
2009-06-16 16:36:15 +02:00
|
|
|
String *arg= args[0]->val_str(&args[0]->str_value);
|
2004-10-29 14:00:39 +02:00
|
|
|
uint dummy_errors;
|
2002-03-29 15:22:21 +01:00
|
|
|
if (!arg)
|
|
|
|
{
|
|
|
|
null_value=1;
|
|
|
|
return 0;
|
|
|
|
}
|
2004-08-26 17:26:38 +02:00
|
|
|
null_value= str_value.copy(arg->ptr(),arg->length(),arg->charset(),
|
2004-10-29 14:00:39 +02:00
|
|
|
conv_charset, &dummy_errors);
|
2005-11-07 09:34:19 +01:00
|
|
|
return null_value ? 0 : check_well_formed_result(&str_value);
|
2002-03-29 15:22:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void Item_func_conv_charset::fix_length_and_dec()
|
|
|
|
{
|
2003-08-05 09:52:37 +02:00
|
|
|
collation.set(conv_charset, DERIVATION_IMPLICIT);
|
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
2010-02-11 05:17:25 +01:00
|
|
|
fix_char_length(args[0]->max_char_length());
|
2002-03-29 15:22:21 +01:00
|
|
|
}
|
|
|
|
|
2008-02-22 11:30:33 +01:00
|
|
|
void Item_func_conv_charset::print(String *str, enum_query_type query_type)
|
2003-10-30 11:57:26 +01:00
|
|
|
{
|
2005-11-20 19:47:07 +01:00
|
|
|
str->append(STRING_WITH_LEN("convert("));
|
2008-02-22 11:30:33 +01:00
|
|
|
args[0]->print(str, query_type);
|
2005-11-20 19:47:07 +01:00
|
|
|
str->append(STRING_WITH_LEN(" using "));
|
2003-10-30 11:57:26 +01:00
|
|
|
str->append(conv_charset->csname);
|
|
|
|
str->append(')');
|
|
|
|
}
|
2002-08-22 15:12:45 +02:00
|
|
|
|
|
|
|
String *Item_func_set_collation::val_str(String *str)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2002-08-22 15:12:45 +02:00
|
|
|
str=args[0]->val_str(str);
|
2002-09-13 11:11:06 +02:00
|
|
|
if ((null_value=args[0]->null_value))
|
|
|
|
return 0;
|
2003-08-05 09:52:37 +02:00
|
|
|
str->set_charset(collation.collation);
|
2002-08-22 15:12:45 +02:00
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2003-03-21 14:21:45 +01:00
|
|
|
void Item_func_set_collation::fix_length_and_dec()
|
2002-08-22 15:12:45 +02:00
|
|
|
{
|
2003-03-04 16:53:53 +01:00
|
|
|
CHARSET_INFO *set_collation;
|
|
|
|
const char *colname;
|
2003-03-21 14:21:45 +01:00
|
|
|
String tmp, *str= args[1]->val_str(&tmp);
|
2003-03-04 16:53:53 +01:00
|
|
|
colname= str->c_ptr();
|
2003-05-21 20:39:58 +02:00
|
|
|
if (colname == binary_keyword)
|
2003-08-05 09:52:37 +02:00
|
|
|
set_collation= get_charset_by_csname(args[0]->collation.collation->csname,
|
2003-03-04 16:53:53 +01:00
|
|
|
MY_CS_BINSORT,MYF(0));
|
|
|
|
else
|
2003-07-29 14:12:14 +02:00
|
|
|
{
|
|
|
|
if (!(set_collation= get_charset_by_name(colname,MYF(0))))
|
|
|
|
{
|
|
|
|
my_error(ER_UNKNOWN_COLLATION, MYF(0), colname);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2003-04-01 07:26:36 +02:00
|
|
|
|
2003-08-05 09:52:37 +02:00
|
|
|
if (!set_collation ||
|
|
|
|
!my_charset_same(args[0]->collation.collation,set_collation))
|
2003-03-02 11:05:03 +01:00
|
|
|
{
|
2004-11-13 18:35:51 +01:00
|
|
|
my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0),
|
|
|
|
colname, args[0]->collation.collation->csname);
|
2003-03-21 14:21:45 +01:00
|
|
|
return;
|
2003-03-02 11:05:03 +01:00
|
|
|
}
|
2007-08-03 12:25:23 +02:00
|
|
|
collation.set(set_collation, DERIVATION_EXPLICIT,
|
|
|
|
args[0]->collation.repertoire);
|
2003-03-21 14:21:45 +01:00
|
|
|
max_length= args[0]->max_length;
|
2002-08-22 15:12:45 +02:00
|
|
|
}
|
|
|
|
|
2003-03-21 14:21:45 +01:00
|
|
|
|
2002-08-26 14:33:44 +02:00
|
|
|
bool Item_func_set_collation::eq(const Item *item, bool binary_cmp) const
|
|
|
|
{
|
|
|
|
/* Assume we don't have rtti */
|
|
|
|
if (this == item)
|
|
|
|
return 1;
|
|
|
|
if (item->type() != FUNC_ITEM)
|
|
|
|
return 0;
|
|
|
|
Item_func *item_func=(Item_func*) item;
|
|
|
|
if (arg_count != item_func->arg_count ||
|
2005-06-17 16:27:47 +02:00
|
|
|
functype() != item_func->functype())
|
2002-08-26 14:33:44 +02:00
|
|
|
return 0;
|
|
|
|
Item_func_set_collation *item_func_sc=(Item_func_set_collation*) item;
|
2003-08-05 09:52:37 +02:00
|
|
|
if (collation.collation != item_func_sc->collation.collation)
|
2002-08-26 14:33:44 +02:00
|
|
|
return 0;
|
|
|
|
for (uint i=0; i < arg_count ; i++)
|
|
|
|
if (!args[i]->eq(item_func_sc->args[i], binary_cmp))
|
|
|
|
return 0;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2004-08-31 09:06:38 +02:00
|
|
|
|
2008-02-22 11:30:33 +01:00
|
|
|
void Item_func_set_collation::print(String *str, enum_query_type query_type)
|
2004-08-31 09:06:38 +02:00
|
|
|
{
|
|
|
|
str->append('(');
|
2008-02-22 11:30:33 +01:00
|
|
|
args[0]->print(str, query_type);
|
2005-11-20 19:47:07 +01:00
|
|
|
str->append(STRING_WITH_LEN(" collate "));
|
2004-08-31 09:06:38 +02:00
|
|
|
DBUG_ASSERT(args[1]->basic_const_item() &&
|
|
|
|
args[1]->type() == Item::STRING_ITEM);
|
|
|
|
args[1]->str_value.print(str);
|
|
|
|
str->append(')');
|
|
|
|
}
|
|
|
|
|
2002-06-26 13:00:43 +02:00
|
|
|
String *Item_func_charset::val_str(String *str)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2004-10-29 14:00:39 +02:00
|
|
|
uint dummy_errors;
|
2002-06-26 13:00:43 +02:00
|
|
|
|
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
2010-02-11 05:17:25 +01:00
|
|
|
CHARSET_INFO *cs= args[0]->charset_for_protocol();
|
2005-03-16 14:44:29 +01:00
|
|
|
null_value= 0;
|
2009-02-10 23:47:54 +01:00
|
|
|
str->copy(cs->csname, (uint) strlen(cs->csname),
|
2004-10-29 14:00:39 +02:00
|
|
|
&my_charset_latin1, collation.collation, &dummy_errors);
|
2003-02-27 13:53:10 +01:00
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
|
|
|
String *Item_func_collation::val_str(String *str)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2004-10-29 14:00:39 +02:00
|
|
|
uint dummy_errors;
|
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
2010-02-11 05:17:25 +01:00
|
|
|
CHARSET_INFO *cs= args[0]->charset_for_protocol();
|
2003-02-27 13:53:10 +01:00
|
|
|
|
2005-03-16 14:44:29 +01:00
|
|
|
null_value= 0;
|
2009-02-10 23:47:54 +01:00
|
|
|
str->copy(cs->name, (uint) strlen(cs->name),
|
2004-10-29 14:00:39 +02:00
|
|
|
&my_charset_latin1, collation.collation, &dummy_errors);
|
2002-06-26 13:00:43 +02:00
|
|
|
return str;
|
|
|
|
}
|
2002-06-20 20:26:04 +02:00
|
|
|
|
|
|
|
|
2001-12-13 14:53:18 +01:00
|
|
|
String *Item_func_hex::val_str(String *str)
|
|
|
|
{
|
2005-10-11 23:58:22 +02:00
|
|
|
String *res;
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2001-12-13 14:53:18 +01:00
|
|
|
if (args[0]->result_type() != STRING_RESULT)
|
|
|
|
{
|
2005-07-13 11:23:09 +02:00
|
|
|
ulonglong dec;
|
2001-12-13 14:53:18 +01:00
|
|
|
char ans[65],*ptr;
|
2005-07-13 11:23:09 +02:00
|
|
|
/* Return hex of unsigned longlong value */
|
2005-07-13 13:08:14 +02:00
|
|
|
if (args[0]->result_type() == REAL_RESULT ||
|
|
|
|
args[0]->result_type() == DECIMAL_RESULT)
|
2005-07-13 11:23:09 +02:00
|
|
|
{
|
2005-07-13 13:08:14 +02:00
|
|
|
double val= args[0]->val_real();
|
2005-07-13 11:23:09 +02:00
|
|
|
if ((val <= (double) LONGLONG_MIN) ||
|
|
|
|
(val >= (double) (ulonglong) ULONGLONG_MAX))
|
|
|
|
dec= ~(longlong) 0;
|
|
|
|
else
|
|
|
|
dec= (ulonglong) (val + (val > 0 ? 0.5 : -0.5));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
dec= (ulonglong) args[0]->val_int();
|
|
|
|
|
2001-12-13 14:53:18 +01:00
|
|
|
if ((null_value= args[0]->null_value))
|
|
|
|
return 0;
|
|
|
|
ptr= longlong2str(dec,ans,16);
|
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
2010-02-11 05:17:25 +01:00
|
|
|
if (str->copy(ans,(uint32) (ptr-ans), &my_charset_numeric))
|
2003-09-18 15:58:02 +02:00
|
|
|
return &my_empty_string; // End of memory
|
2001-12-13 14:53:18 +01:00
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Convert given string to a hex string, character by character */
|
2005-10-11 23:58:22 +02:00
|
|
|
res= args[0]->val_str(str);
|
|
|
|
if (!res || tmp_value.alloc(res->length()*2+1))
|
2001-12-13 14:53:18 +01:00
|
|
|
{
|
|
|
|
null_value=1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
null_value=0;
|
|
|
|
tmp_value.length(res->length()*2);
|
2005-10-11 23:58:22 +02:00
|
|
|
|
|
|
|
octet2hex((char*) tmp_value.ptr(), res->ptr(), res->length());
|
2001-12-13 14:53:18 +01:00
|
|
|
return &tmp_value;
|
|
|
|
}
|
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
/** Convert given hex string to a binary string. */
|
2004-07-09 09:55:16 +02:00
|
|
|
|
2004-03-04 23:18:54 +01:00
|
|
|
String *Item_func_unhex::val_str(String *str)
|
|
|
|
{
|
2004-07-09 09:55:16 +02:00
|
|
|
const char *from, *end;
|
|
|
|
char *to;
|
|
|
|
String *res;
|
|
|
|
uint length;
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2004-07-07 23:49:03 +02:00
|
|
|
|
2004-07-09 09:55:16 +02:00
|
|
|
res= args[0]->val_str(str);
|
|
|
|
if (!res || tmp_value.alloc(length= (1+res->length())/2))
|
2004-03-04 23:18:54 +01:00
|
|
|
{
|
|
|
|
null_value=1;
|
|
|
|
return 0;
|
|
|
|
}
|
2004-07-07 23:49:03 +02:00
|
|
|
|
2004-07-09 09:55:16 +02:00
|
|
|
from= res->ptr();
|
|
|
|
null_value= 0;
|
|
|
|
tmp_value.length(length);
|
2004-03-04 23:18:54 +01:00
|
|
|
to= (char*) tmp_value.ptr();
|
|
|
|
if (res->length() % 2)
|
|
|
|
{
|
2004-07-09 09:55:16 +02:00
|
|
|
int hex_char;
|
|
|
|
*to++= hex_char= hexchar_to_int(*from++);
|
|
|
|
if ((null_value= (hex_char == -1)))
|
2004-03-04 23:18:54 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
for (end=res->ptr()+res->length(); from < end ; from+=2, to++)
|
|
|
|
{
|
2004-07-09 09:55:16 +02:00
|
|
|
int hex_char;
|
|
|
|
*to= (hex_char= hexchar_to_int(from[0])) << 4;
|
|
|
|
if ((null_value= (hex_char == -1)))
|
2004-03-04 23:18:54 +01:00
|
|
|
return 0;
|
2004-07-09 09:55:16 +02:00
|
|
|
*to|= hex_char= hexchar_to_int(from[1]);
|
|
|
|
if ((null_value= (hex_char == -1)))
|
2004-03-04 23:18:54 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return &tmp_value;
|
|
|
|
}
|
2001-12-13 14:53:18 +01:00
|
|
|
|
2004-07-09 09:55:16 +02:00
|
|
|
|
2008-02-22 11:30:33 +01:00
|
|
|
void Item_func_binary::print(String *str, enum_query_type query_type)
|
2003-10-12 16:56:05 +02:00
|
|
|
{
|
2005-11-20 19:47:07 +01:00
|
|
|
str->append(STRING_WITH_LEN("cast("));
|
2008-02-22 11:30:33 +01:00
|
|
|
args[0]->print(str, query_type);
|
2005-11-20 19:47:07 +01:00
|
|
|
str->append(STRING_WITH_LEN(" as binary)"));
|
2003-10-12 16:56:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
#include <my_dir.h> // For my_stat
|
|
|
|
|
|
|
|
String *Item_load_file::val_str(String *str)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2000-07-31 21:29:14 +02:00
|
|
|
String *file_name;
|
|
|
|
File file;
|
|
|
|
MY_STAT stat_info;
|
2004-09-07 08:55:34 +02:00
|
|
|
char path[FN_REFLEN];
|
2000-07-31 21:29:14 +02:00
|
|
|
DBUG_ENTER("load_file");
|
|
|
|
|
2004-09-07 08:55:34 +02:00
|
|
|
if (!(file_name= args[0]->val_str(str))
|
2003-09-26 12:33:13 +02:00
|
|
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
2005-09-15 21:29:07 +02:00
|
|
|
|| !(current_thd->security_ctx->master_access & FILE_ACL)
|
2003-09-26 12:33:13 +02:00
|
|
|
#endif
|
2004-09-07 08:55:34 +02:00
|
|
|
)
|
2000-07-31 21:29:14 +02:00
|
|
|
goto err;
|
2004-09-07 08:55:34 +02:00
|
|
|
|
2009-05-12 10:18:27 +02:00
|
|
|
(void) fn_format(path, file_name->c_ptr_safe(), mysql_real_data_home, "",
|
2004-09-07 14:28:26 +02:00
|
|
|
MY_RELATIVE_PATH | MY_UNPACK_FILENAME);
|
2004-09-07 08:55:34 +02:00
|
|
|
|
2007-02-14 14:44:34 +01:00
|
|
|
/* Read only allowed from within dir specified by secure_file_priv */
|
2010-05-03 18:14:39 +02:00
|
|
|
if (!is_secure_file_path(path))
|
2007-02-14 14:44:34 +01:00
|
|
|
goto err;
|
|
|
|
|
2010-01-07 06:42:07 +01:00
|
|
|
if (!mysql_file_stat(key_file_loadfile, path, &stat_info, MYF(0)))
|
2004-09-07 08:55:34 +02:00
|
|
|
goto err;
|
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
if (!(stat_info.st_mode & S_IROTH))
|
|
|
|
{
|
|
|
|
/* my_error(ER_TEXTFILE_NOT_READABLE, MYF(0), file_name->c_ptr()); */
|
|
|
|
goto err;
|
|
|
|
}
|
2002-07-23 17:31:22 +02:00
|
|
|
if (stat_info.st_size > (long) current_thd->variables.max_allowed_packet)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2004-06-29 16:55:13 +02:00
|
|
|
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
|
|
|
ER_WARN_ALLOWED_PACKET_OVERFLOWED,
|
2004-07-21 18:27:45 +02:00
|
|
|
ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
|
|
|
|
func_name(), current_thd->variables.max_allowed_packet);
|
2000-07-31 21:29:14 +02:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
if (tmp_value.alloc(stat_info.st_size))
|
|
|
|
goto err;
|
2010-01-07 06:42:07 +01:00
|
|
|
if ((file= mysql_file_open(key_file_loadfile,
|
|
|
|
file_name->ptr(), O_RDONLY, MYF(0))) < 0)
|
2000-07-31 21:29:14 +02:00
|
|
|
goto err;
|
2010-01-07 06:42:07 +01:00
|
|
|
if (mysql_file_read(file, (uchar*) tmp_value.ptr(), stat_info.st_size,
|
|
|
|
MYF(MY_NABP)))
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2010-01-07 06:42:07 +01:00
|
|
|
mysql_file_close(file, MYF(0));
|
2000-07-31 21:29:14 +02:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
tmp_value.length(stat_info.st_size);
|
2010-01-07 06:42:07 +01:00
|
|
|
mysql_file_close(file, MYF(0));
|
2000-07-31 21:29:14 +02:00
|
|
|
null_value = 0;
|
2006-03-29 16:04:00 +02:00
|
|
|
DBUG_RETURN(&tmp_value);
|
2000-07-31 21:29:14 +02:00
|
|
|
|
|
|
|
err:
|
|
|
|
null_value = 1;
|
|
|
|
DBUG_RETURN(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
String* Item_func_export_set::val_str(String* str)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2000-07-31 21:29:14 +02:00
|
|
|
ulonglong the_set = (ulonglong) args[0]->val_int();
|
2002-12-04 23:14:51 +01:00
|
|
|
String yes_buf, *yes;
|
2000-07-31 21:29:14 +02:00
|
|
|
yes = args[1]->val_str(&yes_buf);
|
2002-12-04 23:14:51 +01:00
|
|
|
String no_buf, *no;
|
2000-07-31 21:29:14 +02:00
|
|
|
no = args[2]->val_str(&no_buf);
|
2002-12-04 23:14:51 +01:00
|
|
|
String *sep = NULL, sep_buf ;
|
2000-07-31 21:29:14 +02:00
|
|
|
|
|
|
|
uint num_set_values = 64;
|
|
|
|
ulonglong mask = 0x1;
|
|
|
|
str->length(0);
|
2005-03-16 14:44:29 +01:00
|
|
|
str->set_charset(collation.collation);
|
2000-07-31 21:29:14 +02:00
|
|
|
|
|
|
|
/* Check if some argument is a NULL value */
|
|
|
|
if (args[0]->null_value || args[1]->null_value || args[2]->null_value)
|
|
|
|
{
|
|
|
|
null_value=1;
|
|
|
|
return 0;
|
|
|
|
}
|
2003-12-09 23:00:20 +01:00
|
|
|
/*
|
|
|
|
Arg count can only be 3, 4 or 5 here. This is guaranteed from the
|
|
|
|
grammar for EXPORT_SET()
|
|
|
|
*/
|
2000-07-31 21:29:14 +02:00
|
|
|
switch(arg_count) {
|
|
|
|
case 5:
|
|
|
|
num_set_values = (uint) args[4]->val_int();
|
|
|
|
if (num_set_values > 64)
|
|
|
|
num_set_values=64;
|
|
|
|
if (args[4]->null_value)
|
|
|
|
{
|
|
|
|
null_value=1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/* Fall through */
|
|
|
|
case 4:
|
|
|
|
if (!(sep = args[3]->val_str(&sep_buf))) // Only true if NULL
|
|
|
|
{
|
|
|
|
null_value=1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 3:
|
2006-08-12 01:09:19 +02:00
|
|
|
{
|
|
|
|
/* errors is not checked - assume "," can always be converted */
|
|
|
|
uint errors;
|
2006-08-15 02:59:43 +02:00
|
|
|
sep_buf.copy(STRING_WITH_LEN(","), &my_charset_bin, collation.collation, &errors);
|
2006-08-12 01:09:19 +02:00
|
|
|
sep = &sep_buf;
|
|
|
|
}
|
2005-01-24 15:48:25 +01:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
DBUG_ASSERT(0); // cannot happen
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
null_value=0;
|
|
|
|
|
|
|
|
for (uint i = 0; i < num_set_values; i++, mask = (mask << 1))
|
|
|
|
{
|
|
|
|
if (the_set & mask)
|
|
|
|
str->append(*yes);
|
|
|
|
else
|
|
|
|
str->append(*no);
|
2002-06-11 10:20:31 +02:00
|
|
|
if (i != num_set_values - 1)
|
2000-07-31 21:29:14 +02:00
|
|
|
str->append(*sep);
|
|
|
|
}
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Item_func_export_set::fix_length_and_dec()
|
|
|
|
{
|
|
|
|
uint length=max(args[1]->max_length,args[2]->max_length);
|
|
|
|
uint sep_length=(arg_count > 3 ? args[3]->max_length : 1);
|
2003-06-19 10:12:55 +02:00
|
|
|
|
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
2010-02-11 05:17:25 +01:00
|
|
|
if (agg_arg_charsets_for_string_result(collation,
|
|
|
|
args + 1, min(4, arg_count) - 1))
|
2003-07-04 15:12:23 +02:00
|
|
|
return;
|
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
2010-02-11 05:17:25 +01:00
|
|
|
fix_char_length(length * 64 + sep_length * 63);
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
String* Item_func_inet_ntoa::val_str(String* str)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2000-07-31 21:29:14 +02:00
|
|
|
uchar buf[8], *p;
|
|
|
|
ulonglong n = (ulonglong) args[0]->val_int();
|
|
|
|
char num[4];
|
2002-04-06 17:47:54 +02:00
|
|
|
|
2002-04-02 16:42:01 +02:00
|
|
|
/*
|
2002-04-06 17:47:54 +02:00
|
|
|
We do not know if args[0] is NULL until we have called
|
2002-04-02 16:42:01 +02:00
|
|
|
some val function on it if args[0] is not a constant!
|
2002-04-06 17:47:54 +02:00
|
|
|
|
|
|
|
Also return null if n > 255.255.255.255
|
2002-04-02 16:42:01 +02:00
|
|
|
*/
|
2002-04-06 17:47:54 +02:00
|
|
|
if ((null_value= (args[0]->null_value || n > (ulonglong) LL(4294967295))))
|
2000-07-31 21:29:14 +02:00
|
|
|
return 0; // Null value
|
2002-04-02 16:42:01 +02:00
|
|
|
|
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
2010-02-11 05:17:25 +01:00
|
|
|
str->set_charset(collation.collation);
|
2000-07-31 21:29:14 +02:00
|
|
|
str->length(0);
|
2002-04-06 17:47:54 +02:00
|
|
|
int4store(buf,n);
|
2000-07-31 21:29:14 +02:00
|
|
|
|
2002-04-06 17:47:54 +02:00
|
|
|
/* Now we can assume little endian. */
|
2002-12-04 23:14:51 +01:00
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
num[3]='.';
|
2002-04-06 17:47:54 +02:00
|
|
|
for (p=buf+4 ; p-- > buf ; )
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
|
|
|
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';
|
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
2010-02-11 05:17:25 +01:00
|
|
|
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);
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
return str;
|
|
|
|
}
|
2002-08-08 17:25:53 +02:00
|
|
|
|
2002-08-30 11:40:40 +02:00
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
#define get_esc_bit(mask, num) (1 & (*((mask) + ((num) >> 3))) >> ((num) & 7))
|
|
|
|
|
|
|
|
/**
|
2002-08-12 02:33:46 +02:00
|
|
|
QUOTE() function returns argument string in single quotes suitable for
|
|
|
|
using in a SQL statement.
|
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
Adds a \\ before all characters that needs to be escaped in a SQL string.
|
|
|
|
We also escape '^Z' (END-OF-FILE in windows) to avoid probelms when
|
|
|
|
running commands from a file in windows.
|
2002-08-12 02:33:46 +02:00
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
This function is very useful when you want to generate SQL statements.
|
2002-08-12 02:33:46 +02:00
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
@note
|
2004-11-11 15:20:40 +01:00
|
|
|
QUOTE(NULL) returns the string 'NULL' (4 letters, without quotes).
|
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
@retval
|
|
|
|
str Quoted string
|
|
|
|
@retval
|
|
|
|
NULL Out of memory.
|
2002-08-09 12:42:38 +02:00
|
|
|
*/
|
2002-08-12 02:33:46 +02:00
|
|
|
|
2002-08-08 17:25:53 +02:00
|
|
|
String *Item_func_quote::val_str(String *str)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2002-08-12 02:33:46 +02:00
|
|
|
/*
|
|
|
|
Bit mask that has 1 for set for the position of the following characters:
|
|
|
|
0, \, ' and ^Z
|
2002-12-04 23:14:51 +01:00
|
|
|
*/
|
2002-08-12 02:33:46 +02:00
|
|
|
|
2002-08-29 17:20:04 +02:00
|
|
|
static uchar escmask[32]=
|
2002-08-12 02:33:46 +02:00
|
|
|
{
|
|
|
|
0x01, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x00,
|
|
|
|
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
|
|
};
|
2002-08-08 17:25:53 +02:00
|
|
|
|
2002-08-12 02:33:46 +02:00
|
|
|
char *from, *to, *end, *start;
|
|
|
|
String *arg= args[0]->val_str(str);
|
|
|
|
uint arg_length, new_length;
|
|
|
|
if (!arg) // Null argument
|
2004-11-11 15:20:40 +01:00
|
|
|
{
|
2005-11-20 19:47:07 +01:00
|
|
|
/* Return the string 'NULL' */
|
|
|
|
str->copy(STRING_WITH_LEN("NULL"), collation.collation);
|
2004-11-11 15:20:40 +01:00
|
|
|
null_value= 0;
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2002-08-12 02:33:46 +02:00
|
|
|
arg_length= arg->length();
|
|
|
|
new_length= arg_length+2; /* for beginning and ending ' signs */
|
2002-08-09 16:36:36 +02:00
|
|
|
|
2002-08-12 02:33:46 +02:00
|
|
|
for (from= (char*) arg->ptr(), end= from + arg_length; from < end; from++)
|
2003-12-12 21:26:58 +01:00
|
|
|
new_length+= get_esc_bit(escmask, (uchar) *from);
|
2002-08-10 12:13:05 +02:00
|
|
|
|
2005-02-02 03:29:10 +01:00
|
|
|
if (tmp_value.alloc(new_length))
|
2002-08-09 16:36:36 +02:00
|
|
|
goto null;
|
2002-08-12 02:33:46 +02:00
|
|
|
|
|
|
|
/*
|
2005-02-02 03:29:10 +01:00
|
|
|
We replace characters from the end to the beginning
|
2002-08-12 02:33:46 +02:00
|
|
|
*/
|
2005-02-02 03:29:10 +01:00
|
|
|
to= (char*) tmp_value.ptr() + new_length - 1;
|
2002-08-09 12:42:38 +02:00
|
|
|
*to--= '\'';
|
2003-01-01 12:59:35 +01:00
|
|
|
for (start= (char*) arg->ptr(),end= start + arg_length; end-- != start; to--)
|
2002-08-08 17:25:53 +02:00
|
|
|
{
|
2002-08-12 02:33:46 +02:00
|
|
|
/*
|
|
|
|
We can't use the bitmask here as we want to replace \O and ^Z with 0
|
|
|
|
and Z
|
|
|
|
*/
|
|
|
|
switch (*end) {
|
|
|
|
case 0:
|
|
|
|
*to--= '0';
|
|
|
|
*to= '\\';
|
|
|
|
break;
|
|
|
|
case '\032':
|
|
|
|
*to--= 'Z';
|
|
|
|
*to= '\\';
|
|
|
|
break;
|
|
|
|
case '\'':
|
|
|
|
case '\\':
|
|
|
|
*to--= *end;
|
|
|
|
*to= '\\';
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
*to= *end;
|
|
|
|
break;
|
|
|
|
}
|
2002-08-08 17:25:53 +02:00
|
|
|
}
|
2002-08-09 12:42:38 +02:00
|
|
|
*to= '\'';
|
2005-02-02 03:29:10 +01:00
|
|
|
tmp_value.length(new_length);
|
2005-02-02 17:21:11 +01:00
|
|
|
tmp_value.set_charset(collation.collation);
|
2004-05-17 09:47:16 +02:00
|
|
|
null_value= 0;
|
2005-02-02 03:29:10 +01:00
|
|
|
return &tmp_value;
|
2002-08-09 16:36:36 +02:00
|
|
|
|
|
|
|
null:
|
|
|
|
null_value= 1;
|
|
|
|
return 0;
|
2002-08-08 17:25:53 +02:00
|
|
|
}
|
2002-08-30 11:40:40 +02:00
|
|
|
|
2003-08-21 16:15:06 +02:00
|
|
|
longlong Item_func_uncompressed_length::val_int()
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2003-08-21 16:15:06 +02:00
|
|
|
String *res= args[0]->val_str(&value);
|
|
|
|
if (!res)
|
|
|
|
{
|
|
|
|
null_value=1;
|
|
|
|
return 0; /* purecov: inspected */
|
|
|
|
}
|
|
|
|
null_value=0;
|
|
|
|
if (res->is_empty()) return 0;
|
2003-11-04 22:04:07 +01:00
|
|
|
|
|
|
|
/*
|
2009-05-20 10:30:06 +02:00
|
|
|
If length is <= 4 bytes, data is corrupt. This is the best we can do
|
|
|
|
to detect garbage input without decompressing it.
|
|
|
|
*/
|
|
|
|
if (res->length() <= 4)
|
|
|
|
{
|
2009-09-10 11:18:29 +02:00
|
|
|
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
2009-05-20 10:30:06 +02:00
|
|
|
ER_ZLIB_Z_DATA_ERROR,
|
|
|
|
ER(ER_ZLIB_Z_DATA_ERROR));
|
|
|
|
null_value= 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
res->ptr() using is safe because we have tested that string is at least
|
|
|
|
5 bytes long.
|
2003-11-04 22:04:07 +01:00
|
|
|
res->c_ptr() is not used because:
|
|
|
|
- we do not need \0 terminated string to get first 4 bytes
|
|
|
|
- c_ptr() tests simbol after string end (uninitialiozed memory) which
|
|
|
|
confuse valgrind
|
|
|
|
*/
|
|
|
|
return uint4korr(res->ptr()) & 0x3FFFFFFF;
|
2003-08-21 16:15:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
longlong Item_func_crc32::val_int()
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2003-08-21 16:15:06 +02:00
|
|
|
String *res=args[0]->val_str(&value);
|
|
|
|
if (!res)
|
|
|
|
{
|
|
|
|
null_value=1;
|
|
|
|
return 0; /* purecov: inspected */
|
|
|
|
}
|
|
|
|
null_value=0;
|
2003-08-21 18:30:43 +02:00
|
|
|
return (longlong) crc32(0L, (uchar*)res->ptr(), res->length());
|
2003-08-21 16:15:06 +02:00
|
|
|
}
|
|
|
|
|
2003-04-10 02:50:30 +02:00
|
|
|
#ifdef HAVE_COMPRESS
|
2003-06-19 12:18:04 +02:00
|
|
|
#include "zlib.h"
|
2003-04-10 02:50:30 +02:00
|
|
|
|
|
|
|
String *Item_func_compress::val_str(String *str)
|
|
|
|
{
|
2004-10-14 17:03:46 +02:00
|
|
|
int err= Z_OK, code;
|
|
|
|
ulong new_size;
|
|
|
|
String *res;
|
|
|
|
Byte *body;
|
|
|
|
char *tmp, *last_char;
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2004-10-14 17:03:46 +02:00
|
|
|
|
|
|
|
if (!(res= args[0]->val_str(str)))
|
2003-09-19 09:25:03 +02:00
|
|
|
{
|
|
|
|
null_value= 1;
|
|
|
|
return 0;
|
|
|
|
}
|
2006-10-13 16:05:54 +02:00
|
|
|
null_value= 0;
|
2003-04-23 00:41:47 +02:00
|
|
|
if (res->is_empty()) return res;
|
|
|
|
|
2003-04-10 02:50:30 +02:00
|
|
|
/*
|
2004-10-14 17:03:46 +02:00
|
|
|
Citation from zlib.h (comment for compress function):
|
2003-04-10 02:50:30 +02:00
|
|
|
|
|
|
|
Compresses the source buffer into the destination buffer. sourceLen is
|
2004-10-14 17:03:46 +02:00
|
|
|
the byte length of the source buffer. Upon entry, destLen is the total
|
|
|
|
size of the destination buffer, which must be at least 0.1% larger than
|
|
|
|
sourceLen plus 12 bytes.
|
|
|
|
We assume here that the buffer can't grow more than .25 %.
|
2003-04-10 02:50:30 +02:00
|
|
|
*/
|
2004-10-14 17:03:46 +02:00
|
|
|
new_size= res->length() + res->length() / 5 + 12;
|
2003-04-10 02:50:30 +02:00
|
|
|
|
2004-10-14 17:03:46 +02:00
|
|
|
// Check new_size overflow: new_size <= res->length()
|
|
|
|
if (((uint32) (new_size+5) <= res->length()) ||
|
2004-09-13 15:43:59 +02:00
|
|
|
buffer.realloc((uint32) new_size + 4 + 1))
|
|
|
|
{
|
|
|
|
null_value= 1;
|
|
|
|
return 0;
|
|
|
|
}
|
2003-11-04 22:04:07 +01:00
|
|
|
|
2004-10-14 17:03:46 +02:00
|
|
|
body= ((Byte*)buffer.ptr()) + 4;
|
2003-08-21 16:15:06 +02:00
|
|
|
|
2003-11-04 22:04:07 +01:00
|
|
|
// As far as we have checked res->is_empty() we can use ptr()
|
2003-04-23 00:41:47 +02:00
|
|
|
if ((err= compress(body, &new_size,
|
2003-11-04 22:04:07 +01:00
|
|
|
(const Bytef*)res->ptr(), res->length())) != Z_OK)
|
2003-04-10 02:50:30 +02:00
|
|
|
{
|
|
|
|
code= err==Z_MEM_ERROR ? ER_ZLIB_Z_MEM_ERROR : ER_ZLIB_Z_BUF_ERROR;
|
2009-09-10 11:18:29 +02:00
|
|
|
push_warning(current_thd,MYSQL_ERROR::WARN_LEVEL_WARN,code,ER(code));
|
2003-04-10 02:50:30 +02:00
|
|
|
null_value= 1;
|
|
|
|
return 0;
|
|
|
|
}
|
2003-04-30 13:10:53 +02:00
|
|
|
|
2004-10-14 17:03:46 +02:00
|
|
|
tmp= (char*)buffer.ptr(); // int4store is a macro; avoid side effects
|
2003-04-30 13:10:53 +02:00
|
|
|
int4store(tmp, res->length() & 0x3FFFFFFF);
|
2003-04-24 17:37:55 +02:00
|
|
|
|
2004-10-14 17:03:46 +02:00
|
|
|
/* This is to ensure that things works for CHAR fields, which trim ' ': */
|
|
|
|
last_char= ((char*)body)+new_size-1;
|
2003-04-10 02:50:30 +02:00
|
|
|
if (*last_char == ' ')
|
|
|
|
{
|
|
|
|
*++last_char= '.';
|
|
|
|
new_size++;
|
|
|
|
}
|
2003-04-24 17:37:55 +02:00
|
|
|
|
2003-04-23 00:41:47 +02:00
|
|
|
buffer.length((uint32)new_size + 4);
|
2003-04-10 02:50:30 +02:00
|
|
|
return &buffer;
|
|
|
|
}
|
|
|
|
|
2003-11-04 13:09:03 +01:00
|
|
|
|
2003-04-10 02:50:30 +02:00
|
|
|
String *Item_func_uncompress::val_str(String *str)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2003-04-10 02:50:30 +02:00
|
|
|
String *res= args[0]->val_str(str);
|
2003-11-04 13:09:03 +01:00
|
|
|
ulong new_size;
|
|
|
|
int err;
|
2003-04-10 02:50:30 +02:00
|
|
|
uint code;
|
2003-08-21 16:15:06 +02:00
|
|
|
|
2003-11-04 13:09:03 +01:00
|
|
|
if (!res)
|
|
|
|
goto err;
|
2006-04-13 13:19:21 +02:00
|
|
|
null_value= 0;
|
2003-11-04 13:09:03 +01:00
|
|
|
if (res->is_empty())
|
|
|
|
return res;
|
|
|
|
|
2006-07-18 12:41:41 +02:00
|
|
|
/* If length is less than 4 bytes, data is corrupt */
|
|
|
|
if (res->length() <= 4)
|
|
|
|
{
|
2009-09-10 11:18:29 +02:00
|
|
|
push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_WARN,
|
2006-07-18 12:41:41 +02:00
|
|
|
ER_ZLIB_Z_DATA_ERROR,
|
|
|
|
ER(ER_ZLIB_Z_DATA_ERROR));
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Size of uncompressed data is stored as first 4 bytes of field */
|
2003-11-04 13:09:03 +01:00
|
|
|
new_size= uint4korr(res->ptr()) & 0x3FFFFFFF;
|
2003-10-12 15:16:45 +02:00
|
|
|
if (new_size > current_thd->variables.max_allowed_packet)
|
2003-04-10 02:50:30 +02:00
|
|
|
{
|
2009-09-10 11:18:29 +02:00
|
|
|
push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_WARN,
|
2003-04-10 02:50:30 +02:00
|
|
|
ER_TOO_BIG_FOR_UNCOMPRESS,
|
2003-10-12 15:16:45 +02:00
|
|
|
ER(ER_TOO_BIG_FOR_UNCOMPRESS),
|
|
|
|
current_thd->variables.max_allowed_packet);
|
2003-11-04 13:09:03 +01:00
|
|
|
goto err;
|
2003-04-10 02:50:30 +02:00
|
|
|
}
|
2003-11-04 13:09:03 +01:00
|
|
|
if (buffer.realloc((uint32)new_size))
|
|
|
|
goto err;
|
2003-08-21 16:15:06 +02:00
|
|
|
|
2003-11-04 13:09:03 +01:00
|
|
|
if ((err= uncompress((Byte*)buffer.ptr(), &new_size,
|
|
|
|
((const Bytef*)res->ptr())+4,res->length())) == Z_OK)
|
2003-04-10 02:50:30 +02:00
|
|
|
{
|
2003-11-04 13:09:03 +01:00
|
|
|
buffer.length((uint32) new_size);
|
2003-04-10 02:50:30 +02:00
|
|
|
return &buffer;
|
|
|
|
}
|
2003-08-21 16:15:06 +02:00
|
|
|
|
2003-11-04 13:09:03 +01:00
|
|
|
code= ((err == Z_BUF_ERROR) ? ER_ZLIB_Z_BUF_ERROR :
|
|
|
|
((err == Z_MEM_ERROR) ? ER_ZLIB_Z_MEM_ERROR : ER_ZLIB_Z_DATA_ERROR));
|
2009-09-10 11:18:29 +02:00
|
|
|
push_warning(current_thd,MYSQL_ERROR::WARN_LEVEL_WARN,code,ER(code));
|
2003-11-04 13:09:03 +01:00
|
|
|
|
|
|
|
err:
|
2003-04-10 02:50:30 +02:00
|
|
|
null_value= 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|
2004-02-27 20:30:08 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
UUID, as in
|
|
|
|
DCE 1.1: Remote Procedure Call,
|
2004-02-27 22:38:04 +01:00
|
|
|
Open Group Technical Standard Document Number C706, October 1997,
|
2004-02-27 20:30:08 +01:00
|
|
|
(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";
|
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
/**
|
|
|
|
number of 100-nanosecond intervals between
|
|
|
|
1582-10-15 00:00:00.00 and 1970-01-01 00:00:00.00.
|
|
|
|
*/
|
2008-07-10 03:58:30 +02:00
|
|
|
#define UUID_TIME_OFFSET ((ulonglong) 141427 * 24 * 60 * 60 * \
|
|
|
|
1000 * 1000 * 10)
|
2004-02-27 20:30:08 +01:00
|
|
|
|
|
|
|
#define UUID_VERSION 0x1000
|
|
|
|
#define UUID_VARIANT 0x8000
|
|
|
|
|
|
|
|
static void tohex(char *to, uint from, uint len)
|
|
|
|
{
|
|
|
|
to+= len;
|
|
|
|
while (len--)
|
|
|
|
{
|
2004-05-27 15:54:40 +02:00
|
|
|
*--to= _dig_vec_lower[from & 15];
|
2004-02-27 20:30:08 +01:00
|
|
|
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)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2004-02-27 20:30:08 +01:00
|
|
|
char *s;
|
2004-09-13 15:48:01 +02:00
|
|
|
THD *thd= current_thd;
|
|
|
|
|
2010-01-07 06:42:07 +01:00
|
|
|
mysql_mutex_lock(&LOCK_uuid_generator);
|
2004-02-27 20:30:08 +01:00
|
|
|
if (! uuid_time) /* first UUID() call. initializing data */
|
|
|
|
{
|
|
|
|
ulong tmp=sql_rnd_with_mutex();
|
|
|
|
uchar mac[6];
|
2004-03-15 23:04:03 +01:00
|
|
|
int i;
|
2004-02-27 20:30:08 +01:00
|
|
|
if (my_gethwaddr(mac))
|
|
|
|
{
|
2006-12-14 23:51:37 +01:00
|
|
|
/* purecov: begin inspected */
|
2004-02-27 20:30:08 +01:00
|
|
|
/*
|
|
|
|
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
|
|
|
|
*/
|
2006-12-14 23:51:37 +01:00
|
|
|
randominit(&uuid_rand, tmp + (ulong) thd, tmp + (ulong)global_query_id);
|
2004-03-15 23:04:03 +01:00
|
|
|
for (i=0; i < (int)sizeof(mac); i++)
|
2004-02-27 20:30:08 +01:00
|
|
|
mac[i]=(uchar)(my_rnd(&uuid_rand)*255);
|
2006-12-14 23:51:37 +01:00
|
|
|
/* purecov: end */
|
2004-02-27 20:30:08 +01:00
|
|
|
}
|
|
|
|
s=clock_seq_and_node_str+sizeof(clock_seq_and_node_str)-1;
|
|
|
|
for (i=sizeof(mac)-1 ; i>=0 ; i--)
|
|
|
|
{
|
2004-05-27 15:54:40 +02:00
|
|
|
*--s=_dig_vec_lower[mac[i] & 15];
|
|
|
|
*--s=_dig_vec_lower[mac[i] >> 4];
|
2004-02-27 20:30:08 +01:00
|
|
|
}
|
2006-12-14 23:51:37 +01:00
|
|
|
randominit(&uuid_rand, tmp + (ulong) server_start_time,
|
2007-06-09 15:18:34 +02:00
|
|
|
tmp + (ulong) thd->status_var.bytes_sent);
|
2004-02-27 20:30:08 +01:00
|
|
|
set_clock_seq_str();
|
|
|
|
}
|
|
|
|
|
2008-07-10 03:58:30 +02:00
|
|
|
ulonglong tv= my_getsystime() + UUID_TIME_OFFSET + nanoseq;
|
|
|
|
|
|
|
|
if (likely(tv > uuid_time))
|
2005-05-18 09:41:35 +02:00
|
|
|
{
|
2008-07-10 03:58:30 +02:00
|
|
|
/*
|
|
|
|
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)
|
|
|
|
*/
|
2008-07-11 01:51:58 +02:00
|
|
|
ulong delta= min(nanoseq, (ulong) (tv - uuid_time -1));
|
2008-07-10 03:58:30 +02:00
|
|
|
tv-= delta;
|
|
|
|
nanoseq-= delta;
|
|
|
|
}
|
2004-02-27 20:30:08 +01:00
|
|
|
}
|
|
|
|
else
|
2004-03-14 11:50:15 +01:00
|
|
|
{
|
2008-07-10 03:58:30 +02:00
|
|
|
if (unlikely(tv == uuid_time))
|
2004-03-14 11:50:15 +01:00
|
|
|
{
|
2008-07-10 03:58:30 +02:00
|
|
|
/*
|
|
|
|
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"));
|
2004-03-14 11:50:15 +01:00
|
|
|
}
|
|
|
|
}
|
2008-07-10 03:58:30 +02:00
|
|
|
|
2004-02-27 20:30:08 +01:00
|
|
|
uuid_time=tv;
|
2010-01-07 06:42:07 +01:00
|
|
|
mysql_mutex_unlock(&LOCK_uuid_generator);
|
2004-02-27 20:30:08 +01:00
|
|
|
|
2004-05-05 07:59:17 +02:00
|
|
|
uint32 time_low= (uint32) (tv & 0xFFFFFFFF);
|
|
|
|
uint16 time_mid= (uint16) ((tv >> 32) & 0xFFFF);
|
|
|
|
uint16 time_hi_and_version= (uint16) ((tv >> 48) | UUID_VERSION);
|
2004-02-27 20:30:08 +01:00
|
|
|
|
|
|
|
str->realloc(UUID_LENGTH+1);
|
|
|
|
str->length(UUID_LENGTH);
|
2004-02-27 23:59:09 +01:00
|
|
|
str->set_charset(system_charset_info);
|
2004-02-27 20:30:08 +01:00
|
|
|
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);
|
|
|
|
return str;
|
|
|
|
}
|