Skip to content

Commit

Permalink
feat(tianmu): impl load bit type #919
Browse files Browse the repository at this point in the history
[summary]
impl load bit, including empty space and null value, to keep the src code integrity, we add
an bit parse function just like others numeric does.
  • Loading branch information
hustjieke committed Dec 23, 2022
1 parent 311ca94 commit 5a4e4b5
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 2 deletions.
21 changes: 21 additions & 0 deletions mysql-test/suite/tianmu/r/bit_type.result
Original file line number Diff line number Diff line change
Expand Up @@ -124,4 +124,25 @@ ERROR 22003: BIGINT UNSIGNED value is out of range in '(`test`.`bit2`.`a` * 1234
select a * 12345678910111213123456 from bit2;
ERROR HY000: Numeric result of an expression is too large and cannot be handled by tianmu. Please use an explicit cast to a data type handled by tianmu, e.g. CAST(<expr> AS DECIMAL(18,6)).
drop table bit2;
CREATE TABLE `bit_test` (
`bit1` bit(1) DEFAULT NULL,
`bit2` bit(2) DEFAULT NULL,
`bit8` bit(8) DEFAULT NULL,
`bit16` bit(16) DEFAULT NULL,
`bit32` bit(32) DEFAULT NULL,
`bit63` bit(63) DEFAULT NULL
) ENGINE=TIANMU DEFAULT CHARSET=utf8mb4;
LOAD DATA local INFILE 'MYSQL_TEST_DIR/suite/tianmu/std_data/bit_test.txt' INTO TABLE bit_test fields TERMINATED BY ',' (@var1, @var2, @var3, @var4, @var5, @var6)
SET bit1 = CAST(CONV(MID(@var1, 3, LENGTH(@var1)-3), 2, 10) AS UNSIGNED),
bit2 = CAST(CONV(MID(@var2, 3, LENGTH(@var2)-3), 2, 10) AS UNSIGNED),
bit8 = CAST(CONV(MID(@var3, 3, LENGTH(@var3)-3), 2, 10) AS UNSIGNED),
bit16 = CAST(CONV(MID(@var4, 3, LENGTH(@var4)-3), 2, 10) AS UNSIGNED),
bit32 = CAST(CONV(MID(@var5, 3, LENGTH(@var5)-3), 2, 10) AS UNSIGNED),
bit63 = CAST(CONV(MID(@var6, 3, LENGTH(@var6)-3), 2, 10) AS UNSIGNED);
select bit1+0, bit2+0, bit8+0, bit16+0, bit32+0, bit63+0 from bit_test;
bit1+0 bit2+0 bit8+0 bit16+0 bit32+0 bit63+0
NULL NULL NULL NULL NULL NULL
0 0 0 0 0 0
1 2 7 47 3071 268435455
drop table bit_test;
drop database test_bit;
3 changes: 3 additions & 0 deletions mysql-test/suite/tianmu/std_data/bit_test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
,,,,,
NULL,NULL,NULL,NULL,NULL,NULL
b'11111111111',b'101,b'111',b'101111',b'101111111111',b'1111111111111111111111111111'
24 changes: 24 additions & 0 deletions mysql-test/suite/tianmu/t/bit_type.test
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,28 @@ select a * 12345678910111213123 from bit2;
--error 1105
select a * 12345678910111213123456 from bit2;
drop table bit2;

#load bit data
CREATE TABLE `bit_test` (
`bit1` bit(1) DEFAULT NULL,
`bit2` bit(2) DEFAULT NULL,
`bit8` bit(8) DEFAULT NULL,
`bit16` bit(16) DEFAULT NULL,
`bit32` bit(32) DEFAULT NULL,
`bit63` bit(63) DEFAULT NULL
) ENGINE=TIANMU DEFAULT CHARSET=utf8mb4;

