/* Copyright (C) 2014 InfiniDB, Inc. Copyright (c) 2019 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: wf_min_max.cpp 3932 2013-06-25 16:08:10Z xlou $ //#define NDEBUG #include #include #include #include using namespace std; #include using namespace boost; #include "loggingid.h" #include "errorcodes.h" #include "idberrorinfo.h" using namespace logging; #include "rowgroup.h" using namespace rowgroup; #include "joblisttypes.h" #include "calpontsystemcatalog.h" using namespace execplan; #include "windowfunctionstep.h" using namespace joblist; #include "wf_min_max.h" namespace windowfunction { template boost::shared_ptr WF_min_max::makeFunction(int id, const string& name, int ct, WindowFunctionColumn* wc) { boost::shared_ptr func; switch (ct) { case CalpontSystemCatalog::TINYINT: case CalpontSystemCatalog::SMALLINT: case CalpontSystemCatalog::MEDINT: case CalpontSystemCatalog::INT: case CalpontSystemCatalog::BIGINT: { func.reset(new WF_min_max(id, name)); break; } case CalpontSystemCatalog::UTINYINT: case CalpontSystemCatalog::USMALLINT: case CalpontSystemCatalog::UMEDINT: case CalpontSystemCatalog::UINT: case CalpontSystemCatalog::UBIGINT: case CalpontSystemCatalog::DATE: case CalpontSystemCatalog::DATETIME: case CalpontSystemCatalog::TIMESTAMP: case CalpontSystemCatalog::TIME: { func.reset(new WF_min_max(id, name)); break; } case CalpontSystemCatalog::DECIMAL: case CalpontSystemCatalog::UDECIMAL: { decltype(datatypes::MAXDECIMALWIDTH) width = wc->functionParms()[0]->resultType().colWidth; if (width < datatypes::MAXDECIMALWIDTH) { if (ct == CalpontSystemCatalog::UDECIMAL) func.reset(new WF_min_max(id, name)); else func.reset(new WF_min_max(id, name)); } else { func.reset(new WF_min_max(id, name)); } break; } case CalpontSystemCatalog::DOUBLE: case CalpontSystemCatalog::UDOUBLE: { func.reset(new WF_min_max(id, name)); break; } case CalpontSystemCatalog::FLOAT: case CalpontSystemCatalog::UFLOAT: { func.reset(new WF_min_max(id, name)); break; } case CalpontSystemCatalog::LONGDOUBLE: { func.reset(new WF_min_max(id, name)); break; } default: { func.reset(new WF_min_max(id, name)); break; } } return func; } template WindowFunctionType* WF_min_max::clone() const { return new WF_min_max(*this); } template void WF_min_max::resetData() { fCount = 0; WindowFunctionType::resetData(); } template void WF_min_max::operator()(int64_t b, int64_t e, int64_t c) { // for unbounded - current row special handling if (fPrev >= b && fPrev < c) b = c; else if (fPrev <= e && fPrev > c) e = c; uint64_t colIn = fFieldIndex[1]; for (int64_t i = b; i <= e; i++) { if (i % 1000 == 0 && fStep->cancelled()) break; fRow.setData(getPointer(fRowData->at(i))); if (fRow.isNullValue(colIn) == true) continue; T valIn; getValue(colIn, valIn); if ((fCount == 0) || (valIn < fValue && fFunctionId == WF__MIN) || (valIn > fValue && fFunctionId == WF__MAX)) { fValue = valIn; } fCount++; } T* v = ((fCount > 0) ? &fValue : NULL); setValue(fRow.getColType(fFieldIndex[0]), b, e, c, v); fPrev = c; } template boost::shared_ptr WF_min_max::makeFunction(int, const string&, int, WindowFunctionColumn*); } // namespace windowfunction