Skip to content

Commit

Permalink
feat(tianmu): support agg on bit types stoneatom#919
Browse files Browse the repository at this point in the history
  • Loading branch information
hustjieke committed Dec 20, 2022
1 parent 2b50e52 commit 4ea052c
Show file tree
Hide file tree
Showing 8 changed files with 176 additions and 48 deletions.
65 changes: 65 additions & 0 deletions mysql-test/suite/tianmu/r/bit_type.result
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,68 @@ b+0 BIN(b) OCT(b) HEX(b)
insert into t values(' ');
ERROR 22001: Data too long for column 'b' at row 1
drop table t;
create table bit2(a bit(8), b bit(11)) engine=tianmu DEFAULT CHARSET=utf8mb4;
insert into bit2 values(b'10111', b'1011');
insert into bit2 values(b'10111111', b'1011000');
select a>b, a=b, a<b, a<=>b, a<>b, a!=b, a<=b, a>=b from bit2;
a>b a=b a<b a<=>b a<>b a!=b a<=b a>=b
1 0 0 0 1 1 0 1
1 0 0 0 1 1 0 1
select COALESCE(a),greatest(a, 0), greatest(a, 123), a is true, b is false, a is null, isnull(b),least(a,2.0) from bit2;
COALESCE(a) greatest(a, 0) greatest(a, 123) a is true b is false a is null isnull(b) least(a,2.0)
23 23 123 1 0 0 0 2.0
191 191 191 1 0 0 0 2.0
select not a, a is true, b is null, a is not null, !(a+b), a and b, a and 0, a and null, a or 1, a or b, a xor 1, a xor b, a xor 0 from bit2;
not a a is true b is null a is not null !(a+b) a and b a and 0 a and null a or 1 a or b a xor 1 a xor b a xor 0
0 1 0 1 0 1 0 NULL 1 1 0 0 1
0 1 0 1 0 1 0 NULL 1 1 0 0 1
select abs(-a), abs(a), acos(b), asin(a), atan(b),atan2(a),ceil(a+0.1), ceiling(a+0.2),conv(a, 16,2), conv(a, 16, 10), conv(a, 16, 16) from bit2;
abs(-a) abs(a) acos(b) asin(a) atan(b) atan2(a) ceil(a+0.1) ceiling(a+0.2) conv(a, 16,2) conv(a, 16, 10) conv(a, 16, 16)
23 23 NULL NULL 1.4801364395941514 1.5273454314033659 24 24 10111 23 17
191 191 NULL NULL 1.5594331795306058 1.565560772538489 192 192 10111111 191 BF
select cos(a), cot(b), degrees(a), exp(a), floor(a+0.33), ln(a), log(a), log10(a), log2(a), mod(a, 0), pi()+a, pow(a,b), radians(a), rand(a) from
bit2;
cos(a) cot(b) degrees(a) exp(a) floor(a+0.33) ln(a) log(a) log10(a) log2(a) mod(a, 0) pi()+a pow(a,b) radians(a) rand(a)
-0.5328330203333975 -0.0044257413313241135 1317.8029288008934 9744803446.248903 23 3.1354942159291497 3.1354942159291497 1.3617278360175928 4.523561956057013 NULL 26.141593 952809757913927 0.4014257279586958 0.9094319407915994
-0.8037933932096717 28.232237325458215 10943.493886998724 8.917560070598843e82 191 5.25227342804663 5.25227342804663 2.2810333672477277 7.577428828035749 NULL 194.141593 5.38190859821405e200 3.3335788713091694 0.9401942872816643
Warnings:
Warning 1365 Division by 0
Warning 1365 Division by 0
select round(a), sign(b), sin(a), sqrt(a), tan(a),truncate(a+0.1123, 2) from bit2;
round(a) sign(b) sin(a) sqrt(a) tan(a) truncate(a+0.1123, 2)
23 1 -0.8462204041751706 4.795831523312719 1.5881530833912738 23.11
191 1 0.594908548461427 13.820274961085254 -0.7401261984573734 191.11
SELECT DATE_ADD('2018-05-01',INTERVAL a DAY) from bit2;
DATE_ADD('2018-05-01',INTERVAL a DAY)
2018-05-24
2018-11-08
select a like "10111", b not like "1011" from bit2;
a like "10111" b not like "1011"
0 1
0 1
select strcmp(a,b), strcmp(b,a),strcmp(a,a) from bit2;
strcmp(a,b) strcmp(b,a) strcmp(a,a)
1 -1 0
-1 1 0
select charset(binary a), collation(binary b) from bit2;
charset(binary a) collation(binary b)
binary binary
binary binary
SELECT BIT_AND(a), BIT_OR(a), BIT_XOR(a), BIT_COUNT(a), bin(a >> 1), bin(a << 1), bin(~a), bin(a & b'1111'), a ^ b, a | b, a & b from bit2 group by a,b;
BIT_AND(a) BIT_OR(a) BIT_XOR(a) BIT_COUNT(a) bin(a >> 1) bin(a << 1) bin(~a) bin(a & b'1111') a ^ b a | b a & b
23 23 23 4 1011 101110 1111111111111111111111111111111111111111111111111111111111101000 111 28 31 3
191 191 191 7 1011111 101111110 1111111111111111111111111111111111111111111111111111111101000000 1111 231 255 24
select avg(a), count(distinct a), max(b),max(a),std(a),stddev(a),sum(a),var_pop(a),var_samp(b),variance(a) from bit2 group by a;
avg(a) count(distinct a) max(b) max(a) std(a) stddev(a) sum(a) var_pop(a) var_samp(b) variance(a)
23.0000 1 11 23 0 0 23 0 NULL 0
191.0000 1 88 191 0 0 191 0 NULL 0
select a * 12345678910111213 from bit2;
a * 12345678910111213
283950614932557899
2358024671831241683
select a * 1234567891011121312 from bit2;
ERROR 22003: BIGINT UNSIGNED value is out of range in '(`test`.`bit2`.`a` * 1234567891011121312)'
select a * 12345678910111213123 from bit2;
ERROR 22003: BIGINT UNSIGNED value is out of range in '(`test`.`bit2`.`a` * 12345678910111213123)'
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)).
43 changes: 43 additions & 0 deletions mysql-test/suite/tianmu/t/bit_type.test
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,46 @@ SELECT b+0, BIN(b), OCT(b), HEX(b) FROM t;
--error 1406
insert into t values(' ');
drop table t;