--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
eval LOAD DATA local INFILE '$MYSQL_TEST_DIR/suite/tianmu/std_data/bit_test.txt' INTO TABLE bit_test fields TERMINATED BY ',' (@var1, @var2, @var3, @var4, @var5, @var6)
SET bit1 = CAST(CONV(MID(@var1, 3, LENGTH(@var1)-3), 2, 10) AS UNSIGNED),
bit2 = CAST(CONV(MID(@var2, 3, LENGTH(@var2)-3), 2, 10) AS UNSIGNED),
bit8 = CAST(CONV(MID(@var3, 3, LENGTH(@var3)-3), 2, 10) AS UNSIGNED),
bit16 = CAST(CONV(MID(@var4, 3, LENGTH(@var4)-3), 2, 10) AS UNSIGNED),
bit32 = CAST(CONV(MID(@var5, 3, LENGTH(@var5)-3), 2, 10) AS UNSIGNED),
bit63 = CAST(CONV(MID(@var6, 3, LENGTH(@var6)-3), 2, 10) AS UNSIGNED);

select bit1+0, bit2+0, bit8+0, bit16+0, bit32+0, bit63+0 from bit_test;

drop table bit_test;

drop database test_bit;
2 changes: 1 addition & 1 deletion storage/tianmu/loader/parsing_strategy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ ParsingStrategy::ParseResult ParsingStrategy::GetOneRow(const char *const buf, s
str = vec_field_Str_list_[index_of_field];
}
String *res = field->str_result(str);
DEBUG_ASSERT(res);
// DEBUG_ASSERT(res);
if (res && res != str) {
str->copy(*res);
}
Expand Down
45 changes: 45 additions & 0 deletions storage/tianmu/types/value_parser4txt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,51 @@ common::ErrorCode ValueParserForText::ParseBigIntAdapter(const BString &tianmu_s
return return_code;
}

// Unlike the other numeric values, the exactly bit value has already stored int Field_bit in GetOneRow() function,
// and make the string buffer to arg tianmu_s, so this function just convert the string value to int64 back.
common::ErrorCode ValueParserForText::ParseBitAdapter(const BString &tianmu_s, int64_t &out) {
char *val_ptr = tianmu_s.val_;
int len = tianmu_s.len_;
// No matter null value or not, the value stored in char buffer at least one byte and up to 8 bytes.
// calculated by len = (prec+7)/8
DEBUG_ASSERT(len >=1 && len <=8);

// The parse code may never go here, but we still check null value for integrity.
if (tianmu_s.Equals("nullptr", 4)) {
out = common::NULL_VALUE_64;
return common::ErrorCode::SUCCESS;
}

switch (len) {
case 1: {
out = mi_uint1korr(val_ptr);break;
}
case 2: {
out = mi_uint2korr(val_ptr);break;
}
case 3: {
out = mi_uint3korr(val_ptr);break;
}
case 4: {
out = mi_uint4korr(val_ptr);break;
}
case 5: {
out = mi_uint5korr(val_ptr);break;
}
case 6: {
out = mi_uint6korr(val_ptr);break;
}
case 7: {
out = mi_uint7korr(val_ptr);break;
}
default: {
out = mi_uint8korr(val_ptr);break;
}
}

return common::ErrorCode::SUCCESS;
}

common::ErrorCode ValueParserForText::ParseDecimal(BString const &tianmu_s, int64_t &out, short precision,
short scale) {
TianmuNum number;
Expand Down
4 changes: 3 additions & 1 deletion storage/tianmu/types/value_parser4txt.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,9 @@ class ValueParserForText {
case common::ColumnType::INT:
return std::bind<common::ErrorCode>(&ParseNumeric, std::placeholders::_1, std::placeholders::_2, at.Type());
case common::ColumnType::BIGINT:
case common::ColumnType::BIT:
return &ParseBigIntAdapter;
case common::ColumnType::BIT:
return &ParseBitAdapter;
case common::ColumnType::DATE:
case common::ColumnType::TIME:
case common::ColumnType::YEAR:
Expand All @@ -62,6 +63,7 @@ class ValueParserForText {

static common::ErrorCode ParseNumeric(BString const &tianmu_s, int64_t &out, common::ColumnType at);
static common::ErrorCode ParseBigIntAdapter(const BString &tianmu_s, int64_t &out);
static common::ErrorCode ParseBitAdapter(const BString &tianmu_s, int64_t &out);
static common::ErrorCode ParseDecimal(BString const &tianmu_s, int64_t &out, short precision, short scale);
static common::ErrorCode ParseDateTimeAdapter(BString const &tianmu_s, int64_t &out, common::ColumnType at);

Expand Down

0 comments on commit 5a4e4b5

Please sign in to comment.