1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-04-18 21:44:02 +03:00

fix(plugin): MCOL-4942 No-table-SELECT now can return empty set (#3415)

The query like "SELECT 1 WHERE 1=0" was returning a row despite
unsatisfiable condition in WHERE. Now it returns an empty set.
This commit is contained in:
Sergey Zefirov 2025-03-05 10:36:05 +03:00 committed by GitHub
parent 4b7016e67b
commit e99db9c212
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 117 additions and 29 deletions

View File

@ -4520,33 +4520,6 @@ void associateTupleJobSteps(JobStepVector& querySteps, JobStepVector& projectSte
cout << endl;
}
// @bug 2771, handle no table select query
if (jobInfo.tableList.empty())
{
makeNoTableJobStep(querySteps, projectSteps, deliverySteps, jobInfo);
return;
}
// Create a step vector for each table in the from clause.
TableInfoMap tableInfoMap;
for (uint64_t i = 0; i < jobInfo.tableList.size(); i++)
{
uint32_t tableUid = jobInfo.tableList[i];
tableInfoMap[tableUid] = TableInfo();
tableInfoMap[tableUid].fTableOid = jobInfo.keyInfo->tupleKeyVec[tableUid].fId;
tableInfoMap[tableUid].fName = jobInfo.keyInfo->keyName[tableUid];
tableInfoMap[tableUid].fAlias = jobInfo.keyInfo->tupleKeyVec[tableUid].fTable;
tableInfoMap[tableUid].fView = jobInfo.keyInfo->tupleKeyVec[tableUid].fView;
tableInfoMap[tableUid].fSchema = jobInfo.keyInfo->tupleKeyVec[tableUid].fSchema;
tableInfoMap[tableUid].fSubId = jobInfo.keyInfo->tupleKeyVec[tableUid].fSubId;
tableInfoMap[tableUid].fColsInColMap = jobInfo.columnMap[tableUid];
}
// Set of the columns being projected.
for (auto i = jobInfo.pjColList.begin(); i != jobInfo.pjColList.end(); i++)
jobInfo.returnColSet.insert(i->key);
// Strip constantbooleanquerySteps
for (uint64_t i = 0; i < querySteps.size();)
{
@ -4582,6 +4555,33 @@ void associateTupleJobSteps(JobStepVector& querySteps, JobStepVector& projectSte
}
}
// @bug 2771, handle no table select query
if (jobInfo.tableList.empty())
{
makeNoTableJobStep(querySteps, projectSteps, deliverySteps, jobInfo);
return;
}
// Create a step vector for each table in the from clause.
TableInfoMap tableInfoMap;
for (uint64_t i = 0; i < jobInfo.tableList.size(); i++)
{
uint32_t tableUid = jobInfo.tableList[i];
tableInfoMap[tableUid] = TableInfo();
tableInfoMap[tableUid].fTableOid = jobInfo.keyInfo->tupleKeyVec[tableUid].fId;
tableInfoMap[tableUid].fName = jobInfo.keyInfo->keyName[tableUid];
tableInfoMap[tableUid].fAlias = jobInfo.keyInfo->tupleKeyVec[tableUid].fTable;
tableInfoMap[tableUid].fView = jobInfo.keyInfo->tupleKeyVec[tableUid].fView;
tableInfoMap[tableUid].fSchema = jobInfo.keyInfo->tupleKeyVec[tableUid].fSchema;
tableInfoMap[tableUid].fSubId = jobInfo.keyInfo->tupleKeyVec[tableUid].fSubId;
tableInfoMap[tableUid].fColsInColMap = jobInfo.columnMap[tableUid];
}
// Set of the columns being projected.
for (auto i = jobInfo.pjColList.begin(); i != jobInfo.pjColList.end(); i++)
jobInfo.returnColSet.insert(i->key);
// double check if the function join canditates are still there.
JobStepVector steps = querySteps;

View File

@ -284,7 +284,9 @@ void TupleConstantStep::constructContanstRow(const JobInfo& jobInfo)
void TupleConstantStep::run()
{
if (fInputJobStepAssociation.outSize() == 0)
{
throw logic_error("No input data list for constant step.");
}
fInputDL = fInputJobStepAssociation.outAt(0)->rowGroupDL();
@ -585,7 +587,9 @@ void TupleConstantStep::formatMiniStats()
}
// class TupleConstantOnlyStep
TupleConstantOnlyStep::TupleConstantOnlyStep(const JobInfo& jobInfo) : TupleConstantStep(jobInfo)
TupleConstantOnlyStep::TupleConstantOnlyStep(const JobInfo& jobInfo)
: TupleConstantStep(jobInfo)
, fEmptySet(jobInfo.constantFalse)
{
// fExtendedInfo = "TCOS: ";
}
@ -667,8 +671,11 @@ void TupleConstantOnlyStep::run()
fillInConstants();
if (!fEmptySet)
{
fOutputDL->insert(rgDataOut);
}
}
catch (...)
{
handleException(std::current_exception(), logging::tupleConstantStepErr, logging::ERR_ALWAYS_CRITICAL,

View File

@ -132,6 +132,7 @@ class TupleConstantOnlyStep : public TupleConstantStep
uint32_t nextBand(messageqcpp::ByteStream& bs) override;
protected:
bool fEmptySet;
using TupleConstantStep::fillInConstants;
void fillInConstants() override;
};

View File

@ -0,0 +1,22 @@
DROP DATABASE IF EXISTS MCOL4942;
CREATE DATABASE MCOL4942;
USE MCOL4942;
CREATE TABLE t1col (id INT) ENGINE=Columnstore;
SELECT * FROM
(
SELECT ID
FROM
(
SELECT 1 ID
FROM
t1col
) V
UNION ALL
SELECT ID
FROM
(
SELECT NULL ID WHERE 1111=2222
) V
) U;
ID
DROP DATABASE MCOL4942;

View File

@ -0,0 +1,40 @@
--disable_warnings
DROP DATABASE IF EXISTS MCOL4942;
--enable_warnings
CREATE DATABASE MCOL4942;
USE MCOL4942;
CREATE TABLE t1col (id INT) ENGINE=Columnstore;
SELECT * FROM
(
SELECT ID
FROM
(
SELECT 1 ID
FROM
t1col
) V
UNION ALL
SELECT ID
FROM
(
SELECT NULL ID WHERE 1111=2222
) V
) U;
DROP DATABASE MCOL4942;

View File

@ -283,6 +283,24 @@ class ProtocolError : public std::logic_error
} \
} while (0)
#define idblog(x) \
do \
{ \
{ \
std::ostringstream os; \
\
os << __FILE__ << "@" << __LINE__ << ": \'" << x << "\'"; \
std::cerr << os.str() << std::endl; \
logging::MessageLog logger((logging::LoggingID())); \
logging::Message message; \
logging::Message::Args args; \
\
args.add(os.str()); \
message.format(args); \
logger.logErrorMessage(message); \
} \
} while (0)
#define idbassert_s(x, s) \
do \
{ \