diff --git a/storage/tianmu/core/column.h b/storage/tianmu/core/column.h index 0aa07dfc1..1fb8ca91d 100644 --- a/storage/tianmu/core/column.h +++ b/storage/tianmu/core/column.h @@ -24,7 +24,13 @@ namespace Tianmu { namespace core { -enum class PackOntologicalStatus { NULLS_ONLY, UNIFORM, UNIFORM_AND_NULLS, SEQUENTIAL, NORMAL }; +enum class PackOntologicalStatus { + kNullsOnly = 0, + kUniform, + kUniformAndNulls, + kSequential, + kNormal +}; /*! \brief Base class for columns. * diff --git a/storage/tianmu/core/column_type.h b/storage/tianmu/core/column_type.h index bd9eeef54..cce107236 100644 --- a/storage/tianmu/core/column_type.h +++ b/storage/tianmu/core/column_type.h @@ -27,9 +27,9 @@ struct DataType; struct ColumnType { enum class enumCT { - NOT_NULL = 0, - AUTO_INC = 1, - BLOOM_FILTER = 2, + kNotNull = 0, + kAutoInc, + kBloomFilter, }; public: @@ -42,14 +42,14 @@ struct ColumnType { display_size(ATI::TextSize(t, prec, sc, collation)), collation(collation), fmt(fmt) { - flag[static_cast(enumCT::NOT_NULL)] = notnull; + flag[static_cast(enumCT::kNotNull)] = notnull; internal_size = InternalSize(); } void Initialize(common::ColumnType t, bool notnull, common::PackFmt f, uint prec, int sc, DTCollation collation = DTCollation()) { type = t; - flag[static_cast(enumCT::NOT_NULL)] = notnull; + flag[static_cast(enumCT::kNotNull)] = notnull; fmt = f; precision = prec; scale = sc; @@ -137,11 +137,11 @@ struct ColumnType { void SetFmt(common::PackFmt f) { fmt = f; } unsigned char GetFlag() const { return flag.to_ulong(); } void SetFlag(unsigned char v) { flag = std::bitset::digits>(v); } - bool NotNull() const { return flag[static_cast(enumCT::NOT_NULL)]; } + bool NotNull() const { return flag[static_cast(enumCT::kNotNull)]; } bool IsNullable() const { return !NotNull(); } - bool GetAutoInc() const { return flag[static_cast(enumCT::AUTO_INC)]; } - void SetAutoInc(bool inc) { flag[static_cast(enumCT::AUTO_INC)] = inc; } - bool HasFilter() const { return flag[static_cast(enumCT::BLOOM_FILTER)]; } + bool GetAutoInc() const { return flag[static_cast(enumCT::kAutoInc)]; } + void SetAutoInc(bool inc) { flag[static_cast(enumCT::kAutoInc)] = inc; } + bool HasFilter() const { return flag[static_cast(enumCT::kBloomFilter)]; } bool GetUnsigned() const { return is_unsigned; } void SetUnsigned(bool unsigned_) { is_unsigned = unsigned_; } diff --git a/storage/tianmu/core/engine.cpp b/storage/tianmu/core/engine.cpp index 4199b5909..0d3c627c5 100644 --- a/storage/tianmu/core/engine.cpp +++ b/storage/tianmu/core/engine.cpp @@ -166,7 +166,7 @@ static std::string has_mem_name(const LEX_STRING &comment) { return name; } -bool parameter_equals(THD *thd, enum tianmu_var_name vn, longlong value) { +bool parameter_equals(THD *thd, enum TianmuVarName vn, longlong value) { longlong param = 0; std::string s_res; @@ -643,7 +643,7 @@ AttributeTypeInfo Engine::GetAttrTypeInfo(const Field &field) { bool notnull = (field.null_bit == 0); auto str = boost::to_upper_copy(std::string(field.comment.str, field.comment.length)); - bool filter = (str.find("FILTER") != std::string::npos); + bool bloom_filter = (str.find("FILTER") != std::string::npos); auto fmt = common::PackFmt::DEFAULT; if (str.find("LOOKUP") != std::string::npos) { @@ -683,9 +683,9 @@ AttributeTypeInfo Engine::GetAttrTypeInfo(const Field &field) { case MYSQL_TYPE_DATE: case MYSQL_TYPE_NEWDATE: return AttributeTypeInfo(Engine::GetCorrespondingType(field), notnull, (ushort)field.field_length, 0, auto_inc, - DTCollation(), fmt, filter); + DTCollation(), fmt, bloom_filter); case MYSQL_TYPE_TIME: - return AttributeTypeInfo(common::ColumnType::TIME, notnull, 0, 0, false, DTCollation(), fmt, filter); + return AttributeTypeInfo(common::ColumnType::TIME, notnull, 0, 0, false, DTCollation(), fmt, bloom_filter); case MYSQL_TYPE_STRING: case MYSQL_TYPE_VARCHAR: { if (field.field_length > FIELD_MAXLENGTH) @@ -703,17 +703,17 @@ 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, - filter); - return AttributeTypeInfo(common::ColumnType::BYTE, notnull, field.field_length, 0, auto_inc, coll, fmt, filter); + 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(&field)) { DTCollation coll(fvstr->charset(), fvstr->derivation()); if (fmt == common::PackFmt::TRIE && types::IsCaseInsensitive(coll)) throw common::UnsupportedDataTypeException(); if (fvstr->charset() != &my_charset_bin) return AttributeTypeInfo(common::ColumnType::VARCHAR, notnull, field.field_length, 0, auto_inc, coll, fmt, - filter); + bloom_filter); return AttributeTypeInfo(common::ColumnType::VARBYTE, notnull, field.field_length, 0, auto_inc, coll, fmt, - filter); + bloom_filter); } throw common::UnsupportedDataTypeException(); } @@ -739,19 +739,19 @@ AttributeTypeInfo Engine::GetAttrTypeInfo(const Field &field) { if (field.field_length > FIELD_MAXLENGTH) { t = common::ColumnType::LONGTEXT; } - return AttributeTypeInfo(t, notnull, field.field_length, 0, auto_inc, DTCollation(), fmt, filter); + return AttributeTypeInfo(t, notnull, field.field_length, 0, auto_inc, DTCollation(), fmt, bloom_filter); } switch (field.field_length) { case 255: case FIELD_MAXLENGTH: // TINYBLOB, BLOB return AttributeTypeInfo(common::ColumnType::VARBYTE, notnull, field.field_length, 0, auto_inc, - DTCollation(), fmt, filter); + DTCollation(), fmt, bloom_filter); case 16777215: case 4294967295: // MEDIUMBLOB, LONGBLOB return AttributeTypeInfo(common::ColumnType::BIN, notnull, field.field_length, 0, auto_inc, DTCollation(), - fmt, filter); + fmt, bloom_filter); default: throw common::UnsupportedDataTypeException(); } @@ -981,13 +981,13 @@ int Engine::SetUpCacheFolder(const std::string &cachefolder_path) { return 0; } -std::string get_parameter_name(enum tianmu_var_name vn) { +std::string get_parameter_name(enum TianmuVarName vn) { DEBUG_ASSERT(static_cast(vn) >= 0 && - static_cast(vn) <= static_cast(tianmu_var_name::TIANMU_VAR_LIMIT)); + static_cast(vn) <= static_cast(TianmuVarName::kTianmuVarLimit)); return tianmu_var_name_strings[static_cast(vn)]; } -int get_parameter(THD *thd, enum tianmu_var_name vn, double &value) { +int get_parameter(THD *thd, enum TianmuVarName vn, double &value) { std::string var_data = get_parameter_name(vn); user_var_entry *m_entry; my_bool null_val; @@ -1001,7 +1001,7 @@ int get_parameter(THD *thd, enum tianmu_var_name vn, double &value) { return 0; } -int get_parameter(THD *thd, enum tianmu_var_name vn, int64_t &value) { +int get_parameter(THD *thd, enum TianmuVarName vn, int64_t &value) { std::string var_data = get_parameter_name(vn); user_var_entry *m_entry; my_bool null_val; @@ -1016,7 +1016,7 @@ int get_parameter(THD *thd, enum tianmu_var_name vn, int64_t &value) { return 0; } -int get_parameter(THD *thd, enum tianmu_var_name vn, std::string &value) { +int get_parameter(THD *thd, enum TianmuVarName vn, std::string &value) { my_bool null_val; std::string var_data = get_parameter_name(vn); user_var_entry *m_entry; @@ -1035,7 +1035,7 @@ int get_parameter(THD *thd, enum tianmu_var_name vn, std::string &value) { return 0; } -int get_parameter(THD *thd, enum tianmu_var_name vn, longlong &result, std::string &s_result) { +int get_parameter(THD *thd, enum TianmuVarName vn, longlong &result, std::string &s_result) { user_var_entry *m_entry; std::string var_data = get_parameter_name(vn); @@ -1045,7 +1045,7 @@ int get_parameter(THD *thd, enum tianmu_var_name vn, longlong &result, std::stri if (m_entry->type() == DECIMAL_RESULT) { switch (vn) { - case tianmu_var_name::TIANMU_ABORT_ON_THRESHOLD: { + case TianmuVarName::kTianmuAbortOnThreshold: { double dv; my_bool null_value; my_decimal v; @@ -1062,10 +1062,10 @@ int get_parameter(THD *thd, enum tianmu_var_name vn, longlong &result, std::stri return 0; } else if (m_entry->type() == INT_RESULT) { switch (vn) { - case tianmu_var_name::TIANMU_THROTTLE: - case tianmu_var_name::TIANMU_TIANMUEXPRESSIONS: - case tianmu_var_name::TIANMU_PARALLEL_AGGR: - case tianmu_var_name::TIANMU_ABORT_ON_COUNT: + case TianmuVarName::kTianmuThrottle: + case TianmuVarName::kTianmuExpressions: + case TianmuVarName::kTianmuParallelAggr: + case TianmuVarName::kTianmuAbortOnCount: my_bool null_value; result = m_entry->val_int(&null_value); break; @@ -1082,15 +1082,15 @@ int get_parameter(THD *thd, enum tianmu_var_name vn, longlong &result, std::stri m_entry->val_str(&null_value, &str, NOT_FIXED_DEC); var_data = std::string(str.ptr()); - if (vn == tianmu_var_name::TIANMU_DATAFORMAT || vn == tianmu_var_name::TIANMU_REJECT_FILE_PATH) { + if (vn == TianmuVarName::kTianmuDataFormat || vn == TianmuVarName::kTianmuRejectFilePath) { s_result = var_data; - } else if (vn == tianmu_var_name::TIANMU_PIPEMODE) { + } else if (vn == TianmuVarName::kTianmuPipeMode) { boost::to_upper(var_data); if (var_data == "SERVER") result = 1; if (var_data == "CLIENT") result = 0; - } else if (vn == tianmu_var_name::TIANMU_NULL) { + } else if (vn == TianmuVarName::kTianmuNull) { s_result = var_data; } return 0; @@ -1630,13 +1630,13 @@ bool Engine::IsTIANMURoute(THD *thd, TABLE_LIST *table_list, SELECT_LEX *selects if (file) { // it writes to a file longlong param = 0; std::string s_res; - if (!get_parameter(thd, tianmu_var_name::TIANMU_DATAFORMAT, param, s_res)) { + if (!get_parameter(thd, TianmuVarName::kTianmuDataFormat, param, s_res)) { if (boost::iequals(boost::trim_copy(s_res), "MYSQL")) return false; common::DataFormatPtr df = common::DataFormat::GetDataFormat(s_res); if (!df) { // parameter is UNKNOWN VALUE - my_message(ER_SYNTAX_ERROR, "Histgore specific error: Unknown value of TIANMU_DATAFORMAT parameter", MYF(0)); + my_message(ER_SYNTAX_ERROR, "Histgore specific error: Unknown value of kTianmuDataFormat parameter", MYF(0)); return true; } else if (!df->CanExport()) { my_message(ER_SYNTAX_ERROR, @@ -1743,30 +1743,30 @@ common::TianmuError Engine::GetRejectFileIOParameters(THD &thd, std::unique_ptr< int64_t abort_on_count = 0; double abort_on_threshold = 0; - get_parameter(&thd, tianmu_var_name::TIANMU_REJECT_FILE_PATH, reject_file); - if (get_parameter(&thd, tianmu_var_name::TIANMU_REJECT_FILE_PATH, reject_file) == 2) + get_parameter(&thd, TianmuVarName::kTianmuRejectFilePath, reject_file); + if (get_parameter(&thd, TianmuVarName::kTianmuRejectFilePath, reject_file) == 2) return common::TianmuError(common::ErrorCode::WRONG_PARAMETER, "Wrong value of TIANMU_LOAD_REJECT_FILE parameter."); - if (get_parameter(&thd, tianmu_var_name::TIANMU_ABORT_ON_COUNT, abort_on_count) == 2) - return common::TianmuError(common::ErrorCode::WRONG_PARAMETER, "Wrong value of TIANMU_ABORT_ON_COUNT parameter."); + if (get_parameter(&thd, TianmuVarName::kTianmuAbortOnCount, abort_on_count) == 2) + return common::TianmuError(common::ErrorCode::WRONG_PARAMETER, "Wrong value of kTianmuAbortOnCount parameter."); - if (get_parameter(&thd, tianmu_var_name::TIANMU_ABORT_ON_THRESHOLD, abort_on_threshold) == 2) + if (get_parameter(&thd, TianmuVarName::kTianmuAbortOnThreshold, abort_on_threshold) == 2) return common::TianmuError(common::ErrorCode::WRONG_PARAMETER, - "Wrong value of TIANMU_ABORT_ON_THRESHOLD parameter."); + "Wrong value of kTianmuAbortOnThreshold parameter."); if (abort_on_count != 0 && abort_on_threshold != 0) return common::TianmuError(common::ErrorCode::WRONG_PARAMETER, - "TIANMU_ABORT_ON_COUNT and TIANMU_ABORT_ON_THRESHOLD " + "kTianmuAbortOnCount and kTianmuAbortOnThreshold " "parameters are mutualy exclusive."); if (!(abort_on_threshold >= 0.0 && abort_on_threshold < 1.0)) return common::TianmuError(common::ErrorCode::WRONG_PARAMETER, - "TIANMU_ABORT_ON_THRESHOLD parameter value must be in range (0,1)."); + "kTianmuAbortOnThreshold parameter value must be in range (0,1)."); if ((abort_on_count != 0 || abort_on_threshold != 0) && reject_file.empty()) return common::TianmuError(common::ErrorCode::WRONG_PARAMETER, - "TIANMU_ABORT_ON_COUNT or TIANMU_ABORT_ON_THRESHOLD can by only specified with " - "TIANMU_REJECT_FILE_PATH parameter."); + "kTianmuAbortOnCount or kTianmuAbortOnThreshold can by only specified with " + "kTianmuRejectFilePath parameter."); if (!reject_file.empty() && fs::exists(reject_file)) return common::TianmuError(common::ErrorCode::WRONG_PARAMETER, @@ -1807,10 +1807,10 @@ common::TianmuError Engine::GetIOP(std::unique_ptr &io_par longlong param = 0; std::string s_res; if (common::DataFormat::GetNoFormats() > 1) { - if (!get_parameter(&thd, tianmu_var_name::TIANMU_DATAFORMAT, param, s_res)) { + if (!get_parameter(&thd, TianmuVarName::kTianmuDataFormat, param, s_res)) { common::DataFormatPtr df = common::DataFormat::GetDataFormat(s_res); if (!df) - return common::TianmuError(common::ErrorCode::WRONG_PARAMETER, "Unknown value of TIANMU_DATAFORMAT parameter."); + return common::TianmuError(common::ErrorCode::WRONG_PARAMETER, "Unknown value of kTianmuDataFormat parameter."); else io_mode = df->GetId(); } else @@ -1818,7 +1818,7 @@ common::TianmuError Engine::GetIOP(std::unique_ptr &io_par } else io_mode = common::DataFormat::GetDataFormat(0)->GetId(); - if (!get_parameter(&thd, tianmu_var_name::TIANMU_NULL, param, s_res)) + if (!get_parameter(&thd, TianmuVarName::kTianmuNull, param, s_res)) io_params->SetNullsStr(s_res); if (io_params->LoadDelayed()) { diff --git a/storage/tianmu/core/engine.h b/storage/tianmu/core/engine.h index b96af79e4..d2c5dd5df 100644 --- a/storage/tianmu/core/engine.h +++ b/storage/tianmu/core/engine.h @@ -151,11 +151,11 @@ class Engine final { static AttributeTypeInfo GetAttrTypeInfo(const Field &field); static common::ColumnType GetCorrespondingType(const enum_field_types &eft); static bool IsTianmuTable(TABLE *table); - static bool ConvertToField(Field *field, types::TianmuDataType &rcitem, std::vector *blob_buf); - static int Convert(int &is_null, my_decimal *value, types::TianmuDataType &rcitem, int output_scale = -1); - static int Convert(int &is_null, int64_t &value, types::TianmuDataType &rcitem, enum_field_types f_type); - static int Convert(int &is_null, double &value, types::TianmuDataType &rcitem); - static int Convert(int &is_null, String *value, types::TianmuDataType &rcitem, enum_field_types f_type); + static bool ConvertToField(Field *field, types::TianmuDataType &tianmu_item, std::vector *blob_buf); + static int Convert(int &is_null, my_decimal *value, types::TianmuDataType &tianmu_item, int output_scale = -1); + static int Convert(int &is_null, int64_t &value, types::TianmuDataType &tianmu_item, enum_field_types f_type); + static int Convert(int &is_null, double &value, types::TianmuDataType &tianmu_item); + static int Convert(int &is_null, String *value, types::TianmuDataType &tianmu_item, enum_field_types f_type); static void ComputeTimeZoneDiffInMinutes(THD *thd, short &sign, short &minutes); static std::string GetTablePath(TABLE *table); static common::TianmuError GetIOP(std::unique_ptr &io_params, THD &thd, sql_exchange &ex, @@ -169,7 +169,7 @@ class Engine final { QueryRouteTo Execute(THD *thd, LEX *lex, Query_result *result_output, SELECT_LEX_UNIT *unit_for_union = nullptr); int SetUpCacheFolder(const std::string &cachefolder_path); - static bool AreConvertible(types::TianmuDataType &rcitem, enum_field_types my_type, uint length = 0); + static bool AreConvertible(types::TianmuDataType &tianmu_item, enum_field_types my_type, uint length = 0); static bool IsTIANMURoute(THD *thd, TABLE_LIST *table_list, SELECT_LEX *selects_list, int &in_case_of_failure_can_go_to_mysql, int with_insert); static const char *GetFilename(SELECT_LEX *selects_list, int &is_dumpfile); @@ -307,22 +307,22 @@ class ResultExportSender final : public ResultSender { void Init(TempTable *t) override; void SendRecord(const std::vector> &record) override; - exporter::select_tianmu_export *export_res; - std::unique_ptr rcde; - std::shared_ptr rcbuffer; + exporter::select_tianmu_export *export_res_; + std::unique_ptr tianmu_data_exp_; + std::shared_ptr tiammu_buffer_; }; -enum class tianmu_var_name { - TIANMU_DATAFORMAT, - TIANMU_PIPEMODE, - TIANMU_NULL, - TIANMU_THROTTLE, - TIANMU_TIANMUEXPRESSIONS, - TIANMU_PARALLEL_AGGR, - TIANMU_REJECT_FILE_PATH, - TIANMU_ABORT_ON_COUNT, - TIANMU_ABORT_ON_THRESHOLD, - TIANMU_VAR_LIMIT // KEEP THIS LAST +enum class TianmuVarName { + kTianmuDataFormat = 0, + kTianmuPipeMode, + kTianmuNull, + kTianmuThrottle, + kTianmuExpressions, + kTianmuParallelAggr, + kTianmuRejectFilePath, + kTianmuAbortOnCount, + kTianmuAbortOnThreshold, + kTianmuVarLimit // KEEP THIS LAST }; static std::string tianmu_var_name_strings[] = {"TIANMU_LOAD_TIMEOUT", "TIANMU_LOAD_DATAFORMAT", @@ -331,18 +331,18 @@ static std::string tianmu_var_name_strings[] = {"TIANMU_LOAD_TIMEOUT", "T "TIANMU_LOAD_PARALLEL_AGGR", "TIANMU_LOAD_REJECT_FILE", "TIANMU_LOAD_ABORT_ON_COUNT", "TIANMU_LOAD_ABORT_ON_THRESHOLD"}; -std::string get_parameter_name(enum tianmu_var_name vn); +std::string get_parameter_name(enum TianmuVarName vn); -int get_parameter(THD *thd, enum tianmu_var_name vn, longlong &result, std::string &s_result); +int get_parameter(THD *thd, enum TianmuVarName vn, longlong &result, std::string &s_result); // return 0 on success // 1 if parameter was not specified // 2 if was specified but with wrong type -int get_parameter(THD *thd, enum tianmu_var_name vn, double &value); -int get_parameter(THD *thd, enum tianmu_var_name vn, int64_t &value); -int get_parameter(THD *thd, enum tianmu_var_name vn, std::string &value); +int get_parameter(THD *thd, enum TianmuVarName vn, double &value); +int get_parameter(THD *thd, enum TianmuVarName vn, int64_t &value); +int get_parameter(THD *thd, enum TianmuVarName vn, std::string &value); -bool parameter_equals(THD *thd, enum tianmu_var_name vn, longlong value); +bool parameter_equals(THD *thd, enum TianmuVarName vn, longlong value); /** The maximum length of an encode table name in bytes. The max +table and database names are NAME_CHAR_LEN (64) characters. After the diff --git a/storage/tianmu/core/engine_convert.cpp b/storage/tianmu/core/engine_convert.cpp index 3e136c913..f0e40ab3f 100644 --- a/storage/tianmu/core/engine_convert.cpp +++ b/storage/tianmu/core/engine_convert.cpp @@ -23,8 +23,8 @@ namespace Tianmu { namespace core { -bool Engine::ConvertToField(Field *field, types::TianmuDataType &rcitem, std::vector *blob_buf) { - if (rcitem.IsNull()) { +bool Engine::ConvertToField(Field *field, types::TianmuDataType &tianmu_item, std::vector *blob_buf) { + if (tianmu_item.IsNull()) { std::memset(field->ptr, 0, 2); field->set_null(); return true; @@ -34,8 +34,8 @@ bool Engine::ConvertToField(Field *field, types::TianmuDataType &rcitem, std::ve switch (field->type()) { case MYSQL_TYPE_VARCHAR: { - DEBUG_ASSERT(dynamic_cast(&rcitem)); - types::BString &str_val = (types::BString &)rcitem; + DEBUG_ASSERT(dynamic_cast(&tianmu_item)); + types::BString &str_val = (types::BString &)tianmu_item; if (str_val.size() > field->field_length) throw common::DatabaseException("Incorrect field size: " + std::to_string(str_val.size())); if (field->field_length <= 255) @@ -45,20 +45,20 @@ bool Engine::ConvertToField(Field *field, types::TianmuDataType &rcitem, std::ve break; } case MYSQL_TYPE_STRING: - if (dynamic_cast(&rcitem)) { - ((types::BString &)rcitem).PutString((char *&)field->ptr, (ushort)field->field_length, false); + if (dynamic_cast(&tianmu_item)) { + ((types::BString &)tianmu_item).PutString((char *&)field->ptr, (ushort)field->field_length, false); } else { - rcitem.ToBString().PutString((char *&)field->ptr, (ushort)field->field_length, false); + tianmu_item.ToBString().PutString((char *&)field->ptr, (ushort)field->field_length, false); } break; case MYSQL_TYPE_BLOB: { - DEBUG_ASSERT(dynamic_cast(&rcitem)); + DEBUG_ASSERT(dynamic_cast(&tianmu_item)); Field_blob *blob = (Field_blob *)field; if (blob_buf == nullptr) { - blob->set_ptr(((types::BString &)rcitem).len_, (uchar *)((types::BString &)rcitem).val_); + blob->set_ptr(((types::BString &)tianmu_item).len_, (uchar *)((types::BString &)tianmu_item).val_); blob->copy(); } else { - blob->store(((types::BString &)rcitem).val_, ((types::BString &)rcitem).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(); @@ -76,11 +76,11 @@ bool Engine::ConvertToField(Field *field, types::TianmuDataType &rcitem, std::ve case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_NEWDECIMAL: { my_decimal md; - if (rcitem.Type() == common::ColumnType::REAL) { - double2decimal((double)((types::TianmuNum &)(rcitem)), &md); + if (tianmu_item.Type() == common::ColumnType::REAL) { + double2decimal((double)((types::TianmuNum &)(tianmu_item)), &md); } else { int is_null; - Engine::Convert(is_null, &md, rcitem); + Engine::Convert(is_null, &md, tianmu_item); } decimal_round(&md, &md, ((Field_new_decimal *)field)->decimals(), HALF_UP); decimal2bin(&md, (uchar *)field->ptr, ((Field_new_decimal *)field)->precision, @@ -88,7 +88,7 @@ bool Engine::ConvertToField(Field *field, types::TianmuDataType &rcitem, std::ve break; } default: - switch (rcitem.Type()) { + switch (tianmu_item.Type()) { case common::ColumnType::BYTEINT: case common::ColumnType::SMALLINT: case common::ColumnType::MEDIUMINT: @@ -99,25 +99,25 @@ bool Engine::ConvertToField(Field *field, types::TianmuDataType &rcitem, std::ve case common::ColumnType::NUM: switch (field->type()) { case MYSQL_TYPE_TINY: - *(char *)field->ptr = (char)(int64_t)((types::TianmuNum &)(rcitem)); + *(char *)field->ptr = (char)(int64_t)((types::TianmuNum &)(tianmu_item)); break; case MYSQL_TYPE_SHORT: - *(short *)field->ptr = (short)(int64_t)((types::TianmuNum &)(rcitem)); + *(short *)field->ptr = (short)(int64_t)((types::TianmuNum &)(tianmu_item)); break; case MYSQL_TYPE_INT24: - int3store((char *)field->ptr, (int)(int64_t)((types::TianmuNum &)(rcitem))); + int3store((char *)field->ptr, (int)(int64_t)((types::TianmuNum &)(tianmu_item))); break; case MYSQL_TYPE_LONG: - *(int *)field->ptr = (int)(int64_t)((types::TianmuNum &)(rcitem)); + *(int *)field->ptr = (int)(int64_t)((types::TianmuNum &)(tianmu_item)); break; case MYSQL_TYPE_LONGLONG: - *(int64_t *)field->ptr = (int64_t)((types::TianmuNum &)(rcitem)); + *(int64_t *)field->ptr = (int64_t)((types::TianmuNum &)(tianmu_item)); break; case MYSQL_TYPE_FLOAT: - *(float *)field->ptr = (float)((types::TianmuNum &)(rcitem)); + *(float *)field->ptr = (float)((types::TianmuNum &)(tianmu_item)); break; case MYSQL_TYPE_DOUBLE: - *(double *)field->ptr = (double)((types::TianmuNum &)(rcitem)); + *(double *)field->ptr = (double)((types::TianmuNum &)(tianmu_item)); break; default: DEBUG_ASSERT(!"No data types conversion available!"); @@ -127,7 +127,7 @@ bool Engine::ConvertToField(Field *field, types::TianmuDataType &rcitem, std::ve case common::ColumnType::STRING: switch (field->type()) { case MYSQL_TYPE_VARCHAR: { - types::BString &str_val = (types::BString &)rcitem; + types::BString &str_val = (types::BString &)tianmu_item; if (str_val.size() > field->field_length) throw common::DatabaseException("Incorrect field size " + std::to_string(str_val.size())); if (field->field_length <= 255) { @@ -138,15 +138,15 @@ bool Engine::ConvertToField(Field *field, types::TianmuDataType &rcitem, std::ve break; } case MYSQL_TYPE_STRING: - ((types::BString &)rcitem).PutString((char *&)field->ptr, (ushort)field->field_length, false); + ((types::BString &)tianmu_item).PutString((char *&)field->ptr, (ushort)field->field_length, false); break; case MYSQL_TYPE_BLOB: { Field_blob *blob = (Field_blob *)field; if (blob_buf == nullptr) { - blob->set_ptr(((types::BString &)rcitem).len_, (uchar *)((types::BString &)rcitem).val_); + blob->set_ptr(((types::BString &)tianmu_item).len_, (uchar *)((types::BString &)tianmu_item).val_); blob->copy(); } else { - blob->store(((types::BString &)rcitem).val_, ((types::BString &)rcitem).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(); @@ -164,33 +164,33 @@ bool Engine::ConvertToField(Field *field, types::TianmuDataType &rcitem, std::ve case MYSQL_TYPE_DATE: { char tmp[10]; char *tmpptr = tmp; - ((types::BString &)rcitem).PutString(tmpptr, ushort(sizeof(tmp)), false); + ((types::BString &)tianmu_item).PutString(tmpptr, ushort(sizeof(tmp)), false); ((Field_newdate *)field)->store(tmp, sizeof(tmp), nullptr); break; } case MYSQL_TYPE_TIME: { char tmp[10]; char *tmpptr = tmp; - ((types::BString &)rcitem).PutString(tmpptr, ushort(sizeof(tmp)), false); + ((types::BString &)tianmu_item).PutString(tmpptr, ushort(sizeof(tmp)), false); ((Field_time *)field)->store(tmp, sizeof(tmp), nullptr); break; } case MYSQL_TYPE_DATETIME: { char tmp[19]; char *tmpptr = tmp; - ((types::BString &)rcitem).PutString(tmpptr, ushort(sizeof(tmp)), false); + ((types::BString &)tianmu_item).PutString(tmpptr, ushort(sizeof(tmp)), false); ((Field_datetime *)field)->store(tmp, sizeof(tmp), nullptr); break; } default: - ((types::BString &)rcitem).PutString((char *&)field->ptr, (ushort)field->field_length, false); + ((types::BString &)tianmu_item).PutString((char *&)field->ptr, (ushort)field->field_length, false); break; } break; case common::ColumnType::YEAR: { ASSERT(field->type() == MYSQL_TYPE_YEAR); - auto tianmu_dt = dynamic_cast(&rcitem); + auto tianmu_dt = dynamic_cast(&tianmu_item); MYSQL_TIME my_time = {}; tianmu_dt->Store(&my_time, MYSQL_TIMESTAMP_DATE); field->store_time(&my_time); @@ -198,7 +198,7 @@ bool Engine::ConvertToField(Field *field, types::TianmuDataType &rcitem, std::ve } case common::ColumnType::DATE: { if (field->type() == MYSQL_TYPE_DATE || field->type() == MYSQL_TYPE_NEWDATE) { - auto tianmu_dt = dynamic_cast(&rcitem); + auto tianmu_dt = dynamic_cast(&tianmu_item); MYSQL_TIME my_time = {}; tianmu_dt->Store(&my_time, MYSQL_TIMESTAMP_DATE); field->store_time(&my_time); @@ -239,7 +239,7 @@ bool Engine::ConvertToField(Field *field, types::TianmuDataType &rcitem, std::ve case common::ColumnType::TIME: { ASSERT(field->type() == MYSQL_TYPE_TIME); - auto tianmu_dt = dynamic_cast(&rcitem); + auto tianmu_dt = dynamic_cast(&tianmu_item); MYSQL_TIME my_time = {}; tianmu_dt->Store(&my_time, MYSQL_TIMESTAMP_TIME); field->store_time(&my_time); @@ -247,14 +247,14 @@ bool Engine::ConvertToField(Field *field, types::TianmuDataType &rcitem, std::ve } case common::ColumnType::DATETIME: { ASSERT(field->type() == MYSQL_TYPE_DATETIME); - auto tianmu_dt = dynamic_cast(&rcitem); + auto tianmu_dt = dynamic_cast(&tianmu_item); MYSQL_TIME my_time = {}; tianmu_dt->Store(&my_time, MYSQL_TIMESTAMP_DATETIME); field->store_time(&my_time); break; } case common::ColumnType::TIMESTAMP: { - auto tianmu_dt = dynamic_cast(&rcitem); + auto tianmu_dt = dynamic_cast(&tianmu_item); MYSQL_TIME my_time = {}; types::TianmuDateTime::AdjustTimezone(*tianmu_dt); tianmu_dt->Store(&my_time, MYSQL_TIMESTAMP_DATETIME); @@ -273,15 +273,15 @@ bool Engine::ConvertToField(Field *field, types::TianmuDataType &rcitem, std::ve #define DIG_BASE 1000000000 #define ROUND_UP(X) (((X) + DIG_PER_DEC1 - 1) / DIG_PER_DEC1) -int Engine::Convert(int &is_null, my_decimal *value, types::TianmuDataType &rcitem, int output_scale) { - if (rcitem.IsNull()) +int Engine::Convert(int &is_null, my_decimal *value, types::TianmuDataType &tianmu_item, int output_scale) { + if (tianmu_item.IsNull()) is_null = 1; else { - if (!Engine::AreConvertible(rcitem, MYSQL_TYPE_NEWDECIMAL)) + if (!Engine::AreConvertible(tianmu_item, MYSQL_TYPE_NEWDECIMAL)) return false; is_null = 0; - if (rcitem.Type() == common::ColumnType::NUM) { - types::TianmuNum *tianmu_n = (types::TianmuNum *)(&rcitem); + if (tianmu_item.Type() == common::ColumnType::NUM) { + types::TianmuNum *tianmu_n = (types::TianmuNum *)(&tianmu_item); int intg = tianmu_n->GetDecIntLen(); int frac = tianmu_n->GetDecFractLen(); int intg1 = ROUND_UP(intg); @@ -338,11 +338,11 @@ int Engine::Convert(int &is_null, my_decimal *value, types::TianmuDataType &rcit int output_scale_1 = (output_scale > 18) ? 18 : output_scale; my_decimal_round(0, value, (output_scale_1 == -1) ? frac : output_scale_1, false, value); return 1; - } else if (rcitem.Type() == common::ColumnType::REAL || rcitem.Type() == common::ColumnType::FLOAT) { - double2decimal((double)((types::TianmuNum &)(rcitem)), (decimal_t *)value); + } else if (tianmu_item.Type() == common::ColumnType::REAL || tianmu_item.Type() == common::ColumnType::FLOAT) { + double2decimal((double)((types::TianmuNum &)(tianmu_item)), (decimal_t *)value); return 1; - } else if (ATI::IsIntegerType(rcitem.Type())) { - longlong2decimal((longlong)((types::TianmuNum &)(rcitem)).ValueInt(), (decimal_t *)value); + } else if (ATI::IsIntegerType(tianmu_item.Type())) { + longlong2decimal((longlong)((types::TianmuNum &)(tianmu_item)).ValueInt(), (decimal_t *)value); return 1; } return false; @@ -350,13 +350,13 @@ int Engine::Convert(int &is_null, my_decimal *value, types::TianmuDataType &rcit return 1; } -int Engine::Convert(int &is_null, int64_t &value, types::TianmuDataType &rcitem, enum_field_types f_type) { - if (rcitem.IsNull()) +int Engine::Convert(int &is_null, int64_t &value, types::TianmuDataType &tianmu_item, enum_field_types f_type) { + if (tianmu_item.IsNull()) is_null = 1; else { is_null = 0; - if (rcitem.Type() == common::ColumnType::NUM || rcitem.Type() == common::ColumnType::BIGINT) { - value = (int64_t)(types::TianmuNum &)rcitem; + if (tianmu_item.Type() == common::ColumnType::NUM || tianmu_item.Type() == common::ColumnType::BIGINT) { + value = (int64_t)(types::TianmuNum &)tianmu_item; switch (f_type) { case MYSQL_TYPE_LONG: case MYSQL_TYPE_INT24: @@ -387,73 +387,73 @@ int Engine::Convert(int &is_null, int64_t &value, types::TianmuDataType &rcitem, break; } return 1; - } else if (rcitem.Type() == common::ColumnType::INT || rcitem.Type() == common::ColumnType::MEDIUMINT) { - value = (int)(int64_t) dynamic_cast(rcitem); + } else if (tianmu_item.Type() == common::ColumnType::INT || tianmu_item.Type() == common::ColumnType::MEDIUMINT) { + value = (int)(int64_t) dynamic_cast(tianmu_item); return 1; - } else if (rcitem.Type() == common::ColumnType::BYTEINT) { - value = (char)(int64_t) dynamic_cast(rcitem); + } else if (tianmu_item.Type() == common::ColumnType::BYTEINT) { + value = (char)(int64_t) dynamic_cast(tianmu_item); return 1; - } else if (rcitem.Type() == common::ColumnType::SMALLINT) { - value = (short)(int64_t) dynamic_cast(rcitem); + } else if (tianmu_item.Type() == common::ColumnType::SMALLINT) { + value = (short)(int64_t) dynamic_cast(tianmu_item); return 1; - } else if (rcitem.Type() == common::ColumnType::YEAR) { - value = dynamic_cast(rcitem).Year(); + } else if (tianmu_item.Type() == common::ColumnType::YEAR) { + value = dynamic_cast(tianmu_item).Year(); return 1; - } else if (rcitem.Type() == common::ColumnType::REAL) { - value = (int64_t)(double)dynamic_cast(rcitem); + } else if (tianmu_item.Type() == common::ColumnType::REAL) { + value = (int64_t)(double)dynamic_cast(tianmu_item); return 1; } } return 0; } -int Engine::Convert(int &is_null, double &value, types::TianmuDataType &rcitem) { - if (rcitem.IsNull()) +int Engine::Convert(int &is_null, double &value, types::TianmuDataType &tianmu_item) { + if (tianmu_item.IsNull()) is_null = 1; else { - if (!Engine::AreConvertible(rcitem, MYSQL_TYPE_DOUBLE)) + if (!Engine::AreConvertible(tianmu_item, MYSQL_TYPE_DOUBLE)) return 0; is_null = 0; - if (rcitem.Type() == common::ColumnType::REAL) { - value = (double)dynamic_cast(rcitem); + if (tianmu_item.Type() == common::ColumnType::REAL) { + value = (double)dynamic_cast(tianmu_item); return 1; - } else if (rcitem.Type() == common::ColumnType::FLOAT) { - value = (float)dynamic_cast(rcitem); + } else if (tianmu_item.Type() == common::ColumnType::FLOAT) { + value = (float)dynamic_cast(tianmu_item); return 1; } } return 0; } -int Engine::Convert(int &is_null, String *value, types::TianmuDataType &rcitem, enum_field_types f_type) { - if (rcitem.IsNull()) +int Engine::Convert(int &is_null, String *value, types::TianmuDataType &tianmu_item, enum_field_types f_type) { + if (tianmu_item.IsNull()) is_null = 1; else { - if (!Engine::AreConvertible(rcitem, MYSQL_TYPE_STRING)) + if (!Engine::AreConvertible(tianmu_item, MYSQL_TYPE_STRING)) return 0; is_null = 0; if (f_type == MYSQL_TYPE_VARCHAR || f_type == MYSQL_TYPE_VAR_STRING) { - types::BString str = rcitem.ToBString(); + types::BString str = tianmu_item.ToBString(); value->set_ascii(str.val_, str.len_); value->copy(); } else if (f_type == MYSQL_TYPE_STRING) { - types::BString str = rcitem.ToBString(); + types::BString str = tianmu_item.ToBString(); value->set_ascii(str.val_, str.len_); value->copy(); } else if (f_type == MYSQL_TYPE_NEWDATE || f_type == MYSQL_TYPE_DATE) { - types::BString str = rcitem.ToBString(); + types::BString str = tianmu_item.ToBString(); value->set_ascii(str.val_, str.len_); value->copy(); } else if (f_type == MYSQL_TYPE_TIME) { - types::BString str = rcitem.ToBString(); + types::BString str = tianmu_item.ToBString(); value->set_ascii(str.val_, str.len_); value->copy(); } else if (f_type == MYSQL_TYPE_DATETIME) { - types::BString str = rcitem.ToBString(); + types::BString str = tianmu_item.ToBString(); value->set_ascii(str.val_, str.len_); value->copy(); } else if (f_type == MYSQL_TYPE_TIMESTAMP) { - if (types::TianmuDateTime *tianmu_dt = dynamic_cast(&rcitem)) { + if (types::TianmuDateTime *tianmu_dt = dynamic_cast(&tianmu_item)) { if (*tianmu_dt != types::kTianmuTimestampSpec) { MYSQL_TIME local_time; my_time_t secs = tianmu_sec_since_epoch(tianmu_dt->Year(), tianmu_dt->Month(), tianmu_dt->Day(), @@ -467,12 +467,12 @@ int Engine::Convert(int &is_null, String *value, types::TianmuDataType &rcitem, value->set_ascii("0000-00-00 00:00:00", 19); } } else { - types::BString str = rcitem.ToBString(); + types::BString str = tianmu_item.ToBString(); value->set_ascii(str.val_, str.len_); } value->copy(); } else if (f_type == MYSQL_TYPE_BLOB || f_type == MYSQL_TYPE_MEDIUM_BLOB) { - types::BString str = rcitem.ToBString(); + types::BString str = tianmu_item.ToBString(); value->set_ascii(str.val_, str.len_); value->copy(); } @@ -481,15 +481,15 @@ int Engine::Convert(int &is_null, String *value, types::TianmuDataType &rcitem, return 0; } -bool Engine::AreConvertible(types::TianmuDataType &rcitem, enum_field_types my_type, [[maybe_unused]] uint length) { - /*if(rcitem->Type() == Engine::GetCorrespondingType(my_type, length) || - rcitem->IsNull()) return true;*/ - common::ColumnType tianmu_type = rcitem.Type(); +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(); switch (my_type) { case MYSQL_TYPE_LONGLONG: if (tianmu_type == common::ColumnType::INT || tianmu_type == common::ColumnType::MEDIUMINT || tianmu_type == common::ColumnType::BIGINT || - (tianmu_type == common::ColumnType::NUM && dynamic_cast(rcitem).Scale() == 0)) + (tianmu_type == common::ColumnType::NUM && dynamic_cast(tianmu_item).Scale() == 0)) return true; break; case MYSQL_TYPE_NEWDECIMAL: @@ -576,9 +576,9 @@ common::ColumnType Engine::GetCorrespondingType(const enum_field_types &eft) { } common::ColumnType Engine::GetCorrespondingType(const Field &field) { - common::ColumnType res = GetCorrespondingType(field.type()); - if (!ATI::IsStringType(res)) - return res; + common::ColumnType typ = GetCorrespondingType(field.type()); + if (!ATI::IsStringType(typ)) + return typ; else { switch (field.type()) { case MYSQL_TYPE_STRING: diff --git a/storage/tianmu/core/engine_execute.cpp b/storage/tianmu/core/engine_execute.cpp index 008a52b50..3e0209ae6 100644 --- a/storage/tianmu/core/engine_execute.cpp +++ b/storage/tianmu/core/engine_execute.cpp @@ -109,7 +109,7 @@ QueryRouteTo Engine::HandleSelect(THD *thd, LEX *lex, Query_result *&result, ulo tianmu_stat.select++; // at this point all tables are in RCBase engine, so we can proceed with the - // query and we know that if the result goes to the file, the TIANMU_DATAFORMAT is + // query and we know that if the result goes to the file, the kTianmuDataFormat is // one of TIANMU formats QueryRouteTo route = QueryRouteTo::kToTianmu; SELECT_LEX *save_current_select = lex->current_select(); @@ -200,7 +200,7 @@ QueryRouteTo Engine::HandleSelect(THD *thd, LEX *lex, Query_result *&result, ulo const char *err_msg = "Error: Query syntax not implemented in Tianmu, can " "export " - "only to MySQL format (set TIANMU_DATAFORMAT to 'MYSQL')."; + "only to MySQL format (set kTianmuDataFormat to 'MYSQL')."; TIANMU_LOG(LogCtl_Level::ERROR, err_msg); my_message(ER_SYNTAX_ERROR, err_msg, MYF(0)); throw ReturnMeToMySQLWithError(); @@ -239,11 +239,11 @@ QueryRouteTo Engine::HandleSelect(THD *thd, LEX *lex, Query_result *&result, ulo if (route == QueryRouteTo::kToMySQL && !in_case_of_failure_can_go_to_mysql) { TIANMU_LOG(LogCtl_Level::ERROR, "Error: Query syntax not implemented in Tianmu, can export " - "only to MySQL format (set TIANMU_DATAFORMAT to 'MYSQL')."); + "only to MySQL format (set kTianmuDataFormat to 'MYSQL')."); my_message(ER_SYNTAX_ERROR, "Query syntax not implemented in Tianmu, can export only " "to MySQL " - "format (set TIANMU_DATAFORMAT to 'MYSQL').", + "format (set kTianmuDataFormat to 'MYSQL').", MYF(0)); throw ReturnMeToMySQLWithError(); } diff --git a/storage/tianmu/core/engine_results.cpp b/storage/tianmu/core/engine_results.cpp index bf8f86b44..6432dbb9b 100644 --- a/storage/tianmu/core/engine_results.cpp +++ b/storage/tianmu/core/engine_results.cpp @@ -404,14 +404,14 @@ ResultSender::~ResultSender() { delete[] buf_lens; } ResultExportSender::ResultExportSender(THD *thd, Query_result *result, List &fields) : ResultSender(thd, result, fields) { - export_res = dynamic_cast(result); - DEBUG_ASSERT(export_res); + export_res_ = dynamic_cast(result); + DEBUG_ASSERT(export_res_); } void ResultExportSender::SendEof() { - rcbuffer->FlushAndClose(); - export_res->SetRowCount((ha_rows)rows_sent); - export_res->SendOk(thd); + tiammu_buffer_->FlushAndClose(); + export_res_->SetRowCount((ha_rows)rows_sent); + export_res_->SendOk(thd); } void init_field_scan_helpers(THD *&thd, TABLE &tmp_table, TABLE_SHARE &share) { @@ -475,9 +475,9 @@ void ResultExportSender::Init(TempTable *t) { common::TianmuError tianmu_error; - export_res->send_result_set_metadata(fields, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF); + export_res_->send_result_set_metadata(fields, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF); - if ((tianmu_error = Engine::GetIOP(iop, *thd, *export_res->SqlExchange(), 0, nullptr, true)) != + if ((tianmu_error = Engine::GetIOP(iop, *thd, *export_res_->SqlExchange(), 0, nullptr, true)) != common::ErrorCode::SUCCESS) throw common::Exception("Unable to get IOP"); @@ -498,12 +498,12 @@ void ResultExportSender::Init(TempTable *t) { i++; } - rcbuffer = std::make_shared(); - if (!rcbuffer->BufOpen(*iop)) + tiammu_buffer_ = std::make_shared(); + if (!tiammu_buffer_->BufOpen(*iop)) throw common::FileException("Unable to open file or named pipe."); - rcde = common::DataFormat::GetDataFormat(iop->GetEDF())->CreateDataExporter(*iop); - rcde->Init(rcbuffer, t->GetATIs(iop->GetEDF() != common::EDF::TRI_UNKNOWN), f, deas); + tianmu_data_exp_ = common::DataFormat::GetDataFormat(iop->GetEDF())->CreateDataExporter(*iop); + tianmu_data_exp_->Init(tiammu_buffer_, t->GetATIs(iop->GetEDF() != common::EDF::TRI_UNKNOWN), f, deas); } // send to Exporter @@ -515,52 +515,52 @@ void ResultExportSender::SendRecord(const std::vectorPutNull(); + tianmu_data_exp_->PutNull(); else if (ATI::IsTxtType(tianmu_dt.Type())) { types::BString val(tianmu_dt.ToBString()); if (l_item->field_type() == MYSQL_TYPE_DATE) { types::TianmuDateTime dt; types::ValueParserForText::ParseDateTime(val, dt, common::ColumnType::DATE); - rcde->PutDateTime(dt.GetInt64()); + tianmu_data_exp_->PutDateTime(dt.GetInt64()); } else if ((l_item->field_type() == MYSQL_TYPE_DATETIME) || (l_item->field_type() == MYSQL_TYPE_TIMESTAMP)) { types::TianmuDateTime dt; types::ValueParserForText::ParseDateTime(val, dt, common::ColumnType::DATETIME); if (l_item->field_type() == MYSQL_TYPE_TIMESTAMP) { types::TianmuDateTime::AdjustTimezone(dt); } - rcde->PutDateTime(dt.GetInt64()); + tianmu_data_exp_->PutDateTime(dt.GetInt64()); } else { // values from binary columns from TempTable are retrieved as // types::BString -> they get common::CT::STRING type, so an // additional check is necessary if (dynamic_cast(l_item) && static_cast(l_item)->field->binary()) - rcde->PutBin(val); + tianmu_data_exp_->PutBin(val); else - rcde->PutText(val); + tianmu_data_exp_->PutText(val); } } else if (ATI::IsBinType(tianmu_dt.Type())) - rcde->PutBin(tianmu_dt.ToBString()); + tianmu_data_exp_->PutBin(tianmu_dt.ToBString()); else if (ATI::IsNumericType(tianmu_dt.Type())) { if (tianmu_dt.Type() == common::ColumnType::BYTEINT) - rcde->PutNumeric((char)dynamic_cast(tianmu_dt).ValueInt()); + tianmu_data_exp_->PutNumeric((char)dynamic_cast(tianmu_dt).ValueInt()); else if (tianmu_dt.Type() == common::ColumnType::SMALLINT) - rcde->PutNumeric((short)dynamic_cast(tianmu_dt).ValueInt()); + tianmu_data_exp_->PutNumeric((short)dynamic_cast(tianmu_dt).ValueInt()); else if (tianmu_dt.Type() == common::ColumnType::INT || tianmu_dt.Type() == common::ColumnType::MEDIUMINT) - rcde->PutNumeric((int)dynamic_cast(tianmu_dt).ValueInt()); + tianmu_data_exp_->PutNumeric((int)dynamic_cast(tianmu_dt).ValueInt()); else - rcde->PutNumeric(dynamic_cast(tianmu_dt).ValueInt()); + tianmu_data_exp_->PutNumeric(dynamic_cast(tianmu_dt).ValueInt()); } else if (ATI::IsDateTimeType(tianmu_dt.Type())) { if (tianmu_dt.Type() == common::ColumnType::TIMESTAMP) { // timezone conversion types::TianmuDateTime &dt(dynamic_cast(tianmu_dt)); types::TianmuDateTime::AdjustTimezone(dt); - rcde->PutDateTime(dt.GetInt64()); + tianmu_data_exp_->PutDateTime(dt.GetInt64()); } else - rcde->PutDateTime(dynamic_cast(tianmu_dt).GetInt64()); + tianmu_data_exp_->PutDateTime(dynamic_cast(tianmu_dt).GetInt64()); } o++; } - rcde->PutRowEnd(); + tianmu_data_exp_->PutRowEnd(); } } // namespace core } // namespace Tianmu diff --git a/storage/tianmu/core/groupby_wrapper.cpp b/storage/tianmu/core/groupby_wrapper.cpp index c572e7636..c721ee949 100644 --- a/storage/tianmu/core/groupby_wrapper.cpp +++ b/storage/tianmu/core/groupby_wrapper.cpp @@ -383,7 +383,7 @@ bool GroupByWrapper::AggregatePackInOneGroup(int attr_no, MIIterator &mit, int64 } bool GroupByWrapper::AddPackIfUniform(int attr_no, MIIterator &mit) { - if (virt_col[attr_no] && virt_col[attr_no]->GetPackOntologicalStatus(mit) == PackOntologicalStatus::UNIFORM && + if (virt_col[attr_no] && virt_col[attr_no]->GetPackOntologicalStatus(mit) == PackOntologicalStatus::kUniform && !mit.NullsPossibleInPack()) { // Put constant values for the grouping vector (will not be changed for this // pack) diff --git a/storage/tianmu/core/pack_str.cpp b/storage/tianmu/core/pack_str.cpp index 05483e295..e7cd28e55 100644 --- a/storage/tianmu/core/pack_str.cpp +++ b/storage/tianmu/core/pack_str.cpp @@ -755,7 +755,7 @@ void PackStr::LoadUncompressed(system::Stream *f) { ASSERT(data_.sum_len == sz, "bad pack! " + std::to_string(data_.sum_len) + "/" + std::to_string(sz)); } -bool PackStr::Lookup(const types::BString &pattern, uint16_t &id) { +bool PackStr::IsLookup(const types::BString &pattern, uint16_t &id) { marisa::Agent agent; agent.set_query(pattern.GetDataBytesPointer(), pattern.size()); if (!marisa_trie_.lookup(agent)) { diff --git a/storage/tianmu/core/pack_str.h b/storage/tianmu/core/pack_str.h index 32c0de922..f8d50961e 100644 --- a/storage/tianmu/core/pack_str.h +++ b/storage/tianmu/core/pack_str.h @@ -50,7 +50,7 @@ class PackStr final : public Pack { void LoadValues(const loader::ValueCache *vc); bool IsTrie() const { return pack_str_state_ == PackStrtate::kPackTrie; } - bool Lookup(const types::BString &pattern, uint16_t &id); + bool IsLookup(const types::BString &pattern, uint16_t &id); bool LikePrefix(const types::BString &pattern, std::size_t prefixlen, std::unordered_set &ids); bool IsNotMatched(int row, uint16_t &id); bool IsNotMatched(int row, const std::unordered_set &ids); diff --git a/storage/tianmu/core/parameterized_filter.cpp b/storage/tianmu/core/parameterized_filter.cpp index 84c840722..0397d95a7 100644 --- a/storage/tianmu/core/parameterized_filter.cpp +++ b/storage/tianmu/core/parameterized_filter.cpp @@ -812,7 +812,7 @@ bool ParameterizedFilter::TryToMerge(Descriptor &d1, Descriptor &d2) // true, i if (d1.attr.vc == d2.attr.vc && d1.IsInner() && d2.IsInner()) { // IS_NULL and anything based on the same column => FALSE - // NOT_NULL and anything based on the same column => NOT_NULL is not needed + // kNotNull and anything based on the same column => kNotNull is not needed // Exceptions: // null NOT IN {empty set} // null < ALL {empty set} etc. diff --git a/storage/tianmu/core/physical_column.h b/storage/tianmu/core/physical_column.h index 9955f0eff..a88770428 100644 --- a/storage/tianmu/core/physical_column.h +++ b/storage/tianmu/core/physical_column.h @@ -223,7 +223,7 @@ class PhysicalColumn : public Column { */ virtual bool IsDistinct(Filter *f) = 0; - //! \brief Is the pack NULLS_ONLY, UNIFORM, NORMAL etc... + //! \brief Is the pack kNullsOnly, kUniform, kNormal etc... virtual PackOntologicalStatus GetPackOntologicalStatus(int pack_no) = 0; /*! Check whether the value identified by \e row meets the condition \e d and diff --git a/storage/tianmu/core/query.cpp.bak b/storage/tianmu/core/query.cpp.bak deleted file mode 100644 index 4501bebf5..000000000 --- a/storage/tianmu/core/query.cpp.bak +++ /dev/null @@ -1,2078 +0,0 @@ -/* Copyright (c) 2022 StoneAtom, Inc. All rights reserved. - Use is subject to license terms - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA -*/ - -#include "query.h" - -#include "common/common_definitions.h" -#include "compiled_query.h" -#include "core/compilation_tools.h" -#include "core/cq_term.h" -#include "core/engine.h" -#include "core/mysql_expression.h" -#include "core/parameterized_filter.h" -#include "core/rough_multi_index.h" -#include "core/temp_table.h" -#include "core/transaction.h" -#include "core/value_set.h" -#include "vc/const_column.h" -#include "vc/const_expr_column.h" -#include "vc/expr_column.h" -#include "vc/in_set_column.h" -#include "vc/single_column.h" -#include "vc/subselect_column.h" -#include "vc/type_cast_column.h" - -namespace Tianmu { -namespace core { -Query::~Query() { - for (auto it : gc_expressions) delete it; -} - -void Query::RemoveFromManagedList(const std::shared_ptr tab) { - ta.erase(std::remove(ta.begin(), ta.end(), tab), ta.end()); -} - -void Query::LockPackInfoForUse() { - for (auto &it : t) it->LockPackInfoForUse(); -}; - -void Query::UnlockPackInfoFromUse() { - for (auto &it : t) it->UnlockPackInfoFromUse(); -}; - -bool Query::IsCountStar(Item *item_sum) { - Item_sum_count *is = down_cast(item_sum); - if (is) - return (is->sum_func() == Item_sum::COUNT_FUNC) && - ((is->get_arg(0)->type() == Item::INT_ITEM) || is->const_item() || - ((is->get_arg(0)->type() == Item::FUNC_ITEM) && (is->get_arg(0)->const_item()))); - else - return false; -} - -bool Query::IsAggregationItem(Item *item) { return item->type() == Item::SUM_FUNC_ITEM; } - -bool Query::IsDeterministic(Item *item) { - switch (static_cast(item->type())) { - case Item::FUNC_ITEM: { - Item_func *ifunc = down_cast(item); - - if ((down_cast(ifunc) || down_cast(ifunc) || - down_cast(ifunc) || down_cast(ifunc) || - down_cast(ifunc) || down_cast(ifunc) || - down_cast(ifunc) - /* // disputable functions start here - should they be nondeterministic? - || dynamic_cast(ifunc) - || dynamic_cast(ifunc) - || dynamic_cast(ifunc) ||dynamic_cast(ifunc) - || dynamic_cast(ifunc) ||dynamic_cast(ifunc) - || dynamic_cast(ifunc) ||dynamic_cast(ifunc) - */ // end of disputable functions - )) - return false; - - bool is_determ = true; - for (uint i = 0; i < ifunc->argument_count(); i++) - is_determ = is_determ && IsDeterministic(ifunc->arguments()[i]); - return is_determ; - } - - case Item::COND_ITEM: { - Item_cond *cond = down_cast(item); - List_iterator li(*cond->argument_list()); - - Item *arg; - bool is_determ = true; - - while ((arg = li++)) is_determ = is_determ && IsDeterministic(arg); - - return is_determ; - } - - case Item::REF_ITEM: { - Item_ref *iref = down_cast(item); - Item *arg = *(iref->ref); - return IsDeterministic(arg); - } - - default: - return true; - } -} - -bool Query::HasAggregation(Item *item) { - bool has = false; - Item *i = UnRef(item); - - if (i->type() == Item::SUM_FUNC_ITEM) - has = true; - else if (i->type() == Item::FUNC_ITEM) { - Item_func *f = down_cast(i); - - int const arg_count(f->argument_count()); - for (int arg = 0; (arg < arg_count) && !has; ++arg) has = HasAggregation(f->arguments()[arg]); - - } else if (i->type() == Item::COND_ITEM) { - Item_cond *c = down_cast(i); - List *args = c->argument_list(); - List_iterator_fast li(*args); - - Item *item{nullptr}; - while (!has && (item = li++)) has = HasAggregation(item); - - } else if (i->type() == Item_tianmufield::get_tianmuitem_type()) - if (down_cast(i)->IsAggregation()) - has = true; - - return has; -} - -int Query::VirtualColumnAlreadyExists(const TabID &tmp_table, MysqlExpression *expression) { - int exists = common::NULL_VALUE_32; - for (auto it = tab_id2expression.lower_bound(tmp_table), end = tab_id2expression.upper_bound(tmp_table); it != end; - ++it) { - if (*(it->second.second) == *expression) { - exists = it->second.first; - break; - } - } - - return exists; -} - -int Query::VirtualColumnAlreadyExists(const TabID &tmp_table, const TabID &subselect) { - int exists = common::NULL_VALUE_32; - - for (auto it = tab_id2subselect.lower_bound(tmp_table), end = tab_id2subselect.upper_bound(tmp_table); it != end; - ++it) { - if (it->second.second == subselect) { - exists = it->second.first; - break; - } - } - - return exists; -} - -int Query::VirtualColumnAlreadyExists(const TabID &tmp_table, const std::vector &vcs, const AttrID &at) { - int exists = common::NULL_VALUE_32; - for (auto it = tab_id2inset.lower_bound(tmp_table), end = tab_id2inset.upper_bound(tmp_table); it != end; ++it) { - if (it->second.second.second.n == at.n) { - std::set s1, s2; - s1.insert(it->second.second.first.begin(), it->second.second.first.end()); - s2.insert(vcs.begin(), vcs.end()); - if (s1 == s2) { - exists = it->second.first; - break; - } - } - } - - return exists; -} - -std::pair Query::VirtualColumnAlreadyExists(const TabID &tmp_table, const TabID &tab, const AttrID &at) { - for (auto it = phys2virt.lower_bound(std::make_pair(tab.n, at.n)), - end = phys2virt.upper_bound(std::make_pair(tab.n, at.n)); - it != end; ++it) { - if (it->second.first == tmp_table.n) { - return it->second; - } - } - - return std::make_pair(common::NULL_VALUE_32, common::NULL_VALUE_32); -} - -bool Query::IsFieldItem(Item *item) { - return (item->type() == Item::FIELD_ITEM || item->type() == Item::REF_ITEM || - item->type() == Item_tianmufield::get_tianmuitem_type()); -} - -bool Query::IsAggregationOverFieldItem(Item *item) { - return IsAggregationItem(item) && IsFieldItem((down_cast(item))->get_arg(0)); -} - -bool Query::IsConstItem(Item *item) { - bool res = item->type() == Item::INT_ITEM || item->type() == Item::NULL_ITEM || item->type() == Item::INT_ITEM || - item->type() == Item::VARBIN_ITEM || item->type() == Item::STRING_ITEM || - item->type() == Item::DECIMAL_ITEM || item->type() == Item::REAL_ITEM; - return res; -} - -const std::string Query::GetItemName(Item *item) { - // static const char* nameOf[] = { - // "FIELD_ITEM", "FUNC_ITEM", "SUM_FUNC_ITEM", "STRING_ITEM", - // "INT_ITEM", "REAL_ITEM", "NULL_ITEM", "VARBIN_ITEM", - // "COPY_STR_ITEM", "FIELD_AVG_ITEM", "DEFAULT_VALUE_ITEM", - // "PROC_ITEM", "COND_ITEM", "REF_ITEM", "FIELD_STD_ITEM", - // "FIELD_VARIANCE_ITEM", "INSERT_VALUE_ITEM", "SUBSELECT_ITEM", - // "ROW_ITEM", "CACHE_ITEM", "TYPE_HOLDER", "PARAM_ITEM", - // "TRIGGER_FIELD_ITEM", "DECIMAL_ITEM", "XPATH_NODESET", - // "XPATH_NODESET_CMP", "VIEW_FIXER_ITEM" }; - static const char *sumNameOf[] = {"COUNT_FUNC", "COUNT_DISTINCT_FUNC", "SUM_FUNC", "SUM_DISTINCT_FUNC", - "AVG_FUNC", "AVG_DISTINCT_FUNC", "MIN_FUNC", "MAX_FUNC", - "STD_FUNC", "VARIANCE_FUNC", "SUM_BIT_FUNC", "UDF_SUM_FUNC", - "GROUP_CONCAT_FUNC"}; - char buf[256] = {0}; - switch (static_cast(item->type())) { - case Item::FUNC_ITEM: { - Item_func *func = down_cast(item); - return func->func_name(); - } - case Item::COND_ITEM: { - Item_cond *cond = down_cast(item); - return cond->func_name(); - } - case Item::SUM_FUNC_ITEM: { - Item_sum *sum_func = down_cast(item); - uint index = sum_func->sum_func(); - if (index >= sizeof(sumNameOf) / sizeof(*sumNameOf)) - return "UNKNOWN SUM_FUNC_ITEM"; - else - return sumNameOf[index]; - } - case Item::REF_ITEM: { - Item_ref *ref = down_cast(item); - Item *real = ref->real_item(); - if (ref != real) - return GetItemName(real); - return "REF_ITEM"; - } - case Item::NULL_ITEM: - return "nullptr"; - case Item::INT_ITEM: { - Item_int_with_ref *int_ref = dynamic_cast(item); - String s(buf, 256, nullptr); - if (!int_ref) { - String *ps = item->val_str(&s); - return ps ? ps->c_ptr_safe() : "nullptr"; - } - // else item is an instance of Item_int_with_ref, not Item_int - return GetItemName(int_ref->real_item()); - } - case Item::STRING_ITEM: { - String s(buf, 256, nullptr); - String *ps = item->val_str(&s); - return ps ? ps->c_ptr_safe() : "nullptr"; - } - case Item::SUBSELECT_ITEM: - return "SUBSELECT"; - case Item::REAL_ITEM: - return "REAL"; - case Item::DECIMAL_ITEM: - return "DECIMAL"; - case static_cast(Item_tianmufield::enumTIANMUFiledItem::TIANMUFIELD_ITEM): - Item_tianmufield *tianmu = down_cast(item); - size_t cur_var_id = tianmuitems_cur_var_ids[tianmu]++; - if (cur_var_id >= tianmu->varID.size()) - cur_var_id = 0; - std::sprintf(buf, "TIANMU_FIELD(T:%d,A:%d)", tianmu->varID[cur_var_id].tab, tianmu->varID[cur_var_id].col); - return buf; - } - - return "UNKNOWN"; -} - -int Query::GetAddColumnId(const AttrID &vc, const TabID &tmp_table, const common::ColOperation oper, - const bool distinct) { - for (int i = 0; i < cq->NumOfSteps(); i++) { - CompiledQuery::CQStep *step = &cq->Step(i); - if (step->type == CompiledQuery::StepType::ADD_COLUMN && step->t1 == tmp_table && step->e1.vc_id == vc.n && - step->cop == oper && step->n1 == (distinct ? 1 : 0)) { - return step->a1.n; - } - } - - return common::NULL_VALUE_32; -} - -void Query::CQChangeAddColumnLIST2GROUP_BY(const TabID &tmp_table, int attr) { - for (int i = 0; i < cq->NumOfSteps(); i++) { - CompiledQuery::CQStep *step = &cq->Step(i); - if (step->type == CompiledQuery::StepType::ADD_COLUMN && step->t1 == tmp_table && step->a1.n == attr && - step->cop == common::ColOperation::LISTING) { - step->cop = common::ColOperation::GROUP_BY; - cq->AddGroupByStep(*step); - - return; - } - } -} - -void Query::MarkWithAny(common::Operator &op) { - switch (op) { - case common::Operator::O_EQ: - op = common::Operator::O_EQ_ANY; - break; - case common::Operator::O_NOT_EQ: - op = common::Operator::O_NOT_EQ_ANY; - break; - case common::Operator::O_LESS: - op = common::Operator::O_LESS_ANY; - break; - case common::Operator::O_MORE: - op = common::Operator::O_MORE_ANY; - break; - case common::Operator::O_LESS_EQ: - op = common::Operator::O_LESS_EQ_ANY; - break; - case common::Operator::O_MORE_EQ: - op = common::Operator::O_MORE_EQ_ANY; - break; - default: - // ANY can't be added to any other operator - break; - } -} - -void Query::MarkWithAll(common::Operator &op) { - switch (op) { - case common::Operator::O_EQ: - op = common::Operator::O_EQ_ALL; - break; - case common::Operator::O_NOT_EQ: - op = common::Operator::O_NOT_EQ_ALL; - break; - case common::Operator::O_LESS: - op = common::Operator::O_LESS_ALL; - break; - case common::Operator::O_MORE: - op = common::Operator::O_MORE_ALL; - break; - case common::Operator::O_LESS_EQ: - op = common::Operator::O_LESS_EQ_ALL; - break; - case common::Operator::O_MORE_EQ: - op = common::Operator::O_MORE_EQ_ALL; - break; - default: - // ALL can't be added to any other operator - break; - } -} - -bool Query::IsAllAny(common::Operator &op) { - return (op == common::Operator::O_EQ_ALL || op == common::Operator::O_EQ_ANY || - op == common::Operator::O_NOT_EQ_ALL || op == common::Operator::O_NOT_EQ_ANY || - op == common::Operator::O_LESS_ALL || op == common::Operator::O_LESS_ANY || - op == common::Operator::O_MORE_ALL || op == common::Operator::O_MORE_ANY || - op == common::Operator::O_LESS_EQ_ALL || op == common::Operator::O_LESS_EQ_ANY || - op == common::Operator::O_MORE_EQ_ALL || op == common::Operator::O_MORE_EQ_ANY); -} - -void Query::UnmarkAllAny(common::Operator &op) { - switch (op) { - case common::Operator::O_EQ_ALL: - case common::Operator::O_EQ_ANY: - op = common::Operator::O_EQ; - break; - case common::Operator::O_NOT_EQ_ALL: - case common::Operator::O_NOT_EQ_ANY: - op = common::Operator::O_NOT_EQ; - break; - case common::Operator::O_LESS_ALL: - case common::Operator::O_LESS_ANY: - op = common::Operator::O_LESS; - break; - case common::Operator::O_MORE_ALL: - case common::Operator::O_MORE_ANY: - op = common::Operator::O_MORE; - break; - case common::Operator::O_LESS_EQ_ALL: - case common::Operator::O_LESS_EQ_ANY: - op = common::Operator::O_LESS_EQ; - break; - case common::Operator::O_MORE_EQ_ALL: - case common::Operator::O_MORE_EQ_ANY: - op = common::Operator::O_MORE_EQ; - break; - default: - // ALL/ANY can't be removed from any other operator - break; - } -} - -void Query::ExtractOperatorType(Item *&conds, common::Operator &op, bool &negative, char &like_esc) { - bool is_there_not; - like_esc = '\\'; - conds = UnRef(conds); - conds = FindOutAboutNot(conds, is_there_not); // it UnRefs the conds if there is need - - Item_func *cond_func = down_cast(conds); - switch (cond_func->functype()) { - case Item_func::BETWEEN: // between - op = is_there_not ? common::Operator::O_NOT_BETWEEN : common::Operator::O_BETWEEN; - break; - case Item_func::LIKE_FUNC: // like - op = is_there_not ? common::Operator::O_NOT_LIKE : common::Operator::O_LIKE; - like_esc = down_cast(cond_func)->escape; - break; - case Item_func::ISNULL_FUNC: // is null - op = common::Operator::O_IS_NULL; - break; - case Item_func::ISNOTNULL_FUNC: // is not null - op = common::Operator::O_NOT_NULL; - break; - case Item_func::IN_FUNC: // in - op = is_there_not ? common::Operator::O_NOT_IN : common::Operator::O_IN; - break; - case Item_func::EQ_FUNC: // = - op = negative ? common::Operator::O_NOT_EQ : common::Operator::O_EQ; - break; - case Item_func::NE_FUNC: // <> - op = negative ? common::Operator::O_EQ : common::Operator::O_NOT_EQ; - break; - case Item_func::LE_FUNC: // <= - op = negative ? common::Operator::O_MORE : common::Operator::O_LESS_EQ; - break; - case Item_func::GE_FUNC: // >= - op = negative ? common::Operator::O_LESS : common::Operator::O_MORE_EQ; - break; - case Item_func::GT_FUNC: // > - op = negative ? common::Operator::O_LESS_EQ : common::Operator::O_MORE; - break; - case Item_func::LT_FUNC: // < - op = negative ? common::Operator::O_MORE_EQ : common::Operator::O_LESS; - break; - case Item_func::MULT_EQUAL_FUNC: // a=b=c - op = common::Operator::O_MULT_EQUAL_FUNC; - break; - case Item_func::NOT_FUNC: // not - op = common::Operator::O_NOT_FUNC; - break; - case Item_func::NOT_ALL_FUNC: { - Item_func *cond_func = down_cast(conds); - negative = down_cast(cond_func) == nullptr; - ExtractOperatorType(cond_func->arguments()[0], op, negative, like_esc); - - if (down_cast(cond_func)) - MarkWithAny(op); - else if (down_cast(cond_func)) - MarkWithAll(op); - - conds = cond_func->arguments()[0]; - break; - } - case Item_func::UNKNOWN_FUNC: - op = common::Operator::O_UNKNOWN_FUNC; - break; - default: - op = common::Operator::O_ERROR; // unknown function type - break; - } -} - -vcolumn::VirtualColumn *Query::CreateColumnFromExpression(std::vector const &exprs, - TempTable *temp_table, int temp_table_alias, - MultiIndex *mind) { - DEBUG_ASSERT(exprs.size() > 0); - if (exprs.size() != 1) { - DEBUG_ASSERT(0); - } - - vcolumn::VirtualColumn *vc = nullptr; - - Item *item = exprs[0]->GetItem(); - if (exprs[0]->IsDeterministic() && (exprs[0]->GetVars().empty())) { - ColumnType type(exprs[0]->EvalType()); - vc = new vcolumn::ConstColumn(*(exprs[0]->Evaluate()), type, true); - } else if (vcolumn::VirtualColumn::IsConstExpression(exprs[0], temp_table_alias, &temp_table->GetAliases()) && - exprs[0]->IsDeterministic()) { - if (IsFieldItem(item)) { - // a special case when a naked column is a parameter - // without this column type would be a seen by mysql, not TIANMU. - // e.g. timestamp would be string 19 - TabID tab; - AttrID col; - - tab.n = exprs[0]->GetVars().begin()->tab; - col.n = exprs[0]->GetVars().begin()->col; - col.n = col.n < 0 ? -col.n - 1 : col.n; - ColumnType ct = ta[-tab.n - 1]->GetColumnType(col.n); - vc = new vcolumn::ConstExpressionColumn(exprs[0], ct, temp_table, temp_table_alias, mind); - } else - vc = new vcolumn::ConstExpressionColumn(exprs[0], temp_table, temp_table_alias, mind); - } else { - if (tianmu_control_.isOn()) { - if ((item->type()) == Item::FUNC_ITEM) { - Item_func *ifunc = down_cast(item); - tianmu_control_.lock(mind->m_conn->GetThreadID()) - << "Unoptimized expression near '" << ifunc->func_name() << "'" << system::unlock; - } - } - - vc = new vcolumn::ExpressionColumn(exprs[0], temp_table, temp_table_alias, mind); - if (static_cast(vc)->GetStringType() == MysqlExpression::StringType::STRING_TIME && - vc->TypeName() != common::CT::TIME) { // common::CT::TIME is already as int64_t - vcolumn::TypeCastColumn *tcc = new vcolumn::String2DateTimeCastColumn(vc, ColumnType(common::CT::TIME)); - temp_table->AddVirtColumn(vc); - vc = tcc; - } - } - - MysqlExpression::SetOfVars params = vc->GetParams(); - MysqlExpression::TypOfVars types; - for (auto &iter : params) { - types[iter] = ta[-iter.tab - 1]->GetColumnType(iter.col < 0 ? -iter.col - 1 : iter.col); - } - - vc->SetParamTypes(&types); - return vc; -} - -bool Query::IsConstExpr(MysqlExpression::SetOfVars &sv, const TabID &t) { - bool res = false; - for (auto &iter : sv) { - res |= cq->ExistsInTempTable(TabID(iter.tab), t); - } - - return !res; -} - -bool Query::IsParameterFromWhere(const TabID ¶ms_table) { - for (auto &it : subqueries_in_where) { - if (it.first == params_table) - return it.second; - } - - DEBUG_ASSERT(!"Subquery not properly placed on compilation stack"); - return true; -} - -const char *Query::GetTableName(Item_field *ifield) { - const char *table_name = nullptr; - - if (ifield->cached_table && !ifield->cached_table->is_view() && - !ifield->cached_table->is_view_or_derived()) // TIANMU UPGRADE - if (ifield->cached_table->referencing_view) - table_name = ifield->cached_table->referencing_view->table_name; - else - table_name = ifield->cached_table->table_name; - else if (ifield->result_field && ifield->result_field->table && - ifield->result_field->table->s->table_category != TABLE_CATEGORY_TEMPORARY) - table_name = ifield->result_field->table->s->table_name.str; - - return table_name; -} - -void Query::GetPrecisionScale(Item *item, int &precision, int &scale, bool max_scale) { - precision = item->decimal_precision(); - scale = item->decimals; - // if(precision > 19) { - // int integers = (precision - scale); - // precision = 19; - // scale = integers > 19 ? 0 : 19 - integers; - //} - if (scale > 18) { - precision -= (scale - 18); - scale = 18; - } - - if (precision > 18) - precision = 18; - - Item_func *item_func = down_cast(item); - if (max_scale && precision < 18 && item_func && std::strcmp(item_func->func_name(), "/") == 0) { - scale += 18 - precision; - if (scale > 15) - scale = 15; - precision = 18; - } -} - -TempTable *Query::Preexecute(CompiledQuery &qu, ResultSender *sender, [[maybe_unused]] bool display_now) { - if (TIANMU_LOGCHECK(LogCtl_Level::DEBUG)) { - qu.Print(this); - } - - std::vector conds(qu.NumOfConds()); - - TempTable *output_table = nullptr; // NOTE: this pointer will be returned by the function - - ta.resize(qu.NumOfTabs()); - auto global_limits = qu.GetGlobalLimit(); - - cq = &qu; - // Execution itself - for (int i = 0; i < qu.NumOfSteps(); i++) { - CompiledQuery::CQStep step = qu.Step(i); - std::shared_ptr t1_ptr, t2_ptr, t3_ptr; - - if (step.t1.n != common::NULL_VALUE_32) { - if (step.t1.n >= 0) - t1_ptr = Table(step.t1.n); // normal table - else { - t1_ptr = ta[-step.t1.n - 1]; // TempTable - } - } - - if (step.t2.n != common::NULL_VALUE_32) { - if (step.t2.n >= 0) - t2_ptr = Table(step.t2.n); // normal table - else { - t2_ptr = ta[-step.t2.n - 1]; // TempTable - } - } - - if (step.t3.n != common::NULL_VALUE_32) { - if (step.t3.n >= 0) - t3_ptr = Table(step.t3.n); // normal table - else { - t3_ptr = ta[-step.t3.n - 1]; // TempTable - } - } - // Some technical information - if (step.alias && std::strcmp(step.alias, "roughstats") == 0) { - // magical word (passed as table alias) to display statistics - dynamic_cast(ta[-step.t1.n - 1].get())->DisplayRSI(); - } - - if (step.alias && std::strcmp(step.alias, "roughattrstats") == 0) { - // magical word (passed as table alias) to display attr. statistics - m_conn->SetDisplayAttrStats(); - } - - // Implementation of steps - try { - switch (step.type) { - case CompiledQuery::StepType::TABLE_ALIAS: - ta[-step.t1.n - 1] = t2_ptr; - break; - case CompiledQuery::StepType::TMP_TABLE: - DEBUG_ASSERT(step.t1.n < 0); - ta[-step.t1.n - 1] = step.n1 - ? TempTable::Create(ta[-step.tables1[0].n - 1].get(), step.tables1[0].n, this, true) - : TempTable::Create(ta[-step.tables1[0].n - 1].get(), step.tables1[0].n, this); - dynamic_cast(ta[-step.t1.n - 1].get())->ReserveVirtColumns(qu.NumOfVirtualColumns(step.t1)); - break; - case CompiledQuery::StepType::CREATE_CONDS: - DEBUG_ASSERT(step.t1.n < 0); - step.e1.vc = (step.e1.vc_id != common::NULL_VALUE_32) - ? dynamic_cast(ta[-step.t1.n - 1].get())->GetVirtualColumn(step.e1.vc_id) - : nullptr; - step.e2.vc = (step.e2.vc_id != common::NULL_VALUE_32) - ? dynamic_cast(ta[-step.t1.n - 1].get())->GetVirtualColumn(step.e2.vc_id) - : nullptr; - step.e3.vc = (step.e3.vc_id != common::NULL_VALUE_32) - ? dynamic_cast(ta[-step.t1.n - 1].get())->GetVirtualColumn(step.e3.vc_id) - : nullptr; - - if (step.n1 != static_cast(CondType::OR_SUBTREE)) { // on result = false - conds[step.c1.n] = new Condition(); - if (step.c2.IsNull()) { - conds[step.c1.n]->AddDescriptor( - step.e1, step.op, step.e2, step.e3, dynamic_cast(ta[-step.t1.n - 1].get()), - qu.GetNumOfDimens(step.t1), - (step.op == common::Operator::O_LIKE || step.op == common::Operator::O_NOT_LIKE) ? char(step.n2) - : '\\'); - } else { - DEBUG_ASSERT(conds[step.c2.n]->IsType_Tree()); - conds[step.c1.n]->AddDescriptor(static_cast(conds[step.c2.n])->GetTree(), - dynamic_cast(ta[-step.t1.n - 1].get()), - qu.GetNumOfDimens(step.t1)); - } - } else { // on result = true - if (step.c2.IsNull()) - conds[step.c1.n] = new SingleTreeCondition(step.e1, step.op, step.e2, step.e3, - dynamic_cast(ta[-step.t1.n - 1].get()), - qu.GetNumOfDimens(step.t1), char(step.n2)); - else { - DEBUG_ASSERT(conds[step.c2.n]->IsType_Tree()); - conds[step.c1.n] = new Condition(); - conds[step.c1.n]->AddDescriptor((dynamic_cast(conds[step.c2.n])->GetTree()), - dynamic_cast(ta[-step.t1.n - 1].get()), - qu.GetNumOfDimens(step.t1)); - } - } - break; - case CompiledQuery::StepType::AND_F: - case CompiledQuery::StepType::OR_F: - if (!conds[step.c2.n]->IsType_Tree()) { - ASSERT(step.type == CompiledQuery::StepType::AND_F); - auto cond2 = conds[step.c2.n]; - - for (size_t i = 0; i < cond2->Size(); i++) { - auto &desc = (*cond2)[i]; - if (conds[step.c1.n]->IsType_Tree()) { - TempTable *temptb = dynamic_cast(ta[-qu.GetTableOfCond(step.c2).n - 1].get()); - int no_dims = qu.GetNumOfDimens(qu.GetTableOfCond(step.c2)); - if (desc.op == common::Operator::O_OR_TREE) { - static_cast(conds[step.c1.n]) - ->AddTree(common::LogicalOperator::O_AND, desc.tree, no_dims); - } else { - static_cast(conds[step.c1.n]) - ->AddDescriptor(common::LogicalOperator::O_AND, desc.attr, desc.op, desc.val1, desc.val2, temptb, - no_dims, desc.like_esc); - } - } else { - conds[step.c1.n]->AddDescriptor(desc); - } - } - } else if (conds[step.c1.n]->IsType_Tree()) { // on result = false - DEBUG_ASSERT(conds[step.c2.n]->IsType_Tree()); - common::LogicalOperator lop = (step.type == CompiledQuery::StepType::AND_F ? common::LogicalOperator::O_AND - : common::LogicalOperator::O_OR); - static_cast(conds[step.c1.n]) - ->AddTree(lop, static_cast(conds[step.c2.n])->GetTree(), - qu.GetNumOfDimens(step.t1)); - } else { - DEBUG_ASSERT(conds[step.c2.n]->IsType_Tree()); - conds[step.c1.n]->AddDescriptor(static_cast(conds[step.c2.n])->GetTree(), - dynamic_cast(ta[-qu.GetTableOfCond(step.c1).n - 1].get()), - qu.GetNumOfDimens(qu.GetTableOfCond(step.c1))); - } - break; - case CompiledQuery::StepType::OR_DESC: - case CompiledQuery::StepType::AND_DESC: { - common::LogicalOperator lop = - (step.type == CompiledQuery::StepType::AND_DESC ? common::LogicalOperator::O_AND - : common::LogicalOperator::O_OR); - step.e1.vc = (step.e1.vc_id != common::NULL_VALUE_32) - ? dynamic_cast(ta[-step.t1.n - 1].get())->GetVirtualColumn(step.e1.vc_id) - : nullptr; - step.e2.vc = (step.e2.vc_id != common::NULL_VALUE_32) - ? dynamic_cast(ta[-step.t1.n - 1].get())->GetVirtualColumn(step.e2.vc_id) - : nullptr; - step.e3.vc = (step.e3.vc_id != common::NULL_VALUE_32) - ? dynamic_cast(ta[-step.t1.n - 1].get())->GetVirtualColumn(step.e3.vc_id) - : nullptr; - - if (!conds[step.c1.n]->IsType_Tree()) { - DEBUG_ASSERT(conds[step.c1.n]); - conds[step.c1.n]->AddDescriptor( - step.e1, step.op, step.e2, step.e3, dynamic_cast(ta[-step.t1.n - 1].get()), - qu.GetNumOfDimens(step.t1), - (step.op == common::Operator::O_LIKE || step.op == common::Operator::O_NOT_LIKE) ? char(step.n2) - : '\\'); - } else - static_cast(conds[step.c1.n]) - ->AddDescriptor(lop, step.e1, step.op, step.e2, step.e3, - dynamic_cast(ta[-step.t1.n - 1].get()), qu.GetNumOfDimens(step.t1), - (step.op == common::Operator::O_LIKE || step.op == common::Operator::O_NOT_LIKE) - ? char(step.n2) - : '\\'); - break; - } - case CompiledQuery::StepType::T_MODE: - DEBUG_ASSERT(step.t1.n < 0 && ta[-step.t1.n - 1]->TableType() == TType::TEMP_TABLE); - dynamic_cast(ta[-step.t1.n - 1].get())->SetMode(step.tmpar, step.n1, step.n2); - break; - case CompiledQuery::StepType::JOIN_T: - DEBUG_ASSERT(step.t1.n < 0 && ta[-step.t1.n - 1]->TableType() == TType::TEMP_TABLE); - dynamic_cast(ta[-step.t1.n - 1].get())->JoinT(t2_ptr.get(), step.t2.n, step.jt); - break; - case CompiledQuery::StepType::ADD_CONDS: { - DEBUG_ASSERT(step.t1.n < 0 && ta[-step.t1.n - 1]->TableType() == TType::TEMP_TABLE); - if (step.c1.n == common::NULL_VALUE_32) - break; - - if (step.n1 != static_cast(CondType::HAVING_COND)) - conds[step.c1.n]->Simplify(); - - dynamic_cast(ta[-step.t1.n - 1].get())->AddConds(conds[step.c1.n], (CondType)step.n1); - break; - } - case CompiledQuery::StepType::LEFT_JOIN_ON: { - DEBUG_ASSERT(step.t1.n < 0 && ta[-step.t1.n - 1]->TableType() == TType::TEMP_TABLE); - - if (step.c1.n == common::NULL_VALUE_32) - break; - - dynamic_cast(ta[-step.t1.n - 1].get()) - ->AddLeftConds(conds[step.c1.n], step.tables1, step.tables2); - break; - } - case CompiledQuery::StepType::INNER_JOIN_ON: { - DEBUG_ASSERT(step.t1.n < 0 && ta[-step.t1.n - 1]->TableType() == TType::TEMP_TABLE); - - if (step.c1.n == common::NULL_VALUE_32) - break; - - dynamic_cast(ta[-step.t1.n - 1].get())->AddInnerConds(conds[step.c1.n], step.tables1); - break; - } - case CompiledQuery::StepType::APPLY_CONDS: { - int64_t cur_limit = -1; - auto *tb = dynamic_cast(ta[-step.t1.n - 1].get()); - - if (qu.FindDistinct(step.t1.n)) - tb->SetMode(TMParameter::TM_DISTINCT, 0, 0); - - if (qu.NoAggregationOrderingAndDistinct(step.t1.n)) - cur_limit = qu.FindLimit(step.t1.n); - - ParameterizedFilter *filter = tb->GetFilterP(); - - if (cur_limit != -1 && filter->NoParameterizedDescs()) - cur_limit = -1; - - std::set used_dims = qu.GetUsedDims(step.t1, ta); - - // no need any more to check WHERE for not used dims - bool is_simple_filter = true; // qu.IsSimpleFilter(step.c1); - if (used_dims.size() == 1 && used_dims.find(common::NULL_VALUE_32) != used_dims.end()) - is_simple_filter = false; - - for (int i = 0; i < filter->mind->NumOfDimensions(); i++) { - if (used_dims.find(i) == used_dims.end() && is_simple_filter) - filter->mind->ResetUsedInOutput(i); - else - filter->mind->SetUsedInOutput(i); - } - - if (IsRoughQuery()) { - filter->RoughUpdateParamFilter(); - } else - filter->UpdateMultiIndex(qu.CountColumnOnly(step.t1), cur_limit); - break; - } - case CompiledQuery::StepType::ADD_COLUMN: { - DEBUG_ASSERT(step.t1.n < 0 && ta[-step.t1.n - 1]->TableType() == TType::TEMP_TABLE); - CQTerm e(step.e1); - - if (e.vc_id != common::NULL_VALUE_32) - e.vc = dynamic_cast(ta[-step.t1.n - 1].get()) - ->GetVirtualColumn(step.e1.vc_id); // vc must have been created - step.a1.n = dynamic_cast(ta[-step.t1.n - 1].get()) - ->AddColumn(e, step.cop, step.alias, step.n1 ? true : false, step.si); - break; - } - case CompiledQuery::StepType::CREATE_VC: { - DEBUG_ASSERT(step.t1.n < 0 && ta[-step.t1.n - 1]->TableType() == TType::TEMP_TABLE); - - TempTable *t = dynamic_cast(ta[-step.t1.n - 1].get()); - DEBUG_ASSERT(t); - - if (step.mysql_expr.size() > 0) { - // vcolumn::VirtualColumn for Expression - DEBUG_ASSERT(step.mysql_expr.size() == 1); - - MultiIndex *mind = (step.t2.n == step.t1.n) ? t->GetOutputMultiIndexP() : t->GetMultiIndexP(); - int c = dynamic_cast(ta[-step.t1.n - 1].get()) - ->AddVirtColumn(CreateColumnFromExpression(step.mysql_expr, t, step.t1.n, mind), step.a1.n); - - ASSERT(c == step.a1.n, "AddVirtColumn failed"); - } else if (step.virt_cols.size() > 0) { - // vcolumn::VirtualColumn for IN - ColumnType ct; - if (step.a2.n != common::NULL_VALUE_32) - ct = dynamic_cast(ta[-step.t1.n - 1].get())->GetVirtualColumn(step.a2.n)->Type(); - - std::vector vcs; - for (uint i = 0; i < step.virt_cols.size(); i++) - vcs.push_back(dynamic_cast(ta[-step.t1.n - 1].get())->GetVirtualColumn(step.virt_cols[i])); - - int c = dynamic_cast(ta[-step.t1.n - 1].get()) - ->AddVirtColumn(new vcolumn::InSetColumn(ct, t->GetMultiIndexP(), vcs), step.a1.n); - - ASSERT(c == step.a1.n, "AddVirtColumn failed"); - } else if (step.a2.n != common::NULL_VALUE_32) { - // vcolumn::VirtualColumn for PhysicalColumn - JustATable *t_src = ta[-step.t2.n - 1].get(); - PhysicalColumn *phc{nullptr}; - - MultiIndex *mind = (step.t2.n == step.t1.n) ? t->GetOutputMultiIndexP() : t->GetMultiIndexP(); - int dim = (step.t2.n == step.t1.n) ? 0 : t->GetDimension(step.t2); - phc = dynamic_cast(t_src->GetColumn(step.a2.n >= 0 ? step.a2.n : -step.a2.n - 1)); - int c = dynamic_cast(ta[-step.t1.n - 1].get()) - ->AddVirtColumn( - new vcolumn::SingleColumn(phc, mind, step.t2.n, step.a2.n, ta[-step.t2.n - 1].get(), dim), - step.a1.n); - - ASSERT(c == step.a1.n, "AddVirtColumn failed"); - } else { - // vcolumn::VirtualColumn for Subquery - DEBUG_ASSERT(ta[-step.t2.n - 1]->TableType() == TType::TEMP_TABLE); - int c = - dynamic_cast(ta[-step.t1.n - 1].get()) - ->AddVirtColumn(new vcolumn::SubSelectColumn( - dynamic_cast(ta[-step.t2.n - 1].get()), - step.n1 == 1 ? t->GetOutputMultiIndexP() : t->GetMultiIndexP(), t, step.t1.n), - step.a1.n); - - ASSERT(c == step.a1.n, "AddVirtColumn failed"); - } - break; - } - case CompiledQuery::StepType::ADD_ORDER: { - DEBUG_ASSERT(step.t1.n < 0 && ta[-step.t1.n - 1]->TableType() == TType::TEMP_TABLE && step.n1 >= 0 && - step.n1 < 2); - DEBUG_ASSERT(step.a1.n >= 0 && step.a1.n < qu.NumOfVirtualColumns(step.t1)); - - TempTable *loc_t = dynamic_cast(ta[-step.t1.n - 1].get()); - loc_t->AddOrder(loc_t->GetVirtualColumn(step.a1.n), - (int)step.n1); // step.n1 = 0 for asc, 1 for desc - break; - } - case CompiledQuery::StepType::UNION: - DEBUG_ASSERT(step.t1.n < 0 && step.t2.n < 0 && step.t3.n < 0); - DEBUG_ASSERT(ta[-step.t2.n - 1]->TableType() == TType::TEMP_TABLE && - (step.t3.n == common::NULL_VALUE_32 || ta[-step.t3.n - 1]->TableType() == TType::TEMP_TABLE)); - - if (step.t1.n != step.t2.n) - ta[-step.t1.n - 1] = TempTable::Create(*dynamic_cast(ta[-step.t2.n - 1].get()), false); - - if (IsRoughQuery()) { - if (step.t3.n == common::NULL_VALUE_32) - dynamic_cast(ta[-step.t1.n - 1].get()) - ->RoughUnion(nullptr, qu.IsResultTable(step.t1) ? sender : nullptr); - else - dynamic_cast(ta[-step.t1.n - 1].get()) - ->RoughUnion(dynamic_cast(ta[-step.t3.n - 1].get()), - qu.IsResultTable(step.t1) ? sender : nullptr); - } else if (qu.IsResultTable(step.t1) && !qu.IsOrderedBy(step.t1) && step.n1) - dynamic_cast(ta[-step.t1.n - 1].get()) - ->Union(dynamic_cast(ta[-step.t3.n - 1].get()), (int)step.n1, sender, global_limits.first, - global_limits.second); - else { - if (step.t3.n == common::NULL_VALUE_32) - dynamic_cast(ta[-step.t1.n - 1].get())->Union(nullptr, (int)step.n1); - else { - dynamic_cast(ta[-step.t1.n - 1].get()) - ->Union(dynamic_cast(ta[-step.t3.n - 1].get()), (int)step.n1); - ta[-step.t3.n - 1].reset(); - } - } - break; - case CompiledQuery::StepType::RESULT: - DEBUG_ASSERT(step.t1.n < 0 && static_cast(-step.t1.n - 1) < ta.size() && - ta[-step.t1.n - 1]->TableType() == TType::TEMP_TABLE); - output_table = dynamic_cast(ta[-step.t1.n - 1].get()); - break; - case CompiledQuery::StepType::STEP_ERROR: - tianmu_control_.lock(m_conn->GetThreadID()) << "ERROR in step " << step.alias << system::unlock; - break; - default: - tianmu_control_.lock(m_conn->GetThreadID()) - << "ERROR: unsupported type of CQStep (" << static_cast(step.type) << ")" << system::unlock; - } - } catch (...) { - for (auto &c : conds) delete c; - throw; - } - } - - for (auto &c : conds) delete c; - - // NOTE: output_table is sent out of this function and should be managed - // elsewhere. before deleting all TempTables but output_table those have to be - // detected there are used by output_table - - return output_table; -} - -QueryRouteTo Query::Item2CQTerm(Item *an_arg, CQTerm &term, const TabID &tmp_table, CondType filter_type, bool negative, - Item *left_expr_for_subselect, common::Operator *oper_for_subselect) { - an_arg = UnRef(an_arg); - if (an_arg->type() == Item::SUBSELECT_ITEM) { - Item_subselect *item_subs = down_cast(an_arg); - DEBUG_ASSERT(item_subs && "The cast to (Item_subselect*) was unsuccessful"); - - bool ignore_limit = false; - if (dynamic_cast(item_subs) != nullptr || - dynamic_cast(item_subs) != nullptr) - ignore_limit = true; - st_select_lex_unit *select_unit = item_subs->unit; - - // needs to check if we can relay on subquery transformation to min/max - bool ignore_minmax = (dynamic_cast(item_subs) == nullptr && - dynamic_cast(item_subs) == nullptr && negative && - item_subs->substype() == Item_subselect::SINGLEROW_SUBS); - - subqueries_in_where.emplace_back(tmp_table, - item_subs->place() != CTX_HAVING && filter_type != CondType::HAVING_COND); - - // we need to make a copy of global map with table aliases so that subquery - // contains aliases of outer queries and itself but not "parallel" - // subqueries. Once subquery is compiled we can get rid of its aliases since - // they are not needed any longer and stay with aliases of outer query only - - auto outer_map_copy = table_alias2index_ptr; - TabID subselect; - QueryRouteTo res = Compile(cq, select_unit->first_select(), select_unit->union_distinct, &subselect, ignore_limit, - left_expr_for_subselect, oper_for_subselect, ignore_minmax, true); - - // restore outer query aliases - table_alias2index_ptr = outer_map_copy; - - subqueries_in_where.pop_back(); - if (res == QueryRouteTo::kToTianmu) { - AttrID vc; - vc.n = VirtualColumnAlreadyExists(tmp_table, subselect); - - if (vc.n == common::NULL_VALUE_32) { - cq->CreateVirtualColumn(vc, tmp_table, subselect, filter_type == CondType::HAVING_COND ? true : false); - tab_id2subselect.insert(std::make_pair(tmp_table, std::make_pair(vc.n, subselect))); - } - - if (oper_for_subselect) { - if (dynamic_cast(item_subs) != nullptr || - dynamic_cast(item_subs) != nullptr) { - if (negative) { - MarkWithAll(*oper_for_subselect); - if (dynamic_cast(item_subs) != nullptr && - *oper_for_subselect == common::Operator::O_IN) - *oper_for_subselect = common::Operator::O_EQ_ALL; - } else { - MarkWithAny(*oper_for_subselect); - if (dynamic_cast(item_subs) != nullptr && - dynamic_cast(item_subs)->all == 1) - *oper_for_subselect = common::Operator::O_EQ_ALL; - } - } else { - if (negative) { - // if(item_subs->substype() != Item_subselect::SINGLEROW_SUBS) - // return QueryRouteTo::kToMySQL; - MarkWithAll(*oper_for_subselect); - } else - UnmarkAllAny(*oper_for_subselect); - } - } - term = CQTerm(vc.n); - } - - return res; - } - - if (filter_type == CondType::HAVING_COND) { - common::ColOperation oper; - bool distinct; - if (QueryRouteTo::kToMySQL == OperationUnmysterify(an_arg, oper, distinct, - true)) // is_having_clause may be true only in - // case group by clause was present - return QueryRouteTo::kToMySQL; - - AttrID col, vc; - TabID tab; - - if ((IsFieldItem(an_arg) || IsAggregationOverFieldItem(an_arg)) && !FieldUnmysterify(an_arg, tab, col)) - return QueryRouteTo::kToMySQL; - - if (IsAggregationItem(an_arg) && HasAggregation(((Item_sum *)an_arg)->get_arg(0))) - return QueryRouteTo::kToMySQL; - - if ((IsFieldItem(an_arg) || IsAggregationOverFieldItem(an_arg)) && cq->ExistsInTempTable(tab, tmp_table)) { - int col_num = AddColumnForPhysColumn(an_arg, tmp_table, oper, distinct, true); - auto phys_vc = VirtualColumnAlreadyExists(tmp_table, tmp_table, AttrID(-col_num - 1)); - if (phys_vc.first == common::NULL_VALUE_32) { - phys_vc.first = tmp_table.n; - cq->CreateVirtualColumn(phys_vc.second, tmp_table, tmp_table, AttrID(col_num)); - phys2virt.insert(std::make_pair(std::pair(tmp_table.n, -col_num - 1), phys_vc)); - } - - vc.n = phys_vc.second; - } else if (IsCountStar(an_arg)) { - AttrID at; - at.n = GetAddColumnId(AttrID(common::NULL_VALUE_32), tmp_table, common::ColOperation::COUNT, false); - if (at.n == common::NULL_VALUE_32) // doesn't exist yet - cq->AddColumn(at, tmp_table, CQTerm(), common::ColOperation::COUNT, nullptr, false); - - auto phys_vc = VirtualColumnAlreadyExists(tmp_table, tmp_table, at); - if (phys_vc.first == common::NULL_VALUE_32) { - phys_vc.first = tmp_table.n; - cq->CreateVirtualColumn(phys_vc.second, tmp_table, tmp_table, at); - phys2virt.insert(std::make_pair(std::pair(tmp_table.n, at.n), phys_vc)); - } - - vc.n = phys_vc.second; - } else if (an_arg->type() == Item::VARBIN_ITEM) { - String str; - an_arg->val_str(&str); // sets null_value - - if (!an_arg->null_value) { - if (an_arg->max_length <= 8) { - Item *int_item = new Item_int((ulonglong)an_arg->val_int()); - MysqlExpression *mysql_expression = nullptr; - MysqlExpression::Item2VarID item2varid; - gc_expressions.push_back(mysql_expression = new MysqlExpression(int_item, item2varid)); - vc.n = VirtualColumnAlreadyExists(tmp_table, mysql_expression); - if (vc.n == common::NULL_VALUE_32) { - cq->CreateVirtualColumn(vc, tmp_table, mysql_expression); - tab_id2expression.insert(std::make_pair(tmp_table, std::make_pair(vc.n, mysql_expression))); - } - } else - return QueryRouteTo::kToMySQL; // too large binary to be treated - // as BIGINT - } else { - return QueryRouteTo::kToMySQL; - } - } else { - MysqlExpression *expr; - MysqlExpression::SetOfVars vars; - - if (WrapMysqlExpression(an_arg, tmp_table, expr, false, true) == WrapStatus::FAILURE) - return QueryRouteTo::kToMySQL; - if (IsConstExpr(expr->GetVars(), tmp_table)) { - vc.n = VirtualColumnAlreadyExists(tmp_table, expr); - if (vc.n == common::NULL_VALUE_32) { - cq->CreateVirtualColumn(vc, tmp_table, expr, tmp_table); - tab_id2expression.insert(std::make_pair(tmp_table, std::make_pair(vc.n, expr))); - } - } else if (IsAggregationItem(an_arg)) { - DEBUG_ASSERT(expr->GetItem()->type() == Item_tianmufield::get_tianmuitem_type()); - int col_num = - ((Item_tianmufield *)expr->GetItem())->varID[((Item_tianmufield *)expr->GetItem())->varID.size() - 1].col; - auto phys_vc = VirtualColumnAlreadyExists(tmp_table, tmp_table, AttrID(-col_num - 1)); - - if (phys_vc.first == common::NULL_VALUE_32) { - phys_vc.first = tmp_table.n; - cq->CreateVirtualColumn(phys_vc.second, tmp_table, tmp_table, AttrID(col_num)); - phys2virt.insert(std::make_pair(std::pair(tmp_table.n, -col_num - 1), phys_vc)); - } - - vc.n = phys_vc.second; - } else { - // int col_num = - // AddColumnForMysqlExpression(expr, - // tmp_table, - // nullptr, DELAYED, distinct, true); - vc.n = VirtualColumnAlreadyExists(tmp_table, expr); - if (vc.n == common::NULL_VALUE_32) { - cq->CreateVirtualColumn(vc, tmp_table, expr, tmp_table); - tab_id2expression.insert(std::make_pair(tmp_table, std::make_pair(vc.n, expr))); - } - } - } - - term = CQTerm(vc.n); - return QueryRouteTo::kToTianmu; - } else { - // WHERE FILTER - - AttrID vc; - AttrID col; - TabID tab; - if (IsFieldItem(an_arg) && !FieldUnmysterify(an_arg, tab, col)) - return QueryRouteTo::kToMySQL; - - if (IsFieldItem(an_arg) && cq->ExistsInTempTable(tab, tmp_table)) { - auto phys_vc = VirtualColumnAlreadyExists(tmp_table, tab, col); - if (phys_vc.first == common::NULL_VALUE_32) { - phys_vc.first = tmp_table.n; - cq->CreateVirtualColumn(phys_vc.second, tmp_table, tab, col); - phys2virt.insert(std::make_pair(std::pair(tab.n, col.n), phys_vc)); - } - - vc.n = phys_vc.second; - } else if (an_arg->type() == Item::VARBIN_ITEM) { - String str; - an_arg->val_str(&str); // sets null_value - - if (!an_arg->null_value) { - if (an_arg->max_length <= 8) { - Item *int_item = new Item_int((ulonglong)an_arg->val_int()); - MysqlExpression *mysql_expression = nullptr; - MysqlExpression::Item2VarID item2varid; - gc_expressions.push_back(mysql_expression = new MysqlExpression(int_item, item2varid)); - vc.n = VirtualColumnAlreadyExists(tmp_table, mysql_expression); - - if (vc.n == common::NULL_VALUE_32) { - cq->CreateVirtualColumn(vc, tmp_table, mysql_expression); - tab_id2expression.insert(std::make_pair(tmp_table, std::make_pair(vc.n, mysql_expression))); - } - } else - return QueryRouteTo::kToMySQL; // too large binary to be treated - // as BIGINT - } else { - return QueryRouteTo::kToMySQL; - } - } else { - MysqlExpression *expr; - WrapStatus ws = WrapMysqlExpression(an_arg, tmp_table, expr, true, false); - if (ws != WrapStatus::SUCCESS) - return QueryRouteTo::kToMySQL; - vc.n = VirtualColumnAlreadyExists(tmp_table, expr); - if (vc.n == common::NULL_VALUE_32) { - cq->CreateVirtualColumn(vc, tmp_table, expr); - tab_id2expression.insert(std::make_pair(tmp_table, std::make_pair(vc.n, expr))); - } - } - - term = CQTerm(vc.n); - return QueryRouteTo::kToTianmu; - } - return QueryRouteTo::kToMySQL; -} - -CondID Query::ConditionNumberFromMultipleEquality(Item_equal *conds, const TabID &tmp_table, CondType filter_type, - CondID *and_me_filter, bool is_or_subtree) { - Item_equal_iterator li(*conds); - - CQTerm zero_term, first_term, next_term; - Item_field *ifield{nullptr}; - Item *const_item = conds->get_const(); - - if (const_item) { - if (QueryRouteTo::kToMySQL == Item2CQTerm(const_item, zero_term, tmp_table, filter_type)) - return CondID(-1); - } else { - ifield = li++; - if (QueryRouteTo::kToMySQL == Item2CQTerm(ifield, zero_term, tmp_table, filter_type)) - return CondID(-1); - } - - ifield = li++; - if (QueryRouteTo::kToMySQL == Item2CQTerm(ifield, first_term, tmp_table, filter_type)) - return CondID(-1); - - CondID filter; - cq->CreateConds(filter, tmp_table, first_term, common::Operator::O_EQ, zero_term, CQTerm(), - is_or_subtree || filter_type == CondType::HAVING_COND); - - while ((ifield = li++) != nullptr) { - if (QueryRouteTo::kToMySQL == Item2CQTerm(ifield, next_term, tmp_table, filter_type)) - return CondID(-1); - - cq->And(filter, tmp_table, next_term, common::Operator::O_EQ, zero_term); - } - - if (and_me_filter) { - if (is_or_subtree) { - cq->Or(*and_me_filter, tmp_table, filter); - } else { - cq->And(*and_me_filter, tmp_table, filter); - } - } - - if (and_me_filter) - filter = *and_me_filter; - - return filter; -} - -Item *Query::FindOutAboutNot(Item *it, bool &is_there_not) { - is_there_not = false; - - /*First we try to take care of IN and BETWEEN*/ - Item_func_opt_neg *it_maybe_neg = dynamic_cast(it); - if (it_maybe_neg) { - is_there_not = it_maybe_neg->negated; - return it; - } - - Item_func *func = down_cast(it); - /*Then we remove negation in case of LIKE (or sth. else)*/ - if (func && func->functype() == Item_func::NOT_FUNC) { - Item *arg = UnRef(func->arguments()[0]); - // OK, in case of subselects (and possibly other stuff) NOT is handled by - // other statements, So we narrow the choice of cases in which we handle NOT - // down to LIKE - if (arg->type() == Item::FUNC_ITEM && down_cast(arg)->functype() == Item_func::LIKE_FUNC) { - is_there_not = true; - return arg; - } - } - return it; -} - -CondID Query::ConditionNumberFromComparison(Item *conds, const TabID &tmp_table, CondType filter_type, - CondID *and_me_filter, bool is_or_subtree, bool negative) { - CondID filter; - common::Operator op; /*{ common::Operator::O_EQ, common::Operator::O_NOT_EQ, common::Operator::O_LESS, - common::Operator::O_MORE, common::Operator::O_LESS_EQ, common::Operator::O_MORE_EQ, - common::Operator::O_IS_NULL, common::Operator::O_NOT_NULL, common::Operator::O_BETWEEN, - common::Operator::O_LIKE, common::Operator::O_IN, common::Operator::O_ESCAPE etc...};*/ - char like_esc; - Item_in_optimizer *in_opt = nullptr; // set if IN expression with subselect - - ExtractOperatorType(conds, op, negative, like_esc); - Item_func *cond_func = down_cast(conds); - - if (op == common::Operator::O_MULT_EQUAL_FUNC) - return ConditionNumberFromMultipleEquality(down_cast(conds), tmp_table, filter_type, and_me_filter, - is_or_subtree); - else if (op == common::Operator::O_NOT_FUNC) { - if (cond_func->arg_count != 1 || dynamic_cast(cond_func->arguments()[0]) == nullptr) - return CondID(-2); - - return ConditionNumberFromComparison(cond_func->arguments()[0], tmp_table, filter_type, and_me_filter, - is_or_subtree, true); - } else if (op == common::Operator::O_NOT_ALL_FUNC) { - if (cond_func->arg_count != 1) - return CondID(-1); - - return ConditionNumberFromComparison(cond_func->arguments()[0], tmp_table, filter_type, and_me_filter, - is_or_subtree, dynamic_cast(cond_func) == nullptr); - } else if (op == common::Operator::O_UNKNOWN_FUNC) { - in_opt = dynamic_cast(cond_func); - - if (in_opt == nullptr || cond_func->arg_count != 2 || in_opt->arguments()[0]->cols() != 1) - return CondID(-2); - - op = common::Operator::O_IN; - } else if (op == common::Operator::O_ERROR) - return CondID(-2); // unknown function type - - if ((cond_func->arg_count > 3 && op != common::Operator::O_IN && op != common::Operator::O_NOT_IN)) - return CondID(-1); // argument count error - - CQTerm terms[3]; - std::vector exprs; - std::vector vcs; - - Item **args = cond_func->arguments(); - for (uint i = 0; i < cond_func->arg_count; i++) { - Item *an_arg = UnRef(args[i]); - if ((op == common::Operator::O_IN || op == common::Operator::O_NOT_IN) && i > 0) { - if (i == 1 && in_opt) { - if (QueryRouteTo::kToMySQL == - Item2CQTerm(an_arg, terms[i], tmp_table, filter_type, negative, *in_opt->get_cache(), &op)) - return CondID(-1); - - if (negative) - switch (op) { - case common::Operator::O_EQ: - op = common::Operator::O_NOT_EQ; - break; - case common::Operator::O_EQ_ALL: - op = common::Operator::O_NOT_IN; - break; - case common::Operator::O_EQ_ANY: - op = common::Operator::O_NOT_EQ_ANY; - break; - case common::Operator::O_NOT_EQ: - op = common::Operator::O_EQ; - break; - case common::Operator::O_NOT_EQ_ALL: - op = common::Operator::O_EQ_ALL; - break; - case common::Operator::O_NOT_EQ_ANY: - op = common::Operator::O_EQ_ANY; - break; - case common::Operator::O_LESS_EQ: - op = common::Operator::O_MORE; - break; - case common::Operator::O_LESS_EQ_ALL: - op = common::Operator::O_MORE_ALL; - break; - case common::Operator::O_LESS_EQ_ANY: - op = common::Operator::O_MORE_ANY; - break; - case common::Operator::O_MORE_EQ: - op = common::Operator::O_LESS; - break; - case common::Operator::O_MORE_EQ_ALL: - op = common::Operator::O_LESS_ALL; - break; - case common::Operator::O_MORE_EQ_ANY: - op = common::Operator::O_LESS_ANY; - break; - case common::Operator::O_MORE: - op = common::Operator::O_LESS_EQ; - break; - case common::Operator::O_MORE_ALL: - op = common::Operator::O_LESS_EQ_ALL; - break; - case common::Operator::O_MORE_ANY: - op = common::Operator::O_LESS_EQ_ANY; - break; - case common::Operator::O_LESS: - op = common::Operator::O_MORE_EQ; - break; - case common::Operator::O_LESS_ALL: - op = common::Operator::O_MORE_EQ_ALL; - break; - case common::Operator::O_LESS_ANY: - op = common::Operator::O_MORE_EQ_ANY; - break; - case common::Operator::O_LIKE: - op = common::Operator::O_NOT_LIKE; - break; - case common::Operator::O_IN: - op = common::Operator::O_NOT_IN; - break; - case common::Operator::O_NOT_LIKE: - op = common::Operator::O_LIKE; - break; - case common::Operator::O_NOT_IN: - op = common::Operator::O_IN; - break; - default: - return CondID(-1); - } - } else { - CQTerm t; - if (QueryRouteTo::kToMySQL == Item2CQTerm(an_arg, t, tmp_table, filter_type, - an_arg->type() == Item::SUBSELECT_ITEM ? negative : false, nullptr, - &op)) - return CondID(-1); - vcs.push_back(t.vc_id); - } - } else { - if (QueryRouteTo::kToMySQL == Item2CQTerm(an_arg, terms[i], tmp_table, filter_type, - an_arg->type() == Item::SUBSELECT_ITEM ? negative : false, nullptr, - &op)) - return CondID(-1); - if ((op == common::Operator::O_LIKE || op == common::Operator::O_NOT_LIKE) && - !(an_arg->field_type() == MYSQL_TYPE_VARCHAR || an_arg->field_type() == MYSQL_TYPE_STRING || - an_arg->field_type() == MYSQL_TYPE_VAR_STRING || an_arg->field_type() == MYSQL_TYPE_BLOB || - an_arg->field_type() == MYSQL_TYPE_NULL)) { // issue: #763, Argument of LIKE is NULL - - return CondID(-1); // Argument of LIKE is not a string or null, return to MySQL. - } - } - } - - if ((op == common::Operator::O_IN || op == common::Operator::O_NOT_IN) && !in_opt) { - AttrID vc; - vc.n = VirtualColumnAlreadyExists(tmp_table, vcs, AttrID(terms[0].vc_id)); - - if (vc.n == common::NULL_VALUE_32) { - cq->CreateVirtualColumn(vc, tmp_table, vcs, AttrID(terms[0].vc_id)); - tab_id2inset.insert(std::make_pair(tmp_table, std::make_pair(vc.n, std::make_pair(vcs, AttrID(terms[0].vc_id))))); - } - - terms[1] = CQTerm(vc.n); - } - - if (!and_me_filter) - cq->CreateConds(filter, tmp_table, terms[0], op, terms[1], terms[2], - is_or_subtree || filter_type == CondType::HAVING_COND, like_esc); - else { - if (is_or_subtree) - cq->Or(*and_me_filter, tmp_table, terms[0], op, terms[1], terms[2]); - else - cq->And(*and_me_filter, tmp_table, terms[0], op, terms[1], terms[2]); - - filter = *and_me_filter; - } - - return filter; -} - -CondID Query::ConditionNumberFromNaked(Item *conds, const TabID &tmp_table, CondType filter_type, CondID *and_me_filter, - bool is_or_subtree) { - CondID filter; - CQTerm naked_col; - - if (QueryRouteTo::kToMySQL == Item2CQTerm(conds, naked_col, tmp_table, filter_type, - conds->type() == Item::SUBSELECT_ITEM ? (and_me_filter != nullptr) : false)) - return CondID(-1); - - bool is_string = conds->result_type() == STRING_RESULT; - MysqlExpression::Item2VarID item2varid; - AttrID vc; - Item *zero_item; - - if (is_string) - zero_item = new Item_empty_string("", 0, conds->collation.collation); - else - zero_item = new Item_int((longlong)0); - - MysqlExpression *mysql_expression = nullptr; - gc_expressions.push_back(mysql_expression = new MysqlExpression(zero_item, item2varid)); - - // TODO: where mysql_expression & zero_item is destroyed ??? - vc.n = VirtualColumnAlreadyExists(tmp_table, mysql_expression); - if (vc.n == common::NULL_VALUE_32) { - cq->CreateVirtualColumn(vc, tmp_table, mysql_expression); - tab_id2expression.insert(std::make_pair(tmp_table, std::make_pair(vc.n, mysql_expression))); - } - - if (!and_me_filter) - cq->CreateConds(filter, tmp_table, naked_col, common::Operator::O_NOT_EQ, CQTerm(vc.n), CQTerm(), - is_or_subtree || filter_type == CondType::HAVING_COND); - else { - if (is_or_subtree) - cq->Or(*and_me_filter, tmp_table, naked_col, common::Operator::O_NOT_EQ, CQTerm(vc.n), CQTerm()); - else - cq->And(*and_me_filter, tmp_table, naked_col, common::Operator::O_NOT_EQ, CQTerm(vc.n), CQTerm()); - filter = *and_me_filter; - } - - return filter; -} - -struct ItemFieldCompare { - bool operator()(Item_field *const &f1, Item_field *const &f2) const { return f1->field < f2->field; } -}; - -CondID Query::ConditionNumber(Item *conds, const TabID &tmp_table, CondType filter_type, CondID *and_me_filter, - bool is_or_subtree) { - // we know, that conds != 0 - // returns -1 on error - // >=0 is a created filter number - conds = UnRef(conds); - Item::Type cond_type = conds->type(); - CondID cond_id; - - if (cond_type == Item::COND_ITEM) { - Item_cond *cond_cond = (Item_cond *)conds; - Item_func::Functype func_type = cond_cond->functype(); - - switch (func_type) { - case Item_func::COND_AND_FUNC: { - List_iterator_fast li(*(cond_cond->argument_list())); - Item *item{nullptr}; - std::unique_ptr and_cond; - while ((item = li++) != nullptr) { - CondID res = ConditionNumber(item, tmp_table, filter_type, and_cond.get(), - /* - if there is no and_cond the filter has to be created and info - about tree/no tree like descriptor has to be passed recursively - down once filter is created we pass 'false' to indicate AND - */ - and_cond.get() ? false : is_or_subtree); - if (res.IsInvalid()) - return res; - - if (!and_cond.get()) - and_cond = std::unique_ptr(new CondID(res.n)); - } - - if (and_cond.get() != nullptr) { - cond_id.n = and_cond->n; - - if (and_me_filter && is_or_subtree) - cq->Or(*and_me_filter, tmp_table, cond_id); - else if (and_me_filter && !is_or_subtree) - cq->And(*and_me_filter, tmp_table, cond_id); - } - - break; - } - case Item_func::COND_OR_FUNC: { - List_iterator_fast li(*(cond_cond->argument_list())); - Item *item; - // rewriting a=1 or a=2 or b=3 or c=4 into a IN (1,2) or b IN (3,4) - // step1: collect all constants for every column - // a -> 1,2 - // b -> 3,4 - std::map, ItemFieldCompare> value_map; - std::map is_transformed; - std::unique_ptr or_cond; - - while ((item = li++) != nullptr) { - is_transformed[item] = false; - Item_func_eq *item_func = dynamic_cast(item); - - if (!item_func) - continue; - - Item **args = item_func->arguments(); - DEBUG_ASSERT(item_func->arg_count == 2); - Item *first_arg = UnRef(args[0]); - Item *sec_arg = UnRef(args[1]); - - if (IsConstItem(first_arg) && IsFieldItem(sec_arg)) - std::swap(first_arg, sec_arg); - - if (IsFieldItem(first_arg) && IsConstItem(sec_arg)) { - is_transformed[item] = true; - CQTerm t; - - if (QueryRouteTo::kToMySQL == Item2CQTerm(sec_arg, t, tmp_table, filter_type)) - return CondID(-1); - value_map[static_cast(first_arg)].insert(t.vc_id); - } - } - - bool create_or_subtree = is_or_subtree; - li.rewind(); - // generate non-transformed conditions - while ((item = li++) != nullptr) { - if (is_transformed[item] == true) - continue; - - create_or_subtree = true; - CondID res = ConditionNumber(item, tmp_table, filter_type, or_cond.get(), true /*CondType::OR_SUBTREE*/); - - if (res.IsInvalid()) - return res; - - if (!or_cond) - or_cond.reset(new CondID(res.n)); - } - - create_or_subtree = create_or_subtree || (value_map.size() > 1); - // generate re-written INs - // one IN for every element of value_map - for (auto &it : value_map) { - CQTerm terms[2]; - if (QueryRouteTo::kToMySQL == Item2CQTerm(it.first, terms[0], tmp_table, filter_type)) - return CondID(-1); - - AttrID vc; - std::vector vcv(it.second.begin(), it.second.end()); - CondID c_id; - - if (vcv.size() > 1) { - cq->CreateVirtualColumn(vc, tmp_table, vcv, AttrID(terms[0].vc_id)); - terms[1] = CQTerm(vc.n); - - if (!or_cond) { - if (and_me_filter && !create_or_subtree) { - cq->And(*and_me_filter, tmp_table, terms[0], common::Operator::O_IN, terms[1], CQTerm()); - c_id = *and_me_filter; - and_me_filter = nullptr; - } else - cq->CreateConds(c_id, tmp_table, terms[0], common::Operator::O_IN, terms[1], CQTerm(), - create_or_subtree || filter_type == CondType::HAVING_COND); - or_cond.reset(new CondID(c_id.n)); - } else { - cq->Or(*or_cond, tmp_table, terms[0], common::Operator::O_IN, terms[1], CQTerm()); - c_id = *or_cond; - } - } else { - terms[1] = CQTerm(vcv[0]); - if (!or_cond) { - if (and_me_filter && !create_or_subtree) { - cq->And(*and_me_filter, tmp_table, terms[0], common::Operator::O_EQ, terms[1], CQTerm()); - c_id = *and_me_filter; - and_me_filter = nullptr; - } else - cq->CreateConds(c_id, tmp_table, terms[0], common::Operator::O_EQ, terms[1], CQTerm(), - create_or_subtree || filter_type == CondType::HAVING_COND); - or_cond.reset(new CondID(c_id.n)); - } else { - cq->Or(*or_cond, tmp_table, terms[0], common::Operator::O_EQ, terms[1], CQTerm()); - c_id = *or_cond; - } - } - - if (c_id.IsInvalid()) { - return c_id; - } - } - - if (or_cond.get() != nullptr) { - cond_id.n = or_cond->n; - - if (and_me_filter && !is_or_subtree) - cq->And(*and_me_filter, tmp_table, cond_id); - else if (and_me_filter && is_or_subtree) - cq->Or(*and_me_filter, tmp_table, cond_id); - else if (filter_type != CondType::HAVING_COND && create_or_subtree && !is_or_subtree) - cq->CreateConds(cond_id, tmp_table, cond_id, create_or_subtree || filter_type == CondType::HAVING_COND); - } - break; - } - - case Item_func::XOR_FUNC: // we don't handle xor as yet - default: - return CondID(-1); // unknown function type - } // end switch() - } else if (cond_type == Item::FUNC_ITEM) { - Item_func *cond_func = (Item_func *)conds; - Item_func::Functype func_type = cond_func->functype(); - Item *arg = nullptr; - - if (cond_func->arg_count == 1) - arg = cond_func->arguments()[0]; - - if (func_type == Item_func::NOT_FUNC && arg != nullptr && arg->type() == Item::SUBSELECT_ITEM && - ((Item_subselect *)arg)->substype() == Item_subselect::EXISTS_SUBS) { - CQTerm term; - - if (QueryRouteTo::kToMySQL == Item2CQTerm(arg, term, tmp_table, filter_type)) - return CondID(-1); - - if (!and_me_filter) - cq->CreateConds(cond_id, tmp_table, term, common::Operator::O_NOT_EXISTS, CQTerm(), CQTerm(), - is_or_subtree || filter_type == CondType::HAVING_COND); - else { - if (is_or_subtree) - cq->Or(*and_me_filter, tmp_table, term, common::Operator::O_NOT_EXISTS, CQTerm(), CQTerm()); - else - cq->And(*and_me_filter, tmp_table, term, common::Operator::O_NOT_EXISTS, CQTerm(), CQTerm()); - cond_id = *and_me_filter; - } - } else if (func_type == Item_func::XOR_FUNC) { - return CondID(-1); - } else { - CondID val = ConditionNumberFromComparison(cond_func, tmp_table, filter_type, and_me_filter, is_or_subtree); - - if (val.n == -2) - val = ConditionNumberFromNaked(conds, tmp_table, filter_type, and_me_filter, is_or_subtree); - - return val; - } - } else if (cond_type == Item::SUBSELECT_ITEM && - ((Item_subselect *)conds)->substype() == Item_subselect::EXISTS_SUBS) { - CQTerm term; - - if (QueryRouteTo::kToMySQL == Item2CQTerm(conds, term, tmp_table, filter_type)) - return CondID(-1); - - if (!and_me_filter) { - cq->CreateConds(cond_id, tmp_table, term, common::Operator::O_EXISTS, CQTerm(), CQTerm(), - is_or_subtree || filter_type == CondType::HAVING_COND); - } else { - if (is_or_subtree) - cq->Or(*and_me_filter, tmp_table, term, common::Operator::O_EXISTS, CQTerm(), CQTerm()); - else - cq->And(*and_me_filter, tmp_table, term, common::Operator::O_EXISTS, CQTerm(), CQTerm()); - cond_id = *and_me_filter; - } - } else if (cond_type == Item::FIELD_ITEM || cond_type == Item::SUM_FUNC_ITEM || cond_type == Item::SUBSELECT_ITEM || - cond_type == Item::INT_ITEM || cond_type == Item::STRING_ITEM || cond_type == Item::NULL_ITEM || - cond_type == Item::REAL_ITEM || cond_type == Item::DECIMAL_ITEM) { - return ConditionNumberFromNaked(conds, tmp_table, filter_type, and_me_filter, is_or_subtree); - } - - return cond_id; -} - -QueryRouteTo Query::BuildConditions(Item *conds, CondID &cond_id, CompiledQuery *cq, const TabID &tmp_table, - CondType filter_type, bool is_zero_result, [[maybe_unused]] JoinType join_type) { - conds = UnRef(conds); - PrintItemTree("BuildFiler(), item tree passed in 'conds':", conds); - - if (is_zero_result) { - CondID fi; - cq->CreateConds(fi, tmp_table, CQTerm(), common::Operator::O_FALSE, CQTerm(), CQTerm(), false); - cond_id = fi; - return QueryRouteTo::kToTianmu; - } - - if (!conds) - return QueryRouteTo::kToTianmu; // No Conditions - no filters. OK - - // keep local copies of class fields to be changed - CompiledQuery *saved_cq = this->cq; - - // copy method arguments to class fields - this->cq = cq; - - CondID res = ConditionNumber(conds, tmp_table, filter_type); - if (res.IsInvalid()) - return QueryRouteTo::kToMySQL; - - if (filter_type == CondType::HAVING_COND) { - cq->CreateConds(res, tmp_table, res, false); - } - - // restore original values of class fields (may be necessary if this method is - // called recursively) - this->cq = saved_cq; - if (res.IsInvalid()) - return QueryRouteTo::kToMySQL; - cond_id = res; - return QueryRouteTo::kToTianmu; -} - -bool Query::ClearSubselectTransformation(common::Operator &oper_for_subselect, Item *&field_for_subselect, Item *&conds, - Item *&having, Item *&cond_to_reinsert, List *&list_to_reinsert, - Item *left_expr_for_subselect) { - cond_to_reinsert = nullptr; - list_to_reinsert = nullptr; - Item *cond_removed = nullptr; - Item *left_ref = nullptr; - if (having && (having->type() == Item::COND_ITEM || - (having->type() == Item::FUNC_ITEM && - down_cast(having)->functype() != Item_func::ISNOTNULLTEST_FUNC && - (down_cast(having)->functype() != Item_func::TRIG_COND_FUNC || - down_cast(having)->arguments()[0]->type() != Item::FUNC_ITEM || - down_cast(down_cast(having)->arguments()[0])->functype() != - Item_func::ISNOTNULLTEST_FUNC)))) { - if (having->type() == Item::COND_ITEM) { - Item_cond *having_cond = down_cast(having); - // if the condition is a complex formula it must be AND - if (having_cond->functype() != Item_func::COND_AND_FUNC) - return false; - // the extra condition is in the last argument - if (having_cond->argument_list()->elements < 2) - return false; - - List_iterator li(*(having_cond->argument_list())); - - while (li++ != nullptr) cond_to_reinsert = *li.ref(); - li.rewind(); - - while (*li.ref() != cond_to_reinsert) li++; - li.remove(); - - list_to_reinsert = having_cond->argument_list(); - cond_removed = cond_to_reinsert; - } else { - // if no complex boolean formula the original condition was empty - cond_removed = having; - having = nullptr; - } - - cond_removed = UnRef(cond_removed); - // check if the extra condition was wrapped into trigger - if (cond_removed->type() == Item::FUNC_ITEM && - down_cast(cond_removed)->functype() == Item_func::TRIG_COND_FUNC) { - cond_removed = down_cast(cond_removed)->arguments()[0]; - cond_removed = UnRef(cond_removed); - } - // check if the extra condition is a comparison - if (cond_removed->type() != Item::FUNC_ITEM || down_cast(cond_removed)->arg_count != 2) - return false; - // the right side of equality is the field of the original subselect - if (dynamic_cast(down_cast(cond_removed)->arguments()[1]) == nullptr) - return false; - - field_for_subselect = nullptr; - // the left side of equality should be the left side of the original - // expression with subselect - left_ref = down_cast(cond_removed)->arguments()[0]; - } else if (!having || (having->type() == Item::FUNC_ITEM && - (down_cast(having)->functype() == Item_func::ISNOTNULLTEST_FUNC || - down_cast(having)->functype() == Item_func::TRIG_COND_FUNC))) { - if (!conds) - return false; - - if (conds->type() == Item::COND_ITEM && down_cast(conds)->functype() == Item_func::COND_AND_FUNC) { - // if the condition is a conjunctive formula - // the extra condition should be in the last argument - if (down_cast(conds)->argument_list()->elements < 2) - return false; - - List_iterator li(*(down_cast(conds)->argument_list())); - while (li++ != nullptr) cond_to_reinsert = *li.ref(); - li.rewind(); - - while (*li.ref() != cond_to_reinsert) li++; - li.remove(); - - list_to_reinsert = down_cast(conds)->argument_list(); - cond_removed = cond_to_reinsert; - } else { - // if no conjunctive formula the original condition was empty - cond_removed = conds; - conds = nullptr; - } - - if (cond_removed->type() == Item::FUNC_ITEM && - down_cast(cond_removed)->functype() == Item_func::TRIG_COND_FUNC) { - // Condition was wrapped into trigger - cond_removed = down_cast(down_cast(cond_removed)->arguments()[0]); - } - if (cond_removed->type() == Item::COND_ITEM && - down_cast(cond_removed)->functype() == Item_func::COND_OR_FUNC) { - // if the subselect field could have null values - // equality condition was OR-ed with IS nullptr condition - Item_cond *cond_cond = down_cast(cond_removed); - List_iterator_fast li(*(cond_cond->argument_list())); - cond_removed = li++; - - if (cond_removed == nullptr) - return false; - - if (li++ == nullptr) - return false; - - if (li++ != nullptr) - return false; - // the original having was empty - having = nullptr; - } - - // check if the extra condition is a comparison - if (cond_removed->type() != Item::FUNC_ITEM || down_cast(cond_removed)->arg_count != 2) - return false; - - auto item_func = down_cast(cond_removed); - if (item_func->arguments()[0]->type() == Item::REF_ITEM) { - // the right side of equality is the field of the original subselect - field_for_subselect = item_func->arguments()[1]; - // the left side of equality should be the left side of the original - // expression with subselect - left_ref = item_func->arguments()[0]; - } else if (item_func->arguments()[1]->type() == Item::REF_ITEM) { - // ref #767 - // the left side of equality is the field of the original subselect - field_for_subselect = item_func->arguments()[0]; - // the right side of equality should be the left side of the original - // expression with subselect - left_ref = item_func->arguments()[1]; - } else { - return false; - } - } else - return false; - - if (dynamic_cast(left_ref) != nullptr) - left_ref = down_cast(left_ref)->real_item(); - if (left_ref->type() != Item::REF_ITEM || down_cast(left_ref)->ref_type() != Item_ref::DIRECT_REF || - down_cast(left_ref)->real_item() != left_expr_for_subselect) - return false; - - // set the operation type - switch (down_cast(cond_removed)->functype()) { - case Item_func::EQ_FUNC: - oper_for_subselect = common::Operator::O_IN; - break; - case Item_func::NE_FUNC: - oper_for_subselect = common::Operator::O_NOT_EQ; - break; - case Item_func::LT_FUNC: - oper_for_subselect = common::Operator::O_LESS; - break; - case Item_func::LE_FUNC: - oper_for_subselect = common::Operator::O_LESS_EQ; - break; - case Item_func::GT_FUNC: - oper_for_subselect = common::Operator::O_MORE; - break; - case Item_func::GE_FUNC: - oper_for_subselect = common::Operator::O_MORE_EQ; - break; - default: - return false; - } - return true; -} - -// used for verification if all tables involved in a condition were already seen -// used only in assert macro -TableStatus Query::PrefixCheck(Item *conds) { - conds = UnRef(conds); - if (!conds) - return TableStatus::TABLE_YET_UNSEEN_INVOLVED; - - Item::Type cond_type = conds->type(); - CondID filter; - switch (cond_type) { - case Item::COND_ITEM: { - Item_cond *cond_cond = down_cast(conds); - Item_func::Functype func_type = cond_cond->functype(); - - switch (func_type) { - case Item_func::COND_AND_FUNC: - case Item_func::COND_OR_FUNC: { - // List_iterator_fast - // list_equal(((Item_cond_and*)cond_cond)->cond_equal.current_level); - List_iterator_fast li(*(cond_cond->argument_list())); - Item *item{nullptr}; - while ((item = li++) /*|| (item = list_equal++)*/) { - TableStatus ret = PrefixCheck(item); - - if (TableStatus::TABLE_SEEN_INVOLVED == ret) - return TableStatus::TABLE_SEEN_INVOLVED; - - if (TableStatus::TABLE_YET_UNSEEN_INVOLVED == ret) - return TableStatus::TABLE_YET_UNSEEN_INVOLVED; - // for RETURN_TO_RCBASE_ROUTE the next item is evaluated - } - break; - } - case Item_func::XOR_FUNC: // we don't handle xor as yet - default: - return TableStatus::TABLE_UNKONWN_ERROR; // unknown function type - } - break; - } - case Item::FUNC_ITEM: { - Item_func *cond_func = down_cast(conds); - Item_func::Functype func_type = cond_func->functype(); - - switch (func_type) { - case Item_func::BETWEEN: - case Item_func::LIKE_FUNC: - case Item_func::ISNULL_FUNC: - case Item_func::ISNOTNULL_FUNC: - case Item_func::IN_FUNC: - case Item_func::EQ_FUNC: // = - case Item_func::NE_FUNC: // <> - case Item_func::LE_FUNC: // <= - case Item_func::GE_FUNC: // >= - case Item_func::GT_FUNC: // > - case Item_func::LT_FUNC: { // < - for (int i = 0; (unsigned)i < cond_func->arg_count; i++) { - Item **args = cond_func->arguments(); - Item *an_arg = UnRef(args[i]); - TableStatus ret = PrefixCheck(an_arg); - - if (ret == TableStatus::TABLE_SEEN_INVOLVED) - return TableStatus::TABLE_SEEN_INVOLVED; - - if (ret == TableStatus::TABLE_YET_UNSEEN_INVOLVED) - return TableStatus::TABLE_YET_UNSEEN_INVOLVED; - } - break; - } - case Item_func::MULT_EQUAL_FUNC: { - Item_equal_iterator li(*(Item_equal *)conds); - Item_field *ifield{nullptr}; - - while ((ifield = li++) != nullptr) { - TableStatus ret = PrefixCheck(ifield); - - if (TableStatus::TABLE_SEEN_INVOLVED == ret) - return TableStatus::TABLE_SEEN_INVOLVED; - - if (ret == TableStatus::TABLE_YET_UNSEEN_INVOLVED) - return TableStatus::TABLE_YET_UNSEEN_INVOLVED; - } - break; - } - default: - return TableStatus::TABLE_SEEN_INVOLVED; // unknown function type - } - break; - } - case Item::FIELD_ITEM: // regular select - case Item::SUM_FUNC_ITEM: { // min(k), max(k), count(), avg(k), sum - const char *field_alias = nullptr; - const char *table_alias = nullptr; - const char *database_name = nullptr; - const char *table_name = nullptr; - const char *table_path = nullptr; - const TABLE *table_ptr = nullptr; - const char *field_name = nullptr; - if (QueryRouteTo::kToMySQL == FieldUnmysterify(conds, database_name, table_name, table_alias, table_path, - table_ptr, field_name, field_alias)) - return TableStatus::TABLE_YET_UNSEEN_INVOLVED; - - ASSERT(std::strcmp(table_alias, EMPTY_TABLE_CONST_INDICATOR), "unexpected table alias"); - - std::string ext_alias = std::string(table_name ? table_name : "") + std::string(":") + std::string(table_alias); - if (table_alias2index_ptr.lower_bound(ext_alias) == table_alias2index_ptr.end()) - return TableStatus::TABLE_YET_UNSEEN_INVOLVED; - else - return TableStatus::TABLE_SEEN_INVOLVED; - break; - } - default: - // hmmm.... ? - break; - } - - return TableStatus::TABLE_SEEN_INVOLVED; -} - -QueryRouteTo Query::BuildCondsIfPossible(Item *conds, CondID &cond_id, const TabID &tmp_table, JoinType join_type) { - conds = UnRef(conds); - - if (conds) { - CondType filter_type = - (join_type == JoinType::JO_LEFT - ? CondType::ON_LEFT_FILTER - : (join_type == JoinType::JO_RIGHT ? CondType::ON_RIGHT_FILTER : CondType::ON_INNER_FILTER)); - // in case of Right join MySQL changes order of tables. Right must be - // switched back to left! - if (filter_type == CondType::ON_RIGHT_FILTER) - filter_type = CondType::ON_LEFT_FILTER; - - DEBUG_ASSERT(PrefixCheck(conds) != TableStatus::TABLE_YET_UNSEEN_INVOLVED && - "Table not yet seen was involved in this condition"); - - bool zero_result = conds->type() == Item::INT_ITEM && !conds->val_bool(); - - if (BuildConditions(conds, cond_id, cq, tmp_table, filter_type, zero_result, join_type) == QueryRouteTo::kToMySQL) - return QueryRouteTo::kToMySQL; - - conds = 0; - } - return QueryRouteTo::kToTianmu; -} - -} // namespace core -} // namespace Tianmu diff --git a/storage/tianmu/core/temp_table.h b/storage/tianmu/core/temp_table.h index 56bcb568a..e70d9cae6 100644 --- a/storage/tianmu/core/temp_table.h +++ b/storage/tianmu/core/temp_table.h @@ -127,7 +127,7 @@ class TempTable : public JustATable { void DisplayAttrStats(Filter *f [[maybe_unused]]) override {} bool TryToMerge(Descriptor &d1 [[maybe_unused]], Descriptor &d2 [[maybe_unused]]) override { return false; } PackOntologicalStatus GetPackOntologicalStatus(int pack_no [[maybe_unused]]) override { - return PackOntologicalStatus::NORMAL; + return PackOntologicalStatus::kNormal; } // not implemented properly yet void ApplyFilter(MultiIndex &, int64_t offset, int64_t no_obj); void DeleteBuffer(); diff --git a/storage/tianmu/core/temp_table_roughquery.cpp b/storage/tianmu/core/temp_table_roughquery.cpp index dd5ff2ea3..3cd29b2d0 100644 --- a/storage/tianmu/core/temp_table_roughquery.cpp +++ b/storage/tianmu/core/temp_table_roughquery.cpp @@ -79,7 +79,7 @@ void TempTable::RoughAggregateMinMax(vcolumn::VirtualColumn *vc, int64_t &min_va MIIterator mit(filter.mind_, dim, true); while (mit.IsValid()) { if (filter.rough_mind_->GetPackStatus(dim, mit.GetCurPackrow(dim)) != common::RoughSetValue::RS_NONE && - vc->GetPackOntologicalStatus(mit) != PackOntologicalStatus::NULLS_ONLY) { + vc->GetPackOntologicalStatus(mit) != PackOntologicalStatus::kNullsOnly) { int64_t v = vc->GetMinInt64(mit); if (v == common::NULL_VALUE_64) min_val = common::MINUS_INF_64; @@ -154,7 +154,7 @@ void TempTable::RoughAggregateSum(vcolumn::VirtualColumn *vc, int64_t &min_val, // grouping columns are uniform for this packrow } if (res != common::RoughSetValue::RS_NONE && - vc->GetPackOntologicalStatus(mit) != PackOntologicalStatus::NULLS_ONLY) { + vc->GetPackOntologicalStatus(mit) != PackOntologicalStatus::kNullsOnly) { empty_set = false; success = true; bool nonnegative = false; @@ -527,7 +527,7 @@ void TempTable::RoughAggregate(ResultSender *sender) { while (mit.IsValid()) { common::RoughSetValue res = filter.rough_mind_->GetPackStatus(dim, mit.GetCurPackrow(dim)); if (res != common::RoughSetValue::RS_NONE && - vc->GetPackOntologicalStatus(mit) != PackOntologicalStatus::NULLS_ONLY) { + vc->GetPackOntologicalStatus(mit) != PackOntologicalStatus::kNullsOnly) { min_val = UpdateMin(min_val, vc->GetMinInt64(mit), double_vals); max_val = UpdateMax(max_val, vc->GetMaxInt64(mit), double_vals); if (!skip_counting && !group_by_present && res == common::RoughSetValue::RS_ALL) { diff --git a/storage/tianmu/core/tianmu_attr.cpp b/storage/tianmu/core/tianmu_attr.cpp index 07854c2b0..4e94e2036 100644 --- a/storage/tianmu/core/tianmu_attr.cpp +++ b/storage/tianmu/core/tianmu_attr.cpp @@ -102,7 +102,7 @@ void TianmuAttr::Create(const fs::path &dir, const AttributeTypeInfo &ati, uint8 0, // compressed size }; - if (ati.Lookup()) { + if (ati.IsLookup()) { hdr.dict_ver = 1; // starting with 1 because 0 means n/a fs::create_directory(dir / common::COL_DICT_DIR); @@ -362,15 +362,15 @@ PackOntologicalStatus TianmuAttr::GetPackOntologicalStatus(int pack_no) { LoadPackInfo(); DPN const *dpn(pack_no >= 0 ? &get_dpn(pack_no) : nullptr); if (pack_no < 0 || dpn->NullOnly()) - return PackOntologicalStatus::NULLS_ONLY; + return PackOntologicalStatus::kNullsOnly; if (GetPackType() == common::PackType::INT) { if (dpn->min_i == dpn->max_i) { if (dpn->numOfNulls == 0) - return PackOntologicalStatus::UNIFORM; - return PackOntologicalStatus::UNIFORM_AND_NULLS; + return PackOntologicalStatus::kUniform; + return PackOntologicalStatus::kUniformAndNulls; } } - return PackOntologicalStatus::NORMAL; + return PackOntologicalStatus::kNormal; } types::BString TianmuAttr::GetValueString(const int64_t obj) { @@ -526,7 +526,7 @@ int64_t TianmuAttr::GetNumOfNulls(int pack) { } size_t TianmuAttr::GetActualSize(int pack) { - if (GetPackOntologicalStatus(pack) == PackOntologicalStatus::NULLS_ONLY) + if (GetPackOntologicalStatus(pack) == PackOntologicalStatus::kNullsOnly) return 0; if (Type().IsLookup() || GetPackType() != common::PackType::STR) return Type().GetPrecision(); @@ -536,7 +536,7 @@ size_t TianmuAttr::GetActualSize(int pack) { int64_t TianmuAttr::GetSum(int pack, bool &nonnegative) { LoadPackInfo(); auto const &dpn(get_dpn(pack)); - if (GetPackOntologicalStatus(pack) == PackOntologicalStatus::NULLS_ONLY || + if (GetPackOntologicalStatus(pack) == PackOntologicalStatus::kNullsOnly || /* dpns.Size() == 0 || */ Type().IsString()) return common::NULL_VALUE_64; if (!Type().IsFloat() && @@ -549,21 +549,21 @@ int64_t TianmuAttr::GetSum(int pack, bool &nonnegative) { int64_t TianmuAttr::GetMinInt64(int pack) { LoadPackInfo(); - if (GetPackOntologicalStatus(pack) == PackOntologicalStatus::NULLS_ONLY) + if (GetPackOntologicalStatus(pack) == PackOntologicalStatus::kNullsOnly) return common::MINUS_INF_64; return get_dpn(pack).min_i; } int64_t TianmuAttr::GetMaxInt64(int pack) { LoadPackInfo(); - if (GetPackOntologicalStatus(pack) == PackOntologicalStatus::NULLS_ONLY) + if (GetPackOntologicalStatus(pack) == PackOntologicalStatus::kNullsOnly) return common::PLUS_INF_64; return get_dpn(pack).max_i; } types::BString TianmuAttr::GetMaxString(int pack) { LoadPackInfo(); - if (GetPackOntologicalStatus(pack) == PackOntologicalStatus::NULLS_ONLY || pack_type != common::PackType::STR) + if (GetPackOntologicalStatus(pack) == PackOntologicalStatus::kNullsOnly || pack_type != common::PackType::STR) return types::BString(); auto s = get_dpn(pack).max_s; size_t max_len = GetActualSize(pack); @@ -576,7 +576,7 @@ types::BString TianmuAttr::GetMaxString(int pack) { types::BString TianmuAttr::GetMinString(int pack) { LoadPackInfo(); - if (GetPackOntologicalStatus(pack) == PackOntologicalStatus::NULLS_ONLY || pack_type != common::PackType::STR) + if (GetPackOntologicalStatus(pack) == PackOntologicalStatus::kNullsOnly || pack_type != common::PackType::STR) return types::BString(); auto s = get_dpn(pack).min_s; size_t max_len = GetActualSize(pack); @@ -746,7 +746,7 @@ int64_t TianmuAttr::EncodeValue64(const types::TianmuValueObject &v, bool &round size_t TianmuAttr::GetPrefixLength(int pack) { LoadPackInfo(); - if (GetPackOntologicalStatus(pack) == PackOntologicalStatus::NULLS_ONLY) + if (GetPackOntologicalStatus(pack) == PackOntologicalStatus::kNullsOnly) return 0; auto const &dpn(get_dpn(pack)); @@ -1215,8 +1215,8 @@ types::BString TianmuAttr::MinS(Filter *f) { auto const &dpn(get_dpn(b)); auto p = get_packS(b); if (GetPackType() == common::PackType::INT && - (GetPackOntologicalStatus(b) == PackOntologicalStatus::UNIFORM || - (GetPackOntologicalStatus(b) == PackOntologicalStatus::UNIFORM_AND_NULLS && f->IsFull(b)))) { + (GetPackOntologicalStatus(b) == PackOntologicalStatus::kUniform || + (GetPackOntologicalStatus(b) == PackOntologicalStatus::kUniformAndNulls && f->IsFull(b)))) { CompareAndSetCurrentMin(DecodeValue_S(dpn.min_i), min, set); it.NextPack(); } else if (!(dpn.NullOnly() || dpn.numOfRecords == 0)) { @@ -1250,8 +1250,8 @@ types::BString TianmuAttr::MaxS(Filter *f) { auto const &dpn(get_dpn(b)); auto p = get_packS(b); if (GetPackType() == common::PackType::INT && - (GetPackOntologicalStatus(b) == PackOntologicalStatus::UNIFORM || - (GetPackOntologicalStatus(b) == PackOntologicalStatus::UNIFORM_AND_NULLS && f->IsFull(b)))) { + (GetPackOntologicalStatus(b) == PackOntologicalStatus::kUniform || + (GetPackOntologicalStatus(b) == PackOntologicalStatus::kUniformAndNulls && f->IsFull(b)))) { CompareAndSetCurrentMax(DecodeValue_S(dpn.min_i), max); } else if (!(dpn.NullOnly() || dpn.numOfRecords == 0)) { while (it.IsValid() && b == it.GetCurrPack()) { @@ -1287,7 +1287,7 @@ void TianmuAttr::UpdateRSI_CMap(common::PACK_INDEX pi) { if (!GetFilter_CMap()) return; - if (GetPackOntologicalStatus(pi) == PackOntologicalStatus::NULLS_ONLY) + if (GetPackOntologicalStatus(pi) == PackOntologicalStatus::kNullsOnly) return; filter_cmap->Update(pi, get_dpn(pi), get_packS(pi)); } @@ -1300,7 +1300,7 @@ void TianmuAttr::UpdateRSI_Bloom(common::PACK_INDEX pi) { if (NumOfObj() == 0) return; - if (GetPackOntologicalStatus(pi) == PackOntologicalStatus::NULLS_ONLY) + if (GetPackOntologicalStatus(pi) == PackOntologicalStatus::kNullsOnly) return; filter_bloom->Update(pi, get_dpn(pi), get_packS(pi)); diff --git a/storage/tianmu/core/tianmu_attr_exeq_rs.cpp b/storage/tianmu/core/tianmu_attr_exeq_rs.cpp index 1d4bacdf4..ee904af80 100644 --- a/storage/tianmu/core/tianmu_attr_exeq_rs.cpp +++ b/storage/tianmu/core/tianmu_attr_exeq_rs.cpp @@ -683,7 +683,7 @@ std::vector TianmuAttr::GetListOfDistinctValuesInPack(int pack) { if (NumOfNulls() > 0) list_vals.push_back(common::NULL_VALUE_64); return list_vals; - } else if (GetPackOntologicalStatus(pack) == PackOntologicalStatus::NULLS_ONLY) { + } else if (GetPackOntologicalStatus(pack) == PackOntologicalStatus::kNullsOnly) { list_vals.push_back(common::NULL_VALUE_64); return list_vals; } else if (TypeName() == common::ColumnType::REAL || TypeName() == common::ColumnType::FLOAT) { @@ -808,7 +808,7 @@ uint64_t TianmuAttr::ExactDistinctVals(Filter *f) // provide the exact number o return RoughMax(nullptr) + 1; bool nulls_only = true; for (uint p = 0; p < SizeOfPack(); p++) - if (!f->IsEmpty(p) && GetPackOntologicalStatus(p) != PackOntologicalStatus::NULLS_ONLY) { + if (!f->IsEmpty(p) && GetPackOntologicalStatus(p) != PackOntologicalStatus::kNullsOnly) { nulls_only = false; break; } diff --git a/storage/tianmu/core/tianmu_attr_exqp.cpp b/storage/tianmu/core/tianmu_attr_exqp.cpp index ef318f776..19a436be7 100644 --- a/storage/tianmu/core/tianmu_attr_exqp.cpp +++ b/storage/tianmu/core/tianmu_attr_exqp.cpp @@ -348,7 +348,7 @@ void TianmuAttr::EvaluatePack_IsNull(MIUpdatingIterator &mit, int dim) { ++mit; } while (mit.IsValid() && !mit.PackrowStarted()); } else { // pack is trivial - uniform or null only - if (GetPackOntologicalStatus(pack) != PackOntologicalStatus::NULLS_ONLY) { + if (GetPackOntologicalStatus(pack) != PackOntologicalStatus::kNullsOnly) { if (mit.NullsPossibleInPack(dim)) { do { if (mit[dim] != common::NULL_VALUE_64 || get_pack(pack)->IsDeleted(mit.GetCurInpack(dim))) @@ -378,7 +378,7 @@ void TianmuAttr::EvaluatePack_NotNull(MIUpdatingIterator &mit, int dim) { ++mit; } while (mit.IsValid() && !mit.PackrowStarted()); } else { // pack is trivial - uniform or null only - if (GetPackOntologicalStatus(pack) == PackOntologicalStatus::NULLS_ONLY) + if (GetPackOntologicalStatus(pack) == PackOntologicalStatus::kNullsOnly) mit.ResetCurrentPack(); else if (mit.NullsPossibleInPack(dim)) { do { @@ -664,7 +664,7 @@ void TianmuAttr::EvaluatePack_InNum(MIUpdatingIterator &mit, int dim, Descriptor if (d.val1.cond_numvalue != nullptr) arraysize = d.val1.cond_numvalue->capacity(); if (local_min == local_max) { - if (GetPackOntologicalStatus(pack) == PackOntologicalStatus::NULLS_ONLY) { + if (GetPackOntologicalStatus(pack) == PackOntologicalStatus::kNullsOnly) { mit.ResetCurrentPack(); mit.NextPackrow(); } else { @@ -750,7 +750,7 @@ void TianmuAttr::EvaluatePack_BetweenString(MIUpdatingIterator &mit, int dim, De bool use_trie = false; uint16_t trie_id; if (v1 == v2 && p->IsTrie()) { - use_trie = p->Lookup(v1, trie_id); + use_trie = p->IsLookup(v1, trie_id); if (!use_trie) { mit.ResetCurrentPack(); mit.NextPackrow(); @@ -808,7 +808,7 @@ void TianmuAttr::EvaluatePack_BetweenString_UTF(MIUpdatingIterator &mit, int dim bool use_trie = false; uint16_t trie_id; if (v1 == v2 && p->IsTrie()) { - use_trie = p->Lookup(v1, trie_id); + use_trie = p->IsLookup(v1, trie_id); if (!use_trie) { mit.ResetCurrentPack(); mit.NextPackrow(); @@ -1267,7 +1267,7 @@ size_t TianmuAttr::MaxStringSize(Filter *f) // maximal byte string length in co int64_t cur_min = common::PLUS_INF_64; int64_t cur_max = common::MINUS_INF_64; for (uint b = 0; b < SizeOfPack(); b++) { - if ((f && f->IsEmpty(b)) || GetPackOntologicalStatus(b) == PackOntologicalStatus::NULLS_ONLY) + if ((f && f->IsEmpty(b)) || GetPackOntologicalStatus(b) == PackOntologicalStatus::kNullsOnly) continue; auto &d = get_dpn(b); diff --git a/storage/tianmu/core/tianmu_attr_typeinfo.cpp b/storage/tianmu/core/tianmu_attr_typeinfo.cpp index 4ba59ac72..ef1609336 100644 --- a/storage/tianmu/core/tianmu_attr_typeinfo.cpp +++ b/storage/tianmu/core/tianmu_attr_typeinfo.cpp @@ -29,7 +29,7 @@ int ATI::TextSize(common::ColumnType attrt, uint precision, int scale, DTCollati } const types::TianmuDataType &AttributeTypeInfo::ValuePrototype() const { - if (Lookup() || ATI::IsNumericType(attrt_)) + if (IsLookup() || ATI::IsNumericType(attrt_)) return types::TianmuNum::NullValue(); if (ATI::IsStringType(attrt_)) return types::BString::NullValue(); diff --git a/storage/tianmu/core/tianmu_attr_typeinfo.h b/storage/tianmu/core/tianmu_attr_typeinfo.h index cc52d1fab..200ca7818 100644 --- a/storage/tianmu/core/tianmu_attr_typeinfo.h +++ b/storage/tianmu/core/tianmu_attr_typeinfo.h @@ -86,41 +86,41 @@ class ATI { class AttributeTypeInfo { public: enum class enumATI { - NOT_NULL = 0, - AUTO_INC = 1, - BLOOM_FILTER = 2, + kNotNull = 0, + kAutoInc, + kBloomFilter, }; - AttributeTypeInfo(common::ColumnType attrt, bool notnull, uint precision = 0, ushort scale = 0, bool auto_inc = false, + 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(enumATI::NOT_NULL)] = notnull; - flag_[static_cast(enumATI::BLOOM_FILTER)] = filter; - flag_[static_cast(enumATI::AUTO_INC)] = auto_inc; + flag_[static_cast(enumATI::kNotNull)] = not_null; + flag_[static_cast(enumATI::kBloomFilter)] = filter; + flag_[static_cast(enumATI::kAutoInc)] = auto_inc; // lookup only applies to string type - if (attrt != common::ColumnType::STRING && attrt != common::ColumnType::VARCHAR && Lookup()) + if (attrt != common::ColumnType::STRING && attrt != common::ColumnType::VARCHAR && IsLookup()) fmt = common::PackFmt::DEFAULT; } common::ColumnType Type() const { return attrt_; } common::PackType GetPackType() const { - return ATI::IsDateTimeType(attrt_) || ATI::IsNumericType(attrt_) || Lookup() ? common::PackType::INT + return ATI::IsDateTimeType(attrt_) || ATI::IsNumericType(attrt_) || IsLookup() ? common::PackType::INT : common::PackType::STR; } std::string GetFieldName() { return field_name_; } uint Precision() const { return precision_; } ushort Scale() const { return scale_; } uint CharLen() const { return precision_ / collation_.collation->mbmaxlen; } - bool NotNull() const { return flag_[static_cast(enumATI::NOT_NULL)]; } - bool AutoInc() const { return flag_[static_cast(enumATI::AUTO_INC)]; } + bool NotNull() const { return flag_[static_cast(enumATI::kNotNull)]; } + bool AutoInc() const { return flag_[static_cast(enumATI::kAutoInc)]; } void SetCollation(const DTCollation &collation) { this->collation_ = collation; } void SetCollation(CHARSET_INFO *charset_info) { this->collation_.set(charset_info); } DTCollation GetCollation() const { return collation_; } CHARSET_INFO *CharsetInfo() const { return const_cast(this->collation_.collation); } const types::TianmuDataType &ValuePrototype() const; common::PackFmt Fmt() const { return fmt_; } - bool Lookup() const { return fmt_ == common::PackFmt::LOOKUP; } + bool IsLookup() const { return fmt_ == common::PackFmt::LOOKUP; } unsigned char Flag() const { return flag_.to_ulong(); } void SetFlag(unsigned char v) { flag_ = std::bitset::digits>(v); } diff --git a/storage/tianmu/vc/const_column.cpp b/storage/tianmu/vc/const_column.cpp index e6e7e8702..6a85ab450 100644 --- a/storage/tianmu/vc/const_column.cpp +++ b/storage/tianmu/vc/const_column.cpp @@ -177,8 +177,8 @@ size_t ConstColumn::MaxStringSizeImpl() // maximal byte string length in column core::PackOntologicalStatus ConstColumn::GetPackOntologicalStatusImpl([[maybe_unused]] const core::MIIterator &mit) { if (value_or_null_.IsNull()) - return core::PackOntologicalStatus::NULLS_ONLY; - return core::PackOntologicalStatus::UNIFORM; + return core::PackOntologicalStatus::kNullsOnly; + return core::PackOntologicalStatus::kUniform; } void ConstColumn::EvaluatePackImpl([[maybe_unused]] core::MIUpdatingIterator &mit, diff --git a/storage/tianmu/vc/const_expr_column.cpp b/storage/tianmu/vc/const_expr_column.cpp index 5a896064f..7a6c83923 100644 --- a/storage/tianmu/vc/const_expr_column.cpp +++ b/storage/tianmu/vc/const_expr_column.cpp @@ -140,9 +140,9 @@ size_t ConstExpressionColumn::MaxStringSizeImpl() // maximal byte string length core::PackOntologicalStatus ConstExpressionColumn::GetPackOntologicalStatusImpl([ [maybe_unused]] const core::MIIterator &mit) { if (last_val_->IsNull()) - return core::PackOntologicalStatus::NULLS_ONLY; + return core::PackOntologicalStatus::kNullsOnly; - return core::PackOntologicalStatus::UNIFORM; + return core::PackOntologicalStatus::kUniform; } void ConstExpressionColumn::EvaluatePackImpl([[maybe_unused]] core::MIUpdatingIterator &mit, diff --git a/storage/tianmu/vc/expr_column.cpp b/storage/tianmu/vc/expr_column.cpp index c4ca522fc..1411995e2 100644 --- a/storage/tianmu/vc/expr_column.cpp +++ b/storage/tianmu/vc/expr_column.cpp @@ -222,7 +222,7 @@ size_t ExpressionColumn::MaxStringSizeImpl() // maximal byte string length in c core::PackOntologicalStatus ExpressionColumn::GetPackOntologicalStatusImpl(const core::MIIterator &mit) { core::PackOntologicalStatus st = - deterministic_ ? core::PackOntologicalStatus::UNIFORM : core::PackOntologicalStatus::NORMAL; // will be used for + deterministic_ ? core::PackOntologicalStatus::kUniform : core::PackOntologicalStatus::kNormal; // will be used for // what about 0 arguments and null only? core::PackOntologicalStatus st_loc; @@ -230,8 +230,8 @@ core::PackOntologicalStatus ExpressionColumn::GetPackOntologicalStatusImpl(const // cast to remove const as GetPackOntologicalStatus() is not const st_loc = ((core::PhysicalColumn *)it.GetTabPtr()->GetColumn(it.col_ndx)) ->GetPackOntologicalStatus(mit.GetCurPackrow(it.dim)); - if (st_loc != core::PackOntologicalStatus::UNIFORM && st_loc != core::PackOntologicalStatus::NULLS_ONLY) - return core::PackOntologicalStatus::NORMAL; + if (st_loc != core::PackOntologicalStatus::kUniform && st_loc != core::PackOntologicalStatus::kNullsOnly) + return core::PackOntologicalStatus::kNormal; } return st; diff --git a/storage/tianmu/vc/in_set_column.cpp b/storage/tianmu/vc/in_set_column.cpp index 04605fc96..1ba246d3f 100644 --- a/storage/tianmu/vc/in_set_column.cpp +++ b/storage/tianmu/vc/in_set_column.cpp @@ -104,7 +104,7 @@ size_t InSetColumn::MaxStringSizeImpl() // maximal byte string length in column core::PackOntologicalStatus InSetColumn::GetPackOntologicalStatusImpl([[maybe_unused]] const core::MIIterator &mit) { DEBUG_ASSERT(!"To be implemented."); - return core::PackOntologicalStatus::NORMAL; + return core::PackOntologicalStatus::kNormal; } void InSetColumn::EvaluatePackImpl([[maybe_unused]] core::MIUpdatingIterator &mit, diff --git a/storage/tianmu/vc/single_column.cpp b/storage/tianmu/vc/single_column.cpp index c2fb4d44a..43b509532 100644 --- a/storage/tianmu/vc/single_column.cpp +++ b/storage/tianmu/vc/single_column.cpp @@ -159,7 +159,7 @@ double SingleColumn::RoughSelectivity() { return col_->RoughSelectivity(); } std::vector SingleColumn::GetListOfDistinctValues(core::MIIterator const &mit) { int pack = mit.GetCurPackrow(dim_); if (pack < 0 || - (!mit.WholePack(dim_) && col_->GetPackOntologicalStatus(pack) != core::PackOntologicalStatus::UNIFORM)) { + (!mit.WholePack(dim_) && col_->GetPackOntologicalStatus(pack) != core::PackOntologicalStatus::kUniform)) { std::vector empty; return empty; } diff --git a/storage/tianmu/vc/subselect_column.cpp b/storage/tianmu/vc/subselect_column.cpp index b33109019..6736a2341 100644 --- a/storage/tianmu/vc/subselect_column.cpp +++ b/storage/tianmu/vc/subselect_column.cpp @@ -158,7 +158,7 @@ size_t SubSelectColumn::MaxStringSizeImpl() // maximal byte string length in co core::PackOntologicalStatus SubSelectColumn::GetPackOntologicalStatusImpl([ [maybe_unused]] const core::MIIterator &mit) { - return core::PackOntologicalStatus::NORMAL; + return core::PackOntologicalStatus::kNormal; } void SubSelectColumn::EvaluatePackImpl([[maybe_unused]] core::MIUpdatingIterator &mit, diff --git a/storage/tianmu/vc/virtual_column_base.h b/storage/tianmu/vc/virtual_column_base.h index 9fce8bed3..f73eec198 100644 --- a/storage/tianmu/vc/virtual_column_base.h +++ b/storage/tianmu/vc/virtual_column_base.h @@ -358,8 +358,8 @@ class VirtualColumnBase : public core::Column { inline common::RoughSetValue RoughCheck(const core::MIIterator &it, core::Descriptor &d) { return RoughCheckImpl(it, d); } - //! is a datapack pointed by \e mit NULLS_ONLY, UNIFORM, UNIFORM_AND_NULLS or - //! NORMAL + //! is a datapack pointed by \e mit kNullsOnly, kUniform, kUniformAndNulls or + //! kNormal core::PackOntologicalStatus GetPackOntologicalStatus(const core::MIIterator &mit) { return GetPackOntologicalStatusImpl(mit); }