You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-08-01 06:46:55 +03:00
MCOL-677 Fix incompatible join detection
If two tables have multiple joins and one of them was compatible then the incompatible join detection would fail. This patch moves the incompatible join detection so that every join is checked. It also removes the incompatible join detection from expressionstep as this is redundant and was causing some valid quries to fail.
This commit is contained in:
@ -1578,6 +1578,70 @@ void spanningTreeCheck(TableInfoMap& tableInfoMap, JobStepVector joinSteps, JobI
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
// Check that join is compatible
|
||||
set<string> views1;
|
||||
set<string> tables1;
|
||||
string errStr;
|
||||
|
||||
vector<uint32_t>::iterator k = joinedTables.begin();
|
||||
|
||||
k = joinedTables.begin();
|
||||
for (; k != joinedTables.end(); k++)
|
||||
{
|
||||
if (jobInfo.keyInfo->tupleKeyVec[*k].fView.empty())
|
||||
tables1.insert(jobInfo.keyInfo->tupleKeyToName[*k]);
|
||||
else
|
||||
views1.insert(jobInfo.keyInfo->tupleKeyVec[*k].fView);
|
||||
|
||||
if (jobInfo.incompatibleJoinMap.find(*k) != jobInfo.incompatibleJoinMap.end())
|
||||
{
|
||||
errcode = ERR_INCOMPATIBLE_JOIN;
|
||||
|
||||
uint32_t key2 = jobInfo.incompatibleJoinMap[*k];
|
||||
if (jobInfo.keyInfo->tupleKeyVec[*k].fView.length() > 0)
|
||||
{
|
||||
string view2 = jobInfo.keyInfo->tupleKeyVec[key2].fView;
|
||||
if (jobInfo.keyInfo->tupleKeyVec[*k].fView == view2)
|
||||
{
|
||||
// same view
|
||||
errStr += "Tables in '" + view2 + "' have";
|
||||
}
|
||||
else if (view2.empty())
|
||||
{
|
||||
// view and real table
|
||||
errStr += "'" + jobInfo.keyInfo->tupleKeyVec[*k].fView + "' and '" +
|
||||
jobInfo.keyInfo->tupleKeyToName[key2] + "' have";
|
||||
}
|
||||
else
|
||||
{
|
||||
// two views
|
||||
errStr += "'" + jobInfo.keyInfo->tupleKeyVec[*k].fView + "' and '" +
|
||||
view2 + "' have";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string view2 = jobInfo.keyInfo->tupleKeyVec[key2].fView;
|
||||
if (view2.empty())
|
||||
{
|
||||
// two real tables
|
||||
errStr += "'" + jobInfo.keyInfo->tupleKeyToName[*k] + "' and '" +
|
||||
jobInfo.keyInfo->tupleKeyToName[key2] + "' have";
|
||||
}
|
||||
else
|
||||
{
|
||||
// real table and view
|
||||
errStr += "'" + jobInfo.keyInfo->tupleKeyToName[*k] + "' and '" +
|
||||
view2 + "' have";
|
||||
}
|
||||
}
|
||||
args.add(errStr);
|
||||
spanningTree = false;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 1c. check again if all tables are joined after pulling in function joins.
|
||||
if (joinedTables.size() < tableInfoMap.size())
|
||||
{
|
||||
@ -1588,74 +1652,15 @@ void spanningTreeCheck(TableInfoMap& tableInfoMap, JobStepVector joinSteps, JobI
|
||||
notJoinedTables.push_back(i->first);
|
||||
}
|
||||
|
||||
vector<uint32_t>::iterator k = joinedTables.begin();
|
||||
set<string> views1;
|
||||
set<string> tables1;
|
||||
for (; k != joinedTables.end(); k++)
|
||||
{
|
||||
if (jobInfo.keyInfo->tupleKeyVec[*k].fView.empty())
|
||||
tables1.insert(jobInfo.keyInfo->tupleKeyToName[*k]);
|
||||
else
|
||||
views1.insert(jobInfo.keyInfo->tupleKeyVec[*k].fView);
|
||||
}
|
||||
|
||||
k = notJoinedTables.begin();
|
||||
set<string> views2;
|
||||
set<string> tables2;
|
||||
string errStr;
|
||||
for (; k != notJoinedTables.end(); k++)
|
||||
k = notJoinedTables.begin();
|
||||
for (; k != notJoinedTables.end(); k++)
|
||||
{
|
||||
if (jobInfo.keyInfo->tupleKeyVec[*k].fView.empty())
|
||||
tables2.insert(jobInfo.keyInfo->tupleKeyToName[*k]);
|
||||
else
|
||||
views2.insert(jobInfo.keyInfo->tupleKeyVec[*k].fView);
|
||||
|
||||
if (jobInfo.incompatibleJoinMap.find(*k) != jobInfo.incompatibleJoinMap.end())
|
||||
{
|
||||
errcode = ERR_INCOMPATIBLE_JOIN;
|
||||
|
||||
uint32_t key2 = jobInfo.incompatibleJoinMap[*k];
|
||||
if (jobInfo.keyInfo->tupleKeyVec[*k].fView.length() > 0)
|
||||
{
|
||||
string view2 = jobInfo.keyInfo->tupleKeyVec[key2].fView;
|
||||
if (jobInfo.keyInfo->tupleKeyVec[*k].fView == view2)
|
||||
{
|
||||
// same view
|
||||
errStr += "Tables in '" + view2 + "' have";
|
||||
}
|
||||
else if (view2.empty())
|
||||
{
|
||||
// view and real table
|
||||
errStr += "'" + jobInfo.keyInfo->tupleKeyVec[*k].fView + "' and '" +
|
||||
jobInfo.keyInfo->tupleKeyToName[key2] + "' have";
|
||||
}
|
||||
else
|
||||
{
|
||||
// two views
|
||||
errStr += "'" + jobInfo.keyInfo->tupleKeyVec[*k].fView + "' and '" +
|
||||
view2 + "' have";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string view2 = jobInfo.keyInfo->tupleKeyVec[key2].fView;
|
||||
if (view2.empty())
|
||||
{
|
||||
// two real tables
|
||||
errStr += "'" + jobInfo.keyInfo->tupleKeyToName[*k] + "' and '" +
|
||||
jobInfo.keyInfo->tupleKeyToName[key2] + "' have";
|
||||
}
|
||||
else
|
||||
{
|
||||
// real table and view
|
||||
errStr += "'" + jobInfo.keyInfo->tupleKeyToName[*k] + "' and '" +
|
||||
view2 + "' have";
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (errStr.empty())
|
||||
@ -1717,11 +1722,11 @@ void spanningTreeCheck(TableInfoMap& tableInfoMap, JobStepVector joinSteps, JobI
|
||||
}
|
||||
|
||||
errStr = set1 + "' and " + set2 + "' are";
|
||||
args.add(errStr);
|
||||
spanningTree = false;
|
||||
}
|
||||
}
|
||||
|
||||
args.add(errStr);
|
||||
spanningTree = false;
|
||||
}
|
||||
|
||||
// 2. no cycles
|
||||
|
Reference in New Issue
Block a user