You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-07-30 19:23:07 +03:00
clang format apply
This commit is contained in:
@ -17,7 +17,6 @@
|
||||
|
||||
// $Id: framebound.cpp 3828 2013-05-22 17:58:14Z xlou $
|
||||
|
||||
|
||||
//#define NDEBUG
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
@ -35,62 +34,42 @@ using namespace ordering;
|
||||
|
||||
#include "framebound.h"
|
||||
|
||||
|
||||
namespace windowfunction
|
||||
{
|
||||
|
||||
|
||||
int64_t FrameBound::getBound(int64_t b, int64_t e, int64_t c)
|
||||
{
|
||||
if (fBoundType == WF__UNBOUNDED_PRECEDING)
|
||||
return b;
|
||||
if (fBoundType == WF__UNBOUNDED_PRECEDING)
|
||||
return b;
|
||||
|
||||
return e;
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
const string FrameBound::toString() const
|
||||
{
|
||||
ostringstream oss;
|
||||
ostringstream oss;
|
||||
|
||||
switch (fBoundType)
|
||||
{
|
||||
case WF__UNBOUNDED_PRECEDING:
|
||||
oss << "unbound preceding";
|
||||
break;
|
||||
switch (fBoundType)
|
||||
{
|
||||
case WF__UNBOUNDED_PRECEDING: oss << "unbound preceding"; break;
|
||||
|
||||
case WF__UNBOUNDED_FOLLOWING:
|
||||
oss << "unbound following";
|
||||
break;
|
||||
case WF__UNBOUNDED_FOLLOWING: oss << "unbound following"; break;
|
||||
|
||||
case WF__CONSTANT_PRECEDING:
|
||||
oss << "constant preceding";
|
||||
break;
|
||||
case WF__CONSTANT_PRECEDING: oss << "constant preceding"; break;
|
||||
|
||||
case WF__CONSTANT_FOLLOWING:
|
||||
oss << "constant following";
|
||||
break;
|
||||
case WF__CONSTANT_FOLLOWING: oss << "constant following"; break;
|
||||
|
||||
case WF__EXPRESSION_PRECEDING:
|
||||
oss << "expression preceding";
|
||||
break;
|
||||
case WF__EXPRESSION_PRECEDING: oss << "expression preceding"; break;
|
||||
|
||||
case WF__EXPRESSION_FOLLOWING:
|
||||
oss << "expression following";
|
||||
break;
|
||||
case WF__EXPRESSION_FOLLOWING: oss << "expression following"; break;
|
||||
|
||||
case WF__CURRENT_ROW:
|
||||
default:
|
||||
oss << "current row";
|
||||
break;
|
||||
}
|
||||
case WF__CURRENT_ROW:
|
||||
default: oss << "current row"; break;
|
||||
}
|
||||
|
||||
oss << endl;
|
||||
oss << endl;
|
||||
|
||||
return oss.str();
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
|
||||
} //namespace
|
||||
} // namespace windowfunction
|
||||
// vim:ts=4 sw=4:
|
||||
|
||||
|
@ -17,7 +17,6 @@
|
||||
|
||||
// $Id: framebound.h 3932 2013-06-25 16:08:10Z xlou $
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
@ -25,132 +24,125 @@
|
||||
#include "rowgroup.h"
|
||||
#include "windowfunctionstep.h"
|
||||
|
||||
|
||||
namespace ordering
|
||||
{
|
||||
// forward reference
|
||||
class EqualCompData;
|
||||
};
|
||||
}; // namespace ordering
|
||||
|
||||
namespace windowfunction
|
||||
{
|
||||
|
||||
|
||||
const int WF__UNBOUNDED_PRECEDING = 0;
|
||||
const int WF__CONSTANT_PRECEDING = 1;
|
||||
const int WF__UNBOUNDED_PRECEDING = 0;
|
||||
const int WF__CONSTANT_PRECEDING = 1;
|
||||
const int WF__EXPRESSION_PRECEDING = 2;
|
||||
const int WF__CURRENT_ROW = 3;
|
||||
const int WF__UNBOUNDED_FOLLOWING = 4;
|
||||
const int WF__CONSTANT_FOLLOWING = 5;
|
||||
const int WF__CURRENT_ROW = 3;
|
||||
const int WF__UNBOUNDED_FOLLOWING = 4;
|
||||
const int WF__CONSTANT_FOLLOWING = 5;
|
||||
const int WF__EXPRESSION_FOLLOWING = 6;
|
||||
|
||||
|
||||
const int WF__BOUND_ALL = -1; // unbounded - unbounded
|
||||
const int WF__BOUND_ROLLING = -2; // unbounded - current row
|
||||
const int WF__BOUND_ALL = -1; // unbounded - unbounded
|
||||
const int WF__BOUND_ROLLING = -2; // unbounded - current row
|
||||
|
||||
/** @brief class FrameBound
|
||||
*
|
||||
*/
|
||||
class FrameBound
|
||||
{
|
||||
public:
|
||||
/** @brief FrameBound constructor
|
||||
* @param t, frame type
|
||||
*/
|
||||
FrameBound(int t = 0) : fBoundType(t), fStart(true) {};
|
||||
public:
|
||||
/** @brief FrameBound constructor
|
||||
* @param t, frame type
|
||||
*/
|
||||
FrameBound(int t = 0) : fBoundType(t), fStart(true){};
|
||||
|
||||
/** @brief FrameBound destructor
|
||||
*/
|
||||
virtual ~FrameBound() {};
|
||||
/** @brief FrameBound destructor
|
||||
*/
|
||||
virtual ~FrameBound(){};
|
||||
|
||||
/** @brief clone
|
||||
*/
|
||||
virtual FrameBound* clone()
|
||||
{
|
||||
return new FrameBound(*this);
|
||||
}
|
||||
/** @brief clone
|
||||
*/
|
||||
virtual FrameBound* clone()
|
||||
{
|
||||
return new FrameBound(*this);
|
||||
}
|
||||
|
||||
/** @brief virtual void getBound
|
||||
* @param b: partition start position
|
||||
* @param e: partition end position
|
||||
* @param c: current position
|
||||
* @return : frame position
|
||||
*/
|
||||
virtual int64_t getBound(int64_t b, int64_t e, int64_t c);
|
||||
/** @brief virtual void getBound
|
||||
* @param b: partition start position
|
||||
* @param e: partition end position
|
||||
* @param c: current position
|
||||
* @return : frame position
|
||||
*/
|
||||
virtual int64_t getBound(int64_t b, int64_t e, int64_t c);
|
||||
|
||||
virtual const std::string toString() const;
|
||||
virtual const std::string toString() const;
|
||||
|
||||
void setRowData(const boost::shared_ptr<std::vector<joblist::RowPosition> >& d)
|
||||
{
|
||||
fRowData = d;
|
||||
}
|
||||
void setRowMetaData(const rowgroup::RowGroup& g, const rowgroup::Row& r)
|
||||
{
|
||||
fRowGroup = g;
|
||||
fRow = r;
|
||||
}
|
||||
void setRowData(const boost::shared_ptr<std::vector<joblist::RowPosition> >& d)
|
||||
{
|
||||
fRowData = d;
|
||||
}
|
||||
void setRowMetaData(const rowgroup::RowGroup& g, const rowgroup::Row& r)
|
||||
{
|
||||
fRowGroup = g;
|
||||
fRow = r;
|
||||
}
|
||||
|
||||
int64_t boundType() const
|
||||
{
|
||||
return fBoundType;
|
||||
}
|
||||
void boundType(int64_t t)
|
||||
{
|
||||
fBoundType = t;
|
||||
}
|
||||
int64_t boundType() const
|
||||
{
|
||||
return fBoundType;
|
||||
}
|
||||
void boundType(int64_t t)
|
||||
{
|
||||
fBoundType = t;
|
||||
}
|
||||
|
||||
bool start() const
|
||||
{
|
||||
return fStart;
|
||||
}
|
||||
void start(bool s)
|
||||
{
|
||||
fStart = s;
|
||||
}
|
||||
bool start() const
|
||||
{
|
||||
return fStart;
|
||||
}
|
||||
void start(bool s)
|
||||
{
|
||||
fStart = s;
|
||||
}
|
||||
|
||||
const boost::shared_ptr<ordering::EqualCompData>& peer() const
|
||||
{
|
||||
return fPeer;
|
||||
}
|
||||
void peer(const boost::shared_ptr<ordering::EqualCompData>& p)
|
||||
{
|
||||
fPeer = p;
|
||||
}
|
||||
const boost::shared_ptr<ordering::EqualCompData>& peer() const
|
||||
{
|
||||
return fPeer;
|
||||
}
|
||||
void peer(const boost::shared_ptr<ordering::EqualCompData>& p)
|
||||
{
|
||||
fPeer = p;
|
||||
}
|
||||
|
||||
// for string table
|
||||
void setCallback(joblist::WindowFunctionStep* step)
|
||||
{
|
||||
fStep = step;
|
||||
}
|
||||
rowgroup::Row::Pointer getPointer(joblist::RowPosition& r)
|
||||
{
|
||||
return fStep->getPointer(r, fRowGroup, fRow);
|
||||
}
|
||||
// for string table
|
||||
void setCallback(joblist::WindowFunctionStep* step)
|
||||
{
|
||||
fStep = step;
|
||||
}
|
||||
rowgroup::Row::Pointer getPointer(joblist::RowPosition& r)
|
||||
{
|
||||
return fStep->getPointer(r, fRowGroup, fRow);
|
||||
}
|
||||
|
||||
protected:
|
||||
// boundary type
|
||||
int64_t fBoundType;
|
||||
bool fStart;
|
||||
protected:
|
||||
// boundary type
|
||||
int64_t fBoundType;
|
||||
bool fStart;
|
||||
|
||||
// data
|
||||
boost::shared_ptr<std::vector<joblist::RowPosition> > fRowData;
|
||||
// data
|
||||
boost::shared_ptr<std::vector<joblist::RowPosition> > fRowData;
|
||||
|
||||
// row meta data
|
||||
rowgroup::RowGroup fRowGroup;
|
||||
rowgroup::Row fRow;
|
||||
// row meta data
|
||||
rowgroup::RowGroup fRowGroup;
|
||||
rowgroup::Row fRow;
|
||||
|
||||
// functor for peer checking
|
||||
boost::shared_ptr<ordering::EqualCompData> fPeer;
|
||||
// functor for peer checking
|
||||
boost::shared_ptr<ordering::EqualCompData> fPeer;
|
||||
|
||||
// pointer back to step
|
||||
joblist::WindowFunctionStep* fStep;
|
||||
// pointer back to step
|
||||
joblist::WindowFunctionStep* fStep;
|
||||
};
|
||||
|
||||
|
||||
extern std::map<int, std::string> colType2String;
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace windowfunction
|
||||
|
||||
// vim:ts=4 sw=4:
|
||||
|
@ -18,7 +18,6 @@
|
||||
|
||||
// $Id: frameboundrange.cpp 3932 2013-06-25 16:08:10Z xlou $
|
||||
|
||||
|
||||
//#define NDEBUG
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
@ -36,398 +35,380 @@ using namespace ordering;
|
||||
|
||||
#include "frameboundrange.h"
|
||||
|
||||
|
||||
namespace windowfunction
|
||||
{
|
||||
|
||||
|
||||
int64_t FrameBoundRange::getBound(int64_t b, int64_t e, int64_t c)
|
||||
{
|
||||
if (fStart)
|
||||
if (fStart)
|
||||
{
|
||||
while (c > b)
|
||||
{
|
||||
while (c > b)
|
||||
{
|
||||
if (!fPeer->operator()(getPointer(fRowData->at(c)), getPointer(fRowData->at(c - 1))))
|
||||
break;
|
||||
if (!fPeer->operator()(getPointer(fRowData->at(c)), getPointer(fRowData->at(c - 1))))
|
||||
break;
|
||||
|
||||
c--;
|
||||
}
|
||||
c--;
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
while (c < e)
|
||||
{
|
||||
while (c < e)
|
||||
{
|
||||
if (!fPeer->operator()(getPointer(fRowData->at(c)), getPointer(fRowData->at(c + 1))))
|
||||
break;
|
||||
if (!fPeer->operator()(getPointer(fRowData->at(c)), getPointer(fRowData->at(c + 1))))
|
||||
break;
|
||||
|
||||
c++;
|
||||
}
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
const string FrameBoundRange::toString() const
|
||||
{
|
||||
return FrameBound::toString();
|
||||
return FrameBound::toString();
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
int64_t FrameBoundConstantRange<T>::getBound(int64_t b, int64_t e, int64_t c)
|
||||
{
|
||||
// set row data
|
||||
fRow.setData(getPointer(fRowData->at(c)));
|
||||
getValue(fValue, fIndex[2]);
|
||||
// set row data
|
||||
fRow.setData(getPointer(fRowData->at(c)));
|
||||
getValue(fValue, fIndex[2]);
|
||||
|
||||
// make sure the expr is not negative
|
||||
validate();
|
||||
// make sure the expr is not negative
|
||||
validate();
|
||||
|
||||
// calculate the offset, and move
|
||||
if (fIsZero)
|
||||
c = FrameBoundRange::getBound(b, e, c);
|
||||
else if (fBoundType < WF__CURRENT_ROW)
|
||||
c -= getPrecedingOffset(c, b);
|
||||
else
|
||||
c += getFollowingOffset(c, e);
|
||||
// calculate the offset, and move
|
||||
if (fIsZero)
|
||||
c = FrameBoundRange::getBound(b, e, c);
|
||||
else if (fBoundType < WF__CURRENT_ROW)
|
||||
c -= getPrecedingOffset(c, b);
|
||||
else
|
||||
c += getFollowingOffset(c, e);
|
||||
|
||||
return c;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
int64_t FrameBoundConstantRange<T>::getPrecedingOffset(int64_t c, int64_t b)
|
||||
{
|
||||
// test each row to find the bound
|
||||
bool next = true;
|
||||
int64_t i = c;
|
||||
int64_t j = 0;
|
||||
// test each row to find the bound
|
||||
bool next = true;
|
||||
int64_t i = c;
|
||||
int64_t j = 0;
|
||||
|
||||
for (i--, j++; i >= b && next; i--, j++)
|
||||
for (i--, j++; i >= b && next; i--, j++)
|
||||
{
|
||||
// set row data, get order by column value
|
||||
fRow.setData(getPointer(fRowData->at(i)));
|
||||
ValueType<T> v;
|
||||
getValue(v, fIndex[0]);
|
||||
|
||||
if (v.fIsNull)
|
||||
{
|
||||
// set row data, get order by column value
|
||||
fRow.setData(getPointer(fRowData->at(i)));
|
||||
ValueType<T> v;
|
||||
getValue(v, fIndex[0]);
|
||||
|
||||
if (v.fIsNull)
|
||||
{
|
||||
next = fValue.fIsNull; // let null = null
|
||||
}
|
||||
else if (fValue.fIsNull)
|
||||
{
|
||||
next = false;
|
||||
}
|
||||
else if (fAsc && v.fValue < fValue.fValue)
|
||||
{
|
||||
next = false;
|
||||
}
|
||||
else if (!fAsc && v.fValue > fValue.fValue)
|
||||
{
|
||||
next = false;
|
||||
}
|
||||
else if (!fStart && v.fValue == fValue.fValue)
|
||||
{
|
||||
next = false;
|
||||
}
|
||||
next = fValue.fIsNull; // let null = null
|
||||
}
|
||||
|
||||
if (!next)
|
||||
else if (fValue.fIsNull)
|
||||
{
|
||||
if (fStart)
|
||||
j -= 2;
|
||||
else
|
||||
j -= 1;
|
||||
next = false;
|
||||
}
|
||||
else if (fAsc && v.fValue < fValue.fValue)
|
||||
{
|
||||
next = false;
|
||||
}
|
||||
else if (!fAsc && v.fValue > fValue.fValue)
|
||||
{
|
||||
next = false;
|
||||
}
|
||||
else if (!fStart && v.fValue == fValue.fValue)
|
||||
{
|
||||
next = false;
|
||||
}
|
||||
}
|
||||
|
||||
return j;
|
||||
if (!next)
|
||||
{
|
||||
if (fStart)
|
||||
j -= 2;
|
||||
else
|
||||
j -= 1;
|
||||
}
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
int64_t FrameBoundConstantRange<T>::getFollowingOffset(int64_t c, int64_t e)
|
||||
{
|
||||
// test each row to find the bound
|
||||
bool next = true;
|
||||
int64_t i = c;
|
||||
int64_t j = 0;
|
||||
// test each row to find the bound
|
||||
bool next = true;
|
||||
int64_t i = c;
|
||||
int64_t j = 0;
|
||||
|
||||
for (i++, j++; i <= e && next; i++, j++)
|
||||
for (i++, j++; i <= e && next; i++, j++)
|
||||
{
|
||||
// set row data, get order by column value
|
||||
fRow.setData(getPointer(fRowData->at(i)));
|
||||
ValueType<T> v;
|
||||
getValue(v, fIndex[0]);
|
||||
|
||||
if (v.fIsNull)
|
||||
{
|
||||
// set row data, get order by column value
|
||||
fRow.setData(getPointer(fRowData->at(i)));
|
||||
ValueType<T> v;
|
||||
getValue(v, fIndex[0]);
|
||||
|
||||
if (v.fIsNull)
|
||||
{
|
||||
next = fValue.fIsNull; // let null = null
|
||||
}
|
||||
else if (fValue.fIsNull)
|
||||
{
|
||||
next = false;
|
||||
}
|
||||
else if (fAsc && v.fValue > fValue.fValue)
|
||||
{
|
||||
next = false;
|
||||
}
|
||||
else if (!fAsc && v.fValue < fValue.fValue)
|
||||
{
|
||||
next = false;
|
||||
}
|
||||
else if (fStart && v.fValue == fValue.fValue)
|
||||
{
|
||||
next = false;
|
||||
}
|
||||
next = fValue.fIsNull; // let null = null
|
||||
}
|
||||
|
||||
if (!next)
|
||||
else if (fValue.fIsNull)
|
||||
{
|
||||
if (fStart)
|
||||
j -= 1;
|
||||
else
|
||||
j -= 2;
|
||||
next = false;
|
||||
}
|
||||
else if (fAsc && v.fValue > fValue.fValue)
|
||||
{
|
||||
next = false;
|
||||
}
|
||||
else if (!fAsc && v.fValue < fValue.fValue)
|
||||
{
|
||||
next = false;
|
||||
}
|
||||
else if (fStart && v.fValue == fValue.fValue)
|
||||
{
|
||||
next = false;
|
||||
}
|
||||
}
|
||||
|
||||
return j;
|
||||
if (!next)
|
||||
{
|
||||
if (fStart)
|
||||
j -= 1;
|
||||
else
|
||||
j -= 2;
|
||||
}
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
void FrameBoundConstantRange<T>::getValue(ValueType<T>& v, int64_t i)
|
||||
{
|
||||
v.fIsNull = fRow.isNullValue(i);
|
||||
v.fIsNull = fRow.isNullValue(i);
|
||||
|
||||
if (!v.fIsNull)
|
||||
v.fValue = fRow.getIntField(i);
|
||||
if (!v.fIsNull)
|
||||
v.fValue = fRow.getIntField(i);
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
T FrameBoundConstantRange<T>::getValueByType(int64_t i)
|
||||
{
|
||||
T t;
|
||||
return t;
|
||||
T t;
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
template<> int64_t FrameBoundConstantRange<int64_t>::getValueByType(int64_t i)
|
||||
template <>
|
||||
int64_t FrameBoundConstantRange<int64_t>::getValueByType(int64_t i)
|
||||
{
|
||||
return fRow.getIntField(i);
|
||||
return fRow.getIntField(i);
|
||||
}
|
||||
|
||||
|
||||
template<> uint64_t FrameBoundConstantRange<uint64_t>::getValueByType(int64_t i)
|
||||
template <>
|
||||
uint64_t FrameBoundConstantRange<uint64_t>::getValueByType(int64_t i)
|
||||
{
|
||||
uint64_t v = fRow.getUintField(i);
|
||||
uint64_t v = fRow.getUintField(i);
|
||||
|
||||
// convert date to datetime, [refer to treenode.h]
|
||||
if (fRow.getColType(fIndex[0]) == execplan::CalpontSystemCatalog::DATE && i == 0)
|
||||
v = v << 32;
|
||||
// convert date to datetime, [refer to treenode.h]
|
||||
if (fRow.getColType(fIndex[0]) == execplan::CalpontSystemCatalog::DATE && i == 0)
|
||||
v = v << 32;
|
||||
|
||||
return v;
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
template<> double FrameBoundConstantRange<double>::getValueByType(int64_t i)
|
||||
template <>
|
||||
double FrameBoundConstantRange<double>::getValueByType(int64_t i)
|
||||
{
|
||||
return fRow.getDoubleField(i);
|
||||
return fRow.getDoubleField(i);
|
||||
}
|
||||
|
||||
|
||||
template<> float FrameBoundConstantRange<float>::getValueByType(int64_t i)
|
||||
template <>
|
||||
float FrameBoundConstantRange<float>::getValueByType(int64_t i)
|
||||
{
|
||||
return fRow.getFloatField(i);
|
||||
return fRow.getFloatField(i);
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
const string FrameBoundConstantRange<T>::toString() const
|
||||
{
|
||||
ostringstream oss;
|
||||
oss << fValue.fValue << " " << FrameBound::toString();
|
||||
return oss.str();
|
||||
ostringstream oss;
|
||||
oss << fValue.fValue << " " << FrameBound::toString();
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
int64_t FrameBoundExpressionRange<T>::getPrecedingOffset(int64_t c, int64_t b)
|
||||
{
|
||||
return FrameBoundConstantRange<T>::getPrecedingOffset(c, b);
|
||||
return FrameBoundConstantRange<T>::getPrecedingOffset(c, b);
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
int64_t FrameBoundExpressionRange<T>::getFollowingOffset(int64_t c, int64_t e)
|
||||
{
|
||||
return FrameBoundConstantRange<T>::getFollowingOffset(c, e);
|
||||
return FrameBoundConstantRange<T>::getFollowingOffset(c, e);
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
void FrameBoundExpressionRange<T>::validate()
|
||||
{
|
||||
bool invalid = false;
|
||||
ostringstream oss;
|
||||
bool invalid = false;
|
||||
ostringstream oss;
|
||||
|
||||
if (this->fRow.isNullValue(this->fIndex[1]))
|
||||
if (this->fRow.isNullValue(this->fIndex[1]))
|
||||
{
|
||||
invalid = true;
|
||||
oss << "NULL";
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (this->fRow.getColType(this->fIndex[1]))
|
||||
{
|
||||
invalid = true;
|
||||
oss << "NULL";
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (this->fRow.getColType(this->fIndex[1]))
|
||||
case execplan::CalpontSystemCatalog::TINYINT:
|
||||
case execplan::CalpontSystemCatalog::SMALLINT:
|
||||
case execplan::CalpontSystemCatalog::MEDINT:
|
||||
case execplan::CalpontSystemCatalog::INT:
|
||||
case execplan::CalpontSystemCatalog::BIGINT:
|
||||
{
|
||||
int64_t tmp = this->fRow.getIntField(this->fIndex[1]);
|
||||
this->fIsZero = (tmp == 0);
|
||||
|
||||
if (tmp < 0)
|
||||
{
|
||||
case execplan::CalpontSystemCatalog::TINYINT:
|
||||
case execplan::CalpontSystemCatalog::SMALLINT:
|
||||
case execplan::CalpontSystemCatalog::MEDINT:
|
||||
case execplan::CalpontSystemCatalog::INT:
|
||||
case execplan::CalpontSystemCatalog::BIGINT:
|
||||
{
|
||||
int64_t tmp = this->fRow.getIntField(this->fIndex[1]);
|
||||
this->fIsZero = (tmp == 0);
|
||||
|
||||
if (tmp < 0)
|
||||
{
|
||||
invalid = true;
|
||||
oss << tmp;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case execplan::CalpontSystemCatalog::DECIMAL:
|
||||
{
|
||||
if (UNLIKELY(this->fRow.getColumnWidth(this->fIndex[1])
|
||||
< datatypes::MAXDECIMALWIDTH))
|
||||
{
|
||||
int64_t tmp = this->fRow.getIntField(this->fIndex[1]);
|
||||
this->fIsZero = (tmp == 0);
|
||||
|
||||
if (tmp < 0)
|
||||
{
|
||||
invalid = true;
|
||||
oss << "<negative>";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
datatypes::TSInt128 tmp = this->fRow.getTSInt128Field(this->fIndex[1]);
|
||||
this->fIsZero = (tmp == 0);
|
||||
|
||||
if (tmp < 0)
|
||||
{
|
||||
invalid = true;
|
||||
oss << "<negative>";
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case execplan::CalpontSystemCatalog::UDECIMAL:
|
||||
{
|
||||
if (UNLIKELY(this->fRow.getColumnWidth(this->fIndex[1])
|
||||
< datatypes::MAXDECIMALWIDTH))
|
||||
{
|
||||
uint64_t tmp = this->fRow.getUintField(this->fIndex[1]);
|
||||
this->fIsZero = (tmp == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
datatypes::TSInt128 tmp = this->fRow.getTSInt128Field(this->fIndex[1]);
|
||||
this->fIsZero = (tmp == 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case execplan::CalpontSystemCatalog::DOUBLE:
|
||||
case execplan::CalpontSystemCatalog::UDOUBLE:
|
||||
{
|
||||
double tmp = this->fRow.getDoubleField(this->fIndex[1]);
|
||||
this->fIsZero = (tmp == 0.0);
|
||||
|
||||
if (tmp < 0)
|
||||
{
|
||||
invalid = true;
|
||||
oss << tmp;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case execplan::CalpontSystemCatalog::LONGDOUBLE:
|
||||
{
|
||||
long double tmp = this->fRow.getLongDoubleField(this->fIndex[1]);
|
||||
this->fIsZero = (tmp == 0.0);
|
||||
|
||||
if (tmp < 0)
|
||||
{
|
||||
invalid = true;
|
||||
oss << tmp;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case execplan::CalpontSystemCatalog::FLOAT:
|
||||
case execplan::CalpontSystemCatalog::UFLOAT:
|
||||
{
|
||||
float tmp = this->fRow.getFloatField(this->fIndex[1]);
|
||||
this->fIsZero = (tmp == 0.0);
|
||||
|
||||
if (tmp < 0)
|
||||
{
|
||||
invalid = true;
|
||||
oss << tmp;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case execplan::CalpontSystemCatalog::UTINYINT:
|
||||
case execplan::CalpontSystemCatalog::USMALLINT:
|
||||
case execplan::CalpontSystemCatalog::UMEDINT:
|
||||
case execplan::CalpontSystemCatalog::UINT:
|
||||
case execplan::CalpontSystemCatalog::UBIGINT:
|
||||
default:
|
||||
{
|
||||
uint64_t tmp = this->fRow.getUintField(this->fIndex[1]);
|
||||
this->fIsZero = (tmp == 0);
|
||||
break;
|
||||
}
|
||||
invalid = true;
|
||||
oss << tmp;
|
||||
}
|
||||
}
|
||||
|
||||
if (invalid)
|
||||
{
|
||||
oss << " (expr)";
|
||||
throw IDBExcept(IDBErrorInfo::instance()->errorMsg(ERR_WF_BOUND_OUT_OF_RANGE, oss.str()),
|
||||
ERR_WF_BOUND_OUT_OF_RANGE);
|
||||
break;
|
||||
}
|
||||
|
||||
case execplan::CalpontSystemCatalog::DECIMAL:
|
||||
{
|
||||
if (UNLIKELY(this->fRow.getColumnWidth(this->fIndex[1]) < datatypes::MAXDECIMALWIDTH))
|
||||
{
|
||||
int64_t tmp = this->fRow.getIntField(this->fIndex[1]);
|
||||
this->fIsZero = (tmp == 0);
|
||||
|
||||
if (tmp < 0)
|
||||
{
|
||||
invalid = true;
|
||||
oss << "<negative>";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
datatypes::TSInt128 tmp = this->fRow.getTSInt128Field(this->fIndex[1]);
|
||||
this->fIsZero = (tmp == 0);
|
||||
|
||||
if (tmp < 0)
|
||||
{
|
||||
invalid = true;
|
||||
oss << "<negative>";
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case execplan::CalpontSystemCatalog::UDECIMAL:
|
||||
{
|
||||
if (UNLIKELY(this->fRow.getColumnWidth(this->fIndex[1]) < datatypes::MAXDECIMALWIDTH))
|
||||
{
|
||||
uint64_t tmp = this->fRow.getUintField(this->fIndex[1]);
|
||||
this->fIsZero = (tmp == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
datatypes::TSInt128 tmp = this->fRow.getTSInt128Field(this->fIndex[1]);
|
||||
this->fIsZero = (tmp == 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case execplan::CalpontSystemCatalog::DOUBLE:
|
||||
case execplan::CalpontSystemCatalog::UDOUBLE:
|
||||
{
|
||||
double tmp = this->fRow.getDoubleField(this->fIndex[1]);
|
||||
this->fIsZero = (tmp == 0.0);
|
||||
|
||||
if (tmp < 0)
|
||||
{
|
||||
invalid = true;
|
||||
oss << tmp;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case execplan::CalpontSystemCatalog::LONGDOUBLE:
|
||||
{
|
||||
long double tmp = this->fRow.getLongDoubleField(this->fIndex[1]);
|
||||
this->fIsZero = (tmp == 0.0);
|
||||
|
||||
if (tmp < 0)
|
||||
{
|
||||
invalid = true;
|
||||
oss << tmp;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case execplan::CalpontSystemCatalog::FLOAT:
|
||||
case execplan::CalpontSystemCatalog::UFLOAT:
|
||||
{
|
||||
float tmp = this->fRow.getFloatField(this->fIndex[1]);
|
||||
this->fIsZero = (tmp == 0.0);
|
||||
|
||||
if (tmp < 0)
|
||||
{
|
||||
invalid = true;
|
||||
oss << tmp;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case execplan::CalpontSystemCatalog::UTINYINT:
|
||||
case execplan::CalpontSystemCatalog::USMALLINT:
|
||||
case execplan::CalpontSystemCatalog::UMEDINT:
|
||||
case execplan::CalpontSystemCatalog::UINT:
|
||||
case execplan::CalpontSystemCatalog::UBIGINT:
|
||||
default:
|
||||
{
|
||||
uint64_t tmp = this->fRow.getUintField(this->fIndex[1]);
|
||||
this->fIsZero = (tmp == 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (invalid)
|
||||
{
|
||||
oss << " (expr)";
|
||||
throw IDBExcept(IDBErrorInfo::instance()->errorMsg(ERR_WF_BOUND_OUT_OF_RANGE, oss.str()),
|
||||
ERR_WF_BOUND_OUT_OF_RANGE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
const string FrameBoundExpressionRange<T>::toString() const
|
||||
{
|
||||
ostringstream oss;
|
||||
oss << " value_expr " << FrameBound::toString();
|
||||
return oss.str();
|
||||
ostringstream oss;
|
||||
oss << " value_expr " << FrameBound::toString();
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
template class FrameBoundConstantRange<int64_t>;
|
||||
template class FrameBoundConstantRange<uint64_t>;
|
||||
template class FrameBoundConstantRange<double>;
|
||||
template class FrameBoundConstantRange<float>;
|
||||
|
||||
template class FrameBoundConstantRange<int64_t>;
|
||||
template class FrameBoundConstantRange<uint64_t>;
|
||||
template class FrameBoundConstantRange<double>;
|
||||
template class FrameBoundConstantRange<float>;
|
||||
template class FrameBoundExpressionRange<int64_t>;
|
||||
template class FrameBoundExpressionRange<double>;
|
||||
template class FrameBoundExpressionRange<float>;
|
||||
template class FrameBoundExpressionRange<uint64_t>;
|
||||
|
||||
template class FrameBoundExpressionRange<int64_t>;
|
||||
template class FrameBoundExpressionRange<double>;
|
||||
template class FrameBoundExpressionRange<float>;
|
||||
template class FrameBoundExpressionRange<uint64_t>;
|
||||
|
||||
} //namespace
|
||||
} // namespace windowfunction
|
||||
// vim:ts=4 sw=4:
|
||||
|
||||
|
@ -17,216 +17,200 @@
|
||||
|
||||
// $Id: frameboundrange.h 3868 2013-06-06 22:13:05Z xlou $
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "framebound.h"
|
||||
|
||||
|
||||
namespace windowfunction
|
||||
{
|
||||
|
||||
|
||||
/** @brief class FrameBoundRange
|
||||
*
|
||||
*/
|
||||
class FrameBoundRange : public FrameBound
|
||||
{
|
||||
public:
|
||||
/** @brief FrameBoundRange constructor
|
||||
* @param t, frame type
|
||||
* @param a, order by sort spec: asc | desc
|
||||
* @param n, order by sort spec: null first | null last
|
||||
* @param v, order by column data type
|
||||
*/
|
||||
FrameBoundRange(int t = 0, bool a = true, bool n = true)
|
||||
: FrameBound(t), fAsc(a), fNullFirst(n), fIsZero(false) {};
|
||||
public:
|
||||
/** @brief FrameBoundRange constructor
|
||||
* @param t, frame type
|
||||
* @param a, order by sort spec: asc | desc
|
||||
* @param n, order by sort spec: null first | null last
|
||||
* @param v, order by column data type
|
||||
*/
|
||||
FrameBoundRange(int t = 0, bool a = true, bool n = true)
|
||||
: FrameBound(t), fAsc(a), fNullFirst(n), fIsZero(false){};
|
||||
|
||||
/** @brief FrameBoundRange destructor
|
||||
*/
|
||||
virtual ~FrameBoundRange() {};
|
||||
/** @brief FrameBoundRange destructor
|
||||
*/
|
||||
virtual ~FrameBoundRange(){};
|
||||
|
||||
/** @brief clone
|
||||
*/
|
||||
virtual FrameBound* clone()
|
||||
{
|
||||
return NULL; // abstract class
|
||||
}
|
||||
/** @brief clone
|
||||
*/
|
||||
virtual FrameBound* clone()
|
||||
{
|
||||
return NULL; // abstract class
|
||||
}
|
||||
|
||||
/** @brief virtual void getBound
|
||||
*/
|
||||
int64_t getBound(int64_t, int64_t, int64_t);
|
||||
/** @brief virtual void getBound
|
||||
*/
|
||||
int64_t getBound(int64_t, int64_t, int64_t);
|
||||
|
||||
const std::string toString() const;
|
||||
const std::string toString() const;
|
||||
|
||||
void setTupleId(std::vector<uint64_t> ids)
|
||||
{
|
||||
fTupleId = ids;
|
||||
}
|
||||
std::vector<uint64_t> getTupleId() const
|
||||
{
|
||||
return fTupleId;
|
||||
}
|
||||
void setTupleId(std::vector<uint64_t> ids)
|
||||
{
|
||||
fTupleId = ids;
|
||||
}
|
||||
std::vector<uint64_t> getTupleId() const
|
||||
{
|
||||
return fTupleId;
|
||||
}
|
||||
|
||||
void setIndex(vector<int> idx)
|
||||
{
|
||||
fIndex = idx;
|
||||
}
|
||||
const std::vector<int>& getIndex() const
|
||||
{
|
||||
return fIndex;
|
||||
}
|
||||
void setIndex(vector<int> idx)
|
||||
{
|
||||
fIndex = idx;
|
||||
}
|
||||
const std::vector<int>& getIndex() const
|
||||
{
|
||||
return fIndex;
|
||||
}
|
||||
|
||||
void isZero(bool z)
|
||||
{
|
||||
fIsZero = z;
|
||||
}
|
||||
bool isZero() const
|
||||
{
|
||||
return fIsZero;
|
||||
}
|
||||
void isZero(bool z)
|
||||
{
|
||||
fIsZero = z;
|
||||
}
|
||||
bool isZero() const
|
||||
{
|
||||
return fIsZero;
|
||||
}
|
||||
|
||||
protected:
|
||||
protected:
|
||||
// for range calculation
|
||||
// data, row meta data, order by column index, ascending | descending
|
||||
// [0]: order by; [1]: interval; [2]: [0] +/- [1]
|
||||
std::vector<uint64_t> fTupleId;
|
||||
std::vector<int> fIndex;
|
||||
|
||||
// for range calculation
|
||||
// data, row meta data, order by column index, ascending | descending
|
||||
// [0]: order by; [1]: interval; [2]: [0] +/- [1]
|
||||
std::vector<uint64_t> fTupleId;
|
||||
std::vector<int> fIndex;
|
||||
|
||||
// order by sort specification
|
||||
bool fAsc;
|
||||
bool fNullFirst;
|
||||
|
||||
// in case expr evaluates to 0
|
||||
bool fIsZero;
|
||||
// order by sort specification
|
||||
bool fAsc;
|
||||
bool fNullFirst;
|
||||
|
||||
// in case expr evaluates to 0
|
||||
bool fIsZero;
|
||||
};
|
||||
|
||||
|
||||
/** @brief struct ValueType
|
||||
*
|
||||
*/
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
struct ValueType
|
||||
{
|
||||
T fValue;
|
||||
bool fIsNull;
|
||||
T fValue;
|
||||
bool fIsNull;
|
||||
|
||||
// constructor
|
||||
ValueType() : fValue(0), fIsNull(false) {}
|
||||
// constructor
|
||||
ValueType() : fValue(0), fIsNull(false)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** @brief class FrameBoundConstantRange
|
||||
*
|
||||
*/
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
class FrameBoundConstantRange : public FrameBoundRange
|
||||
{
|
||||
public:
|
||||
/** @brief FrameBoundConstant constructor
|
||||
* @param t, frame type
|
||||
* @param a, order by sort spec: asc | desc
|
||||
* @param n, order by sort spec: null first | null last
|
||||
* @param c, constant value. !! caller need to check NULL or negative value !!
|
||||
*/
|
||||
FrameBoundConstantRange(int t = 0, bool a = true, bool n = true, void* c = NULL)
|
||||
: FrameBoundRange(t, a, n)
|
||||
{
|
||||
fValue.fIsNull = (c == NULL);
|
||||
public:
|
||||
/** @brief FrameBoundConstant constructor
|
||||
* @param t, frame type
|
||||
* @param a, order by sort spec: asc | desc
|
||||
* @param n, order by sort spec: null first | null last
|
||||
* @param c, constant value. !! caller need to check NULL or negative value !!
|
||||
*/
|
||||
FrameBoundConstantRange(int t = 0, bool a = true, bool n = true, void* c = NULL) : FrameBoundRange(t, a, n)
|
||||
{
|
||||
fValue.fIsNull = (c == NULL);
|
||||
|
||||
if (!fValue.fIsNull)
|
||||
fValue.fValue = *((T*) c);
|
||||
};
|
||||
if (!fValue.fIsNull)
|
||||
fValue.fValue = *((T*)c);
|
||||
};
|
||||
|
||||
/** @brief FrameBoundConstantRange destructor
|
||||
*/
|
||||
virtual ~FrameBoundConstantRange() {};
|
||||
/** @brief FrameBoundConstantRange destructor
|
||||
*/
|
||||
virtual ~FrameBoundConstantRange(){};
|
||||
|
||||
/** @brief clone
|
||||
*/
|
||||
virtual FrameBound* clone()
|
||||
{
|
||||
return new FrameBoundConstantRange(*this);
|
||||
}
|
||||
/** @brief clone
|
||||
*/
|
||||
virtual FrameBound* clone()
|
||||
{
|
||||
return new FrameBoundConstantRange(*this);
|
||||
}
|
||||
|
||||
/** @brief virtual void getBound
|
||||
*/
|
||||
int64_t getBound(int64_t, int64_t, int64_t);
|
||||
/** @brief virtual void getBound
|
||||
*/
|
||||
int64_t getBound(int64_t, int64_t, int64_t);
|
||||
|
||||
const std::string toString() const;
|
||||
const std::string toString() const;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
// find the range offset
|
||||
// i: partition upper bound
|
||||
// j: current row
|
||||
// k: partition lower bound
|
||||
virtual int64_t getPrecedingOffset(int64_t j, int64_t i);
|
||||
virtual int64_t getFollowingOffset(int64_t j, int64_t k);
|
||||
|
||||
// find the range offset
|
||||
// i: partition upper bound
|
||||
// j: current row
|
||||
// k: partition lower bound
|
||||
virtual int64_t getPrecedingOffset(int64_t j, int64_t i);
|
||||
virtual int64_t getFollowingOffset(int64_t j, int64_t k);
|
||||
// validate value is not negative
|
||||
virtual void validate()
|
||||
{
|
||||
}
|
||||
|
||||
// validate value is not negative
|
||||
virtual void validate() {}
|
||||
|
||||
// get value at fIndex[x]
|
||||
void getValue(ValueType<T>&, int64_t);
|
||||
T getValueByType(int64_t);
|
||||
|
||||
// order by column value type
|
||||
ValueType<T> fValue;
|
||||
// get value at fIndex[x]
|
||||
void getValue(ValueType<T>&, int64_t);
|
||||
T getValueByType(int64_t);
|
||||
|
||||
// order by column value type
|
||||
ValueType<T> fValue;
|
||||
};
|
||||
|
||||
|
||||
/** @brief class FrameBoundExpressionRange
|
||||
*
|
||||
*/
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
class FrameBoundExpressionRange : public FrameBoundConstantRange<T>
|
||||
{
|
||||
public:
|
||||
/** @brief FrameBoundExpressionRange constructor
|
||||
* @param t, frame type
|
||||
* @param a, order by sort spec: asc | desc
|
||||
* @param n, order by sort spec: null first | null last
|
||||
*/
|
||||
FrameBoundExpressionRange(int t = 0, bool a = true, bool n = true) :
|
||||
FrameBoundConstantRange<T>(t, a, n) {};
|
||||
public:
|
||||
/** @brief FrameBoundExpressionRange constructor
|
||||
* @param t, frame type
|
||||
* @param a, order by sort spec: asc | desc
|
||||
* @param n, order by sort spec: null first | null last
|
||||
*/
|
||||
FrameBoundExpressionRange(int t = 0, bool a = true, bool n = true) : FrameBoundConstantRange<T>(t, a, n){};
|
||||
|
||||
/** @brief FrameBoundExpressionRange destructor
|
||||
*/
|
||||
virtual ~FrameBoundExpressionRange() {};
|
||||
/** @brief FrameBoundExpressionRange destructor
|
||||
*/
|
||||
virtual ~FrameBoundExpressionRange(){};
|
||||
|
||||
/** @brief clone
|
||||
*/
|
||||
virtual FrameBound* clone()
|
||||
{
|
||||
return new FrameBoundExpressionRange(*this);
|
||||
}
|
||||
/** @brief clone
|
||||
*/
|
||||
virtual FrameBound* clone()
|
||||
{
|
||||
return new FrameBoundExpressionRange(*this);
|
||||
}
|
||||
|
||||
/** @brief virtual void getBound
|
||||
*/
|
||||
// int64_t getBound(int64_t, int64_t, int64_t);
|
||||
/** @brief virtual void getBound
|
||||
*/
|
||||
// int64_t getBound(int64_t, int64_t, int64_t);
|
||||
|
||||
const std::string toString() const;
|
||||
const std::string toString() const;
|
||||
|
||||
protected:
|
||||
// virtual in FrameBoundRange
|
||||
int64_t getPrecedingOffset(int64_t j, int64_t i);
|
||||
int64_t getFollowingOffset(int64_t j, int64_t k);
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
// virtual in FrameBoundRange
|
||||
int64_t getPrecedingOffset(int64_t j, int64_t i);
|
||||
int64_t getFollowingOffset(int64_t j, int64_t k);
|
||||
|
||||
// validate the expression is not negative
|
||||
void validate();
|
||||
|
||||
// validate the expression is not negative
|
||||
void validate();
|
||||
};
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace windowfunction
|
||||
|
||||
// vim:ts=4 sw=4:
|
||||
|
@ -17,7 +17,6 @@
|
||||
|
||||
// $Id: frameboundrow.cpp 3932 2013-06-25 16:08:10Z xlou $
|
||||
|
||||
|
||||
//#define NDEBUG
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
@ -36,119 +35,108 @@ using namespace ordering;
|
||||
#include "treenode.h"
|
||||
#include "frameboundrow.h"
|
||||
|
||||
|
||||
namespace windowfunction
|
||||
{
|
||||
|
||||
|
||||
int64_t FrameBoundRow::getBound(int64_t b, int64_t e, int64_t c)
|
||||
{
|
||||
return c;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
const string FrameBoundRow::toString() const
|
||||
{
|
||||
return FrameBound::toString();
|
||||
return FrameBound::toString();
|
||||
}
|
||||
|
||||
|
||||
int64_t FrameBoundConstantRow::getBound(int64_t b, int64_t e, int64_t c)
|
||||
{
|
||||
if (fBoundType < WF__CURRENT_ROW)
|
||||
{
|
||||
if (fOffset <= (c - b))
|
||||
c -= fOffset;
|
||||
else
|
||||
c = b - (!fStart ? 1 : 0);
|
||||
}
|
||||
if (fBoundType < WF__CURRENT_ROW)
|
||||
{
|
||||
if (fOffset <= (c - b))
|
||||
c -= fOffset;
|
||||
else
|
||||
{
|
||||
if (fOffset <= (e - c))
|
||||
c += fOffset;
|
||||
else
|
||||
c = e + (fStart ? 1 : 0);
|
||||
}
|
||||
c = b - (!fStart ? 1 : 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fOffset <= (e - c))
|
||||
c += fOffset;
|
||||
else
|
||||
c = e + (fStart ? 1 : 0);
|
||||
}
|
||||
|
||||
return c;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
const string FrameBoundConstantRow::toString() const
|
||||
{
|
||||
ostringstream oss;
|
||||
oss << fOffset << " " << FrameBound::toString();
|
||||
return oss.str();
|
||||
ostringstream oss;
|
||||
oss << fOffset << " " << FrameBound::toString();
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
int64_t FrameBoundExpressionRow<T>::getBound(int64_t b, int64_t e, int64_t c)
|
||||
{
|
||||
// set row data
|
||||
// get expression int value
|
||||
fRow.setData(getPointer(fRowData->at(c)));
|
||||
// set row data
|
||||
// get expression int value
|
||||
fRow.setData(getPointer(fRowData->at(c)));
|
||||
|
||||
if (fRow.isNullValue(fExprIdx))
|
||||
throw IDBExcept(IDBErrorInfo::instance()->errorMsg(ERR_WF_BOUND_OUT_OF_RANGE, "NULL"),
|
||||
ERR_WF_BOUND_OUT_OF_RANGE);
|
||||
if (fRow.isNullValue(fExprIdx))
|
||||
throw IDBExcept(IDBErrorInfo::instance()->errorMsg(ERR_WF_BOUND_OUT_OF_RANGE, "NULL"),
|
||||
ERR_WF_BOUND_OUT_OF_RANGE);
|
||||
|
||||
getOffset();
|
||||
getOffset();
|
||||
|
||||
if (fOffset < 0)
|
||||
{
|
||||
throw IDBExcept(IDBErrorInfo::instance()->errorMsg(ERR_WF_BOUND_OUT_OF_RANGE, fOffset),
|
||||
ERR_WF_BOUND_OUT_OF_RANGE);
|
||||
}
|
||||
if (fOffset < 0)
|
||||
{
|
||||
throw IDBExcept(IDBErrorInfo::instance()->errorMsg(ERR_WF_BOUND_OUT_OF_RANGE, fOffset),
|
||||
ERR_WF_BOUND_OUT_OF_RANGE);
|
||||
}
|
||||
|
||||
return FrameBoundConstantRow::getBound(b, e, c);
|
||||
return FrameBoundConstantRow::getBound(b, e, c);
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
const string FrameBoundExpressionRow<T>::toString() const
|
||||
{
|
||||
ostringstream oss;
|
||||
oss << "value_expr " << FrameBound::toString();
|
||||
return oss.str();
|
||||
ostringstream oss;
|
||||
oss << "value_expr " << FrameBound::toString();
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
|
||||
template<typename T> void FrameBoundExpressionRow<T>::getOffset()
|
||||
template <typename T>
|
||||
void FrameBoundExpressionRow<T>::getOffset()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
template<> void FrameBoundExpressionRow<int64_t>::getOffset()
|
||||
template <>
|
||||
void FrameBoundExpressionRow<int64_t>::getOffset()
|
||||
{
|
||||
fOffset = fRow.getIntField(fExprIdx);
|
||||
fOffset = fRow.getIntField(fExprIdx);
|
||||
}
|
||||
|
||||
|
||||
template<> void FrameBoundExpressionRow<uint64_t>::getOffset()
|
||||
template <>
|
||||
void FrameBoundExpressionRow<uint64_t>::getOffset()
|
||||
{
|
||||
fOffset = fRow.getUintField(fExprIdx);
|
||||
fOffset = fRow.getUintField(fExprIdx);
|
||||
}
|
||||
|
||||
|
||||
template<> void FrameBoundExpressionRow<double>::getOffset()
|
||||
template <>
|
||||
void FrameBoundExpressionRow<double>::getOffset()
|
||||
{
|
||||
fOffset = (int64_t) fRow.getDoubleField(fExprIdx);
|
||||
fOffset = (int64_t)fRow.getDoubleField(fExprIdx);
|
||||
}
|
||||
|
||||
|
||||
template<> void FrameBoundExpressionRow<float>::getOffset()
|
||||
template <>
|
||||
void FrameBoundExpressionRow<float>::getOffset()
|
||||
{
|
||||
fOffset = (int64_t) fRow.getFloatField(fExprIdx);
|
||||
fOffset = (int64_t)fRow.getFloatField(fExprIdx);
|
||||
}
|
||||
|
||||
|
||||
template class FrameBoundExpressionRow<int64_t>;
|
||||
template class FrameBoundExpressionRow<double>;
|
||||
template class FrameBoundExpressionRow<float>;
|
||||
template class FrameBoundExpressionRow<uint64_t>;
|
||||
|
||||
|
||||
} //namespace
|
||||
} // namespace windowfunction
|
||||
// vim:ts=4 sw=4:
|
||||
|
||||
|
@ -17,152 +17,133 @@
|
||||
|
||||
// $Id: frameboundrow.h 3868 2013-06-06 22:13:05Z xlou $
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "framebound.h"
|
||||
|
||||
|
||||
namespace windowfunction
|
||||
{
|
||||
|
||||
|
||||
/** @brief class FrameBoundRow
|
||||
*
|
||||
*/
|
||||
class FrameBoundRow : public FrameBound
|
||||
{
|
||||
public:
|
||||
/** @brief FrameBoundRow constructor
|
||||
* @param t, frame type
|
||||
*/
|
||||
FrameBoundRow(int t = 0) : FrameBound(t) {};
|
||||
public:
|
||||
/** @brief FrameBoundRow constructor
|
||||
* @param t, frame type
|
||||
*/
|
||||
FrameBoundRow(int t = 0) : FrameBound(t){};
|
||||
|
||||
/** @brief FrameBoundRow destructor
|
||||
*/
|
||||
virtual ~FrameBoundRow() {};
|
||||
/** @brief FrameBoundRow destructor
|
||||
*/
|
||||
virtual ~FrameBoundRow(){};
|
||||
|
||||
/** @brief clone
|
||||
*/
|
||||
virtual FrameBound* clone()
|
||||
{
|
||||
return new FrameBoundRow(*this);
|
||||
}
|
||||
/** @brief clone
|
||||
*/
|
||||
virtual FrameBound* clone()
|
||||
{
|
||||
return new FrameBoundRow(*this);
|
||||
}
|
||||
|
||||
/** @brief virtual void getBound
|
||||
*/
|
||||
int64_t getBound(int64_t, int64_t, int64_t);
|
||||
/** @brief virtual void getBound
|
||||
*/
|
||||
int64_t getBound(int64_t, int64_t, int64_t);
|
||||
|
||||
const std::string toString() const;
|
||||
|
||||
|
||||
protected:
|
||||
const std::string toString() const;
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
|
||||
/** @brief class FrameBoundConstantRow
|
||||
*
|
||||
*/
|
||||
class FrameBoundConstantRow : public FrameBoundRow
|
||||
{
|
||||
public:
|
||||
/** @brief FrameBoundConstant constructor
|
||||
* @param t, frame type
|
||||
* @param c, constant value. !! caller need to check NULL or negative value !!
|
||||
*/
|
||||
FrameBoundConstantRow(int t = 0, int c = 0) : FrameBoundRow(t), fOffset(c) {};
|
||||
public:
|
||||
/** @brief FrameBoundConstant constructor
|
||||
* @param t, frame type
|
||||
* @param c, constant value. !! caller need to check NULL or negative value !!
|
||||
*/
|
||||
FrameBoundConstantRow(int t = 0, int c = 0) : FrameBoundRow(t), fOffset(c){};
|
||||
|
||||
/** @brief FrameBoundConstantRow destructor
|
||||
*/
|
||||
virtual ~FrameBoundConstantRow() {};
|
||||
/** @brief FrameBoundConstantRow destructor
|
||||
*/
|
||||
virtual ~FrameBoundConstantRow(){};
|
||||
|
||||
/** @brief clone
|
||||
*/
|
||||
virtual FrameBound* clone()
|
||||
{
|
||||
return new FrameBoundConstantRow(*this);
|
||||
}
|
||||
/** @brief clone
|
||||
*/
|
||||
virtual FrameBound* clone()
|
||||
{
|
||||
return new FrameBoundConstantRow(*this);
|
||||
}
|
||||
|
||||
/** @brief virtual void getBound
|
||||
*/
|
||||
int64_t getBound(int64_t, int64_t, int64_t);
|
||||
/** @brief virtual void getBound
|
||||
*/
|
||||
int64_t getBound(int64_t, int64_t, int64_t);
|
||||
|
||||
const std::string toString() const;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// constant offset
|
||||
int64_t fOffset;
|
||||
const std::string toString() const;
|
||||
|
||||
protected:
|
||||
// constant offset
|
||||
int64_t fOffset;
|
||||
};
|
||||
|
||||
|
||||
/** @brief class FrameBoundExpressionRow
|
||||
*
|
||||
*/
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
class FrameBoundExpressionRow : public FrameBoundConstantRow
|
||||
{
|
||||
public:
|
||||
/** @brief FrameBoundExpressionRow constructor
|
||||
* @param t, frame type
|
||||
*/
|
||||
FrameBoundExpressionRow(int t, uint64_t id = -1, int idx = -1) :
|
||||
FrameBoundConstantRow(t), fExprTupleId(id), fExprIdx(idx) {};
|
||||
public:
|
||||
/** @brief FrameBoundExpressionRow constructor
|
||||
* @param t, frame type
|
||||
*/
|
||||
FrameBoundExpressionRow(int t, uint64_t id = -1, int idx = -1)
|
||||
: FrameBoundConstantRow(t), fExprTupleId(id), fExprIdx(idx){};
|
||||
|
||||
/** @brief FrameBoundExpressionRow destructor
|
||||
*/
|
||||
virtual ~FrameBoundExpressionRow() {};
|
||||
/** @brief FrameBoundExpressionRow destructor
|
||||
*/
|
||||
virtual ~FrameBoundExpressionRow(){};
|
||||
|
||||
/** @brief clone
|
||||
*/
|
||||
virtual FrameBound* clone()
|
||||
{
|
||||
return new FrameBoundExpressionRow<T>(*this);
|
||||
}
|
||||
/** @brief clone
|
||||
*/
|
||||
virtual FrameBound* clone()
|
||||
{
|
||||
return new FrameBoundExpressionRow<T>(*this);
|
||||
}
|
||||
|
||||
/** @brief virtual void getBound
|
||||
*/
|
||||
int64_t getBound(int64_t, int64_t, int64_t);
|
||||
/** @brief virtual void getBound
|
||||
*/
|
||||
int64_t getBound(int64_t, int64_t, int64_t);
|
||||
|
||||
const std::string toString() const;
|
||||
const std::string toString() const;
|
||||
|
||||
void setExprTupleId(int id)
|
||||
{
|
||||
fExprTupleId = id;
|
||||
}
|
||||
uint64_t getExprTupleId() const
|
||||
{
|
||||
return fExprTupleId;
|
||||
}
|
||||
void setExprTupleId(int id)
|
||||
{
|
||||
fExprTupleId = id;
|
||||
}
|
||||
uint64_t getExprTupleId() const
|
||||
{
|
||||
return fExprTupleId;
|
||||
}
|
||||
|
||||
void setExprIndex(int i)
|
||||
{
|
||||
fExprIdx = i;
|
||||
}
|
||||
uint64_t getExprIndex() const
|
||||
{
|
||||
return fExprIdx;
|
||||
}
|
||||
void setExprIndex(int i)
|
||||
{
|
||||
fExprIdx = i;
|
||||
}
|
||||
uint64_t getExprIndex() const
|
||||
{
|
||||
return fExprIdx;
|
||||
}
|
||||
|
||||
protected:
|
||||
void getOffset();
|
||||
|
||||
protected:
|
||||
|
||||
void getOffset();
|
||||
|
||||
// id and index in row
|
||||
uint64_t fExprTupleId;
|
||||
int fExprIdx;
|
||||
|
||||
// id and index in row
|
||||
uint64_t fExprTupleId;
|
||||
int fExprIdx;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace windowfunction
|
||||
|
||||
// vim:ts=4 sw=4:
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -18,7 +18,6 @@
|
||||
|
||||
// $Id: idborderby.h 4012 2013-07-24 21:04:45Z pleblanc $
|
||||
|
||||
|
||||
/** @file */
|
||||
|
||||
#pragma once
|
||||
@ -43,31 +42,38 @@
|
||||
// forward reference
|
||||
namespace joblist
|
||||
{
|
||||
class ResourceManager;
|
||||
class ResourceManager;
|
||||
}
|
||||
|
||||
|
||||
namespace ordering
|
||||
{
|
||||
|
||||
template<typename _Tp, typename _Sequence = std::vector<_Tp>,
|
||||
typename _Compare = std::less<typename _Sequence::value_type> >
|
||||
class reservablePQ: private std::priority_queue<_Tp, _Sequence, _Compare>
|
||||
template <typename _Tp, typename _Sequence = std::vector<_Tp>,
|
||||
typename _Compare = std::less<typename _Sequence::value_type> >
|
||||
class reservablePQ : private std::priority_queue<_Tp, _Sequence, _Compare>
|
||||
{
|
||||
public:
|
||||
typedef typename std::priority_queue<_Tp, _Sequence, _Compare>::size_type size_type;
|
||||
reservablePQ(size_type capacity = 0) { reserve(capacity); };
|
||||
void reserve(size_type capacity) { this->c.reserve(capacity); }
|
||||
size_type capacity() const { return this->c.capacity(); }
|
||||
using std::priority_queue<_Tp, _Sequence, _Compare>::size;
|
||||
using std::priority_queue<_Tp, _Sequence, _Compare>::top;
|
||||
using std::priority_queue<_Tp, _Sequence, _Compare>::pop;
|
||||
using std::priority_queue<_Tp, _Sequence, _Compare>::push;
|
||||
using std::priority_queue<_Tp, _Sequence, _Compare>::empty;
|
||||
public:
|
||||
typedef typename std::priority_queue<_Tp, _Sequence, _Compare>::size_type size_type;
|
||||
reservablePQ(size_type capacity = 0)
|
||||
{
|
||||
reserve(capacity);
|
||||
};
|
||||
void reserve(size_type capacity)
|
||||
{
|
||||
this->c.reserve(capacity);
|
||||
}
|
||||
size_type capacity() const
|
||||
{
|
||||
return this->c.capacity();
|
||||
}
|
||||
using std::priority_queue<_Tp, _Sequence, _Compare>::size;
|
||||
using std::priority_queue<_Tp, _Sequence, _Compare>::top;
|
||||
using std::priority_queue<_Tp, _Sequence, _Compare>::pop;
|
||||
using std::priority_queue<_Tp, _Sequence, _Compare>::push;
|
||||
using std::priority_queue<_Tp, _Sequence, _Compare>::empty;
|
||||
};
|
||||
|
||||
// forward reference
|
||||
class IdbCompare;
|
||||
class IdbCompare;
|
||||
class OrderByRow;
|
||||
|
||||
typedef reservablePQ<OrderByRow> SortingPQ;
|
||||
@ -75,80 +81,97 @@ typedef reservablePQ<OrderByRow> SortingPQ;
|
||||
// order by specification
|
||||
struct IdbSortSpec
|
||||
{
|
||||
int fIndex;
|
||||
// TODO There are three ordering specs since 10.2
|
||||
int fAsc; // <ordering specification> ::= ASC | DESC
|
||||
int fNf; // <null ordering> ::= NULLS FIRST | NULLS LAST
|
||||
int fIndex;
|
||||
// TODO There are three ordering specs since 10.2
|
||||
int fAsc; // <ordering specification> ::= ASC | DESC
|
||||
int fNf; // <null ordering> ::= NULLS FIRST | NULLS LAST
|
||||
|
||||
IdbSortSpec() : fIndex(-1), fAsc(1), fNf(1) {}
|
||||
IdbSortSpec(int i, bool b) : fIndex(i), fAsc(b ? 1 : -1), fNf(fAsc) {}
|
||||
IdbSortSpec(int i, bool b, bool n) : fIndex(i), fAsc(b ? 1 : -1), fNf(n ? 1 : -1) {}
|
||||
IdbSortSpec() : fIndex(-1), fAsc(1), fNf(1)
|
||||
{
|
||||
}
|
||||
IdbSortSpec(int i, bool b) : fIndex(i), fAsc(b ? 1 : -1), fNf(fAsc)
|
||||
{
|
||||
}
|
||||
IdbSortSpec(int i, bool b, bool n) : fIndex(i), fAsc(b ? 1 : -1), fNf(n ? 1 : -1)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// compare functor for different datatypes
|
||||
// cannot use template because Row's getXxxField method.
|
||||
class Compare
|
||||
{
|
||||
public:
|
||||
Compare(const IdbSortSpec& spec) : fSpec(spec) {}
|
||||
virtual ~Compare() {}
|
||||
public:
|
||||
Compare(const IdbSortSpec& spec) : fSpec(spec)
|
||||
{
|
||||
}
|
||||
virtual ~Compare()
|
||||
{
|
||||
}
|
||||
|
||||
virtual int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer) = 0;
|
||||
void revertSortSpec()
|
||||
{
|
||||
fSpec.fAsc = -fSpec.fAsc;
|
||||
fSpec.fNf = -fSpec.fNf;
|
||||
}
|
||||
virtual int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer) = 0;
|
||||
void revertSortSpec()
|
||||
{
|
||||
fSpec.fAsc = -fSpec.fAsc;
|
||||
fSpec.fNf = -fSpec.fNf;
|
||||
}
|
||||
|
||||
protected:
|
||||
IdbSortSpec fSpec;
|
||||
protected:
|
||||
IdbSortSpec fSpec;
|
||||
};
|
||||
|
||||
// Comparators for signed types
|
||||
|
||||
class TinyIntCompare : public Compare
|
||||
{
|
||||
public:
|
||||
TinyIntCompare(const IdbSortSpec& spec) : Compare(spec) {}
|
||||
public:
|
||||
TinyIntCompare(const IdbSortSpec& spec) : Compare(spec)
|
||||
{
|
||||
}
|
||||
|
||||
int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
|
||||
int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
|
||||
};
|
||||
|
||||
|
||||
class SmallIntCompare : public Compare
|
||||
{
|
||||
public:
|
||||
SmallIntCompare(const IdbSortSpec& spec) : Compare(spec) {}
|
||||
public:
|
||||
SmallIntCompare(const IdbSortSpec& spec) : Compare(spec)
|
||||
{
|
||||
}
|
||||
|
||||
int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
|
||||
int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
|
||||
};
|
||||
|
||||
|
||||
class IntCompare : public Compare
|
||||
{
|
||||
public:
|
||||
IntCompare(const IdbSortSpec& spec) : Compare(spec) {}
|
||||
public:
|
||||
IntCompare(const IdbSortSpec& spec) : Compare(spec)
|
||||
{
|
||||
}
|
||||
|
||||
int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
|
||||
int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
|
||||
};
|
||||
|
||||
|
||||
class BigIntCompare : public Compare
|
||||
{
|
||||
public:
|
||||
BigIntCompare(const IdbSortSpec& spec) : Compare(spec) {}
|
||||
public:
|
||||
BigIntCompare(const IdbSortSpec& spec) : Compare(spec)
|
||||
{
|
||||
}
|
||||
|
||||
int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
|
||||
int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
|
||||
};
|
||||
|
||||
class WideDecimalCompare : public Compare
|
||||
{
|
||||
int keyColumnOffset;
|
||||
public:
|
||||
WideDecimalCompare(const IdbSortSpec& spec, int offset) : Compare(spec), keyColumnOffset(offset) { }
|
||||
int keyColumnOffset;
|
||||
|
||||
int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
|
||||
public:
|
||||
WideDecimalCompare(const IdbSortSpec& spec, int offset) : Compare(spec), keyColumnOffset(offset)
|
||||
{
|
||||
}
|
||||
|
||||
int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
|
||||
};
|
||||
|
||||
// End of comparators for signed types
|
||||
@ -156,37 +179,42 @@ public:
|
||||
|
||||
class UTinyIntCompare : public Compare
|
||||
{
|
||||
public:
|
||||
UTinyIntCompare(const IdbSortSpec& spec) : Compare(spec) {}
|
||||
public:
|
||||
UTinyIntCompare(const IdbSortSpec& spec) : Compare(spec)
|
||||
{
|
||||
}
|
||||
|
||||
int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
|
||||
int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
|
||||
};
|
||||
|
||||
|
||||
class USmallIntCompare : public Compare
|
||||
{
|
||||
public:
|
||||
USmallIntCompare(const IdbSortSpec& spec) : Compare(spec) {}
|
||||
public:
|
||||
USmallIntCompare(const IdbSortSpec& spec) : Compare(spec)
|
||||
{
|
||||
}
|
||||
|
||||
int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
|
||||
int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
|
||||
};
|
||||
|
||||
|
||||
class UIntCompare : public Compare
|
||||
{
|
||||
public:
|
||||
UIntCompare(const IdbSortSpec& spec) : Compare(spec) {}
|
||||
public:
|
||||
UIntCompare(const IdbSortSpec& spec) : Compare(spec)
|
||||
{
|
||||
}
|
||||
|
||||
int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
|
||||
int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
|
||||
};
|
||||
|
||||
|
||||
class UBigIntCompare : public Compare
|
||||
{
|
||||
public:
|
||||
UBigIntCompare(const IdbSortSpec& spec) : Compare(spec) {}
|
||||
public:
|
||||
UBigIntCompare(const IdbSortSpec& spec) : Compare(spec)
|
||||
{
|
||||
}
|
||||
|
||||
int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
|
||||
int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
|
||||
};
|
||||
|
||||
// end of comparators for unsigned types
|
||||
@ -195,28 +223,32 @@ public:
|
||||
|
||||
class DoubleCompare : public Compare
|
||||
{
|
||||
public:
|
||||
DoubleCompare(const IdbSortSpec& spec) : Compare(spec) {}
|
||||
public:
|
||||
DoubleCompare(const IdbSortSpec& spec) : Compare(spec)
|
||||
{
|
||||
}
|
||||
|
||||
int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
|
||||
int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
|
||||
};
|
||||
|
||||
|
||||
class LongDoubleCompare : public Compare
|
||||
{
|
||||
public:
|
||||
LongDoubleCompare(const IdbSortSpec& spec) : Compare(spec) {}
|
||||
public:
|
||||
LongDoubleCompare(const IdbSortSpec& spec) : Compare(spec)
|
||||
{
|
||||
}
|
||||
|
||||
int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
|
||||
int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
|
||||
};
|
||||
|
||||
|
||||
class FloatCompare : public Compare
|
||||
{
|
||||
public:
|
||||
FloatCompare(const IdbSortSpec& spec) : Compare(spec) {}
|
||||
public:
|
||||
FloatCompare(const IdbSortSpec& spec) : Compare(spec)
|
||||
{
|
||||
}
|
||||
|
||||
int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
|
||||
int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
|
||||
};
|
||||
|
||||
// End of comparators for float types
|
||||
@ -224,28 +256,32 @@ public:
|
||||
|
||||
class DateCompare : public Compare
|
||||
{
|
||||
public:
|
||||
DateCompare(const IdbSortSpec& spec) : Compare(spec) {}
|
||||
public:
|
||||
DateCompare(const IdbSortSpec& spec) : Compare(spec)
|
||||
{
|
||||
}
|
||||
|
||||
int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
|
||||
int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
|
||||
};
|
||||
|
||||
|
||||
class DatetimeCompare : public Compare
|
||||
{
|
||||
public:
|
||||
DatetimeCompare(const IdbSortSpec& spec) : Compare(spec) {}
|
||||
public:
|
||||
DatetimeCompare(const IdbSortSpec& spec) : Compare(spec)
|
||||
{
|
||||
}
|
||||
|
||||
int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
|
||||
int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
|
||||
};
|
||||
|
||||
|
||||
class TimeCompare : public Compare
|
||||
{
|
||||
public:
|
||||
TimeCompare(const IdbSortSpec& spec) : Compare(spec) {}
|
||||
public:
|
||||
TimeCompare(const IdbSortSpec& spec) : Compare(spec)
|
||||
{
|
||||
}
|
||||
|
||||
int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
|
||||
int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
|
||||
};
|
||||
|
||||
// End of comparators for temporal types
|
||||
@ -254,184 +290,189 @@ public:
|
||||
|
||||
class StringCompare : public Compare
|
||||
{
|
||||
public:
|
||||
StringCompare(const IdbSortSpec& spec) : Compare(spec), cs(NULL) {}
|
||||
public:
|
||||
StringCompare(const IdbSortSpec& spec) : Compare(spec), cs(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
|
||||
|
||||
CHARSET_INFO* cs;
|
||||
int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer);
|
||||
|
||||
CHARSET_INFO* cs;
|
||||
};
|
||||
|
||||
// End of comparators for variable sized types
|
||||
|
||||
class CompareRule
|
||||
{
|
||||
public:
|
||||
CompareRule(IdbCompare* c = NULL) : fIdbCompare(c) {}
|
||||
public:
|
||||
CompareRule(IdbCompare* c = NULL) : fIdbCompare(c)
|
||||
{
|
||||
}
|
||||
|
||||
bool less(rowgroup::Row::Pointer r1, rowgroup::Row::Pointer r2);
|
||||
|
||||
bool less(rowgroup::Row::Pointer r1, rowgroup::Row::Pointer r2);
|
||||
void compileRules(const std::vector<IdbSortSpec>&, const rowgroup::RowGroup&);
|
||||
void revertRules();
|
||||
|
||||
void compileRules(const std::vector<IdbSortSpec>&, const rowgroup::RowGroup&);
|
||||
void revertRules();
|
||||
|
||||
std::vector<Compare*> fCompares;
|
||||
IdbCompare* fIdbCompare;
|
||||
std::vector<Compare*> fCompares;
|
||||
IdbCompare* fIdbCompare;
|
||||
};
|
||||
|
||||
|
||||
class IdbCompare
|
||||
{
|
||||
public:
|
||||
IdbCompare() {};
|
||||
virtual ~IdbCompare() {};
|
||||
public:
|
||||
IdbCompare(){};
|
||||
virtual ~IdbCompare(){};
|
||||
|
||||
virtual void initialize(const rowgroup::RowGroup&);
|
||||
void setStringTable(bool b);
|
||||
virtual void initialize(const rowgroup::RowGroup&);
|
||||
void setStringTable(bool b);
|
||||
|
||||
rowgroup::Row& row1()
|
||||
{
|
||||
return fRow1;
|
||||
}
|
||||
rowgroup::Row& row2()
|
||||
{
|
||||
return fRow2;
|
||||
}
|
||||
rowgroup::Row& row1()
|
||||
{
|
||||
return fRow1;
|
||||
}
|
||||
rowgroup::Row& row2()
|
||||
{
|
||||
return fRow2;
|
||||
}
|
||||
|
||||
rowgroup::RowGroup* rowGroup()
|
||||
{
|
||||
return &fRowGroup;
|
||||
}
|
||||
protected:
|
||||
rowgroup::RowGroup fRowGroup;
|
||||
rowgroup::Row fRow1;
|
||||
rowgroup::Row fRow2;
|
||||
rowgroup::RowGroup* rowGroup()
|
||||
{
|
||||
return &fRowGroup;
|
||||
}
|
||||
|
||||
protected:
|
||||
rowgroup::RowGroup fRowGroup;
|
||||
rowgroup::Row fRow1;
|
||||
rowgroup::Row fRow2;
|
||||
};
|
||||
|
||||
|
||||
class OrderByRow
|
||||
{
|
||||
public:
|
||||
OrderByRow(const rowgroup::Row& r, CompareRule& c) : fData(r.getPointer()), fRule(&c) {}
|
||||
public:
|
||||
OrderByRow(const rowgroup::Row& r, CompareRule& c) : fData(r.getPointer()), fRule(&c)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator < (const OrderByRow& rhs) const
|
||||
{
|
||||
return fRule->less(fData, rhs.fData);
|
||||
}
|
||||
bool operator<(const OrderByRow& rhs) const
|
||||
{
|
||||
return fRule->less(fData, rhs.fData);
|
||||
}
|
||||
|
||||
rowgroup::Row::Pointer fData;
|
||||
CompareRule* fRule;
|
||||
rowgroup::Row::Pointer fData;
|
||||
CompareRule* fRule;
|
||||
};
|
||||
|
||||
|
||||
class EqualCompData : public IdbCompare
|
||||
{
|
||||
public:
|
||||
EqualCompData(std::vector<uint64_t>& v) : fIndex(v) {}
|
||||
EqualCompData(std::vector<uint64_t>& v, const rowgroup::RowGroup& rg) :
|
||||
fIndex(v)
|
||||
{
|
||||
initialize(rg);
|
||||
}
|
||||
public:
|
||||
EqualCompData(std::vector<uint64_t>& v) : fIndex(v)
|
||||
{
|
||||
}
|
||||
EqualCompData(std::vector<uint64_t>& v, const rowgroup::RowGroup& rg) : fIndex(v)
|
||||
{
|
||||
initialize(rg);
|
||||
}
|
||||
|
||||
~EqualCompData() {};
|
||||
~EqualCompData(){};
|
||||
|
||||
bool operator()(rowgroup::Row::Pointer, rowgroup::Row::Pointer);
|
||||
bool operator()(rowgroup::Row::Pointer, rowgroup::Row::Pointer);
|
||||
|
||||
std::vector<uint64_t> fIndex;
|
||||
std::vector<uint64_t> fIndex;
|
||||
};
|
||||
|
||||
|
||||
class OrderByData : public IdbCompare
|
||||
{
|
||||
public:
|
||||
OrderByData(const std::vector<IdbSortSpec>&, const rowgroup::RowGroup&);
|
||||
virtual ~OrderByData();
|
||||
public:
|
||||
OrderByData(const std::vector<IdbSortSpec>&, const rowgroup::RowGroup&);
|
||||
virtual ~OrderByData();
|
||||
|
||||
bool operator() (rowgroup::Row::Pointer p1, rowgroup::Row::Pointer p2)
|
||||
{
|
||||
return fRule.less(p1, p2);
|
||||
}
|
||||
const CompareRule& rule() const
|
||||
{
|
||||
return fRule;
|
||||
}
|
||||
bool operator()(rowgroup::Row::Pointer p1, rowgroup::Row::Pointer p2)
|
||||
{
|
||||
return fRule.less(p1, p2);
|
||||
}
|
||||
const CompareRule& rule() const
|
||||
{
|
||||
return fRule;
|
||||
}
|
||||
|
||||
protected:
|
||||
CompareRule fRule;
|
||||
protected:
|
||||
CompareRule fRule;
|
||||
};
|
||||
|
||||
|
||||
// base classs for order by clause used in IDB
|
||||
class IdbOrderBy : public IdbCompare
|
||||
{
|
||||
public:
|
||||
IdbOrderBy();
|
||||
virtual ~IdbOrderBy();
|
||||
public:
|
||||
IdbOrderBy();
|
||||
virtual ~IdbOrderBy();
|
||||
|
||||
virtual void initialize(const rowgroup::RowGroup&);
|
||||
virtual void processRow(const rowgroup::Row&) = 0;
|
||||
virtual uint64_t getKeyLength() const = 0;
|
||||
virtual const std::string toString() const = 0;
|
||||
virtual void initialize(const rowgroup::RowGroup&);
|
||||
virtual void processRow(const rowgroup::Row&) = 0;
|
||||
virtual uint64_t getKeyLength() const = 0;
|
||||
virtual const std::string toString() const = 0;
|
||||
|
||||
bool getData(rowgroup::RGData& data);
|
||||
bool getData(rowgroup::RGData& data);
|
||||
|
||||
void distinct(bool b)
|
||||
void distinct(bool b)
|
||||
{
|
||||
fDistinct = b;
|
||||
}
|
||||
bool distinct() const
|
||||
{
|
||||
return fDistinct;
|
||||
}
|
||||
SortingPQ& getQueue()
|
||||
{
|
||||
return fOrderByQueue;
|
||||
}
|
||||
CompareRule& getRule()
|
||||
{
|
||||
return fRule;
|
||||
}
|
||||
|
||||
SortingPQ fOrderByQueue;
|
||||
|
||||
protected:
|
||||
std::vector<IdbSortSpec> fOrderByCond;
|
||||
rowgroup::Row fRow0;
|
||||
CompareRule fRule;
|
||||
|
||||
rowgroup::RGData fData;
|
||||
std::queue<rowgroup::RGData> fDataQueue;
|
||||
|
||||
struct Hasher
|
||||
{
|
||||
IdbOrderBy* ts;
|
||||
utils::Hasher_r h;
|
||||
uint32_t colCount;
|
||||
Hasher(IdbOrderBy* t, uint32_t c) : ts(t), colCount(c)
|
||||
{
|
||||
fDistinct = b;
|
||||
}
|
||||
bool distinct() const
|
||||
uint64_t operator()(const rowgroup::Row::Pointer&) const;
|
||||
};
|
||||
struct Eq
|
||||
{
|
||||
IdbOrderBy* ts;
|
||||
uint32_t colCount;
|
||||
Eq(IdbOrderBy* t, uint32_t c) : ts(t), colCount(c)
|
||||
{
|
||||
return fDistinct;
|
||||
}
|
||||
SortingPQ& getQueue()
|
||||
{
|
||||
return fOrderByQueue;
|
||||
}
|
||||
CompareRule &getRule()
|
||||
{
|
||||
return fRule;
|
||||
}
|
||||
bool operator()(const rowgroup::Row::Pointer&, const rowgroup::Row::Pointer&) const;
|
||||
};
|
||||
|
||||
SortingPQ fOrderByQueue;
|
||||
protected:
|
||||
std::vector<IdbSortSpec> fOrderByCond;
|
||||
rowgroup::Row fRow0;
|
||||
CompareRule fRule;
|
||||
typedef std::tr1::unordered_set<rowgroup::Row::Pointer, Hasher, Eq,
|
||||
utils::STLPoolAllocator<rowgroup::Row::Pointer> >
|
||||
DistinctMap_t;
|
||||
boost::scoped_ptr<DistinctMap_t> fDistinctMap;
|
||||
rowgroup::Row row1, row2; // scratch space for Hasher & Eq
|
||||
|
||||
rowgroup::RGData fData;
|
||||
std::queue<rowgroup::RGData> fDataQueue;
|
||||
|
||||
struct Hasher
|
||||
{
|
||||
IdbOrderBy* ts;
|
||||
utils::Hasher_r h;
|
||||
uint32_t colCount;
|
||||
Hasher(IdbOrderBy* t, uint32_t c) : ts(t), colCount(c) { }
|
||||
uint64_t operator()(const rowgroup::Row::Pointer&) const;
|
||||
};
|
||||
struct Eq
|
||||
{
|
||||
IdbOrderBy* ts;
|
||||
uint32_t colCount;
|
||||
Eq(IdbOrderBy* t, uint32_t c) : ts(t), colCount(c) { }
|
||||
bool operator()(const rowgroup::Row::Pointer&, const rowgroup::Row::Pointer&) const;
|
||||
};
|
||||
|
||||
typedef std::tr1::unordered_set<rowgroup::Row::Pointer, Hasher, Eq,
|
||||
utils::STLPoolAllocator<rowgroup::Row::Pointer> > DistinctMap_t;
|
||||
boost::scoped_ptr<DistinctMap_t> fDistinctMap;
|
||||
rowgroup::Row row1, row2; // scratch space for Hasher & Eq
|
||||
|
||||
bool fDistinct;
|
||||
uint64_t fMemSize;
|
||||
uint64_t fRowsPerRG;
|
||||
uint64_t fErrorCode;
|
||||
joblist::ResourceManager* fRm;
|
||||
boost::shared_ptr<int64_t> fSessionMemLimit;
|
||||
bool fDistinct;
|
||||
uint64_t fMemSize;
|
||||
uint64_t fRowsPerRG;
|
||||
uint64_t fErrorCode;
|
||||
joblist::ResourceManager* fRm;
|
||||
boost::shared_ptr<int64_t> fSessionMemLimit;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
} // namespace ordering
|
||||
|
@ -17,7 +17,6 @@
|
||||
|
||||
// $Id: wf_count.cpp 3932 2013-06-25 16:08:10Z xlou $
|
||||
|
||||
|
||||
//#define NDEBUG
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
@ -49,150 +48,140 @@ using namespace joblist;
|
||||
|
||||
#include "wf_count.h"
|
||||
|
||||
|
||||
namespace windowfunction
|
||||
{
|
||||
|
||||
|
||||
template<typename T>
|
||||
boost::shared_ptr<WindowFunctionType> WF_count<T>::makeFunction(int id, const string& name, int ct, WindowFunctionColumn* wc)
|
||||
template <typename T>
|
||||
boost::shared_ptr<WindowFunctionType> WF_count<T>::makeFunction(int id, const string& name, int ct,
|
||||
WindowFunctionColumn* wc)
|
||||
{
|
||||
boost::shared_ptr<WindowFunctionType> func;
|
||||
boost::shared_ptr<WindowFunctionType> func;
|
||||
|
||||
switch (ct)
|
||||
switch (ct)
|
||||
{
|
||||
case CalpontSystemCatalog::CHAR:
|
||||
case CalpontSystemCatalog::VARCHAR:
|
||||
case CalpontSystemCatalog::VARBINARY:
|
||||
{
|
||||
case CalpontSystemCatalog::CHAR:
|
||||
case CalpontSystemCatalog::VARCHAR:
|
||||
case CalpontSystemCatalog::VARBINARY:
|
||||
{
|
||||
func.reset(new WF_count<string>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::DECIMAL:
|
||||
case CalpontSystemCatalog::UDECIMAL:
|
||||
{
|
||||
decltype(datatypes::MAXDECIMALWIDTH) width =
|
||||
wc->functionParms()[0]->resultType().colWidth;
|
||||
if (width < datatypes::MAXDECIMALWIDTH)
|
||||
{
|
||||
func.reset(new WF_count<int64_t>(id, name));
|
||||
}
|
||||
else if (width == datatypes::MAXDECIMALWIDTH)
|
||||
{
|
||||
func.reset(new WF_count<int128_t>(id, name));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
func.reset(new WF_count<int64_t>(id, name));
|
||||
break;
|
||||
}
|
||||
func.reset(new WF_count<string>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
return func;
|
||||
case CalpontSystemCatalog::DECIMAL:
|
||||
case CalpontSystemCatalog::UDECIMAL:
|
||||
{
|
||||
decltype(datatypes::MAXDECIMALWIDTH) width = wc->functionParms()[0]->resultType().colWidth;
|
||||
if (width < datatypes::MAXDECIMALWIDTH)
|
||||
{
|
||||
func.reset(new WF_count<int64_t>(id, name));
|
||||
}
|
||||
else if (width == datatypes::MAXDECIMALWIDTH)
|
||||
{
|
||||
func.reset(new WF_count<int128_t>(id, name));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
func.reset(new WF_count<int64_t>(id, name));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return func;
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
WindowFunctionType* WF_count<T>::clone() const
|
||||
{
|
||||
return new WF_count(*this);
|
||||
return new WF_count(*this);
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
void WF_count<T>::resetData()
|
||||
{
|
||||
fCount = 0;
|
||||
fSet.clear();
|
||||
fCount = 0;
|
||||
fSet.clear();
|
||||
|
||||
WindowFunctionType::resetData();
|
||||
WindowFunctionType::resetData();
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
void WF_count<T>::operator()(int64_t b, int64_t e, int64_t c)
|
||||
{
|
||||
if ((fFrameUnit == WF__FRAME_ROWS) ||
|
||||
(fPrev == -1) ||
|
||||
(!fPeer->operator()(getPointer(fRowData->at(c)), getPointer(fRowData->at(fPrev)))))
|
||||
if ((fFrameUnit == WF__FRAME_ROWS) || (fPrev == -1) ||
|
||||
(!fPeer->operator()(getPointer(fRowData->at(c)), getPointer(fRowData->at(fPrev)))))
|
||||
{
|
||||
// for unbounded - current row special handling
|
||||
if (fPrev >= b && fPrev < c)
|
||||
b = c;
|
||||
else if (fPrev <= e && fPrev > c)
|
||||
e = c;
|
||||
|
||||
// for count(*), the column is optimized out, index[1] does not exist.
|
||||
int64_t colIn = (fFunctionId == WF__COUNT_ASTERISK) ? 0 : fFieldIndex[1];
|
||||
|
||||
// constant param will have fFieldIndex[1] of -1. Get value of constant param
|
||||
if (colIn == -1)
|
||||
{
|
||||
// for unbounded - current row special handling
|
||||
if (fPrev >= b && fPrev < c)
|
||||
b = c;
|
||||
else if (fPrev <= e && fPrev > c)
|
||||
e = c;
|
||||
ConstantColumn* cc = static_cast<ConstantColumn*>(fConstantParms[0].get());
|
||||
|
||||
// for count(*), the column is optimized out, index[1] does not exist.
|
||||
int64_t colIn = (fFunctionId == WF__COUNT_ASTERISK) ? 0 : fFieldIndex[1];
|
||||
if (cc)
|
||||
{
|
||||
bool isNull = false;
|
||||
cc->getIntVal(fRow, isNull);
|
||||
|
||||
// constant param will have fFieldIndex[1] of -1. Get value of constant param
|
||||
if (colIn == -1)
|
||||
if (!isNull)
|
||||
{
|
||||
ConstantColumn* cc = static_cast<ConstantColumn*>(fConstantParms[0].get());
|
||||
|
||||
if (cc)
|
||||
{
|
||||
bool isNull = false;
|
||||
cc->getIntVal(fRow, isNull);
|
||||
|
||||
if (!isNull)
|
||||
{
|
||||
// constant, set fCount to row count
|
||||
fCount += e - b + 1;
|
||||
}
|
||||
}
|
||||
// constant, set fCount to row count
|
||||
fCount += e - b + 1;
|
||||
}
|
||||
else if (fFunctionId == WF__COUNT_ASTERISK)
|
||||
}
|
||||
}
|
||||
else if (fFunctionId == WF__COUNT_ASTERISK)
|
||||
{
|
||||
// count(*), set fCount to row count
|
||||
fCount += e - b + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
|
||||
if (fFunctionId != WF__COUNT_DISTINCT)
|
||||
{
|
||||
// count(*), set fCount to row count
|
||||
fCount += e - b + 1;
|
||||
fCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int64_t i = b; i <= e; i++)
|
||||
{
|
||||
if (i % 1000 == 0 && fStep->cancelled())
|
||||
break;
|
||||
T valIn;
|
||||
getValue(colIn, valIn);
|
||||
|
||||
fRow.setData(getPointer(fRowData->at(i)));
|
||||
if (fSet.find(valIn) == fSet.end())
|
||||
{
|
||||
fCount++;
|
||||
|
||||
if (fRow.isNullValue(colIn) == true)
|
||||
continue;
|
||||
|
||||
if (fFunctionId != WF__COUNT_DISTINCT)
|
||||
{
|
||||
fCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
T valIn;
|
||||
getValue(colIn, valIn);
|
||||
|
||||
if (fSet.find(valIn) == fSet.end())
|
||||
{
|
||||
fCount++;
|
||||
|
||||
if (fFunctionId == WF__COUNT_DISTINCT)
|
||||
fSet.insert(valIn);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fFunctionId == WF__COUNT_DISTINCT)
|
||||
fSet.insert(valIn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setValue(CalpontSystemCatalog::BIGINT, b, e, c, &fCount);
|
||||
setValue(CalpontSystemCatalog::BIGINT, b, e, c, &fCount);
|
||||
|
||||
fPrev = c;
|
||||
fPrev = c;
|
||||
}
|
||||
|
||||
template boost::shared_ptr<WindowFunctionType> WF_count<int64_t>::makeFunction(int, const string&, int,
|
||||
WindowFunctionColumn*);
|
||||
|
||||
template
|
||||
boost::shared_ptr<WindowFunctionType> WF_count<int64_t>::makeFunction(int, const string&, int, WindowFunctionColumn*);
|
||||
|
||||
|
||||
} //namespace
|
||||
} // namespace windowfunction
|
||||
// vim:ts=4 sw=4:
|
||||
|
||||
|
@ -17,42 +17,34 @@
|
||||
|
||||
// $Id: wf_count.h 3868 2013-06-06 22:13:05Z xlou $
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
#include "windowfunctiontype.h"
|
||||
|
||||
|
||||
namespace windowfunction
|
||||
{
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
class WF_count : public WindowFunctionType
|
||||
{
|
||||
public:
|
||||
WF_count(int id, const std::string& name) : WindowFunctionType(id, name)
|
||||
{
|
||||
resetData();
|
||||
}
|
||||
public:
|
||||
WF_count(int id, const std::string& name) : WindowFunctionType(id, name)
|
||||
{
|
||||
resetData();
|
||||
}
|
||||
|
||||
// pure virtual in base
|
||||
void operator()(int64_t b, int64_t e, int64_t c);
|
||||
WindowFunctionType* clone() const;
|
||||
void resetData();
|
||||
// pure virtual in base
|
||||
void operator()(int64_t b, int64_t e, int64_t c);
|
||||
WindowFunctionType* clone() const;
|
||||
void resetData();
|
||||
|
||||
static boost::shared_ptr<WindowFunctionType> makeFunction(int, const string&, int, WindowFunctionColumn*);
|
||||
static boost::shared_ptr<WindowFunctionType> makeFunction(int, const string&, int, WindowFunctionColumn*);
|
||||
|
||||
protected:
|
||||
|
||||
uint64_t fCount;
|
||||
std::set<T> fSet;
|
||||
protected:
|
||||
uint64_t fCount;
|
||||
std::set<T> fSet;
|
||||
};
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace windowfunction
|
||||
|
||||
// vim:ts=4 sw=4:
|
||||
|
||||
|
@ -18,7 +18,6 @@
|
||||
|
||||
// $Id: wf_lead_lag.cpp 3932 2013-06-25 16:08:10Z xlou $
|
||||
|
||||
|
||||
//#define NDEBUG
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
@ -47,266 +46,257 @@ using namespace joblist;
|
||||
|
||||
#include "wf_lead_lag.h"
|
||||
|
||||
|
||||
namespace windowfunction
|
||||
{
|
||||
|
||||
|
||||
template<typename T>
|
||||
boost::shared_ptr<WindowFunctionType> WF_lead_lag<T>::makeFunction(int id, const string& name, int ct, WindowFunctionColumn* wc)
|
||||
template <typename T>
|
||||
boost::shared_ptr<WindowFunctionType> WF_lead_lag<T>::makeFunction(int id, const string& name, int ct,
|
||||
WindowFunctionColumn* wc)
|
||||
{
|
||||
boost::shared_ptr<WindowFunctionType> func;
|
||||
boost::shared_ptr<WindowFunctionType> func;
|
||||
|
||||
switch (ct)
|
||||
switch (ct)
|
||||
{
|
||||
case CalpontSystemCatalog::TINYINT:
|
||||
case CalpontSystemCatalog::SMALLINT:
|
||||
case CalpontSystemCatalog::MEDINT:
|
||||
case CalpontSystemCatalog::INT:
|
||||
case CalpontSystemCatalog::BIGINT:
|
||||
{
|
||||
case CalpontSystemCatalog::TINYINT:
|
||||
case CalpontSystemCatalog::SMALLINT:
|
||||
case CalpontSystemCatalog::MEDINT:
|
||||
case CalpontSystemCatalog::INT:
|
||||
case CalpontSystemCatalog::BIGINT:
|
||||
{
|
||||
func.reset(new WF_lead_lag<int64_t>(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_lead_lag<uint64_t>(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_lead_lag<uint64_t>(id, name));
|
||||
else
|
||||
func.reset(new WF_lead_lag<int64_t>(id, name));
|
||||
}
|
||||
else if (width == datatypes::MAXDECIMALWIDTH)
|
||||
{
|
||||
func.reset(new WF_lead_lag<int128_t>(id, name));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CalpontSystemCatalog::DOUBLE:
|
||||
case CalpontSystemCatalog::UDOUBLE:
|
||||
{
|
||||
func.reset(new WF_lead_lag<double>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::LONGDOUBLE:
|
||||
{
|
||||
func.reset(new WF_lead_lag<long double>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::FLOAT:
|
||||
case CalpontSystemCatalog::UFLOAT:
|
||||
{
|
||||
func.reset(new WF_lead_lag<float>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
func.reset(new WF_lead_lag<string>(id, name));
|
||||
break;
|
||||
}
|
||||
func.reset(new WF_lead_lag<int64_t>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
return func;
|
||||
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_lead_lag<uint64_t>(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_lead_lag<uint64_t>(id, name));
|
||||
else
|
||||
func.reset(new WF_lead_lag<int64_t>(id, name));
|
||||
}
|
||||
else if (width == datatypes::MAXDECIMALWIDTH)
|
||||
{
|
||||
func.reset(new WF_lead_lag<int128_t>(id, name));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CalpontSystemCatalog::DOUBLE:
|
||||
case CalpontSystemCatalog::UDOUBLE:
|
||||
{
|
||||
func.reset(new WF_lead_lag<double>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::LONGDOUBLE:
|
||||
{
|
||||
func.reset(new WF_lead_lag<long double>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::FLOAT:
|
||||
case CalpontSystemCatalog::UFLOAT:
|
||||
{
|
||||
func.reset(new WF_lead_lag<float>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
func.reset(new WF_lead_lag<string>(id, name));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return func;
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
WindowFunctionType* WF_lead_lag<T>::clone() const
|
||||
{
|
||||
return new WF_lead_lag<T>(*this);
|
||||
return new WF_lead_lag<T>(*this);
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
void WF_lead_lag<T>::resetData()
|
||||
{
|
||||
WindowFunctionType::resetData();
|
||||
WindowFunctionType::resetData();
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
void WF_lead_lag<T>::parseParms(const std::vector<execplan::SRCP>& parms)
|
||||
{
|
||||
// lead | lag
|
||||
fLead = 1;
|
||||
fRespectNulls = true;
|
||||
fDefNull = false;
|
||||
// fDefault = (T)0; // Won't work for std::string. Default should always be set below.
|
||||
// lead | lag
|
||||
fLead = 1;
|
||||
fRespectNulls = true;
|
||||
fDefNull = false;
|
||||
// fDefault = (T)0; // Won't work for std::string. Default should always be set below.
|
||||
fOffsetNull = false;
|
||||
fOffset = 0;
|
||||
|
||||
if (fFunctionId == WF__LAG)
|
||||
fLead = -1;
|
||||
|
||||
// parms[0]: value-expr
|
||||
// skip
|
||||
|
||||
// parms[1]: offset
|
||||
ConstantColumn* cc = dynamic_cast<ConstantColumn*>(parms[1].get());
|
||||
|
||||
if (cc != NULL)
|
||||
{
|
||||
fOffsetNull = false;
|
||||
fOffset = 0;
|
||||
fOffset = cc->getIntVal(fRow, fOffsetNull) * fLead; // row not used, no need to setData.
|
||||
}
|
||||
|
||||
if (fFunctionId == WF__LAG)
|
||||
fLead = -1;
|
||||
// parms[2]: default value
|
||||
cc = dynamic_cast<ConstantColumn*>(parms[2].get());
|
||||
|
||||
// parms[0]: value-expr
|
||||
// skip
|
||||
if (cc != NULL)
|
||||
{
|
||||
fDefNull = false;
|
||||
getConstValue(cc, fDefault, fDefNull);
|
||||
}
|
||||
|
||||
// parms[1]: offset
|
||||
ConstantColumn* cc = dynamic_cast<ConstantColumn*>(parms[1].get());
|
||||
|
||||
if (cc != NULL)
|
||||
{
|
||||
fOffsetNull = false;
|
||||
fOffset = cc->getIntVal(fRow, fOffsetNull) * fLead; // row not used, no need to setData.
|
||||
}
|
||||
|
||||
// parms[2]: default value
|
||||
cc = dynamic_cast<ConstantColumn*>(parms[2].get());
|
||||
|
||||
if (cc != NULL)
|
||||
{
|
||||
fDefNull = false;
|
||||
getConstValue(cc, fDefault, fDefNull);
|
||||
}
|
||||
|
||||
// parms[3]: respect null | ignore null
|
||||
cc = dynamic_cast<ConstantColumn*>(parms[3].get());
|
||||
if (cc != NULL)
|
||||
{
|
||||
bool isNull = false; // dummy. Return not used
|
||||
fRespectNulls = (cc->getIntVal(fRow, isNull) > 0);
|
||||
}
|
||||
// parms[3]: respect null | ignore null
|
||||
cc = dynamic_cast<ConstantColumn*>(parms[3].get());
|
||||
if (cc != NULL)
|
||||
{
|
||||
bool isNull = false; // dummy. Return not used
|
||||
fRespectNulls = (cc->getIntVal(fRow, isNull) > 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
void WF_lead_lag<T>::operator()(int64_t b, int64_t e, int64_t c)
|
||||
{
|
||||
uint64_t colIn = fFieldIndex[1];
|
||||
bool isNull = true;
|
||||
uint64_t colIn = fFieldIndex[1];
|
||||
bool isNull = true;
|
||||
|
||||
for (int64_t c = b; c <= e; c++)
|
||||
for (int64_t c = b; c <= e; c++)
|
||||
{
|
||||
if (c % 1000 == 0 && fStep->cancelled())
|
||||
break;
|
||||
|
||||
fRow.setData(getPointer(fRowData->at(c)));
|
||||
// get offset if not constant
|
||||
int64_t idx = fFieldIndex[2];
|
||||
|
||||
if (idx != -1)
|
||||
{
|
||||
if (c % 1000 == 0 && fStep->cancelled())
|
||||
break;
|
||||
double tmp = 0.0; // use double to cover all column types
|
||||
fOffsetNull = fRow.isNullValue(idx);
|
||||
|
||||
fRow.setData(getPointer(fRowData->at(c)));
|
||||
// get offset if not constant
|
||||
int64_t idx = fFieldIndex[2];
|
||||
|
||||
if (idx != -1)
|
||||
{
|
||||
double tmp = 0.0; // use double to cover all column types
|
||||
fOffsetNull = fRow.isNullValue(idx);
|
||||
|
||||
if (!fOffsetNull)
|
||||
{
|
||||
implicit2T(idx, tmp, 0);
|
||||
fOffset = round(tmp);
|
||||
fOffset *= fLead;
|
||||
}
|
||||
}
|
||||
|
||||
// get default if not constant
|
||||
idx = fFieldIndex[3];
|
||||
|
||||
if (idx != -1)
|
||||
{
|
||||
fDefNull = fRow.isNullValue(idx);
|
||||
|
||||
if (!fDefNull)
|
||||
implicit2T(idx, fDefault, (int) fRow.getScale(idx));
|
||||
}
|
||||
|
||||
int64_t o = c + fOffset;
|
||||
|
||||
if (o < b || o > e || fOffsetNull) // out of bound
|
||||
{
|
||||
T* v = (fDefNull) ? NULL : &fDefault;
|
||||
setValue(fRow.getColType(fFieldIndex[0]), b, e, c, v);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fRespectNulls == false && fRow.isNullValue(colIn) == true)
|
||||
{
|
||||
if (fOffset > 0)
|
||||
{
|
||||
while (++o < e)
|
||||
{
|
||||
fRow.setData(getPointer(fRowData->at(o)));
|
||||
|
||||
if (fRow.isNullValue(colIn) == false)
|
||||
break;
|
||||
}
|
||||
|
||||
if (o <= e)
|
||||
{
|
||||
fRow.setData(getPointer(fRowData->at(o)));
|
||||
getValue(colIn, fValue);
|
||||
isNull = fRow.isNullValue(colIn);
|
||||
}
|
||||
}
|
||||
else if (fOffset < 0)
|
||||
{
|
||||
while (--o > b)
|
||||
{
|
||||
fRow.setData(getPointer(fRowData->at(o)));
|
||||
|
||||
if (fRow.isNullValue(colIn) == false)
|
||||
break;
|
||||
}
|
||||
|
||||
if (o >= b)
|
||||
{
|
||||
fRow.setData(getPointer(fRowData->at(o)));
|
||||
getValue(colIn, fValue);
|
||||
isNull = fRow.isNullValue(colIn);
|
||||
}
|
||||
}
|
||||
|
||||
T* v = NULL;
|
||||
|
||||
if (!isNull)
|
||||
v = &fValue;
|
||||
else if (!fDefNull)
|
||||
v = &fDefault;
|
||||
|
||||
setValue(fRow.getColType(fFieldIndex[0]), b, e, c, v);
|
||||
}
|
||||
else
|
||||
{
|
||||
fRow.setData(getPointer(fRowData->at(o)));
|
||||
getValue(colIn, fValue);
|
||||
isNull = fRow.isNullValue(colIn);
|
||||
|
||||
T* v = NULL;
|
||||
|
||||
if (!isNull)
|
||||
v = &fValue;
|
||||
else if (!fDefNull)
|
||||
v = &fDefault;
|
||||
|
||||
setValue(fRow.getColType(fFieldIndex[0]), b, e, c, v);
|
||||
}
|
||||
if (!fOffsetNull)
|
||||
{
|
||||
implicit2T(idx, tmp, 0);
|
||||
fOffset = round(tmp);
|
||||
fOffset *= fLead;
|
||||
}
|
||||
}
|
||||
|
||||
// get default if not constant
|
||||
idx = fFieldIndex[3];
|
||||
|
||||
if (idx != -1)
|
||||
{
|
||||
fDefNull = fRow.isNullValue(idx);
|
||||
|
||||
if (!fDefNull)
|
||||
implicit2T(idx, fDefault, (int)fRow.getScale(idx));
|
||||
}
|
||||
|
||||
int64_t o = c + fOffset;
|
||||
|
||||
if (o < b || o > e || fOffsetNull) // out of bound
|
||||
{
|
||||
T* v = (fDefNull) ? NULL : &fDefault;
|
||||
setValue(fRow.getColType(fFieldIndex[0]), b, e, c, v);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fRespectNulls == false && fRow.isNullValue(colIn) == true)
|
||||
{
|
||||
if (fOffset > 0)
|
||||
{
|
||||
while (++o < e)
|
||||
{
|
||||
fRow.setData(getPointer(fRowData->at(o)));
|
||||
|
||||
if (fRow.isNullValue(colIn) == false)
|
||||
break;
|
||||
}
|
||||
|
||||
if (o <= e)
|
||||
{
|
||||
fRow.setData(getPointer(fRowData->at(o)));
|
||||
getValue(colIn, fValue);
|
||||
isNull = fRow.isNullValue(colIn);
|
||||
}
|
||||
}
|
||||
else if (fOffset < 0)
|
||||
{
|
||||
while (--o > b)
|
||||
{
|
||||
fRow.setData(getPointer(fRowData->at(o)));
|
||||
|
||||
if (fRow.isNullValue(colIn) == false)
|
||||
break;
|
||||
}
|
||||
|
||||
if (o >= b)
|
||||
{
|
||||
fRow.setData(getPointer(fRowData->at(o)));
|
||||
getValue(colIn, fValue);
|
||||
isNull = fRow.isNullValue(colIn);
|
||||
}
|
||||
}
|
||||
|
||||
T* v = NULL;
|
||||
|
||||
if (!isNull)
|
||||
v = &fValue;
|
||||
else if (!fDefNull)
|
||||
v = &fDefault;
|
||||
|
||||
setValue(fRow.getColType(fFieldIndex[0]), b, e, c, v);
|
||||
}
|
||||
else
|
||||
{
|
||||
fRow.setData(getPointer(fRowData->at(o)));
|
||||
getValue(colIn, fValue);
|
||||
isNull = fRow.isNullValue(colIn);
|
||||
|
||||
T* v = NULL;
|
||||
|
||||
if (!isNull)
|
||||
v = &fValue;
|
||||
else if (!fDefNull)
|
||||
v = &fDefault;
|
||||
|
||||
setValue(fRow.getColType(fFieldIndex[0]), b, e, c, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template
|
||||
boost::shared_ptr<WindowFunctionType> WF_lead_lag<int64_t>::makeFunction(int, const string&, int, WindowFunctionColumn*);
|
||||
template boost::shared_ptr<WindowFunctionType> WF_lead_lag<int64_t>::makeFunction(int, const string&, int,
|
||||
WindowFunctionColumn*);
|
||||
|
||||
template void WF_lead_lag<int64_t>::parseParms(const std::vector<execplan::SRCP>&);
|
||||
template void WF_lead_lag<uint64_t>::parseParms(const std::vector<execplan::SRCP>&);
|
||||
@ -315,6 +305,5 @@ template void WF_lead_lag<float>::parseParms(const std::vector<execplan::SRCP>&)
|
||||
template void WF_lead_lag<double>::parseParms(const std::vector<execplan::SRCP>&);
|
||||
template void WF_lead_lag<string>::parseParms(const std::vector<execplan::SRCP>&);
|
||||
|
||||
} //namespace
|
||||
} // namespace windowfunction
|
||||
// vim:ts=4 sw=4:
|
||||
|
||||
|
@ -17,47 +17,39 @@
|
||||
|
||||
// $Id: wf_lead_lag.h 3868 2013-06-06 22:13:05Z xlou $
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "windowfunctiontype.h"
|
||||
|
||||
|
||||
namespace windowfunction
|
||||
{
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
class WF_lead_lag : public WindowFunctionType
|
||||
{
|
||||
public:
|
||||
WF_lead_lag(int id, const std::string& name) : WindowFunctionType(id, name)
|
||||
{
|
||||
resetData();
|
||||
}
|
||||
public:
|
||||
WF_lead_lag(int id, const std::string& name) : WindowFunctionType(id, name)
|
||||
{
|
||||
resetData();
|
||||
}
|
||||
|
||||
// pure virtual in base
|
||||
void operator()(int64_t b, int64_t e, int64_t c);
|
||||
WindowFunctionType* clone() const;
|
||||
void resetData();
|
||||
void parseParms(const std::vector<execplan::SRCP>&);
|
||||
// pure virtual in base
|
||||
void operator()(int64_t b, int64_t e, int64_t c);
|
||||
WindowFunctionType* clone() const;
|
||||
void resetData();
|
||||
void parseParms(const std::vector<execplan::SRCP>&);
|
||||
|
||||
static boost::shared_ptr<WindowFunctionType> makeFunction(int, const string&, int, WindowFunctionColumn*);
|
||||
|
||||
protected:
|
||||
T fValue;
|
||||
T fDefault;
|
||||
int64_t fOffset;
|
||||
int64_t fLead;
|
||||
bool fOffsetNull;
|
||||
bool fDefNull;
|
||||
bool fRespectNulls; // respect null | ignore null
|
||||
static boost::shared_ptr<WindowFunctionType> makeFunction(int, const string&, int, WindowFunctionColumn*);
|
||||
|
||||
protected:
|
||||
T fValue;
|
||||
T fDefault;
|
||||
int64_t fOffset;
|
||||
int64_t fLead;
|
||||
bool fOffsetNull;
|
||||
bool fDefNull;
|
||||
bool fRespectNulls; // respect null | ignore null
|
||||
};
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace windowfunction
|
||||
|
||||
// vim:ts=4 sw=4:
|
||||
|
||||
|
@ -18,7 +18,6 @@
|
||||
|
||||
// $Id: wf_min_max.cpp 3932 2013-06-25 16:08:10Z xlou $
|
||||
|
||||
|
||||
//#define NDEBUG
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
@ -46,154 +45,144 @@ using namespace joblist;
|
||||
|
||||
#include "wf_min_max.h"
|
||||
|
||||
|
||||
namespace windowfunction
|
||||
{
|
||||
|
||||
|
||||
template<typename T>
|
||||
boost::shared_ptr<WindowFunctionType> WF_min_max<T>::makeFunction(int id, const string& name, int ct, WindowFunctionColumn* wc)
|
||||
template <typename T>
|
||||
boost::shared_ptr<WindowFunctionType> WF_min_max<T>::makeFunction(int id, const string& name, int ct,
|
||||
WindowFunctionColumn* wc)
|
||||
{
|
||||
boost::shared_ptr<WindowFunctionType> func;
|
||||
boost::shared_ptr<WindowFunctionType> func;
|
||||
|
||||
switch (ct)
|
||||
switch (ct)
|
||||
{
|
||||
case CalpontSystemCatalog::TINYINT:
|
||||
case CalpontSystemCatalog::SMALLINT:
|
||||
case CalpontSystemCatalog::MEDINT:
|
||||
case CalpontSystemCatalog::INT:
|
||||
case CalpontSystemCatalog::BIGINT:
|
||||
{
|
||||
case CalpontSystemCatalog::TINYINT:
|
||||
case CalpontSystemCatalog::SMALLINT:
|
||||
case CalpontSystemCatalog::MEDINT:
|
||||
case CalpontSystemCatalog::INT:
|
||||
case CalpontSystemCatalog::BIGINT:
|
||||
{
|
||||
func.reset(new WF_min_max<int64_t>(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<uint64_t>(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<uint64_t>(id, name));
|
||||
else
|
||||
func.reset(new WF_min_max<int64_t>(id, name));
|
||||
}
|
||||
else
|
||||
{
|
||||
func.reset(new WF_min_max<int128_t>(id, name));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::DOUBLE:
|
||||
case CalpontSystemCatalog::UDOUBLE:
|
||||
{
|
||||
func.reset(new WF_min_max<double>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::FLOAT:
|
||||
case CalpontSystemCatalog::UFLOAT:
|
||||
{
|
||||
func.reset(new WF_min_max<float>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::LONGDOUBLE:
|
||||
{
|
||||
func.reset(new WF_min_max<long double>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
func.reset(new WF_min_max<string>(id, name));
|
||||
break;
|
||||
}
|
||||
func.reset(new WF_min_max<int64_t>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
return func;
|
||||
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<uint64_t>(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<uint64_t>(id, name));
|
||||
else
|
||||
func.reset(new WF_min_max<int64_t>(id, name));
|
||||
}
|
||||
else
|
||||
{
|
||||
func.reset(new WF_min_max<int128_t>(id, name));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::DOUBLE:
|
||||
case CalpontSystemCatalog::UDOUBLE:
|
||||
{
|
||||
func.reset(new WF_min_max<double>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::FLOAT:
|
||||
case CalpontSystemCatalog::UFLOAT:
|
||||
{
|
||||
func.reset(new WF_min_max<float>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::LONGDOUBLE:
|
||||
{
|
||||
func.reset(new WF_min_max<long double>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
func.reset(new WF_min_max<string>(id, name));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return func;
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
WindowFunctionType* WF_min_max<T>::clone() const
|
||||
{
|
||||
return new WF_min_max<T>(*this);
|
||||
return new WF_min_max<T>(*this);
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
void WF_min_max<T>::resetData()
|
||||
{
|
||||
fCount = 0;
|
||||
fCount = 0;
|
||||
|
||||
WindowFunctionType::resetData();
|
||||
WindowFunctionType::resetData();
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
void WF_min_max<T>::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;
|
||||
// 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];
|
||||
uint64_t colIn = fFieldIndex[1];
|
||||
|
||||
for (int64_t i = b; i <= e; i++)
|
||||
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))
|
||||
{
|
||||
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++;
|
||||
fValue = valIn;
|
||||
}
|
||||
|
||||
T* v = ((fCount > 0) ? &fValue : NULL);
|
||||
setValue(fRow.getColType(fFieldIndex[0]), b, e, c, v);
|
||||
fCount++;
|
||||
}
|
||||
|
||||
fPrev = c;
|
||||
T* v = ((fCount > 0) ? &fValue : NULL);
|
||||
setValue(fRow.getColType(fFieldIndex[0]), b, e, c, v);
|
||||
|
||||
fPrev = c;
|
||||
}
|
||||
|
||||
template boost::shared_ptr<WindowFunctionType> WF_min_max<int64_t>::makeFunction(int, const string&, int,
|
||||
WindowFunctionColumn*);
|
||||
|
||||
template
|
||||
boost::shared_ptr<WindowFunctionType> WF_min_max<int64_t>::makeFunction(int, const string&, int, WindowFunctionColumn*);
|
||||
|
||||
|
||||
} //namespace
|
||||
} // namespace windowfunction
|
||||
// vim:ts=4 sw=4:
|
||||
|
||||
|
@ -17,40 +17,33 @@
|
||||
|
||||
// $Id: wf_min_max.h 3868 2013-06-06 22:13:05Z xlou $
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "windowfunctiontype.h"
|
||||
|
||||
|
||||
namespace windowfunction
|
||||
{
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
class WF_min_max : public WindowFunctionType
|
||||
{
|
||||
public:
|
||||
WF_min_max(int id, const std::string& name) : WindowFunctionType(id, name)
|
||||
{
|
||||
resetData();
|
||||
}
|
||||
public:
|
||||
WF_min_max(int id, const std::string& name) : WindowFunctionType(id, name)
|
||||
{
|
||||
resetData();
|
||||
}
|
||||
|
||||
// pure virtual in base
|
||||
void operator()(int64_t b, int64_t e, int64_t c);
|
||||
WindowFunctionType* clone() const;
|
||||
void resetData();
|
||||
// pure virtual in base
|
||||
void operator()(int64_t b, int64_t e, int64_t c);
|
||||
WindowFunctionType* clone() const;
|
||||
void resetData();
|
||||
|
||||
static boost::shared_ptr<WindowFunctionType> makeFunction(int, const string&, int, WindowFunctionColumn*);
|
||||
static boost::shared_ptr<WindowFunctionType> makeFunction(int, const string&, int, WindowFunctionColumn*);
|
||||
|
||||
protected:
|
||||
T fValue;
|
||||
uint64_t fCount;
|
||||
protected:
|
||||
T fValue;
|
||||
uint64_t fCount;
|
||||
};
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace windowfunction
|
||||
|
||||
// vim:ts=4 sw=4:
|
||||
|
||||
|
@ -18,7 +18,6 @@
|
||||
|
||||
// $Id: wf_nth_value.cpp 3932 2013-06-25 16:08:10Z xlou $
|
||||
|
||||
|
||||
//#define NDEBUG
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
@ -47,239 +46,229 @@ using namespace joblist;
|
||||
|
||||
#include "wf_nth_value.h"
|
||||
|
||||
|
||||
namespace windowfunction
|
||||
{
|
||||
|
||||
|
||||
template<typename T>
|
||||
boost::shared_ptr<WindowFunctionType> WF_nth_value<T>::makeFunction(int id, const string& name, int ct, WindowFunctionColumn* wc)
|
||||
template <typename T>
|
||||
boost::shared_ptr<WindowFunctionType> WF_nth_value<T>::makeFunction(int id, const string& name, int ct,
|
||||
WindowFunctionColumn* wc)
|
||||
{
|
||||
boost::shared_ptr<WindowFunctionType> func;
|
||||
boost::shared_ptr<WindowFunctionType> func;
|
||||
|
||||
switch (ct)
|
||||
switch (ct)
|
||||
{
|
||||
case CalpontSystemCatalog::TINYINT:
|
||||
case CalpontSystemCatalog::SMALLINT:
|
||||
case CalpontSystemCatalog::MEDINT:
|
||||
case CalpontSystemCatalog::INT:
|
||||
case CalpontSystemCatalog::BIGINT:
|
||||
{
|
||||
case CalpontSystemCatalog::TINYINT:
|
||||
case CalpontSystemCatalog::SMALLINT:
|
||||
case CalpontSystemCatalog::MEDINT:
|
||||
case CalpontSystemCatalog::INT:
|
||||
case CalpontSystemCatalog::BIGINT:
|
||||
{
|
||||
func.reset(new WF_nth_value<int64_t>(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_nth_value<uint64_t>(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_nth_value<uint64_t>(id, name));
|
||||
else
|
||||
func.reset(new WF_nth_value<int64_t>(id, name));
|
||||
}
|
||||
else if (width == datatypes::MAXDECIMALWIDTH)
|
||||
{
|
||||
func.reset(new WF_nth_value<int128_t>(id, name));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::DOUBLE:
|
||||
case CalpontSystemCatalog::UDOUBLE:
|
||||
{
|
||||
func.reset(new WF_nth_value<double>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::FLOAT:
|
||||
case CalpontSystemCatalog::UFLOAT:
|
||||
{
|
||||
func.reset(new WF_nth_value<float>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::LONGDOUBLE:
|
||||
{
|
||||
func.reset(new WF_nth_value<long double>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
func.reset(new WF_nth_value<string>(id, name));
|
||||
break;
|
||||
}
|
||||
func.reset(new WF_nth_value<int64_t>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
return func;
|
||||
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_nth_value<uint64_t>(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_nth_value<uint64_t>(id, name));
|
||||
else
|
||||
func.reset(new WF_nth_value<int64_t>(id, name));
|
||||
}
|
||||
else if (width == datatypes::MAXDECIMALWIDTH)
|
||||
{
|
||||
func.reset(new WF_nth_value<int128_t>(id, name));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::DOUBLE:
|
||||
case CalpontSystemCatalog::UDOUBLE:
|
||||
{
|
||||
func.reset(new WF_nth_value<double>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::FLOAT:
|
||||
case CalpontSystemCatalog::UFLOAT:
|
||||
{
|
||||
func.reset(new WF_nth_value<float>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::LONGDOUBLE:
|
||||
{
|
||||
func.reset(new WF_nth_value<long double>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
func.reset(new WF_nth_value<string>(id, name));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return func;
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
WindowFunctionType* WF_nth_value<T>::clone() const
|
||||
{
|
||||
return new WF_nth_value<T>(*this);
|
||||
return new WF_nth_value<T>(*this);
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
void WF_nth_value<T>::resetData()
|
||||
{
|
||||
WindowFunctionType::resetData();
|
||||
WindowFunctionType::resetData();
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
void WF_nth_value<T>::parseParms(const std::vector<execplan::SRCP>& parms)
|
||||
{
|
||||
// parms[0]: value-expr
|
||||
// skip
|
||||
// parms[0]: value-expr
|
||||
// skip
|
||||
|
||||
// parms[1]: nth value
|
||||
ConstantColumn* cc = dynamic_cast<ConstantColumn*>(parms[1].get());
|
||||
// parms[1]: nth value
|
||||
ConstantColumn* cc = dynamic_cast<ConstantColumn*>(parms[1].get());
|
||||
|
||||
if (cc != NULL)
|
||||
if (cc != NULL)
|
||||
{
|
||||
fNthNull = false;
|
||||
fNth = cc->getIntVal(fRow, fNthNull); // row not used, no need to setData.
|
||||
|
||||
if (fNth <= 0)
|
||||
{
|
||||
fNthNull = false;
|
||||
fNth = cc->getIntVal(fRow, fNthNull); // row not used, no need to setData.
|
||||
|
||||
if (fNth <= 0)
|
||||
{
|
||||
ostringstream oss;
|
||||
oss << fNth;
|
||||
throw IDBExcept(IDBErrorInfo::instance()->errorMsg(ERR_WF_ARG_OUT_OF_RANGE,
|
||||
oss.str()), ERR_WF_ARG_OUT_OF_RANGE);
|
||||
}
|
||||
ostringstream oss;
|
||||
oss << fNth;
|
||||
throw IDBExcept(IDBErrorInfo::instance()->errorMsg(ERR_WF_ARG_OUT_OF_RANGE, oss.str()),
|
||||
ERR_WF_ARG_OUT_OF_RANGE);
|
||||
}
|
||||
}
|
||||
|
||||
// parms[2]: from first | from last
|
||||
bool isNull = false;
|
||||
cc = dynamic_cast<ConstantColumn*>(parms[2].get());
|
||||
idbassert(cc != NULL);
|
||||
fFromFirst = (cc->getIntVal(fRow, isNull) > 0);
|
||||
// parms[2]: from first | from last
|
||||
bool isNull = false;
|
||||
cc = dynamic_cast<ConstantColumn*>(parms[2].get());
|
||||
idbassert(cc != NULL);
|
||||
fFromFirst = (cc->getIntVal(fRow, isNull) > 0);
|
||||
|
||||
// parms[3]: respect null | ignore null
|
||||
cc = dynamic_cast<ConstantColumn*>(parms[3].get());
|
||||
idbassert(cc != NULL);
|
||||
fRespectNulls = (cc->getIntVal(fRow, isNull) > 0);
|
||||
// parms[3]: respect null | ignore null
|
||||
cc = dynamic_cast<ConstantColumn*>(parms[3].get());
|
||||
idbassert(cc != NULL);
|
||||
fRespectNulls = (cc->getIntVal(fRow, isNull) > 0);
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
void WF_nth_value<T>::operator()(int64_t b, int64_t e, int64_t c)
|
||||
{
|
||||
int64_t s = b;
|
||||
int64_t t = e;
|
||||
int64_t s = b;
|
||||
int64_t t = e;
|
||||
|
||||
if (c != WF__BOUND_ALL)
|
||||
s = t = c;
|
||||
if (c != WF__BOUND_ALL)
|
||||
s = t = c;
|
||||
|
||||
for (int64_t c = s; c <= t; c++)
|
||||
for (int64_t c = s; c <= t; c++)
|
||||
{
|
||||
if (c % 1000 == 0 && fStep->cancelled())
|
||||
break;
|
||||
|
||||
int64_t idx = fFieldIndex[2];
|
||||
fRow.setData(getPointer(fRowData->at(c)));
|
||||
|
||||
if (idx != -1)
|
||||
{
|
||||
if (c % 1000 == 0 && fStep->cancelled())
|
||||
break;
|
||||
double tmp = 1.0;
|
||||
fNthNull = fRow.isNullValue(idx);
|
||||
|
||||
int64_t idx = fFieldIndex[2];
|
||||
fRow.setData(getPointer(fRowData->at(c)));
|
||||
|
||||
if (idx != -1)
|
||||
{
|
||||
double tmp = 1.0;
|
||||
fNthNull = fRow.isNullValue(idx);
|
||||
|
||||
if (!fNthNull)
|
||||
{
|
||||
implicit2T(idx, tmp, 0);
|
||||
fNth = round(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
bool isNull = true;
|
||||
|
||||
if ((!fNthNull) && ((b + fNth - 1) <= e))
|
||||
{
|
||||
uint64_t colIn = fFieldIndex[1];
|
||||
|
||||
if (fFromFirst)
|
||||
{
|
||||
int64_t k = b;
|
||||
fRow.setData(getPointer(fRowData->at(k)));
|
||||
|
||||
if (fRespectNulls == false && fRow.isNullValue(colIn) == true)
|
||||
{
|
||||
while (++k < e)
|
||||
{
|
||||
fRow.setData(getPointer(fRowData->at(k)));
|
||||
|
||||
if (fRow.isNullValue(colIn) == false)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int64_t n = k + fNth - 1;
|
||||
|
||||
if (n <= e && n >= 0)
|
||||
{
|
||||
fRow.setData(getPointer(fRowData->at(n)));
|
||||
getValue(colIn, fValue);
|
||||
isNull = fRow.isNullValue(colIn);
|
||||
}
|
||||
}
|
||||
else // from last
|
||||
{
|
||||
int64_t k = e;
|
||||
fRow.setData(getPointer(fRowData->at(k)));
|
||||
|
||||
if (fRespectNulls == false && fRow.isNullValue(colIn) == true)
|
||||
{
|
||||
while (--k > b)
|
||||
{
|
||||
fRow.setData(getPointer(fRowData->at(k)));
|
||||
|
||||
if (fRow.isNullValue(colIn) == false)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int64_t n = k - fNth + 1;
|
||||
|
||||
if (n >= b)
|
||||
{
|
||||
fRow.setData(getPointer(fRowData->at(n)));
|
||||
getValue(colIn, fValue);
|
||||
isNull = fRow.isNullValue(colIn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
T* v = (isNull) ? NULL : &fValue;
|
||||
setValue(fRow.getColType(fFieldIndex[0]), b, e, c, v);
|
||||
if (!fNthNull)
|
||||
{
|
||||
implicit2T(idx, tmp, 0);
|
||||
fNth = round(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
bool isNull = true;
|
||||
|
||||
if ((!fNthNull) && ((b + fNth - 1) <= e))
|
||||
{
|
||||
uint64_t colIn = fFieldIndex[1];
|
||||
|
||||
if (fFromFirst)
|
||||
{
|
||||
int64_t k = b;
|
||||
fRow.setData(getPointer(fRowData->at(k)));
|
||||
|
||||
if (fRespectNulls == false && fRow.isNullValue(colIn) == true)
|
||||
{
|
||||
while (++k < e)
|
||||
{
|
||||
fRow.setData(getPointer(fRowData->at(k)));
|
||||
|
||||
if (fRow.isNullValue(colIn) == false)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int64_t n = k + fNth - 1;
|
||||
|
||||
if (n <= e && n >= 0)
|
||||
{
|
||||
fRow.setData(getPointer(fRowData->at(n)));
|
||||
getValue(colIn, fValue);
|
||||
isNull = fRow.isNullValue(colIn);
|
||||
}
|
||||
}
|
||||
else // from last
|
||||
{
|
||||
int64_t k = e;
|
||||
fRow.setData(getPointer(fRowData->at(k)));
|
||||
|
||||
if (fRespectNulls == false && fRow.isNullValue(colIn) == true)
|
||||
{
|
||||
while (--k > b)
|
||||
{
|
||||
fRow.setData(getPointer(fRowData->at(k)));
|
||||
|
||||
if (fRow.isNullValue(colIn) == false)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int64_t n = k - fNth + 1;
|
||||
|
||||
if (n >= b)
|
||||
{
|
||||
fRow.setData(getPointer(fRowData->at(n)));
|
||||
getValue(colIn, fValue);
|
||||
isNull = fRow.isNullValue(colIn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
T* v = (isNull) ? NULL : &fValue;
|
||||
setValue(fRow.getColType(fFieldIndex[0]), b, e, c, v);
|
||||
}
|
||||
}
|
||||
|
||||
template boost::shared_ptr<WindowFunctionType> WF_nth_value<int64_t>::makeFunction(int, const string&, int,
|
||||
WindowFunctionColumn*);
|
||||
|
||||
template
|
||||
boost::shared_ptr<WindowFunctionType> WF_nth_value<int64_t>::makeFunction(int, const string&, int, WindowFunctionColumn*);
|
||||
|
||||
|
||||
} //namespace
|
||||
} // namespace windowfunction
|
||||
// vim:ts=4 sw=4:
|
||||
|
||||
|
@ -17,45 +17,37 @@
|
||||
|
||||
// $Id: wf_nth_value.h 3868 2013-06-06 22:13:05Z xlou $
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "windowfunctiontype.h"
|
||||
|
||||
|
||||
namespace windowfunction
|
||||
{
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
class WF_nth_value : public WindowFunctionType
|
||||
{
|
||||
public:
|
||||
WF_nth_value(int id, const std::string& name) : WindowFunctionType(id, name)
|
||||
{
|
||||
resetData();
|
||||
}
|
||||
public:
|
||||
WF_nth_value(int id, const std::string& name) : WindowFunctionType(id, name)
|
||||
{
|
||||
resetData();
|
||||
}
|
||||
|
||||
// pure virtual in base
|
||||
void operator()(int64_t b, int64_t e, int64_t c);
|
||||
WindowFunctionType* clone() const;
|
||||
void resetData();
|
||||
void parseParms(const std::vector<execplan::SRCP>&);
|
||||
// pure virtual in base
|
||||
void operator()(int64_t b, int64_t e, int64_t c);
|
||||
WindowFunctionType* clone() const;
|
||||
void resetData();
|
||||
void parseParms(const std::vector<execplan::SRCP>&);
|
||||
|
||||
static boost::shared_ptr<WindowFunctionType> makeFunction(int, const string&, int, WindowFunctionColumn*);
|
||||
|
||||
protected:
|
||||
T fValue;
|
||||
int64_t fNth;
|
||||
bool fNthNull;
|
||||
bool fFromFirst; // from first | from last
|
||||
bool fRespectNulls; // respect null | ignore null
|
||||
static boost::shared_ptr<WindowFunctionType> makeFunction(int, const string&, int, WindowFunctionColumn*);
|
||||
|
||||
protected:
|
||||
T fValue;
|
||||
int64_t fNth;
|
||||
bool fNthNull;
|
||||
bool fFromFirst; // from first | from last
|
||||
bool fRespectNulls; // respect null | ignore null
|
||||
};
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace windowfunction
|
||||
|
||||
// vim:ts=4 sw=4:
|
||||
|
||||
|
@ -17,7 +17,6 @@
|
||||
|
||||
// $Id: wf_ntile.cpp 3932 2013-06-25 16:08:10Z xlou $
|
||||
|
||||
|
||||
//#define NDEBUG
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
@ -49,118 +48,110 @@ using namespace joblist;
|
||||
|
||||
#include "wf_ntile.h"
|
||||
|
||||
|
||||
namespace windowfunction
|
||||
{
|
||||
|
||||
|
||||
boost::shared_ptr<WindowFunctionType> WF_ntile::makeFunction(int id, const string& name, int ct, WindowFunctionColumn* wc)
|
||||
boost::shared_ptr<WindowFunctionType> WF_ntile::makeFunction(int id, const string& name, int ct,
|
||||
WindowFunctionColumn* wc)
|
||||
{
|
||||
boost::shared_ptr<WindowFunctionType> func(new WF_ntile(id, name));
|
||||
return func;
|
||||
boost::shared_ptr<WindowFunctionType> func(new WF_ntile(id, name));
|
||||
return func;
|
||||
}
|
||||
|
||||
|
||||
WindowFunctionType* WF_ntile::clone() const
|
||||
{
|
||||
return new WF_ntile(*this);
|
||||
return new WF_ntile(*this);
|
||||
}
|
||||
|
||||
|
||||
void WF_ntile::resetData()
|
||||
{
|
||||
WindowFunctionType::resetData();
|
||||
WindowFunctionType::resetData();
|
||||
}
|
||||
|
||||
|
||||
void WF_ntile::parseParms(const std::vector<execplan::SRCP>& parms)
|
||||
{
|
||||
// parms[0]: nt
|
||||
ConstantColumn* cc = dynamic_cast<ConstantColumn*>(parms[0].get());
|
||||
// parms[0]: nt
|
||||
ConstantColumn* cc = dynamic_cast<ConstantColumn*>(parms[0].get());
|
||||
|
||||
if (cc != NULL)
|
||||
if (cc != NULL)
|
||||
{
|
||||
fNtileNull = false;
|
||||
fNtile = cc->getIntVal(fRow, fNtileNull); // row not used, no need to setData.
|
||||
|
||||
if (!fNtileNull && fNtile <= 0)
|
||||
{
|
||||
fNtileNull = false;
|
||||
fNtile = cc->getIntVal(fRow, fNtileNull); // row not used, no need to setData.
|
||||
|
||||
if (!fNtileNull && fNtile <= 0)
|
||||
{
|
||||
ostringstream oss;
|
||||
oss << fNtile;
|
||||
throw IDBExcept(IDBErrorInfo::instance()->errorMsg(ERR_WF_ARG_OUT_OF_RANGE,
|
||||
oss.str()), ERR_WF_ARG_OUT_OF_RANGE);
|
||||
}
|
||||
ostringstream oss;
|
||||
oss << fNtile;
|
||||
throw IDBExcept(IDBErrorInfo::instance()->errorMsg(ERR_WF_ARG_OUT_OF_RANGE, oss.str()),
|
||||
ERR_WF_ARG_OUT_OF_RANGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void WF_ntile::operator()(int64_t b, int64_t e, int64_t c)
|
||||
{
|
||||
int64_t idx = fFieldIndex[1];
|
||||
int64_t idx = fFieldIndex[1];
|
||||
|
||||
if (idx != -1)
|
||||
{
|
||||
fRow.setData(getPointer(fRowData->at(b)));
|
||||
|
||||
if (idx != -1)
|
||||
{
|
||||
fRow.setData(getPointer(fRowData->at(b)));
|
||||
double tmp = 1.0;
|
||||
fNtileNull = fRow.isNullValue(idx);
|
||||
|
||||
if (idx != -1)
|
||||
{
|
||||
double tmp = 1.0;
|
||||
fNtileNull = fRow.isNullValue(idx);
|
||||
if (!fNtileNull)
|
||||
implicit2T(idx, tmp, 0);
|
||||
|
||||
if (!fNtileNull)
|
||||
implicit2T(idx, tmp, 0);
|
||||
if (!fNtileNull && tmp <= 0)
|
||||
{
|
||||
ostringstream oss;
|
||||
oss << tmp;
|
||||
throw IDBExcept(IDBErrorInfo::instance()->errorMsg(ERR_WF_ARG_OUT_OF_RANGE, oss.str()),
|
||||
ERR_WF_ARG_OUT_OF_RANGE);
|
||||
}
|
||||
|
||||
if (!fNtileNull && tmp <= 0)
|
||||
{
|
||||
ostringstream oss;
|
||||
oss << tmp;
|
||||
throw IDBExcept(IDBErrorInfo::instance()->errorMsg(ERR_WF_ARG_OUT_OF_RANGE,
|
||||
oss.str()), ERR_WF_ARG_OUT_OF_RANGE);
|
||||
}
|
||||
|
||||
fNtile = round(tmp);
|
||||
}
|
||||
fNtile = round(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
c = b;
|
||||
c = b;
|
||||
|
||||
if (!fNtileNull)
|
||||
if (!fNtileNull)
|
||||
{
|
||||
int64_t rowPerBucket = (e - b + 1) / fNtile;
|
||||
int64_t n = rowPerBucket * fNtile;
|
||||
int64_t x = (e - b + 1) - n; // extra
|
||||
int64_t y = 0;
|
||||
int64_t z = 0;
|
||||
|
||||
while (c <= e)
|
||||
{
|
||||
int64_t rowPerBucket = (e - b + 1) / fNtile;
|
||||
int64_t n = rowPerBucket * fNtile;
|
||||
int64_t x = (e - b + 1) - n; // extra
|
||||
int64_t y = 0;
|
||||
int64_t z = 0;
|
||||
if (c % 1000 == 0 && fStep->cancelled())
|
||||
break;
|
||||
|
||||
while (c <= e)
|
||||
{
|
||||
if (c % 1000 == 0 && fStep->cancelled())
|
||||
break;
|
||||
y = rowPerBucket + ((x-- > 0) ? 1 : 0);
|
||||
z++;
|
||||
|
||||
y = rowPerBucket + ((x-- > 0) ? 1 : 0);
|
||||
z++;
|
||||
|
||||
for (int64_t i = 0; i < y && c <= e; i++)
|
||||
{
|
||||
fRow.setData(getPointer(fRowData->at(c++)));
|
||||
setIntValue(fFieldIndex[0], z);
|
||||
}
|
||||
}
|
||||
for (int64_t i = 0; i < y && c <= e; i++)
|
||||
{
|
||||
fRow.setData(getPointer(fRowData->at(c++)));
|
||||
setIntValue(fFieldIndex[0], z);
|
||||
}
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
while (c <= e)
|
||||
{
|
||||
while (c <= e)
|
||||
{
|
||||
if (c % 1000 == 0 && fStep->cancelled())
|
||||
break;
|
||||
if (c % 1000 == 0 && fStep->cancelled())
|
||||
break;
|
||||
|
||||
fRow.setData(getPointer(fRowData->at(c++)));
|
||||
setIntValue(fFieldIndex[0], joblist::BIGINTNULL);
|
||||
}
|
||||
fRow.setData(getPointer(fRowData->at(c++)));
|
||||
setIntValue(fFieldIndex[0], joblist::BIGINTNULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} //namespace
|
||||
} // namespace windowfunction
|
||||
// vim:ts=4 sw=4:
|
||||
|
||||
|
@ -17,42 +17,34 @@
|
||||
|
||||
// $Id: wf_ntile.h 3868 2013-06-06 22:13:05Z xlou $
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
#include "windowfunctiontype.h"
|
||||
|
||||
|
||||
namespace windowfunction
|
||||
{
|
||||
|
||||
|
||||
class WF_ntile : public WindowFunctionType
|
||||
{
|
||||
public:
|
||||
WF_ntile(int id, const std::string& name) : WindowFunctionType(id, name)
|
||||
{
|
||||
resetData();
|
||||
}
|
||||
public:
|
||||
WF_ntile(int id, const std::string& name) : WindowFunctionType(id, name)
|
||||
{
|
||||
resetData();
|
||||
}
|
||||
|
||||
// pure virtual in base
|
||||
void operator()(int64_t b, int64_t e, int64_t c);
|
||||
WindowFunctionType* clone() const;
|
||||
void resetData();
|
||||
void parseParms(const std::vector<execplan::SRCP>&);
|
||||
// pure virtual in base
|
||||
void operator()(int64_t b, int64_t e, int64_t c);
|
||||
WindowFunctionType* clone() const;
|
||||
void resetData();
|
||||
void parseParms(const std::vector<execplan::SRCP>&);
|
||||
|
||||
static boost::shared_ptr<WindowFunctionType> makeFunction(int, const string&, int, WindowFunctionColumn*);
|
||||
static boost::shared_ptr<WindowFunctionType> makeFunction(int, const string&, int, WindowFunctionColumn*);
|
||||
|
||||
protected:
|
||||
|
||||
uint64_t fNtile;
|
||||
bool fNtileNull;
|
||||
protected:
|
||||
uint64_t fNtile;
|
||||
bool fNtileNull;
|
||||
};
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace windowfunction
|
||||
|
||||
// vim:ts=4 sw=4:
|
||||
|
||||
|
@ -18,7 +18,6 @@
|
||||
|
||||
// $Id: wf_percentile.cpp 3932 2013-06-25 16:08:10Z xlou $
|
||||
|
||||
|
||||
//#define NDEBUG
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
@ -51,347 +50,336 @@ using namespace joblist;
|
||||
|
||||
#include "wf_percentile.h"
|
||||
|
||||
|
||||
namespace windowfunction
|
||||
{
|
||||
|
||||
template<typename T>
|
||||
boost::shared_ptr<WindowFunctionType> WF_percentile<T>::makeFunction(int id, const string& name, int ct, WindowFunctionColumn* wc)
|
||||
template <typename T>
|
||||
boost::shared_ptr<WindowFunctionType> WF_percentile<T>::makeFunction(int id, const string& name, int ct,
|
||||
WindowFunctionColumn* wc)
|
||||
{
|
||||
boost::shared_ptr<WindowFunctionType> func;
|
||||
boost::shared_ptr<WindowFunctionType> func;
|
||||
|
||||
if (id == WF__PERCENTILE_DISC)
|
||||
if (id == WF__PERCENTILE_DISC)
|
||||
{
|
||||
switch (ct)
|
||||
{
|
||||
switch (ct)
|
||||
case CalpontSystemCatalog::TINYINT:
|
||||
case CalpontSystemCatalog::SMALLINT:
|
||||
case CalpontSystemCatalog::MEDINT:
|
||||
case CalpontSystemCatalog::INT:
|
||||
case CalpontSystemCatalog::BIGINT:
|
||||
{
|
||||
func.reset(new WF_percentile<int64_t>(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_percentile<uint64_t>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::DECIMAL:
|
||||
case CalpontSystemCatalog::UDECIMAL:
|
||||
{
|
||||
decltype(datatypes::MAXDECIMALWIDTH) width = wc->resultType().colWidth;
|
||||
|
||||
if (width < datatypes::MAXDECIMALWIDTH)
|
||||
{
|
||||
case CalpontSystemCatalog::TINYINT:
|
||||
case CalpontSystemCatalog::SMALLINT:
|
||||
case CalpontSystemCatalog::MEDINT:
|
||||
case CalpontSystemCatalog::INT:
|
||||
case CalpontSystemCatalog::BIGINT:
|
||||
{
|
||||
func.reset(new WF_percentile<int64_t>(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_percentile<uint64_t>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::DECIMAL:
|
||||
case CalpontSystemCatalog::UDECIMAL:
|
||||
{
|
||||
decltype(datatypes::MAXDECIMALWIDTH) width =
|
||||
wc->resultType().colWidth;
|
||||
|
||||
if (width < datatypes::MAXDECIMALWIDTH)
|
||||
{
|
||||
if (ct == CalpontSystemCatalog::UDECIMAL)
|
||||
func.reset(new WF_percentile<uint64_t>(id, name));
|
||||
else
|
||||
func.reset(new WF_percentile<int64_t>(id, name));
|
||||
}
|
||||
else if (width == datatypes::MAXDECIMALWIDTH)
|
||||
{
|
||||
func.reset(new WF_percentile<int128_t>(id, name));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::DOUBLE:
|
||||
case CalpontSystemCatalog::UDOUBLE:
|
||||
{
|
||||
func.reset(new WF_percentile<double>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::FLOAT:
|
||||
case CalpontSystemCatalog::UFLOAT:
|
||||
{
|
||||
func.reset(new WF_percentile<float>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::LONGDOUBLE:
|
||||
{
|
||||
func.reset(new WF_percentile<long double>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
if (id == WF__PERCENTILE_DISC)
|
||||
{
|
||||
func.reset(new WF_percentile<string>(id, name));
|
||||
}
|
||||
else
|
||||
{
|
||||
string errStr = name + "(" + colType2String[ct] + ")";
|
||||
errStr = IDBErrorInfo::instance()->errorMsg(ERR_WF_INVALID_PARM_TYPE, errStr);
|
||||
cerr << errStr << endl;
|
||||
throw IDBExcept(errStr, ERR_WF_INVALID_PARM_TYPE);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
if (ct == CalpontSystemCatalog::UDECIMAL)
|
||||
func.reset(new WF_percentile<uint64_t>(id, name));
|
||||
else
|
||||
func.reset(new WF_percentile<int64_t>(id, name));
|
||||
}
|
||||
else if (width == datatypes::MAXDECIMALWIDTH)
|
||||
{
|
||||
func.reset(new WF_percentile<int128_t>(id, name));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::DOUBLE:
|
||||
case CalpontSystemCatalog::UDOUBLE:
|
||||
{
|
||||
func.reset(new WF_percentile<double>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::FLOAT:
|
||||
case CalpontSystemCatalog::UFLOAT:
|
||||
{
|
||||
func.reset(new WF_percentile<float>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::LONGDOUBLE:
|
||||
{
|
||||
func.reset(new WF_percentile<long double>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
if (id == WF__PERCENTILE_DISC)
|
||||
{
|
||||
func.reset(new WF_percentile<string>(id, name));
|
||||
}
|
||||
else
|
||||
{
|
||||
string errStr = name + "(" + colType2String[ct] + ")";
|
||||
errStr = IDBErrorInfo::instance()->errorMsg(ERR_WF_INVALID_PARM_TYPE, errStr);
|
||||
cerr << errStr << endl;
|
||||
throw IDBExcept(errStr, ERR_WF_INVALID_PARM_TYPE);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (ct)
|
||||
{
|
||||
switch (ct)
|
||||
{
|
||||
case CalpontSystemCatalog::TINYINT:
|
||||
case CalpontSystemCatalog::SMALLINT:
|
||||
case CalpontSystemCatalog::MEDINT:
|
||||
case CalpontSystemCatalog::INT:
|
||||
case CalpontSystemCatalog::BIGINT:
|
||||
case CalpontSystemCatalog::DECIMAL:
|
||||
case CalpontSystemCatalog::UTINYINT:
|
||||
case CalpontSystemCatalog::USMALLINT:
|
||||
case CalpontSystemCatalog::UMEDINT:
|
||||
case CalpontSystemCatalog::UINT:
|
||||
case CalpontSystemCatalog::UBIGINT:
|
||||
case CalpontSystemCatalog::UDECIMAL:
|
||||
case CalpontSystemCatalog::DOUBLE:
|
||||
case CalpontSystemCatalog::UDOUBLE:
|
||||
case CalpontSystemCatalog::FLOAT:
|
||||
case CalpontSystemCatalog::UFLOAT:
|
||||
{
|
||||
func.reset(new WF_percentile<double>(id, name));
|
||||
break;
|
||||
}
|
||||
case CalpontSystemCatalog::TINYINT:
|
||||
case CalpontSystemCatalog::SMALLINT:
|
||||
case CalpontSystemCatalog::MEDINT:
|
||||
case CalpontSystemCatalog::INT:
|
||||
case CalpontSystemCatalog::BIGINT:
|
||||
case CalpontSystemCatalog::DECIMAL:
|
||||
case CalpontSystemCatalog::UTINYINT:
|
||||
case CalpontSystemCatalog::USMALLINT:
|
||||
case CalpontSystemCatalog::UMEDINT:
|
||||
case CalpontSystemCatalog::UINT:
|
||||
case CalpontSystemCatalog::UBIGINT:
|
||||
case CalpontSystemCatalog::UDECIMAL:
|
||||
case CalpontSystemCatalog::DOUBLE:
|
||||
case CalpontSystemCatalog::UDOUBLE:
|
||||
case CalpontSystemCatalog::FLOAT:
|
||||
case CalpontSystemCatalog::UFLOAT:
|
||||
{
|
||||
func.reset(new WF_percentile<double>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::LONGDOUBLE:
|
||||
{
|
||||
func.reset(new WF_percentile<long double>(id, name));
|
||||
break;
|
||||
}
|
||||
case CalpontSystemCatalog::LONGDOUBLE:
|
||||
{
|
||||
func.reset(new WF_percentile<long double>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
string errStr = name + "(" + colType2String[ct] + ")";
|
||||
errStr = IDBErrorInfo::instance()->errorMsg(ERR_WF_INVALID_PARM_TYPE, errStr);
|
||||
cerr << errStr << endl;
|
||||
throw IDBExcept(errStr, ERR_WF_INVALID_PARM_TYPE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
default:
|
||||
{
|
||||
string errStr = name + "(" + colType2String[ct] + ")";
|
||||
errStr = IDBErrorInfo::instance()->errorMsg(ERR_WF_INVALID_PARM_TYPE, errStr);
|
||||
cerr << errStr << endl;
|
||||
throw IDBExcept(errStr, ERR_WF_INVALID_PARM_TYPE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return func;
|
||||
return func;
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
WindowFunctionType* WF_percentile<T>::clone() const
|
||||
{
|
||||
return new WF_percentile(*this);
|
||||
return new WF_percentile(*this);
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
void WF_percentile<T>::resetData()
|
||||
{
|
||||
WindowFunctionType::resetData();
|
||||
WindowFunctionType::resetData();
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
void WF_percentile<T>::parseParms(const std::vector<execplan::SRCP>& parms)
|
||||
{
|
||||
// parms[0]: nve
|
||||
ConstantColumn* cc = dynamic_cast<ConstantColumn*>(parms[0].get());
|
||||
// parms[0]: nve
|
||||
ConstantColumn* cc = dynamic_cast<ConstantColumn*>(parms[0].get());
|
||||
|
||||
if (cc != NULL)
|
||||
if (cc != NULL)
|
||||
{
|
||||
fNveNull = false;
|
||||
fNve = cc->getDoubleVal(fRow, fNveNull); // row not used, no need to setData.
|
||||
|
||||
if (!fNveNull && (fNve < 0 || fNve > 1))
|
||||
{
|
||||
fNveNull = false;
|
||||
fNve = cc->getDoubleVal(fRow, fNveNull); // row not used, no need to setData.
|
||||
|
||||
if (!fNveNull && (fNve < 0 || fNve > 1))
|
||||
{
|
||||
ostringstream oss;
|
||||
oss << fNve;
|
||||
throw IDBExcept(IDBErrorInfo::instance()->errorMsg(ERR_WF_ARG_OUT_OF_RANGE,
|
||||
oss.str()), ERR_WF_ARG_OUT_OF_RANGE);
|
||||
}
|
||||
ostringstream oss;
|
||||
oss << fNve;
|
||||
throw IDBExcept(IDBErrorInfo::instance()->errorMsg(ERR_WF_ARG_OUT_OF_RANGE, oss.str()),
|
||||
ERR_WF_ARG_OUT_OF_RANGE);
|
||||
}
|
||||
}
|
||||
|
||||
// workaround for the within group order by column index
|
||||
idbassert(fPeer->fIndex.size() > 0);
|
||||
fFieldIndex.push_back(fPeer->fIndex[0]);
|
||||
// workaround for the within group order by column index
|
||||
idbassert(fPeer->fIndex.size() > 0);
|
||||
fFieldIndex.push_back(fPeer->fIndex[0]);
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
void WF_percentile<T>::operator()(int64_t b, int64_t e, int64_t c)
|
||||
{
|
||||
int64_t idx = fFieldIndex[1];
|
||||
fRow.setData(getPointer(fRowData->at(b)));
|
||||
int64_t idx = fFieldIndex[1];
|
||||
fRow.setData(getPointer(fRowData->at(b)));
|
||||
|
||||
if (idx != -1)
|
||||
{
|
||||
if (idx != -1)
|
||||
{
|
||||
if (idx != -1)
|
||||
{
|
||||
fNveNull = fRow.isNullValue(idx);
|
||||
implicit2T(idx, fNve, 0);
|
||||
fNveNull = fRow.isNullValue(idx);
|
||||
implicit2T(idx, fNve, 0);
|
||||
|
||||
if (!fNveNull && (fNve < 0 || fNve > 1))
|
||||
{
|
||||
ostringstream oss;
|
||||
oss << fNve;
|
||||
throw IDBExcept(IDBErrorInfo::instance()->errorMsg(ERR_WF_ARG_OUT_OF_RANGE,
|
||||
oss.str()), ERR_WF_ARG_OUT_OF_RANGE);
|
||||
}
|
||||
}
|
||||
if (!fNveNull && (fNve < 0 || fNve > 1))
|
||||
{
|
||||
ostringstream oss;
|
||||
oss << fNve;
|
||||
throw IDBExcept(IDBErrorInfo::instance()->errorMsg(ERR_WF_ARG_OUT_OF_RANGE, oss.str()),
|
||||
ERR_WF_ARG_OUT_OF_RANGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fNveNull)
|
||||
{
|
||||
for (c = b; c <= e; c++)
|
||||
{
|
||||
if (c % 1000 == 0 && fStep->cancelled())
|
||||
break;
|
||||
|
||||
fRow.setData(getPointer(fRowData->at(c)));
|
||||
setValue(fRow.getColType(fFieldIndex[0]), b, e, c, (T*) NULL);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
idx = fFieldIndex[2];
|
||||
int64_t rank = 0;
|
||||
int64_t dups = 0;
|
||||
int64_t b1 = -1;
|
||||
int64_t e1 = -1;
|
||||
scoped_array<int64_t> rk(new int64_t[e - b + 1]);
|
||||
|
||||
if (fNveNull)
|
||||
{
|
||||
for (c = b; c <= e; c++)
|
||||
{
|
||||
if (c % 1000 == 0 && fStep->cancelled())
|
||||
if (c % 1000 == 0 && fStep->cancelled())
|
||||
break;
|
||||
|
||||
fRow.setData(getPointer(fRowData->at(c)));
|
||||
setValue(fRow.getColType(fFieldIndex[0]), b, e, c, (T*)NULL);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
idx = fFieldIndex[2];
|
||||
int64_t rank = 0;
|
||||
int64_t dups = 0;
|
||||
int64_t b1 = -1;
|
||||
int64_t e1 = -1;
|
||||
scoped_array<int64_t> rk(new int64_t[e - b + 1]);
|
||||
|
||||
for (c = b; c <= e; c++)
|
||||
{
|
||||
if (c % 1000 == 0 && fStep->cancelled())
|
||||
break;
|
||||
|
||||
fRow.setData(getPointer(fRowData->at(c)));
|
||||
|
||||
if (fRow.isNullValue(idx))
|
||||
continue;
|
||||
|
||||
// ignore nulls
|
||||
if (b1 == -1)
|
||||
b1 = c;
|
||||
|
||||
e1 = c;
|
||||
|
||||
if (fFunctionId == WF__PERCENTILE_DISC)
|
||||
{
|
||||
// need cume_rank
|
||||
if (c != b && fPeer->operator()(getPointer(fRowData->at(c)), getPointer(fRowData->at(c - 1))))
|
||||
{
|
||||
dups++;
|
||||
}
|
||||
else
|
||||
{
|
||||
rank++;
|
||||
rank += dups;
|
||||
dups = 0;
|
||||
}
|
||||
|
||||
rk[c - b] = rank;
|
||||
}
|
||||
}
|
||||
|
||||
T* p = NULL;
|
||||
T v;
|
||||
int ct = (fFunctionId == WF__PERCENTILE_CONT) ? CalpontSystemCatalog::DOUBLE : fRow.getColType(idx);
|
||||
|
||||
if (b1 != -1)
|
||||
{
|
||||
double cnt = (e1 - b1 + 1);
|
||||
|
||||
if (fFunctionId == WF__PERCENTILE_CONT)
|
||||
{
|
||||
// @bug5820, this "rn" is the normalized row number, not the real row number.
|
||||
// Using real row number here will introduce a small calculation error in double result.
|
||||
double rn = fNve * (cnt - 1);
|
||||
double crn = ceil(rn);
|
||||
double frn = floor(rn);
|
||||
double vd = 0;
|
||||
|
||||
if (crn == rn && rn == frn)
|
||||
{
|
||||
fRow.setData(getPointer(fRowData->at((size_t)rn + (size_t)b1)));
|
||||
implicit2T(idx, vd, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
double cv = 0.0, fv = 0.0;
|
||||
fRow.setData(getPointer(fRowData->at((size_t)frn + (size_t)b1)));
|
||||
implicit2T(idx, fv, 0);
|
||||
fRow.setData(getPointer(fRowData->at((size_t)crn + (size_t)b1)));
|
||||
implicit2T(idx, cv, 0);
|
||||
vd = (crn - rn) * fv + (rn - frn) * cv;
|
||||
}
|
||||
|
||||
v = *(reinterpret_cast<T*>(&vd));
|
||||
p = &v;
|
||||
}
|
||||
else // (fFunctionId == WF__PERCENTILE_DISC)
|
||||
{
|
||||
int prevRank = ++rank + dups;
|
||||
double cumeDist = 1;
|
||||
fRow.setData(getPointer(fRowData->at(e1)));
|
||||
|
||||
for (c = e1; c >= b1; c--)
|
||||
{
|
||||
int currRank = rk[c - b];
|
||||
|
||||
if (currRank != prevRank)
|
||||
{
|
||||
cumeDist = ((double)(prevRank - 1)) / cnt;
|
||||
|
||||
if (cumeDist < fNve)
|
||||
break;
|
||||
|
||||
fRow.setData(getPointer(fRowData->at(c)));
|
||||
|
||||
if (fRow.isNullValue(idx))
|
||||
continue;
|
||||
|
||||
// ignore nulls
|
||||
if (b1 == -1)
|
||||
b1 = c;
|
||||
|
||||
e1 = c;
|
||||
|
||||
if (fFunctionId == WF__PERCENTILE_DISC)
|
||||
{
|
||||
// need cume_rank
|
||||
if (c != b &&
|
||||
fPeer->operator()(getPointer(fRowData->at(c)), getPointer(fRowData->at(c - 1))))
|
||||
{
|
||||
dups++;
|
||||
}
|
||||
else
|
||||
{
|
||||
rank++;
|
||||
rank += dups;
|
||||
dups = 0;
|
||||
}
|
||||
|
||||
rk[c - b] = rank;
|
||||
prevRank = currRank;
|
||||
}
|
||||
}
|
||||
|
||||
c++;
|
||||
|
||||
fRow.setData(getPointer(fRowData->at(c)));
|
||||
getValue(idx, v);
|
||||
|
||||
p = &v;
|
||||
}
|
||||
}
|
||||
|
||||
T* p = NULL;
|
||||
T v;
|
||||
int ct = (fFunctionId == WF__PERCENTILE_CONT) ?
|
||||
CalpontSystemCatalog::DOUBLE : fRow.getColType(idx);
|
||||
for (c = b; c <= e; c++)
|
||||
{
|
||||
if (c % 1000 == 0 && fStep->cancelled())
|
||||
break;
|
||||
|
||||
if (b1 != -1)
|
||||
{
|
||||
double cnt = (e1 - b1 + 1);
|
||||
|
||||
if (fFunctionId == WF__PERCENTILE_CONT)
|
||||
{
|
||||
// @bug5820, this "rn" is the normalized row number, not the real row number.
|
||||
// Using real row number here will introduce a small calculation error in double result.
|
||||
double rn = fNve * (cnt - 1);
|
||||
double crn = ceil(rn);
|
||||
double frn = floor(rn);
|
||||
double vd = 0;
|
||||
|
||||
if (crn == rn && rn == frn)
|
||||
{
|
||||
fRow.setData(getPointer(fRowData->at((size_t) rn + (size_t) b1)));
|
||||
implicit2T(idx, vd, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
double cv = 0.0, fv = 0.0;
|
||||
fRow.setData(getPointer(fRowData->at((size_t) frn + (size_t) b1)));
|
||||
implicit2T(idx, fv, 0);
|
||||
fRow.setData(getPointer(fRowData->at((size_t) crn + (size_t) b1)));
|
||||
implicit2T(idx, cv, 0);
|
||||
vd = (crn - rn) * fv + (rn - frn) * cv;
|
||||
}
|
||||
|
||||
v = *(reinterpret_cast<T*>(&vd));
|
||||
p = &v;
|
||||
}
|
||||
else // (fFunctionId == WF__PERCENTILE_DISC)
|
||||
{
|
||||
int prevRank = ++rank + dups;
|
||||
double cumeDist = 1;
|
||||
fRow.setData(getPointer(fRowData->at(e1)));
|
||||
|
||||
for (c = e1; c >= b1; c--)
|
||||
{
|
||||
int currRank = rk[c - b];
|
||||
|
||||
if (currRank != prevRank)
|
||||
{
|
||||
cumeDist = ((double) (prevRank - 1)) / cnt;
|
||||
|
||||
if (cumeDist < fNve)
|
||||
break;
|
||||
|
||||
prevRank = currRank;
|
||||
}
|
||||
}
|
||||
|
||||
c++;
|
||||
|
||||
fRow.setData(getPointer(fRowData->at(c)));
|
||||
getValue(idx, v);
|
||||
|
||||
p = &v;
|
||||
}
|
||||
}
|
||||
|
||||
for (c = b; c <= e; c++)
|
||||
{
|
||||
if (c % 1000 == 0 && fStep->cancelled())
|
||||
break;
|
||||
|
||||
fRow.setData(getPointer(fRowData->at(c)));
|
||||
setValue(ct, b, e, c, p);
|
||||
}
|
||||
fRow.setData(getPointer(fRowData->at(c)));
|
||||
setValue(ct, b, e, c, p);
|
||||
}
|
||||
}
|
||||
|
||||
template boost::shared_ptr<WindowFunctionType> WF_percentile<int64_t>::makeFunction(int, const string&, int,
|
||||
WindowFunctionColumn*);
|
||||
|
||||
template
|
||||
boost::shared_ptr<WindowFunctionType> WF_percentile<int64_t>::makeFunction(int, const string&, int, WindowFunctionColumn*);
|
||||
|
||||
|
||||
} //namespace
|
||||
} // namespace windowfunction
|
||||
// vim:ts=4 sw=4:
|
||||
|
||||
|
@ -17,43 +17,35 @@
|
||||
|
||||
// $Id: wf_percentile.h 3868 2013-06-06 22:13:05Z xlou $
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
#include "windowfunctiontype.h"
|
||||
|
||||
|
||||
namespace windowfunction
|
||||
{
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
class WF_percentile : public WindowFunctionType
|
||||
{
|
||||
public:
|
||||
WF_percentile(int id, const std::string& name) : WindowFunctionType(id, name)
|
||||
{
|
||||
resetData();
|
||||
}
|
||||
public:
|
||||
WF_percentile(int id, const std::string& name) : WindowFunctionType(id, name)
|
||||
{
|
||||
resetData();
|
||||
}
|
||||
|
||||
// pure virtual in base
|
||||
void operator()(int64_t b, int64_t e, int64_t c);
|
||||
WindowFunctionType* clone() const;
|
||||
void resetData();
|
||||
void parseParms(const std::vector<execplan::SRCP>&);
|
||||
// pure virtual in base
|
||||
void operator()(int64_t b, int64_t e, int64_t c);
|
||||
WindowFunctionType* clone() const;
|
||||
void resetData();
|
||||
void parseParms(const std::vector<execplan::SRCP>&);
|
||||
|
||||
static boost::shared_ptr<WindowFunctionType> makeFunction(int, const string&, int, WindowFunctionColumn*);
|
||||
static boost::shared_ptr<WindowFunctionType> makeFunction(int, const string&, int, WindowFunctionColumn*);
|
||||
|
||||
protected:
|
||||
|
||||
double fNve;
|
||||
bool fNveNull;
|
||||
protected:
|
||||
double fNve;
|
||||
bool fNveNull;
|
||||
};
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace windowfunction
|
||||
|
||||
// vim:ts=4 sw=4:
|
||||
|
||||
|
@ -17,7 +17,6 @@
|
||||
|
||||
// $Id: wf_ranking.cpp 3932 2013-06-25 16:08:10Z xlou $
|
||||
|
||||
|
||||
//#define NDEBUG
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
@ -48,110 +47,102 @@ using namespace joblist;
|
||||
|
||||
#include "wf_ranking.h"
|
||||
|
||||
|
||||
namespace windowfunction
|
||||
{
|
||||
|
||||
|
||||
boost::shared_ptr<WindowFunctionType> WF_ranking::makeFunction(int id, const string& name, int ct, WindowFunctionColumn* wc)
|
||||
boost::shared_ptr<WindowFunctionType> WF_ranking::makeFunction(int id, const string& name, int ct,
|
||||
WindowFunctionColumn* wc)
|
||||
{
|
||||
boost::shared_ptr<WindowFunctionType> func(new WF_ranking(id, name));
|
||||
return func;
|
||||
boost::shared_ptr<WindowFunctionType> func(new WF_ranking(id, name));
|
||||
return func;
|
||||
}
|
||||
|
||||
|
||||
WindowFunctionType* WF_ranking::clone() const
|
||||
{
|
||||
return new WF_ranking(*this);
|
||||
return new WF_ranking(*this);
|
||||
}
|
||||
|
||||
|
||||
void WF_ranking::resetData()
|
||||
{
|
||||
fRank = 0;
|
||||
fDups = 0;
|
||||
fRank = 0;
|
||||
fDups = 0;
|
||||
|
||||
WindowFunctionType::resetData();
|
||||
WindowFunctionType::resetData();
|
||||
}
|
||||
|
||||
|
||||
void WF_ranking::operator()(int64_t b, int64_t e, int64_t c)
|
||||
{
|
||||
// one row handling
|
||||
if (fPartition.first == fPartition.second)
|
||||
// one row handling
|
||||
if (fPartition.first == fPartition.second)
|
||||
{
|
||||
fRow.setData(getPointer(fRowData->at(fPartition.first)));
|
||||
int64_t r = (fFunctionId == WF__PERCENT_RANK) ? 0 : 1;
|
||||
|
||||
if (fFunctionId == WF__RANK || fFunctionId == WF__DENSE_RANK)
|
||||
setIntValue(fFieldIndex[0], r);
|
||||
else
|
||||
setDoubleValue(fFieldIndex[0], r);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// more than one row, e > b
|
||||
b = fPartition.first;
|
||||
e = fPartition.second;
|
||||
double n1 = e - b; // count(*) - 1, n will not be 0.
|
||||
|
||||
for (c = b; c <= e; c++)
|
||||
{
|
||||
if (c % 1000 == 0 && fStep->cancelled())
|
||||
break;
|
||||
|
||||
if (c != b && fPeer->operator()(getPointer(fRowData->at(c)), getPointer(fRowData->at(c - 1))))
|
||||
{
|
||||
fRow.setData(getPointer(fRowData->at(fPartition.first)));
|
||||
int64_t r = (fFunctionId == WF__PERCENT_RANK) ? 0 : 1;
|
||||
fDups++;
|
||||
}
|
||||
else
|
||||
{
|
||||
fRank++;
|
||||
|
||||
if (fFunctionId == WF__RANK || fFunctionId == WF__DENSE_RANK)
|
||||
setIntValue(fFieldIndex[0], r);
|
||||
else
|
||||
setDoubleValue(fFieldIndex[0], r);
|
||||
if (fFunctionId != WF__DENSE_RANK)
|
||||
fRank += fDups;
|
||||
|
||||
return;
|
||||
fDups = 0;
|
||||
}
|
||||
|
||||
// more than one row, e > b
|
||||
b = fPartition.first;
|
||||
e = fPartition.second;
|
||||
double n1 = e - b; // count(*) - 1, n will not be 0.
|
||||
fRow.setData(getPointer(fRowData->at(c)));
|
||||
|
||||
for (c = b; c <= e; c++)
|
||||
if (fFunctionId != WF__PERCENT_RANK)
|
||||
setIntValue(fFieldIndex[0], fRank);
|
||||
else
|
||||
setDoubleValue(fFieldIndex[0], (fRank - 1) / n1);
|
||||
}
|
||||
|
||||
// Two-pass, need to find peers.
|
||||
if (fFunctionId == WF__CUME_DIST)
|
||||
{
|
||||
int prevRank = ++fRank + fDups; // hypothetical row at (e+1)
|
||||
double n0 = (e - b + 1); // count(*)
|
||||
double cumeDist = 1;
|
||||
fRow.setData(getPointer(fRowData->at(e)));
|
||||
|
||||
for (c = e; c >= b; c--)
|
||||
{
|
||||
if (c % 1000 == 0 && fStep->cancelled())
|
||||
break;
|
||||
if (c % 1000 == 0 && fStep->cancelled())
|
||||
break;
|
||||
|
||||
if (c != b &&
|
||||
fPeer->operator()(getPointer(fRowData->at(c)), getPointer(fRowData->at(c - 1))))
|
||||
{
|
||||
fDups++;
|
||||
}
|
||||
else
|
||||
{
|
||||
fRank++;
|
||||
fRow.setData(getPointer(fRowData->at(c)));
|
||||
int currRank = getIntValue(fFieldIndex[0]);
|
||||
|
||||
if (fFunctionId != WF__DENSE_RANK)
|
||||
fRank += fDups;
|
||||
if (currRank != prevRank)
|
||||
{
|
||||
cumeDist = ((double)(prevRank - 1)) / n0;
|
||||
prevRank = currRank;
|
||||
}
|
||||
|
||||
fDups = 0;
|
||||
}
|
||||
|
||||
fRow.setData(getPointer(fRowData->at(c)));
|
||||
|
||||
if (fFunctionId != WF__PERCENT_RANK)
|
||||
setIntValue(fFieldIndex[0], fRank);
|
||||
else
|
||||
setDoubleValue(fFieldIndex[0], (fRank - 1) / n1);
|
||||
}
|
||||
|
||||
// Two-pass, need to find peers.
|
||||
if (fFunctionId == WF__CUME_DIST)
|
||||
{
|
||||
int prevRank = ++fRank + fDups; // hypothetical row at (e+1)
|
||||
double n0 = (e - b + 1); // count(*)
|
||||
double cumeDist = 1;
|
||||
fRow.setData(getPointer(fRowData->at(e)));
|
||||
|
||||
for (c = e; c >= b; c--)
|
||||
{
|
||||
if (c % 1000 == 0 && fStep->cancelled())
|
||||
break;
|
||||
|
||||
fRow.setData(getPointer(fRowData->at(c)));
|
||||
int currRank = getIntValue(fFieldIndex[0]);
|
||||
|
||||
if (currRank != prevRank)
|
||||
{
|
||||
cumeDist = ((double) (prevRank - 1)) / n0;
|
||||
prevRank = currRank;
|
||||
}
|
||||
|
||||
setDoubleValue(fFieldIndex[0], cumeDist);
|
||||
}
|
||||
setDoubleValue(fFieldIndex[0], cumeDist);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} //namespace
|
||||
} // namespace windowfunction
|
||||
// vim:ts=4 sw=4:
|
||||
|
||||
|
@ -17,41 +17,33 @@
|
||||
|
||||
// $Id: wf_ranking.h 3868 2013-06-06 22:13:05Z xlou $
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
#include "windowfunctiontype.h"
|
||||
|
||||
|
||||
namespace windowfunction
|
||||
{
|
||||
|
||||
|
||||
class WF_ranking : public WindowFunctionType
|
||||
{
|
||||
public:
|
||||
WF_ranking(int id, const std::string& name) : WindowFunctionType(id, name)
|
||||
{
|
||||
resetData();
|
||||
}
|
||||
public:
|
||||
WF_ranking(int id, const std::string& name) : WindowFunctionType(id, name)
|
||||
{
|
||||
resetData();
|
||||
}
|
||||
|
||||
// pure virtual in base
|
||||
void operator()(int64_t b, int64_t e, int64_t c);
|
||||
WindowFunctionType* clone() const;
|
||||
void resetData();
|
||||
// pure virtual in base
|
||||
void operator()(int64_t b, int64_t e, int64_t c);
|
||||
WindowFunctionType* clone() const;
|
||||
void resetData();
|
||||
|
||||
static boost::shared_ptr<WindowFunctionType> makeFunction(int, const string&, int, WindowFunctionColumn*);
|
||||
static boost::shared_ptr<WindowFunctionType> makeFunction(int, const string&, int, WindowFunctionColumn*);
|
||||
|
||||
protected:
|
||||
|
||||
uint64_t fRank;
|
||||
uint64_t fDups;
|
||||
protected:
|
||||
uint64_t fRank;
|
||||
uint64_t fDups;
|
||||
};
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace windowfunction
|
||||
|
||||
// vim:ts=4 sw=4:
|
||||
|
||||
|
@ -17,7 +17,6 @@
|
||||
|
||||
// $Id: wf_row_number.cpp 3932 2013-06-25 16:08:10Z xlou $
|
||||
|
||||
|
||||
//#define NDEBUG
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
@ -48,50 +47,43 @@ using namespace joblist;
|
||||
|
||||
#include "wf_row_number.h"
|
||||
|
||||
|
||||
namespace windowfunction
|
||||
{
|
||||
|
||||
|
||||
boost::shared_ptr<WindowFunctionType> WF_row_number::makeFunction(int id, const string& name, int ct, WindowFunctionColumn* wc)
|
||||
boost::shared_ptr<WindowFunctionType> WF_row_number::makeFunction(int id, const string& name, int ct,
|
||||
WindowFunctionColumn* wc)
|
||||
{
|
||||
boost::shared_ptr<WindowFunctionType> func(new WF_row_number(id, name));
|
||||
return func;
|
||||
boost::shared_ptr<WindowFunctionType> func(new WF_row_number(id, name));
|
||||
return func;
|
||||
}
|
||||
|
||||
|
||||
WindowFunctionType* WF_row_number::clone() const
|
||||
{
|
||||
return new WF_row_number(*this);
|
||||
return new WF_row_number(*this);
|
||||
}
|
||||
|
||||
|
||||
void WF_row_number::resetData()
|
||||
{
|
||||
fRowNumber = 0;
|
||||
fRowNumber = 0;
|
||||
|
||||
WindowFunctionType::resetData();
|
||||
WindowFunctionType::resetData();
|
||||
}
|
||||
|
||||
|
||||
void WF_row_number::operator()(int64_t b, int64_t e, int64_t c)
|
||||
{
|
||||
b = fPartition.first;
|
||||
e = fPartition.second;
|
||||
b = fPartition.first;
|
||||
e = fPartition.second;
|
||||
|
||||
for (c = b; c <= e; c++)
|
||||
{
|
||||
if (c % 1000 == 0 && fStep->cancelled())
|
||||
break;
|
||||
for (c = b; c <= e; c++)
|
||||
{
|
||||
if (c % 1000 == 0 && fStep->cancelled())
|
||||
break;
|
||||
|
||||
fRow.setData(getPointer(fRowData->at(c)));
|
||||
fRowNumber++;
|
||||
fRow.setData(getPointer(fRowData->at(c)));
|
||||
fRowNumber++;
|
||||
|
||||
setIntValue(fFieldIndex[0], fRowNumber);
|
||||
}
|
||||
setIntValue(fFieldIndex[0], fRowNumber);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} //namespace
|
||||
} // namespace windowfunction
|
||||
// vim:ts=4 sw=4:
|
||||
|
||||
|
@ -17,40 +17,32 @@
|
||||
|
||||
// $Id: wf_row_number.h 3868 2013-06-06 22:13:05Z xlou $
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
#include "windowfunctiontype.h"
|
||||
|
||||
|
||||
namespace windowfunction
|
||||
{
|
||||
|
||||
|
||||
class WF_row_number : public WindowFunctionType
|
||||
{
|
||||
public:
|
||||
WF_row_number(int id, const std::string& name) : WindowFunctionType(id, name)
|
||||
{
|
||||
resetData();
|
||||
}
|
||||
public:
|
||||
WF_row_number(int id, const std::string& name) : WindowFunctionType(id, name)
|
||||
{
|
||||
resetData();
|
||||
}
|
||||
|
||||
// pure virtual in base
|
||||
void operator()(int64_t b, int64_t e, int64_t c);
|
||||
WindowFunctionType* clone() const;
|
||||
void resetData();
|
||||
// pure virtual in base
|
||||
void operator()(int64_t b, int64_t e, int64_t c);
|
||||
WindowFunctionType* clone() const;
|
||||
void resetData();
|
||||
|
||||
static boost::shared_ptr<WindowFunctionType> makeFunction(int, const string&, int, WindowFunctionColumn*);
|
||||
static boost::shared_ptr<WindowFunctionType> makeFunction(int, const string&, int, WindowFunctionColumn*);
|
||||
|
||||
protected:
|
||||
|
||||
uint64_t fRowNumber;
|
||||
protected:
|
||||
uint64_t fRowNumber;
|
||||
};
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace windowfunction
|
||||
|
||||
// vim:ts=4 sw=4:
|
||||
|
||||
|
@ -18,7 +18,6 @@
|
||||
|
||||
// $Id: wf_stats.cpp 3932 2013-06-25 16:08:10Z xlou $
|
||||
|
||||
|
||||
//#define NDEBUG
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
@ -49,206 +48,195 @@ using namespace joblist;
|
||||
|
||||
#include "wf_stats.h"
|
||||
|
||||
|
||||
namespace windowfunction
|
||||
{
|
||||
|
||||
|
||||
template<typename T>
|
||||
boost::shared_ptr<WindowFunctionType> WF_stats<T>::makeFunction(int id, const string& name, int ct, WindowFunctionColumn* wc)
|
||||
template <typename T>
|
||||
boost::shared_ptr<WindowFunctionType> WF_stats<T>::makeFunction(int id, const string& name, int ct,
|
||||
WindowFunctionColumn* wc)
|
||||
{
|
||||
boost::shared_ptr<WindowFunctionType> func;
|
||||
boost::shared_ptr<WindowFunctionType> func;
|
||||
|
||||
switch (ct)
|
||||
switch (ct)
|
||||
{
|
||||
case CalpontSystemCatalog::TINYINT:
|
||||
case CalpontSystemCatalog::SMALLINT:
|
||||
case CalpontSystemCatalog::MEDINT:
|
||||
case CalpontSystemCatalog::INT:
|
||||
case CalpontSystemCatalog::BIGINT:
|
||||
{
|
||||
case CalpontSystemCatalog::TINYINT:
|
||||
case CalpontSystemCatalog::SMALLINT:
|
||||
case CalpontSystemCatalog::MEDINT:
|
||||
case CalpontSystemCatalog::INT:
|
||||
case CalpontSystemCatalog::BIGINT:
|
||||
{
|
||||
func.reset(new WF_stats<int64_t>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::UTINYINT:
|
||||
case CalpontSystemCatalog::USMALLINT:
|
||||
case CalpontSystemCatalog::UMEDINT:
|
||||
case CalpontSystemCatalog::UINT:
|
||||
case CalpontSystemCatalog::UBIGINT:
|
||||
{
|
||||
func.reset(new WF_stats<uint64_t>(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_stats<uint64_t>(id, name));
|
||||
else
|
||||
func.reset(new WF_stats<int64_t>(id, name));
|
||||
}
|
||||
else if (width == datatypes::MAXDECIMALWIDTH)
|
||||
{
|
||||
func.reset(new WF_stats<int128_t>(id, name));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::DOUBLE:
|
||||
case CalpontSystemCatalog::UDOUBLE:
|
||||
{
|
||||
func.reset(new WF_stats<double>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::FLOAT:
|
||||
case CalpontSystemCatalog::UFLOAT:
|
||||
{
|
||||
func.reset(new WF_stats<float>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::LONGDOUBLE:
|
||||
{
|
||||
func.reset(new WF_stats<long double>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
string errStr = name + "(" + colType2String[ct] + ")";
|
||||
errStr = IDBErrorInfo::instance()->errorMsg(ERR_WF_INVALID_PARM_TYPE, errStr);
|
||||
cerr << errStr << endl;
|
||||
throw IDBExcept(errStr, ERR_WF_INVALID_PARM_TYPE);
|
||||
|
||||
break;
|
||||
}
|
||||
func.reset(new WF_stats<int64_t>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
return func;
|
||||
case CalpontSystemCatalog::UTINYINT:
|
||||
case CalpontSystemCatalog::USMALLINT:
|
||||
case CalpontSystemCatalog::UMEDINT:
|
||||
case CalpontSystemCatalog::UINT:
|
||||
case CalpontSystemCatalog::UBIGINT:
|
||||
{
|
||||
func.reset(new WF_stats<uint64_t>(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_stats<uint64_t>(id, name));
|
||||
else
|
||||
func.reset(new WF_stats<int64_t>(id, name));
|
||||
}
|
||||
else if (width == datatypes::MAXDECIMALWIDTH)
|
||||
{
|
||||
func.reset(new WF_stats<int128_t>(id, name));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::DOUBLE:
|
||||
case CalpontSystemCatalog::UDOUBLE:
|
||||
{
|
||||
func.reset(new WF_stats<double>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::FLOAT:
|
||||
case CalpontSystemCatalog::UFLOAT:
|
||||
{
|
||||
func.reset(new WF_stats<float>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::LONGDOUBLE:
|
||||
{
|
||||
func.reset(new WF_stats<long double>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
string errStr = name + "(" + colType2String[ct] + ")";
|
||||
errStr = IDBErrorInfo::instance()->errorMsg(ERR_WF_INVALID_PARM_TYPE, errStr);
|
||||
cerr << errStr << endl;
|
||||
throw IDBExcept(errStr, ERR_WF_INVALID_PARM_TYPE);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return func;
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
WindowFunctionType* WF_stats<T>::clone() const
|
||||
{
|
||||
return new WF_stats<T>(*this);
|
||||
return new WF_stats<T>(*this);
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
void WF_stats<T>::resetData()
|
||||
{
|
||||
fSum1 = 0;
|
||||
fSum2 = 0;
|
||||
fCount = 0;
|
||||
fStats = 0.0;
|
||||
fSum1 = 0;
|
||||
fSum2 = 0;
|
||||
fCount = 0;
|
||||
fStats = 0.0;
|
||||
|
||||
WindowFunctionType::resetData();
|
||||
WindowFunctionType::resetData();
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
void WF_stats<T>::operator()(int64_t b, int64_t e, int64_t c)
|
||||
{
|
||||
CDT cdt;
|
||||
if ((fFrameUnit == WF__FRAME_ROWS) ||
|
||||
(fPrev == -1) ||
|
||||
(!fPeer->operator()(getPointer(fRowData->at(c)), getPointer(fRowData->at(fPrev)))))
|
||||
CDT cdt;
|
||||
if ((fFrameUnit == WF__FRAME_ROWS) || (fPrev == -1) ||
|
||||
(!fPeer->operator()(getPointer(fRowData->at(c)), getPointer(fRowData->at(fPrev)))))
|
||||
{
|
||||
// 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++)
|
||||
{
|
||||
// for unbounded - current row special handling
|
||||
if (fPrev >= b && fPrev < c)
|
||||
b = c;
|
||||
else if (fPrev <= e && fPrev > c)
|
||||
e = c;
|
||||
if (i % 1000 == 0 && fStep->cancelled())
|
||||
break;
|
||||
|
||||
uint64_t colIn = fFieldIndex[1];
|
||||
fRow.setData(getPointer(fRowData->at(i)));
|
||||
|
||||
for (int64_t i = b; i <= e; i++)
|
||||
{
|
||||
if (i % 1000 == 0 && fStep->cancelled())
|
||||
break;
|
||||
if (fRow.isNullValue(colIn) == true)
|
||||
continue;
|
||||
|
||||
fRow.setData(getPointer(fRowData->at(i)));
|
||||
T valIn;
|
||||
getValue(colIn, valIn, &cdt);
|
||||
long double val = (long double)valIn;
|
||||
|
||||
if (fRow.isNullValue(colIn) == true)
|
||||
continue;
|
||||
|
||||
T valIn;
|
||||
getValue(colIn, valIn, &cdt);
|
||||
long double val = (long double) valIn;
|
||||
|
||||
fSum1 += val;
|
||||
fSum2 += val * val;
|
||||
fCount++;
|
||||
}
|
||||
|
||||
if (fCount > 1)
|
||||
{
|
||||
uint32_t scale = fRow.getScale(colIn);
|
||||
auto factor = datatypes::scaleDivisor<long double>(scale);
|
||||
long double ldSum1 = fSum1;
|
||||
long double ldSum2 = fSum2;
|
||||
|
||||
// adjust the scale if necessary
|
||||
if (scale != 0 &&
|
||||
cdt != CalpontSystemCatalog::LONGDOUBLE)
|
||||
{
|
||||
ldSum1 /= factor;
|
||||
ldSum2 /= factor * factor;
|
||||
}
|
||||
|
||||
long double stat = ldSum1 * ldSum1 / fCount;
|
||||
stat = ldSum2 - stat;
|
||||
|
||||
if (fFunctionId == WF__STDDEV_POP)
|
||||
stat = sqrt(stat / fCount);
|
||||
else if (fFunctionId == WF__STDDEV_SAMP)
|
||||
stat = sqrt(stat / (fCount - 1));
|
||||
else if (fFunctionId == WF__VAR_POP)
|
||||
stat = stat / fCount;
|
||||
else if (fFunctionId == WF__VAR_SAMP)
|
||||
stat = stat / (fCount - 1);
|
||||
|
||||
fStats = (double) stat;
|
||||
}
|
||||
fSum1 += val;
|
||||
fSum2 += val * val;
|
||||
fCount++;
|
||||
}
|
||||
|
||||
if (fCount == 0)
|
||||
if (fCount > 1)
|
||||
{
|
||||
setValue(CalpontSystemCatalog::DOUBLE, b, e, c, (double*) NULL);
|
||||
}
|
||||
else if (fCount == 1)
|
||||
{
|
||||
if (fFunctionId == WF__STDDEV_SAMP || fFunctionId == WF__VAR_SAMP)
|
||||
{
|
||||
setValue(CalpontSystemCatalog::DOUBLE, b, e, c, (double*) NULL);
|
||||
}
|
||||
else // fFunctionId == WF__STDDEV_POP || fFunctionId == WF__VAR_POP
|
||||
{
|
||||
double temp = 0.0;
|
||||
setValue(CalpontSystemCatalog::DOUBLE, b, e, c, (double*) &temp);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
setValue(CalpontSystemCatalog::DOUBLE, b, e, c, &fStats);
|
||||
}
|
||||
uint32_t scale = fRow.getScale(colIn);
|
||||
auto factor = datatypes::scaleDivisor<long double>(scale);
|
||||
long double ldSum1 = fSum1;
|
||||
long double ldSum2 = fSum2;
|
||||
|
||||
fPrev = c;
|
||||
// adjust the scale if necessary
|
||||
if (scale != 0 && cdt != CalpontSystemCatalog::LONGDOUBLE)
|
||||
{
|
||||
ldSum1 /= factor;
|
||||
ldSum2 /= factor * factor;
|
||||
}
|
||||
|
||||
long double stat = ldSum1 * ldSum1 / fCount;
|
||||
stat = ldSum2 - stat;
|
||||
|
||||
if (fFunctionId == WF__STDDEV_POP)
|
||||
stat = sqrt(stat / fCount);
|
||||
else if (fFunctionId == WF__STDDEV_SAMP)
|
||||
stat = sqrt(stat / (fCount - 1));
|
||||
else if (fFunctionId == WF__VAR_POP)
|
||||
stat = stat / fCount;
|
||||
else if (fFunctionId == WF__VAR_SAMP)
|
||||
stat = stat / (fCount - 1);
|
||||
|
||||
fStats = (double)stat;
|
||||
}
|
||||
}
|
||||
|
||||
if (fCount == 0)
|
||||
{
|
||||
setValue(CalpontSystemCatalog::DOUBLE, b, e, c, (double*)NULL);
|
||||
}
|
||||
else if (fCount == 1)
|
||||
{
|
||||
if (fFunctionId == WF__STDDEV_SAMP || fFunctionId == WF__VAR_SAMP)
|
||||
{
|
||||
setValue(CalpontSystemCatalog::DOUBLE, b, e, c, (double*)NULL);
|
||||
}
|
||||
else // fFunctionId == WF__STDDEV_POP || fFunctionId == WF__VAR_POP
|
||||
{
|
||||
double temp = 0.0;
|
||||
setValue(CalpontSystemCatalog::DOUBLE, b, e, c, (double*)&temp);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
setValue(CalpontSystemCatalog::DOUBLE, b, e, c, &fStats);
|
||||
}
|
||||
|
||||
fPrev = c;
|
||||
}
|
||||
|
||||
template boost::shared_ptr<WindowFunctionType> WF_stats<int64_t>::makeFunction(int, const string&, int,
|
||||
WindowFunctionColumn*);
|
||||
|
||||
template
|
||||
boost::shared_ptr<WindowFunctionType> WF_stats<int64_t>::makeFunction(int, const string&, int, WindowFunctionColumn*);
|
||||
|
||||
|
||||
} //namespace
|
||||
} // namespace windowfunction
|
||||
// vim:ts=4 sw=4:
|
||||
|
||||
|
@ -17,42 +17,35 @@
|
||||
|
||||
// $Id: wf_stats.h 3868 2013-06-06 22:13:05Z xlou $
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "windowfunctiontype.h"
|
||||
|
||||
|
||||
namespace windowfunction
|
||||
{
|
||||
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
class WF_stats : public WindowFunctionType
|
||||
{
|
||||
public:
|
||||
WF_stats(int id, const std::string& name) : WindowFunctionType(id, name)
|
||||
{
|
||||
resetData();
|
||||
}
|
||||
public:
|
||||
WF_stats(int id, const std::string& name) : WindowFunctionType(id, name)
|
||||
{
|
||||
resetData();
|
||||
}
|
||||
|
||||
// pure virtual in base
|
||||
void operator()(int64_t b, int64_t e, int64_t c);
|
||||
WindowFunctionType* clone() const;
|
||||
void resetData();
|
||||
// pure virtual in base
|
||||
void operator()(int64_t b, int64_t e, int64_t c);
|
||||
WindowFunctionType* clone() const;
|
||||
void resetData();
|
||||
|
||||
static boost::shared_ptr<WindowFunctionType> makeFunction(int, const string&, int, WindowFunctionColumn*);
|
||||
static boost::shared_ptr<WindowFunctionType> makeFunction(int, const string&, int, WindowFunctionColumn*);
|
||||
|
||||
protected:
|
||||
long double fSum1;
|
||||
long double fSum2;
|
||||
uint64_t fCount;
|
||||
double fStats;
|
||||
protected:
|
||||
long double fSum1;
|
||||
long double fSum2;
|
||||
uint64_t fCount;
|
||||
double fStats;
|
||||
};
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace windowfunction
|
||||
|
||||
// vim:ts=4 sw=4:
|
||||
|
||||
|
@ -18,7 +18,6 @@
|
||||
|
||||
// $Id: wf_sum_avg.cpp 3932 2013-06-25 16:08:10Z xlou $
|
||||
|
||||
|
||||
//#define NDEBUG
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
@ -49,275 +48,262 @@ using namespace joblist;
|
||||
|
||||
#include "wf_sum_avg.h"
|
||||
|
||||
|
||||
namespace windowfunction
|
||||
{
|
||||
|
||||
template<typename T_IN, typename T_OUT>
|
||||
inline void WF_sum_avg<T_IN,T_OUT>::checkSumLimit(const T_IN& val,
|
||||
const T_OUT& sum)
|
||||
{ }
|
||||
|
||||
template<>
|
||||
inline void WF_sum_avg<int128_t,int128_t>::checkSumLimit(const int128_t& val,
|
||||
const int128_t& sum)
|
||||
template <typename T_IN, typename T_OUT>
|
||||
inline void WF_sum_avg<T_IN, T_OUT>::checkSumLimit(const T_IN& val, const T_OUT& sum)
|
||||
{
|
||||
datatypes::AdditionOverflowCheck ofCheckOp;
|
||||
ofCheckOp(sum, val);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void WF_sum_avg<long double,long double>::checkSumLimit(const long double& val,
|
||||
const long double& sum)
|
||||
{ }
|
||||
template <>
|
||||
inline void WF_sum_avg<int128_t, int128_t>::checkSumLimit(const int128_t& val, const int128_t& sum)
|
||||
{
|
||||
datatypes::AdditionOverflowCheck ofCheckOp;
|
||||
ofCheckOp(sum, val);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void WF_sum_avg<float, long double>::checkSumLimit(const float&,
|
||||
const long double&)
|
||||
{ }
|
||||
template <>
|
||||
inline void WF_sum_avg<long double, long double>::checkSumLimit(const long double& val,
|
||||
const long double& sum)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void WF_sum_avg<long, long double>::checkSumLimit(const long&,
|
||||
const long double&)
|
||||
{ }
|
||||
template <>
|
||||
inline void WF_sum_avg<float, long double>::checkSumLimit(const float&, const long double&)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void WF_sum_avg<unsigned long, long double>::checkSumLimit(const unsigned long&,
|
||||
const long double&)
|
||||
{ }
|
||||
template<>
|
||||
inline void WF_sum_avg<double, long double>::checkSumLimit(const double&,
|
||||
const long double&)
|
||||
{ }
|
||||
template <>
|
||||
inline void WF_sum_avg<long, long double>::checkSumLimit(const long&, const long double&)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
void WF_sum_avg<int128_t,int128_t>::checkSumLimit(const int128_t&, const int128_t&);
|
||||
template<>
|
||||
void WF_sum_avg<long double,long double>::checkSumLimit(const long double& val, const long double&);
|
||||
template<>
|
||||
template <>
|
||||
inline void WF_sum_avg<unsigned long, long double>::checkSumLimit(const unsigned long&, const long double&)
|
||||
{
|
||||
}
|
||||
template <>
|
||||
inline void WF_sum_avg<double, long double>::checkSumLimit(const double&, const long double&)
|
||||
{
|
||||
}
|
||||
|
||||
template <>
|
||||
void WF_sum_avg<int128_t, int128_t>::checkSumLimit(const int128_t&, const int128_t&);
|
||||
template <>
|
||||
void WF_sum_avg<long double, long double>::checkSumLimit(const long double& val, const long double&);
|
||||
template <>
|
||||
void WF_sum_avg<float, long double>::checkSumLimit(const float&, const long double&);
|
||||
template<>
|
||||
template <>
|
||||
void WF_sum_avg<long, long double>::checkSumLimit(const long&, const long double&);
|
||||
template<>
|
||||
void WF_sum_avg<unsigned long, long double>::checkSumLimit(const unsigned long&,
|
||||
const long double&);
|
||||
template<>
|
||||
template <>
|
||||
void WF_sum_avg<unsigned long, long double>::checkSumLimit(const unsigned long&, const long double&);
|
||||
template <>
|
||||
void WF_sum_avg<double, long double>::checkSumLimit(const double&, const long double&);
|
||||
|
||||
template<typename T_IN, typename T_OUT>
|
||||
int128_t WF_sum_avg<T_IN, T_OUT>::calculateAvg(const int128_t& sum,
|
||||
const uint64_t count,
|
||||
const int scale)
|
||||
template <typename T_IN, typename T_OUT>
|
||||
int128_t WF_sum_avg<T_IN, T_OUT>::calculateAvg(const int128_t& sum, const uint64_t count, const int scale)
|
||||
{
|
||||
int128_t avg = 0;
|
||||
int128_t factor;
|
||||
datatypes::getScaleDivisor(factor, scale);
|
||||
if (scale > 0)
|
||||
int128_t avg = 0;
|
||||
int128_t factor;
|
||||
datatypes::getScaleDivisor(factor, scale);
|
||||
if (scale > 0)
|
||||
{
|
||||
if ((sum * factor) / factor == sum)
|
||||
{
|
||||
if ((sum * factor) / factor == sum)
|
||||
{
|
||||
avg = sum * factor;
|
||||
avg /= count;
|
||||
}
|
||||
else
|
||||
{
|
||||
// scale won't fit before divide, we're gonna lose precision.
|
||||
avg = sum / count;
|
||||
if ((avg * factor) / factor != avg) // Still won't fit
|
||||
{
|
||||
string errStr = string("AVG(int)");
|
||||
errStr = IDBErrorInfo::instance()->errorMsg(ERR_WF_OVERFLOW, errStr);
|
||||
cerr << errStr << endl;
|
||||
throw IDBExcept(errStr, ERR_WF_OVERFLOW);
|
||||
}
|
||||
avg *= factor;
|
||||
}
|
||||
avg = sum * factor;
|
||||
avg /= count;
|
||||
}
|
||||
else
|
||||
{
|
||||
avg = sum / count;
|
||||
// scale won't fit before divide, we're gonna lose precision.
|
||||
avg = sum / count;
|
||||
if ((avg * factor) / factor != avg) // Still won't fit
|
||||
{
|
||||
string errStr = string("AVG(int)");
|
||||
errStr = IDBErrorInfo::instance()->errorMsg(ERR_WF_OVERFLOW, errStr);
|
||||
cerr << errStr << endl;
|
||||
throw IDBExcept(errStr, ERR_WF_OVERFLOW);
|
||||
}
|
||||
avg *= factor;
|
||||
}
|
||||
|
||||
avg += (avg < 0) ? (-0.5) : (0.5);
|
||||
return avg;
|
||||
}
|
||||
else
|
||||
{
|
||||
avg = sum / count;
|
||||
}
|
||||
|
||||
avg += (avg < 0) ? (-0.5) : (0.5);
|
||||
return avg;
|
||||
}
|
||||
|
||||
template<typename T_IN, typename T_OUT>
|
||||
inline long double WF_sum_avg<T_IN, T_OUT>::calculateAvg(const long double& sum,
|
||||
const uint64_t count,
|
||||
const int scale)
|
||||
template <typename T_IN, typename T_OUT>
|
||||
inline long double WF_sum_avg<T_IN, T_OUT>::calculateAvg(const long double& sum, const uint64_t count,
|
||||
const int scale)
|
||||
{
|
||||
return sum / count;
|
||||
return sum / count;
|
||||
}
|
||||
|
||||
// For the static function makeFunction, the template parameters are ignored
|
||||
template<typename T_IN, typename T_OUT>
|
||||
boost::shared_ptr<WindowFunctionType> WF_sum_avg<T_IN, T_OUT>::makeFunction(int id, const string& name, int ct, WindowFunctionColumn* wc)
|
||||
template <typename T_IN, typename T_OUT>
|
||||
boost::shared_ptr<WindowFunctionType> WF_sum_avg<T_IN, T_OUT>::makeFunction(int id, const string& name,
|
||||
int ct, WindowFunctionColumn* wc)
|
||||
{
|
||||
boost::shared_ptr<WindowFunctionType> func;
|
||||
switch (ct)
|
||||
boost::shared_ptr<WindowFunctionType> func;
|
||||
switch (ct)
|
||||
{
|
||||
case CalpontSystemCatalog::TINYINT:
|
||||
case CalpontSystemCatalog::SMALLINT:
|
||||
case CalpontSystemCatalog::MEDINT:
|
||||
case CalpontSystemCatalog::INT:
|
||||
case CalpontSystemCatalog::BIGINT:
|
||||
{
|
||||
case CalpontSystemCatalog::TINYINT:
|
||||
case CalpontSystemCatalog::SMALLINT:
|
||||
case CalpontSystemCatalog::MEDINT:
|
||||
case CalpontSystemCatalog::INT:
|
||||
case CalpontSystemCatalog::BIGINT:
|
||||
{
|
||||
// Look into using int128_t instead of long double
|
||||
func.reset(new WF_sum_avg<int64_t, long double>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::UTINYINT:
|
||||
case CalpontSystemCatalog::USMALLINT:
|
||||
case CalpontSystemCatalog::UMEDINT:
|
||||
case CalpontSystemCatalog::UINT:
|
||||
case CalpontSystemCatalog::UBIGINT:
|
||||
{
|
||||
func.reset(new WF_sum_avg<uint64_t, long double>(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_sum_avg<uint64_t, int128_t>(id, name));
|
||||
else
|
||||
func.reset(new WF_sum_avg<int64_t, int128_t>(id, name));
|
||||
}
|
||||
else if (width == datatypes::MAXDECIMALWIDTH)
|
||||
{
|
||||
func.reset(new WF_sum_avg<int128_t, int128_t>(id, name));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::DOUBLE:
|
||||
case CalpontSystemCatalog::UDOUBLE:
|
||||
{
|
||||
func.reset(new WF_sum_avg<double, long double>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::FLOAT:
|
||||
case CalpontSystemCatalog::UFLOAT:
|
||||
{
|
||||
func.reset(new WF_sum_avg<float, long double>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::LONGDOUBLE:
|
||||
{
|
||||
func.reset(new WF_sum_avg<long double, long double>(id, name));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
string errStr = name + "(" + colType2String[ct] + ")";
|
||||
errStr = IDBErrorInfo::instance()->errorMsg(ERR_WF_INVALID_PARM_TYPE, errStr);
|
||||
cerr << errStr << endl;
|
||||
throw IDBExcept(errStr, ERR_WF_INVALID_PARM_TYPE);
|
||||
|
||||
break;
|
||||
}
|
||||
// Look into using int128_t instead of long double
|
||||
func.reset(new WF_sum_avg<int64_t, long double>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
return func;
|
||||
case CalpontSystemCatalog::UTINYINT:
|
||||
case CalpontSystemCatalog::USMALLINT:
|
||||
case CalpontSystemCatalog::UMEDINT:
|
||||
case CalpontSystemCatalog::UINT:
|
||||
case CalpontSystemCatalog::UBIGINT:
|
||||
{
|
||||
func.reset(new WF_sum_avg<uint64_t, long double>(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_sum_avg<uint64_t, int128_t>(id, name));
|
||||
else
|
||||
func.reset(new WF_sum_avg<int64_t, int128_t>(id, name));
|
||||
}
|
||||
else if (width == datatypes::MAXDECIMALWIDTH)
|
||||
{
|
||||
func.reset(new WF_sum_avg<int128_t, int128_t>(id, name));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::DOUBLE:
|
||||
case CalpontSystemCatalog::UDOUBLE:
|
||||
{
|
||||
func.reset(new WF_sum_avg<double, long double>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::FLOAT:
|
||||
case CalpontSystemCatalog::UFLOAT:
|
||||
{
|
||||
func.reset(new WF_sum_avg<float, long double>(id, name));
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::LONGDOUBLE:
|
||||
{
|
||||
func.reset(new WF_sum_avg<long double, long double>(id, name));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
string errStr = name + "(" + colType2String[ct] + ")";
|
||||
errStr = IDBErrorInfo::instance()->errorMsg(ERR_WF_INVALID_PARM_TYPE, errStr);
|
||||
cerr << errStr << endl;
|
||||
throw IDBExcept(errStr, ERR_WF_INVALID_PARM_TYPE);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return func;
|
||||
}
|
||||
|
||||
|
||||
template<typename T_IN, typename T_OUT>
|
||||
template <typename T_IN, typename T_OUT>
|
||||
WindowFunctionType* WF_sum_avg<T_IN, T_OUT>::clone() const
|
||||
{
|
||||
return new WF_sum_avg<T_IN, T_OUT>(*this);
|
||||
return new WF_sum_avg<T_IN, T_OUT>(*this);
|
||||
}
|
||||
|
||||
|
||||
template<typename T_IN, typename T_OUT>
|
||||
template <typename T_IN, typename T_OUT>
|
||||
void WF_sum_avg<T_IN, T_OUT>::resetData()
|
||||
{
|
||||
fAvg = 0;
|
||||
fSum = 0;
|
||||
fCount = 0;
|
||||
fSet.clear();
|
||||
fAvg = 0;
|
||||
fSum = 0;
|
||||
fCount = 0;
|
||||
fSet.clear();
|
||||
|
||||
WindowFunctionType::resetData();
|
||||
WindowFunctionType::resetData();
|
||||
}
|
||||
|
||||
|
||||
template<typename T_IN, typename T_OUT>
|
||||
template <typename T_IN, typename T_OUT>
|
||||
void WF_sum_avg<T_IN, T_OUT>::operator()(int64_t b, int64_t e, int64_t c)
|
||||
{
|
||||
uint64_t colOut = fFieldIndex[0];
|
||||
uint64_t colOut = fFieldIndex[0];
|
||||
|
||||
if ((fFrameUnit == WF__FRAME_ROWS) ||
|
||||
(fPrev == -1) ||
|
||||
(!fPeer->operator()(getPointer(fRowData->at(c)), getPointer(fRowData->at(fPrev)))))
|
||||
if ((fFrameUnit == WF__FRAME_ROWS) || (fPrev == -1) ||
|
||||
(!fPeer->operator()(getPointer(fRowData->at(c)), getPointer(fRowData->at(fPrev)))))
|
||||
{
|
||||
// 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];
|
||||
int scale = fRow.getScale(colOut) - fRow.getScale(colIn);
|
||||
for (int64_t i = b; i <= e; i++)
|
||||
{
|
||||
// for unbounded - current row special handling
|
||||
if (fPrev >= b && fPrev < c)
|
||||
b = c;
|
||||
else if (fPrev <= e && fPrev > c)
|
||||
e = c;
|
||||
if (i % 1000 == 0 && fStep->cancelled())
|
||||
break;
|
||||
|
||||
uint64_t colIn = fFieldIndex[1];
|
||||
int scale = fRow.getScale(colOut) - fRow.getScale(colIn);
|
||||
for (int64_t i = b; i <= e; i++)
|
||||
{
|
||||
if (i % 1000 == 0 && fStep->cancelled())
|
||||
break;
|
||||
fRow.setData(getPointer(fRowData->at(i)));
|
||||
|
||||
fRow.setData(getPointer(fRowData->at(i)));
|
||||
if (fRow.isNullValue(colIn) == true)
|
||||
continue;
|
||||
|
||||
if (fRow.isNullValue(colIn) == true)
|
||||
continue;
|
||||
CDT cdt;
|
||||
getValue(colIn, fVal, &cdt);
|
||||
|
||||
CDT cdt;
|
||||
getValue(colIn, fVal, &cdt);
|
||||
if ((!fDistinct) || (fSet.find(fVal) == fSet.end()))
|
||||
{
|
||||
checkSumLimit(fVal, fSum);
|
||||
fSum += (T_OUT)fVal;
|
||||
fCount++;
|
||||
|
||||
if ((!fDistinct) || (fSet.find(fVal) == fSet.end()))
|
||||
{
|
||||
checkSumLimit(fVal, fSum);
|
||||
fSum += (T_OUT)fVal;
|
||||
fCount++;
|
||||
|
||||
if (fDistinct)
|
||||
fSet.insert(fVal);
|
||||
}
|
||||
}
|
||||
|
||||
if ((fCount > 0) && (fFunctionId == WF__AVG || fFunctionId == WF__AVG_DISTINCT))
|
||||
{
|
||||
fAvg = calculateAvg(fSum, fCount, scale);
|
||||
}
|
||||
if (fDistinct)
|
||||
fSet.insert(fVal);
|
||||
}
|
||||
}
|
||||
|
||||
T_OUT* v = NULL;
|
||||
|
||||
if (fCount > 0)
|
||||
if ((fCount > 0) && (fFunctionId == WF__AVG || fFunctionId == WF__AVG_DISTINCT))
|
||||
{
|
||||
if (fFunctionId == WF__AVG || fFunctionId == WF__AVG_DISTINCT)
|
||||
v = &fAvg;
|
||||
else
|
||||
v = &fSum;
|
||||
fAvg = calculateAvg(fSum, fCount, scale);
|
||||
}
|
||||
}
|
||||
|
||||
setValue(fRow.getColType(colOut), b, e, c, v);
|
||||
T_OUT* v = NULL;
|
||||
|
||||
fPrev = c;
|
||||
if (fCount > 0)
|
||||
{
|
||||
if (fFunctionId == WF__AVG || fFunctionId == WF__AVG_DISTINCT)
|
||||
v = &fAvg;
|
||||
else
|
||||
v = &fSum;
|
||||
}
|
||||
|
||||
setValue(fRow.getColType(colOut), b, e, c, v);
|
||||
|
||||
fPrev = c;
|
||||
}
|
||||
|
||||
template boost::shared_ptr<WindowFunctionType> WF_sum_avg<int64_t, long double>::makeFunction(
|
||||
int, const string&, int, WindowFunctionColumn*);
|
||||
|
||||
template
|
||||
boost::shared_ptr<WindowFunctionType> WF_sum_avg<int64_t, long double>::makeFunction(int, const string&, int, WindowFunctionColumn*);
|
||||
|
||||
|
||||
} //namespace
|
||||
} // namespace windowfunction
|
||||
// vim:ts=4 sw=4:
|
||||
|
||||
|
@ -18,51 +18,46 @@
|
||||
|
||||
// $Id: wf_sum_avg.h 3868 2013-06-06 22:13:05Z xlou $
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
#include "windowfunctiontype.h"
|
||||
|
||||
|
||||
namespace windowfunction
|
||||
{
|
||||
|
||||
// T_IN is the data type of the input values.
|
||||
// T_OUT is the data type we are using for output and internal values
|
||||
template<typename T_IN, typename T_OUT>
|
||||
// T_OUT is the data type we are using for output and internal values
|
||||
template <typename T_IN, typename T_OUT>
|
||||
class WF_sum_avg : public WindowFunctionType
|
||||
{
|
||||
public:
|
||||
WF_sum_avg(int id, const std::string& name) :
|
||||
WindowFunctionType(id, name), fDistinct(id != WF__SUM && id != WF__AVG)
|
||||
{
|
||||
resetData();
|
||||
}
|
||||
public:
|
||||
WF_sum_avg(int id, const std::string& name)
|
||||
: WindowFunctionType(id, name), fDistinct(id != WF__SUM && id != WF__AVG)
|
||||
{
|
||||
resetData();
|
||||
}
|
||||
|
||||
// pure virtual in base
|
||||
void operator()(int64_t b, int64_t e, int64_t c);
|
||||
WindowFunctionType* clone() const;
|
||||
void resetData();
|
||||
// pure virtual in base
|
||||
void operator()(int64_t b, int64_t e, int64_t c);
|
||||
WindowFunctionType* clone() const;
|
||||
void resetData();
|
||||
|
||||
static boost::shared_ptr<WindowFunctionType> makeFunction(int, const string&, int, WindowFunctionColumn*);
|
||||
static boost::shared_ptr<WindowFunctionType> makeFunction(int, const string&, int, WindowFunctionColumn*);
|
||||
|
||||
protected:
|
||||
T_IN fVal;
|
||||
T_OUT fAvg;
|
||||
T_OUT fSum;
|
||||
uint64_t fCount;
|
||||
bool fDistinct;
|
||||
std::set<T_IN> fSet;
|
||||
protected:
|
||||
T_IN fVal;
|
||||
T_OUT fAvg;
|
||||
T_OUT fSum;
|
||||
uint64_t fCount;
|
||||
bool fDistinct;
|
||||
std::set<T_IN> fSet;
|
||||
|
||||
void checkSumLimit(const T_IN& val, const T_OUT& sum);
|
||||
void checkSumLimit(const T_IN& val, const T_OUT& sum);
|
||||
|
||||
int128_t calculateAvg(const int128_t& sum, const uint64_t count, const int scale);
|
||||
long double calculateAvg(const long double& sum, const uint64_t count, const int scale);
|
||||
int128_t calculateAvg(const int128_t& sum, const uint64_t count, const int scale);
|
||||
long double calculateAvg(const long double& sum, const uint64_t count, const int scale);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace windowfunction
|
||||
|
||||
// vim:ts=4 sw=4:
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -17,7 +17,6 @@
|
||||
51 Franklin St., Fifth Floor, Boston, MA 02110, USA
|
||||
*************************************************************************************/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef _MSC_VER
|
||||
@ -28,90 +27,89 @@
|
||||
#include "windowfunctiontype.h"
|
||||
#include "mcsv1_udaf.h"
|
||||
|
||||
|
||||
namespace windowfunction
|
||||
{
|
||||
// Hash classes for the distinct hashmap
|
||||
class DistinctHasher
|
||||
{
|
||||
public:
|
||||
inline size_t operator()(const static_any::any& a) const
|
||||
{
|
||||
return a.getHash();
|
||||
}
|
||||
public:
|
||||
inline size_t operator()(const static_any::any& a) const
|
||||
{
|
||||
return a.getHash();
|
||||
}
|
||||
};
|
||||
|
||||
class DistinctEqual
|
||||
{
|
||||
public:
|
||||
inline bool operator()(const static_any::any lhs, static_any::any rhs) const
|
||||
{
|
||||
return lhs == rhs;
|
||||
}
|
||||
public:
|
||||
inline bool operator()(const static_any::any lhs, static_any::any rhs) const
|
||||
{
|
||||
return lhs == rhs;
|
||||
}
|
||||
};
|
||||
|
||||
// A class to control the execution of User Define Analytic Functions (UDAnF)
|
||||
// as defined by a specialization of mcsv1sdk::mcsv1_UDAF
|
||||
class WF_udaf : public WindowFunctionType
|
||||
{
|
||||
public:
|
||||
WF_udaf(int id, const std::string& name, mcsv1sdk::mcsv1Context& context) :
|
||||
WindowFunctionType(id, name), fUDAFContext(context), fDistinct(false), bHasDropValue(true) {}
|
||||
WF_udaf(WF_udaf& rhs);
|
||||
// pure virtual in base
|
||||
void operator()(int64_t b, int64_t e, int64_t c);
|
||||
WindowFunctionType* clone() const;
|
||||
void resetData();
|
||||
void parseParms(const std::vector<execplan::SRCP>&);
|
||||
virtual bool dropValues(int64_t, int64_t);
|
||||
public:
|
||||
WF_udaf(int id, const std::string& name, mcsv1sdk::mcsv1Context& context)
|
||||
: WindowFunctionType(id, name), fUDAFContext(context), fDistinct(false), bHasDropValue(true)
|
||||
{
|
||||
}
|
||||
WF_udaf(WF_udaf& rhs);
|
||||
// pure virtual in base
|
||||
void operator()(int64_t b, int64_t e, int64_t c);
|
||||
WindowFunctionType* clone() const;
|
||||
void resetData();
|
||||
void parseParms(const std::vector<execplan::SRCP>&);
|
||||
virtual bool dropValues(int64_t, int64_t);
|
||||
|
||||
mcsv1sdk::mcsv1Context& getContext()
|
||||
{
|
||||
return fUDAFContext;
|
||||
}
|
||||
mcsv1sdk::mcsv1Context& getContext()
|
||||
{
|
||||
return fUDAFContext;
|
||||
}
|
||||
|
||||
bool getInterrupted()
|
||||
{
|
||||
return bInterrupted;
|
||||
}
|
||||
bool getInterrupted()
|
||||
{
|
||||
return bInterrupted;
|
||||
}
|
||||
|
||||
bool * getInterruptedPtr()
|
||||
{
|
||||
return &bInterrupted;
|
||||
}
|
||||
bool* getInterruptedPtr()
|
||||
{
|
||||
return &bInterrupted;
|
||||
}
|
||||
|
||||
bool getDistinct()
|
||||
{
|
||||
return fDistinct;
|
||||
}
|
||||
bool getDistinct()
|
||||
{
|
||||
return fDistinct;
|
||||
}
|
||||
|
||||
void setDistinct(bool d = true)
|
||||
{
|
||||
fDistinct = d;
|
||||
}
|
||||
void setDistinct(bool d = true)
|
||||
{
|
||||
fDistinct = d;
|
||||
}
|
||||
|
||||
protected:
|
||||
void SetUDAFValue(static_any::any& valOut, int64_t colOut, int64_t b, int64_t e, int64_t c);
|
||||
protected:
|
||||
void SetUDAFValue(static_any::any& valOut, int64_t colOut, int64_t b, int64_t e, int64_t c);
|
||||
|
||||
mcsv1sdk::mcsv1Context fUDAFContext; // The UDAF context
|
||||
bool bInterrupted; // Shared by all the threads
|
||||
bool fDistinct;
|
||||
bool bRespectNulls; // respect null | ignore null
|
||||
bool bHasDropValue; // Set to false when we discover the UDAnF doesn't implement dropValue.
|
||||
// To hold distinct values and their counts
|
||||
typedef std::tr1::unordered_map<static_any::any, uint64_t, DistinctHasher, DistinctEqual> DistinctMap;
|
||||
DistinctMap fDistinctMap;
|
||||
mcsv1sdk::mcsv1Context fUDAFContext; // The UDAF context
|
||||
bool bInterrupted; // Shared by all the threads
|
||||
bool fDistinct;
|
||||
bool bRespectNulls; // respect null | ignore null
|
||||
bool bHasDropValue; // Set to false when we discover the UDAnF doesn't implement dropValue.
|
||||
// To hold distinct values and their counts
|
||||
typedef std::tr1::unordered_map<static_any::any, uint64_t, DistinctHasher, DistinctEqual> DistinctMap;
|
||||
DistinctMap fDistinctMap;
|
||||
|
||||
static_any::any fValOut; // The return value
|
||||
static_any::any fValOut; // The return value
|
||||
|
||||
public:
|
||||
static boost::shared_ptr<WindowFunctionType> makeFunction(int id, const string& name,
|
||||
int ct, mcsv1sdk::mcsv1Context& context, WindowFunctionColumn* wc);
|
||||
public:
|
||||
static boost::shared_ptr<WindowFunctionType> makeFunction(int id, const string& name, int ct,
|
||||
mcsv1sdk::mcsv1Context& context,
|
||||
WindowFunctionColumn* wc);
|
||||
};
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace windowfunction
|
||||
|
||||
// vim:ts=4 sw=4:
|
||||
|
||||
|
@ -18,7 +18,6 @@
|
||||
MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
|
||||
//#define NDEBUG
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
@ -40,52 +39,46 @@ using namespace rowgroup;
|
||||
|
||||
#include "windowframe.h"
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
string UnitStr[] = {"ROWS", "RANGE"};
|
||||
}
|
||||
|
||||
|
||||
namespace windowfunction
|
||||
{
|
||||
|
||||
|
||||
pair<uint64_t, uint64_t> WindowFrame::getWindow(int64_t b, int64_t e, int64_t c)
|
||||
{
|
||||
int64_t upper = fUpper->getBound(b, e, c);
|
||||
int64_t lower = fLower->getBound(b, e, c);
|
||||
int64_t upper = fUpper->getBound(b, e, c);
|
||||
int64_t lower = fLower->getBound(b, e, c);
|
||||
|
||||
// case 1 || case 2 || case 3
|
||||
if ((upper > lower) || (upper < b && lower < b) || (upper > e && lower > e))
|
||||
{
|
||||
// construct an empty window
|
||||
upper = b + 1;
|
||||
lower = b;
|
||||
}
|
||||
// case 1 || case 2 || case 3
|
||||
if ((upper > lower) || (upper < b && lower < b) || (upper > e && lower > e))
|
||||
{
|
||||
// construct an empty window
|
||||
upper = b + 1;
|
||||
lower = b;
|
||||
}
|
||||
|
||||
if (upper < b) // case 2, lower >= b
|
||||
{
|
||||
upper = b;
|
||||
}
|
||||
if (upper < b) // case 2, lower >= b
|
||||
{
|
||||
upper = b;
|
||||
}
|
||||
|
||||
if (lower > e) // case 3, upper <= e
|
||||
{
|
||||
lower = e;
|
||||
}
|
||||
if (lower > e) // case 3, upper <= e
|
||||
{
|
||||
lower = e;
|
||||
}
|
||||
|
||||
return make_pair(upper, lower);
|
||||
return make_pair(upper, lower);
|
||||
}
|
||||
|
||||
|
||||
const string WindowFrame::toString() const
|
||||
{
|
||||
string ret(UnitStr[fUnit]);
|
||||
ret = ret + " between " + fUpper->toString() + " and " + fLower->toString();
|
||||
string ret(UnitStr[fUnit]);
|
||||
ret = ret + " between " + fUpper->toString() + " and " + fLower->toString();
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
} //namespace
|
||||
} // namespace windowfunction
|
||||
// vim:ts=4 sw=4:
|
||||
|
||||
|
@ -17,112 +17,106 @@
|
||||
|
||||
// $Id: windowframe.h 3932 2013-06-25 16:08:10Z xlou $
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <utility> // std::pair, std::make_pair
|
||||
#include <utility> // std::pair, std::make_pair
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include "framebound.h"
|
||||
|
||||
namespace windowfunction
|
||||
{
|
||||
|
||||
const int64_t WF__FRAME_ROWS = 0;
|
||||
const int64_t WF__FRAME_ROWS = 0;
|
||||
const int64_t WF__FRAME_RANGE = 1;
|
||||
|
||||
|
||||
/** @brief class WindowFrame
|
||||
*
|
||||
*/
|
||||
class WindowFrame
|
||||
{
|
||||
public:
|
||||
/** @brief WindowFrame constructor
|
||||
*/
|
||||
WindowFrame(int64_t t, boost::shared_ptr<FrameBound>& u, boost::shared_ptr<FrameBound>& l) :
|
||||
fUnit(t), fUpper(u), fLower(l)
|
||||
{}
|
||||
public:
|
||||
/** @brief WindowFrame constructor
|
||||
*/
|
||||
WindowFrame(int64_t t, boost::shared_ptr<FrameBound>& u, boost::shared_ptr<FrameBound>& l)
|
||||
: fUnit(t), fUpper(u), fLower(l)
|
||||
{
|
||||
}
|
||||
|
||||
/** @brief WindowFrame copy constructor
|
||||
*/
|
||||
WindowFrame(const WindowFrame& rhs) :
|
||||
fUnit(rhs.fUnit),
|
||||
fUpper(rhs.fUpper->clone()),
|
||||
fLower(rhs.fLower->clone())
|
||||
{}
|
||||
/** @brief WindowFrame copy constructor
|
||||
*/
|
||||
WindowFrame(const WindowFrame& rhs)
|
||||
: fUnit(rhs.fUnit), fUpper(rhs.fUpper->clone()), fLower(rhs.fLower->clone())
|
||||
{
|
||||
}
|
||||
|
||||
/** @brief WindowFrame destructor
|
||||
*/
|
||||
virtual ~WindowFrame() {};
|
||||
/** @brief WindowFrame destructor
|
||||
*/
|
||||
virtual ~WindowFrame(){};
|
||||
|
||||
/** @brief clone
|
||||
*/
|
||||
virtual WindowFrame* clone()
|
||||
{
|
||||
return new WindowFrame(*this);
|
||||
};
|
||||
/** @brief clone
|
||||
*/
|
||||
virtual WindowFrame* clone()
|
||||
{
|
||||
return new WindowFrame(*this);
|
||||
};
|
||||
|
||||
/** @brief virtual void getWindow
|
||||
*/
|
||||
std::pair<uint64_t, uint64_t> getWindow(int64_t, int64_t, int64_t);
|
||||
/** @brief virtual void getWindow
|
||||
*/
|
||||
std::pair<uint64_t, uint64_t> getWindow(int64_t, int64_t, int64_t);
|
||||
|
||||
const std::string toString() const;
|
||||
const std::string toString() const;
|
||||
|
||||
/** @brief set methods
|
||||
*/
|
||||
void setRowMetaData(const rowgroup::RowGroup& g, const rowgroup::Row& r)
|
||||
{
|
||||
fUpper->setRowMetaData(g, r);
|
||||
fLower->setRowMetaData(g, r);
|
||||
}
|
||||
void setRowData(boost::shared_ptr<std::vector<joblist::RowPosition> >& d)
|
||||
{
|
||||
fUpper->setRowData(d);
|
||||
fLower->setRowData(d);
|
||||
}
|
||||
void setCallback(joblist::WindowFunctionStep* s)
|
||||
{
|
||||
fUpper->setCallback(s);
|
||||
fLower->setCallback(s);
|
||||
}
|
||||
/** @brief set methods
|
||||
*/
|
||||
void setRowMetaData(const rowgroup::RowGroup& g, const rowgroup::Row& r)
|
||||
{
|
||||
fUpper->setRowMetaData(g, r);
|
||||
fLower->setRowMetaData(g, r);
|
||||
}
|
||||
void setRowData(boost::shared_ptr<std::vector<joblist::RowPosition> >& d)
|
||||
{
|
||||
fUpper->setRowData(d);
|
||||
fLower->setRowData(d);
|
||||
}
|
||||
void setCallback(joblist::WindowFunctionStep* s)
|
||||
{
|
||||
fUpper->setCallback(s);
|
||||
fLower->setCallback(s);
|
||||
}
|
||||
|
||||
int64_t unit() const
|
||||
{
|
||||
return fUnit;
|
||||
}
|
||||
void unit(int64_t t)
|
||||
{
|
||||
fUnit = t;
|
||||
}
|
||||
const boost::shared_ptr<FrameBound>& upper() const
|
||||
{
|
||||
return fUpper;
|
||||
}
|
||||
void upper(const boost::shared_ptr<FrameBound>& u)
|
||||
{
|
||||
fUpper = u;
|
||||
}
|
||||
const boost::shared_ptr<FrameBound>& lower() const
|
||||
{
|
||||
return fLower;
|
||||
}
|
||||
void lower(const boost::shared_ptr<FrameBound>& l)
|
||||
{
|
||||
fLower = l;
|
||||
}
|
||||
int64_t unit() const
|
||||
{
|
||||
return fUnit;
|
||||
}
|
||||
void unit(int64_t t)
|
||||
{
|
||||
fUnit = t;
|
||||
}
|
||||
const boost::shared_ptr<FrameBound>& upper() const
|
||||
{
|
||||
return fUpper;
|
||||
}
|
||||
void upper(const boost::shared_ptr<FrameBound>& u)
|
||||
{
|
||||
fUpper = u;
|
||||
}
|
||||
const boost::shared_ptr<FrameBound>& lower() const
|
||||
{
|
||||
return fLower;
|
||||
}
|
||||
void lower(const boost::shared_ptr<FrameBound>& l)
|
||||
{
|
||||
fLower = l;
|
||||
}
|
||||
|
||||
protected:
|
||||
protected:
|
||||
// type
|
||||
int64_t fUnit;
|
||||
|
||||
// type
|
||||
int64_t fUnit;
|
||||
|
||||
// data
|
||||
boost::shared_ptr<FrameBound> fUpper;
|
||||
boost::shared_ptr<FrameBound> fLower;
|
||||
// data
|
||||
boost::shared_ptr<FrameBound> fUpper;
|
||||
boost::shared_ptr<FrameBound> fLower;
|
||||
};
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace windowfunction
|
||||
|
||||
// vim:ts=4 sw=4:
|
||||
|
@ -45,232 +45,218 @@ using namespace joblist;
|
||||
#include "windowframe.h"
|
||||
#include "windowfunction.h"
|
||||
|
||||
|
||||
namespace windowfunction
|
||||
{
|
||||
|
||||
WindowFunction::WindowFunction(boost::shared_ptr<WindowFunctionType>& f,
|
||||
boost::shared_ptr<ordering::EqualCompData>& p,
|
||||
boost::shared_ptr<OrderByData>& o,
|
||||
boost::shared_ptr<WindowFrame>& w,
|
||||
const RowGroup& g,
|
||||
const Row& r) :
|
||||
fFunctionType(f), fPartitionBy(p), fOrderBy(o), fFrame(w), fRowGroup(g), fRow(r)
|
||||
boost::shared_ptr<OrderByData>& o, boost::shared_ptr<WindowFrame>& w,
|
||||
const RowGroup& g, const Row& r)
|
||||
: fFunctionType(f), fPartitionBy(p), fOrderBy(o), fFrame(w), fRowGroup(g), fRow(r)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
WindowFunction::~WindowFunction()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void WindowFunction::operator()()
|
||||
{
|
||||
try
|
||||
try
|
||||
{
|
||||
fRowData.reset(new vector<RowPosition>(fStep->getRowData()));
|
||||
|
||||
if (fOrderBy->rule().fCompares.size() > 0)
|
||||
sort(fRowData->begin(), fRowData->size());
|
||||
|
||||
// get partitions
|
||||
if (fPartitionBy.get() != NULL && !fStep->cancelled())
|
||||
{
|
||||
fRowData.reset(new vector<RowPosition>(fStep->getRowData()));
|
||||
int64_t i = 0;
|
||||
int64_t j = 1;
|
||||
int64_t rowCnt = fRowData->size();
|
||||
|
||||
if (fOrderBy->rule().fCompares.size() > 0)
|
||||
sort(fRowData->begin(), fRowData->size());
|
||||
for (j = 1; j < rowCnt; j++)
|
||||
{
|
||||
if ((*(fPartitionBy.get()))(getPointer((*fRowData)[j - 1]), getPointer((*fRowData)[j])))
|
||||
continue;
|
||||
|
||||
// get partitions
|
||||
if (fPartitionBy.get() != NULL && !fStep->cancelled())
|
||||
fPartition.push_back(make_pair(i, j - 1));
|
||||
i = j;
|
||||
}
|
||||
|
||||
fPartition.push_back(make_pair(i, j - 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
fPartition.push_back(make_pair(0, fRowData->size()));
|
||||
}
|
||||
|
||||
// compute partition by partition
|
||||
int64_t uft = fFrame->upper()->boundType();
|
||||
int64_t lft = fFrame->lower()->boundType();
|
||||
bool upperUbnd = (uft == WF__UNBOUNDED_PRECEDING || uft == WF__UNBOUNDED_FOLLOWING);
|
||||
bool lowerUbnd = (lft == WF__UNBOUNDED_PRECEDING || lft == WF__UNBOUNDED_FOLLOWING);
|
||||
bool upperCnrw = (uft == WF__CURRENT_ROW);
|
||||
bool lowerCnrw = (lft == WF__CURRENT_ROW);
|
||||
fFunctionType->setRowData(fRowData);
|
||||
fFunctionType->setRowMetaData(fRowGroup, fRow);
|
||||
fFrame->setRowData(fRowData);
|
||||
fFrame->setRowMetaData(fRowGroup, fRow);
|
||||
|
||||
for (uint64_t k = 0; k < fPartition.size() && !fStep->cancelled(); k++)
|
||||
{
|
||||
fFunctionType->resetData();
|
||||
fFunctionType->partition(fPartition[k]);
|
||||
|
||||
int64_t begin = fPartition[k].first;
|
||||
int64_t end = fPartition[k].second;
|
||||
|
||||
if (upperUbnd && lowerUbnd)
|
||||
{
|
||||
fFunctionType->operator()(begin, end, WF__BOUND_ALL);
|
||||
}
|
||||
else if (upperUbnd && lowerCnrw)
|
||||
{
|
||||
if (fFrame->unit() == WF__FRAME_ROWS)
|
||||
{
|
||||
int64_t i = 0;
|
||||
int64_t j = 1;
|
||||
int64_t rowCnt = fRowData->size();
|
||||
|
||||
for (j = 1; j < rowCnt; j++)
|
||||
{
|
||||
if ((*(fPartitionBy.get()))
|
||||
(getPointer((*fRowData)[j - 1]), getPointer((*fRowData)[j])))
|
||||
continue;
|
||||
|
||||
fPartition.push_back(make_pair(i, j - 1));
|
||||
i = j;
|
||||
}
|
||||
|
||||
fPartition.push_back(make_pair(i, j - 1));
|
||||
for (int64_t i = begin; i <= end && !fStep->cancelled(); i++)
|
||||
{
|
||||
fFunctionType->operator()(begin, i, i);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fPartition.push_back(make_pair(0, fRowData->size()));
|
||||
for (int64_t i = begin; i <= end && !fStep->cancelled(); i++)
|
||||
{
|
||||
pair<int64_t, int64_t> w = fFrame->getWindow(begin, end, i);
|
||||
int64_t j = i;
|
||||
|
||||
if (w.second > i)
|
||||
j = w.second;
|
||||
|
||||
fFunctionType->operator()(begin, j, i);
|
||||
}
|
||||
}
|
||||
|
||||
// compute partition by partition
|
||||
int64_t uft = fFrame->upper()->boundType();
|
||||
int64_t lft = fFrame->lower()->boundType();
|
||||
bool upperUbnd = (uft == WF__UNBOUNDED_PRECEDING || uft == WF__UNBOUNDED_FOLLOWING);
|
||||
bool lowerUbnd = (lft == WF__UNBOUNDED_PRECEDING || lft == WF__UNBOUNDED_FOLLOWING);
|
||||
bool upperCnrw = (uft == WF__CURRENT_ROW);
|
||||
bool lowerCnrw = (lft == WF__CURRENT_ROW);
|
||||
fFunctionType->setRowData(fRowData);
|
||||
fFunctionType->setRowMetaData(fRowGroup, fRow);
|
||||
fFrame->setRowData(fRowData);
|
||||
fFrame->setRowMetaData(fRowGroup, fRow);
|
||||
|
||||
for (uint64_t k = 0; k < fPartition.size() && !fStep->cancelled(); k++)
|
||||
}
|
||||
else if (upperCnrw && lowerUbnd)
|
||||
{
|
||||
if (fFrame->unit() == WF__FRAME_ROWS)
|
||||
{
|
||||
fFunctionType->resetData();
|
||||
fFunctionType->partition(fPartition[k]);
|
||||
|
||||
int64_t begin = fPartition[k].first;
|
||||
int64_t end = fPartition[k].second;
|
||||
|
||||
if (upperUbnd && lowerUbnd)
|
||||
{
|
||||
fFunctionType->operator()(begin, end, WF__BOUND_ALL);
|
||||
}
|
||||
else if (upperUbnd && lowerCnrw)
|
||||
{
|
||||
if (fFrame->unit() == WF__FRAME_ROWS)
|
||||
{
|
||||
for (int64_t i = begin; i <= end && !fStep->cancelled(); i++)
|
||||
{
|
||||
fFunctionType->operator()(begin, i, i);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int64_t i = begin; i <= end && !fStep->cancelled(); i++)
|
||||
{
|
||||
pair<int64_t, int64_t> w = fFrame->getWindow(begin, end, i);
|
||||
int64_t j = i;
|
||||
|
||||
if (w.second > i)
|
||||
j = w.second;
|
||||
|
||||
fFunctionType->operator()(begin, j, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (upperCnrw && lowerUbnd)
|
||||
{
|
||||
if (fFrame->unit() == WF__FRAME_ROWS)
|
||||
{
|
||||
for (int64_t i = end; i >= begin && !fStep->cancelled(); i--)
|
||||
{
|
||||
fFunctionType->operator()(i, end, i);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int64_t i = end; i >= begin && !fStep->cancelled(); i--)
|
||||
{
|
||||
pair<int64_t, int64_t> w = fFrame->getWindow(begin, end, i);
|
||||
int64_t j = i;
|
||||
|
||||
if (w.first < i)
|
||||
j = w.first;
|
||||
|
||||
fFunctionType->operator()(j, end, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pair<int64_t, int64_t> w;
|
||||
pair<int64_t, int64_t> prevFrame;
|
||||
int64_t b, e;
|
||||
bool firstTime = true;
|
||||
|
||||
for (int64_t i = begin; i <= end && !fStep->cancelled(); i++)
|
||||
{
|
||||
w = fFrame->getWindow(begin, end, i);
|
||||
b = w.first;
|
||||
e = w.second;
|
||||
|
||||
if (firstTime)
|
||||
{
|
||||
prevFrame = w;
|
||||
}
|
||||
|
||||
// UDAnF functions may have a dropValue function implemented.
|
||||
// If they do, we can optimize by calling dropValue() for those
|
||||
// values leaving the window and nextValue for those entering, rather
|
||||
// than a resetData() and then iterating over the entire window.
|
||||
// Built-in functions may have this functionality added in the future.
|
||||
// If b > e then the frame is entirely outside of the partition
|
||||
// and there's no values to drop
|
||||
if (!firstTime && (b <= e) && fFunctionType->dropValues(prevFrame.first, w.first))
|
||||
{
|
||||
// Adjust the beginning of the frame for nextValue
|
||||
// to start where the previous frame left off.
|
||||
b = prevFrame.second + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If dropValues failed or doesn't exist,
|
||||
// calculate the entire frame.
|
||||
fFunctionType->resetData();
|
||||
}
|
||||
fFunctionType->operator()(b, e, i); // UDAnF: Calls nextValue and evaluate
|
||||
prevFrame = w;
|
||||
firstTime = false;
|
||||
}
|
||||
}
|
||||
for (int64_t i = end; i >= begin && !fStep->cancelled(); i--)
|
||||
{
|
||||
fFunctionType->operator()(i, end, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
fStep->handleException(std::current_exception(),
|
||||
logging::ERR_EXECUTE_WINDOW_FUNCTION,
|
||||
logging::ERR_WF_DATA_SET_TOO_BIG,
|
||||
"WindowFunction::operator()");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int64_t i = end; i >= begin && !fStep->cancelled(); i--)
|
||||
{
|
||||
pair<int64_t, int64_t> w = fFrame->getWindow(begin, end, i);
|
||||
int64_t j = i;
|
||||
|
||||
if (w.first < i)
|
||||
j = w.first;
|
||||
|
||||
fFunctionType->operator()(j, end, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pair<int64_t, int64_t> w;
|
||||
pair<int64_t, int64_t> prevFrame;
|
||||
int64_t b, e;
|
||||
bool firstTime = true;
|
||||
|
||||
for (int64_t i = begin; i <= end && !fStep->cancelled(); i++)
|
||||
{
|
||||
w = fFrame->getWindow(begin, end, i);
|
||||
b = w.first;
|
||||
e = w.second;
|
||||
|
||||
if (firstTime)
|
||||
{
|
||||
prevFrame = w;
|
||||
}
|
||||
|
||||
// UDAnF functions may have a dropValue function implemented.
|
||||
// If they do, we can optimize by calling dropValue() for those
|
||||
// values leaving the window and nextValue for those entering, rather
|
||||
// than a resetData() and then iterating over the entire window.
|
||||
// Built-in functions may have this functionality added in the future.
|
||||
// If b > e then the frame is entirely outside of the partition
|
||||
// and there's no values to drop
|
||||
if (!firstTime && (b <= e) && fFunctionType->dropValues(prevFrame.first, w.first))
|
||||
{
|
||||
// Adjust the beginning of the frame for nextValue
|
||||
// to start where the previous frame left off.
|
||||
b = prevFrame.second + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If dropValues failed or doesn't exist,
|
||||
// calculate the entire frame.
|
||||
fFunctionType->resetData();
|
||||
}
|
||||
fFunctionType->operator()(b, e, i); // UDAnF: Calls nextValue and evaluate
|
||||
prevFrame = w;
|
||||
firstTime = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
fStep->handleException(std::current_exception(), logging::ERR_EXECUTE_WINDOW_FUNCTION,
|
||||
logging::ERR_WF_DATA_SET_TOO_BIG, "WindowFunction::operator()");
|
||||
}
|
||||
}
|
||||
|
||||
void WindowFunction::setCallback(joblist::WindowFunctionStep* step, int id)
|
||||
{
|
||||
fStep = step;
|
||||
fId = id;
|
||||
fFunctionType->setCallback(step);
|
||||
fFrame->setCallback(step);
|
||||
fStep = step;
|
||||
fId = id;
|
||||
fFunctionType->setCallback(step);
|
||||
fFrame->setCallback(step);
|
||||
}
|
||||
|
||||
|
||||
const Row& WindowFunction::getRow() const
|
||||
{
|
||||
return fRow;
|
||||
return fRow;
|
||||
}
|
||||
|
||||
|
||||
void WindowFunction::sort(std::vector<RowPosition>::iterator v, uint64_t n)
|
||||
{
|
||||
// recursive function termination condition.
|
||||
if (n < 2 || fStep->cancelled())
|
||||
return;
|
||||
// recursive function termination condition.
|
||||
if (n < 2 || fStep->cancelled())
|
||||
return;
|
||||
|
||||
RowPosition p = *(v + n / 2); // pivot value
|
||||
vector<RowPosition>::iterator l = v; // low address
|
||||
vector<RowPosition>::iterator h = v + (n - 1); // high address
|
||||
RowPosition p = *(v + n / 2); // pivot value
|
||||
vector<RowPosition>::iterator l = v; // low address
|
||||
vector<RowPosition>::iterator h = v + (n - 1); // high address
|
||||
|
||||
while (l <= h && !(fStep->cancelled()))
|
||||
while (l <= h && !(fStep->cancelled()))
|
||||
{
|
||||
// Can use while here, but need check boundary and cancel status.
|
||||
if (fOrderBy->operator()(getPointer(*l), getPointer(p)))
|
||||
{
|
||||
// Can use while here, but need check boundary and cancel status.
|
||||
if (fOrderBy->operator()(getPointer(*l), getPointer(p)))
|
||||
{
|
||||
l++;
|
||||
}
|
||||
else if (fOrderBy->operator()(getPointer(p), getPointer(*h)))
|
||||
{
|
||||
h--;
|
||||
}
|
||||
else
|
||||
{
|
||||
RowPosition t = *l; // temp value for swap
|
||||
*l++ = *h;
|
||||
*h-- = t;
|
||||
}
|
||||
l++;
|
||||
}
|
||||
else if (fOrderBy->operator()(getPointer(p), getPointer(*h)))
|
||||
{
|
||||
h--;
|
||||
}
|
||||
else
|
||||
{
|
||||
RowPosition t = *l; // temp value for swap
|
||||
*l++ = *h;
|
||||
*h-- = t;
|
||||
}
|
||||
}
|
||||
|
||||
sort(v, std::distance(v, h) + 1);
|
||||
sort(l, std::distance(l, v) + n);
|
||||
sort(v, std::distance(v, h) + 1);
|
||||
sort(l, std::distance(l, v) + n);
|
||||
}
|
||||
|
||||
|
||||
} //namespace
|
||||
} // namespace windowfunction
|
||||
// vim:ts=4 sw=4:
|
||||
|
||||
|
@ -17,7 +17,6 @@
|
||||
|
||||
// $Id: windowfunction.h 3932 2013-06-25 16:08:10Z xlou $
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
@ -33,93 +32,83 @@ namespace ordering
|
||||
// forward reference
|
||||
class EqualCompData;
|
||||
class OrderByData;
|
||||
};
|
||||
|
||||
}; // namespace ordering
|
||||
|
||||
namespace windowfunction
|
||||
{
|
||||
|
||||
// forward reference
|
||||
class WindowFunctionType;
|
||||
class WindowFrame;
|
||||
|
||||
|
||||
/** @brief class WindowFunction
|
||||
*
|
||||
*/
|
||||
class WindowFunction
|
||||
{
|
||||
public:
|
||||
/** @brief WindowFunction constructor
|
||||
* @param f: shared pointer to a WindowFuncitonType
|
||||
* @param p: shared pointer to equal compare functor
|
||||
* @param o: shared pointer to order by functor
|
||||
* @param w: shared pointer to window specification
|
||||
* @param r: row meta data
|
||||
*/
|
||||
WindowFunction(boost::shared_ptr<WindowFunctionType>& f,
|
||||
boost::shared_ptr<ordering::EqualCompData>& p,
|
||||
boost::shared_ptr<ordering::OrderByData>& o,
|
||||
boost::shared_ptr<WindowFrame>& w,
|
||||
const rowgroup::RowGroup& g,
|
||||
const rowgroup::Row& r);
|
||||
public:
|
||||
/** @brief WindowFunction constructor
|
||||
* @param f: shared pointer to a WindowFuncitonType
|
||||
* @param p: shared pointer to equal compare functor
|
||||
* @param o: shared pointer to order by functor
|
||||
* @param w: shared pointer to window specification
|
||||
* @param r: row meta data
|
||||
*/
|
||||
WindowFunction(boost::shared_ptr<WindowFunctionType>& f, boost::shared_ptr<ordering::EqualCompData>& p,
|
||||
boost::shared_ptr<ordering::OrderByData>& o, boost::shared_ptr<WindowFrame>& w,
|
||||
const rowgroup::RowGroup& g, const rowgroup::Row& r);
|
||||
|
||||
/** @brief WindowFunction destructor
|
||||
*/
|
||||
virtual ~WindowFunction();
|
||||
/** @brief WindowFunction destructor
|
||||
*/
|
||||
virtual ~WindowFunction();
|
||||
|
||||
/** @brief virtual void Run method
|
||||
*/
|
||||
void operator()();
|
||||
/** @brief virtual void Run method
|
||||
*/
|
||||
void operator()();
|
||||
|
||||
const std::string toString() const;
|
||||
const std::string toString() const;
|
||||
|
||||
void setCallback(joblist::WindowFunctionStep*, int);
|
||||
const rowgroup::Row& getRow() const;
|
||||
void setCallback(joblist::WindowFunctionStep*, int);
|
||||
const rowgroup::Row& getRow() const;
|
||||
|
||||
protected:
|
||||
// cancellable sort function
|
||||
void sort(std::vector<joblist::RowPosition>::iterator, uint64_t);
|
||||
|
||||
protected:
|
||||
// special window frames
|
||||
void processUnboundedWindowFrame1();
|
||||
void processUnboundedWindowFrame2();
|
||||
void processUnboundedWindowFrame3();
|
||||
void processExprWindowFrame();
|
||||
|
||||
// cancellable sort function
|
||||
void sort(std::vector<joblist::RowPosition>::iterator, uint64_t);
|
||||
// for string table
|
||||
rowgroup::Row::Pointer getPointer(joblist::RowPosition& r)
|
||||
{
|
||||
return fStep->getPointer(r, fRowGroup, fRow);
|
||||
}
|
||||
|
||||
// special window frames
|
||||
void processUnboundedWindowFrame1();
|
||||
void processUnboundedWindowFrame2();
|
||||
void processUnboundedWindowFrame3();
|
||||
void processExprWindowFrame();
|
||||
// function type
|
||||
boost::shared_ptr<WindowFunctionType> fFunctionType;
|
||||
|
||||
// for string table
|
||||
rowgroup::Row::Pointer getPointer(joblist::RowPosition& r)
|
||||
{
|
||||
return fStep->getPointer(r, fRowGroup, fRow);
|
||||
}
|
||||
// window clause
|
||||
boost::shared_ptr<ordering::EqualCompData> fPartitionBy;
|
||||
boost::shared_ptr<ordering::OrderByData> fOrderBy;
|
||||
boost::shared_ptr<WindowFrame> fFrame;
|
||||
std::vector<std::pair<int64_t, int64_t> > fPartition;
|
||||
|
||||
// function type
|
||||
boost::shared_ptr<WindowFunctionType> fFunctionType;
|
||||
// data
|
||||
boost::shared_ptr<std::vector<joblist::RowPosition> > fRowData;
|
||||
|
||||
// window clause
|
||||
boost::shared_ptr<ordering::EqualCompData> fPartitionBy;
|
||||
boost::shared_ptr<ordering::OrderByData> fOrderBy;
|
||||
boost::shared_ptr<WindowFrame> fFrame;
|
||||
std::vector<std::pair<int64_t, int64_t> > fPartition;
|
||||
// row meta data
|
||||
rowgroup::RowGroup fRowGroup;
|
||||
rowgroup::Row fRow;
|
||||
|
||||
// data
|
||||
boost::shared_ptr<std::vector<joblist::RowPosition> > fRowData;
|
||||
// pointer back to step
|
||||
joblist::WindowFunctionStep* fStep;
|
||||
int fId;
|
||||
|
||||
// row meta data
|
||||
rowgroup::RowGroup fRowGroup;
|
||||
rowgroup::Row fRow;
|
||||
|
||||
// pointer back to step
|
||||
joblist::WindowFunctionStep* fStep;
|
||||
int fId;
|
||||
|
||||
friend class joblist::WindowFunctionStep;
|
||||
friend class joblist::WindowFunctionStep;
|
||||
};
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace windowfunction
|
||||
|
||||
// vim:ts=4 sw=4:
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -18,7 +18,6 @@
|
||||
|
||||
// $Id: windowfunctiontype.h 3932 2013-06-25 16:08:10Z xlou $
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
@ -38,68 +37,67 @@ namespace ordering
|
||||
{
|
||||
// forward reference
|
||||
class EqualCompData;
|
||||
};
|
||||
}; // namespace ordering
|
||||
|
||||
namespace execplan
|
||||
{
|
||||
// forward reference
|
||||
class ConstantColumn;
|
||||
};
|
||||
}; // namespace execplan
|
||||
|
||||
namespace joblist
|
||||
{
|
||||
// forward reference
|
||||
class WindowFunctionStep;
|
||||
};
|
||||
}; // namespace joblist
|
||||
|
||||
namespace windowfunction
|
||||
{
|
||||
|
||||
// forward reference
|
||||
class WindowFunctionType;
|
||||
class IdbOrderBy;
|
||||
class WindowFrame;
|
||||
|
||||
const int WF__UNDEFINED = 0;
|
||||
const int WF__COUNT_ASTERISK = 1;
|
||||
const int WF__COUNT = 2;
|
||||
const int WF__SUM = 3;
|
||||
const int WF__AVG = 4;
|
||||
const int WF__MIN = 5;
|
||||
const int WF__MAX = 6;
|
||||
const int WF__COUNT_DISTINCT = 7;
|
||||
const int WF__SUM_DISTINCT = 8;
|
||||
const int WF__AVG_DISTINCT = 9;
|
||||
const int WF__STDDEV_POP = 10;
|
||||
const int WF__STDDEV_SAMP = 11;
|
||||
const int WF__VAR_POP = 12;
|
||||
const int WF__VAR_SAMP = 13;
|
||||
const int WF__UNDEFINED = 0;
|
||||
const int WF__COUNT_ASTERISK = 1;
|
||||
const int WF__COUNT = 2;
|
||||
const int WF__SUM = 3;
|
||||
const int WF__AVG = 4;
|
||||
const int WF__MIN = 5;
|
||||
const int WF__MAX = 6;
|
||||
const int WF__COUNT_DISTINCT = 7;
|
||||
const int WF__SUM_DISTINCT = 8;
|
||||
const int WF__AVG_DISTINCT = 9;
|
||||
const int WF__STDDEV_POP = 10;
|
||||
const int WF__STDDEV_SAMP = 11;
|
||||
const int WF__VAR_POP = 12;
|
||||
const int WF__VAR_SAMP = 13;
|
||||
|
||||
const int WF__ROW_NUMBER = 14;
|
||||
const int WF__RANK = 15;
|
||||
const int WF__PERCENT_RANK = 16;
|
||||
const int WF__DENSE_RANK = 17;
|
||||
const int WF__CUME_DIST = 18;
|
||||
const int WF__ROW_NUMBER = 14;
|
||||
const int WF__RANK = 15;
|
||||
const int WF__PERCENT_RANK = 16;
|
||||
const int WF__DENSE_RANK = 17;
|
||||
const int WF__CUME_DIST = 18;
|
||||
|
||||
const int WF__FIRST_VALUE = 19;
|
||||
const int WF__LAST_VALUE = 20;
|
||||
const int WF__NTH_VALUE = 21;
|
||||
const int WF__LAG = 22;
|
||||
const int WF__LEAD = 23;
|
||||
const int WF__NTILE = 24;
|
||||
const int WF__FIRST_VALUE = 19;
|
||||
const int WF__LAST_VALUE = 20;
|
||||
const int WF__NTH_VALUE = 21;
|
||||
const int WF__LAG = 22;
|
||||
const int WF__LEAD = 23;
|
||||
const int WF__NTILE = 24;
|
||||
const int WF__PERCENTILE_CONT = 25;
|
||||
const int WF__PERCENTILE_DISC = 26;
|
||||
|
||||
const int WF__REGR_SLOPE = 27;
|
||||
const int WF__REGR_INTERCEPT = 28;
|
||||
const int WF__REGR_COUNT = 29;
|
||||
const int WF__REGR_R2 = 30;
|
||||
const int WF__REGR_AVGX = 31;
|
||||
const int WF__REGR_AVGY = 32;
|
||||
const int WF__REGR_SXX = 33;
|
||||
const int WF__REGR_SXY = 34;
|
||||
const int WF__REGR_SYY = 35;
|
||||
const int WF__UDAF = 36;
|
||||
const int WF__REGR_SLOPE = 27;
|
||||
const int WF__REGR_INTERCEPT = 28;
|
||||
const int WF__REGR_COUNT = 29;
|
||||
const int WF__REGR_R2 = 30;
|
||||
const int WF__REGR_AVGX = 31;
|
||||
const int WF__REGR_AVGY = 32;
|
||||
const int WF__REGR_SXX = 33;
|
||||
const int WF__REGR_SXY = 34;
|
||||
const int WF__REGR_SYY = 35;
|
||||
const int WF__UDAF = 36;
|
||||
|
||||
typedef execplan::CalpontSystemCatalog::ColDataType CDT;
|
||||
|
||||
@ -108,199 +106,201 @@ typedef execplan::CalpontSystemCatalog::ColDataType CDT;
|
||||
*/
|
||||
class WindowFunctionType
|
||||
{
|
||||
public:
|
||||
// @brief WindowFunctionType constructor
|
||||
WindowFunctionType(int id = 0, const std::string& name = "") :
|
||||
fFunctionId(id), fFunctionName(name), fFrameUnit(0) {};
|
||||
public:
|
||||
// @brief WindowFunctionType constructor
|
||||
WindowFunctionType(int id = 0, const std::string& name = "")
|
||||
: fFunctionId(id), fFunctionName(name), fFrameUnit(0){};
|
||||
|
||||
// use default copy construct
|
||||
//WindowFunctionType(const WindowFunctionType&);
|
||||
// use default copy construct
|
||||
// WindowFunctionType(const WindowFunctionType&);
|
||||
|
||||
// @brief WindowFunctionType destructor
|
||||
virtual ~WindowFunctionType() {};
|
||||
// @brief WindowFunctionType destructor
|
||||
virtual ~WindowFunctionType(){};
|
||||
|
||||
// @brief virtual operator(begin, end, current, data, row)
|
||||
virtual void operator()(int64_t, int64_t, int64_t) = 0;
|
||||
// @brief virtual operator(begin, end, current, data, row)
|
||||
virtual void operator()(int64_t, int64_t, int64_t) = 0;
|
||||
|
||||
// @brief virtual clone()
|
||||
virtual WindowFunctionType* clone() const = 0;
|
||||
// @brief virtual clone()
|
||||
virtual WindowFunctionType* clone() const = 0;
|
||||
|
||||
// @brief virtual resetData()
|
||||
virtual void resetData()
|
||||
{
|
||||
fPrev = -1;
|
||||
}
|
||||
// @brief virtual resetData()
|
||||
virtual void resetData()
|
||||
{
|
||||
fPrev = -1;
|
||||
}
|
||||
|
||||
// @brief virtual parseParms()
|
||||
virtual void parseParms(const std::vector<execplan::SRCP>&) {}
|
||||
// @brief virtual parseParms()
|
||||
virtual void parseParms(const std::vector<execplan::SRCP>&)
|
||||
{
|
||||
}
|
||||
|
||||
// @brief virtual dropValues() For UDAnF functions
|
||||
// return false if there's no dropValue() implemented in the function.
|
||||
virtual bool dropValues(int64_t, int64_t)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// @brief virtual dropValues() For UDAnF functions
|
||||
// return false if there's no dropValue() implemented in the function.
|
||||
virtual bool dropValues(int64_t, int64_t)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// @brief virtual display method
|
||||
virtual const std::string toString() const;
|
||||
// @brief virtual display method
|
||||
virtual const std::string toString() const;
|
||||
|
||||
// @brief access methods
|
||||
int64_t functionId() const
|
||||
{
|
||||
return fFunctionId;
|
||||
}
|
||||
// @brief access methods
|
||||
int64_t functionId() const
|
||||
{
|
||||
return fFunctionId;
|
||||
}
|
||||
|
||||
const std::string functionName() const
|
||||
{
|
||||
return fFunctionName;
|
||||
}
|
||||
const std::string functionName() const
|
||||
{
|
||||
return fFunctionName;
|
||||
}
|
||||
|
||||
void functionId(int id)
|
||||
{
|
||||
fFunctionId = id;
|
||||
}
|
||||
const std::vector<int64_t>& fieldIndex() const
|
||||
{
|
||||
return fFieldIndex;
|
||||
}
|
||||
void fieldIndex(const std::vector<int64_t>& v)
|
||||
{
|
||||
fFieldIndex = v;
|
||||
}
|
||||
void setRowMetaData(const rowgroup::RowGroup& g, const rowgroup::Row& r)
|
||||
{
|
||||
fRowGroup = g;
|
||||
fRow = r;
|
||||
}
|
||||
void setRowData(const boost::shared_ptr<std::vector<joblist::RowPosition> >& d)
|
||||
{
|
||||
fRowData = d;
|
||||
}
|
||||
int64_t frameUnit() const
|
||||
{
|
||||
return fFrameUnit;
|
||||
}
|
||||
void frameUnit(int u)
|
||||
{
|
||||
fFrameUnit = u;
|
||||
}
|
||||
std::pair<int64_t, int64_t> partition() const
|
||||
{
|
||||
return fPartition;
|
||||
}
|
||||
void partition(std::pair<int64_t, int64_t>& p)
|
||||
{
|
||||
fPartition = p;
|
||||
}
|
||||
const boost::shared_ptr<ordering::EqualCompData>& peer() const
|
||||
{
|
||||
return fPeer;
|
||||
}
|
||||
void peer(const boost::shared_ptr<ordering::EqualCompData>& p)
|
||||
{
|
||||
fPeer = p;
|
||||
}
|
||||
void setCallback(joblist::WindowFunctionStep* step)
|
||||
{
|
||||
fStep = step;
|
||||
}
|
||||
void functionId(int id)
|
||||
{
|
||||
fFunctionId = id;
|
||||
}
|
||||
const std::vector<int64_t>& fieldIndex() const
|
||||
{
|
||||
return fFieldIndex;
|
||||
}
|
||||
void fieldIndex(const std::vector<int64_t>& v)
|
||||
{
|
||||
fFieldIndex = v;
|
||||
}
|
||||
void setRowMetaData(const rowgroup::RowGroup& g, const rowgroup::Row& r)
|
||||
{
|
||||
fRowGroup = g;
|
||||
fRow = r;
|
||||
}
|
||||
void setRowData(const boost::shared_ptr<std::vector<joblist::RowPosition> >& d)
|
||||
{
|
||||
fRowData = d;
|
||||
}
|
||||
int64_t frameUnit() const
|
||||
{
|
||||
return fFrameUnit;
|
||||
}
|
||||
void frameUnit(int u)
|
||||
{
|
||||
fFrameUnit = u;
|
||||
}
|
||||
std::pair<int64_t, int64_t> partition() const
|
||||
{
|
||||
return fPartition;
|
||||
}
|
||||
void partition(std::pair<int64_t, int64_t>& p)
|
||||
{
|
||||
fPartition = p;
|
||||
}
|
||||
const boost::shared_ptr<ordering::EqualCompData>& peer() const
|
||||
{
|
||||
return fPeer;
|
||||
}
|
||||
void peer(const boost::shared_ptr<ordering::EqualCompData>& p)
|
||||
{
|
||||
fPeer = p;
|
||||
}
|
||||
void setCallback(joblist::WindowFunctionStep* step)
|
||||
{
|
||||
fStep = step;
|
||||
}
|
||||
|
||||
void constParms(const std::vector<execplan::SRCP>& functionParms);
|
||||
void constParms(const std::vector<execplan::SRCP>& functionParms);
|
||||
|
||||
static boost::shared_ptr<WindowFunctionType> makeWindowFunction(const std::string&, int ct, execplan::WindowFunctionColumn* wc);
|
||||
static boost::shared_ptr<WindowFunctionType> makeWindowFunction(const std::string&, int ct,
|
||||
execplan::WindowFunctionColumn* wc);
|
||||
|
||||
protected:
|
||||
protected:
|
||||
static std::map<std::string, int> windowFunctionId;
|
||||
|
||||
static std::map<std::string, int> windowFunctionId;
|
||||
// utility methods
|
||||
template <typename T>
|
||||
void getValue(uint64_t, T&, CDT* cdt = NULL);
|
||||
template <typename T>
|
||||
void setValue(int, int64_t, int64_t, int64_t, T* = NULL);
|
||||
template <typename T>
|
||||
void setValue(uint64_t, T&);
|
||||
template <typename T>
|
||||
void implicit2T(uint64_t, T&, int);
|
||||
template <typename T>
|
||||
void getConstValue(execplan::ConstantColumn*, T&, bool&);
|
||||
|
||||
// utility methods
|
||||
template<typename T> void getValue(uint64_t, T&, CDT* cdt = NULL);
|
||||
template<typename T> void setValue(int, int64_t, int64_t, int64_t, T* = NULL);
|
||||
template<typename T> void setValue(uint64_t, T&);
|
||||
template<typename T> void implicit2T(uint64_t, T&, int);
|
||||
template<typename T> void getConstValue(execplan::ConstantColumn*, T&, bool&);
|
||||
virtual void* getNullValueByType(int, int);
|
||||
|
||||
virtual void* getNullValueByType(int, int);
|
||||
// There are two types of getters for integral types and for
|
||||
// DTs wider then 8 bytes.
|
||||
void getInt128Value(uint64_t i, int128_t& x)
|
||||
{
|
||||
return fRow.getInt128Field(i, x);
|
||||
}
|
||||
int64_t getIntValue(uint64_t i)
|
||||
{
|
||||
return fRow.getIntField(i);
|
||||
}
|
||||
double getDoubleValue(uint64_t i)
|
||||
{
|
||||
return fRow.getDoubleField(i);
|
||||
}
|
||||
long double getLongDoubleValue(uint64_t i)
|
||||
{
|
||||
return fRow.getLongDoubleField(i);
|
||||
}
|
||||
void setIntValue(int64_t i, int64_t v)
|
||||
{
|
||||
fRow.setIntField(v, i);
|
||||
}
|
||||
void setInt128Value(int64_t i, const int128_t& v)
|
||||
{
|
||||
fRow.setInt128Field(v, i);
|
||||
}
|
||||
void setDoubleValue(int64_t i, double v)
|
||||
{
|
||||
fRow.setDoubleField(v, i);
|
||||
}
|
||||
void setLongDoubleValue(int64_t i, const long double& v)
|
||||
{
|
||||
fRow.setLongDoubleField(v, i);
|
||||
}
|
||||
|
||||
// There are two types of getters for integral types and for
|
||||
// DTs wider then 8 bytes.
|
||||
void getInt128Value(uint64_t i, int128_t& x)
|
||||
{
|
||||
return fRow.getInt128Field(i, x);
|
||||
}
|
||||
int64_t getIntValue(uint64_t i)
|
||||
{
|
||||
return fRow.getIntField(i);
|
||||
}
|
||||
double getDoubleValue(uint64_t i)
|
||||
{
|
||||
return fRow.getDoubleField(i);
|
||||
}
|
||||
long double getLongDoubleValue(uint64_t i)
|
||||
{
|
||||
return fRow.getLongDoubleField(i);
|
||||
}
|
||||
void setIntValue(int64_t i, int64_t v)
|
||||
{
|
||||
fRow.setIntField(v, i);
|
||||
}
|
||||
void setInt128Value(int64_t i, const int128_t& v)
|
||||
{
|
||||
fRow.setInt128Field(v, i);
|
||||
}
|
||||
void setDoubleValue(int64_t i, double v)
|
||||
{
|
||||
fRow.setDoubleField(v, i);
|
||||
}
|
||||
void setLongDoubleValue(int64_t i, const long double& v)
|
||||
{
|
||||
fRow.setLongDoubleField(v, i);
|
||||
}
|
||||
// for string table
|
||||
rowgroup::Row::Pointer getPointer(joblist::RowPosition& r)
|
||||
{
|
||||
return fStep->getPointer(r, fRowGroup, fRow);
|
||||
}
|
||||
|
||||
// for string table
|
||||
rowgroup::Row::Pointer getPointer(joblist::RowPosition& r)
|
||||
{
|
||||
return fStep->getPointer(r, fRowGroup, fRow);
|
||||
}
|
||||
// function type
|
||||
int64_t fFunctionId;
|
||||
std::string fFunctionName;
|
||||
|
||||
// function type
|
||||
int64_t fFunctionId;
|
||||
std::string fFunctionName;
|
||||
// output and input field indices: [0] - output
|
||||
std::vector<int64_t> fFieldIndex;
|
||||
|
||||
// output and input field indices: [0] - output
|
||||
std::vector<int64_t> fFieldIndex;
|
||||
// constant function parameters -- needed for udaf with constant
|
||||
std::vector<execplan::SRCP> fConstantParms;
|
||||
|
||||
// constant function parameters -- needed for udaf with constant
|
||||
std::vector<execplan::SRCP> fConstantParms;
|
||||
// row meta data
|
||||
rowgroup::RowGroup fRowGroup;
|
||||
rowgroup::Row fRow;
|
||||
|
||||
// row meta data
|
||||
rowgroup::RowGroup fRowGroup;
|
||||
rowgroup::Row fRow;
|
||||
// data set
|
||||
boost::shared_ptr<std::vector<joblist::RowPosition> > fRowData;
|
||||
|
||||
// data set
|
||||
boost::shared_ptr<std::vector<joblist::RowPosition> > fRowData;
|
||||
// frame unit ( ROWS | RANGE )
|
||||
int64_t fFrameUnit;
|
||||
|
||||
// frame unit ( ROWS | RANGE )
|
||||
int64_t fFrameUnit;
|
||||
// partition
|
||||
std::pair<int64_t, int64_t> fPartition;
|
||||
|
||||
// partition
|
||||
std::pair<int64_t, int64_t> fPartition;
|
||||
|
||||
// functor for peer checking
|
||||
boost::shared_ptr<ordering::EqualCompData> fPeer;
|
||||
int64_t fPrev;
|
||||
|
||||
// for checking if query is cancelled
|
||||
joblist::WindowFunctionStep* fStep;
|
||||
// functor for peer checking
|
||||
boost::shared_ptr<ordering::EqualCompData> fPeer;
|
||||
int64_t fPrev;
|
||||
|
||||
// for checking if query is cancelled
|
||||
joblist::WindowFunctionStep* fStep;
|
||||
};
|
||||
|
||||
|
||||
extern std::map<int, std::string> colType2String;
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace windowfunction
|
||||
|
||||
// vim:ts=4 sw=4:
|
||||
|
||||
|
Reference in New Issue
Block a user