From b0938c2d1822514f91e6b3e90478783f2b8463af Mon Sep 17 00:00:00 2001 From: xiongjiwei Date: Tue, 28 Sep 2021 15:42:46 +0800 Subject: [PATCH] coprocessor: add gbk_bin support in coprocessor (#10996) * add gbk_bin support Signed-off-by: xiongjiwei * address comments Signed-off-by: xiongjiwei --- .../src/codec/collation/charset.rs | 3 + .../src/codec/collation/collator/gbk_bin.data | Bin 0 -> 131072 bytes .../src/codec/collation/collator/gbk_bin.rs | 66 ++++++++++++++++++ .../src/codec/collation/collator/mod.rs | 48 ++++++++++++- .../src/codec/collation/mod.rs | 1 + .../tidb_query_datatype/src/def/field_type.rs | 2 + 6 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 components/tidb_query_datatype/src/codec/collation/collator/gbk_bin.data create mode 100644 components/tidb_query_datatype/src/codec/collation/collator/gbk_bin.rs diff --git a/components/tidb_query_datatype/src/codec/collation/charset.rs b/components/tidb_query_datatype/src/codec/collation/charset.rs index 9982582225f..5aeca5089c1 100644 --- a/components/tidb_query_datatype/src/codec/collation/charset.rs +++ b/components/tidb_query_datatype/src/codec/collation/charset.rs @@ -47,3 +47,6 @@ impl Charset for CharsetUtf8mb4 { }) } } + +// gbk character data actually stored with utf8mb4 character encoding. +pub type CharsetGbk = CharsetUtf8mb4; diff --git a/components/tidb_query_datatype/src/codec/collation/collator/gbk_bin.data b/components/tidb_query_datatype/src/codec/collation/collator/gbk_bin.data new file mode 100644 index 0000000000000000000000000000000000000000..8422aadbf784f3233367d90006770dacbc4792f8 GIT binary patch literal 131072 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ɲSD;H&sr;4{8{_8Q;N$ni~l3*YvO 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 X|NHYV^)Jb-1ktapMA57N&e{GCcB5l3 literal 0 HcmV?d00001 diff --git a/components/tidb_query_datatype/src/codec/collation/collator/gbk_bin.rs b/components/tidb_query_datatype/src/codec/collation/collator/gbk_bin.rs new file mode 100644 index 00000000000..ebc1e85e28b --- /dev/null +++ b/components/tidb_query_datatype/src/codec/collation/collator/gbk_bin.rs @@ -0,0 +1,66 @@ +// Copyright 2021 TiKV Project Authors. Licensed under Apache-2.0. + +use super::*; + +/// Collator for `gbk_bin` collation with padding behavior (trims right spaces). +#[derive(Debug)] +pub struct CollatorGbkBin; + +impl Collator for CollatorGbkBin { + type Charset = CharsetGbk; + type Weight = u16; + + const IS_CASE_INSENSITIVE: bool = false; + + #[inline] + fn char_weight(ch: char) -> Self::Weight { + // All GBK code point are in BMP, if the incoming character is not, convert it to '?'. + // This should not happened. + let r = ch as usize; + if r > 0xFFFF { + return '?' as u16; + } + + (&GBK_BIN_TABLE[r * 2..r * 2 + 2]).read_u16().unwrap() + } + + #[inline] + fn write_sort_key(writer: &mut W, bstr: &[u8]) -> Result { + let s = str::from_utf8(bstr)?.trim_end_matches(PADDING_SPACE); + let mut n = 0; + for ch in s.chars() { + let weight = Self::char_weight(ch); + if weight > 0xFF { + writer.write_u16_be(weight)?; + n += 2; + } else { + writer.write_u8(weight as u8)?; + n += 1; + } + } + Ok(n * std::mem::size_of::()) + } + + #[inline] + fn sort_compare(a: &[u8], b: &[u8]) -> Result { + let sa = str::from_utf8(a)?.trim_end_matches(PADDING_SPACE); + let sb = str::from_utf8(b)?.trim_end_matches(PADDING_SPACE); + Ok(sa + .chars() + .map(Self::char_weight) + .cmp(sb.chars().map(Self::char_weight))) + } + + #[inline] + fn sort_hash(state: &mut H, bstr: &[u8]) -> Result<()> { + let s = str::from_utf8(bstr)?.trim_end_matches(PADDING_SPACE); + for ch in s.chars().map(Self::char_weight) { + ch.hash(state); + } + Ok(()) + } +} + +// GBK_BIN_TABLE are the encoding tables from Unicode to GBK code, it is totally the same with golang's GBK encoding. +// If there is no mapping code in GBK, use 0x3F(?) instead. It should not happened. +static GBK_BIN_TABLE: &[u8; (0xffff + 1) * 2] = include_bytes!("gbk_bin.data"); diff --git a/components/tidb_query_datatype/src/codec/collation/collator/mod.rs b/components/tidb_query_datatype/src/codec/collation/collator/mod.rs index e2ddb1a4e3f..33697ff396e 100644 --- a/components/tidb_query_datatype/src/codec/collation/collator/mod.rs +++ b/components/tidb_query_datatype/src/codec/collation/collator/mod.rs @@ -1,12 +1,14 @@ // Copyright 2020 TiKV Project Authors. Licensed under Apache-2.0. mod binary; +mod gbk_bin; mod latin1_bin; mod utf8mb4_binary; mod utf8mb4_general_ci; mod utf8mb4_unicode_ci; pub use binary::*; +pub use gbk_bin::*; pub use latin1_bin::*; pub use utf8mb4_binary::*; pub use utf8mb4_general_ci::*; @@ -42,9 +44,10 @@ mod tests { (Collation::Utf8Mb4GeneralCi, 2), (Collation::Utf8Mb4UnicodeCi, 3), (Collation::Latin1Bin, 4), + (Collation::GbkBin, 5), ]; let cases = vec![ - // (sa, sb, [Utf8Mb4Bin, Utf8Mb4BinNoPadding, Utf8Mb4GeneralCi, Utf8Mb4UnicodeCi]) + // (sa, sb, [Utf8Mb4Bin, Utf8Mb4BinNoPadding, Utf8Mb4GeneralCi, Utf8Mb4UnicodeCi, GBKBin]) ( "a".as_bytes(), "a".as_bytes(), @@ -54,6 +57,7 @@ mod tests { Ordering::Equal, Ordering::Equal, Ordering::Equal, + Ordering::Equal, ], ), ( @@ -65,6 +69,7 @@ mod tests { Ordering::Equal, Ordering::Equal, Ordering::Equal, + Ordering::Equal, ], ), ( @@ -76,6 +81,7 @@ mod tests { Ordering::Equal, Ordering::Equal, Ordering::Greater, + Ordering::Greater, ], ), ( @@ -87,6 +93,7 @@ mod tests { Ordering::Greater, Ordering::Greater, Ordering::Greater, + Ordering::Greater, ], ), ( @@ -98,6 +105,7 @@ mod tests { Ordering::Less, Ordering::Less, Ordering::Less, + Ordering::Less, ], ), ( @@ -109,6 +117,7 @@ mod tests { Ordering::Equal, Ordering::Equal, Ordering::Less, + Ordering::Less, ], ), ( @@ -120,6 +129,7 @@ mod tests { Ordering::Equal, Ordering::Equal, Ordering::Less, + Ordering::Less, ], ), ( @@ -131,6 +141,19 @@ mod tests { Ordering::Less, Ordering::Equal, Ordering::Greater, + Ordering::Less, + ], + ), + ( + "中文".as_bytes(), + "汉字".as_bytes(), + [ + Ordering::Less, + Ordering::Less, + Ordering::Less, + Ordering::Less, + Ordering::Less, + Ordering::Greater, ], ), ]; @@ -185,9 +208,10 @@ mod tests { (Collation::Utf8Mb4GeneralCi, 2), (Collation::Utf8Mb4UnicodeCi, 3), (Collation::Latin1Bin, 4), + (Collation::GbkBin, 5), ]; let cases = vec![ - // (str, [Utf8Mb4Bin, Utf8Mb4BinNoPadding, Utf8Mb4GeneralCi, Utf8Mb4UnicodeCi]) + // (str, [Utf8Mb4Bin, Utf8Mb4BinNoPadding, Utf8Mb4GeneralCi, Utf8Mb4UnicodeCi, GBKbin]) ( "a", [ @@ -196,6 +220,7 @@ mod tests { vec![0x00, 0x41], vec![0x0E, 0x33], vec![0x61], + vec![0x61], ], ), ( @@ -206,6 +231,7 @@ mod tests { vec![0x00, 0x41], vec![0x0E, 0x33], vec![0x41], + vec![0x41], ], ), ( @@ -216,6 +242,7 @@ mod tests { vec![0x00, 0x41], vec![0x0E, 0x33], vec![0x41], + vec![0x41], ], ), ( @@ -226,6 +253,7 @@ mod tests { vec![0xff, 0xfd], vec![0xff, 0xfd], vec![0xF0, 0x9F, 0x98, 0x83], + vec![0x3F], ], ), ( @@ -258,6 +286,10 @@ mod tests { 0x9D, 0x8C, 0x86, 0x20, 0x62, 0x61, 0x7A, 0x20, 0xE2, 0x98, 0x83, 0x20, 0x71, 0x75, 0x78, ], + vec![ + 0x46, 0x6f, 0x6f, 0x20, 0x3f, 0x20, 0x62, 0x61, 0x72, 0x20, 0x3f, 0x20, + 0x62, 0x61, 0x7a, 0x20, 0x3f, 0x20, 0x71, 0x75, 0x78, + ], ], ), ( @@ -271,6 +303,18 @@ mod tests { 0x13, 0xAB, 0x13, 0xB7, ], vec![0xEF, 0xB7, 0xBB], + vec![0x3f], + ], + ), + ( + "中文", + [ + vec![0xE4, 0xB8, 0xAD, 0xE6, 0x96, 0x87], + vec![0xE4, 0xB8, 0xAD, 0xE6, 0x96, 0x87], + vec![0x4E, 0x2D, 0x65, 0x87], + vec![0xFB, 0x40, 0xCE, 0x2D, 0xFB, 0x40, 0xE5, 0x87], + vec![0xE4, 0xB8, 0xAD, 0xE6, 0x96, 0x87], + vec![0xD6, 0xD0, 0xCE, 0xC4], ], ), ]; diff --git a/components/tidb_query_datatype/src/codec/collation/mod.rs b/components/tidb_query_datatype/src/codec/collation/mod.rs index d1559e56178..e1e8d731362 100644 --- a/components/tidb_query_datatype/src/codec/collation/mod.rs +++ b/components/tidb_query_datatype/src/codec/collation/mod.rs @@ -27,6 +27,7 @@ macro_rules! match_template_collator { Utf8Mb4GeneralCi => CollatorUtf8Mb4GeneralCi, Utf8Mb4UnicodeCi => CollatorUtf8Mb4UnicodeCi, Latin1Bin => CollatorLatin1Bin, + GbkBin => CollatorGbkBin, ], $($tail)* } diff --git a/components/tidb_query_datatype/src/def/field_type.rs b/components/tidb_query_datatype/src/def/field_type.rs index 3a7a98fb132..d6e77e6b2d6 100644 --- a/components/tidb_query_datatype/src/def/field_type.rs +++ b/components/tidb_query_datatype/src/def/field_type.rs @@ -111,6 +111,7 @@ pub enum Collation { Utf8Mb4GeneralCi = -45, Utf8Mb4UnicodeCi = -224, Latin1Bin = -47, + GbkBin = -87, } impl Collation { @@ -126,6 +127,7 @@ impl Collation { -47 => Ok(Collation::Latin1Bin), -63 | 63 | 47 => Ok(Collation::Binary), -224 | -192 => Ok(Collation::Utf8Mb4UnicodeCi), + -87 => Ok(Collation::GbkBin), n if n >= 0 => Ok(Collation::Utf8Mb4BinNoPadding), n => Err(DataTypeError::UnsupportedCollation { code: n }), }