You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-07-29 08:21:15 +03:00
MCOL-4666 Empty set when using BIT OR and BIT AND functions in WHERE
This commit is contained in:
@ -307,6 +307,7 @@ void FunctionColumn::unserialize(messageqcpp::ByteStream& b)
|
|||||||
FuncExp* funcExp = FuncExp::instance();
|
FuncExp* funcExp = FuncExp::instance();
|
||||||
fFunctor = funcExp->getFunctor(fFunctionName);
|
fFunctor = funcExp->getFunctor(fFunctionName);
|
||||||
fFunctor->timeZone(fTimeZone);
|
fFunctor->timeZone(fTimeZone);
|
||||||
|
fFunctor->fix(*this);
|
||||||
|
|
||||||
// @bug 3506. Special treatment for rand() function. reset the seed
|
// @bug 3506. Special treatment for rand() function. reset the seed
|
||||||
Func_rand* rand = dynamic_cast<Func_rand*>(fFunctor);
|
Func_rand* rand = dynamic_cast<Func_rand*>(fFunctor);
|
||||||
|
@ -309,15 +309,6 @@ public:
|
|||||||
return fFunctor->getTimeIntVal(row, fFunctionParms, isNull, fOperationType);
|
return fFunctor->getTimeIntVal(row, fFunctionParms, isNull, fOperationType);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fixIfNeeded() override
|
|
||||||
{
|
|
||||||
if (fFixed)
|
|
||||||
return false;
|
|
||||||
if (fFunctor->fix(*this))
|
|
||||||
return true;
|
|
||||||
fFixed = true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void setFunctor(funcexp::Func* functor)
|
void setFunctor(funcexp::Func* functor)
|
||||||
{
|
{
|
||||||
fFunctor = functor;
|
fFunctor = functor;
|
||||||
|
@ -328,11 +328,6 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool fixIfNeeded()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// return all flag set if the other column is outer join column (+)
|
// return all flag set if the other column is outer join column (+)
|
||||||
bool fReturnAll;
|
bool fReturnAll;
|
||||||
|
@ -594,6 +594,17 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void writeCodeAndError(messageqcpp::ByteStream::quadbyte code,
|
||||||
|
const std::string emsg)
|
||||||
|
{
|
||||||
|
messageqcpp::ByteStream emsgBs;
|
||||||
|
messageqcpp::ByteStream tbs;
|
||||||
|
tbs << code;
|
||||||
|
fIos.write(tbs);
|
||||||
|
emsgBs << emsg;
|
||||||
|
fIos.write(emsgBs);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void operator()()
|
void operator()()
|
||||||
@ -692,7 +703,18 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
new_plan:
|
new_plan:
|
||||||
csep.unserialize(bs);
|
try
|
||||||
|
{
|
||||||
|
csep.unserialize(bs);
|
||||||
|
}
|
||||||
|
catch (logging::IDBExcept &ex)
|
||||||
|
{
|
||||||
|
// We can get here on illegal function parameter data type, e.g.
|
||||||
|
// SELECT blob_column|1 FROM t1;
|
||||||
|
statementsRunningCount->decr(stmtCounted);
|
||||||
|
writeCodeAndError(ex.errorCode(), std::string(ex.what()));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
querytele::QueryTeleStats qts;
|
querytele::QueryTeleStats qts;
|
||||||
|
|
||||||
@ -781,41 +803,28 @@ new_plan:
|
|||||||
{
|
{
|
||||||
try // @bug2244: try/catch around fIos.write() calls responding to makeTupleList
|
try // @bug2244: try/catch around fIos.write() calls responding to makeTupleList
|
||||||
{
|
{
|
||||||
std::string emsg("NOERROR");
|
|
||||||
messageqcpp::ByteStream emsgBs;
|
|
||||||
messageqcpp::ByteStream::quadbyte tflg = 0;
|
|
||||||
jl = joblist::JobListFactory::makeJobList(&csep, fRm, true, true);
|
jl = joblist::JobListFactory::makeJobList(&csep, fRm, true, true);
|
||||||
// assign query stats
|
// assign query stats
|
||||||
jl->queryStats(fStats);
|
jl->queryStats(fStats);
|
||||||
|
|
||||||
messageqcpp::ByteStream tbs;
|
|
||||||
|
|
||||||
if ((jl->status()) == 0 && (jl->putEngineComm(fEc) == 0))
|
if ((jl->status()) == 0 && (jl->putEngineComm(fEc) == 0))
|
||||||
{
|
{
|
||||||
usingTuples = true;
|
usingTuples = true;
|
||||||
|
|
||||||
//Tell the FE that we're sending tuples back, not TableBands
|
//Tell the FE that we're sending tuples back, not TableBands
|
||||||
tbs << tflg;
|
writeCodeAndError(0, "NOERROR");
|
||||||
fIos.write(tbs);
|
|
||||||
emsgBs.reset();
|
|
||||||
emsgBs << emsg;
|
|
||||||
fIos.write(emsgBs);
|
|
||||||
auto tjlp = dynamic_cast<joblist::TupleJobList*>(jl.get());
|
auto tjlp = dynamic_cast<joblist::TupleJobList*>(jl.get());
|
||||||
assert(tjlp);
|
assert(tjlp);
|
||||||
tbs.restart();
|
messageqcpp::ByteStream tbs;
|
||||||
tbs << tjlp->getOutputRowGroup();
|
tbs << tjlp->getOutputRowGroup();
|
||||||
fIos.write(tbs);
|
fIos.write(tbs);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
const std::string emsg = jl->errMsg();
|
||||||
statementsRunningCount->decr(stmtCounted);
|
statementsRunningCount->decr(stmtCounted);
|
||||||
tflg = jl->status();
|
writeCodeAndError(jl->status(), emsg);
|
||||||
emsg = jl->errMsg();
|
|
||||||
tbs << tflg;
|
|
||||||
fIos.write(tbs);
|
|
||||||
emsgBs.reset();
|
|
||||||
emsgBs << emsg;
|
|
||||||
fIos.write(emsgBs);
|
|
||||||
std::cerr << "ExeMgr: could not build a tuple joblist: " << emsg << std::endl;
|
std::cerr << "ExeMgr: could not build a tuple joblist: " << emsg << std::endl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -105,5 +105,20 @@ a 1<<a 1>>a
|
|||||||
64 0 0
|
64 0 0
|
||||||
65 0 0
|
65 0 0
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# MCOL-4666 Empty set when using BIT OR and BIT AND functions in WHERE
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a DECIMAL(18,2));
|
||||||
|
INSERT INTO t1 VALUES (3.4);
|
||||||
|
SELECT a, a|4, a&4 FROM t1;
|
||||||
|
a a|4 a&4
|
||||||
|
3.40 7 0
|
||||||
|
SELECT * FROM t1 WHERE (a|4) <> a;
|
||||||
|
a
|
||||||
|
3.40
|
||||||
|
SELECT * FROM t1 WHERE (a&4) <> a;
|
||||||
|
a
|
||||||
|
3.40
|
||||||
|
DROP TABLE t1;
|
||||||
DROP DATABASE func_bit;
|
DROP DATABASE func_bit;
|
||||||
USE test;
|
USE test;
|
||||||
|
14
mtr/basic/r/func_bit_mcs.result
Normal file
14
mtr/basic/r/func_bit_mcs.result
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
SET default_storage_engine=ColumnStore;
|
||||||
|
DROP DATABASE IF EXISTS func_bit_mcs;
|
||||||
|
CREATE DATABASE func_bit_mcs;
|
||||||
|
USE func_bit_mcs;
|
||||||
|
#
|
||||||
|
# MCOL-4666 Empty set when using BIT OR and BIT AND functions in WHERE
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a BLOB);
|
||||||
|
INSERT INTO t1 VALUES ('1');
|
||||||
|
SELECT a|1 FROM t1;
|
||||||
|
ERROR HY000: Internal error: Illegal parameter data type blob for operation bitor
|
||||||
|
DROP TABLE t1;
|
||||||
|
DROP DATABASE func_bit_mcs;
|
||||||
|
USE test;
|
@ -131,6 +131,19 @@ SELECT a, 1<<a,1>>a FROM t1;
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MCOL-4666 Empty set when using BIT OR and BIT AND functions in WHERE
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a DECIMAL(18,2));
|
||||||
|
INSERT INTO t1 VALUES (3.4);
|
||||||
|
SELECT a, a|4, a&4 FROM t1;
|
||||||
|
SELECT * FROM t1 WHERE (a|4) <> a;
|
||||||
|
SELECT * FROM t1 WHERE (a&4) <> a;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Clean up
|
# Clean up
|
||||||
#
|
#
|
||||||
|
30
mtr/basic/t/func_bit_mcs.test
Normal file
30
mtr/basic/t/func_bit_mcs.test
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
--source ../include/have_columnstore.inc
|
||||||
|
|
||||||
|
SET default_storage_engine=ColumnStore;
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
DROP DATABASE IF EXISTS func_bit_mcs;
|
||||||
|
--enable_warnings
|
||||||
|
CREATE DATABASE func_bit_mcs;
|
||||||
|
USE func_bit_mcs;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MCOL-4666 Empty set when using BIT OR and BIT AND functions in WHERE
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a BLOB);
|
||||||
|
INSERT INTO t1 VALUES ('1');
|
||||||
|
--error ER_INTERNAL_ERROR
|
||||||
|
SELECT a|1 FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Clean up
|
||||||
|
#
|
||||||
|
|
||||||
|
DROP DATABASE func_bit_mcs;
|
||||||
|
USE test;
|
||||||
|
|
@ -50,15 +50,6 @@ namespace
|
|||||||
using namespace funcexp;
|
using namespace funcexp;
|
||||||
|
|
||||||
|
|
||||||
void bitWiseExceptionHandler(const std::string& funcName,
|
|
||||||
const CalpontSystemCatalog::ColType& colType)
|
|
||||||
{
|
|
||||||
std::ostringstream oss;
|
|
||||||
oss << funcName << ": datatype of " << execplan::colDataTypeToString(colType.colDataType);
|
|
||||||
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool validateBitOperandTypeOrError(execplan::FunctionColumn &col,
|
bool validateBitOperandTypeOrError(execplan::FunctionColumn &col,
|
||||||
const Func & func,
|
const Func & func,
|
||||||
uint argno)
|
uint argno)
|
||||||
@ -66,7 +57,7 @@ bool validateBitOperandTypeOrError(execplan::FunctionColumn &col,
|
|||||||
auto & type = col.functionParms()[argno]->data()->resultType();
|
auto & type = col.functionParms()[argno]->data()->resultType();
|
||||||
if (type.canReturnXInt64())
|
if (type.canReturnXInt64())
|
||||||
return false;
|
return false;
|
||||||
bitWiseExceptionHandler(func.funcName(), type);
|
func.raiseIllegalParameterDataTypeError(type);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,8 +262,6 @@ void FuncExp::evaluate(rowgroup::Row& row, std::vector<execplan::SRCP>& expressi
|
|||||||
{
|
{
|
||||||
isNull = false;
|
isNull = false;
|
||||||
|
|
||||||
expression[i]->fixIfNeeded();
|
|
||||||
|
|
||||||
switch (expression[i]->resultType().colDataType)
|
switch (expression[i]->resultType().colDataType)
|
||||||
{
|
{
|
||||||
case CalpontSystemCatalog::DATE:
|
case CalpontSystemCatalog::DATE:
|
||||||
|
@ -84,6 +84,16 @@ public:
|
|||||||
fTimeZone = timeZone;
|
fTimeZone = timeZone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void raiseIllegalParameterDataTypeError(const execplan::CalpontSystemCatalog::ColType& colType) const
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "Illegal parameter data type "
|
||||||
|
<< execplan::colDataTypeToString(colType.colDataType)
|
||||||
|
<< " for operation "
|
||||||
|
<< funcName();
|
||||||
|
throw logging::IDBExcept(oss.str(), logging::ERR_DATATYPE_NOT_SUPPORT);
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool fix(execplan::FunctionColumn &col) const
|
virtual bool fix(execplan::FunctionColumn &col) const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
Reference in New Issue
Block a user