# test functions and operators
create table bit2(a bit(8), b bit(11)) engine=tianmu DEFAULT CHARSET=utf8mb4;
insert into bit2 values(b'10111', b'1011');
insert into bit2 values(b'10111111', b'1011000');
# test comparison operators: https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html
select a>b, a=b, a<b, a<=>b, a<>b, a!=b, a<=b, a>=b from bit2;
select COALESCE(a),greatest(a, 0), greatest(a, 123), a is true, b is false, a is null, isnull(b),least(a,2.0) from bit2;

# test Logical Operators: https://dev.mysql.com/doc/refman/5.7/en/logical-operators.html
select not a, a is true, b is null, a is not null, !(a+b), a and b, a and 0, a and null, a or 1, a or b, a xor 1, a xor b, a xor 0 from bit2;

# test Mathematical Functions: https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html
select abs(-a), abs(a), acos(b), asin(a), atan(b),atan2(a),ceil(a+0.1), ceiling(a+0.2),conv(a, 16,2), conv(a, 16, 10), conv(a, 16, 16) from bit2;
select cos(a), cot(b), degrees(a), exp(a), floor(a+0.33), ln(a), log(a), log10(a), log2(a), mod(a, 0), pi()+a, pow(a,b), radians(a), rand(a) from
bit2;
select round(a), sign(b), sin(a), sqrt(a), tan(a),truncate(a+0.1123, 2) from bit2;

# test date and time: https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html
SELECT DATE_ADD('2018-05-01',INTERVAL a DAY) from bit2;

# test string ... : https://dev.mysql.com/doc/refman/5.7/en/string-comparison-functions.html
select a like "10111", b not like "1011" from bit2;
select strcmp(a,b), strcmp(b,a),strcmp(a,a) from bit2;
select charset(binary a), collation(binary b) from bit2;

# test bit function & operators: https://dev.mysql.com/doc/refman/8.0/en/bit-functions.html
SELECT BIT_AND(a), BIT_OR(a), BIT_XOR(a), BIT_COUNT(a), bin(a >> 1), bin(a << 1), bin(~a), bin(a & b'1111'), a ^ b, a | b, a & b from bit2 group by a,b;

