Skip to content

Commit

Permalink
feat(tianmu): impl bit type on tianmu engine #919
Browse files Browse the repository at this point in the history
[summary]
1. impl insert with mode delayed=0/1
2. impl simple select bit data from table
  • Loading branch information
hustjieke authored and mergify[bot] committed Jan 5, 2023
1 parent 41ca5e4 commit 17cdb6c
Show file tree
Hide file tree
Showing 15 changed files with 164 additions and 38 deletions.
56 changes: 56 additions & 0 deletions mysql-test/suite/tianmu/r/bit_type.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
drop table if exists bittypes, t;
Warnings:
Note 1051 Unknown table 'test.bittypes'
Note 1051 Unknown table 'test.t'
CREATE TABLE t (b BIT(8));
INSERT INTO t SET b = b'11111111';
INSERT INTO t SET b = B'1010';
INSERT INTO t SET b = 0b0101;
INSERT INTO t values(b'1'), (B'1010'), (0b0101);
SELECT b+0, BIN(b), OCT(b), HEX(b) FROM t;
b+0 BIN(b) OCT(b) HEX(b)
255 11111111 377 FF
10 1010 12 A
5 101 5 5
1 1 1 1
10 1010 12 A
5 101 5 5
INSERT INTO t values(b'111111111');
ERROR 22001: Data too long for column 'b' at row 1
insert into t values(b'2');
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'b'2')' at line 1
insert into t values(0B111);
ERROR 42S22: Unknown column '0B111' in 'field list'
drop table t;
CREATE TABLE t (b BIT(8));
insert into t values('');
insert into t values(' ');
insert into t values('1');
insert into t values('2');
insert into t values('9');
SELECT b+0, BIN(b), OCT(b), HEX(b) FROM t;
b+0 BIN(b) OCT(b) HEX(b)
0 0 0 0
32 100000 40 20
49 110001 61 31
50 110010 62 32
57 111001 71 39
insert into t values('10');
ERROR 22001: Data too long for column 'b' at row 1
insert into t values(' ');
ERROR 22001: Data too long for column 'b' at row 1
insert into t values("22");
ERROR 22001: Data too long for column 'b' at row 1
drop table t;
CREATE TABLE t (b BIT);
insert into t values(b'0');
insert into t values(b'1');
insert into t values(b'');
SELECT b+0, BIN(b), OCT(b), HEX(b) FROM t;
b+0 BIN(b) OCT(b) HEX(b)
0 0 0 0
1 1 1 1
0 0 0 0
insert into t values(' ');
ERROR 22001: Data too long for column 'b' at row 1
drop table t;
1 change: 1 addition & 0 deletions mysql-test/suite/tianmu/r/create_table.result
Original file line number Diff line number Diff line change
Expand Up @@ -602,5 +602,6 @@ bittypes CREATE TABLE `bittypes` (
`bit63` bit(63) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=TIANMU DEFAULT CHARSET=utf8mb4
drop table bittypes;
create table tc(a bit(64)) engine=tianmu;
ERROR HY000: The bit(M) type, M must be less than or equal to 63 in tianmu engine.
52 changes: 52 additions & 0 deletions mysql-test/suite/tianmu/t/bit_type.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
--source include/have_tianmu.inc

drop table if exists bittypes, t;
CREATE TABLE t (b BIT(8));
# insert values using literals: https://dev.mysql.com/doc/refman/8.0/en/bit-value-literals.html
INSERT INTO t SET b = b'11111111';
INSERT INTO t SET b = B'1010';
INSERT INTO t SET b = 0b0101;
INSERT INTO t values(b'1'), (B'1010'), (0b0101);
SELECT b+0, BIN(b), OCT(b), HEX(b) FROM t;

# data too long
--error 1406
INSERT INTO t values(b'111111111');

# wrong SQL syntax
--error 1064
insert into t values(b'2');

--error 1054
insert into t values(0B111);

# insert values with string mode
drop table t;
CREATE TABLE t (b BIT(8));
insert into t values('');
insert into t values(' ');
insert into t values('1');
insert into t values('2');
insert into t values('9');
SELECT b+0, BIN(b), OCT(b), HEX(b) FROM t;

# ERROR 1406 (22001): Data too long for column 'b' at row 1
--error 1406
insert into t values('10');
--error 1406
insert into t values(' ');
--error 1406
insert into t values("22");
drop table t;

# test default M=1
CREATE TABLE t (b BIT);
insert into t values(b'0');
insert into t values(b'1');
insert into t values(b'');
SELECT b+0, BIN(b), OCT(b), HEX(b) FROM t;

# space will be parsed as num 32, so data too long error is returned
--error 1406
insert into t values(' ');
drop table t;
1 change: 1 addition & 0 deletions mysql-test/suite/tianmu/t/create_table.test
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,7 @@ create table bittypes (

) ENGINE=tianmu DEFAULT CHARSET=utf8mb4;
show create table bittypes;
drop table bittypes;

--error 6
create table tc(a bit(64)) engine=tianmu;
8 changes: 1 addition & 7 deletions storage/tianmu/core/column.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,7 @@

namespace Tianmu {
namespace core {
enum class PackOntologicalStatus {
kNullsOnly = 0,
kUniform,
kUniformAndNulls,
kSequential,
kNormal
};
enum class PackOntologicalStatus { kNullsOnly = 0, kUniform, kUniformAndNulls, kSequential, kNormal };

/*! \brief Base class for columns.
*
Expand Down
16 changes: 8 additions & 8 deletions storage/tianmu/core/engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -489,8 +489,9 @@ void Engine::EncodeRecord(const std::string &table_path, int table_id, Field **f
} break;
case MYSQL_TYPE_BIT: {
int64_t v = f->val_int();
ASSERT(v < 0, "bit type data should never less than 0.");
if (v > common::TIANMU_BIGINT_MAX) // how can v > bigint max ??
// DEBUG_ASSERT(v < 0, "bit type data should never less than 0.");
// open it when support M = 64, now all value parsed is < 0.
if (v > common::TIANMU_BIGINT_MAX) // v > bigint max when uint64_t is supported
v = common::TIANMU_BIGINT_MAX; // TODO(fix with bit prec)
*(int64_t *)ptr = v;
ptr += sizeof(int64_t);
Expand Down Expand Up @@ -704,7 +705,8 @@ AttributeTypeInfo Engine::GetAttrTypeInfo(const Field &field) {
if (fstr->charset() != &my_charset_bin)
return AttributeTypeInfo(common::ColumnType::STRING, notnull, field.field_length, 0, auto_inc, coll, fmt,
bloom_filter);
return AttributeTypeInfo(common::ColumnType::BYTE, notnull, field.field_length, 0, auto_inc, coll, fmt, bloom_filter);
return AttributeTypeInfo(common::ColumnType::BYTE, notnull, field.field_length, 0, auto_inc, coll, fmt,
bloom_filter);
} else if (const Field_str *fvstr = dynamic_cast<const Field_varstring *>(&field)) {
DTCollation coll(fvstr->charset(), fvstr->derivation());
if (fmt == common::PackFmt::TRIE && types::IsCaseInsensitive(coll))
Expand All @@ -720,7 +722,7 @@ AttributeTypeInfo Engine::GetAttrTypeInfo(const Field &field) {
case MYSQL_TYPE_BIT: {
const Field_bit_as_char *f_bit = ((const Field_bit_as_char *)&field);
if (/*f_bit->field_length > 0 && */ f_bit->field_length <= common::kTianmuBitMaxPrec)
return AttributeTypeInfo(common::ColumnType::NUM, notnull, f_bit->field_length);
return AttributeTypeInfo(common::ColumnType::BIT, notnull, f_bit->field_length);
throw common::UnsupportedDataTypeException(
"The bit(M) type, M must be less than or equal to 63 in tianmu engine.");
}
Expand Down Expand Up @@ -982,8 +984,7 @@ int Engine::SetUpCacheFolder(const std::string &cachefolder_path) {
}

std::string get_parameter_name(enum TianmuVarName vn) {
DEBUG_ASSERT(static_cast<int>(vn) >= 0 &&
static_cast<int>(vn) <= static_cast<int>(TianmuVarName::kTianmuVarLimit));
DEBUG_ASSERT(static_cast<int>(vn) >= 0 && static_cast<int>(vn) <= static_cast<int>(TianmuVarName::kTianmuVarLimit));
return tianmu_var_name_strings[static_cast<int>(vn)];
}

Expand Down Expand Up @@ -1751,8 +1752,7 @@ common::TianmuError Engine::GetRejectFileIOParameters(THD &thd, std::unique_ptr<
return common::TianmuError(common::ErrorCode::WRONG_PARAMETER, "Wrong value of kTianmuAbortOnCount parameter.");

if (get_parameter(&thd, TianmuVarName::kTianmuAbortOnThreshold, abort_on_threshold) == 2)
return common::TianmuError(common::ErrorCode::WRONG_PARAMETER,
"Wrong value of kTianmuAbortOnThreshold parameter.");
return common::TianmuError(common::ErrorCode::WRONG_PARAMETER, "Wrong value of kTianmuAbortOnThreshold parameter.");

if (abort_on_count != 0 && abort_on_threshold != 0)
return common::TianmuError(common::ErrorCode::WRONG_PARAMETER,
Expand Down
14 changes: 12 additions & 2 deletions storage/tianmu/core/engine_convert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ bool Engine::ConvertToField(Field *field, types::TianmuDataType &tianmu_item, st
case common::ColumnType::REAL:
case common::ColumnType::FLOAT:
case common::ColumnType::NUM:
case common::ColumnType::BIT:
switch (field->type()) {
case MYSQL_TYPE_TINY:
*(char *)field->ptr = (char)(int64_t)((types::TianmuNum &)(tianmu_item));
Expand All @@ -113,6 +114,9 @@ bool Engine::ConvertToField(Field *field, types::TianmuDataType &tianmu_item, st
case MYSQL_TYPE_LONGLONG:
*(int64_t *)field->ptr = (int64_t)((types::TianmuNum &)(tianmu_item));
break;
case MYSQL_TYPE_BIT: // mysql bit(1~64), here is (1~63, 1 precision lose)
*(int64_t *)field->ptr = (int64_t)((types::TianmuNum &)(tianmu_item));
break;
case MYSQL_TYPE_FLOAT:
*(float *)field->ptr = (float)((types::TianmuNum &)(tianmu_item));
break;
Expand Down Expand Up @@ -146,7 +150,8 @@ bool Engine::ConvertToField(Field *field, types::TianmuDataType &tianmu_item, st
blob->set_ptr(((types::BString &)tianmu_item).len_, (uchar *)((types::BString &)tianmu_item).val_);
blob->copy();
} else {
blob->store(((types::BString &)tianmu_item).val_, ((types::BString &)tianmu_item).len_, &my_charset_bin);
blob->store(((types::BString &)tianmu_item).val_, ((types::BString &)tianmu_item).len_,
&my_charset_bin);
uchar *src, *tgt;

uint packlength = blob->pack_length_no_ptr();
Expand Down Expand Up @@ -481,7 +486,8 @@ int Engine::Convert(int &is_null, String *value, types::TianmuDataType &tianmu_i
return 0;
}

bool Engine::AreConvertible(types::TianmuDataType &tianmu_item, enum_field_types my_type, [[maybe_unused]] uint length) {
bool Engine::AreConvertible(types::TianmuDataType &tianmu_item, enum_field_types my_type,
[[maybe_unused]] uint length) {
/*if(tianmu_item->Type() == Engine::GetCorrespondingType(my_type, length) ||
tianmu_item->IsNull()) return true;*/
common::ColumnType tianmu_type = tianmu_item.Type();
Expand Down Expand Up @@ -514,6 +520,8 @@ bool Engine::AreConvertible(types::TianmuDataType &tianmu_item, enum_field_types
return tianmu_type == common::ColumnType::MEDIUMINT;
case MYSQL_TYPE_LONG:
return tianmu_type == common::ColumnType::INT;
case MYSQL_TYPE_BIT:
return tianmu_type == common::ColumnType::BIT;
case MYSQL_TYPE_FLOAT:
case MYSQL_TYPE_DOUBLE:
return tianmu_type == common::ColumnType::FLOAT || tianmu_type == common::ColumnType::REAL;
Expand Down Expand Up @@ -549,6 +557,8 @@ common::ColumnType Engine::GetCorrespondingType(const enum_field_types &eft) {
return common::ColumnType::INT;
case MYSQL_TYPE_LONGLONG:
return common::ColumnType::BIGINT;
case MYSQL_TYPE_BIT:
return common::ColumnType::BIT;
case MYSQL_TYPE_FLOAT:
return common::ColumnType::FLOAT;
case MYSQL_TYPE_DOUBLE:
Expand Down
4 changes: 3 additions & 1 deletion storage/tianmu/core/temp_table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ void TempTable::Attr::SetValueInt64(int64_t obj, int64_t val) {
switch (TypeName()) {
case common::ColumnType::BIGINT:
case common::ColumnType::NUM:
case common::ColumnType::BIT:
case common::ColumnType::YEAR:
case common::ColumnType::TIME:
case common::ColumnType::DATE:
Expand Down Expand Up @@ -2199,7 +2200,8 @@ TempTable::RecordIterator::RecordIterator(TempTable *table_, Transaction *conn_,
common::ColumnType att_type = table->GetDisplayableAttrP(att)->TypeName();
if (att_type == common::ColumnType::INT || att_type == common::ColumnType::MEDIUMINT ||
att_type == common::ColumnType::SMALLINT || att_type == common::ColumnType::BYTEINT ||
ATI::IsRealType(att_type) || att_type == common::ColumnType::NUM || att_type == common::ColumnType::BIGINT)
ATI::IsRealType(att_type) || att_type == common::ColumnType::NUM || att_type == common::ColumnType::BIGINT ||
att_type == common::ColumnType::BIT)
dataTypes.emplace_back(new types::TianmuNum());
else if (ATI::IsDateTimeType(att_type))
dataTypes.emplace_back(new types::TianmuDateTime());
Expand Down
3 changes: 2 additions & 1 deletion storage/tianmu/core/temp_table_low.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,8 @@ void TempTable::SendResult(int64_t limit, int64_t offset, ResultSender &sender,

auto vc = col->term.vc;
if (ct == common::ColumnType::INT || ct == common::ColumnType::MEDIUMINT || ct == common::ColumnType::SMALLINT ||
ct == common::ColumnType::BYTEINT || ct == common::ColumnType::NUM || ct == common::ColumnType::BIGINT) {
ct == common::ColumnType::BYTEINT || ct == common::ColumnType::NUM || ct == common::ColumnType::BIGINT ||
ct == common::ColumnType::BIT) {
auto data_ptr = new types::TianmuNum();
if (vc->IsNull(it))
data_ptr->SetToNull();
Expand Down
9 changes: 5 additions & 4 deletions storage/tianmu/core/tianmu_attr_typeinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,10 @@ class AttributeTypeInfo {
kBloomFilter,
};

AttributeTypeInfo(common::ColumnType attrt, bool not_null, uint precision = 0, ushort scale = 0, bool auto_inc = false,
DTCollation collation = DTCollation(), common::PackFmt fmt = common::PackFmt::DEFAULT,
bool filter = false, std::string field_name = std::string())
AttributeTypeInfo(common::ColumnType attrt, bool not_null, uint precision = 0, ushort scale = 0,
bool auto_inc = false, DTCollation collation = DTCollation(),
common::PackFmt fmt = common::PackFmt::DEFAULT, bool filter = false,
std::string field_name = std::string())
: attrt_(attrt), fmt_(fmt), precision_(precision), scale_(scale), collation_(collation), field_name_(field_name) {
flag_[static_cast<int>(enumATI::kNotNull)] = not_null;
flag_[static_cast<int>(enumATI::kBloomFilter)] = filter;
Expand All @@ -106,7 +107,7 @@ class AttributeTypeInfo {
common::ColumnType Type() const { return attrt_; }
common::PackType GetPackType() const {
return ATI::IsDateTimeType(attrt_) || ATI::IsNumericType(attrt_) || IsLookup() ? common::PackType::INT
: common::PackType::STR;
: common::PackType::STR;
}
std::string GetFieldName() { return field_name_; }
uint Precision() const { return precision_; }
Expand Down
12 changes: 6 additions & 6 deletions storage/tianmu/core/tianmu_table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,7 @@ void TianmuTable::Field2VC(Field *f, loader::ValueCache &vc, size_t col) {
case MYSQL_TYPE_LONG:
case MYSQL_TYPE_INT24:
case MYSQL_TYPE_LONGLONG: {
case MYSQL_TYPE_BIT:
int64_t value = f->val_int();
if (m_attrs[col]->GetIfAutoInc() && value == 0)
// Value of auto inc column was not assigned by user
Expand All @@ -620,7 +621,6 @@ void TianmuTable::Field2VC(Field *f, loader::ValueCache &vc, size_t col) {
if (value > 0 || ((m_attrs[col]->TypeName() == common::ColumnType::BIGINT) && m_attrs[col]->GetIfUnsigned()))
m_attrs[col]->SetAutoInc(value);
}
}
} break;
case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_FLOAT:
Expand Down Expand Up @@ -708,7 +708,6 @@ void TianmuTable::Field2VC(Field *f, loader::ValueCache &vc, size_t col) {
case MYSQL_TYPE_ENUM:
case MYSQL_TYPE_GEOMETRY:
case MYSQL_TYPE_NULL:
case MYSQL_TYPE_BIT:
default:
throw common::Exception("unsupported mysql type " + std::to_string(f->type()));
break;
Expand Down Expand Up @@ -1016,15 +1015,16 @@ int TianmuTable::binlog_insert2load_block(std::vector<loader::ValueCache> &vcs,
case common::ColumnType::SMALLINT:
case common::ColumnType::INT:
case common::ColumnType::MEDIUMINT:
case common::ColumnType::BIGINT: {
case common::ColumnType::BIGINT:
case common::ColumnType::BIT: {
types::BString s;
int64_t v = *(int64_t *)(vcs[att].GetDataBytesPointer(i));
if (v == common::NULL_VALUE_64)
s = types::BString();
else {
types::TianmuNum rcd(v, m_attrs[att]->Type().GetScale(), m_attrs[att]->Type().IsFloat(),
m_attrs[att]->TypeName());
s = rcd.ToBString();
types::TianmuNum tianmu_d(v, m_attrs[att]->Type().GetScale(), m_attrs[att]->Type().IsFloat(),
m_attrs[att]->TypeName());
s = tianmu_d.ToBString();
}
std::memcpy(ptr, s.GetDataBytesPointer(), s.size());
ptr += s.size();
Expand Down
Loading

0 comments on commit 17cdb6c

Please sign in to comment.