Open davidshiz opened 2 years ago
ACK
ACK
mysql5.7 Logical Operators documentation Reference
https://dev.mysql.com/doc/refman/5.7/en/logical-operators.html#operator_xor
Lack of support for XOR logical operation predicates
enum class StepType {
TABLE_ALIAS,
TMP_TABLE,
CREATE_CONDS,
AND_F,
OR_F,
AND_DESC,
OR_DESC,
T_MODE,
JOIN_T,
LEFT_JOIN_ON,
INNER_JOIN_ON,
ADD_CONDS,
APPLY_CONDS,
ADD_COLUMN,
ADD_ORDER,
UNION,
RESULT,
STEP_ERROR,
CREATE_VC
};
Compare the processing stack for the OR predicate
(gdb) bt
#0 Tianmu::core::CompiledQuery::Or (this=0x7fb692328730, c1=..., t=..., e1=..., pr=Tianmu::common::Operator::O_MORE, e2=..., e3=...)
at /root/work/stonedb-dev-20230116/storage/tianmu/core/compiled_query.cpp:520
#1 0x0000000002cb2b9c in Tianmu::core::Query::ConditionNumberFromComparison (this=0x7fb692328800, conds=0x7fb3eca679a0, tmp_table=..., filter_type=Tianmu::core::CondType::WHERE_COND,
and_me_filter=0x7fb3eca0cf20, is_or_subtree=true, negative=false, can_cond_push=false) at /root/work/stonedb-dev-20230116/storage/tianmu/core/query.cpp:1355
#2 0x0000000002cb4bf4 in Tianmu::core::Query::ConditionNumber (this=0x7fb692328800, conds=0x7fb3eca679a0, tmp_table=..., filter_type=Tianmu::core::CondType::WHERE_COND,
and_me_filter=0x7fb3eca0cf20, is_or_subtree=true, can_cond_push=false) at /root/work/stonedb-dev-20230116/storage/tianmu/core/query.cpp:1575
#3 0x0000000002cb3c41 in Tianmu::core::Query::ConditionNumber (this=0x7fb692328800, conds=0x7fb3ec0e0398, tmp_table=..., filter_type=Tianmu::core::CondType::WHERE_COND, and_me_filter=0x0,
is_or_subtree=false, can_cond_push=false) at /root/work/stonedb-dev-20230116/storage/tianmu/core/query.cpp:1481
#4 0x0000000002cb5636 in Tianmu::core::Query::BuildConditions (this=0x7fb692328800, conds=0x7fb3ec0e0398, cond_id=..., cq=0x7fb692328730, tmp_table=...,
filter_type=Tianmu::core::CondType::WHERE_COND, is_zero_result=false, join_type=Tianmu::core::JoinType::JO_INNER, can_cond_push=false)
at /root/work/stonedb-dev-20230116/storage/tianmu/core/query.cpp:1623
#5 0x0000000002cd4276 in Tianmu::core::Query::Compile (this=0x7fb692328800, compiled_query=0x7fb692328730, selects_list=0x7fb3ec0def60, last_distinct=0x0, res_tab=0x0, ignore_limit=false,
left_expr_for_subselect=0x0, oper_for_subselect=0x0, ignore_minmax=false, for_subq_in_where=false) at /root/work/stonedb-dev-20230116/storage/tianmu/core/query_compile.cpp:1122
#6 0x0000000002c8026b in Tianmu::core::Engine::Execute (this=0x53dcfd0, thd=0x7fb3ec0db740, lex=0x7fb3ec0dda68, result_output=0x7fb3ec0eee20, unit_for_union=0x0)
at /root/work/stonedb-dev-20230116/storage/tianmu/core/engine_execute.cpp:436
#7 0x0000000002c7f5a2 in Tianmu::core::Engine::HandleSelect (this=0x53dcfd0, thd=0x7fb3ec0db740, lex=0x7fb3ec0dda68, result=@0x7fb692328dc8: 0x7fb3ec0eee20, setup_tables_done_option=0,
res=@0x7fb692328dc4: 0, optimize_after_tianmu=@0x7fb692328dbc: 1, tianmu_free_join=@0x7fb692328dc0: 1, with_insert=0)
at /root/work/stonedb-dev-20230116/storage/tianmu/core/engine_execute.cpp:238
#8 0x0000000002d839fd in Tianmu::handler::ha_my_tianmu_query (thd=0x7fb3ec0db740, lex=0x7fb3ec0dda68, result_output=@0x7fb692328dc8: 0x7fb3ec0eee20, setup_tables_done_option=0,
res=@0x7fb692328dc4: 0, optimize_after_tianmu=@0x7fb692328dbc: 1, tianmu_free_join=@0x7fb692328dc0: 1, with_insert=0)
at /root/work/stonedb-dev-20230116/storage/tianmu/handler/ha_my_tianmu.cpp:88
#9 0x00000000023c0859 in execute_sqlcom_select (thd=0x7fb3ec0db740, all_tables=0x7fb3ec0ee310) at /root/work/stonedb-dev-20230116/sql/sql_parse.cc:5208
#10 0x00000000023b9bcf in mysql_execute_command (thd=0x7fb3ec0db740, first_level=true) at /root/work/stonedb-dev-20230116/sql/sql_parse.cc:2851
#11 0x00000000023c18bf in mysql_parse (thd=0x7fb3ec0db740, parser_state=0x7fb692329f90) at /root/work/stonedb-dev-20230116/sql/sql_parse.cc:5646
#12 0x00000000023b68a8 in dispatch_command (thd=0x7fb3ec0db740, com_data=0x7fb69232a730, command=COM_QUERY) at /root/work/stonedb-dev-20230116/sql/sql_parse.cc:1495
#13 0x00000000023b56e9 in do_command (thd=0x7fb3ec0db740) at /root/work/stonedb-dev-20230116/sql/sql_parse.cc:1034
#14 0x00000000024e6ebf in handle_connection (arg=0x901a5c0) at /root/work/stonedb-dev-20230116/sql/conn_handler/connection_handler_per_thread.cc:313
#15 0x0000000002bb6cd8 in pfs_spawn_thread (arg=0x8e71990) at /root/work/stonedb-dev-20230116/storage/perfschema/pfs.cc:2197
#16 0x00007fb6e1ce41ca in start_thread () from /lib64/libpthread.so.0
#17 0x00007fb6dec3ce73 in clone () from /lib64/libc.so.6
Code with disabled XOR predicate functionality
Call stack
(gdb) bt
#0 Tianmu::core::Query::ConditionNumber (this=0x7fb692328800, conds=0x7fb3ec0e0398, tmp_table=..., filter_type=Tianmu::core::CondType::WHERE_COND, and_me_filter=0x0, is_or_subtree=false,
can_cond_push=false) at /root/work/stonedb-dev-20230116/storage/tianmu/core/query.cpp:1571
#1 0x0000000002cb5636 in Tianmu::core::Query::BuildConditions (this=0x7fb692328800, conds=0x7fb3ec0e0398, cond_id=..., cq=0x7fb692328730, tmp_table=...,
filter_type=Tianmu::core::CondType::WHERE_COND, is_zero_result=false, join_type=Tianmu::core::JoinType::JO_INNER, can_cond_push=false)
at /root/work/stonedb-dev-20230116/storage/tianmu/core/query.cpp:1623
#2 0x0000000002cd4276 in Tianmu::core::Query::Compile (this=0x7fb692328800, compiled_query=0x7fb692328730, selects_list=0x7fb3ec0def60, last_distinct=0x0, res_tab=0x0, ignore_limit=false,
left_expr_for_subselect=0x0, oper_for_subselect=0x0, ignore_minmax=false, for_subq_in_where=false) at /root/work/stonedb-dev-20230116/storage/tianmu/core/query_compile.cpp:1122
#3 0x0000000002c8026b in Tianmu::core::Engine::Execute (this=0x53dcfd0, thd=0x7fb3ec0db740, lex=0x7fb3ec0dda68, result_output=0x7fb3ec0eee70, unit_for_union=0x0)
at /root/work/stonedb-dev-20230116/storage/tianmu/core/engine_execute.cpp:436
#4 0x0000000002c7f5a2 in Tianmu::core::Engine::HandleSelect (this=0x53dcfd0, thd=0x7fb3ec0db740, lex=0x7fb3ec0dda68, result=@0x7fb692328dc8: 0x7fb3ec0eee70, setup_tables_done_option=0,
res=@0x7fb692328dc4: 0, optimize_after_tianmu=@0x7fb692328dbc: 1, tianmu_free_join=@0x7fb692328dc0: 1, with_insert=0)
at /root/work/stonedb-dev-20230116/storage/tianmu/core/engine_execute.cpp:238
#5 0x0000000002d839fd in Tianmu::handler::ha_my_tianmu_query (thd=0x7fb3ec0db740, lex=0x7fb3ec0dda68, result_output=@0x7fb692328dc8: 0x7fb3ec0eee70, setup_tables_done_option=0,
res=@0x7fb692328dc4: 0, optimize_after_tianmu=@0x7fb692328dbc: 1, tianmu_free_join=@0x7fb692328dc0: 1, with_insert=0)
at /root/work/stonedb-dev-20230116/storage/tianmu/handler/ha_my_tianmu.cpp:88
#6 0x00000000023c0859 in execute_sqlcom_select (thd=0x7fb3ec0db740, all_tables=0x7fb3ec0ee310) at /root/work/stonedb-dev-20230116/sql/sql_parse.cc:5208
#7 0x00000000023b9bcf in mysql_execute_command (thd=0x7fb3ec0db740, first_level=true) at /root/work/stonedb-dev-20230116/sql/sql_parse.cc:2851
#8 0x00000000023c18bf in mysql_parse (thd=0x7fb3ec0db740, parser_state=0x7fb692329f90) at /root/work/stonedb-dev-20230116/sql/sql_parse.cc:5646
#9 0x00000000023b68a8 in dispatch_command (thd=0x7fb3ec0db740, com_data=0x7fb69232a730, command=COM_QUERY) at /root/work/stonedb-dev-20230116/sql/sql_parse.cc:1495
#10 0x00000000023b56e9 in do_command (thd=0x7fb3ec0db740) at /root/work/stonedb-dev-20230116/sql/sql_parse.cc:1034
#11 0x00000000024e6ebf in handle_connection (arg=0x901a5c0) at /root/work/stonedb-dev-20230116/sql/conn_handler/connection_handler_per_thread.cc:313
#12 0x0000000002bb6cd8 in pfs_spawn_thread (arg=0x8e71990) at /root/work/stonedb-dev-20230116/storage/perfschema/pfs.cc:2197
#13 0x00007fb6e1ce41ca in start_thread () from /lib64/libpthread.so.0
#14 0x00007fb6dec3ce73 in clone () from /lib64/libc.so.6
The query tree transformation code is a bit complex and needs to be analyzed carefully
(gdb) bt
#0 Tianmu::core::Query::Preexecute (this=this@entry=0x7f76ba34ae20, qu=..., sender=sender@entry=0x7f73d44a1d70, display_now=display_now@entry=true)
at /root/work/stonedb-dev-20230207/storage/tianmu/core/query.cpp:572
#1 0x00000000014aa681 in Tianmu::core::Engine::Execute (this=<optimized out>, thd=0x7f7414c654b0, lex=0x7f7414c67628, result_output=0x7f7414a063d8, unit_for_union=<optimized out>)
at /root/work/stonedb-dev-20230207/storage/tianmu/core/engine_execute.cpp:477
#2 0x00000000014abaaa in Tianmu::core::Engine::HandleSelect (this=<optimized out>, thd=thd@entry=0x7f7414c654b0, lex=lex@entry=0x7f7414c67628, result=@0x7f76ba34b1d8: 0x7f7414a063d8,
setup_tables_done_option=setup_tables_done_option@entry=0, res=@0x7f76ba34b1cc: 32628, optimize_after_tianmu=<optimized out>, tianmu_free_join=<optimized out>,
with_insert=<optimized out>) at /root/work/stonedb-dev-20230207/storage/tianmu/core/engine_execute.cpp:238
#3 0x0000000001532365 in Tianmu::handler::ha_my_tianmu_query (thd=thd@entry=0x7f7414c654b0, lex=lex@entry=0x7f7414c67628, result_output=@0x7f76ba34b1d8: 0x7f7414a063d8,
setup_tables_done_option=setup_tables_done_option@entry=0, res=@0x7f76ba34b1cc: 32628, optimize_after_tianmu=@0x7f76ba34b1d4: 1, tianmu_free_join=@0x7f76ba34b1d0: 1, with_insert=0)
at /root/work/stonedb-dev-20230207/storage/tianmu/handler/ha_my_tianmu.cpp:88
#4 0x0000000000eb44ae in execute_sqlcom_select (thd=thd@entry=0x7f7414c654b0, all_tables=<optimized out>) at /root/work/stonedb-dev-20230207/sql/sql_parse.cc:4874
#5 0x0000000000ebbac8 in mysql_execute_command (thd=0x7f7414c654b0, first_level=<optimized out>) at /root/work/stonedb-dev-20230207/sql/sql_parse.cc:2675
#6 0x0000000000ebdf3d in mysql_parse (thd=thd@entry=0x7f7414c654b0, parser_state=parser_state@entry=0x7f76ba34c0c0) at /root/work/stonedb-dev-20230207/sql/sql_parse.cc:5279
#7 0x0000000000ebf23c in dispatch_command (thd=0x7f7414c654b0, com_data=<optimized out>, command=COM_QUERY) at /root/work/stonedb-dev-20230207/sql/sql_parse.cc:1399
#8 0x0000000000ec03f7 in do_command (thd=thd@entry=0x7f7414c654b0) at /root/work/stonedb-dev-20230207/sql/sql_parse.cc:976
#9 0x0000000000f78c58 in handle_connection (arg=arg@entry=0x7081d60) at /root/work/stonedb-dev-20230207/sql/conn_handler/connection_handler_per_thread.cc:313
#10 0x00000000014265e7 in pfs_spawn_thread (arg=0x6afef10) at /root/work/stonedb-dev-20230207/storage/perfschema/pfs.cc:2197
#11 0x00007f7708fad1ca in start_thread () from /lib64/libpthread.so.0
#12 0x00007f7705f05e73 in clone () from /lib64/libc.so.6
TempTable *Query::Preexecute(CompiledQuery &qu, ResultSender *sender, [[maybe_unused]] bool display_now) {
if (TIANMU_LOGCHECK(LogCtl_Level::DEBUG)) {
qu.Print(this);
}
std::vector<Condition *> 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<JustATable> 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
((TempTable *)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);
((TempTable *)ta[-step.t1.n - 1].get())->ReserveVirtColumns(qu.NumOfVirtualColumns(step.t1));
break;
case CompiledQuery::StepType::CREATE_CONDS:
DEBUG_ASSERT(step.t1.n < 0);
if (step.ex_op == common::ExtraOperation::EX_COND_PUSH) {
((TempTable *)ta[-step.t1.n - 1].get())->MarkCondPush();
}
step.e1.vc = (step.e1.vc_id != common::NULL_VALUE_32)
? ((TempTable *)ta[-step.t1.n - 1].get())->GetVirtualColumn(step.e1.vc_id)
: nullptr;
step.e2.vc = (step.e2.vc_id != common::NULL_VALUE_32)
? ((TempTable *)ta[-step.t1.n - 1].get())->GetVirtualColumn(step.e2.vc_id)
: nullptr;
step.e3.vc = (step.e3.vc_id != common::NULL_VALUE_32)
? ((TempTable *)ta[-step.t1.n - 1].get())->GetVirtualColumn(step.e3.vc_id)
: nullptr;
if (step.n1 != static_cast<int64_t>(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, (TempTable *)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<SingleTreeCondition *>(conds[step.c2.n])->GetTree(),
(TempTable *)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, (TempTable *)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(((SingleTreeCondition *)conds[step.c2.n])->GetTree(),
(TempTable *)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 = (TempTable *)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<SingleTreeCondition *>(conds[step.c1.n])
->AddTree(common::LogicalOperator::O_AND, desc.tree, no_dims);
} else {
static_cast<SingleTreeCondition *>(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<SingleTreeCondition *>(conds[step.c1.n])
->AddTree(lop, static_cast<SingleTreeCondition *>(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<SingleTreeCondition *>(conds[step.c2.n])->GetTree(),
(TempTable *)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)
? ((TempTable *)ta[-step.t1.n - 1].get())->GetVirtualColumn(step.e1.vc_id)
: nullptr;
step.e2.vc = (step.e2.vc_id != common::NULL_VALUE_32)
? ((TempTable *)ta[-step.t1.n - 1].get())->GetVirtualColumn(step.e2.vc_id)
: nullptr;
step.e3.vc = (step.e3.vc_id != common::NULL_VALUE_32)
? ((TempTable *)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, (TempTable *)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<SingleTreeCondition *>(conds[step.c1.n])
->AddDescriptor(lop, step.e1, step.op, step.e2, step.e3, (TempTable *)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);
((TempTable *)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);
((TempTable *)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<int64_t>(CondType::HAVING_COND))
conds[step.c1.n]->Simplify();
((TempTable *)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;
((TempTable *)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;
((TempTable *)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 = (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);
ParameterizedFilter *filter = tb->GetFilterP();
if (cur_limit != -1 && filter->NoParameterizedDescs())
cur_limit = -1;
std::set<int> 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++) {
(used_dims.find(i) == used_dims.end() && is_simple_filter && (!tb->CanCondPushDown()))
? filter->mind_->ResetUsedInOutput(i)
: 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 =
((TempTable *)ta[-step.t1.n - 1].get())->GetVirtualColumn(step.e1.vc_id); // vc must have been created
step.a1.n = ((TempTable *)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 = (TempTable *)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 = ((TempTable *)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 = ((TempTable *)ta[-step.t1.n - 1].get())->GetVirtualColumn(step.a2.n)->Type();
std::vector<vcolumn::VirtualColumn *> vcs;
for (uint i = 0; i < step.virt_cols.size(); i++)
vcs.push_back(((TempTable *)ta[-step.t1.n - 1].get())->GetVirtualColumn(step.virt_cols[i]));
int c = ((TempTable *)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;
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 = (PhysicalColumn *)t_src->GetColumn(step.a2.n >= 0 ? step.a2.n : -step.a2.n - 1);
int c = ((TempTable *)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 =
((TempTable *)ta[-step.t1.n - 1].get())
->AddVirtColumn(new vcolumn::SubSelectColumn(
dynamic_cast<TempTable *>(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 = (TempTable *)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(*(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(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 : 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(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();
}
}
break;
case CompiledQuery::StepType::RESULT:
DEBUG_ASSERT(step.t1.n < 0 && static_cast<size_t>(-step.t1.n - 1) < ta.size() &&
ta[-step.t1.n - 1]->TableType() == TType::TEMP_TABLE);
output_table = (TempTable *)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<int>(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;
}
The element node of mysql needs to be converted to the predicate description of stonedb
Have you read the Contributing Guidelines on issues?
Please confirm if bug report does NOT exists already ?
Describe the problem
Expected behavior
mysql> select 1 from (select * from tt) as A join tt where A.val > 1 XOR tt.val > 2; +---+ | 1 | +---+ | 1 | +---+ 1 row in set (0.00 sec)
How To Reproduce
Environment
ubuntu@ubuntu:~$ cat /etc/os-release NAME="Ubuntu" VERSION="20.04.4 LTS (Focal Fossa)" ID=ubuntu ID_LIKE=debian PRETTY_NAME="Ubuntu 20.04.4 LTS" VERSION_ID="20.04"
ubuntu@ubuntu:~$ /stonedb57/install/bin/mysqld --version /stonedb57/install/bin/mysqld Ver 5.7.36-StoneDB for Linux on x86_64 (build-) build information as follow: Repository address: https://github.com/stoneatom/stonedb.git:stonedb-5.7-dev Branch name: stonedb-5.7-dev Last commit ID: https://github.com/stoneatom/stonedb/commit/5d996f9355b5241eaa54f3e4b652a60c9c229b0e Last commit time: Date: Sat Oct 8 14:34:42 2022 +0800 Build time: Date: Fri 14 Oct 2022 12:28:00 PM UTC
Are you interested in submitting a PR to solve the problem?