Cleanup#2 for MDEV-34319: DECLARE TYPE .. TABLE OF .. INDEX BY - packed_col_length
Additional small cleanup (forgoten in the previous commit): - Item_splocal_assoc_array_element_field::fix_fields() Fixing the error message for: SELECT marks('a').name; -- marks is a TABLE OF VARCHAR(10) From: ERROR 42S22: Unknown column '1' in 'SELECT' To: ERROR 42S22: Unknown column 'name' in 'marks' Fixing wrong results of packed_col_length(): it returned a wrong result for: - CHAR(N) - BINARY(N) - MEDIUMBLOB - LONGBLOB Note, this method was not used. Now it's used by the assoc array data type. Details: - Cleanup: adding "const" qualifier to: * Field::pack() * Field::max_packed_col_length() * Field::packed_col_length() - Removing the "max_length" argument from Field::pack(). The caller passed either UINT_MAX or Field::max_data_length() to it. So it was never used to limit the destination size and only made the code more complicated and confusing. - Removing arguments from packed_col_length(). Now it calculates the value for the Field, using its "ptr", and assuming the entire value will be packed, without limiting the destination size. - Fixing Field_blob::packed_col_length(). It worked fine only for TINYBLOB and BLOB, and did not work for MEDIUMBLOB and LONGBLOB. - Overriding Field_char::packed_col_length(). Using the inherited method was wrong - it implemented variable length data behavior. - Overriding Field_string::max_data_length(). It was also incorrect. Implementing fixed size behavior. Moving the old implementation of Field_longstring::max_data_length() to Field_varstring::max_data_length(). - Fixing class StringPack: * Removing the "length" argument from StringPack::packed_col_length(). It now assumes that the packed length for the entire data buffer is needed, without limiting the destination size. * Fixing StringPack::packed_col_length() to implement fixed dat size behavior. It erroneously implemented VARCHAR style behavor (assumed that the length was stored in the leading 1 or 2 bytes). * Adding a helper method length_bytes(). Reusing it in packed_col_length() and max_packed_col_length(). * Moving a part the method pack() into a new method trimmed_length(). Reusing it in pack() and packed_col_length(). * Rewriting the code in trimmed_length() in a more straightforward way. It was hard to understand what it was doing. Adding a comment. - Adding a test sp-assoc-array-pack-debug.test covering packed_col_length() and pack() for various data types.
This commit is contained in:
parent
3acda17aa9
commit
f9b330e0b4
@ -0,0 +1 @@
|
|||||||
|
--max-allowed-packet=33554432
|
@ -0,0 +1,486 @@
|
|||||||
|
set sql_mode=oracle;
|
||||||
|
SET NAMES utf8mb4;
|
||||||
|
SELECT @@SESSION.max_allowed_packet;
|
||||||
|
@@SESSION.max_allowed_packet
|
||||||
|
33554432
|
||||||
|
#
|
||||||
|
# MDEV-34319 DECLARE TYPE .. TABLE OF .. INDEX BY in stored routines
|
||||||
|
#
|
||||||
|
SET debug_dbug='d,assoc_array_pack';
|
||||||
|
CREATE TABLE dtypes
|
||||||
|
(
|
||||||
|
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
dtype VARCHAR(128),
|
||||||
|
val LONGTEXT
|
||||||
|
);
|
||||||
|
INSERT INTO dtypes (dtype, val) VALUES
|
||||||
|
('bit(1)', 'bit:1'),
|
||||||
|
('bit(8)', 'bit:255'),
|
||||||
|
('bit(16)', 'bit:65535'),
|
||||||
|
('bit(64)', 'bit:18446744073709551615'),
|
||||||
|
('tinyint', '123'),
|
||||||
|
('tinyint unsigned', '123'),
|
||||||
|
('smallint', '123'),
|
||||||
|
('smallint unsigned', '123'),
|
||||||
|
('int', '123'),
|
||||||
|
('int unsigned', '123'),
|
||||||
|
('mediumint', '123'),
|
||||||
|
('mediumint unsigned', '123'),
|
||||||
|
('bigint', '123'),
|
||||||
|
('bigint unsigned', '123'),
|
||||||
|
('decimal(10,2)', '123.45'),
|
||||||
|
('float', '123e5'),
|
||||||
|
('double', '123e5'),
|
||||||
|
('mariadb_schema.date', '2001-01-01'),
|
||||||
|
('time', '800:59:59'),
|
||||||
|
('time(6)', '800:59:59.123456'),
|
||||||
|
('datetime', '2001-01-01 23:59:59'),
|
||||||
|
('datetime(6)', '2001-01-01 23:59:59.123456'),
|
||||||
|
('timestamp', '2001-01-01 23:59:59'),
|
||||||
|
('timestamp(6)', '2001-01-01 23:59:59.123456'),
|
||||||
|
('binary(10)', 'test'),
|
||||||
|
('binary(20)', 'test'),
|
||||||
|
('binary(10)', 'test test'),
|
||||||
|
('binary(20)', 'test test'),
|
||||||
|
('char(10) character set latin1', 'test'),
|
||||||
|
('char(10) character set utf8mb4', 'test'),
|
||||||
|
('varchar(10) character set latin1', 'test'),
|
||||||
|
('varchar(10) character set utf8mb4', 'test'),
|
||||||
|
('tinytext character set latin1', 'test'),
|
||||||
|
('tinytext character set utf8mb4', 'test'),
|
||||||
|
('text character set latin1', 'test'),
|
||||||
|
('text character set utf8mb4', 'test'),
|
||||||
|
('mediumtext character set latin1', 'test'),
|
||||||
|
('mediumtext character set utf8mb4', 'test'),
|
||||||
|
('longtext character set latin1', 'test'),
|
||||||
|
('longtext character set utf8mb4', 'test'),
|
||||||
|
('char(255) character set latin1', REPEAT('test ',50)),
|
||||||
|
('char(255) character set utf8mb4', REPEAT('test ',50)),
|
||||||
|
('varchar(255) character set latin1', REPEAT('test ',50)),
|
||||||
|
('varchar(255) character set utf8mb4', REPEAT('test ',50)),
|
||||||
|
('tinytext character set latin1', REPEAT('test ',50)),
|
||||||
|
('tinytext character set utf8mb4', REPEAT('test ',50)),
|
||||||
|
('text character set latin1', REPEAT('test ',50)),
|
||||||
|
('text character set utf8mb4', REPEAT('test ',50)),
|
||||||
|
('mediumtext character set latin1', REPEAT('test ',50)),
|
||||||
|
('mediumtext character set utf8mb4', REPEAT('test ',50)),
|
||||||
|
('longtext character set latin1', REPEAT('test ',50)),
|
||||||
|
('longtext character set utf8mb4', REPEAT('test ',50)),
|
||||||
|
('text character set latin1', REPEAT('test ',(256*256-1)/5)),
|
||||||
|
('text character set utf8mb4', REPEAT('test ',(256*256-1)/5)),
|
||||||
|
('mediumtext character set latin1', REPEAT('test ',(256*256-1)/5)),
|
||||||
|
('mediumtext character set utf8mb4', REPEAT('test ',(256*256-1)/5)),
|
||||||
|
('longtext character set latin1', REPEAT('test ',(256*256-1)/5)),
|
||||||
|
('longtext character set utf8mb4', REPEAT('test ',(256*256-1)/5)),
|
||||||
|
('mediumtext character set utf8mb4', REPEAT('test ',(256*256*256-1)/5)),
|
||||||
|
('longtext character set utf8mb4', REPEAT('test ',(256*256*256-1)/5 + 1));
|
||||||
|
CREATE PROCEDURE test_type(rec dtypes%ROWTYPE) AS
|
||||||
|
TYPE assoc_t IS TABLE OF t1.val%TYPE INDEX BY INTEGER;
|
||||||
|
assoc assoc_t;
|
||||||
|
val LONGTEXT;
|
||||||
|
BEGIN
|
||||||
|
IF rec.val LIKE 'bit:%'
|
||||||
|
THEN
|
||||||
|
assoc(0) := CAST(REPLACE(rec.val,'bit:','') AS UNSIGNED);
|
||||||
|
SHOW WARNINGS;
|
||||||
|
SELECT assoc(0)+0 AS `assoc(0)`;
|
||||||
|
ELSIF rec.dtype LIKE 'binary%'
|
||||||
|
THEN
|
||||||
|
assoc(0):= rec.val;
|
||||||
|
SHOW WARNINGS;
|
||||||
|
SELECT HEX(assoc(0)), LENGTH(assoc(0));
|
||||||
|
ELSE
|
||||||
|
assoc(0) := rec.val;
|
||||||
|
SHOW WARNINGS;
|
||||||
|
IF LENGTH(rec.val) > 64
|
||||||
|
THEN
|
||||||
|
SELECT LEFT(assoc(0),30) ||
|
||||||
|
'..' || LENGTH(assoc(0)) || '.. ' ||
|
||||||
|
RIGHT(assoc(0),30) AS `assoc(0)`;
|
||||||
|
ELSE
|
||||||
|
SELECT assoc(0);
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
CREATE PROCEDURE test_types AS
|
||||||
|
BEGIN
|
||||||
|
FOR rec IN (SELECT * FROM dtypes)
|
||||||
|
LOOP
|
||||||
|
EXECUTE IMMEDIATE REPLACE('CREATE TABLE t1 (val DTYPE)','DTYPE',rec.dtype);
|
||||||
|
SELECT
|
||||||
|
COLUMN_TYPE AS ``, COALESCE(CHARACTER_SET_NAME,'') AS ``
|
||||||
|
FROM
|
||||||
|
INFORMATION_SCHEMA.COLUMNS
|
||||||
|
WHERE
|
||||||
|
TABLE_SCHEMA='test' AND TABLE_NAME='t1' AND COLUMN_NAME='val';
|
||||||
|
INSERT INTO t1 VALUES (rec.val);
|
||||||
|
CALL test_type(rec);
|
||||||
|
DROP TABLE t1;
|
||||||
|
END LOOP;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
CALL test_types;
|
||||||
|
|
||||||
|
bit(1)
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=1 plen=1 ; mdlen=1 flen=1 ; `assoc` bit(1)
|
||||||
|
assoc(0)
|
||||||
|
1
|
||||||
|
|
||||||
|
bit(8)
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=1 plen=1 ; mdlen=1 flen=8 ; `assoc` bit(8)
|
||||||
|
assoc(0)
|
||||||
|
255
|
||||||
|
|
||||||
|
bit(16)
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=2 plen=2 ; mdlen=2 flen=16 ; `assoc` bit(16)
|
||||||
|
assoc(0)
|
||||||
|
65535
|
||||||
|
|
||||||
|
bit(64)
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=8 plen=8 ; mdlen=8 flen=64 ; `assoc` bit(64)
|
||||||
|
assoc(0)
|
||||||
|
18446744073709551615
|
||||||
|
|
||||||
|
tinyint(4)
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=1 plen=1 ; mdlen=1 flen=4 ; `assoc` tinyint(4)
|
||||||
|
assoc(0)
|
||||||
|
123
|
||||||
|
|
||||||
|
tinyint(3) unsigned
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=1 plen=1 ; mdlen=1 flen=3 ; `assoc` tinyint(3) unsigned
|
||||||
|
assoc(0)
|
||||||
|
123
|
||||||
|
|
||||||
|
smallint(6)
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=2 plen=2 ; mdlen=2 flen=6 ; `assoc` smallint(6)
|
||||||
|
assoc(0)
|
||||||
|
123
|
||||||
|
|
||||||
|
smallint(5) unsigned
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=2 plen=2 ; mdlen=2 flen=5 ; `assoc` smallint(5) unsigned
|
||||||
|
assoc(0)
|
||||||
|
123
|
||||||
|
|
||||||
|
int(11)
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=4 plen=4 ; mdlen=4 flen=11 ; `assoc` int(11)
|
||||||
|
assoc(0)
|
||||||
|
123
|
||||||
|
|
||||||
|
int(10) unsigned
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=4 plen=4 ; mdlen=4 flen=10 ; `assoc` int(10) unsigned
|
||||||
|
assoc(0)
|
||||||
|
123
|
||||||
|
|
||||||
|
mediumint(9)
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=3 plen=3 ; mdlen=3 flen=9 ; `assoc` mediumint(9)
|
||||||
|
assoc(0)
|
||||||
|
123
|
||||||
|
|
||||||
|
mediumint(8) unsigned
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=3 plen=3 ; mdlen=3 flen=8 ; `assoc` mediumint(8) unsigned
|
||||||
|
assoc(0)
|
||||||
|
123
|
||||||
|
|
||||||
|
bigint(20)
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=8 plen=8 ; mdlen=8 flen=20 ; `assoc` bigint(20)
|
||||||
|
assoc(0)
|
||||||
|
123
|
||||||
|
|
||||||
|
bigint(20) unsigned
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=8 plen=8 ; mdlen=8 flen=20 ; `assoc` bigint(20) unsigned
|
||||||
|
assoc(0)
|
||||||
|
123
|
||||||
|
|
||||||
|
decimal(10,2)
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=5 plen=5 ; mdlen=5 flen=12 ; `assoc` decimal(10,2)
|
||||||
|
assoc(0)
|
||||||
|
123.45
|
||||||
|
|
||||||
|
float
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=4 plen=4 ; mdlen=4 flen=12 ; `assoc` float
|
||||||
|
assoc(0)
|
||||||
|
12300000
|
||||||
|
|
||||||
|
double
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=8 plen=8 ; mdlen=8 flen=22 ; `assoc` double
|
||||||
|
assoc(0)
|
||||||
|
12300000
|
||||||
|
|
||||||
|
date
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=3 plen=3 ; mdlen=3 flen=10 ; `assoc` date
|
||||||
|
assoc(0)
|
||||||
|
2001-01-01
|
||||||
|
|
||||||
|
time
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=3 plen=3 ; mdlen=3 flen=10 ; `assoc` time
|
||||||
|
assoc(0)
|
||||||
|
800:59:59
|
||||||
|
|
||||||
|
time(6)
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=6 plen=6 ; mdlen=6 flen=17 ; `assoc` time(6)
|
||||||
|
assoc(0)
|
||||||
|
800:59:59.123456
|
||||||
|
|
||||||
|
datetime
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=5 plen=5 ; mdlen=5 flen=19 ; `assoc` datetime
|
||||||
|
assoc(0)
|
||||||
|
2001-01-01 23:59:59
|
||||||
|
|
||||||
|
datetime(6)
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=8 plen=8 ; mdlen=8 flen=26 ; `assoc` datetime(6)
|
||||||
|
assoc(0)
|
||||||
|
2001-01-01 23:59:59.123456
|
||||||
|
|
||||||
|
timestamp
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=4 plen=4 ; mdlen=4 flen=19 ; `assoc` timestamp
|
||||||
|
assoc(0)
|
||||||
|
2001-01-01 23:59:59
|
||||||
|
|
||||||
|
timestamp(6)
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=7 plen=7 ; mdlen=7 flen=26 ; `assoc` timestamp(6)
|
||||||
|
assoc(0)
|
||||||
|
2001-01-01 23:59:59.123456
|
||||||
|
|
||||||
|
binary(10)
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=5 plen=5 ; mdlen=10 flen=10 ; `assoc` binary(10)
|
||||||
|
HEX(assoc(0)) LENGTH(assoc(0))
|
||||||
|
74657374000000000000 10
|
||||||
|
|
||||||
|
binary(20)
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=5 plen=5 ; mdlen=20 flen=20 ; `assoc` binary(20)
|
||||||
|
HEX(assoc(0)) LENGTH(assoc(0))
|
||||||
|
7465737400000000000000000000000000000000 20
|
||||||
|
|
||||||
|
binary(10)
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=10 plen=10 ; mdlen=10 flen=10 ; `assoc` binary(10)
|
||||||
|
HEX(assoc(0)) LENGTH(assoc(0))
|
||||||
|
74657374207465737400 10
|
||||||
|
|
||||||
|
binary(20)
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=10 plen=10 ; mdlen=20 flen=20 ; `assoc` binary(20)
|
||||||
|
HEX(assoc(0)) LENGTH(assoc(0))
|
||||||
|
7465737420746573740000000000000000000000 20
|
||||||
|
|
||||||
|
char(10) latin1
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=5 plen=5 ; mdlen=10 flen=10 ; `assoc` char(10)
|
||||||
|
assoc(0)
|
||||||
|
test
|
||||||
|
|
||||||
|
char(10) utf8mb4
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=5 plen=5 ; mdlen=40 flen=40 ; `assoc` char(10)
|
||||||
|
assoc(0)
|
||||||
|
test
|
||||||
|
|
||||||
|
varchar(10) latin1
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=5 plen=5 ; mdlen=11 flen=10 ; `assoc` varchar(10)
|
||||||
|
assoc(0)
|
||||||
|
test
|
||||||
|
|
||||||
|
varchar(10) utf8mb4
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=5 plen=5 ; mdlen=41 flen=40 ; `assoc` varchar(10)
|
||||||
|
assoc(0)
|
||||||
|
test
|
||||||
|
|
||||||
|
tinytext latin1
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=5 plen=5 ; mdlen=255 flen=255 ; `assoc` tinytext
|
||||||
|
assoc(0)
|
||||||
|
test
|
||||||
|
|
||||||
|
tinytext utf8mb4
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=5 plen=5 ; mdlen=255 flen=255 ; `assoc` tinytext
|
||||||
|
assoc(0)
|
||||||
|
test
|
||||||
|
|
||||||
|
text latin1
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=6 plen=6 ; mdlen=65535 flen=65535 ; `assoc` text
|
||||||
|
assoc(0)
|
||||||
|
test
|
||||||
|
|
||||||
|
text utf8mb4
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=6 plen=6 ; mdlen=65535 flen=65535 ; `assoc` text
|
||||||
|
assoc(0)
|
||||||
|
test
|
||||||
|
|
||||||
|
mediumtext latin1
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=7 plen=7 ; mdlen=16777215 flen=16777215 ; `assoc` mediumtext
|
||||||
|
assoc(0)
|
||||||
|
test
|
||||||
|
|
||||||
|
mediumtext utf8mb4
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=7 plen=7 ; mdlen=16777215 flen=16777215 ; `assoc` mediumtext
|
||||||
|
assoc(0)
|
||||||
|
test
|
||||||
|
|
||||||
|
longtext latin1
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=8 plen=8 ; mdlen=4294967295 flen=4294967295 ; `assoc` longtext
|
||||||
|
assoc(0)
|
||||||
|
test
|
||||||
|
|
||||||
|
longtext utf8mb4
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=8 plen=8 ; mdlen=4294967295 flen=4294967295 ; `assoc` longtext
|
||||||
|
assoc(0)
|
||||||
|
test
|
||||||
|
|
||||||
|
char(255) latin1
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=250 plen=250 ; mdlen=255 flen=255 ; `assoc` char(255)
|
||||||
|
assoc(0)
|
||||||
|
test test test test test test ..249.. test test test test test test
|
||||||
|
|
||||||
|
char(255) utf8mb4
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=251 plen=251 ; mdlen=1020 flen=1020 ; `assoc` char(255)
|
||||||
|
assoc(0)
|
||||||
|
test test test test test test ..249.. test test test test test test
|
||||||
|
|
||||||
|
varchar(255) latin1
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=251 plen=251 ; mdlen=256 flen=255 ; `assoc` varchar(255)
|
||||||
|
assoc(0)
|
||||||
|
test test test test test test ..250.. test test test test test test
|
||||||
|
|
||||||
|
varchar(255) utf8mb4
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=252 plen=252 ; mdlen=1022 flen=1020 ; `assoc` varchar(255)
|
||||||
|
assoc(0)
|
||||||
|
test test test test test test ..250.. test test test test test test
|
||||||
|
|
||||||
|
tinytext latin1
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=251 plen=251 ; mdlen=255 flen=255 ; `assoc` tinytext
|
||||||
|
assoc(0)
|
||||||
|
test test test test test test ..250.. test test test test test test
|
||||||
|
|
||||||
|
tinytext utf8mb4
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=251 plen=251 ; mdlen=255 flen=255 ; `assoc` tinytext
|
||||||
|
assoc(0)
|
||||||
|
test test test test test test ..250.. test test test test test test
|
||||||
|
|
||||||
|
text latin1
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=252 plen=252 ; mdlen=65535 flen=65535 ; `assoc` text
|
||||||
|
assoc(0)
|
||||||
|
test test test test test test ..250.. test test test test test test
|
||||||
|
|
||||||
|
text utf8mb4
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=252 plen=252 ; mdlen=65535 flen=65535 ; `assoc` text
|
||||||
|
assoc(0)
|
||||||
|
test test test test test test ..250.. test test test test test test
|
||||||
|
|
||||||
|
mediumtext latin1
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=253 plen=253 ; mdlen=16777215 flen=16777215 ; `assoc` mediumtext
|
||||||
|
assoc(0)
|
||||||
|
test test test test test test ..250.. test test test test test test
|
||||||
|
|
||||||
|
mediumtext utf8mb4
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=253 plen=253 ; mdlen=16777215 flen=16777215 ; `assoc` mediumtext
|
||||||
|
assoc(0)
|
||||||
|
test test test test test test ..250.. test test test test test test
|
||||||
|
|
||||||
|
longtext latin1
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=254 plen=254 ; mdlen=4294967295 flen=4294967295 ; `assoc` longtext
|
||||||
|
assoc(0)
|
||||||
|
test test test test test test ..250.. test test test test test test
|
||||||
|
|
||||||
|
longtext utf8mb4
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=254 plen=254 ; mdlen=4294967295 flen=4294967295 ; `assoc` longtext
|
||||||
|
assoc(0)
|
||||||
|
test test test test test test ..250.. test test test test test test
|
||||||
|
|
||||||
|
text latin1
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=65537 plen=65537 ; mdlen=65535 flen=65535 ; `assoc` text
|
||||||
|
assoc(0)
|
||||||
|
test test test test test test ..65535.. test test test test test test
|
||||||
|
|
||||||
|
text utf8mb4
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=65537 plen=65537 ; mdlen=65535 flen=65535 ; `assoc` text
|
||||||
|
assoc(0)
|
||||||
|
test test test test test test ..65535.. test test test test test test
|
||||||
|
|
||||||
|
mediumtext latin1
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=65538 plen=65538 ; mdlen=16777215 flen=16777215 ; `assoc` mediumtext
|
||||||
|
assoc(0)
|
||||||
|
test test test test test test ..65535.. test test test test test test
|
||||||
|
|
||||||
|
mediumtext utf8mb4
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=65538 plen=65538 ; mdlen=16777215 flen=16777215 ; `assoc` mediumtext
|
||||||
|
assoc(0)
|
||||||
|
test test test test test test ..65535.. test test test test test test
|
||||||
|
|
||||||
|
longtext latin1
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=65539 plen=65539 ; mdlen=4294967295 flen=4294967295 ; `assoc` longtext
|
||||||
|
assoc(0)
|
||||||
|
test test test test test test ..65535.. test test test test test test
|
||||||
|
|
||||||
|
longtext utf8mb4
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=65539 plen=65539 ; mdlen=4294967295 flen=4294967295 ; `assoc` longtext
|
||||||
|
assoc(0)
|
||||||
|
test test test test test test ..65535.. test test test test test test
|
||||||
|
|
||||||
|
mediumtext utf8mb4
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=16777218 plen=16777218 ; mdlen=16777215 flen=16777215 ; `assoc` mediumtext
|
||||||
|
assoc(0)
|
||||||
|
test test test test test test ..16777215.. test test test test test test
|
||||||
|
|
||||||
|
longtext utf8mb4
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 pack=16777224 plen=16777224 ; mdlen=4294967295 flen=4294967295 ; `assoc` longtext
|
||||||
|
assoc(0)
|
||||||
|
test test test test test test ..16777220.. test test test test test test
|
||||||
|
DROP PROCEDURE test_type;
|
||||||
|
DROP PROCEDURE test_types;
|
||||||
|
DROP TABLE dtypes;
|
@ -0,0 +1,144 @@
|
|||||||
|
-- source include/have_debug.inc
|
||||||
|
|
||||||
|
set sql_mode=oracle;
|
||||||
|
SET NAMES utf8mb4;
|
||||||
|
SELECT @@SESSION.max_allowed_packet;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-34319 DECLARE TYPE .. TABLE OF .. INDEX BY in stored routines
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SET debug_dbug='d,assoc_array_pack';
|
||||||
|
|
||||||
|
CREATE TABLE dtypes
|
||||||
|
(
|
||||||
|
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
dtype VARCHAR(128),
|
||||||
|
val LONGTEXT
|
||||||
|
);
|
||||||
|
INSERT INTO dtypes (dtype, val) VALUES
|
||||||
|
|
||||||
|
('bit(1)', 'bit:1'),
|
||||||
|
('bit(8)', 'bit:255'),
|
||||||
|
('bit(16)', 'bit:65535'),
|
||||||
|
('bit(64)', 'bit:18446744073709551615'),
|
||||||
|
('tinyint', '123'),
|
||||||
|
('tinyint unsigned', '123'),
|
||||||
|
('smallint', '123'),
|
||||||
|
('smallint unsigned', '123'),
|
||||||
|
('int', '123'),
|
||||||
|
('int unsigned', '123'),
|
||||||
|
('mediumint', '123'),
|
||||||
|
('mediumint unsigned', '123'),
|
||||||
|
('bigint', '123'),
|
||||||
|
('bigint unsigned', '123'),
|
||||||
|
('decimal(10,2)', '123.45'),
|
||||||
|
('float', '123e5'),
|
||||||
|
('double', '123e5'),
|
||||||
|
('mariadb_schema.date', '2001-01-01'),
|
||||||
|
('time', '800:59:59'),
|
||||||
|
('time(6)', '800:59:59.123456'),
|
||||||
|
('datetime', '2001-01-01 23:59:59'),
|
||||||
|
('datetime(6)', '2001-01-01 23:59:59.123456'),
|
||||||
|
('timestamp', '2001-01-01 23:59:59'),
|
||||||
|
('timestamp(6)', '2001-01-01 23:59:59.123456'),
|
||||||
|
|
||||||
|
('binary(10)', 'test'),
|
||||||
|
('binary(20)', 'test'),
|
||||||
|
('binary(10)', 'test test'),
|
||||||
|
('binary(20)', 'test test'),
|
||||||
|
|
||||||
|
('char(10) character set latin1', 'test'),
|
||||||
|
('char(10) character set utf8mb4', 'test'),
|
||||||
|
('varchar(10) character set latin1', 'test'),
|
||||||
|
('varchar(10) character set utf8mb4', 'test'),
|
||||||
|
('tinytext character set latin1', 'test'),
|
||||||
|
('tinytext character set utf8mb4', 'test'),
|
||||||
|
('text character set latin1', 'test'),
|
||||||
|
('text character set utf8mb4', 'test'),
|
||||||
|
('mediumtext character set latin1', 'test'),
|
||||||
|
('mediumtext character set utf8mb4', 'test'),
|
||||||
|
('longtext character set latin1', 'test'),
|
||||||
|
('longtext character set utf8mb4', 'test'),
|
||||||
|
|
||||||
|
('char(255) character set latin1', REPEAT('test ',50)),
|
||||||
|
('char(255) character set utf8mb4', REPEAT('test ',50)),
|
||||||
|
('varchar(255) character set latin1', REPEAT('test ',50)),
|
||||||
|
('varchar(255) character set utf8mb4', REPEAT('test ',50)),
|
||||||
|
('tinytext character set latin1', REPEAT('test ',50)),
|
||||||
|
('tinytext character set utf8mb4', REPEAT('test ',50)),
|
||||||
|
('text character set latin1', REPEAT('test ',50)),
|
||||||
|
('text character set utf8mb4', REPEAT('test ',50)),
|
||||||
|
('mediumtext character set latin1', REPEAT('test ',50)),
|
||||||
|
('mediumtext character set utf8mb4', REPEAT('test ',50)),
|
||||||
|
('longtext character set latin1', REPEAT('test ',50)),
|
||||||
|
('longtext character set utf8mb4', REPEAT('test ',50)),
|
||||||
|
|
||||||
|
('text character set latin1', REPEAT('test ',(256*256-1)/5)),
|
||||||
|
('text character set utf8mb4', REPEAT('test ',(256*256-1)/5)),
|
||||||
|
('mediumtext character set latin1', REPEAT('test ',(256*256-1)/5)),
|
||||||
|
('mediumtext character set utf8mb4', REPEAT('test ',(256*256-1)/5)),
|
||||||
|
('longtext character set latin1', REPEAT('test ',(256*256-1)/5)),
|
||||||
|
('longtext character set utf8mb4', REPEAT('test ',(256*256-1)/5)),
|
||||||
|
|
||||||
|
('mediumtext character set utf8mb4', REPEAT('test ',(256*256*256-1)/5)),
|
||||||
|
('longtext character set utf8mb4', REPEAT('test ',(256*256*256-1)/5 + 1));
|
||||||
|
|
||||||
|
|
||||||
|
DELIMITER $$;
|
||||||
|
CREATE PROCEDURE test_type(rec dtypes%ROWTYPE) AS
|
||||||
|
TYPE assoc_t IS TABLE OF t1.val%TYPE INDEX BY INTEGER;
|
||||||
|
assoc assoc_t;
|
||||||
|
val LONGTEXT;
|
||||||
|
BEGIN
|
||||||
|
IF rec.val LIKE 'bit:%'
|
||||||
|
THEN
|
||||||
|
assoc(0) := CAST(REPLACE(rec.val,'bit:','') AS UNSIGNED);
|
||||||
|
SHOW WARNINGS;
|
||||||
|
SELECT assoc(0)+0 AS `assoc(0)`;
|
||||||
|
ELSIF rec.dtype LIKE 'binary%'
|
||||||
|
THEN
|
||||||
|
assoc(0):= rec.val;
|
||||||
|
SHOW WARNINGS;
|
||||||
|
SELECT HEX(assoc(0)), LENGTH(assoc(0));
|
||||||
|
ELSE
|
||||||
|
assoc(0) := rec.val;
|
||||||
|
SHOW WARNINGS;
|
||||||
|
IF LENGTH(rec.val) > 64
|
||||||
|
THEN
|
||||||
|
SELECT LEFT(assoc(0),30) ||
|
||||||
|
'..' || LENGTH(assoc(0)) || '.. ' ||
|
||||||
|
RIGHT(assoc(0),30) AS `assoc(0)`;
|
||||||
|
ELSE
|
||||||
|
SELECT assoc(0);
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
DELIMITER ;$$
|
||||||
|
|
||||||
|
DELIMITER $$;
|
||||||
|
CREATE PROCEDURE test_types AS
|
||||||
|
BEGIN
|
||||||
|
FOR rec IN (SELECT * FROM dtypes)
|
||||||
|
LOOP
|
||||||
|
EXECUTE IMMEDIATE REPLACE('CREATE TABLE t1 (val DTYPE)','DTYPE',rec.dtype);
|
||||||
|
SELECT
|
||||||
|
COLUMN_TYPE AS ``, COALESCE(CHARACTER_SET_NAME,'') AS ``
|
||||||
|
FROM
|
||||||
|
INFORMATION_SCHEMA.COLUMNS
|
||||||
|
WHERE
|
||||||
|
TABLE_SCHEMA='test' AND TABLE_NAME='t1' AND COLUMN_NAME='val';
|
||||||
|
INSERT INTO t1 VALUES (rec.val);
|
||||||
|
CALL test_type(rec);
|
||||||
|
DROP TABLE t1;
|
||||||
|
END LOOP;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
DELIMITER ;$$
|
||||||
|
|
||||||
|
CALL test_types;
|
||||||
|
|
||||||
|
DROP PROCEDURE test_type;
|
||||||
|
DROP PROCEDURE test_types;
|
||||||
|
DROP TABLE dtypes;
|
@ -1,6 +1,9 @@
|
|||||||
SET sql_mode=ORACLE;
|
SET sql_mode=ORACLE;
|
||||||
SET NAMES utf8mb4;
|
SET NAMES utf8mb4;
|
||||||
|
|
||||||
|
# Needed for mtr --cursor
|
||||||
|
--enable_prepare_warnings
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # MDEV-34319 DECLARE TYPE .. TABLE OF .. INDEX BY in stored routines
|
--echo # MDEV-34319 DECLARE TYPE .. TABLE OF .. INDEX BY in stored routines
|
||||||
--echo #
|
--echo #
|
||||||
|
@ -1522,7 +1522,7 @@ marks(1) := 1;
|
|||||||
SELECT marks(1).name;
|
SELECT marks(1).name;
|
||||||
END;
|
END;
|
||||||
$$
|
$$
|
||||||
ERROR 42S22: Unknown column '1' in 'SELECT'
|
ERROR 42S22: Unknown column 'name' in 'marks'
|
||||||
#
|
#
|
||||||
# Field assignment
|
# Field assignment
|
||||||
#
|
#
|
||||||
|
@ -128,12 +128,26 @@ public:
|
|||||||
DBUG_ASSERT(field);
|
DBUG_ASSERT(field);
|
||||||
DBUG_ASSERT(m_buffer);
|
DBUG_ASSERT(m_buffer);
|
||||||
|
|
||||||
auto length= field->packed_col_length(field->ptr,
|
uint length= field->packed_col_length();
|
||||||
field->value_length()) + 1;
|
if (unlikely(m_buffer->realloc(length + 1/*QQ: is +1 needed?*/)))
|
||||||
if (unlikely(m_buffer->realloc(length)))
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
#ifndef DBUG_OFF
|
||||||
|
StringBuffer<64> type;
|
||||||
|
field->sql_type(type);
|
||||||
|
const uchar *pend=
|
||||||
|
#endif
|
||||||
field->pack(ptr(), field->ptr);
|
field->pack(ptr(), field->ptr);
|
||||||
|
DBUG_ASSERT((uint) (pend - ptr()) == length);
|
||||||
|
DBUG_EXECUTE_IF("assoc_array_pack",
|
||||||
|
push_warning_printf(current_thd,
|
||||||
|
Sql_condition::WARN_LEVEL_NOTE,
|
||||||
|
ER_YES, "pack=%u plen=%u ; mdlen=%u flen=%u ; `%s` %s",
|
||||||
|
(uint) (pend - ptr()), length,
|
||||||
|
field->max_data_length(),
|
||||||
|
field->field_length,
|
||||||
|
field->field_name.str,
|
||||||
|
type.c_ptr()););
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,8 +285,7 @@ public:
|
|||||||
for (uint i= 0; i < vtable.s->fields; i++)
|
for (uint i= 0; i < vtable.s->fields; i++)
|
||||||
{
|
{
|
||||||
auto field= vtable.field[i];
|
auto field= vtable.field[i];
|
||||||
length+= field->packed_col_length(field->ptr,
|
length+= field->packed_col_length() + 1;
|
||||||
field->value_length()) + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return length;
|
return length;
|
||||||
@ -1532,8 +1545,7 @@ bool Field_assoc_array::create_element_buffer(THD *thd, Binary_string *buffer)
|
|||||||
return buffer->alloc(length);
|
return buffer->alloc(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint length= m_element_field->packed_col_length(m_element_field->ptr,
|
uint length= m_element_field->packed_col_length() + 1;
|
||||||
m_element_field->value_length()) + 1;
|
|
||||||
return buffer->alloc(length);
|
return buffer->alloc(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2005,7 +2017,7 @@ bool Item_splocal_assoc_array_element_field::fix_fields(THD *thd, Item **ref)
|
|||||||
m_field_name,
|
m_field_name,
|
||||||
m_field_idx))
|
m_field_idx))
|
||||||
{
|
{
|
||||||
my_error(ER_BAD_FIELD_ERROR, MYF(0), str->c_ptr(), thd_where(thd));
|
my_error(ER_BAD_FIELD_ERROR, MYF(0), m_field_name.str, m_name.str);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,12 +294,11 @@ public:
|
|||||||
extending the binary log format to put the extact data type name into
|
extending the binary log format to put the extact data type name into
|
||||||
the column metadata.
|
the column metadata.
|
||||||
*/
|
*/
|
||||||
static uchar *pack(uchar *to, const uchar *from, uint max_length)
|
static uchar *pack(uchar *to, const uchar *from)
|
||||||
{
|
{
|
||||||
uchar buf[binary_length()];
|
uchar buf[binary_length()];
|
||||||
record_to_memory((char *) buf, (const char *) from);
|
record_to_memory((char *) buf, (const char *) from);
|
||||||
return StringPack(&my_charset_bin, binary_length()).
|
return StringPack(&my_charset_bin, binary_length()).pack(to, buf);
|
||||||
pack(to, buf, max_length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert binlog representation to in-record representation
|
// Convert binlog representation to in-record representation
|
||||||
|
70
sql/field.cc
70
sql/field.cc
@ -2126,19 +2126,11 @@ int Field_blob::store_from_statistical_minmax_field(Field *stat_field,
|
|||||||
@param from
|
@param from
|
||||||
Pointer to memory area where record representation of field is
|
Pointer to memory area where record representation of field is
|
||||||
stored.
|
stored.
|
||||||
|
|
||||||
@param max_length
|
|
||||||
Maximum length of the field, as given in the column definition. For
|
|
||||||
example, for <code>CHAR(1000)</code>, the <code>max_length</code>
|
|
||||||
is 1000. This information is sometimes needed to decide how to pack
|
|
||||||
the data.
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
uchar *
|
uchar *
|
||||||
Field::pack(uchar *to, const uchar *from, uint max_length)
|
Field::pack(uchar *to, const uchar *from) const
|
||||||
{
|
{
|
||||||
uint32 length= pack_length();
|
uint32 length= pack_length();
|
||||||
set_if_smaller(length, max_length);
|
|
||||||
memcpy(to, from, length);
|
memcpy(to, from, length);
|
||||||
return to+length;
|
return to+length;
|
||||||
}
|
}
|
||||||
@ -7608,12 +7600,6 @@ int Field_longstr::store_decimal(const my_decimal *d)
|
|||||||
return store(str.ptr(), str.length(), str.charset());
|
return store(str.ptr(), str.length(), str.charset());
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 Field_longstr::max_data_length() const
|
|
||||||
{
|
|
||||||
return field_length + (field_length > 255 ? 2 : 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Data_type_compatibility
|
Data_type_compatibility
|
||||||
Field_longstr::cmp_to_string_with_same_collation(const Item_bool_func *cond,
|
Field_longstr::cmp_to_string_with_same_collation(const Item_bool_func *cond,
|
||||||
const Item *item) const
|
const Item *item) const
|
||||||
@ -7917,10 +7903,10 @@ void Field_string::sql_rpl_type(String *res) const
|
|||||||
Field_string::sql_type(*res);
|
Field_string::sql_type(*res);
|
||||||
}
|
}
|
||||||
|
|
||||||
uchar *Field_string::pack(uchar *to, const uchar *from, uint max_length)
|
uchar *Field_string::pack(uchar *to, const uchar *from) const
|
||||||
{
|
{
|
||||||
DBUG_PRINT("debug", ("Packing field '%s'", field_name.str));
|
DBUG_PRINT("debug", ("Packing field '%s'", field_name.str));
|
||||||
return StringPack(field_charset(), field_length).pack(to, from, max_length);
|
return StringPack(field_charset(), field_length).pack(to, from);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -8004,13 +7990,14 @@ Binlog_type_info Field_string::binlog_type_info() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint Field_string::packed_col_length(const uchar *data_ptr, uint length)
|
uint Field_string::packed_col_length() const
|
||||||
{
|
{
|
||||||
return StringPack::packed_col_length(data_ptr, length);
|
return StringPack(field_charset(), field_length).
|
||||||
|
packed_col_length(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint Field_string::max_packed_col_length(uint max_length)
|
uint Field_string::max_packed_col_length(uint max_length) const
|
||||||
{
|
{
|
||||||
return StringPack::max_packed_col_length(max_length);
|
return StringPack::max_packed_col_length(max_length);
|
||||||
}
|
}
|
||||||
@ -8395,19 +8382,16 @@ uint32 Field_varstring::data_length()
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Functions to create a packed row.
|
Functions to create a packed row.
|
||||||
Here the number of length bytes are depending on the given max_length
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
uchar *Field_varstring::pack(uchar *to, const uchar *from, uint max_length)
|
uchar *Field_varstring::pack(uchar *to, const uchar *from) const
|
||||||
{
|
{
|
||||||
uint length= length_bytes == 1 ? (uint) *from : uint2korr(from);
|
uint length= length_bytes == 1 ? (uint) *from : uint2korr(from);
|
||||||
set_if_smaller(max_length, field_length);
|
DBUG_ASSERT(length <= field_length);
|
||||||
if (length > max_length)
|
|
||||||
length=max_length;
|
|
||||||
|
|
||||||
/* Length always stored little-endian */
|
/* Length always stored little-endian */
|
||||||
*to++= length & 0xFF;
|
*to++= length & 0xFF;
|
||||||
if (max_length > 255)
|
if (field_length > 255)
|
||||||
*to++= (length >> 8) & 0xFF;
|
*to++= (length >> 8) & 0xFF;
|
||||||
|
|
||||||
/* Store bytes of string */
|
/* Store bytes of string */
|
||||||
@ -8466,15 +8450,15 @@ Field_varstring::unpack(uchar *to, const uchar *from, const uchar *from_end,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint Field_varstring::packed_col_length(const uchar *data_ptr, uint length)
|
uint Field_varstring::packed_col_length() const
|
||||||
{
|
{
|
||||||
if (length > 255)
|
if (field_length > 255)
|
||||||
return uint2korr(data_ptr)+2;
|
return uint2korr(ptr) + 2;
|
||||||
return (uint) *data_ptr + 1;
|
return (uint) *ptr + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint Field_varstring::max_packed_col_length(uint max_length)
|
uint Field_varstring::max_packed_col_length(uint max_length) const
|
||||||
{
|
{
|
||||||
return (max_length > 255 ? 2 : 1)+max_length;
|
return (max_length > 255 ? 2 : 1)+max_length;
|
||||||
}
|
}
|
||||||
@ -8823,6 +8807,7 @@ Field_blob::Field_blob(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
|
|||||||
|
|
||||||
|
|
||||||
void Field_blob::store_length(uchar *i_ptr, uint i_packlength, uint32 i_number)
|
void Field_blob::store_length(uchar *i_ptr, uint i_packlength, uint32 i_number)
|
||||||
|
const
|
||||||
{
|
{
|
||||||
store_lowendian(i_number, i_ptr, i_packlength);
|
store_lowendian(i_number, i_ptr, i_packlength);
|
||||||
}
|
}
|
||||||
@ -9287,7 +9272,7 @@ void Field_blob::sql_type(String &res) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uchar *Field_blob::pack(uchar *to, const uchar *from, uint max_length)
|
uchar *Field_blob::pack(uchar *to, const uchar *from) const
|
||||||
{
|
{
|
||||||
uint32 length=get_length(from, packlength); // Length of from string
|
uint32 length=get_length(from, packlength); // Length of from string
|
||||||
|
|
||||||
@ -9296,7 +9281,7 @@ uchar *Field_blob::pack(uchar *to, const uchar *from, uint max_length)
|
|||||||
length given is smaller than the actual length of the blob, we
|
length given is smaller than the actual length of the blob, we
|
||||||
just store the initial bytes of the blob.
|
just store the initial bytes of the blob.
|
||||||
*/
|
*/
|
||||||
store_length(to, packlength, MY_MIN(length, max_length));
|
store_length(to, packlength, length);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Store the actual blob data, which will occupy 'length' bytes.
|
Store the actual blob data, which will occupy 'length' bytes.
|
||||||
@ -9347,15 +9332,13 @@ const uchar *Field_blob::unpack(uchar *to, const uchar *from,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint Field_blob::packed_col_length(const uchar *data_ptr, uint length)
|
uint Field_blob::packed_col_length() const
|
||||||
{
|
{
|
||||||
if (length > 255)
|
return (uint) read_lowendian(ptr, packlength) + packlength;
|
||||||
return uint2korr(data_ptr)+2;
|
|
||||||
return (uint) *data_ptr + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint Field_blob::max_packed_col_length(uint max_length)
|
uint Field_blob::max_packed_col_length(uint max_length) const
|
||||||
{
|
{
|
||||||
return (max_length > 255 ? 2 : 1)+max_length;
|
return (max_length > 255 ? 2 : 1)+max_length;
|
||||||
}
|
}
|
||||||
@ -9891,7 +9874,7 @@ bool Field_enum::is_equal(const Column_definition &new_field) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uchar *Field_enum::pack(uchar *to, const uchar *from, uint max_length)
|
uchar *Field_enum::pack(uchar *to, const uchar *from) const
|
||||||
{
|
{
|
||||||
DBUG_ENTER("Field_enum::pack");
|
DBUG_ENTER("Field_enum::pack");
|
||||||
DBUG_PRINT("debug", ("packlength: %d", packlength));
|
DBUG_PRINT("debug", ("packlength: %d", packlength));
|
||||||
@ -10389,10 +10372,8 @@ void Field_bit::sql_type(String &res) const
|
|||||||
|
|
||||||
|
|
||||||
uchar *
|
uchar *
|
||||||
Field_bit::pack(uchar *to, const uchar *from, uint max_length)
|
Field_bit::pack(uchar *to, const uchar *from) const
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(max_length > 0);
|
|
||||||
uint length;
|
|
||||||
if (bit_len > 0)
|
if (bit_len > 0)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -10417,9 +10398,8 @@ Field_bit::pack(uchar *to, const uchar *from, uint max_length)
|
|||||||
uchar bits= get_rec_bits(bit_ptr + (from - ptr), bit_ofs, bit_len);
|
uchar bits= get_rec_bits(bit_ptr + (from - ptr), bit_ofs, bit_len);
|
||||||
*to++= bits;
|
*to++= bits;
|
||||||
}
|
}
|
||||||
length= MY_MIN(bytes_in_rec, max_length - (bit_len > 0));
|
memcpy(to, from, bytes_in_rec);
|
||||||
memcpy(to, from, length);
|
return to + bytes_in_rec;
|
||||||
return to + length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
110
sql/field.h
110
sql/field.h
@ -1717,23 +1717,14 @@ public:
|
|||||||
}
|
}
|
||||||
virtual bool send(Protocol *protocol);
|
virtual bool send(Protocol *protocol);
|
||||||
|
|
||||||
virtual uchar *pack(uchar *to, const uchar *from, uint max_length);
|
virtual uchar *pack(uchar *to, const uchar *from) const;
|
||||||
/**
|
|
||||||
@overload Field::pack(uchar*, const uchar*, uint, bool)
|
|
||||||
*/
|
|
||||||
uchar *pack(uchar *to, const uchar *from)
|
|
||||||
{
|
|
||||||
DBUG_ENTER("Field::pack");
|
|
||||||
uchar *result= this->pack(to, from, UINT_MAX);
|
|
||||||
DBUG_RETURN(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual const uchar *unpack(uchar* to, const uchar *from,
|
virtual const uchar *unpack(uchar* to, const uchar *from,
|
||||||
const uchar *from_end, uint param_data=0);
|
const uchar *from_end, uint param_data=0);
|
||||||
|
|
||||||
virtual uint packed_col_length(const uchar *to, uint length)
|
virtual uint packed_col_length() const
|
||||||
{ return length;}
|
{ return pack_length(); }
|
||||||
virtual uint max_packed_col_length(uint max_length)
|
virtual uint max_packed_col_length(uint max_length) const
|
||||||
{ return max_length;}
|
{ return max_length;}
|
||||||
virtual bool is_packable() const { return false; }
|
virtual bool is_packable() const { return false; }
|
||||||
|
|
||||||
@ -2118,13 +2109,13 @@ private:
|
|||||||
virtual size_t do_last_null_byte() const;
|
virtual size_t do_last_null_byte() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uchar *pack_int(uchar *to, const uchar *from, size_t size)
|
static uchar *pack_int(uchar *to, const uchar *from, size_t size)
|
||||||
{
|
{
|
||||||
memcpy(to, from, size);
|
memcpy(to, from, size);
|
||||||
return to + size;
|
return to + size;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uchar *unpack_int(uchar* to, const uchar *from,
|
static const uchar *unpack_int(uchar* to, const uchar *from,
|
||||||
const uchar *from_end, size_t size)
|
const uchar *from_end, size_t size)
|
||||||
{
|
{
|
||||||
if (from + size > from_end)
|
if (from + size > from_end)
|
||||||
@ -2133,21 +2124,25 @@ protected:
|
|||||||
return from + size;
|
return from + size;
|
||||||
}
|
}
|
||||||
|
|
||||||
uchar *pack_int16(uchar *to, const uchar *from)
|
static uchar *pack_int16(uchar *to, const uchar *from)
|
||||||
{ return pack_int(to, from, 2); }
|
{ return pack_int(to, from, 2); }
|
||||||
const uchar *unpack_int16(uchar* to, const uchar *from, const uchar *from_end)
|
static const uchar *unpack_int16(uchar* to,
|
||||||
|
const uchar *from, const uchar *from_end)
|
||||||
{ return unpack_int(to, from, from_end, 2); }
|
{ return unpack_int(to, from, from_end, 2); }
|
||||||
uchar *pack_int24(uchar *to, const uchar *from)
|
static uchar *pack_int24(uchar *to, const uchar *from)
|
||||||
{ return pack_int(to, from, 3); }
|
{ return pack_int(to, from, 3); }
|
||||||
const uchar *unpack_int24(uchar* to, const uchar *from, const uchar *from_end)
|
static const uchar *unpack_int24(uchar* to,
|
||||||
|
const uchar *from, const uchar *from_end)
|
||||||
{ return unpack_int(to, from, from_end, 3); }
|
{ return unpack_int(to, from, from_end, 3); }
|
||||||
uchar *pack_int32(uchar *to, const uchar *from)
|
static uchar *pack_int32(uchar *to, const uchar *from)
|
||||||
{ return pack_int(to, from, 4); }
|
{ return pack_int(to, from, 4); }
|
||||||
const uchar *unpack_int32(uchar* to, const uchar *from, const uchar *from_end)
|
static const uchar *unpack_int32(uchar* to,
|
||||||
|
const uchar *from, const uchar *from_end)
|
||||||
{ return unpack_int(to, from, from_end, 4); }
|
{ return unpack_int(to, from, from_end, 4); }
|
||||||
uchar *pack_int64(uchar* to, const uchar *from)
|
static uchar *pack_int64(uchar* to, const uchar *from)
|
||||||
{ return pack_int(to, from, 8); }
|
{ return pack_int(to, from, 8); }
|
||||||
const uchar *unpack_int64(uchar* to, const uchar *from, const uchar *from_end)
|
static const uchar *unpack_int64(uchar* to,
|
||||||
|
const uchar *from, const uchar *from_end)
|
||||||
{ return unpack_int(to, from, from_end, 8); }
|
{ return unpack_int(to, from, from_end, 8); }
|
||||||
|
|
||||||
double pos_in_interval_val_real(Field *min, Field *max);
|
double pos_in_interval_val_real(Field *min, Field *max);
|
||||||
@ -2379,7 +2374,8 @@ public:
|
|||||||
const Relay_log_info *rli,
|
const Relay_log_info *rli,
|
||||||
const Conv_param ¶m) const override;
|
const Conv_param ¶m) const override;
|
||||||
int store_decimal(const my_decimal *d) override;
|
int store_decimal(const my_decimal *d) override;
|
||||||
uint32 max_data_length() const override;
|
uint32 max_data_length() const override= 0;
|
||||||
|
uint packed_col_length() const override= 0;
|
||||||
void make_send_field(Send_field *) override;
|
void make_send_field(Send_field *) override;
|
||||||
bool send(Protocol *protocol) override;
|
bool send(Protocol *protocol) override;
|
||||||
bool val_bool() override;
|
bool val_bool() override;
|
||||||
@ -2503,9 +2499,9 @@ public:
|
|||||||
void overflow(bool negative);
|
void overflow(bool negative);
|
||||||
bool zero_pack() const override { return false; }
|
bool zero_pack() const override { return false; }
|
||||||
void sql_type(String &str) const override;
|
void sql_type(String &str) const override;
|
||||||
uchar *pack(uchar* to, const uchar *from, uint max_length) override
|
uchar *pack(uchar* to, const uchar *from) const override
|
||||||
{
|
{
|
||||||
return Field::pack(to, from, max_length);
|
return Field::pack(to, from);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2720,7 +2716,7 @@ public:
|
|||||||
return type_handler_priv()->type_limits_int();
|
return type_handler_priv()->type_limits_int();
|
||||||
}
|
}
|
||||||
|
|
||||||
uchar *pack(uchar* to, const uchar *from, uint max_length) override
|
uchar *pack(uchar* to, const uchar *from) const override
|
||||||
{
|
{
|
||||||
*to= *from;
|
*to= *from;
|
||||||
return to + 1;
|
return to + 1;
|
||||||
@ -2782,7 +2778,7 @@ public:
|
|||||||
{
|
{
|
||||||
return type_handler_priv()->type_limits_int();
|
return type_handler_priv()->type_limits_int();
|
||||||
}
|
}
|
||||||
uchar *pack(uchar* to, const uchar *from, uint) override
|
uchar *pack(uchar* to, const uchar *from) const override
|
||||||
{ return pack_int16(to, from); }
|
{ return pack_int16(to, from); }
|
||||||
|
|
||||||
const uchar *unpack(uchar* to, const uchar *from,
|
const uchar *unpack(uchar* to, const uchar *from,
|
||||||
@ -2829,9 +2825,9 @@ public:
|
|||||||
{
|
{
|
||||||
return type_handler_priv()->type_limits_int();
|
return type_handler_priv()->type_limits_int();
|
||||||
}
|
}
|
||||||
uchar *pack(uchar* to, const uchar *from, uint max_length) override
|
uchar *pack(uchar* to, const uchar *from) const override
|
||||||
{
|
{
|
||||||
return Field::pack(to, from, max_length);
|
return Field::pack(to, from);
|
||||||
}
|
}
|
||||||
ulonglong get_max_int_value() const override
|
ulonglong get_max_int_value() const override
|
||||||
{
|
{
|
||||||
@ -2881,7 +2877,7 @@ public:
|
|||||||
{
|
{
|
||||||
return type_handler_priv()->type_limits_int();
|
return type_handler_priv()->type_limits_int();
|
||||||
}
|
}
|
||||||
uchar *pack(uchar* to, const uchar *from, uint) override
|
uchar *pack(uchar* to, const uchar *from) const override
|
||||||
{
|
{
|
||||||
return pack_int32(to, from);
|
return pack_int32(to, from);
|
||||||
}
|
}
|
||||||
@ -2942,7 +2938,7 @@ public:
|
|||||||
{
|
{
|
||||||
return type_handler_priv()->type_limits_int();
|
return type_handler_priv()->type_limits_int();
|
||||||
}
|
}
|
||||||
uchar *pack(uchar* to, const uchar *from, uint) override
|
uchar *pack(uchar* to, const uchar *from) const override
|
||||||
{
|
{
|
||||||
return pack_int64(to, from);
|
return pack_int64(to, from);
|
||||||
}
|
}
|
||||||
@ -3404,7 +3400,7 @@ public:
|
|||||||
/* Get TIMESTAMP field value as seconds since begging of Unix Epoch */
|
/* Get TIMESTAMP field value as seconds since begging of Unix Epoch */
|
||||||
my_time_t get_timestamp(const uchar *pos, ulong *sec_part) const override;
|
my_time_t get_timestamp(const uchar *pos, ulong *sec_part) const override;
|
||||||
bool val_native(Native *to) override;
|
bool val_native(Native *to) override;
|
||||||
uchar *pack(uchar *to, const uchar *from, uint) override
|
uchar *pack(uchar *to, const uchar *from) const override
|
||||||
{
|
{
|
||||||
return pack_int32(to, from);
|
return pack_int32(to, from);
|
||||||
}
|
}
|
||||||
@ -3441,8 +3437,8 @@ public:
|
|||||||
}
|
}
|
||||||
decimal_digits_t decimals() const override { return dec; }
|
decimal_digits_t decimals() const override { return dec; }
|
||||||
enum ha_base_keytype key_type() const override { return HA_KEYTYPE_BINARY; }
|
enum ha_base_keytype key_type() const override { return HA_KEYTYPE_BINARY; }
|
||||||
uchar *pack(uchar *to, const uchar *from, uint max_length) override
|
uchar *pack(uchar *to, const uchar *from) const override
|
||||||
{ return Field::pack(to, from, max_length); }
|
{ return Field::pack(to, from); }
|
||||||
const uchar *unpack(uchar* to, const uchar *from, const uchar *from_end,
|
const uchar *unpack(uchar* to, const uchar *from, const uchar *from_end,
|
||||||
uint param_data) override
|
uint param_data) override
|
||||||
{ return Field::unpack(to, from, from_end, param_data); }
|
{ return Field::unpack(to, from, from_end, param_data); }
|
||||||
@ -3654,7 +3650,7 @@ public:
|
|||||||
void sort_string(uchar *buff,uint length) override;
|
void sort_string(uchar *buff,uint length) override;
|
||||||
uint32 pack_length() const override { return 4; }
|
uint32 pack_length() const override { return 4; }
|
||||||
void sql_type(String &str) const override;
|
void sql_type(String &str) const override;
|
||||||
uchar *pack(uchar* to, const uchar *from, uint) override
|
uchar *pack(uchar* to, const uchar *from) const override
|
||||||
{
|
{
|
||||||
return pack_int32(to, from);
|
return pack_int32(to, from);
|
||||||
}
|
}
|
||||||
@ -3975,7 +3971,7 @@ public:
|
|||||||
uint32 pack_length() const override { return 8; }
|
uint32 pack_length() const override { return 8; }
|
||||||
bool get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate) override
|
bool get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate) override
|
||||||
{ return Field_datetime0::get_TIME(ltime, ptr, fuzzydate); }
|
{ return Field_datetime0::get_TIME(ltime, ptr, fuzzydate); }
|
||||||
uchar *pack(uchar* to, const uchar *from, uint) override
|
uchar *pack(uchar* to, const uchar *from) const override
|
||||||
{
|
{
|
||||||
return pack_int64(to, from);
|
return pack_int64(to, from);
|
||||||
}
|
}
|
||||||
@ -4010,8 +4006,8 @@ public:
|
|||||||
enum ha_base_keytype key_type() const override final { return HA_KEYTYPE_BINARY; }
|
enum ha_base_keytype key_type() const override final { return HA_KEYTYPE_BINARY; }
|
||||||
void make_send_field(Send_field *field) override final;
|
void make_send_field(Send_field *field) override final;
|
||||||
bool send(Protocol *protocol) override final;
|
bool send(Protocol *protocol) override final;
|
||||||
uchar *pack(uchar *to, const uchar *from, uint max_length) override final
|
uchar *pack(uchar *to, const uchar *from) const override final
|
||||||
{ return Field::pack(to, from, max_length); }
|
{ return Field::pack(to, from); }
|
||||||
const uchar *unpack(uchar* to, const uchar *from, const uchar *from_end,
|
const uchar *unpack(uchar* to, const uchar *from, const uchar *from_end,
|
||||||
uint param_data) override final
|
uint param_data) override final
|
||||||
{ return Field::unpack(to, from, from_end, param_data); }
|
{ return Field::unpack(to, from, from_end, param_data); }
|
||||||
@ -4216,7 +4212,7 @@ public:
|
|||||||
void sql_type(String &str) const override;
|
void sql_type(String &str) const override;
|
||||||
void sql_rpl_type(String*) const override;
|
void sql_rpl_type(String*) const override;
|
||||||
bool is_equal(const Column_definition &new_field) const override;
|
bool is_equal(const Column_definition &new_field) const override;
|
||||||
uchar *pack(uchar *to, const uchar *from, uint max_length) override;
|
uchar *pack(uchar *to, const uchar *from) const override;
|
||||||
const uchar *unpack(uchar* to, const uchar *from, const uchar *from_end,
|
const uchar *unpack(uchar* to, const uchar *from, const uchar *from_end,
|
||||||
uint param_data) override;
|
uint param_data) override;
|
||||||
uint pack_length_from_metadata(uint field_metadata) const override
|
uint pack_length_from_metadata(uint field_metadata) const override
|
||||||
@ -4229,8 +4225,12 @@ public:
|
|||||||
bool compatible_field_size(uint field_metadata, const Relay_log_info *rli,
|
bool compatible_field_size(uint field_metadata, const Relay_log_info *rli,
|
||||||
uint16 mflags, int *order_var) const override;
|
uint16 mflags, int *order_var) const override;
|
||||||
uint row_pack_length() const override { return field_length; }
|
uint row_pack_length() const override { return field_length; }
|
||||||
uint packed_col_length(const uchar *to, uint length) override;
|
uint32 max_data_length() const override
|
||||||
uint max_packed_col_length(uint max_length) override;
|
{
|
||||||
|
return field_length;
|
||||||
|
}
|
||||||
|
uint packed_col_length() const override;
|
||||||
|
uint max_packed_col_length(uint max_length) const override;
|
||||||
uint size_of() const override { return sizeof *this; }
|
uint size_of() const override { return sizeof *this; }
|
||||||
bool has_charset() const override { return charset() != &my_charset_bin; }
|
bool has_charset() const override { return charset() != &my_charset_bin; }
|
||||||
Field *make_new_field(MEM_ROOT *root, TABLE *new_table, bool keep_type)
|
Field *make_new_field(MEM_ROOT *root, TABLE *new_table, bool keep_type)
|
||||||
@ -4263,7 +4263,7 @@ public:
|
|||||||
return length_bytes == 1 ? (uint) *ptr_arg : uint2korr(ptr_arg);
|
return length_bytes == 1 ? (uint) *ptr_arg : uint2korr(ptr_arg);
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
void store_length(uint32 number)
|
void store_length(uint32 number) const
|
||||||
{
|
{
|
||||||
if (length_bytes == 1)
|
if (length_bytes == 1)
|
||||||
*ptr= (uchar) number;
|
*ptr= (uchar) number;
|
||||||
@ -4311,6 +4311,10 @@ public:
|
|||||||
uint row_pack_length() const override { return field_length; }
|
uint row_pack_length() const override { return field_length; }
|
||||||
bool zero_pack() const override { return false; }
|
bool zero_pack() const override { return false; }
|
||||||
int reset() override { bzero(ptr,field_length+length_bytes); return 0; }
|
int reset() override { bzero(ptr,field_length+length_bytes); return 0; }
|
||||||
|
uint32 max_data_length() const override
|
||||||
|
{
|
||||||
|
return field_length + (field_length > 255 ? 2 : 1);
|
||||||
|
}
|
||||||
uint32 pack_length() const override
|
uint32 pack_length() const override
|
||||||
{ return (uint32) field_length+length_bytes; }
|
{ return (uint32) field_length+length_bytes; }
|
||||||
uint32 key_length() const override { return (uint32) field_length; }
|
uint32 key_length() const override { return (uint32) field_length; }
|
||||||
@ -4348,15 +4352,15 @@ public:
|
|||||||
void set_key_image(const uchar *buff,uint length) override;
|
void set_key_image(const uchar *buff,uint length) override;
|
||||||
void sql_type(String &str) const override;
|
void sql_type(String &str) const override;
|
||||||
void sql_rpl_type(String*) const override;
|
void sql_rpl_type(String*) const override;
|
||||||
uchar *pack(uchar *to, const uchar *from, uint max_length) override;
|
uchar *pack(uchar *to, const uchar *from) const override;
|
||||||
const uchar *unpack(uchar* to, const uchar *from, const uchar *from_end,
|
const uchar *unpack(uchar* to, const uchar *from, const uchar *from_end,
|
||||||
uint param_data) override;
|
uint param_data) override;
|
||||||
int cmp_binary(const uchar *a,const uchar *b, uint32 max_length=~0U) const
|
int cmp_binary(const uchar *a,const uchar *b, uint32 max_length=~0U) const
|
||||||
override;
|
override;
|
||||||
int key_cmp(const uchar *,const uchar*) const override;
|
int key_cmp(const uchar *,const uchar*) const override;
|
||||||
int key_cmp(const uchar *str, uint length) const override;
|
int key_cmp(const uchar *str, uint length) const override;
|
||||||
uint packed_col_length(const uchar *to, uint length) override;
|
uint packed_col_length() const override;
|
||||||
uint max_packed_col_length(uint max_length) override;
|
uint max_packed_col_length(uint max_length) const override;
|
||||||
uint32 data_length() override;
|
uint32 data_length() override;
|
||||||
uint size_of() const override { return sizeof *this; }
|
uint size_of() const override { return sizeof *this; }
|
||||||
bool has_charset() const override
|
bool has_charset() const override
|
||||||
@ -4677,8 +4681,8 @@ public:
|
|||||||
bzero((uchar*) &read_value, sizeof read_value);
|
bzero((uchar*) &read_value, sizeof read_value);
|
||||||
}
|
}
|
||||||
uint32 get_field_buffer_size() { return value.alloced_length(); }
|
uint32 get_field_buffer_size() { return value.alloced_length(); }
|
||||||
void store_length(uchar *i_ptr, uint i_packlength, uint32 i_number);
|
void store_length(uchar *i_ptr, uint i_packlength, uint32 i_number) const;
|
||||||
void store_length(size_t number)
|
void store_length(size_t number) const
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(number < UINT_MAX32);
|
DBUG_ASSERT(number < UINT_MAX32);
|
||||||
store_length(ptr, packlength, (uint32)number);
|
store_length(ptr, packlength, (uint32)number);
|
||||||
@ -4778,11 +4782,11 @@ public:
|
|||||||
/* Set value pointer. Lengths are not important */
|
/* Set value pointer. Lengths are not important */
|
||||||
value.reset((char*) data, 1, 1, &my_charset_bin);
|
value.reset((char*) data, 1, 1, &my_charset_bin);
|
||||||
}
|
}
|
||||||
uchar *pack(uchar *to, const uchar *from, uint max_length) override;
|
uchar *pack(uchar *to, const uchar *from) const override;
|
||||||
const uchar *unpack(uchar *to, const uchar *from, const uchar *from_end,
|
const uchar *unpack(uchar *to, const uchar *from, const uchar *from_end,
|
||||||
uint param_data) override;
|
uint param_data) override;
|
||||||
uint packed_col_length(const uchar *col_ptr, uint length) override;
|
uint packed_col_length() const override;
|
||||||
uint max_packed_col_length(uint max_length) override;
|
uint max_packed_col_length(uint max_length) const override;
|
||||||
void free() override
|
void free() override
|
||||||
{
|
{
|
||||||
value.free();
|
value.free();
|
||||||
@ -4972,7 +4976,7 @@ public:
|
|||||||
{
|
{
|
||||||
return Type_extra_attributes(m_typelib);
|
return Type_extra_attributes(m_typelib);
|
||||||
}
|
}
|
||||||
uchar *pack(uchar *to, const uchar *from, uint max_length) override;
|
uchar *pack(uchar *to, const uchar *from) const override;
|
||||||
const uchar *unpack(uchar *to, const uchar *from, const uchar *from_end,
|
const uchar *unpack(uchar *to, const uchar *from, const uchar *from_end,
|
||||||
uint param_data) override;
|
uint param_data) override;
|
||||||
|
|
||||||
@ -5177,7 +5181,7 @@ public:
|
|||||||
bool compatible_field_size(uint metadata, const Relay_log_info *rli,
|
bool compatible_field_size(uint metadata, const Relay_log_info *rli,
|
||||||
uint16 mflags, int *order_var) const override;
|
uint16 mflags, int *order_var) const override;
|
||||||
void sql_type(String &str) const override;
|
void sql_type(String &str) const override;
|
||||||
uchar *pack(uchar *to, const uchar *from, uint max_length) override;
|
uchar *pack(uchar *to, const uchar *from) const override;
|
||||||
const uchar *unpack(uchar *to, const uchar *from,
|
const uchar *unpack(uchar *to, const uchar *from,
|
||||||
const uchar *from_end, uint param_data) override;
|
const uchar *from_end, uint param_data) override;
|
||||||
int set_default() override;
|
int set_default() override;
|
||||||
|
@ -103,8 +103,7 @@ pack_row(TABLE *table, MY_BITMAP const* cols,
|
|||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
const uchar *old_pack_ptr= pack_ptr;
|
const uchar *old_pack_ptr= pack_ptr;
|
||||||
#endif
|
#endif
|
||||||
pack_ptr= field->pack(pack_ptr, field->ptr + offset,
|
pack_ptr= field->pack(pack_ptr, field->ptr + offset);
|
||||||
field->max_data_length());
|
|
||||||
DBUG_PRINT("debug", ("field: %s; real_type: %d, pack_ptr: %p;"
|
DBUG_PRINT("debug", ("field: %s; real_type: %d, pack_ptr: %p;"
|
||||||
" pack_ptr':%p; bytes: %d",
|
" pack_ptr':%p; bytes: %d",
|
||||||
field->field_name.str, field->real_type(),
|
field->field_name.str, field->real_type(),
|
||||||
|
@ -719,10 +719,10 @@ public:
|
|||||||
FbtImpl::binary_length(), &my_charset_bin);
|
FbtImpl::binary_length(), &my_charset_bin);
|
||||||
}
|
}
|
||||||
|
|
||||||
uchar *pack(uchar *to, const uchar *from, uint max_length) override
|
uchar *pack(uchar *to, const uchar *from) const override
|
||||||
{
|
{
|
||||||
DBUG_PRINT("debug", ("Packing field '%s'", field_name.str));
|
DBUG_PRINT("debug", ("Packing field '%s'", field_name.str));
|
||||||
return FbtImpl::pack(to, from, max_length);
|
return FbtImpl::pack(to, from);
|
||||||
}
|
}
|
||||||
|
|
||||||
const uchar *unpack(uchar *to, const uchar *from, const uchar *from_end,
|
const uchar *unpack(uchar *to, const uchar *from, const uchar *from_end,
|
||||||
@ -731,14 +731,15 @@ public:
|
|||||||
return FbtImpl::unpack(to, from, from_end, param_data);
|
return FbtImpl::unpack(to, from, from_end, param_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint max_packed_col_length(uint max_length) override
|
uint max_packed_col_length(uint max_length) const override
|
||||||
{
|
{
|
||||||
return StringPack::max_packed_col_length(max_length);
|
return StringPack::max_packed_col_length(max_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint packed_col_length(const uchar *fbt_ptr, uint length) override
|
uint packed_col_length() const override
|
||||||
{
|
{
|
||||||
return StringPack::packed_col_length(fbt_ptr, length);
|
return StringPack(&my_charset_bin, pack_length()).
|
||||||
|
packed_col_length(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint size_of() const override { return sizeof(*this); }
|
uint size_of() const override { return sizeof(*this); }
|
||||||
|
@ -150,9 +150,9 @@ public:
|
|||||||
Used in Field::pack(), and in filesort to store the addon fields.
|
Used in Field::pack(), and in filesort to store the addon fields.
|
||||||
By default, do what BINARY(N) does.
|
By default, do what BINARY(N) does.
|
||||||
*/
|
*/
|
||||||
static uchar *pack(uchar *to, const uchar *from, uint max_length)
|
static uchar *pack(uchar *to, const uchar *from)
|
||||||
{
|
{
|
||||||
return StringPack(&my_charset_bin, binary_length()).pack(to, from, max_length);
|
return StringPack(&my_charset_bin, binary_length()).pack(to, from);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -20,17 +20,34 @@
|
|||||||
#include "sql_type_string.h"
|
#include "sql_type_string.h"
|
||||||
|
|
||||||
|
|
||||||
uchar *
|
// Trim trailing spaces for CHAR or 0x00 bytes for BINARY
|
||||||
StringPack::pack(uchar *to, const uchar *from, uint max_length) const
|
uint StringPack::rtrimmed_length(const char *from) const
|
||||||
{
|
{
|
||||||
size_t length= MY_MIN(m_octet_length, max_length);
|
DBUG_PRINT("debug", ("length: %u ", (uint) m_octet_length));
|
||||||
size_t local_char_length= char_length();
|
|
||||||
DBUG_PRINT("debug", ("length: %zu ", length));
|
|
||||||
|
|
||||||
if (length > local_char_length)
|
if (mbmaxlen() > 1)
|
||||||
local_char_length= charset()->charpos(from, from + length,
|
{
|
||||||
local_char_length);
|
/*
|
||||||
set_if_smaller(length, local_char_length);
|
Suppose we have CHAR(100) CHARACTER SET utf8mb4.
|
||||||
|
Its octet_length is 400.
|
||||||
|
- In case of ASCII characters only, the leftmost 100 bytes
|
||||||
|
contain real data, the other 300 bytes are padding spaces.
|
||||||
|
- In case of 100 2-byte characters, the leftmost 200 bytes
|
||||||
|
contain real data, the other 200 bytes are padding spaces.
|
||||||
|
- All 400 bytes contain real data (without padding spaces)
|
||||||
|
only in case of 100 4-byte characters, which is a rare scenario.
|
||||||
|
|
||||||
|
There are two approaches possible to trim the data:
|
||||||
|
1. Left-to-right: call charpos() to find the end of the 100th
|
||||||
|
character, then switch to a right-to-left loop to trim trailing spaces.
|
||||||
|
2. Right-to-left: trim characters from the position "from+400" towards
|
||||||
|
the beginning.
|
||||||
|
|
||||||
|
N1 should be faster in an average case, and is much faster for pure ASCII.
|
||||||
|
*/
|
||||||
|
size_t length= charset()->charpos(from, from+m_octet_length, char_length());
|
||||||
|
return (uint) charset()->lengthsp((const char*) from, length);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TODO: change charset interface to add a new function that does
|
TODO: change charset interface to add a new function that does
|
||||||
@ -38,13 +55,17 @@ StringPack::pack(uchar *to, const uchar *from, uint max_length) const
|
|||||||
(this is for not packing padding adding bytes in BINARY
|
(this is for not packing padding adding bytes in BINARY
|
||||||
fields).
|
fields).
|
||||||
*/
|
*/
|
||||||
if (mbmaxlen() == 1)
|
size_t length= m_octet_length;
|
||||||
{
|
while (length && from[length - 1] == charset()->pad_char)
|
||||||
while (length && from[length-1] == charset()->pad_char)
|
|
||||||
length --;
|
length --;
|
||||||
}
|
return (uint) length;
|
||||||
else
|
}
|
||||||
length= charset()->lengthsp((const char*) from, length);
|
|
||||||
|
|
||||||
|
uchar *
|
||||||
|
StringPack::pack(uchar *to, const uchar *from) const
|
||||||
|
{
|
||||||
|
size_t length= rtrimmed_length((const char *) from);
|
||||||
|
|
||||||
// Length always stored little-endian
|
// Length always stored little-endian
|
||||||
*to++= (uchar) length;
|
*to++= (uchar) length;
|
||||||
|
@ -23,24 +23,29 @@ class StringPack
|
|||||||
CHARSET_INFO *charset() const { return m_cs; }
|
CHARSET_INFO *charset() const { return m_cs; }
|
||||||
uint mbmaxlen() const { return m_cs->mbmaxlen; };
|
uint mbmaxlen() const { return m_cs->mbmaxlen; };
|
||||||
uint32 char_length() const { return m_octet_length / mbmaxlen(); }
|
uint32 char_length() const { return m_octet_length / mbmaxlen(); }
|
||||||
|
// Trim trailing spaces for CHAR or 0x00 bytes for BINARY
|
||||||
|
uint rtrimmed_length(const char *from) const;
|
||||||
|
static uint length_bytes(uint max_length)
|
||||||
|
{
|
||||||
|
return max_length > 255 ? 2 : 1;
|
||||||
|
}
|
||||||
public:
|
public:
|
||||||
StringPack(CHARSET_INFO *cs, uint32 octet_length)
|
StringPack(CHARSET_INFO *cs, uint32 octet_length)
|
||||||
:m_cs(cs),
|
:m_cs(cs),
|
||||||
m_octet_length(octet_length)
|
m_octet_length(octet_length)
|
||||||
{ }
|
{ }
|
||||||
uchar *pack(uchar *to, const uchar *from, uint max_length) const;
|
uchar *pack(uchar *to, const uchar *from) const;
|
||||||
const uchar *unpack(uchar *to, const uchar *from, const uchar *from_end,
|
const uchar *unpack(uchar *to, const uchar *from, const uchar *from_end,
|
||||||
uint param_data) const;
|
uint param_data) const;
|
||||||
public:
|
public:
|
||||||
static uint max_packed_col_length(uint max_length)
|
static uint max_packed_col_length(uint max_length)
|
||||||
{
|
{
|
||||||
return (max_length > 255 ? 2 : 1) + max_length;
|
return length_bytes(max_length) + max_length;
|
||||||
}
|
}
|
||||||
static uint packed_col_length(const uchar *data_ptr, uint length)
|
uint packed_col_length(const uchar *data_ptr) const
|
||||||
{
|
{
|
||||||
if (length > 255)
|
return length_bytes(m_octet_length) +
|
||||||
return uint2korr(data_ptr)+2;
|
rtrimmed_length((const char *) data_ptr);
|
||||||
return (uint) *data_ptr + 1;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user