1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

MDEV-27208: Extend CRC32() and implement CRC32C()

We used to define a native unary function CRC32() that computes the CRC-32
of a string using the ISO 3309 polynomial that is being used by zlib
and many others.

Often, a CRC is computed in pieces. To faciliate this, we introduce a
2-ary variant of the function that inputs a previous CRC as the first
argument: CRC32('MariaDB')=CRC32(CRC32('Maria'),'DB').

InnoDB and MyRocks use a different polynomial, which was implemented
in SSE4.2 instructions that were introduced in the
Intel Nehalem microarchitecture. This is commonly called CRC-32C
(Castagnoli).

We introduce a native function that uses the Castagnoli polynomial:
CRC32C('MariaDB')=CRC32C(CRC32C('Maria'),'DB'). This allows
SELECT...INTO DUMPFILE to be used for the creation of files with
valid checksums, such as a logically empty InnoDB redo log file
ib_logfile0 corresponding to a particular log sequence number.
This commit is contained in:
Marko Mäkelä
2022-01-21 19:24:00 +02:00
parent b07920b634
commit 5b3ad94c7b
6 changed files with 254 additions and 32 deletions

View File

@ -849,15 +849,58 @@ SELECT CRC32('01234567'), CRC32('012345678');
SELECT CRC32('~!@$%^*'), CRC32('-0.0001');
SELECT CRC32(99999999999999999999999999999999);
SELECT CRC32(-99999999999999999999999999999999);
SELECT CRC32C(NULL), CRC32C(''), CRC32C('MariaDB'), CRC32C('mariadb');
SELECT CRC32(NULL,1),CRC32C(NULL,1), CRC32(1,''), CRC32C(1,'');
SELECT CRC32(42,''),CRC32C(42,''),CRC32('42',''),CRC32C('42','');
SELECT CRC32(42,NULL),CRC32C(42,NULL);
SELECT CRC32 ('5c',''),CRC32 ('5c',0),CRC32 ('5c', '0'),CRC32 ('5c',NULL);
SELECT CRC32C('5c',''),CRC32C('5c',0),CRC32C('5c', '0'),CRC32C('5c',NULL);
SELECT CRC32('MariaDB',NULL),CRC32C('MariaDB',NULL);
SELECT CRC32(CRC32('MySQL'),''),CRC32(CRC32('My'),'SQL'),CRC32(0,'MySQL');
SELECT CRC32C(CRC32C('MariaDB'),''),CRC32C(CRC32C('Maria'),'DB'),CRC32C(0,'MariaDB');
--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
select crc32(0,'My','SQL');
--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
select crc32c(0,'Maria','DB');
--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
select crc32();
--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
select crc32c();
--error ER_WRONG_PARAMETERS_TO_NATIVE_FCT
select crc32('' as empty);
--error ER_WRONG_PARAMETERS_TO_NATIVE_FCT
select crc32c('' as empty);
--error ER_WRONG_PARAMETERS_TO_NATIVE_FCT
select crc32(0, '' as empty);
--error ER_WRONG_PARAMETERS_TO_NATIVE_FCT
select crc32c(0, '' as empty);
--error ER_WRONG_PARAMETERS_TO_NATIVE_FCT
select crc32(0 as zero, '');
--error ER_WRONG_PARAMETERS_TO_NATIVE_FCT
select crc32c(0 as zero, '');
CREATE TEMPORARY TABLE t
(a CHAR(2), i INT UNSIGNED, c INT UNSIGNED AS (CRC32C(i,a)));
INSERT INTO t (a,i) VALUES ('DB',CRC32C('Maria'));
SELECT * FROM t;
DROP TEMPORARY TABLE t;
select crc32(4294967296,''), hex(char(4294967296));
select crc32(1e100,''), hex(char(1e100));
select crc32(10.11,''), hex(char(10.11));
select crc32(-1,''), hex(char(-1));
select crc32('',''), hex(char(''));
select crc32(429496729656755555555555555555555555555555555555555555555555555555555555555555555555555,'a') as x;
# Test cases for using the function in aggregate functions, group-by, having
# and order-by clauses
DROP TABLE IF EXISTS t;
CREATE TABLE t(a INT, b VARCHAR(2));
INSERT INTO t VALUES (1,'a'), (2,'qw'), (1,'t'), (3,'t');
SELECT crc32(SUM(a)) FROM t;
SELECT crc32(AVG(a)) FROM t GROUP BY b;
SELECT crc32(MAX(b)) FROM t GROUP BY a;
SELECT crc32(SUM(a)),crc32c(SUM(a)) FROM t;
SELECT crc32(AVG(a)),crc32c(AVG(a)) FROM t GROUP BY b;
SELECT crc32(MAX(b)),crc32c(MAX(b)) FROM t GROUP BY a;
SELECT a, b, crc32(a) FROM t GROUP BY a,b HAVING crc32(MAX(a))=450215437;
SELECT a,b,concat(a,b),crc32(concat(a,b)) FROM t ORDER BY crc32(concat(a,b));
DROP TABLE t;