From bd5afacbeb631355b62f3a4485093bba1d9f921f Mon Sep 17 00:00:00 2001 From: lihongjian Date: Wed, 28 Sep 2022 16:15:11 +0800 Subject: [PATCH] fix(tianmu) Query results more data (#282) Cause: Execution plan error when AND/OR sql logical operator in condition occurs at the same time Resolvent: Optimize multiple equal execution plan logic --- mysql-test/suite/tianmu/r/issue282.result | 111 ++++++++++++ mysql-test/suite/tianmu/t/issue282.test | 56 ++++++ storage/tianmu/core/query.cpp | 197 +++++++++++----------- 3 files changed, 264 insertions(+), 100 deletions(-) create mode 100644 mysql-test/suite/tianmu/r/issue282.result create mode 100644 mysql-test/suite/tianmu/t/issue282.test diff --git a/mysql-test/suite/tianmu/r/issue282.result b/mysql-test/suite/tianmu/r/issue282.result new file mode 100644 index 000000000..4b7d36e17 --- /dev/null +++ b/mysql-test/suite/tianmu/r/issue282.result @@ -0,0 +1,111 @@ +use test; +CREATE TABLE issue282_t1 (sku int PRIMARY KEY, pr int)engine=tianmu; +CREATE TABLE issue282_t2 (sku int PRIMARY KEY, sppr int, name varchar(255))engine=tianmu; +INSERT INTO issue282_t1 VALUES +(10, 10), (20, 10), (30, 20), (40, 30), (50, 10), (60, 10); +INSERT INTO issue282_t2 VALUES +(10, 10, 'aaa'), (20, 10, 'bbb'), (30, 10, 'ccc'), (40, 20, 'ddd'), +(50, 10, 'eee'), (60, 20, 'fff'), (70, 20, 'ggg'), (80, 30, 'hhh'); +SELECT issue282_t2.sku, issue282_t2.sppr, issue282_t2.name, issue282_t1.sku, issue282_t1.pr +FROM issue282_t2, issue282_t1 WHERE issue282_t2.sku=20 AND (issue282_t2.sku=issue282_t1.sku OR issue282_t2.sppr=issue282_t1.sku); +sku sppr name sku pr +20 10 bbb 10 10 +20 10 bbb 20 10 +SELECT issue282_t2.sku, issue282_t2.sppr, issue282_t2.name, issue282_t1.sku, issue282_t1.pr +FROM issue282_t2, issue282_t1 WHERE issue282_t2.sku=20 OR (issue282_t2.sku=issue282_t1.sku OR issue282_t2.sppr=issue282_t1.sku) order by issue282_t2.sku asc; +sku sppr name sku pr +10 10 aaa 10 10 +20 10 bbb 10 10 +20 10 bbb 20 10 +20 10 bbb 30 20 +20 10 bbb 40 30 +20 10 bbb 50 10 +20 10 bbb 60 10 +30 10 ccc 10 10 +30 10 ccc 30 20 +40 20 ddd 20 10 +40 20 ddd 40 30 +50 10 eee 10 10 +50 10 eee 50 10 +60 20 fff 20 10 +60 20 fff 60 10 +70 20 ggg 20 10 +80 30 hhh 30 20 +SELECT issue282_t2.sku, issue282_t2.sppr, issue282_t2.name, issue282_t1.sku, issue282_t1.pr +FROM issue282_t2, issue282_t1 WHERE issue282_t2.sku=20 AND (issue282_t2.sku=issue282_t1.sku AND issue282_t2.sppr=issue282_t1.sku); +sku sppr name sku pr +SELECT issue282_t2.sku, issue282_t2.sppr, issue282_t2.name, issue282_t1.sku, issue282_t1.pr +FROM issue282_t2, issue282_t1 WHERE issue282_t2.sku=20 OR (issue282_t2.sku=issue282_t1.sku AND issue282_t2.sppr=issue282_t1.sku); +sku sppr name sku pr +10 10 aaa 10 10 +20 10 bbb 10 10 +20 10 bbb 20 10 +20 10 bbb 30 20 +20 10 bbb 40 30 +20 10 bbb 50 10 +20 10 bbb 60 10 +SELECT issue282_t2.sku, issue282_t2.sppr, issue282_t2.name, issue282_t1.sku, issue282_t1.pr +FROM issue282_t2, issue282_t1 WHERE issue282_t2.sku=20 OR issue282_t2.sku=issue282_t1.sku AND issue282_t2.sppr=issue282_t1.sku; +sku sppr name sku pr +10 10 aaa 10 10 +20 10 bbb 10 10 +20 10 bbb 20 10 +20 10 bbb 30 20 +20 10 bbb 40 30 +20 10 bbb 50 10 +20 10 bbb 60 10 +SELECT issue282_t2.sku, issue282_t2.sppr, issue282_t2.name, issue282_t1.sku, issue282_t1.pr +FROM issue282_t2, issue282_t1 WHERE (issue282_t2.sku>20 OR issue282_t2.sku=issue282_t1.sku) AND issue282_t2.sppr=issue282_t1.sku; +sku sppr name sku pr +10 10 aaa 10 10 +30 10 ccc 10 10 +40 20 ddd 20 10 +50 10 eee 10 10 +60 20 fff 20 10 +70 20 ggg 20 10 +80 30 hhh 30 20 +SELECT issue282_t2.sku, issue282_t2.sppr, issue282_t2.name, issue282_t1.sku, issue282_t1.pr +FROM issue282_t2, issue282_t1 WHERE (issue282_t2.sku<=20 OR issue282_t2.sku=issue282_t1.sku) AND issue282_t2.sppr=issue282_t1.sku; +sku sppr name sku pr +10 10 aaa 10 10 +20 10 bbb 10 10 +SELECT issue282_t2.sku, issue282_t2.sppr, issue282_t2.name, issue282_t1.sku, issue282_t1.pr +FROM issue282_t2, issue282_t1 WHERE (issue282_t2.sku<=20 AND issue282_t2.sku>issue282_t1.sku) OR issue282_t2.sppr=issue282_t1.sku; +sku sppr name sku pr +10 10 aaa 10 10 +20 10 bbb 10 10 +30 10 ccc 10 10 +50 10 eee 10 10 +40 20 ddd 20 10 +60 20 fff 20 10 +70 20 ggg 20 10 +80 30 hhh 30 20 +# +# Multiple nesting +# +SELECT issue282_t2.sku, issue282_t2.sppr, issue282_t2.name, issue282_t1.sku, issue282_t1.pr +FROM issue282_t2, issue282_t1 WHERE +issue282_t1.sku=60 OR +(issue282_t2.sku=20 AND +(issue282_t2.sku=issue282_t1.sku OR +issue282_t2.sppr=issue282_t1.sku)); +sku sppr name sku pr +20 10 bbb 10 10 +20 10 bbb 20 10 +10 10 aaa 60 10 +20 10 bbb 60 10 +30 10 ccc 60 10 +40 20 ddd 60 10 +50 10 eee 60 10 +60 20 fff 60 10 +70 20 ggg 60 10 +80 30 hhh 60 10 +SELECT issue282_t2.sku, issue282_t2.sppr, issue282_t2.name, issue282_t1.sku, issue282_t1.pr +FROM issue282_t2, issue282_t1 WHERE +issue282_t1.sku=10 AND +(issue282_t2.sku=20 AND +(issue282_t2.sku=issue282_t1.sku OR +issue282_t2.sppr=issue282_t1.sku)); +sku sppr name sku pr +20 10 bbb 10 10 +drop table issue282_t1 ,issue282_t2; diff --git a/mysql-test/suite/tianmu/t/issue282.test b/mysql-test/suite/tianmu/t/issue282.test new file mode 100644 index 000000000..1b865e30a --- /dev/null +++ b/mysql-test/suite/tianmu/t/issue282.test @@ -0,0 +1,56 @@ +--source include/have_tianmu.inc + +use test; +CREATE TABLE issue282_t1 (sku int PRIMARY KEY, pr int)engine=tianmu; +CREATE TABLE issue282_t2 (sku int PRIMARY KEY, sppr int, name varchar(255))engine=tianmu; + +INSERT INTO issue282_t1 VALUES + (10, 10), (20, 10), (30, 20), (40, 30), (50, 10), (60, 10); + +INSERT INTO issue282_t2 VALUES + (10, 10, 'aaa'), (20, 10, 'bbb'), (30, 10, 'ccc'), (40, 20, 'ddd'), + (50, 10, 'eee'), (60, 20, 'fff'), (70, 20, 'ggg'), (80, 30, 'hhh'); + +SELECT issue282_t2.sku, issue282_t2.sppr, issue282_t2.name, issue282_t1.sku, issue282_t1.pr + FROM issue282_t2, issue282_t1 WHERE issue282_t2.sku=20 AND (issue282_t2.sku=issue282_t1.sku OR issue282_t2.sppr=issue282_t1.sku); + +SELECT issue282_t2.sku, issue282_t2.sppr, issue282_t2.name, issue282_t1.sku, issue282_t1.pr + FROM issue282_t2, issue282_t1 WHERE issue282_t2.sku=20 OR (issue282_t2.sku=issue282_t1.sku OR issue282_t2.sppr=issue282_t1.sku) order by issue282_t2.sku asc; + +SELECT issue282_t2.sku, issue282_t2.sppr, issue282_t2.name, issue282_t1.sku, issue282_t1.pr + FROM issue282_t2, issue282_t1 WHERE issue282_t2.sku=20 AND (issue282_t2.sku=issue282_t1.sku AND issue282_t2.sppr=issue282_t1.sku); + +SELECT issue282_t2.sku, issue282_t2.sppr, issue282_t2.name, issue282_t1.sku, issue282_t1.pr + FROM issue282_t2, issue282_t1 WHERE issue282_t2.sku=20 OR (issue282_t2.sku=issue282_t1.sku AND issue282_t2.sppr=issue282_t1.sku); + +SELECT issue282_t2.sku, issue282_t2.sppr, issue282_t2.name, issue282_t1.sku, issue282_t1.pr + FROM issue282_t2, issue282_t1 WHERE issue282_t2.sku=20 OR issue282_t2.sku=issue282_t1.sku AND issue282_t2.sppr=issue282_t1.sku; + +SELECT issue282_t2.sku, issue282_t2.sppr, issue282_t2.name, issue282_t1.sku, issue282_t1.pr + FROM issue282_t2, issue282_t1 WHERE (issue282_t2.sku>20 OR issue282_t2.sku=issue282_t1.sku) AND issue282_t2.sppr=issue282_t1.sku; + +SELECT issue282_t2.sku, issue282_t2.sppr, issue282_t2.name, issue282_t1.sku, issue282_t1.pr + FROM issue282_t2, issue282_t1 WHERE (issue282_t2.sku<=20 OR issue282_t2.sku=issue282_t1.sku) AND issue282_t2.sppr=issue282_t1.sku; + +SELECT issue282_t2.sku, issue282_t2.sppr, issue282_t2.name, issue282_t1.sku, issue282_t1.pr + FROM issue282_t2, issue282_t1 WHERE (issue282_t2.sku<=20 AND issue282_t2.sku>issue282_t1.sku) OR issue282_t2.sppr=issue282_t1.sku; + +--echo # +--echo # Multiple nesting +--echo # + +SELECT issue282_t2.sku, issue282_t2.sppr, issue282_t2.name, issue282_t1.sku, issue282_t1.pr + FROM issue282_t2, issue282_t1 WHERE + issue282_t1.sku=60 OR + (issue282_t2.sku=20 AND + (issue282_t2.sku=issue282_t1.sku OR + issue282_t2.sppr=issue282_t1.sku)); + +SELECT issue282_t2.sku, issue282_t2.sppr, issue282_t2.name, issue282_t1.sku, issue282_t1.pr + FROM issue282_t2, issue282_t1 WHERE + issue282_t1.sku=10 AND + (issue282_t2.sku=20 AND + (issue282_t2.sku=issue282_t1.sku OR + issue282_t2.sppr=issue282_t1.sku)); + +drop table issue282_t1 ,issue282_t2; \ No newline at end of file diff --git a/storage/tianmu/core/query.cpp b/storage/tianmu/core/query.cpp index 13d8f5f3a..260089d02 100644 --- a/storage/tianmu/core/query.cpp +++ b/storage/tianmu/core/query.cpp @@ -239,7 +239,7 @@ const std::string Query::GetItemName(Item *item) { return "NULL"; case Item::INT_ITEM: { Item_int_with_ref *int_ref = dynamic_cast(item); - String s(buf, 256, NULL); + String s(buf, 256, nullptr); if (!int_ref) { String *ps = item->val_str(&s); return ps ? ps->c_ptr_safe() : "NULL"; @@ -248,7 +248,7 @@ const std::string Query::GetItemName(Item *item) { return GetItemName(int_ref->real_item()); } case Item::STRING_ITEM: { - String s(buf, 256, NULL); + String s(buf, 256, nullptr); String *ps = item->val_str(&s); return ps ? ps->c_ptr_safe() : "NULL"; } @@ -435,7 +435,7 @@ void Query::ExtractOperatorType(Item *&conds, common::Operator &op, bool &negati break; case Item_func::NOT_ALL_FUNC: { Item_func *cond_func = (Item_func *)conds; - negative = dynamic_cast(cond_func) == NULL; + negative = dynamic_cast(cond_func) == nullptr; ExtractOperatorType(cond_func->arguments()[0], op, negative, like_esc); if (dynamic_cast(cond_func)) MarkWithAny(op); @@ -457,7 +457,7 @@ vcolumn::VirtualColumn *Query::CreateColumnFromExpression(std::vector 0); - vcolumn::VirtualColumn *vc = NULL; + vcolumn::VirtualColumn *vc = nullptr; if (exprs.size() == 1) { bool is_const_expr = vcolumn::VirtualColumn::IsConstExpression(exprs[0], temp_table_alias, &temp_table->GetAliases()); @@ -522,17 +522,18 @@ bool Query::IsParameterFromWhere(const TabID ¶ms_table) { return true; } -const char *Query::GetTableName(Item_field *ifield) -{ - const char *table_name = NULL; - 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; +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) { @@ -563,7 +564,7 @@ TempTable *Query::Preexecute(CompiledQuery &qu, ResultSender *sender, [[maybe_un } std::vector conds(qu.NumOfConds()); - TempTable *output_table = NULL; // NOTE: this pointer will be returned by the function + TempTable *output_table = nullptr; // NOTE: this pointer will be returned by the function ta.resize(qu.NumOfTabs()); auto global_limits = qu.GetGlobalLimit(); @@ -623,13 +624,13 @@ TempTable *Query::Preexecute(CompiledQuery &qu, ResultSender *sender, [[maybe_un DEBUG_ASSERT(step.t1.n < 0); step.e1.vc = (step.e1.vc_id != common::NULL_VALUE_32) ? ((TempTable *)ta[-step.t1.n - 1].get())->GetVirtualColumn(step.e1.vc_id) - : NULL; + : nullptr; step.e2.vc = (step.e2.vc_id != common::NULL_VALUE_32) ? ((TempTable *)ta[-step.t1.n - 1].get())->GetVirtualColumn(step.e2.vc_id) - : NULL; + : nullptr; step.e3.vc = (step.e3.vc_id != common::NULL_VALUE_32) ? ((TempTable *)ta[-step.t1.n - 1].get())->GetVirtualColumn(step.e3.vc_id) - : NULL; + : nullptr; if (step.n1 != static_cast(CondType::OR_SUBTREE)) { // on result = false conds[step.c1.n] = new Condition(); if (step.c2.IsNull()) { @@ -682,7 +683,8 @@ TempTable *Query::Preexecute(CompiledQuery &qu, ResultSender *sender, [[maybe_un 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)); + ->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(), @@ -697,13 +699,13 @@ TempTable *Query::Preexecute(CompiledQuery &qu, ResultSender *sender, [[maybe_un : common::LogicalOperator::O_OR); step.e1.vc = (step.e1.vc_id != common::NULL_VALUE_32) ? ((TempTable *)ta[-step.t1.n - 1].get())->GetVirtualColumn(step.e1.vc_id) - : NULL; + : nullptr; step.e2.vc = (step.e2.vc_id != common::NULL_VALUE_32) ? ((TempTable *)ta[-step.t1.n - 1].get())->GetVirtualColumn(step.e2.vc_id) - : NULL; + : nullptr; step.e3.vc = (step.e3.vc_id != common::NULL_VALUE_32) ? ((TempTable *)ta[-step.t1.n - 1].get())->GetVirtualColumn(step.e3.vc_id) - : NULL; + : nullptr; if (!conds[step.c1.n]->IsType_Tree()) { DEBUG_ASSERT(conds[step.c1.n]); conds[step.c1.n]->AddDescriptor( @@ -750,15 +752,12 @@ TempTable *Query::Preexecute(CompiledQuery &qu, ResultSender *sender, [[maybe_un int64_t cur_limit = -1; auto *tb = (TempTable *)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); + 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; + if (cur_limit != -1 && filter->NoParameterizedDescs()) cur_limit = -1; std::set used_dims = qu.GetUsedDims(step.t1, ta); @@ -774,9 +773,9 @@ TempTable *Query::Preexecute(CompiledQuery &qu, ResultSender *sender, [[maybe_un } if (IsRoughQuery()) { - filter->RoughUpdateParamFilter(); + filter->RoughUpdateParamFilter(); } else - filter->UpdateMultiIndex(qu.CountColumnOnly(step.t1), cur_limit); + filter->UpdateMultiIndex(qu.CountColumnOnly(step.t1), cur_limit); break; } case CompiledQuery::StepType::ADD_COLUMN: { @@ -854,17 +853,18 @@ TempTable *Query::Preexecute(CompiledQuery &qu, ResultSender *sender, [[maybe_un ta[-step.t1.n - 1] = TempTable::Create(*(TempTable *)ta[-step.t2.n - 1].get(), false); if (IsRoughQuery()) { if (step.t3.n == common::NULL_VALUE_32) - ((TempTable *)ta[-step.t1.n - 1].get())->RoughUnion(NULL, qu.IsResultTable(step.t1) ? sender : NULL); + ((TempTable *)ta[-step.t1.n - 1].get()) + ->RoughUnion(nullptr, qu.IsResultTable(step.t1) ? sender : nullptr); else ((TempTable *)ta[-step.t1.n - 1].get()) - ->RoughUnion((TempTable *)ta[-step.t3.n - 1].get(), qu.IsResultTable(step.t1) ? sender : NULL); + ->RoughUnion((TempTable *)ta[-step.t3.n - 1].get(), qu.IsResultTable(step.t1) ? sender : nullptr); } else if (qu.IsResultTable(step.t1) && !qu.IsOrderedBy(step.t1) && step.n1) ((TempTable *)ta[-step.t1.n - 1].get()) ->Union((TempTable *)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) - ((TempTable *)ta[-step.t1.n - 1].get())->Union(NULL, (int)step.n1); + ((TempTable *)ta[-step.t1.n - 1].get())->Union(nullptr, (int)step.n1); else { ((TempTable *)ta[-step.t1.n - 1].get())->Union((TempTable *)ta[-step.t3.n - 1].get(), (int)step.n1); ta[-step.t3.n - 1].reset(); @@ -906,14 +906,14 @@ int Query::Item2CQTerm(Item *an_arg, CQTerm &term, const TabID &tmp_table, CondT DEBUG_ASSERT(item_subs && "The cast to (Item_subselect*) was unsuccessful"); bool ignore_limit = false; - if (dynamic_cast(item_subs) != NULL || - dynamic_cast(item_subs) != NULL) + 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) == NULL && - dynamic_cast(item_subs) == NULL && negative && + 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); @@ -938,15 +938,16 @@ int Query::Item2CQTerm(Item *an_arg, CQTerm &term, const TabID &tmp_table, CondT tab_id2subselect.insert(std::make_pair(tmp_table, std::make_pair(vc.n, subselect))); } if (oper_for_subselect) { - if (dynamic_cast(item_subs) != NULL || - dynamic_cast(item_subs) != NULL) { + if (dynamic_cast(item_subs) != nullptr || + dynamic_cast(item_subs) != nullptr) { if (negative) { MarkWithAll(*oper_for_subselect); - if (dynamic_cast(item_subs) != NULL && *oper_for_subselect == common::Operator::O_IN) + 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) != NULL && + if (dynamic_cast(item_subs) != nullptr && dynamic_cast(item_subs)->all == 1) *oper_for_subselect = common::Operator::O_EQ_ALL; } @@ -991,7 +992,7 @@ int Query::Item2CQTerm(Item *an_arg, CQTerm &term, const TabID &tmp_table, CondT 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, NULL, false); + 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; @@ -1005,7 +1006,7 @@ int Query::Item2CQTerm(Item *an_arg, CQTerm &term, const TabID &tmp_table, CondT 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 = NULL; + 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); @@ -1045,7 +1046,7 @@ int Query::Item2CQTerm(Item *an_arg, CQTerm &term, const TabID &tmp_table, CondT // int col_num = // AddColumnForMysqlExpression(expr, // tmp_table, - // NULL, DELAYED, distinct, true); + // 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); @@ -1076,7 +1077,7 @@ int Query::Item2CQTerm(Item *an_arg, CQTerm &term, const TabID &tmp_table, CondT 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 = NULL; + 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); @@ -1119,32 +1120,26 @@ CondID Query::ConditionNumberFromMultipleEquality(Item_equal *conds, const TabID ifield = li++; if (!Item2CQTerm(ifield, zero_term, tmp_table, filter_type)) return CondID(-1); } + ifield = li++; if (!Item2CQTerm(ifield, first_term, tmp_table, filter_type)) return CondID(-1); + CondID filter; - if (!and_me_filter) - cq->CreateConds(filter, tmp_table, first_term, common::Operator::O_EQ, zero_term, CQTerm(), - is_or_subtree || filter_type == CondType::HAVING_COND); - else { - if (is_or_subtree) - cq->Or(*and_me_filter, tmp_table, first_term, common::Operator::O_EQ, zero_term); - else - cq->And(*and_me_filter, tmp_table, first_term, common::Operator::O_EQ, zero_term); - } + 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 (!Item2CQTerm(ifield, next_term, tmp_table, filter_type)) return CondID(-1); - if (!and_me_filter) { - if (is_or_subtree) - cq->Or(filter, tmp_table, next_term, common::Operator::O_EQ, zero_term); - else - cq->And(filter, tmp_table, next_term, common::Operator::O_EQ, zero_term); + 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 { - if (is_or_subtree) - cq->Or(*and_me_filter, tmp_table, next_term, common::Operator::O_EQ, zero_term); - else - cq->And(*and_me_filter, tmp_table, next_term, common::Operator::O_EQ, zero_term); + cq->And(*and_me_filter, tmp_table, filter); } } + if (and_me_filter) filter = *and_me_filter; return filter; } @@ -1181,7 +1176,7 @@ CondID Query::ConditionNumberFromComparison(Item *conds, const TabID &tmp_table, 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 = NULL; // set if IN expression with subselect + Item_in_optimizer *in_opt = nullptr; // set if IN expression with subselect ExtractOperatorType(conds, op, negative, like_esc); Item_func *cond_func = (Item_func *)conds; @@ -1189,17 +1184,17 @@ CondID Query::ConditionNumberFromComparison(Item *conds, const TabID &tmp_table, return ConditionNumberFromMultipleEquality((Item_equal *)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]) == NULL) + 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) == NULL); + 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 == NULL || cond_func->arg_count != 2 || in_opt->arguments()[0]->cols() != 1) return CondID(-2); + 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 @@ -1291,13 +1286,13 @@ CondID Query::ConditionNumberFromComparison(Item *conds, const TabID &tmp_table, } else { CQTerm t; if (!Item2CQTerm(an_arg, t, tmp_table, filter_type, an_arg->type() == Item::SUBSELECT_ITEM ? negative : false, - NULL, &op)) + nullptr, &op)) return CondID(-1); vcs.push_back(t.vc_id); } } else { if (!Item2CQTerm(an_arg, terms[i], tmp_table, filter_type, - an_arg->type() == Item::SUBSELECT_ITEM ? negative : false, NULL, &op)) + 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 || @@ -1335,7 +1330,7 @@ CondID Query::ConditionNumberFromNaked(Item *conds, const TabID &tmp_table, Cond CondID filter; CQTerm naked_col; if (!Item2CQTerm(conds, naked_col, tmp_table, filter_type, - conds->type() == Item::SUBSELECT_ITEM ? (and_me_filter != NULL) : false)) + conds->type() == Item::SUBSELECT_ITEM ? (and_me_filter != nullptr) : false)) return CondID(-1); bool is_string = conds->result_type() == STRING_RESULT; @@ -1347,7 +1342,7 @@ CondID Query::ConditionNumberFromNaked(Item *conds, const TabID &tmp_table, Cond else zero_item = new Item_int((longlong)0); - MysqlExpression *mysql_expression = NULL; + 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); @@ -1390,9 +1385,11 @@ CondID Query::ConditionNumber(Item *conds, const TabID &tmp_table, CondType filt 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 + /* + 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)); @@ -1459,7 +1456,7 @@ CondID Query::ConditionNumber(Item *conds, const TabID &tmp_table, CondType filt 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 = NULL; + 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); @@ -1474,7 +1471,7 @@ CondID Query::ConditionNumber(Item *conds, const TabID &tmp_table, CondType filt 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 = NULL; + 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); @@ -1507,9 +1504,9 @@ CondID Query::ConditionNumber(Item *conds, const TabID &tmp_table, CondType filt } else if (cond_type == Item::FUNC_ITEM) { Item_func *cond_func = (Item_func *)conds; Item_func::Functype func_type = cond_func->functype(); - Item *arg = NULL; + Item *arg = nullptr; if (cond_func->arg_count == 1) arg = cond_func->arguments()[0]; - if (func_type == Item_func::NOT_FUNC && arg != NULL && arg->type() == Item::SUBSELECT_ITEM && + 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 (!Item2CQTerm(arg, term, tmp_table, filter_type)) return CondID(-1); @@ -1588,8 +1585,8 @@ int Query::BuildConditions(Item *conds, CondID &cond_id, CompiledQuery *cq, cons 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 = NULL; - list_to_reinsert = NULL; + cond_to_reinsert = nullptr; + list_to_reinsert = nullptr; Item *cond_removed; if (having && (having->type() == Item::COND_ITEM || @@ -1604,7 +1601,7 @@ bool Query::ClearSubselectTransformation(common::Operator &oper_for_subselect, I // 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++ != NULL) cond_to_reinsert = *li.ref(); + while (li++ != nullptr) cond_to_reinsert = *li.ref(); li.rewind(); while (*li.ref() != cond_to_reinsert) li++; li.remove(); @@ -1613,7 +1610,7 @@ bool Query::ClearSubselectTransformation(common::Operator &oper_for_subselect, I } else { // if no complex boolean formula the original condition was empty cond_removed = having; - having = NULL; + having = nullptr; } cond_removed = UnRef(cond_removed); // check if the extra condition was wrapped into trigger @@ -1625,8 +1622,8 @@ bool Query::ClearSubselectTransformation(common::Operator &oper_for_subselect, I // check if the extra condition is a comparison if (cond_removed->type() != Item::FUNC_ITEM || ((Item_func *)cond_removed)->arg_count != 2) return false; // the right side of equality is the field of the original subselect - if (dynamic_cast(((Item_func *)cond_removed)->arguments()[1]) == NULL) return false; - field_for_subselect = NULL; + if (dynamic_cast(((Item_func *)cond_removed)->arguments()[1]) == nullptr) return false; + field_for_subselect = nullptr; } else if (!having || (having->type() == Item::FUNC_ITEM && (((Item_func *)having)->functype() == Item_func::ISNOTNULLTEST_FUNC || ((Item_func *)having)->functype() == Item_func::TRIG_COND_FUNC))) { @@ -1636,7 +1633,7 @@ bool Query::ClearSubselectTransformation(common::Operator &oper_for_subselect, I // the extra condition should be in the last argument if (((Item_cond *)conds)->argument_list()->elements < 2) return false; List_iterator li(*(((Item_cond *)conds)->argument_list())); - while (li++ != NULL) cond_to_reinsert = *li.ref(); + while (li++ != nullptr) cond_to_reinsert = *li.ref(); li.rewind(); while (*li.ref() != cond_to_reinsert) li++; li.remove(); @@ -1645,7 +1642,7 @@ bool Query::ClearSubselectTransformation(common::Operator &oper_for_subselect, I } else { // if no conjunctive formula the original condition was empty cond_removed = conds; - conds = NULL; + conds = nullptr; } if (cond_removed->type() == Item::FUNC_ITEM && ((Item_func *)cond_removed)->functype() == Item_func::TRIG_COND_FUNC) { @@ -1654,15 +1651,15 @@ bool Query::ClearSubselectTransformation(common::Operator &oper_for_subselect, I } if (cond_removed->type() == Item::COND_ITEM && ((Item_func *)cond_removed)->functype() == Item_func::COND_OR_FUNC) { // if the subselect field could have null values - // equality condition was OR-ed with IS NULL condition + // equality condition was OR-ed with IS nullptr condition Item_cond *cond_cond = (Item_cond *)cond_removed; List_iterator_fast li(*(cond_cond->argument_list())); cond_removed = li++; - if (cond_removed == NULL) return false; - if (li++ == NULL) return false; - if (li++ != NULL) return false; + if (cond_removed == nullptr) return false; + if (li++ == nullptr) return false; + if (li++ != nullptr) return false; // the original having was empty - having = NULL; + having = nullptr; } // check if the extra condition is a comparison if (cond_removed->type() != Item::FUNC_ITEM || ((Item_func *)cond_removed)->arg_count != 2) return false; @@ -1673,7 +1670,7 @@ bool Query::ClearSubselectTransformation(common::Operator &oper_for_subselect, I // the left side of equality should be the left side of the original // expression with subselect Item *left_ref = ((Item_func *)cond_removed)->arguments()[0]; - if (dynamic_cast(left_ref) != NULL) left_ref = ((Item_int_with_ref *)left_ref)->real_item(); + if (dynamic_cast(left_ref) != nullptr) left_ref = ((Item_int_with_ref *)left_ref)->real_item(); if (left_ref->type() != Item::REF_ITEM || ((Item_ref *)left_ref)->ref_type() != Item_ref::DIRECT_REF || ((Item_ref *)left_ref)->real_item() != left_expr_for_subselect) return false; @@ -1777,13 +1774,13 @@ int Query::PrefixCheck(Item *conds) { } case Item::FIELD_ITEM: // regular select case Item::SUM_FUNC_ITEM: { // min(k), max(k), count(), avg(k), sum - const char *field_alias = NULL; - const char *table_alias = NULL; - const char *database_name = NULL; - const char *table_name = NULL; - const char *table_path = NULL; - const TABLE *table_ptr = NULL; - const char *field_name = NULL; + 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 (!FieldUnmysterify(conds, database_name, table_name, table_alias, table_path, table_ptr, field_name, field_alias)) return RETURN_QUERY_TO_MYSQL_ROUTE;