# test agg
select avg(a), count(distinct a), max(b),max(a),std(a),stddev(a),sum(a),var_pop(a),var_samp(b),variance(a) from bit2 group by a;


# test boundary operations, unsigned bigint is 20 bits digits
select a * 12345678910111213 from bit2;
# error like mysql does: BIGINT UNSIGNED value is out of range in '(`test`.`bit2`.`a` * 1234567891011121312)'
--error 1690
select a * 1234567891011121312 from bit2;
--error 1690
select a * 12345678910111213123 from bit2;
# error(mysql will be numeric results, diff with tianmu): 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)).
--error 1105
select a * 12345678910111213123456 from bit2;
2 changes: 1 addition & 1 deletion storage/tianmu/common/txt_data_format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ uint TxtDataFormat::StaticExtrnalSize(ColumnType attrt, uint precision, int scal
return 10;
else if (attrt == ColumnType::INT)
return 11;
else if (attrt == ColumnType::BIGINT)
else if (attrt == ColumnType::BIGINT || attrt == ColumnType::BIT)
return 20;
else if (attrt == ColumnType::BYTEINT || attrt == ColumnType::YEAR)
return 4;
Expand Down
3 changes: 2 additions & 1 deletion storage/tianmu/core/engine_convert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,8 @@ int Engine::Convert(int &is_null, int64_t &value, types::TianmuDataType &tianmu_
is_null = 1;
else {
is_null = 0;
if (tianmu_item.Type() == common::ColumnType::NUM || tianmu_item.Type() == common::ColumnType::BIGINT) {
if (tianmu_item.Type() == common::ColumnType::NUM || tianmu_item.Type() == common::ColumnType::BIGINT ||
tianmu_item.Type() == common::ColumnType::BIT) {
value = (int64_t)(types::TianmuNum &)tianmu_item;
switch (f_type) {
case MYSQL_TYPE_LONG:
Expand Down
20 changes: 19 additions & 1 deletion storage/tianmu/core/temp_table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ void TempTable::Attr::CreateBuffer(uint64_t size, Transaction *conn, bool not_c)
case common::ColumnType::DATE:
case common::ColumnType::DATETIME:
case common::ColumnType::TIMESTAMP:
case common::ColumnType::BIT:
if (!buffer)
buffer = new AttrBuffer<int64_t>(page_size, sizeof(int64_t), conn);
break;
Expand Down Expand Up @@ -258,6 +259,7 @@ void TempTable::Attr::DeleteBuffer() {
case common::ColumnType::DATE:
case common::ColumnType::DATETIME:
case common::ColumnType::TIMESTAMP:
case common::ColumnType::BIT:
delete (AttrBuffer<int64_t> *)(buffer);
break;
case common::ColumnType::REAL:
Expand Down Expand Up @@ -350,6 +352,7 @@ void TempTable::Attr::SetNull(int64_t obj) {
case common::ColumnType::DATE:
case common::ColumnType::DATETIME:
case common::ColumnType::TIMESTAMP:
case common::ColumnType::BIT:
((AttrBuffer<int64_t> *)buffer)->Set(obj, common::NULL_VALUE_64);
break;
case common::ColumnType::INT:
Expand Down Expand Up @@ -418,6 +421,7 @@ void TempTable::Attr::SetValueString(int64_t obj, const types::BString &val) {
case common::ColumnType::DATE:
case common::ColumnType::DATETIME:
case common::ColumnType::TIMESTAMP:
case common::ColumnType::BIT:
val64 = *(int64_t *)(val.GetDataBytesPointer());
((AttrBuffer<int64_t> *)buffer)->Set(obj, val64);
break;
Expand Down Expand Up @@ -450,6 +454,8 @@ types::TianmuValueObject TempTable::Attr::GetValue(int64_t obj, [[maybe_unused]]
ret = types::TianmuNum(this->GetValueInt64(obj), 0, true);
else if (TypeName() == common::ColumnType::NUM)
ret = types::TianmuNum((int64_t)GetValueInt64(obj), Type().GetScale());
else if (TypeName() == common::ColumnType::BIT)
ret = types::TianmuNum((int64_t)GetValueInt64(obj), Type().GetScale(), false, TypeName()); // TODO(check prec & scale)
return ret;
}

Expand Down Expand Up @@ -494,6 +500,11 @@ void TempTable::Attr::GetValueString(types::BString &value, int64_t obj) {
value = tianmu_n.GetValueInt64() == common::NULL_VALUE_64 ? types::BString() : tianmu_n.ToBString();
break;
}
case common::ColumnType::BIT: {
types::TianmuNum tianmu_n((*(AttrBuffer<int64_t> *)buffer)[obj], Type().GetScale(), false, TypeName());
value = tianmu_n.GetValueInt64() == common::NULL_VALUE_64 ? types::BString() : tianmu_n.ToBString();
break;
}
case common::ColumnType::YEAR:
case common::ColumnType::TIME:
case common::ColumnType::DATE:
Expand Down Expand Up @@ -636,6 +647,7 @@ int64_t TempTable::Attr::GetValueInt64(int64_t obj) const {
case common::ColumnType::DATE:
case common::ColumnType::DATETIME:
case common::ColumnType::TIMESTAMP:
case common::ColumnType::BIT:
if (!IsNull(obj))
res = (*(AttrBuffer<int64_t> *)buffer)[obj];
break;
Expand Down Expand Up @@ -695,6 +707,7 @@ int64_t TempTable::Attr::GetNotNullValueInt64(int64_t obj) const {
case common::ColumnType::DATE:
case common::ColumnType::DATETIME:
case common::ColumnType::TIMESTAMP:
case common::ColumnType::BIT:
res = (*(AttrBuffer<int64_t> *)buffer)[obj];
break;
case common::ColumnType::REAL:
Expand Down Expand Up @@ -738,6 +751,7 @@ bool TempTable::Attr::IsNull(const int64_t obj) const {
case common::ColumnType::DATE:
case common::ColumnType::DATETIME:
case common::ColumnType::TIMESTAMP:
case common::ColumnType::BIT:
res = (*(AttrBuffer<int64_t> *)buffer)[obj] == common::NULL_VALUE_64;
break;
case common::ColumnType::REAL:
Expand Down Expand Up @@ -802,6 +816,7 @@ void TempTable::Attr::ApplyFilter(MultiIndex &mind, int64_t offset, int64_t last
case common::ColumnType::DATE:
case common::ColumnType::DATETIME:
case common::ColumnType::TIMESTAMP:
case common::ColumnType::BIT:
((AttrBuffer<int64_t> *)buffer)->Set(i, (*(AttrBuffer<int64_t> *)old_buffer)[idx]);
break;
case common::ColumnType::REAL:
Expand Down Expand Up @@ -840,6 +855,7 @@ void TempTable::Attr::ApplyFilter(MultiIndex &mind, int64_t offset, int64_t last
case common::ColumnType::DATE:
case common::ColumnType::DATETIME:
case common::ColumnType::TIMESTAMP:
case common::ColumnType::BIT:
delete (AttrBuffer<int64_t> *)old_buffer;
break;
case common::ColumnType::REAL:
Expand Down Expand Up @@ -1232,6 +1248,7 @@ int TempTable::AddColumn(CQTerm e, common::ColOperation mode, char *alias, bool
precision = 18;
break;
case common::ColumnType::BIGINT:
case common::ColumnType::BIT:
type = common::ColumnType::BIGINT;
precision = 19;
break;
Expand Down Expand Up @@ -2157,7 +2174,8 @@ void TempTable::RecordIterator::PrepareValues() {
dataTypes[att]->SetToNull();
else
((types::TianmuNum *)dataTypes[att].get())->Assign(v);
} else if (attrt_tmp == common::ColumnType::NUM || attrt_tmp == common::ColumnType::BIGINT) {
} else if (attrt_tmp == common::ColumnType::NUM || attrt_tmp == common::ColumnType::BIGINT ||
attrt_tmp == common::ColumnType::BIT) {
int64_t &v = (*(AttrBuffer<int64_t> *)table->GetDisplayableAttrP(att)->buffer)[_currentRNo];
if (v == common::NULL_VALUE_64)
dataTypes[att]->SetToNull();
Expand Down
33 changes: 17 additions & 16 deletions storage/tianmu/core/tianmu_attr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ size_t TianmuAttr::ComputeNaturalSize() {
break;
case common::ColumnType::BIGINT:
case common::ColumnType::REAL:
case common::ColumnType::BIT:
na_size += 8 * NumOfObj();
break;
case common::ColumnType::FLOAT:
Expand Down Expand Up @@ -446,7 +447,7 @@ void TianmuAttr::GetValueBin(int64_t obj, size_t &size, char *val_buf) {
val_buf[4] = 0;
return;
} else if (a_type == common::ColumnType::NUM || a_type == common::ColumnType::BIGINT || ATI::IsRealType(a_type) ||
ATI::IsDateTimeType(a_type)) {
ATI::IsDateTimeType(a_type) || a_type == common::ColumnType::BIT) {
size = 8;
int64_t v = GetValueInt64(obj);
if (v == common::NULL_VALUE_64)
Expand Down Expand Up @@ -487,7 +488,7 @@ types::TianmuValueObject TianmuAttr::GetValue(int64_t obj, bool lookup_to_num) {
ret = types::TianmuDateTime(this->GetNotNullValueInt64(obj), a_type);
else if (ATI::IsRealType(a_type))
ret = types::TianmuNum(this->GetNotNullValueInt64(obj), 0, true, a_type);
else if (lookup_to_num || a_type == common::ColumnType::NUM)
else if (lookup_to_num || a_type == common::ColumnType::NUM || a_type == common::ColumnType::BIT)
ret = types::TianmuNum((int64_t)GetNotNullValueInt64(obj), Type().GetScale());
}
return ret;
Expand Down Expand Up @@ -610,27 +611,27 @@ types::BString TianmuAttr::DecodeValue_S(int64_t code) {
common::ColumnType a_type = TypeName();
if (ATI::IsIntegerType(a_type)) {
types::TianmuNum tianmu_n(code, -1, false, a_type);
types::BString local_rcb = tianmu_n.ToBString();
local_rcb.MakePersistent();
return local_rcb;
types::BString local_tianmu_b = tianmu_n.ToBString();
local_tianmu_b.MakePersistent();
return local_tianmu_b;
} else if (ATI::IsRealType(a_type)) {
types::TianmuNum tianmu_n(code, -1, true, a_type);
types::BString local_rcb = tianmu_n.ToBString();
local_rcb.MakePersistent();
return local_rcb;
} else if (a_type == common::ColumnType::NUM) {
types::BString local_tianmu_b = tianmu_n.ToBString();
local_tianmu_b.MakePersistent();
return local_tianmu_b;
} else if (a_type == common::ColumnType::NUM || a_type == common::ColumnType::BIT) {
types::TianmuNum tianmu_n(code, Type().GetScale(), false, a_type);
types::BString local_rcb = tianmu_n.ToBString();
local_rcb.MakePersistent();
return local_rcb;
types::BString local_tianmu_b = tianmu_n.ToBString();
local_tianmu_b.MakePersistent();
return local_tianmu_b;
} else if (ATI::IsDateTimeType(a_type)) {
types::TianmuDateTime tianmu_dt(code, a_type);
if (a_type == common::ColumnType::TIMESTAMP) {
types::TianmuDateTime::AdjustTimezone(tianmu_dt);
}
types::BString local_rcb = tianmu_dt.ToBString();
local_rcb.MakePersistent();
return local_rcb;
types::BString local_tianmu_b = tianmu_dt.ToBString();
local_tianmu_b.MakePersistent();
return local_tianmu_b;
}
return types::BString();
}
Expand Down Expand Up @@ -690,7 +691,7 @@ int64_t TianmuAttr::EncodeValue64(types::TianmuDataType *v, bool &rounded, commo
if (!v || v->IsNull())
return common::NULL_VALUE_64;

if ((Type().IsLookup() && v->Type() != common::ColumnType::NUM)) {
if ((Type().IsLookup() && v->Type() != common::ColumnType::NUM && v->Type() != common::ColumnType::BIT)) {
return EncodeValue_T(v->ToBString(), false, tianmu_err_code);
} else if (ATI::IsDateTimeType(TypeName()) || ATI::IsDateTimeNType(TypeName())) {
return ((types::TianmuDateTime *)v)->GetInt64();
Expand Down
Loading

0 comments on commit 4ea052c

Please sign in to comment.