diff --git a/datatypes/CMakeLists.txt b/datatypes/CMakeLists.txt index 3526d61842..b73ce43a71 100644 --- a/datatypes/CMakeLists.txt +++ b/datatypes/CMakeLists.txt @@ -2,7 +2,8 @@ include_directories( ${ENGINE_COMMON_INCLUDES} ) set(datatypes_LIB_SRCS mcs_int128.cpp - mcs_decimal.cpp) + mcs_decimal.cpp + mcs_systemcatalog.cpp) add_library(datatypes SHARED ${datatypes_LIB_SRCS}) add_dependencies(datatypes loggingcpp external_boost) diff --git a/datatypes/mcs_datatype.h b/datatypes/mcs_datatype.h index 8db04d353b..991233bbd0 100644 --- a/datatypes/mcs_datatype.h +++ b/datatypes/mcs_datatype.h @@ -21,7 +21,7 @@ #include #include "exceptclasses.h" #include "conststring.h" -#include "mcs_datatype_basic.h" +#include "mcs_datatypes_limits.h" #include "mcs_numeric_limits.h" #include "mcs_data_condition.h" #include "mcs_decimal.h" diff --git a/datatypes/mcs_datatype_basic.h b/datatypes/mcs_datatype_basic.h index 5108f64467..5a1d37c7c1 100644 --- a/datatypes/mcs_datatype_basic.h +++ b/datatypes/mcs_datatype_basic.h @@ -19,7 +19,9 @@ #pragma once #include + #include "joblisttypes.h" +#include "mcs_systemcatalog.h" /* This file contains simple definitions that can be @@ -28,142 +30,6 @@ namespace datatypes { -class SystemCatalog -{ - public: - /** the set of Calpont column widths - * - */ - enum ColWidth - { - ONE_BIT, - ONE_BYTE, - TWO_BYTE, - THREE_BYTE, - FOUR_BYTE, - FIVE_BYTE, - SIX_BYTE, - SEVEN_BYTE, - EIGHT_BYTE - }; - - /** the set of Calpont column data types - * - */ - enum ColDataType - { - BIT, /*!< BIT type */ - TINYINT, /*!< TINYINT type */ - CHAR, /*!< CHAR type */ - SMALLINT, /*!< SMALLINT type */ - DECIMAL, /*!< DECIMAL type */ - MEDINT, /*!< MEDINT type */ - INT, /*!< INT type */ - FLOAT, /*!< FLOAT type */ - DATE, /*!< DATE type */ - BIGINT, /*!< BIGINT type */ - DOUBLE, /*!< DOUBLE type */ - DATETIME, /*!< DATETIME type */ - VARCHAR, /*!< VARCHAR type */ - VARBINARY, /*!< VARBINARY type */ - CLOB, /*!< CLOB type */ - BLOB, /*!< BLOB type */ - UTINYINT, /*!< Unsigned TINYINT type */ - USMALLINT, /*!< Unsigned SMALLINT type */ - UDECIMAL, /*!< Unsigned DECIMAL type */ - UMEDINT, /*!< Unsigned MEDINT type */ - UINT, /*!< Unsigned INT type */ - UFLOAT, /*!< Unsigned FLOAT type */ - UBIGINT, /*!< Unsigned BIGINT type */ - UDOUBLE, /*!< Unsigned DOUBLE type */ - TEXT, /*!< TEXT type */ - TIME, /*!< TIME type */ - TIMESTAMP, /*!< TIMESTAMP type */ - NUM_OF_COL_DATA_TYPE, /* NEW TYPES ABOVE HERE */ - LONGDOUBLE, /* @bug3241, dev and variance calculation only */ - STRINT, /* @bug3532, string as int for fast comparison */ - UNDEFINED, /*!< Undefined - used in UDAF API */ - }; -}; - -template -struct ColTypeToIntegral -{ - using type = struct - { - }; -}; - -template <> -struct ColTypeToIntegral -{ - using type = int8_t; - constexpr static size_t bitWidth = 8; -}; - -template <> -struct ColTypeToIntegral -{ - using type = uint8_t; - constexpr static size_t bitWidth = 8; -}; - -template <> -struct ColTypeToIntegral -{ - using type = int16_t; - constexpr static size_t bitWidth = 16; -}; - -template <> -struct ColTypeToIntegral -{ - using type = uint16_t; - constexpr static size_t bitWidth = 16; -}; - -template <> -struct ColTypeToIntegral -{ - using type = int32_t; - constexpr static size_t bitWidth = 32; -}; - -template <> -struct ColTypeToIntegral -{ - using type = uint32_t; - constexpr static size_t bitWidth = 32; -}; - -template <> -struct ColTypeToIntegral -{ - using type = int32_t; - constexpr static size_t bitWidth = 32; -}; - -template <> -struct ColTypeToIntegral -{ - using type = uint32_t; - constexpr static size_t bitWidth = 32; -}; - -template <> -struct ColTypeToIntegral -{ - using type = int64_t; - constexpr static size_t bitWidth = 64; -}; - -template <> -struct ColTypeToIntegral -{ - using type = uint64_t; - constexpr static size_t bitWidth = 64; -}; - template struct ranges_limits { diff --git a/datatypes/mcs_datatypes_limits.h b/datatypes/mcs_datatypes_limits.h new file mode 100644 index 0000000000..ff955ba20d --- /dev/null +++ b/datatypes/mcs_datatypes_limits.h @@ -0,0 +1,208 @@ +/* + Copyright (C) 2024 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. +*/ +#pragma once + +#include + +#include "joblisttypes.h" +#include "mcs_systemcatalog.h" + +/* + This file contains simple definitions that can be + needed in multiple mcs_TYPE.h files. +*/ + +namespace datatypes +{ +template +struct ranges_limits +{ + using T = ColTypeToIntegral::type; + static constexpr T min() + { + if constexpr (std::is_signed_v) + return std::numeric_limits::min() + 2; + else + return std::numeric_limits::min(); + } + static constexpr T max() + { + if constexpr (std::is_signed_v) + return std::numeric_limits::max(); + else + return std::numeric_limits::max() - 2; + } +}; + +template <> +struct ranges_limits +{ + using T = int32_t; + static constexpr T min() + { + return static_cast(-(1ULL << 23)); + } + static constexpr T max() + { + return static_cast((1ULL << 23) - 1); + } +}; + +template <> +struct ranges_limits +{ + using T = int32_t; + static constexpr T min() + { + return static_cast(0); + } + static constexpr T max() + { + return static_cast((1ULL << 24) - 1); + } +}; + +} // namespace datatypes + +namespace +{ +// Signed types +const int64_t MIN_TINYINT __attribute__((unused)) = + datatypes::ranges_limits::min(); // -126; +const int64_t MIN_SMALLINT __attribute__((unused)) = + datatypes::ranges_limits::min(); // -32766; +const int64_t MIN_MEDINT __attribute__((unused)) = + datatypes::ranges_limits::min(); // -8388608; +const int64_t MIN_INT __attribute__((unused)) = + datatypes::ranges_limits::min(); // -2147483646; +const int64_t MIN_BIGINT = + datatypes::ranges_limits::min(); // -9223372036854775806LL; + +const int64_t MAX_TINYINT __attribute__((unused)) = + datatypes::ranges_limits::max(); // 127; +const int64_t MAX_SMALLINT __attribute__((unused)) = + datatypes::ranges_limits::max(); // 32767; +const int64_t MAX_MEDINT __attribute__((unused)) = + datatypes::ranges_limits::max(); // 8388607; +const int64_t MAX_INT __attribute__((unused)) = + datatypes::ranges_limits::max(); // 2147483647; +const int64_t MAX_BIGINT = + datatypes::ranges_limits::max(); // 9223372036854775807 + +// Unsigned types +const uint64_t MIN_UTINYINT __attribute__((unused)) = + datatypes::ranges_limits::min(); +const uint64_t MIN_USMALLINT __attribute__((unused)) = + datatypes::ranges_limits::min(); +const uint64_t MIN_UMEDINT __attribute__((unused)) = + datatypes::ranges_limits::min(); +const uint64_t MIN_UINT __attribute__((unused)) = + datatypes::ranges_limits::min(); +const uint64_t MIN_UBIGINT = datatypes::ranges_limits::min(); + +const uint64_t MAX_UTINYINT __attribute__((unused)) = + datatypes::ranges_limits::max(); // 253; +const uint64_t MAX_USMALLINT __attribute__((unused)) = + datatypes::ranges_limits::max(); // 65533; +const uint64_t MAX_UMEDINT __attribute__((unused)) = + datatypes::ranges_limits::max(); // 16777215 +const uint64_t MAX_UINT __attribute__((unused)) = + datatypes::ranges_limits::max(); // 4294967293 +const uint64_t MAX_UBIGINT = + datatypes::ranges_limits::max(); // 18446744073709551613 + +// Floating point types +const float MIN_FLOAT __attribute__((unused)) = -std::numeric_limits::max(); +const long double MAX_LONGDOUBLE __attribute__((unused)) = + std::numeric_limits::max(); // 1.7976931348623157e+308 +const long double MIN_LONGDOUBLE __attribute__((unused)) = -std::numeric_limits::max(); + +const float MAX_FLOAT __attribute__((unused)) = std::numeric_limits::max(); // 3.402823466385289e+38 +const double MAX_DOUBLE __attribute__((unused)) = + std::numeric_limits::max(); // 1.7976931348623157e+308 +const double MIN_DOUBLE __attribute__((unused)) = -std::numeric_limits::max(); + +const uint64_t AUTOINCR_SATURATED __attribute__((unused)) = std::numeric_limits::max(); +} // namespace + +namespace datatypes +{ +// Convert a positive floating point value to +// a signed or unsigned integer with rounding +// SRC - a floating point data type (float, double, float128_t) +// DST - a signed or unsigned integer data type (int32_t, uint64_t, int128_t, etc) +template +DST positiveXFloatToXIntRound(SRC value, DST limit) +{ + SRC tmp = value + 0.5; + if (tmp >= static_cast(limit)) + return limit; + return static_cast(tmp); +} + +// Convert a negative floating point value to +// a signed integer with rounding +// SRC - a floating point data type (float, double, float128_t) +// DST - a signed integer data type (int32_t, int64_t, int128_t, etc) +template +DST negativeXFloatToXIntRound(SRC value, DST limit) +{ + SRC tmp = value - 0.5; + if (tmp <= static_cast(limit)) + return limit; + return static_cast(tmp); +} + +// Convert a floating point value to ColumnStore int64_t +// Magic values cannot be returned. +template +int64_t xFloatToMCSSInt64Round(SRC value) +{ + if (value > 0) + { + return positiveXFloatToXIntRound(value, MAX_BIGINT); + } + if (value < 0) + { + //@Bug 4632 and 4648: Don't return marker value for NULL, but allow return of marker value for EMPTYROW. + return negativeXFloatToXIntRound(value, joblist::BIGINTEMPTYROW); + } + return 0; +} + +// Convert a floating point value to ColumnStore uint64_t +// Magic values cannot be returned. +template +uint64_t xFloatToMCSUInt64Round(SRC value) +{ + if (value > 0) + { + //@Bug 4632 and 4648: Don't return marker value for NULL, but allow return of marker value for EMPTYROW. + const auto val = positiveXFloatToXIntRound(value, joblist::UBIGINTEMPTYROW); + return val == joblist::UBIGINTNULL ? MAX_UBIGINT : val; + } + if (value < 0) + { + return negativeXFloatToXIntRound(value, MIN_UBIGINT); + } + + return 0; +} + +} // end of namespace datatypes diff --git a/datatypes/mcs_double.h b/datatypes/mcs_double.h index ca05ea757a..b760707dcb 100644 --- a/datatypes/mcs_double.h +++ b/datatypes/mcs_double.h @@ -18,7 +18,7 @@ */ #pragma once -#include "mcs_datatype_basic.h" +#include "mcs_datatypes_limits.h" namespace datatypes { @@ -53,4 +53,3 @@ class TDouble }; } // end of namespace datatypes - diff --git a/datatypes/mcs_int128.h b/datatypes/mcs_int128.h index cd4bc011c5..076836d548 100644 --- a/datatypes/mcs_int128.h +++ b/datatypes/mcs_int128.h @@ -24,7 +24,7 @@ #include #include -#include "mcs_datatype_basic.h" +#include "mcs_datatypes_limits.h" #include "mcs_float128.h" // Inline asm has three argument lists: output, input and clobber list diff --git a/datatypes/mcs_int64.h b/datatypes/mcs_int64.h index 7b2447cdec..4104582f28 100644 --- a/datatypes/mcs_int64.h +++ b/datatypes/mcs_int64.h @@ -20,7 +20,7 @@ #include #include "exceptclasses.h" -#include "mcs_datatype_basic.h" +#include "mcs_datatypes_limits.h" namespace datatypes { diff --git a/datatypes/mcs_longdouble.h b/datatypes/mcs_longdouble.h index f0b68d8352..c1131b012a 100644 --- a/datatypes/mcs_longdouble.h +++ b/datatypes/mcs_longdouble.h @@ -18,7 +18,7 @@ */ #pragma once -#include "mcs_datatype_basic.h" +#include "mcs_datatypes_limits.h" namespace datatypes { @@ -53,4 +53,3 @@ class TLongDouble }; } // end of namespace datatypes - diff --git a/datatypes/mcs_systemcatalog.cpp b/datatypes/mcs_systemcatalog.cpp new file mode 100644 index 0000000000..69b69caecd --- /dev/null +++ b/datatypes/mcs_systemcatalog.cpp @@ -0,0 +1,61 @@ +/* + Copyright (C) 2024 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. +*/ +#include "mcs_systemcatalog.h" + +namespace datatypes +{ +std::ostream& operator<<(std::ostream& os, SystemCatalog::ColDataType type) +{ + switch (type) + { + case SystemCatalog::BIT: os << "BIT"; break; + case SystemCatalog::TINYINT: os << "TINYINT"; break; + case SystemCatalog::CHAR: os << "CHAR"; break; + case SystemCatalog::SMALLINT: os << "SMALLINT"; break; + case SystemCatalog::DECIMAL: os << "DECIMAL"; break; + case SystemCatalog::MEDINT: os << "MEDINT"; break; + case SystemCatalog::INT: os << "INT"; break; + case SystemCatalog::FLOAT: os << "FLOAT"; break; + case SystemCatalog::DATE: os << "DATE"; break; + case SystemCatalog::BIGINT: os << "BIGINT"; break; + case SystemCatalog::DOUBLE: os << "DOUBLE"; break; + case SystemCatalog::DATETIME: os << "DATETIME"; break; + case SystemCatalog::VARCHAR: os << "VARCHAR"; break; + case SystemCatalog::VARBINARY: os << "VARBINARY"; break; + case SystemCatalog::CLOB: os << "CLOB"; break; + case SystemCatalog::BLOB: os << "BLOB"; break; + case SystemCatalog::UTINYINT: os << "UTINYINT"; break; + case SystemCatalog::USMALLINT: os << "USMALLINT"; break; + case SystemCatalog::UDECIMAL: os << "UDECIMAL"; break; + case SystemCatalog::UMEDINT: os << "UMEDINT"; break; + case SystemCatalog::UINT: os << "UINT"; break; + case SystemCatalog::UFLOAT: os << "UFLOAT"; break; + case SystemCatalog::UBIGINT: os << "UBIGINT"; break; + case SystemCatalog::UDOUBLE: os << "UDOUBLE"; break; + case SystemCatalog::TEXT: os << "TEXT"; break; + case SystemCatalog::TIME: os << "TIME"; break; + case SystemCatalog::TIMESTAMP: os << "TIMESTAMP"; break; + case SystemCatalog::LONGDOUBLE: os << "LONGDOUBLE"; break; + case SystemCatalog::STRINT: os << "STRINT"; break; + case SystemCatalog::UNDEFINED: os << "UNDEFINED"; break; + default: os << "UNKNOWN TYPE"; // Safety net for unexpected values + } + return os; +} +} // namespace datatypes \ No newline at end of file diff --git a/datatypes/mcs_systemcatalog.h b/datatypes/mcs_systemcatalog.h new file mode 100644 index 0000000000..9bbeab458e --- /dev/null +++ b/datatypes/mcs_systemcatalog.h @@ -0,0 +1,168 @@ +/* + Copyright (C) 2024 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. +*/ +#pragma once + +/* + This file contains simple definitions that can be + needed in multiple mcs_TYPE.h files. +*/ + +#include +#include + +namespace datatypes +{ +class SystemCatalog +{ + public: + /** the set of Calpont column widths + * + */ + enum ColWidth + { + ONE_BIT, + ONE_BYTE, + TWO_BYTE, + THREE_BYTE, + FOUR_BYTE, + FIVE_BYTE, + SIX_BYTE, + SEVEN_BYTE, + EIGHT_BYTE + }; + + /** the set of Calpont column data types + * + */ + enum ColDataType + { + BIT, /*!< BIT type */ + TINYINT, /*!< TINYINT type */ + CHAR, /*!< CHAR type */ + SMALLINT, /*!< SMALLINT type */ + DECIMAL, /*!< DECIMAL type */ + MEDINT, /*!< MEDINT type */ + INT, /*!< INT type */ + FLOAT, /*!< FLOAT type */ + DATE, /*!< DATE type */ + BIGINT, /*!< BIGINT type */ + DOUBLE, /*!< DOUBLE type */ + DATETIME, /*!< DATETIME type */ + VARCHAR, /*!< VARCHAR type */ + VARBINARY, /*!< VARBINARY type */ + CLOB, /*!< CLOB type */ + BLOB, /*!< BLOB type */ + UTINYINT, /*!< Unsigned TINYINT type */ + USMALLINT, /*!< Unsigned SMALLINT type */ + UDECIMAL, /*!< Unsigned DECIMAL type */ + UMEDINT, /*!< Unsigned MEDINT type */ + UINT, /*!< Unsigned INT type */ + UFLOAT, /*!< Unsigned FLOAT type */ + UBIGINT, /*!< Unsigned BIGINT type */ + UDOUBLE, /*!< Unsigned DOUBLE type */ + TEXT, /*!< TEXT type */ + TIME, /*!< TIME type */ + TIMESTAMP, /*!< TIMESTAMP type */ + NUM_OF_COL_DATA_TYPE, /* NEW TYPES ABOVE HERE */ + LONGDOUBLE, /* @bug3241, dev and variance calculation only */ + STRINT, /* @bug3532, string as int for fast comparison */ + UNDEFINED, /*!< Undefined - used in UDAF API */ + }; +}; + +std::ostream& operator<<(std::ostream& os, SystemCatalog::ColDataType type); + +template +struct ColTypeToIntegral +{ + using type = struct + { + }; +}; + +template <> +struct ColTypeToIntegral +{ + using type = int8_t; + constexpr static std::size_t bitWidth = 8; +}; + +template <> +struct ColTypeToIntegral +{ + using type = uint8_t; + constexpr static std::size_t bitWidth = 8; +}; + +template <> +struct ColTypeToIntegral +{ + using type = int16_t; + constexpr static std::size_t bitWidth = 16; +}; + +template <> +struct ColTypeToIntegral +{ + using type = uint16_t; + constexpr static std::size_t bitWidth = 16; +}; + +template <> +struct ColTypeToIntegral +{ + using type = int32_t; + constexpr static std::size_t bitWidth = 32; +}; + +template <> +struct ColTypeToIntegral +{ + using type = uint32_t; + constexpr static std::size_t bitWidth = 32; +}; + +template <> +struct ColTypeToIntegral +{ + using type = int32_t; + constexpr static std::size_t bitWidth = 32; +}; + +template <> +struct ColTypeToIntegral +{ + using type = uint32_t; + constexpr static std::size_t bitWidth = 32; +}; + +template <> +struct ColTypeToIntegral +{ + using type = int64_t; + constexpr static std::size_t bitWidth = 64; +}; + +template <> +struct ColTypeToIntegral +{ + using type = uint64_t; + constexpr static std::size_t bitWidth = 64; +}; +} // namespace datatypes diff --git a/dbcon/execplan/CMakeLists.txt b/dbcon/execplan/CMakeLists.txt index e13609f91f..b5acdfca42 100755 --- a/dbcon/execplan/CMakeLists.txt +++ b/dbcon/execplan/CMakeLists.txt @@ -28,6 +28,7 @@ set(execplan_LIB_SRCS objectidmanager.cpp objectreader.cpp operator.cpp + optype.cpp oracleexecutionplan.cpp outerjoinonfilter.cpp predicateoperator.cpp diff --git a/dbcon/execplan/arithmeticcolumn.cpp b/dbcon/execplan/arithmeticcolumn.cpp index d4b25fafb6..2c6f41eaff 100644 --- a/dbcon/execplan/arithmeticcolumn.cpp +++ b/dbcon/execplan/arithmeticcolumn.cpp @@ -30,6 +30,7 @@ using namespace std; #include "constantcolumn.h" #include "simplecolumn.h" #include "operator.h" +#include "optype.h" #include "bytestream.h" using namespace messageqcpp; @@ -52,6 +53,50 @@ void walkfn(const execplan::ParseTree* n, ostream& output) output << *(n->data()) << endl; } +void toExpressionStringWalker(const execplan::ParseTree* node, + void (*fn)(const execplan::ParseTree* n, std::ostream& output), ostream& output) +{ + execplan::BFSStack stack; + stack.emplace_back(const_cast(node)); + + while (!stack.empty()) + { + auto [node, dir] = stack.front(); + if (dir == execplan::GoTo::Left) + { + stack.front().direction = execplan::GoTo::Right; + if (node->left() != nullptr) + stack.emplace_back(node->left()); + } + else if (dir == execplan::GoTo::Right) + { + stack.front().direction = execplan::GoTo::Up; + if (node->right() != nullptr) + stack.emplace_back(node->right()); + } + else + { + execplan::ParseTree* temp = const_cast(node); + fn(temp, output); + stack.pop_front(); + } + } +} + +void toExpressionStringPrinter(const execplan::ParseTree* n, ostream& output) +{ + // call a method of ParseTree::fData that is polymorphic and add a suffix in the end. + auto* op = dynamic_cast(n->data()); + if (op) + { + output << op->op() << "|"; + } + else + { + output << n->data()->toExpressionString() << " "; + } +} + } // namespace namespace execplan @@ -246,7 +291,6 @@ void ArithmeticColumn::buildTree() const string ArithmeticColumn::nextToken(string::size_type& pos, char end) const { string token; - // string fData = ReturnedColumn::data(); // increment num when get '(' and decrement when get ')' // to find the mathing ')' when num = 0 @@ -469,11 +513,17 @@ bool ArithmeticColumn::singleTable(CalpontSystemCatalog::TableAliasName& tan) std::string ArithmeticColumn::toExpressionString() const { - // WIP this should return the expression string in prefix form. - stringstream ss; - ss << "ArithmeticColumn(" << std::quoted(fData) << ", " << sessionID() << ")"; + stringstream oss; + if (fExpression) + { + fExpression->prefixFormExprWalker(toExpressionStringWalker, toExpressionStringPrinter, oss); + } + else + { + oss << "unknown()"; + } - return ss.str(); + return oss.str(); } } // namespace execplan diff --git a/dbcon/execplan/arithmeticoperator.h b/dbcon/execplan/arithmeticoperator.h index 3b958995ff..5c1729e6ee 100644 --- a/dbcon/execplan/arithmeticoperator.h +++ b/dbcon/execplan/arithmeticoperator.h @@ -31,7 +31,7 @@ #include #include "mcs_data_condition.h" -#include "mcs_datatype_basic.h" +#include "mcs_datatypes_limits.h" #include "mcs_outofrange.h" #include "mcs_int128.h" #include "operator.h" @@ -46,8 +46,6 @@ namespace execplan { class ArithmeticOperator : public Operator { - using cscType = execplan::CalpontSystemCatalog::ColType; - public: ArithmeticOperator(); ArithmeticOperator(const std::string& operatorName); @@ -578,45 +576,6 @@ inline llvm::Value* ArithmeticOperator::compileIntWithConditions_(llvm::IRBuilde return res; } -// template -// inline llvm::Value* ArithmeticOperator::compileIntWithConditions_(llvm::IRBuilder<>& b, llvm::Value* l, -// llvm::Value* r, llvm::Value* isNull, -// llvm::Value* dataConditionError, -// ParseTree* lop, ParseTree* rop) -// { -// auto* intBigerType = llvm::IntegerType::get(b.getContext(), 128); -// auto* intCurrentType = llvm::IntegerType::get(b.getContext(), 64); -// auto* intErrorType = llvm::IntegerType::get(b.getContext(), 32); - -// bool signedLeft = lop->data()->resultType().isSignedInteger(); -// bool signedRight = rop->data()->resultType().isSignedInteger(); - -// auto* lCasted = (signedLeft) ? b.CreateSExt(l, intBigerType, "l_to_int128") -// : b.CreateZExt(l, intBigerType, "l_to_int128"); -// auto* rCasted = (signedRight) ? b.CreateSExt(r, intBigerType, "r_to_int128") -// : b.CreateZExt(r, intBigerType, "r_to_int128"); -// auto* operReturn = compileInt_(b, lCasted, rCasted); - -// auto minValue = datatypes::ranges_limits::min(); -// auto maxValue = datatypes::ranges_limits::max(); -// auto* cmpGTMax = b.CreateICmpSGT(operReturn, llvm::ConstantInt::get(operReturn->getType(), maxValue)); -// auto* cmpLTMin = b.CreateICmpSLT(operReturn, llvm::ConstantInt::get(operReturn->getType(), minValue)); -// auto* cmpOutOfRange = b.CreateOr(cmpGTMax, cmpLTMin); - -// auto* getDataConditionError = b.CreateLoad(intErrorType, dataConditionError); -// // Left shift might be faster here than multiplication but this would add up another one-time constant in -// // DataCondition. -// auto* getErrorCode = b.CreateMul(b.CreateZExt(cmpOutOfRange, intErrorType, "castBoolToInt"), -// b.getInt32(datatypes::DataCondition::X_NUMERIC_VALUE_OUT_OF_RANGE)); -// auto* setOutOfRangeBitInDataCondition = b.CreateOr(getDataConditionError, getErrorCode); -// [[maybe_unused]] auto* storeIsOutOfRange = -// b.CreateStore(setOutOfRangeBitInDataCondition, dataConditionError); - -// auto* res = b.CreateTrunc(operReturn, intCurrentType, "truncatedToSmaller"); - -// return res; -// } - inline llvm::Value* ArithmeticOperator::compileInt_(llvm::IRBuilder<>& b, llvm::Value* l, llvm::Value* r) { switch (fOp) diff --git a/dbcon/execplan/constantcolumn.cpp b/dbcon/execplan/constantcolumn.cpp index 83d73353a9..2edf68a4a2 100644 --- a/dbcon/execplan/constantcolumn.cpp +++ b/dbcon/execplan/constantcolumn.cpp @@ -234,6 +234,13 @@ std::string ConstantColumn::toCppCode(IncludeSet& includes) const return ss.str(); } +std::string ConstantColumn::toExpressionString() const +{ + ostringstream oss; + oss << "Const(" << fResultType.colDataType << ")"; + return oss.str(); +} + const string ConstantColumn::data() const { return fData; @@ -354,8 +361,6 @@ const utils::NullString& RollupMarkColumn::getStrVal(rowgroup::Row& row, bool& i return ns; } - - bool ConstantColumn::operator==(const ConstantColumn& t) const { const ReturnedColumn *rc1, *rc2; diff --git a/dbcon/execplan/constantcolumn.h b/dbcon/execplan/constantcolumn.h index df0516eefe..35b540d880 100644 --- a/dbcon/execplan/constantcolumn.h +++ b/dbcon/execplan/constantcolumn.h @@ -158,6 +158,8 @@ class ConstantColumn : public ReturnedColumn virtual const std::string toString() const override; virtual std::string toCppCode(IncludeSet& includes) const override; + virtual std::string toExpressionString() const override; + /** return a copy of this pointer * * deep copy of this pointer and return the copy diff --git a/dbcon/execplan/objectreader.cpp b/dbcon/execplan/objectreader.cpp index 152c751d14..3e7037364c 100644 --- a/dbcon/execplan/objectreader.cpp +++ b/dbcon/execplan/objectreader.cpp @@ -207,15 +207,15 @@ void ObjectReader::writeParseTree(const ParseTree* tree, messageqcpp::ByteStream stack.pop_back(); continue; } - if (dir == ParseTree::GoTo::Left) + if (dir == execplan::GoTo::Left) { b << (id_t)PARSETREE; - stack.back().direction = ParseTree::GoTo::Right; + stack.back().direction = execplan::GoTo::Right; stack.emplace_back(node->left()); } - else if (dir == ParseTree::GoTo::Right) + else if (dir == execplan::GoTo::Right) { - stack.back().direction = ParseTree::GoTo::Up; + stack.back().direction = execplan::GoTo::Up; stack.emplace_back(node->right()); } else @@ -246,7 +246,7 @@ ParseTree* ObjectReader::createParseTree(messageqcpp::ByteStream& b) while (!stack.empty()) { auto [node, dir] = stack.back(); - if (dir == ParseTree::GoTo::Left) + if (dir == execplan::GoTo::Left) { id = ZERO; ParseTree* cur = NULL; @@ -255,18 +255,18 @@ ParseTree* ObjectReader::createParseTree(messageqcpp::ByteStream& b) if (id == NULL_CLASS) { stack.back().node->left(cur); - stack.back().direction = ParseTree::GoTo::Right; + stack.back().direction = execplan::GoTo::Right; continue; } if (id != PARSETREE) throw UnserializeException("Not a ParseTree"); cur = new ParseTree(); - stack.back().direction = ParseTree::GoTo::Right; + stack.back().direction = execplan::GoTo::Right; stack.back().node->left(cur); stack.emplace_back(node->left()); } - else if (dir == ParseTree::GoTo::Right) + else if (dir == execplan::GoTo::Right) { id = ZERO; ParseTree* cur = NULL; @@ -275,14 +275,14 @@ ParseTree* ObjectReader::createParseTree(messageqcpp::ByteStream& b) if (id == NULL_CLASS) { stack.back().node->right(cur); - stack.back().direction = ParseTree::GoTo::Up; + stack.back().direction = execplan::GoTo::Up; continue; } if (id != PARSETREE) throw UnserializeException("Not a ParseTree"); cur = new ParseTree(); - stack.back().direction = ParseTree::GoTo::Up; + stack.back().direction = execplan::GoTo::Up; stack.back().node->right(cur); stack.emplace_back(node->right()); } diff --git a/dbcon/execplan/optype.cpp b/dbcon/execplan/optype.cpp new file mode 100644 index 0000000000..7d581df27f --- /dev/null +++ b/dbcon/execplan/optype.cpp @@ -0,0 +1,55 @@ +/* Copyright (C) 2016-2024 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. */ + +#include + +#include "optype.h" + +namespace execplan +{ +std::ostream& operator<<(std::ostream& os, execplan::OpType type) +{ + switch (type) + { + case execplan::OP_ADD: os << "+"; break; + case execplan::OP_SUB: os << "-"; break; + case execplan::OP_MUL: os << "*"; break; + case execplan::OP_DIV: os << "/"; break; + case execplan::OP_EQ: os << "=="; break; + case execplan::OP_NE: os << "!="; break; + case execplan::OP_GT: os << ">"; break; + case execplan::OP_GE: os << ">="; break; + case execplan::OP_LT: os << "<"; break; + case execplan::OP_LE: os << "<="; break; + case execplan::OP_LIKE: os << "LIKE"; break; + case execplan::OP_NOTLIKE: os << "NOT LIKE"; break; + case execplan::OP_AND: os << "AND"; break; + case execplan::OP_OR: os << "OR"; break; + case execplan::OP_ISNULL: os << "IS NULL"; break; + case execplan::OP_ISNOTNULL: os << "IS NOT NULL"; break; + case execplan::OP_BETWEEN: os << "BETWEEN"; break; + case execplan::OP_NOTBETWEEN: os << "NOT BETWEEN"; break; + case execplan::OP_IN: os << "IN"; break; + case execplan::OP_NOTIN: os << "NOT IN"; break; + case execplan::OP_XOR: os << "XOR"; break; + case execplan::OP_UNKNOWN: os << "UNKNOWN"; break; + default: os << "UNDEFINED"; // Catch-all for safety + } + return os; +} + +} // namespace execplan diff --git a/dbcon/execplan/optype.h b/dbcon/execplan/optype.h index f605eb104b..9c53de909d 100644 --- a/dbcon/execplan/optype.h +++ b/dbcon/execplan/optype.h @@ -17,6 +17,8 @@ #pragma once +#include + namespace execplan { enum OpType @@ -45,4 +47,5 @@ enum OpType OP_UNKNOWN, }; +std::ostream& operator<<(std::ostream& os, execplan::OpType type); } // namespace execplan diff --git a/dbcon/execplan/parsetree.h b/dbcon/execplan/parsetree.h index 3365381db3..17c3433d82 100644 --- a/dbcon/execplan/parsetree.h +++ b/dbcon/execplan/parsetree.h @@ -25,16 +25,19 @@ #pragma once -#include -#include -#include "treenode.h" -#include "operator.h" -#include "mcs_decimal.h" #include + +#include +#include +#include #include #include #include +#include "treenode.h" +#include "operator.h" +#include "mcs_decimal.h" + namespace rowgroup { class Row; @@ -42,6 +45,13 @@ class Row; namespace execplan { +enum class GoTo +{ + Left, + Right, + Up +}; + // class Operator; /** * @brief A template class template to represent an expression tree @@ -147,6 +157,9 @@ class ParseTree */ inline void walk(void (*fn)(const ParseTree* n, std::ostream& output), std::ostream& output) const; + template + inline void prefixFormExprWalker(W* walker, F* function, std::ostream& output) const; + /** output the tree * * take user argument to walk and output the tree @@ -227,13 +240,6 @@ class ParseTree inline void setDerivedTable(); - enum class GoTo - { - Left, - Right, - Up - }; - struct StackFrame { ParseTree* node; @@ -422,6 +428,7 @@ inline ParseTree::ParseTree(const ParseTree& rhs) } using DFSStack = std::vector; +using BFSStack = std::deque; inline ParseTree::~ParseTree() { @@ -562,6 +569,12 @@ inline void ParseTree::walk(void (*fn)(const ParseTree* n, std::ostream& output) } } +template +inline void ParseTree::prefixFormExprWalker(W* walker, F* fn, std::ostream& output) const +{ + walker(this, fn, output); +} + inline void ParseTree::walk(void (*fn)(const ParseTree* n, void* obj), void* obj) const { DFSStack stack; diff --git a/dbcon/execplan/returnedcolumn.cpp b/dbcon/execplan/returnedcolumn.cpp index 5a698829d5..e22f947f01 100644 --- a/dbcon/execplan/returnedcolumn.cpp +++ b/dbcon/execplan/returnedcolumn.cpp @@ -33,14 +33,6 @@ using namespace messageqcpp; namespace execplan { -// Helper -std::string toExpressionString_(const std::string id) -{ - stringstream ss; - ss << "ReturnedColumn(" << std::quoted(id) << ")"; - - return ss.str(); -} /** * Constructors/Destructors @@ -254,12 +246,17 @@ const string ReturnedColumn::toString() const string ReturnedColumn::toCppCode(IncludeSet& includes) const { includes.insert("returnedcolumn.h"); - return toExpressionString_(fData); + + ostringstream oss; + oss << "ReturnedColumn(" << std::quoted(fData) << ")"; + return oss.str(); } std::string ReturnedColumn::toExpressionString() const { - return toExpressionString_(fAlias); + ostringstream oss; + oss << fResultType.colDataType; + return oss.str(); } // All columns that may have simple column added to the list need to implement diff --git a/dbcon/execplan/rewrites.cpp b/dbcon/execplan/rewrites.cpp index 6c1ef8612b..52b949db67 100644 --- a/dbcon/execplan/rewrites.cpp +++ b/dbcon/execplan/rewrites.cpp @@ -112,11 +112,12 @@ bool simpleFiltersCmp(const SimpleFilter* left, const SimpleFilter* right) struct StackFrameWithSet { execplan::ParseTree* node; - ParseTree::GoTo direction; + execplan::GoTo direction; bool orMet; bool andParent; CommonContainer localset; - StackFrameWithSet(execplan::ParseTree* node_, ParseTree::GoTo direction_, bool orMet_ = false, bool andParent_ = false) + StackFrameWithSet(execplan::ParseTree* node_, execplan::GoTo direction_, bool orMet_ = false, + bool andParent_ = false) : node(node_), direction(direction_), orMet(orMet_), andParent(andParent_), localset({{}, {}}) { } @@ -131,7 +132,7 @@ void advanceSetUp(std::vector& stack, CommonContainer& accumu auto sz = stack.size(); if (operatorType(stack.at(sz - 2).node) == OP_OR) { - if (stack.at(sz - 2).direction == ParseTree::GoTo::Right) + if (stack.at(sz - 2).direction == execplan::GoTo::Right) stack[sz - 2].localset = stack.back().localset; else { @@ -145,7 +146,7 @@ void advanceSetUp(std::vector& stack, CommonContainer& accumu } else { - if (stack.at(sz - 2).direction == ParseTree::GoTo::Right) + if (stack.at(sz - 2).direction == execplan::GoTo::Right) stack[sz - 2].localset = stack.back().localset; else { @@ -166,32 +167,32 @@ void collectCommonConjuctions(execplan::ParseTree* root, CommonContainer& accumu } std::vector stack; - stack.emplace_back(root, ParseTree::GoTo::Left); + stack.emplace_back(root, execplan::GoTo::Left); while (!stack.empty()) { auto [node, dir, orMet, andParent, localset] = stack.back(); - if (dir == ParseTree::GoTo::Left) + if (dir == execplan::GoTo::Left) { - stack.back().direction = ParseTree::GoTo::Right; + stack.back().direction = execplan::GoTo::Right; if (node->left() != nullptr) { if (operatorType(node) == OP_OR) - stack.emplace_back(node->left(), ParseTree::GoTo::Left, true); + stack.emplace_back(node->left(), execplan::GoTo::Left, true); else - stack.emplace_back(node->left(), ParseTree::GoTo::Left, orMet, operatorType(node) == OP_AND); + stack.emplace_back(node->left(), execplan::GoTo::Left, orMet, operatorType(node) == OP_AND); } continue; } - else if (dir == ParseTree::GoTo::Right) + else if (dir == execplan::GoTo::Right) { - stack.back().direction = ParseTree::GoTo::Up; + stack.back().direction = execplan::GoTo::Up; if (node->right() != nullptr) { if (operatorType(node) == OP_OR) - stack.emplace_back(node->right(), ParseTree::GoTo::Left, true); + stack.emplace_back(node->right(), execplan::GoTo::Left, true); else - stack.emplace_back(node->right(), ParseTree::GoTo::Left, orMet, operatorType(node) == OP_AND); + stack.emplace_back(node->right(), execplan::GoTo::Left, orMet, operatorType(node) == OP_AND); } continue; } @@ -253,10 +254,10 @@ execplan::ParseTree* appendToRoot(execplan::ParseTree* tree, const Common& commo struct StackFrame { execplan::ParseTree** node; - ParseTree::GoTo direction; + execplan::GoTo direction; ChildType containsLeft; ChildType containsRight; - StackFrame(execplan::ParseTree** node_, ParseTree::GoTo direction_) + StackFrame(execplan::ParseTree** node_, execplan::GoTo direction_) : node(node_), direction(direction_), containsLeft(ChildType::Leave), containsRight(ChildType::Leave) { } @@ -283,24 +284,24 @@ void deleteOneNode(execplan::ParseTree** node) } // this utility function adds one stack frame to a stack for dfs traversal -void addStackFrame(DFSStack& stack, ParseTree::GoTo direction, execplan::ParseTree* node) +void addStackFrame(DFSStack& stack, execplan::GoTo direction, execplan::ParseTree* node) { - if (direction == ParseTree::GoTo::Left) + if (direction == execplan::GoTo::Left) { - stack.back().direction = ParseTree::GoTo::Right; + stack.back().direction = execplan::GoTo::Right; if (node->left() != nullptr) { auto left = node->leftRef(); - stack.emplace_back(left, ParseTree::GoTo::Left); + stack.emplace_back(left, execplan::GoTo::Left); } } - else if (direction == ParseTree::GoTo::Right) + else if (direction == execplan::GoTo::Right) { - stack.back().direction = ParseTree::GoTo::Up; + stack.back().direction = execplan::GoTo::Up; if (node->right() != nullptr) { auto right = node->rightRef(); - stack.emplace_back(right, ParseTree::GoTo::Left); + stack.emplace_back(right, execplan::GoTo::Left); } } } @@ -310,7 +311,7 @@ void addStackFrame(DFSStack& stack, ParseTree::GoTo direction, execplan::ParseTr // specified in the stack frame void replaceContainsTypeFlag(StackFrame& stackframe, ChildType containsflag) { - if (stackframe.direction == ParseTree::GoTo::Right) + if (stackframe.direction == execplan::GoTo::Right) stackframe.containsLeft = containsflag; else stackframe.containsRight = containsflag; @@ -362,11 +363,11 @@ void removeFromTreeIterative(execplan::ParseTree** root, const CommonContainer& return; DFSStack stack; - stack.emplace_back(root, ParseTree::GoTo::Left); + stack.emplace_back(root, execplan::GoTo::Left); while (!stack.empty()) { auto [node, flag, ltype, rtype] = stack.back(); - if (flag != ParseTree::GoTo::Up) + if (flag != execplan::GoTo::Up) { addStackFrame(stack, flag, *node); continue; @@ -484,17 +485,18 @@ bool NodeSemanticComparator::operator()(execplan::ParseTree* left, execplan::Par return left->data()->data() < right->data()->data(); } - bool checkFiltersLimit(execplan::ParseTree* tree, uint64_t limit) { uint64_t maxLimit = 0; - auto walker = [](const execplan::ParseTree* node, void* maxLimit){ + auto walker = [](const execplan::ParseTree* node, void* maxLimit) + { auto maybe_cf = dynamic_cast(node->data()); - if (maybe_cf != nullptr && (maybe_cf->op()->op() == OpType::OP_OR || maybe_cf->op()->op() == OpType::OP_IN)) - { - *((uint64_t*)maxLimit) = std::max(maybe_cf->filterList().size(), *((uint64_t*)maxLimit)); - } - }; + if (maybe_cf != nullptr && + (maybe_cf->op()->op() == OpType::OP_OR || maybe_cf->op()->op() == OpType::OP_IN)) + { + *((uint64_t*)maxLimit) = std::max(maybe_cf->filterList().size(), *((uint64_t*)maxLimit)); + } + }; tree->walk(walker, &maxLimit); return maxLimit <= limit; } diff --git a/utils/common/nullstring.h b/utils/common/nullstring.h index 313a5bcb97..24c535c9a3 100644 --- a/utils/common/nullstring.h +++ b/utils/common/nullstring.h @@ -26,7 +26,7 @@ #include #include "exceptclasses.h" #include "conststring.h" -#include "mcs_datatype_basic.h" +#include "mcs_datatypes_limits.h" namespace utils { diff --git a/utils/funcexp/funcexpwrapper.cpp b/utils/funcexp/funcexpwrapper.cpp index 42f39ab748..7adae0f22f 100644 --- a/utils/funcexp/funcexpwrapper.cpp +++ b/utils/funcexp/funcexpwrapper.cpp @@ -121,7 +121,7 @@ bool FuncExpWrapper::evaluate(Row* r) { try { - msc_jit::compileExpression(rcs, *r); + msc_jit::compileExpressions(rcs, *r); } catch (const std::logic_error& e) { diff --git a/utils/jit/compilehelper.h b/utils/jit/compilehelper.h index 6acbc97e71..60c0f42bca 100644 --- a/utils/jit/compilehelper.h +++ b/utils/jit/compilehelper.h @@ -3,7 +3,7 @@ #include "llvm/IR/Value.h" #include "llvm/IR/IRBuilder.h" -#include "mcs_datatype_basic.h" +#include "mcs_datatypes_limits.h" namespace msc_jit { diff --git a/utils/jit/compileoperator.cpp b/utils/jit/compileoperator.cpp index a494aeeba8..5a3357368f 100644 --- a/utils/jit/compileoperator.cpp +++ b/utils/jit/compileoperator.cpp @@ -17,6 +17,11 @@ void compileExternalFunction(llvm::Module& module, llvm::IRBuilder<>& b) "dataconvert::DataConvert::timestampValueToInt", module); } +std::string computeFunctionName(const execplan::SRCP& expression) +{ + return expression->toExpressionString(); +} + void compileOperator(llvm::Module& module, const execplan::SRCP& expression, rowgroup::Row& row) { auto columns = expression.get()->simpleColumnList(); @@ -47,11 +52,10 @@ void compileOperator(llvm::Module& module, const execplan::SRCP& expression, row case CalpontSystemCatalog::UFLOAT: returnType = b.getFloatTy(); break; default: throw logic_error("compileOperator: unsupported type"); } - IncludeSet includes; - const auto& expressionName = expression->toCppCode(includes); + const auto& functionName = computeFunctionName(expression); auto* funcType = llvm::FunctionType::get(returnType, {dataType, isNullType, dataConditionErrorType}, false); - auto* func = llvm::Function::Create(funcType, llvm::Function::ExternalLinkage, expressionName, module); + auto* func = llvm::Function::Create(funcType, llvm::Function::ExternalLinkage, functionName, module); func->setDoesNotThrow(); auto* args = func->args().begin(); llvm::Value* dataPtr = args++; @@ -73,11 +77,7 @@ CompiledOperator compileOperator(msc_jit::JIT& jit, const execplan::SRCP& expres jit.compileModule([&](llvm::Module& module) { compileOperator(module, expression, row); }); CompiledOperator compiledOperator{.compiled_module = compiled_module}; - // WIP - IncludeSet includes; - const auto& expressionName = expression->toCppCode(includes); - std::cout << "compileOperator exp name " << expression->alias() << std::endl; - std::cout << "compileOperator toExpressionString " << expressionName << std::endl; + const auto& functionName = computeFunctionName(expression); switch (expression->resultType().colDataType) { @@ -88,7 +88,7 @@ CompiledOperator compileOperator(msc_jit::JIT& jit, const execplan::SRCP& expres case CalpontSystemCatalog::TINYINT: case CalpontSystemCatalog::DATE: compiledOperator.compiled_function_int64 = reinterpret_cast>( - compiled_module.function_name_to_symbol[expressionName]); + compiled_module.function_name_to_symbol[functionName]); break; case CalpontSystemCatalog::UBIGINT: case CalpontSystemCatalog::UINT: @@ -97,17 +97,17 @@ CompiledOperator compileOperator(msc_jit::JIT& jit, const execplan::SRCP& expres case CalpontSystemCatalog::UTINYINT: compiledOperator.compiled_function_uint64 = reinterpret_cast>( - compiled_module.function_name_to_symbol[expressionName]); + compiled_module.function_name_to_symbol[functionName]); break; case CalpontSystemCatalog::DOUBLE: case CalpontSystemCatalog::UDOUBLE: compiledOperator.compiled_function_double = reinterpret_cast>( - compiled_module.function_name_to_symbol[expressionName]); + compiled_module.function_name_to_symbol[functionName]); break; case CalpontSystemCatalog::FLOAT: case CalpontSystemCatalog::UFLOAT: - compiledOperator.compiled_function_float = reinterpret_cast>( - compiled_module.function_name_to_symbol[expressionName]); + compiledOperator.compiled_function_float = + reinterpret_cast>(compiled_module.function_name_to_symbol[functionName]); break; default: throw logic_error("compileOperator: unsupported type"); } diff --git a/utils/jit/expressionjit.h b/utils/jit/expressionjit.h index fd97df9caa..3f1449d8f5 100644 --- a/utils/jit/expressionjit.h +++ b/utils/jit/expressionjit.h @@ -83,7 +83,7 @@ class CompiledColumn : public execplan::ReturnedColumn } }; // TODO: Optimize code structure, maybe it should be implemented using recursion. -static void compileExpression(std::vector& expressions, rowgroup::Row& row) +static void compileExpressions(std::vector& expressions, rowgroup::Row& row) { for (auto it = expressions.rbegin(); it != expressions.rend(); ++it) { @@ -121,7 +121,7 @@ static void compileExpression(std::vector& expressions, rowgroup // { // ParseTree* node = nodeQueue.front(); // nodeQueue.pop(); - // std::cout << "compileExpression node " << std::hex << (uint64_t)(node) << std::dec << std::endl; + // std::cout << "compileExpressions node " << std::hex << (uint64_t)(node) << std::dec << std::endl; // if (!node->isCompilable(row)) // { // if (node->left() && node->right()) diff --git a/utils/jit/jit.cpp b/utils/jit/jit.cpp index 6725cb4d85..f432a6a5f4 100644 --- a/utils/jit/jit.cpp +++ b/utils/jit/jit.cpp @@ -253,6 +253,7 @@ class JITCompiler // TODO: throw a more specific exception throw std::logic_error("Failed to materialize module: " + error_message); } + // WIP constant size? llvm::SmallVector buffer; llvm::raw_svector_ostream ostream(buffer); llvm::legacy::PassManager pass_manager; @@ -262,6 +263,11 @@ class JITCompiler // TODO: throw a more specific exception throw std::logic_error("Failed to create MC pass manager"); } + + // std::cout << "compile " << std::endl; + // module.print(llvm::outs(), nullptr); + // std::cout.flush(); + pass_manager.run(module); std::unique_ptr compiled_memory_buffer = @@ -335,13 +341,12 @@ JIT::CompiledModule JIT::compileModule(std::function compil JIT::CompiledModule JIT::compileModule(std::unique_ptr module) { - std::cout << "JIT::compileModule !!!!!!!!!!1" << std::endl; - module->print(llvm::outs(), nullptr); + // std::cout << "JIT::compileModule !!!!!!!!!!" << std::endl; + // module->print(llvm::outs(), nullptr); runOptimizationPassesOnModule(*module); auto buffer = compiler->compile(*module); - // std::cout << "JIT::compileModule 2" << std::endl; - // module->print(llvm::outs(), nullptr); + llvm::Expected> object_file = llvm::object::ObjectFile::createObjectFile(buffer->getMemBufferRef()); if (!object_file) @@ -359,8 +364,6 @@ JIT::CompiledModule JIT::compileModule(std::unique_ptr module) module_memory_manager->finalizeMemory(nullptr); CompiledModule compiled_module; - // std::cout << "JIT::compileModule 3" << std::endl; - // module->print(llvm::outs(), nullptr); for (const auto& function : *module) { if (function.isDeclaration()) @@ -481,27 +484,18 @@ void JIT::runOptimizationPassesOnModule(llvm::Module& module) const pass_manager_builder.populateModulePassManager(mpm); fpm.doInitialization(); - std::cout << "JIT::runOptimizationPassesOnModule 1" << std::endl; - module.print(llvm::outs(), nullptr); for (auto& function : module) { fpm.run(function); } - std::cout << "JIT::runOptimizationPassesOnModule 2" << std::endl; - module.print(llvm::outs(), nullptr); fpm.doFinalization(); - std::cout << "JIT::runOptimizationPassesOnModule 3" << std::endl; - module.print(llvm::outs(), nullptr); // // WIP the module opt pass removes the function compiled // Module opt passes aggresivelly remove "unreferenced" functions from // a module. // mpm.run(module); - - std::cout << "JIT::runOptimizationPassesOnModule 4" << std::endl; - module.print(llvm::outs(), nullptr); } JIT::~JIT() { diff --git a/utils/jit/jit.h b/utils/jit/jit.h index 71b211c87b..965ad0447b 100644 --- a/utils/jit/jit.h +++ b/utils/jit/jit.h @@ -38,7 +38,7 @@ class JIT std::unique_ptr compiler; std::unique_ptr symbol_resolver; std::unordered_map> module_identifier_to_memory_manager; - uint64_t current_module_key = 0; + std::atomic current_module_key{0}; std::atomic compiled_code_size; // TODO lock when compiling a module mutable std::mutex jit_lock;