Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
cefa1cf9
Commit
cefa1cf9
authored
Nov 01, 2006
by
bar@bar.intranet.mysql.r18.ru
Browse files
Options
Browse Files
Download
Plain Diff
Merge mysql.com:/usr/home/bar/mysql-5.0.b18908
into mysql.com:/usr/home/bar/mysql-5.1-rpl
parents
c9b963cf
0e3a1eec
Changes
13
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
400 additions
and
145 deletions
+400
-145
BitKeeper/etc/collapsed
BitKeeper/etc/collapsed
+1
-0
mysql-test/include/strict_autoinc.inc
mysql-test/include/strict_autoinc.inc
+4
-0
mysql-test/r/ctype_recoding.result
mysql-test/r/ctype_recoding.result
+2
-2
mysql-test/r/ctype_utf8.result
mysql-test/r/ctype_utf8.result
+3
-3
mysql-test/r/fulltext.result
mysql-test/r/fulltext.result
+4
-4
mysql-test/r/strict_autoinc_1myisam.result
mysql-test/r/strict_autoinc_1myisam.result
+1
-0
mysql-test/r/strict_autoinc_2innodb.result
mysql-test/r/strict_autoinc_2innodb.result
+1
-0
mysql-test/r/strict_autoinc_3heap.result
mysql-test/r/strict_autoinc_3heap.result
+1
-0
mysql-test/r/strict_autoinc_4bdb.result
mysql-test/r/strict_autoinc_4bdb.result
+1
-0
mysql-test/r/strict_autoinc_5ndb.result
mysql-test/r/strict_autoinc_5ndb.result
+1
-0
sql/field.cc
sql/field.cc
+217
-136
sql/sql_string.cc
sql/sql_string.cc
+156
-0
sql/sql_string.h
sql/sql_string.h
+8
-0
No files found.
BitKeeper/etc/collapsed
View file @
cefa1cf9
...
@@ -7,3 +7,4 @@
...
@@ -7,3 +7,4 @@
4513d8e4Af4dQWuk13sArwofRgFDQw
4513d8e4Af4dQWuk13sArwofRgFDQw
4519a6c5BVUxEHTf5iJnjZkixMBs8g
4519a6c5BVUxEHTf5iJnjZkixMBs8g
451ab499rgdjXyOnUDqHu-wBDoS-OQ
451ab499rgdjXyOnUDqHu-wBDoS-OQ
452c6c6dAjuNghfc1ObZ_UQ5SCl85g
mysql-test/include/strict_autoinc.inc
View file @
cefa1cf9
...
@@ -2,6 +2,10 @@
...
@@ -2,6 +2,10 @@
# Test for strict-mode autoincrement
# Test for strict-mode autoincrement
#
#
--
disable_warnings
drop
table
if
exists
t1
;
--
enable_warnings
set
@
org_mode
=@@
sql_mode
;
set
@
org_mode
=@@
sql_mode
;
eval
create
table
t1
eval
create
table
t1
(
(
...
...
mysql-test/r/ctype_recoding.result
View file @
cefa1cf9
...
@@ -171,8 +171,8 @@ create table t1 (a char(10) character set koi8r, b text character set koi8r);
...
@@ -171,8 +171,8 @@ create table t1 (a char(10) character set koi8r, b text character set koi8r);
insert into t1 values ('test','test');
insert into t1 values ('test','test');
insert into t1 values ('','');
insert into t1 values ('','');
Warnings:
Warnings:
Warning 1
265 Data truncated
for column 'a' at row 1
Warning 1
366 Incorrect string value: '\xCA\xC3\xD5\xCB'
for column 'a' at row 1
Warning 1
265 Data truncated
for column 'b' at row 1
Warning 1
366 Incorrect string value: '\xCA\xC3\xD5\xCB'
for column 'b' at row 1
drop table t1;
drop table t1;
set names koi8r;
set names koi8r;
create table t1 (a char(10) character set cp1251);
create table t1 (a char(10) character set cp1251);
...
...
mysql-test/r/ctype_utf8.result
View file @
cefa1cf9
...
@@ -197,7 +197,7 @@ drop table t1;
...
@@ -197,7 +197,7 @@ drop table t1;
create table t1 (s1 char(10) character set utf8);
create table t1 (s1 char(10) character set utf8);
insert into t1 values (0x41FF);
insert into t1 values (0x41FF);
Warnings:
Warnings:
Warning 1
265 Data truncated
for column 's1' at row 1
Warning 1
366 Incorrect string value: '\xFF'
for column 's1' at row 1
select hex(s1) from t1;
select hex(s1) from t1;
hex(s1)
hex(s1)
41
41
...
@@ -205,7 +205,7 @@ drop table t1;
...
@@ -205,7 +205,7 @@ drop table t1;
create table t1 (s1 varchar(10) character set utf8);
create table t1 (s1 varchar(10) character set utf8);
insert into t1 values (0x41FF);
insert into t1 values (0x41FF);
Warnings:
Warnings:
Warning 1
265 Data truncated
for column 's1' at row 1
Warning 1
366 Incorrect string value: '\xFF'
for column 's1' at row 1
select hex(s1) from t1;
select hex(s1) from t1;
hex(s1)
hex(s1)
41
41
...
@@ -213,7 +213,7 @@ drop table t1;
...
@@ -213,7 +213,7 @@ drop table t1;
create table t1 (s1 text character set utf8);
create table t1 (s1 text character set utf8);
insert into t1 values (0x41FF);
insert into t1 values (0x41FF);
Warnings:
Warnings:
Warning 1
265 Data truncated
for column 's1' at row 1
Warning 1
366 Incorrect string value: '\xFF'
for column 's1' at row 1
select hex(s1) from t1;
select hex(s1) from t1;
hex(s1)
hex(s1)
41
41
...
...
mysql-test/r/fulltext.result
View file @
cefa1cf9
...
@@ -381,10 +381,10 @@ t collation(t) FORMAT(MATCH t AGAINST ('Osnabruck'),6)
...
@@ -381,10 +381,10 @@ t collation(t) FORMAT(MATCH t AGAINST ('Osnabruck'),6)
aus Osnabrck utf8_general_ci 1.591140
aus Osnabrck utf8_general_ci 1.591140
alter table t1 modify t varchar(200) collate latin1_german2_ci not null;
alter table t1 modify t varchar(200) collate latin1_german2_ci not null;
Warnings:
Warnings:
Warning 1
265 Data truncated
for column 't' at row 3
Warning 1
366 Incorrect string value: '\xD0\xAD\xD1\x82\xD0\xBE...'
for column 't' at row 3
Warning 1
265 Data truncated
for column 't' at row 4
Warning 1
366 Incorrect string value: '\xD0\x9E\xD1\x82\xD0\xBB...'
for column 't' at row 4
Warning 1
265 Data truncated
for column 't' at row 5
Warning 1
366 Incorrect string value: '\xD0\x9D\xD0\xB5 \xD0...'
for column 't' at row 5
Warning 1
265 Data truncated
for column 't' at row 6
Warning 1
366 Incorrect string value: '\xD0\xB8 \xD0\xB1\xD1...'
for column 't' at row 6
SELECT t, collation(t) FROM t1 WHERE MATCH t AGAINST ('Osnabrck');
SELECT t, collation(t) FROM t1 WHERE MATCH t AGAINST ('Osnabrck');
t collation(t)
t collation(t)
aus Osnabrck latin1_german2_ci
aus Osnabrck latin1_german2_ci
...
...
mysql-test/r/strict_autoinc_1myisam.result
View file @
cefa1cf9
drop table if exists t1;
set @org_mode=@@sql_mode;
set @org_mode=@@sql_mode;
create table t1
create table t1
(
(
...
...
mysql-test/r/strict_autoinc_2innodb.result
View file @
cefa1cf9
drop table if exists t1;
set @org_mode=@@sql_mode;
set @org_mode=@@sql_mode;
create table t1
create table t1
(
(
...
...
mysql-test/r/strict_autoinc_3heap.result
View file @
cefa1cf9
drop table if exists t1;
set @org_mode=@@sql_mode;
set @org_mode=@@sql_mode;
create table t1
create table t1
(
(
...
...
mysql-test/r/strict_autoinc_4bdb.result
View file @
cefa1cf9
drop table if exists t1;
set @org_mode=@@sql_mode;
set @org_mode=@@sql_mode;
create table t1
create table t1
(
(
...
...
mysql-test/r/strict_autoinc_5ndb.result
View file @
cefa1cf9
drop table if exists t1;
set @org_mode=@@sql_mode;
set @org_mode=@@sql_mode;
create table t1
create table t1
(
(
...
...
sql/field.cc
View file @
cefa1cf9
...
@@ -5922,38 +5922,149 @@ void Field_datetime::sql_type(String &res) const
...
@@ -5922,38 +5922,149 @@ void Field_datetime::sql_type(String &res) const
** A string may be varchar or binary
** A string may be varchar or binary
****************************************************************************/
****************************************************************************/
/*
Report "not well formed" or "cannot convert" error
after storing a character string info a field.
SYNOPSIS
check_string_copy_error()
field - Field
well_formed_error_pos - where not well formed data was first met
cannot_convert_error_pos - where a not-convertable character was first met
end - end of the string
NOTES
As of version 5.0 both cases return the same error:
"Invalid string value: 'xxx' for column 't' at row 1"
Future versions will possibly introduce a new error message:
"Cannot convert character string: 'xxx' for column 't' at row 1"
RETURN
FALSE - If errors didn't happen
TRUE - If an error happened
*/
static
bool
check_string_copy_error
(
Field_str
*
field
,
const
char
*
well_formed_error_pos
,
const
char
*
cannot_convert_error_pos
,
const
char
*
end
)
{
const
char
*
pos
,
*
end_orig
;
char
tmp
[
64
],
*
t
;
if
(
!
(
pos
=
well_formed_error_pos
)
&&
!
(
pos
=
cannot_convert_error_pos
))
return
FALSE
;
end_orig
=
end
;
set_if_smaller
(
end
,
pos
+
6
);
for
(
t
=
tmp
;
pos
<
end
;
pos
++
)
{
if
(((
unsigned
char
)
*
pos
)
>=
0x20
&&
((
unsigned
char
)
*
pos
)
<=
0x7F
)
{
*
t
++=
*
pos
;
}
else
{
*
t
++=
'\\'
;
*
t
++=
'x'
;
*
t
++=
_dig_vec_upper
[((
unsigned
char
)
*
pos
)
>>
4
];
*
t
++=
_dig_vec_upper
[((
unsigned
char
)
*
pos
)
&
15
];
}
}
if
(
end_orig
>
end
)
{
*
t
++=
'.'
;
*
t
++=
'.'
;
*
t
++=
'.'
;
}
*
t
=
'\0'
;
push_warning_printf
(
field
->
table
->
in_use
,
field
->
table
->
in_use
->
abort_on_warning
?
MYSQL_ERROR
::
WARN_LEVEL_ERROR
:
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD
,
ER
(
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD
),
"string"
,
tmp
,
field
->
field_name
,
(
ulong
)
field
->
table
->
in_use
->
row_count
);
return
TRUE
;
}
/*
Send a truncation warning or a truncation error
after storing a too long character string info a field.
SYNOPSIS
report_data_too_long()
field - Field
RETURN
N/A
*/
inline
void
report_data_too_long
(
Field_str
*
field
)
{
if
(
field
->
table
->
in_use
->
abort_on_warning
)
field
->
set_warning
(
MYSQL_ERROR
::
WARN_LEVEL_ERROR
,
ER_DATA_TOO_LONG
,
1
);
else
field
->
set_warning
(
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
WARN_DATA_TRUNCATED
,
1
);
}
/*
Test if the given string contains important data:
not spaces for character string,
or any data for binary string.
SYNOPSIS
test_if_important_data()
cs Character set
str String to test
strend String end
RETURN
FALSE - If string does not have important data
TRUE - If string has some important data
*/
static
bool
test_if_important_data
(
CHARSET_INFO
*
cs
,
const
char
*
str
,
const
char
*
strend
)
{
if
(
cs
!=
&
my_charset_bin
)
str
+=
cs
->
cset
->
scan
(
cs
,
str
,
strend
,
MY_SEQ_SPACES
);
return
(
str
<
strend
);
}
/* Copy a string and fill with space */
/* Copy a string and fill with space */
int
Field_string
::
store
(
const
char
*
from
,
uint
length
,
CHARSET_INFO
*
cs
)
int
Field_string
::
store
(
const
char
*
from
,
uint
length
,
CHARSET_INFO
*
cs
)
{
{
ASSERT_COLUMN_MARKED_FOR_WRITE
;
ASSERT_COLUMN_MARKED_FOR_WRITE
;
int
error
=
0
,
well_formed_error
;
uint32
not_used
;
char
buff
[
STRING_BUFFER_USUAL_SIZE
];
String
tmpstr
(
buff
,
sizeof
(
buff
),
&
my_charset_bin
);
uint
copy_length
;
uint
copy_length
;
const
char
*
well_formed_error_pos
;
const
char
*
cannot_convert_error_pos
;
const
char
*
from_end_pos
;
/* See the comment for Field_long::store(long long) */
/* See the comment for Field_long::store(long long) */
DBUG_ASSERT
(
table
->
in_use
==
current_thd
);
DBUG_ASSERT
(
table
->
in_use
==
current_thd
);
/* Convert character set if necessary */
copy_length
=
well_formed_copy_nchars
(
field_charset
,
if
(
String
::
needs_conversion
(
length
,
cs
,
field_charset
,
&
not_used
))
ptr
,
field_length
,
{
cs
,
from
,
length
,
uint
conv_errors
;
field_length
/
field_charset
->
mbmaxlen
,
tmpstr
.
copy
(
from
,
length
,
cs
,
field_charset
,
&
conv_errors
);
&
well_formed_error_pos
,
from
=
tmpstr
.
ptr
();
&
cannot_convert_error_pos
,
length
=
tmpstr
.
length
();
&
from_end_pos
);
if
(
conv_errors
)
error
=
2
;
}
/* Make sure we don't break a multibyte sequence or copy malformed data. */
copy_length
=
field_charset
->
cset
->
well_formed_len
(
field_charset
,
from
,
from
+
length
,
field_length
/
field_charset
->
mbmaxlen
,
&
well_formed_error
);
memmove
(
ptr
,
from
,
copy_length
);
/* Append spaces if the string was shorter than the field. */
/* Append spaces if the string was shorter than the field. */
if
(
copy_length
<
field_length
)
if
(
copy_length
<
field_length
)
...
@@ -5961,32 +6072,23 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
...
@@ -5961,32 +6072,23 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
field_length
-
copy_length
,
field_length
-
copy_length
,
field_charset
->
pad_char
);
field_charset
->
pad_char
);
if
(
check_string_copy_error
(
this
,
well_formed_error_pos
,
cannot_convert_error_pos
,
from
+
length
))
return
2
;
/*
/*
Check if we lost any important data (anything in a binary string,
Check if we lost any important data (anything in a binary string,
or any non-space in others).
or any non-space in others).
*/
*/
if
((
copy_length
<
length
)
&&
table
->
in_use
->
count_cuted_fields
)
if
((
from_end_pos
<
from
+
length
)
&&
table
->
in_use
->
count_cuted_fields
)
{
{
if
(
binary
())
if
(
test_if_important_data
(
field_charset
,
from_end_pos
,
from
+
length
))
error
=
2
;
else
{
{
const
char
*
end
=
from
+
length
;
report_data_too_long
(
this
);
from
+=
copy_length
;
return
2
;
from
+=
field_charset
->
cset
->
scan
(
field_charset
,
from
,
end
,
MY_SEQ_SPACES
);
if
(
from
!=
end
)
error
=
2
;
}
}
}
if
(
error
)
{
if
(
table
->
in_use
->
abort_on_warning
)
set_warning
(
MYSQL_ERROR
::
WARN_LEVEL_ERROR
,
ER_DATA_TOO_LONG
,
1
);
else
set_warning
(
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
WARN_DATA_TRUNCATED
,
1
);
}
}
return
error
;
return
0
;
}
}
...
@@ -6344,58 +6446,35 @@ Field *Field_string::new_field(MEM_ROOT *root, struct st_table *new_table,
...
@@ -6344,58 +6446,35 @@ Field *Field_string::new_field(MEM_ROOT *root, struct st_table *new_table,
int
Field_varstring
::
store
(
const
char
*
from
,
uint
length
,
CHARSET_INFO
*
cs
)
int
Field_varstring
::
store
(
const
char
*
from
,
uint
length
,
CHARSET_INFO
*
cs
)
{
{
ASSERT_COLUMN_MARKED_FOR_WRITE
;
ASSERT_COLUMN_MARKED_FOR_WRITE
;
uint32
not_used
,
copy_length
;
uint
copy_length
;
char
buff
[
STRING_BUFFER_USUAL_SIZE
];
const
char
*
well_formed_error_pos
;
String
tmpstr
(
buff
,
sizeof
(
buff
),
&
my_charset_bin
);
const
char
*
cannot_convert_error_pos
;
int
error_code
=
0
,
well_formed_error
;
const
char
*
from_end_pos
;
enum
MYSQL_ERROR
::
enum_warning_level
level
=
MYSQL_ERROR
::
WARN_LEVEL_WARN
;
copy_length
=
well_formed_copy_nchars
(
field_charset
,
ptr
+
length_bytes
,
field_length
,
cs
,
from
,
length
,
field_length
/
field_charset
->
mbmaxlen
,
&
well_formed_error_pos
,
&
cannot_convert_error_pos
,
&
from_end_pos
);
/* Convert character set if necessary */
if
(
String
::
needs_conversion
(
length
,
cs
,
field_charset
,
&
not_used
))
{
uint
conv_errors
;
tmpstr
.
copy
(
from
,
length
,
cs
,
field_charset
,
&
conv_errors
);
from
=
tmpstr
.
ptr
();
length
=
tmpstr
.
length
();
if
(
conv_errors
)
error_code
=
WARN_DATA_TRUNCATED
;
}
/*
Make sure we don't break a multibyte sequence
as well as don't copy a malformed data.
*/
copy_length
=
field_charset
->
cset
->
well_formed_len
(
field_charset
,
from
,
from
+
length
,
field_length
/
field_charset
->
mbmaxlen
,
&
well_formed_error
);
memmove
(
ptr
+
length_bytes
,
from
,
copy_length
);
if
(
length_bytes
==
1
)
if
(
length_bytes
==
1
)
*
ptr
=
(
uchar
)
copy_length
;
*
ptr
=
(
uchar
)
copy_length
;
else
else
int2store
(
ptr
,
copy_length
);
int2store
(
ptr
,
copy_length
);
if
(
check_string_copy_error
(
this
,
well_formed_error_pos
,
cannot_convert_error_pos
,
from
+
length
))
return
2
;
// Check if we lost something other than just trailing spaces
// Check if we lost something other than just trailing spaces
if
((
copy_length
<
length
)
&&
table
->
in_use
->
count_cuted_fields
&&
if
((
from_end_pos
<
from
+
length
)
&&
table
->
in_use
->
count_cuted_fields
)
!
error_code
)
{
if
(
!
binary
())
{
const
char
*
end
=
from
+
length
;
from
+=
copy_length
;
from
+=
field_charset
->
cset
->
scan
(
field_charset
,
from
,
end
,
MY_SEQ_SPACES
);
/* If we lost only spaces then produce a NOTE, not a WARNING */
if
(
from
==
end
)
level
=
MYSQL_ERROR
::
WARN_LEVEL_NOTE
;
}
error_code
=
WARN_DATA_TRUNCATED
;
}
if
(
error_code
)
{
{
if
(
level
==
MYSQL_ERROR
::
WARN_LEVEL_WARN
&&
if
(
test_if_important_data
(
field_charset
,
from_end_pos
,
from
+
length
))
table
->
in_use
->
abort_on_warning
)
report_data_too_long
(
this
);
error_code
=
ER_DATA_TOO_LONG
;
else
/* If we lost only spaces then produce a NOTE, not a WARNING */
set_warning
(
level
,
error_code
,
1
);
set_warning
(
MYSQL_ERROR
::
WARN_LEVEL_NOTE
,
WARN_DATA_TRUNCATED
,
1
);
return
2
;
return
2
;
}
}
return
0
;
return
0
;
...
@@ -7013,68 +7092,70 @@ void Field_blob::put_length(char *pos, uint32 length)
...
@@ -7013,68 +7092,70 @@ void Field_blob::put_length(char *pos, uint32 length)
int
Field_blob
::
store
(
const
char
*
from
,
uint
length
,
CHARSET_INFO
*
cs
)
int
Field_blob
::
store
(
const
char
*
from
,
uint
length
,
CHARSET_INFO
*
cs
)
{
{
ASSERT_COLUMN_MARKED_FOR_WRITE
;
ASSERT_COLUMN_MARKED_FOR_WRITE
;
int
error
=
0
,
well_formed_error
;
uint
copy_length
,
new_length
;
const
char
*
well_formed_error_pos
;
const
char
*
cannot_convert_error_pos
;
const
char
*
from_end_pos
,
*
tmp
;
char
buff
[
STRING_BUFFER_USUAL_SIZE
];
String
tmpstr
(
buff
,
sizeof
(
buff
),
&
my_charset_bin
);
if
(
!
length
)
if
(
!
length
)
{
{
bzero
(
ptr
,
Field_blob
::
pack_length
());
bzero
(
ptr
,
Field_blob
::
pack_length
());
return
0
;
}
}
else
{
bool
was_conversion
;
char
buff
[
STRING_BUFFER_USUAL_SIZE
];
String
tmpstr
(
buff
,
sizeof
(
buff
),
&
my_charset_bin
);
uint
copy_length
;
uint32
not_used
;
/* Convert character set if necessary */
if
(
from
==
value
.
ptr
())
if
((
was_conversion
=
String
::
needs_conversion
(
length
,
cs
,
field_charset
,
&
not_used
)))
{
{
uint
conv_errors
;
uint32
dummy_offset
;
if
(
tmpstr
.
copy
(
from
,
length
,
cs
,
field_charset
,
&
conv_errors
))
if
(
!
String
::
needs_conversion
(
length
,
cs
,
field_charset
,
&
dummy_offset
))
{
{
/* Fatal OOM error */
Field_blob
::
store_length
(
length
);
bzero
(
ptr
,
Field_blob
::
pack_length
(
));
bmove
(
ptr
+
packlength
,(
char
*
)
&
from
,
sizeof
(
char
*
));
return
-
1
;
return
0
;
}
}
if
(
tmpstr
.
copy
(
from
,
length
,
cs
))
goto
oom_error
;
from
=
tmpstr
.
ptr
();
from
=
tmpstr
.
ptr
();
length
=
tmpstr
.
length
();
if
(
conv_errors
)
error
=
2
;
}
}
copy_length
=
max_data_length
();
new_length
=
min
(
max_data_length
(),
field_charset
->
mbmaxlen
*
length
);
if
(
value
.
alloc
(
new_length
))
goto
oom_error
;
/*
/*
copy_length is OK as last argument to well_formed_len as this is never
"length" is OK as "nchars" argument to well_formed_copy_nchars as this
used to limit the length of the data. The cut of long data is done with
is never used to limit the length of the data. The cut of long data
the 'min()' call below
.
is done with the new_length value
.
*/
*/
copy_length
=
field_charset
->
cset
->
well_formed_len
(
field_charset
,
copy_length
=
well_formed_copy_nchars
(
field_charset
,
from
,
from
+
(
char
*
)
value
.
ptr
(),
new_length
,
min
(
length
,
copy_length
),
cs
,
from
,
length
,
copy_length
,
length
,
&
well_formed_error
);
&
well_formed_error_pos
,
if
(
copy_length
<
length
)
&
cannot_convert_error_pos
,
error
=
2
;
&
from_end_pos
);
Field_blob
::
store_length
(
copy_length
);
Field_blob
::
store_length
(
copy_length
);
if
(
was_conversion
||
table
->
copy_blobs
||
copy_length
<=
MAX_FIELD_WIDTH
)
tmp
=
value
.
ptr
();
{
// Must make a copy
bmove
(
ptr
+
packlength
,(
char
*
)
&
tmp
,
sizeof
(
char
*
));
if
(
from
!=
value
.
ptr
())
// For valgrind
{
if
(
check_string_copy_error
(
this
,
well_formed_error_pos
,
value
.
copy
(
from
,
copy_length
,
charset
());
cannot_convert_error_pos
,
from
+
length
))
from
=
value
.
ptr
();
return
2
;
}
}
if
(
copy_length
<
length
)
bmove
(
ptr
+
packlength
,(
char
*
)
&
from
,
sizeof
(
char
*
));
}
if
(
error
)
{
{
if
(
table
->
in_use
->
abort_on_warning
)
report_data_too_long
(
this
);
set_warning
(
MYSQL_ERROR
::
WARN_LEVEL_ERROR
,
ER_DATA_TOO_LONG
,
1
);
return
2
;
else
set_warning
(
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
WARN_DATA_TRUNCATED
,
1
);
}
}
return
0
;
return
0
;
oom_error:
/* Fatal OOM error */
bzero
(
ptr
,
Field_blob
::
pack_length
());
return
-
1
;
}
}
...
...
sql/sql_string.cc
View file @
cefa1cf9
...
@@ -844,6 +844,162 @@ copy_and_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs,
...
@@ -844,6 +844,162 @@ copy_and_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs,
}
}
/*
copy a string,
with optional character set conversion,
with optional left padding (for binary -> UCS2 conversion)
SYNOPSIS
well_formed_copy_nhars()
to Store result here
to_length Maxinum length of "to" string
to_cs Character set of "to" string
from Copy from here
from_length Length of from string
from_cs From character set
nchars Copy not more that nchars characters
well_formed_error_pos Return position when "from" is not well formed
or NULL otherwise.
cannot_convert_error_pos Return position where a not convertable
character met, or NULL otherwise.
from_end_pos Return position where scanning of "from"
string stopped.
NOTES
RETURN
length of bytes copied to 'to'
*/
uint32
well_formed_copy_nchars
(
CHARSET_INFO
*
to_cs
,
char
*
to
,
uint
to_length
,
CHARSET_INFO
*
from_cs
,
const
char
*
from
,
uint
from_length
,
uint
nchars
,
const
char
**
well_formed_error_pos
,
const
char
**
cannot_convert_error_pos
,
const
char
**
from_end_pos
)
{
uint
res
;
if
((
to_cs
==
&
my_charset_bin
)
||
(
from_cs
==
&
my_charset_bin
)
||
(
to_cs
==
from_cs
)
||
my_charset_same
(
from_cs
,
to_cs
))
{
if
(
to_length
<
to_cs
->
mbminlen
||
!
nchars
)
{
*
from_end_pos
=
from
;
*
cannot_convert_error_pos
=
NULL
;
*
well_formed_error_pos
=
NULL
;
return
0
;
}
if
(
to_cs
==
&
my_charset_bin
)
{
res
=
min
(
min
(
nchars
,
to_length
),
from_length
);
memmove
(
to
,
from
,
res
);
*
from_end_pos
=
from
+
res
;
*
well_formed_error_pos
=
NULL
;
*
cannot_convert_error_pos
=
NULL
;
}
else
{
int
well_formed_error
;
uint
from_offset
;
if
((
from_offset
=
(
from_length
%
to_cs
->
mbminlen
))
&&
(
from_cs
==
&
my_charset_bin
))
{
/*
Copying from BINARY to UCS2 needs to prepend zeros sometimes:
INSERT INTO t1 (ucs2_column) VALUES (0x01);
0x01 -> 0x0001
*/
uint
pad_length
=
to_cs
->
mbminlen
-
from_offset
;
bzero
(
to
,
pad_length
);
memmove
(
to
+
pad_length
,
from
,
from_offset
);
nchars
--
;
from
+=
from_offset
;
from_length
-=
from_offset
;
to
+=
to_cs
->
mbminlen
;
to_length
-=
to_cs
->
mbminlen
;
}
set_if_smaller
(
from_length
,
to_length
);
res
=
to_cs
->
cset
->
well_formed_len
(
to_cs
,
from
,
from
+
from_length
,
nchars
,
&
well_formed_error
);
memmove
(
to
,
from
,
res
);
*
from_end_pos
=
from
+
res
;
*
well_formed_error_pos
=
well_formed_error
?
from
+
res
:
NULL
;
*
cannot_convert_error_pos
=
NULL
;
if
(
from_offset
)
res
+=
to_cs
->
mbminlen
;
}
}
else
{
int
cnvres
;
my_wc_t
wc
;
int
(
*
mb_wc
)(
struct
charset_info_st
*
,
my_wc_t
*
,
const
uchar
*
,
const
uchar
*
)
=
from_cs
->
cset
->
mb_wc
;
int
(
*
wc_mb
)(
struct
charset_info_st
*
,
my_wc_t
,
uchar
*
s
,
uchar
*
e
)
=
to_cs
->
cset
->
wc_mb
;
const
uchar
*
from_end
=
(
const
uchar
*
)
from
+
from_length
;
uchar
*
to_end
=
(
uchar
*
)
to
+
to_length
;
char
*
to_start
=
to
;
*
well_formed_error_pos
=
NULL
;
*
cannot_convert_error_pos
=
NULL
;
for
(
;
nchars
;
nchars
--
)
{
const
char
*
from_prev
=
from
;
if
((
cnvres
=
(
*
mb_wc
)(
from_cs
,
&
wc
,
(
uchar
*
)
from
,
from_end
))
>
0
)
from
+=
cnvres
;
else
if
(
cnvres
==
MY_CS_ILSEQ
)
{
if
(
!*
well_formed_error_pos
)
*
well_formed_error_pos
=
from
;
from
++
;
wc
=
'?'
;
}
else
if
(
cnvres
>
MY_CS_TOOSMALL
)
{
/*
A correct multibyte sequence detected
But it doesn't have Unicode mapping.
*/
if
(
!*
cannot_convert_error_pos
)
*
cannot_convert_error_pos
=
from
;
from
+=
(
-
cnvres
);
wc
=
'?'
;
}
else
break
;
// Not enough characters
outp:
if
((
cnvres
=
(
*
wc_mb
)(
to_cs
,
wc
,
(
uchar
*
)
to
,
to_end
))
>
0
)
to
+=
cnvres
;
else
if
(
cnvres
==
MY_CS_ILUNI
&&
wc
!=
'?'
)
{
if
(
!*
cannot_convert_error_pos
)
*
cannot_convert_error_pos
=
from_prev
;
wc
=
'?'
;
goto
outp
;
}
else
break
;
}
*
from_end_pos
=
from
;
res
=
to
-
to_start
;
}
return
(
uint32
)
res
;
}
void
String
::
print
(
String
*
str
)
void
String
::
print
(
String
*
str
)
{
{
char
*
st
=
(
char
*
)
Ptr
,
*
end
=
st
+
str_length
;
char
*
st
=
(
char
*
)
Ptr
,
*
end
=
st
+
str_length
;
...
...
sql/sql_string.h
View file @
cefa1cf9
...
@@ -30,6 +30,14 @@ String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
...
@@ -30,6 +30,14 @@ String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
uint32
copy_and_convert
(
char
*
to
,
uint32
to_length
,
CHARSET_INFO
*
to_cs
,
uint32
copy_and_convert
(
char
*
to
,
uint32
to_length
,
CHARSET_INFO
*
to_cs
,
const
char
*
from
,
uint32
from_length
,
const
char
*
from
,
uint32
from_length
,
CHARSET_INFO
*
from_cs
,
uint
*
errors
);
CHARSET_INFO
*
from_cs
,
uint
*
errors
);
uint32
well_formed_copy_nchars
(
CHARSET_INFO
*
to_cs
,
char
*
to
,
uint
to_length
,
CHARSET_INFO
*
from_cs
,
const
char
*
from
,
uint
from_length
,
uint
nchars
,
const
char
**
well_formed_error_pos
,
const
char
**
cannot_convert_error_pos
,
const
char
**
from_end_pos
);
class
String
class
String
{
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment