/* Copyright (C) 2014 InfiniDB, Inc. Copyright (C) 2020 MariaDB Corporation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // $Id: functor_bool.h 3495 2013-01-21 14:09:51Z rdempsey $ /** @file */ #ifndef FUNCTOR_BOOL_H #define FUNCTOR_BOOL_H #include "functor.h" namespace funcexp { /** @brief Func_Bool class * For function that returns a boolean result. * Must implement getBoolVal() * Implement any other methods that behave differently from the default. */ class Func_Bool : public Func { public: Func_Bool() {} Func_Bool(const std::string& funcName) : Func(funcName) {} virtual ~Func_Bool() {} /* virtual bool getBoolVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull, execplan::CalpontSystemCatalog::ColType& op_ct) = 0; */ int64_t getIntVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull, execplan::CalpontSystemCatalog::ColType& op_ct) { return (getBoolVal(row, fp, isNull, op_ct) ? 1 : 0); } double getDoubleVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull, execplan::CalpontSystemCatalog::ColType& op_ct) { return (getBoolVal(row, fp, isNull, op_ct) ? 1.0 : 0.0); } long double getLongDoubleVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull, execplan::CalpontSystemCatalog::ColType& op_ct) { return (getBoolVal(row, fp, isNull, op_ct) ? 1.0 : 0.0); } std::string getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull, execplan::CalpontSystemCatalog::ColType& op_ct) { return (getBoolVal(row, fp, isNull, op_ct) ? "1" : "0"); } execplan::IDB_Decimal getDecimalVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull, execplan::CalpontSystemCatalog::ColType& op_ct) { return execplan::IDB_Decimal(getIntVal(row, fp, isNull, op_ct), 0, 0); } int32_t getDateIntVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull, execplan::CalpontSystemCatalog::ColType& op_ct) { isNull = true; return 0; } int64_t getDatetimeIntVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull, execplan::CalpontSystemCatalog::ColType& op_ct) { isNull = true; return 0; } int64_t getTimestampIntVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull, execplan::CalpontSystemCatalog::ColType& op_ct) { isNull = true; return 0; } int64_t getTimeIntVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull, execplan::CalpontSystemCatalog::ColType& op_ct) { isNull = true; return 0; } }; /** @brief Func_between class */ class Func_between : public Func_Bool { public: Func_between() : Func_Bool("between") {} virtual ~Func_between() {} execplan::CalpontSystemCatalog::ColType operationType(FunctionParm& fp, execplan::CalpontSystemCatalog::ColType& resultType); bool getBoolVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull, execplan::CalpontSystemCatalog::ColType& op_ct); }; /** @brief Func_notbetween class */ class Func_notbetween : public Func_Bool { public: Func_notbetween() : Func_Bool("notbetween") {} virtual ~Func_notbetween() {} execplan::CalpontSystemCatalog::ColType operationType(FunctionParm& fp, execplan::CalpontSystemCatalog::ColType& resultType); bool getBoolVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull, execplan::CalpontSystemCatalog::ColType& op_ct); }; /** @brief Func_in class */ class Func_in : public Func_Bool { public: Func_in() : Func_Bool("in") {} virtual ~Func_in() {} execplan::CalpontSystemCatalog::ColType operationType(FunctionParm& fp, execplan::CalpontSystemCatalog::ColType& resultType); bool getBoolVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull, execplan::CalpontSystemCatalog::ColType& op_ct); }; /** @brief Func_notin class */ class Func_notin : public Func_Bool { public: Func_notin() : Func_Bool("notin") {} virtual ~Func_notin() {} execplan::CalpontSystemCatalog::ColType operationType(FunctionParm& fp, execplan::CalpontSystemCatalog::ColType& resultType); bool getBoolVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull, execplan::CalpontSystemCatalog::ColType& op_ct); }; /** @brief Func_regexp class */ class Func_regexp : public Func_Bool { public: Func_regexp() : Func_Bool("regexp") {} virtual ~Func_regexp() {} execplan::CalpontSystemCatalog::ColType operationType(FunctionParm& fp, execplan::CalpontSystemCatalog::ColType& resultType); bool getBoolVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull, execplan::CalpontSystemCatalog::ColType& op_ct); }; /** @brief Func_isnull class */ class Func_isnull : public Func_Bool { public: /* * Constructor. Pass the function name to the base constructor. */ Func_isnull(): fIsNotNull(false) {} Func_isnull(bool isnotnull) : fIsNotNull(isnotnull) {} /* * Destructor. isnull does not need to do anything here to clean up. */ virtual ~Func_isnull() {} /** * Decide on the function's operation type */ execplan::CalpontSystemCatalog::ColType operationType(FunctionParm& fp, execplan::CalpontSystemCatalog::ColType& resultType); bool getBoolVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull, execplan::CalpontSystemCatalog::ColType& op_ct); private: bool fIsNotNull; }; /** @brief Func_Truth class */ class Func_Truth : public Func_Bool { public: Func_Truth(const std::string& funcName, bool a_value, bool a_affirmative) : Func_Bool(funcName), value(a_value), affirmative(a_affirmative) {} virtual ~Func_Truth() {} execplan::CalpontSystemCatalog::ColType operationType(FunctionParm& fp, execplan::CalpontSystemCatalog::ColType& resultType) { assert (fp.size() == 1); return fp[0]->data()->resultType(); } bool getBoolVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull, execplan::CalpontSystemCatalog::ColType& op_ct) { bool val = fp[0]->data()->getBoolVal(row, isNull); /* NULL val IS {TRUE, FALSE} --> FALSE NULL val IS NOT {TRUE, FALSE} --> TRUE {TRUE, FALSE} val IS {TRUE, FALSE} value --> val == value {TRUE, FALSE} val IS NOT {TRUE, FALSE} value --> val != value These cases can be reduced to the following bitwise operation. */ bool ret = (isNull & (!affirmative)) | ((!isNull) & (affirmative ^ (value ^ val))); isNull = false; return ret; } private: const bool value, affirmative; }; /** @brief Func_IsTrue class */ class Func_IsTrue : public Func_Truth { public: Func_IsTrue() : Func_Truth("istrue", true, true) {} ~Func_IsTrue() {} }; /** @brief Func_IsNotTrue class */ class Func_IsNotTrue : public Func_Truth { public: Func_IsNotTrue() : Func_Truth("isnottrue", true, false) {} ~Func_IsNotTrue() {} }; /** @brief Func_IsFalse class */ class Func_IsFalse : public Func_Truth { public: Func_IsFalse() : Func_Truth("isfalse", false, true) {} ~Func_IsFalse() {} }; /** @brief Func_IsNotFalse class */ class Func_IsNotFalse : public Func_Truth { public: Func_IsNotFalse() : Func_Truth("isnotfalse", false, false) {} ~Func_IsNotFalse() {} }; } #endif