1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-08-01 06:46:55 +03:00

Reformat all code to coding standard

This commit is contained in:
Andrew Hutchings
2017-10-26 17:18:17 +01:00
parent 4985f3456e
commit 01446d1e22
1296 changed files with 403852 additions and 353747 deletions

View File

@ -42,37 +42,40 @@ namespace batchloader
// Mutex lock not needed in this function as it is only called from main thread
//------------------------------------------------------------------------------
BatchLoader::BatchLoader ( uint32_t tableOid,
execplan::CalpontSystemCatalog::SCN sessionId,
std::vector<uint32_t>& PMs )
execplan::CalpontSystemCatalog::SCN sessionId,
std::vector<uint32_t>& PMs )
{
fFirstPm=0;
fNextIdx=0;
fFirstPm = 0;
fNextIdx = 0;
fPMs = PMs;
fSessionId = sessionId;
fTableOid = tableOid;
OamCache * oamcache = OamCache::makeOamCache();
oam::OamCache::PMDbrootsMap_t systemPmDbrootMap = oamcache->getPMToDbrootsMap();
std::map<int, OamCache::dbRoots>::iterator iter = systemPmDbrootMap->begin();
//cout << "fPMs size is " << fPMs.size() << endl;
fPmDbrootMap.reset(new OamCache::PMDbrootsMap_t::element_type());
fDbrootPMmap.reset(new map<int, int>());
for (uint32_t i=0; i < fPMs.size(); i++)
{
iter = systemPmDbrootMap->find(fPMs[i]);
if (iter != systemPmDbrootMap->end())
{
fDbRoots.insert(fDbRoots.end(), (iter->second).begin(), (iter->second).end());
(*fPmDbrootMap)[fPMs[i]] = iter->second;
}
}
//Build dbroot to PM map
for (iter = fPmDbrootMap->begin(); iter != fPmDbrootMap->end(); iter++)
{
for ( uint32_t i = 0; i < iter->second.size(); i++)
{
(*fDbrootPMmap)[iter->second[i]] = iter->first;
}
}
fSessionId = sessionId;
fTableOid = tableOid;
OamCache* oamcache = OamCache::makeOamCache();
oam::OamCache::PMDbrootsMap_t systemPmDbrootMap = oamcache->getPMToDbrootsMap();
std::map<int, OamCache::dbRoots>::iterator iter = systemPmDbrootMap->begin();
//cout << "fPMs size is " << fPMs.size() << endl;
fPmDbrootMap.reset(new OamCache::PMDbrootsMap_t::element_type());
fDbrootPMmap.reset(new map<int, int>());
for (uint32_t i = 0; i < fPMs.size(); i++)
{
iter = systemPmDbrootMap->find(fPMs[i]);
if (iter != systemPmDbrootMap->end())
{
fDbRoots.insert(fDbRoots.end(), (iter->second).begin(), (iter->second).end());
(*fPmDbrootMap)[fPMs[i]] = iter->second;
}
}
//Build dbroot to PM map
for (iter = fPmDbrootMap->begin(); iter != fPmDbrootMap->end(); iter++)
{
for ( uint32_t i = 0; i < iter->second.size(); i++)
{
(*fDbrootPMmap)[iter->second[i]] = iter->first;
}
}
}
//------------------------------------------------------------------------------
// Select the first PM to send the first batch of rows.
@ -88,288 +91,310 @@ BatchLoader::BatchLoader ( uint32_t tableOid,
//------------------------------------------------------------------------------
void BatchLoader::selectFirstPM ( uint32_t& PMId)
{
boost::shared_ptr<CalpontSystemCatalog> systemCatalogPtr = CalpontSystemCatalog::makeCalpontSystemCatalog(fSessionId);
//cout << "calling tableName for oid " << fTableOid << endl;
CalpontSystemCatalog::TableName aTableName = systemCatalogPtr->tableName(fTableOid);
CalpontSystemCatalog::RIDList ridList;
ridList = systemCatalogPtr->columnRIDs(aTableName, true); //exception will be handled in caller program.
scoped_ptr<DBRM> dbrmp(new DBRM());
//Build distVec, start from the PM where the table is created. If not in the PM list, 0 will be used.
uint16_t createdDbroot = 0;
int rc = 0;
std::vector<BRM::EmDbRootHWMInfo_v> allInfo (fPMs.size());
for (unsigned i = 0; i < fPMs.size(); i++)
{
rc = dbrmp->getDbRootHWMInfo((ridList[0].objnum), fPMs[i], allInfo[i]);
if ( rc !=0 ) //@Bug 4760
break;
}
if ( rc != 0 ) {
ostringstream oss;
oss << "There is no extent information for table " << aTableName.table;
throw std::runtime_error(oss.str());
}
uint32_t numDbroot = fDbRoots.size();
boost::shared_ptr<CalpontSystemCatalog> systemCatalogPtr = CalpontSystemCatalog::makeCalpontSystemCatalog(fSessionId);
//cout << "calling tableName for oid " << fTableOid << endl;
CalpontSystemCatalog::TableName aTableName = systemCatalogPtr->tableName(fTableOid);
CalpontSystemCatalog::RIDList ridList;
ridList = systemCatalogPtr->columnRIDs(aTableName, true); //exception will be handled in caller program.
scoped_ptr<DBRM> dbrmp(new DBRM());
//Build distVec, start from the PM where the table is created. If not in the PM list, 0 will be used.
uint16_t createdDbroot = 0;
int rc = 0;
std::vector<BRM::EmDbRootHWMInfo_v> allInfo (fPMs.size());
for (unsigned i = 0; i < fPMs.size(); i++)
{
rc = dbrmp->getDbRootHWMInfo((ridList[0].objnum), fPMs[i], allInfo[i]);
if ( rc != 0 ) //@Bug 4760
break;
}
if ( rc != 0 )
{
ostringstream oss;
oss << "There is no extent information for table " << aTableName.table;
throw std::runtime_error(oss.str());
}
uint32_t numDbroot = fDbRoots.size();
if (numDbroot == 0)
{
throw std::runtime_error("There are no dbroots found during selectFirstPM");
throw std::runtime_error("There are no dbroots found during selectFirstPM");
}
uint64_t* rootExtents = (uint64_t*)alloca((numDbroot + 1) * sizeof(uint64_t)); //array of number extents for each dbroot
for (unsigned i = 0; i < fDbRoots.size(); i++)
{
uint64_t numExtents;
dbrmp->getExtentCount_dbroot((ridList[0].objnum), fDbRoots[i],
false, numExtents);
rootExtents[fDbRoots[i]] = numExtents;
}
bool startDBRootSet = false;
uint64_t* rootBlocks = (uint64_t*)alloca((numDbroot + 1) * sizeof(uint64_t)); //array of number of blocks for the last partition for each dbroot
//cout << "allInfo size is " << allInfo.size() << endl;
//--------------------------------------------------------------------------
// Load rootBlocks to carry total blocks for each DBRoot
// Set startDBRootSet if the partition 0 segment 0 extent is empty
// Set createdDbroot for the DBRoot that carries the partition 0
// segment 0 extent (used to set the default PMId)
//--------------------------------------------------------------------------
for (unsigned i=0; i < allInfo.size(); i++) //All PMs
{
BRM::EmDbRootHWMInfo_v emDbRootHWMInfos = allInfo[i]; //one pm
for (unsigned j=0; j < emDbRootHWMInfos.size(); j++)
{
if (emDbRootHWMInfos[j].totalBlocks == 0) {
//cout << "totalBlocks is 0" << endl;
continue; }
uint64_t* rootExtents = (uint64_t*)alloca((numDbroot + 1) * sizeof(uint64_t)); //array of number extents for each dbroot
//------------------------------------------------------------------
// Ignore partition 0, segment 0 HWM extent if it is disabled
//------------------------------------------------------------------
if ((emDbRootHWMInfos[j].partitionNum == 0) &&
(emDbRootHWMInfos[j].segmentNum ==0) &&
(emDbRootHWMInfos[j].status != BRM::EXTENTOUTOFSERVICE))
{
if (emDbRootHWMInfos[j].localHWM == 0)
{
//newly created table
//cout << " This is newly created table. PM id is " << PMId;
startDBRootSet = true;
createdDbroot = emDbRootHWMInfos[j].dbRoot;
break;
}
else
{
createdDbroot = emDbRootHWMInfos[j].dbRoot;
//cout << " and createdDbroot is " << createdDbroot << endl;
rootBlocks[emDbRootHWMInfos[j].dbRoot] = emDbRootHWMInfos[j].totalBlocks;
}
}
else
{
rootBlocks[emDbRootHWMInfos[j].dbRoot] = emDbRootHWMInfos[j].totalBlocks;
}
}
if (startDBRootSet)
break;
}
//--------------------------------------------------------------------------
// Set the default PMId to the PM with the partition 0 segment 0 extent
//--------------------------------------------------------------------------
PMId = 0;
if ( createdDbroot != 0)
{
std::map<int, int>::iterator iter = fDbrootPMmap->begin();
iter = fDbrootPMmap->find(createdDbroot);
if (iter != fDbrootPMmap->end())
PMId = iter->second;
}
for (unsigned i = 0; i < fDbRoots.size(); i++)
{
uint64_t numExtents;
dbrmp->getExtentCount_dbroot((ridList[0].objnum), fDbRoots[i],
false, numExtents);
rootExtents[fDbRoots[i]] = numExtents;
}
// This will build the batch distribution sequence
//cout << "Building BatchDistSeqVector with PMId " << PMId << endl;
buildBatchDistSeqVector(PMId);
bool startDBRootSet = false;
uint64_t* rootBlocks = (uint64_t*)alloca((numDbroot + 1) * sizeof(uint64_t)); //array of number of blocks for the last partition for each dbroot
//cout << "allInfo size is " << allInfo.size() << endl;
//cout << "startDBRootSet = " << startDBRootSet << endl;
bool allEqual = true;
bool allOtherDbrootEmpty = true;
//--------------------------------------------------------------------------
// Load rootBlocks to carry total blocks for each DBRoot
// Set startDBRootSet if the partition 0 segment 0 extent is empty
// Set createdDbroot for the DBRoot that carries the partition 0
// segment 0 extent (used to set the default PMId)
//--------------------------------------------------------------------------
for (unsigned i = 0; i < allInfo.size(); i++) //All PMs
{
BRM::EmDbRootHWMInfo_v emDbRootHWMInfos = allInfo[i]; //one pm
//--------------------------------------------------------------------------
// startDBRootSet == false
// We don't have an empty partition 0, segment 0 extent to load;
// so evaluate more selection criteria.
//--------------------------------------------------------------------------
if (!startDBRootSet)
{
std::vector<PMRootInfo> rootsExtentsBlocks;
std::map<int, OamCache::dbRoots>::iterator iter;
for (unsigned j = 0; j < emDbRootHWMInfos.size(); j++)
{
if (emDbRootHWMInfos[j].totalBlocks == 0)
{
//cout << "totalBlocks is 0" << endl;
continue;
}
//----------------------------------------------------------------------
// Load rootsExtentsBlocks to carry the number of extents and blocks
// for each DBRoot.
//----------------------------------------------------------------------
for (unsigned j=0; j < fPmDistSeq.size(); j++)
{
PMRootInfo aEntry;
aEntry.PMId = fPmDistSeq[j];
iter = fPmDbrootMap->find(aEntry.PMId);
for (unsigned k=0; k < (iter->second).size(); k++)
{
RootExtentsBlocks aRootInfo;
aRootInfo.DBRoot = (iter->second)[k];
aRootInfo.numExtents = rootExtents[aRootInfo.DBRoot];
aRootInfo.numBlocks = rootBlocks[aRootInfo.DBRoot];
//cout << "aRootInfo DBRoot:numExtents:numBlocks = " << aRootInfo.DBRoot<<":"<<aRootInfo.numExtents<<":"<<aRootInfo.numBlocks<<endl;
aEntry.rootInfo.push_back(aRootInfo);
}
rootsExtentsBlocks.push_back(aEntry);
}
//cout << "rootsExtentsBlocks size is " << rootsExtentsBlocks.size() << " and allOtherDbrootEmpty is " << allOtherDbrootEmpty<< endl;
//------------------------------------------------------------------
// Ignore partition 0, segment 0 HWM extent if it is disabled
//------------------------------------------------------------------
if ((emDbRootHWMInfos[j].partitionNum == 0) &&
(emDbRootHWMInfos[j].segmentNum == 0) &&
(emDbRootHWMInfos[j].status != BRM::EXTENTOUTOFSERVICE))
{
if (emDbRootHWMInfos[j].localHWM == 0)
{
//newly created table
//cout << " This is newly created table. PM id is " << PMId;
startDBRootSet = true;
createdDbroot = emDbRootHWMInfos[j].dbRoot;
break;
}
else
{
createdDbroot = emDbRootHWMInfos[j].dbRoot;
//cout << " and createdDbroot is " << createdDbroot << endl;
rootBlocks[emDbRootHWMInfos[j].dbRoot] = emDbRootHWMInfos[j].totalBlocks;
}
}
else
{
rootBlocks[emDbRootHWMInfos[j].dbRoot] = emDbRootHWMInfos[j].totalBlocks;
}
}
//----------------------------------------------------------------------
// See if all other DBRoots other than the createdDbroot have 0 extents
//----------------------------------------------------------------------
for (unsigned i=1; i < rootsExtentsBlocks.size(); i++)
{
if (!allOtherDbrootEmpty)
break;
//cout << "createdDbroot is " << createdDbroot << endl;
if (i != createdDbroot)
{
for ( unsigned j=0; j < rootsExtentsBlocks[i].rootInfo.size(); j++)
{
if (rootsExtentsBlocks[i].rootInfo[j].numExtents != 0)
{
//cout << "setting allOtherDbrootEmpty to false and i:j = " << i<<":"<<j<<endl;
//cout << "numExtents = " << rootsExtentsBlocks[i].rootInfo[j].numExtents << endl;
allOtherDbrootEmpty = false;
break;
}
}
}
}
//cout << "allOtherDbrootEmpty is " << allOtherDbrootEmpty << endl;
if (startDBRootSet)
break;
}
//----------------------------------------------------------------------
// allOtherDbrootEmpty == true
// No DBRoots (other than the DBRoot having the partition 0,
// segment 0 extent) have extents
//----------------------------------------------------------------------
if (allOtherDbrootEmpty)
{
//find the next PM id on the list
startDBRootSet = true;
buildBatchDistSeqVector();
allEqual = false;
}
//----------------------------------------------------------------------
// allOtherDbrootEmpty == false
// Some DBRoots (other than the DBRoot having the partition 0,
// segment 0 extent) have extents. More evaluation necessary.
//----------------------------------------------------------------------
else //find the dbroot which has the least extents to start
{
//cout << "finding least dbroot to start." << endl;
//------------------------------------------------------------------
// Select PM with DBRoot having the fewest extents.
//------------------------------------------------------------------
uint32_t tmpLeastExtents = rootsExtentsBlocks[0].rootInfo[0].numExtents;
PMId = rootsExtentsBlocks[0].PMId; //@Bug 4809.
for ( unsigned j=1; j < rootsExtentsBlocks[0].rootInfo.size(); j++)
{
if (tmpLeastExtents > rootsExtentsBlocks[0].rootInfo[j].numExtents)
tmpLeastExtents = rootsExtentsBlocks[0].rootInfo[j].numExtents;
}
for (unsigned i=1; i < rootsExtentsBlocks.size(); i++)
{
uint32_t leastExtents = rootsExtentsBlocks[i].rootInfo[0].numExtents;
for ( unsigned j=0; j < rootsExtentsBlocks[i].rootInfo.size(); j++)
{
if (leastExtents > rootsExtentsBlocks[i].rootInfo[j].numExtents)
leastExtents = rootsExtentsBlocks[i].rootInfo[j].numExtents;
}
if (leastExtents < tmpLeastExtents)
{
tmpLeastExtents = leastExtents;
PMId = rootsExtentsBlocks[i].PMId;
allEqual = false;
}
else if (leastExtents > tmpLeastExtents)
allEqual = false;
}
//cout << "allEqual is " << allEqual << endl;
//--------------------------------------------------------------------------
// Set the default PMId to the PM with the partition 0 segment 0 extent
//--------------------------------------------------------------------------
PMId = 0;
//------------------------------------------------------------------
// All DBRoots have the same number of extents.
// Select PM with DBRoot having the fewest number of blocks.
//------------------------------------------------------------------
if (allEqual) //Find the dbroot which has least number of blocks
{
//cout << "All PMs have equal # of least extents" << endl;
uint32_t tmpBloks = rootsExtentsBlocks[0].rootInfo[0].numBlocks;
PMId = rootsExtentsBlocks[0].PMId;
//cout << "tmpBloks:PMId = " << tmpBloks <<":"<<PMId<<endl;
for ( unsigned j=1; j < rootsExtentsBlocks[0].rootInfo.size(); j++)
{
if (tmpBloks > rootsExtentsBlocks[0].rootInfo[j].numBlocks)
tmpBloks = rootsExtentsBlocks[0].rootInfo[j].numBlocks;
}
for (unsigned i=1; i < rootsExtentsBlocks.size(); i++)
{
uint32_t leastBlocks = rootsExtentsBlocks[i].rootInfo[0].numBlocks;
//cout << "leastBlocks = " << leastBlocks << endl;
for ( unsigned j=0; j < rootsExtentsBlocks[i].rootInfo.size(); j++)
{
if (leastBlocks > rootsExtentsBlocks[i].rootInfo[j].numBlocks)
leastBlocks = rootsExtentsBlocks[i].rootInfo[j].numBlocks;
}
if (leastBlocks < tmpBloks)
{
tmpBloks = leastBlocks;
//cout << "tmpBloks changed to " << tmpBloks << endl;
PMId = rootsExtentsBlocks[i].PMId;
//cout << "setting allEqual to false now" << endl;
allEqual = false;
}
}
}
}
}
//--------------------------------------------------------------------------
// startDBRootSet == true
// We select the empty partition 0, segment 0 extent to load
//--------------------------------------------------------------------------
else
{
allEqual = false;
}
fFirstPm = PMId;
if (!allOtherDbrootEmpty || (PMId == 0))
{
prepareForSecondPM();
//cout << "prepareForSecondPM is called. " << endl;
}
if ((allEqual && (PMId == 0)) || allOtherDbrootEmpty)
{
PMId = selectNextPM();
fFirstPm = PMId;
//cout << "PMId is now " << PMId << endl;
}
if ( createdDbroot != 0)
{
std::map<int, int>::iterator iter = fDbrootPMmap->begin();
iter = fDbrootPMmap->find(createdDbroot);
if (iter != fDbrootPMmap->end())
PMId = iter->second;
}
// This will build the batch distribution sequence
//cout << "Building BatchDistSeqVector with PMId " << PMId << endl;
buildBatchDistSeqVector(PMId);
//cout << "startDBRootSet = " << startDBRootSet << endl;
bool allEqual = true;
bool allOtherDbrootEmpty = true;
//--------------------------------------------------------------------------
// startDBRootSet == false
// We don't have an empty partition 0, segment 0 extent to load;
// so evaluate more selection criteria.
//--------------------------------------------------------------------------
if (!startDBRootSet)
{
std::vector<PMRootInfo> rootsExtentsBlocks;
std::map<int, OamCache::dbRoots>::iterator iter;
//----------------------------------------------------------------------
// Load rootsExtentsBlocks to carry the number of extents and blocks
// for each DBRoot.
//----------------------------------------------------------------------
for (unsigned j = 0; j < fPmDistSeq.size(); j++)
{
PMRootInfo aEntry;
aEntry.PMId = fPmDistSeq[j];
iter = fPmDbrootMap->find(aEntry.PMId);
for (unsigned k = 0; k < (iter->second).size(); k++)
{
RootExtentsBlocks aRootInfo;
aRootInfo.DBRoot = (iter->second)[k];
aRootInfo.numExtents = rootExtents[aRootInfo.DBRoot];
aRootInfo.numBlocks = rootBlocks[aRootInfo.DBRoot];
//cout << "aRootInfo DBRoot:numExtents:numBlocks = " << aRootInfo.DBRoot<<":"<<aRootInfo.numExtents<<":"<<aRootInfo.numBlocks<<endl;
aEntry.rootInfo.push_back(aRootInfo);
}
rootsExtentsBlocks.push_back(aEntry);
}
//cout << "rootsExtentsBlocks size is " << rootsExtentsBlocks.size() << " and allOtherDbrootEmpty is " << allOtherDbrootEmpty<< endl;
//----------------------------------------------------------------------
// See if all other DBRoots other than the createdDbroot have 0 extents
//----------------------------------------------------------------------
for (unsigned i = 1; i < rootsExtentsBlocks.size(); i++)
{
if (!allOtherDbrootEmpty)
break;
//cout << "createdDbroot is " << createdDbroot << endl;
if (i != createdDbroot)
{
for ( unsigned j = 0; j < rootsExtentsBlocks[i].rootInfo.size(); j++)
{
if (rootsExtentsBlocks[i].rootInfo[j].numExtents != 0)
{
//cout << "setting allOtherDbrootEmpty to false and i:j = " << i<<":"<<j<<endl;
//cout << "numExtents = " << rootsExtentsBlocks[i].rootInfo[j].numExtents << endl;
allOtherDbrootEmpty = false;
break;
}
}
}
}
//cout << "allOtherDbrootEmpty is " << allOtherDbrootEmpty << endl;
//----------------------------------------------------------------------
// allOtherDbrootEmpty == true
// No DBRoots (other than the DBRoot having the partition 0,
// segment 0 extent) have extents
//----------------------------------------------------------------------
if (allOtherDbrootEmpty)
{
//find the next PM id on the list
startDBRootSet = true;
buildBatchDistSeqVector();
allEqual = false;
}
//----------------------------------------------------------------------
// allOtherDbrootEmpty == false
// Some DBRoots (other than the DBRoot having the partition 0,
// segment 0 extent) have extents. More evaluation necessary.
//----------------------------------------------------------------------
else //find the dbroot which has the least extents to start
{
//cout << "finding least dbroot to start." << endl;
//------------------------------------------------------------------
// Select PM with DBRoot having the fewest extents.
//------------------------------------------------------------------
uint32_t tmpLeastExtents = rootsExtentsBlocks[0].rootInfo[0].numExtents;
PMId = rootsExtentsBlocks[0].PMId; //@Bug 4809.
for ( unsigned j = 1; j < rootsExtentsBlocks[0].rootInfo.size(); j++)
{
if (tmpLeastExtents > rootsExtentsBlocks[0].rootInfo[j].numExtents)
tmpLeastExtents = rootsExtentsBlocks[0].rootInfo[j].numExtents;
}
for (unsigned i = 1; i < rootsExtentsBlocks.size(); i++)
{
uint32_t leastExtents = rootsExtentsBlocks[i].rootInfo[0].numExtents;
for ( unsigned j = 0; j < rootsExtentsBlocks[i].rootInfo.size(); j++)
{
if (leastExtents > rootsExtentsBlocks[i].rootInfo[j].numExtents)
leastExtents = rootsExtentsBlocks[i].rootInfo[j].numExtents;
}
if (leastExtents < tmpLeastExtents)
{
tmpLeastExtents = leastExtents;
PMId = rootsExtentsBlocks[i].PMId;
allEqual = false;
}
else if (leastExtents > tmpLeastExtents)
allEqual = false;
}
//cout << "allEqual is " << allEqual << endl;
//------------------------------------------------------------------
// All DBRoots have the same number of extents.
// Select PM with DBRoot having the fewest number of blocks.
//------------------------------------------------------------------
if (allEqual) //Find the dbroot which has least number of blocks
{
//cout << "All PMs have equal # of least extents" << endl;
uint32_t tmpBloks = rootsExtentsBlocks[0].rootInfo[0].numBlocks;
PMId = rootsExtentsBlocks[0].PMId;
//cout << "tmpBloks:PMId = " << tmpBloks <<":"<<PMId<<endl;
for ( unsigned j = 1; j < rootsExtentsBlocks[0].rootInfo.size(); j++)
{
if (tmpBloks > rootsExtentsBlocks[0].rootInfo[j].numBlocks)
tmpBloks = rootsExtentsBlocks[0].rootInfo[j].numBlocks;
}
for (unsigned i = 1; i < rootsExtentsBlocks.size(); i++)
{
uint32_t leastBlocks = rootsExtentsBlocks[i].rootInfo[0].numBlocks;
//cout << "leastBlocks = " << leastBlocks << endl;
for ( unsigned j = 0; j < rootsExtentsBlocks[i].rootInfo.size(); j++)
{
if (leastBlocks > rootsExtentsBlocks[i].rootInfo[j].numBlocks)
leastBlocks = rootsExtentsBlocks[i].rootInfo[j].numBlocks;
}
if (leastBlocks < tmpBloks)
{
tmpBloks = leastBlocks;
//cout << "tmpBloks changed to " << tmpBloks << endl;
PMId = rootsExtentsBlocks[i].PMId;
//cout << "setting allEqual to false now" << endl;
allEqual = false;
}
}
}
}
}
//--------------------------------------------------------------------------
// startDBRootSet == true
// We select the empty partition 0, segment 0 extent to load
//--------------------------------------------------------------------------
else
{
allEqual = false;
}
fFirstPm = PMId;
if (!allOtherDbrootEmpty || (PMId == 0))
{
prepareForSecondPM();
//cout << "prepareForSecondPM is called. " << endl;
}
if ((allEqual && (PMId == 0)) || allOtherDbrootEmpty)
{
PMId = selectNextPM();
fFirstPm = PMId;
//cout << "PMId is now " << PMId << endl;
}
}
//------------------------------------------------------------------------------
@ -380,54 +405,61 @@ void BatchLoader::selectFirstPM ( uint32_t& PMId)
//------------------------------------------------------------------------------
void BatchLoader::buildBatchDistSeqVector()
{
fPmDistSeq.clear();
BlIntVec aDbCntVec(fPMs.size());
fPmDistSeq.clear();
BlIntVec aDbCntVec(fPMs.size());
std::map<int, OamCache::dbRoots>::iterator iter = fPmDbrootMap->begin();
for (uint32_t i=0; i < fPMs.size(); i++)
{
iter = fPmDbrootMap->find(fPMs[i]);
if ((iter != fPmDbrootMap->end()) && ((iter->second).begin()!=(iter->second).end()))
{
try
{
aDbCntVec[i] = (iter->second).size();
//cout << "PM - "<<fPMs[i] << " Size = " << aDbCntVec[i] << endl;
}
catch(std::exception& exp)
{
throw runtime_error(exp.what());
}
}
else
aDbCntVec[i] = 0;
}
std::map<int, OamCache::dbRoots>::iterator iter = fPmDbrootMap->begin();
int aTotDbRoots = 0;
for (uint32_t i=0; i<aDbCntVec.size(); i++) aTotDbRoots+=aDbCntVec[i];
for (uint32_t i = 0; i < fPMs.size(); i++)
{
iter = fPmDbrootMap->find(fPMs[i]);
int aIdx=0;
while(aIdx < aTotDbRoots)
{
uint32_t aMax=0;
uint32_t aPmId=0;
uint32_t aRefIdx=0;
for (uint32_t i=0; i<aDbCntVec.size(); i++)
{
if(aDbCntVec[i] > aMax)
{
aMax = aDbCntVec[i];
aPmId = fPMs[i];
aRefIdx = i;
}
}
if(aMax>0)
{
fPmDistSeq.push_back(aPmId);
aDbCntVec[aRefIdx]--;
}
aIdx++;
}
if ((iter != fPmDbrootMap->end()) && ((iter->second).begin() != (iter->second).end()))
{
try
{
aDbCntVec[i] = (iter->second).size();
//cout << "PM - "<<fPMs[i] << " Size = " << aDbCntVec[i] << endl;
}
catch (std::exception& exp)
{
throw runtime_error(exp.what());
}
}
else
aDbCntVec[i] = 0;
}
int aTotDbRoots = 0;
for (uint32_t i = 0; i < aDbCntVec.size(); i++) aTotDbRoots += aDbCntVec[i];
int aIdx = 0;
while (aIdx < aTotDbRoots)
{
uint32_t aMax = 0;
uint32_t aPmId = 0;
uint32_t aRefIdx = 0;
for (uint32_t i = 0; i < aDbCntVec.size(); i++)
{
if (aDbCntVec[i] > aMax)
{
aMax = aDbCntVec[i];
aPmId = fPMs[i];
aRefIdx = i;
}
}
if (aMax > 0)
{
fPmDistSeq.push_back(aPmId);
aDbCntVec[aRefIdx]--;
}
aIdx++;
}
}
@ -440,81 +472,90 @@ void BatchLoader::buildBatchDistSeqVector()
//------------------------------------------------------------------------------
void BatchLoader::buildBatchDistSeqVector(uint32_t StartPm)
{
fPmDistSeq.clear();
BlIntVec aDbCntVec(fPMs.size());
BlIntVec aPms;
fPmDistSeq.clear();
BlIntVec aDbCntVec(fPMs.size());
BlIntVec aPms;
if((fPMs.size()==0)&&(StartPm!=0))
throw runtime_error("ERROR : PM list empty while Start != 0");
if ((fPMs.size() == 0) && (StartPm != 0))
throw runtime_error("ERROR : PM list empty while Start != 0");
//for (uint32_t i=0; i<fPMs.size(); i++)
// cout <<"fPM list "<<i <<" = " << fPMs[i] << endl;
//cout << "StartPm = "<< StartPm << endl;
//for (uint32_t i=0; i<fPMs.size(); i++)
// cout <<"fPM list "<<i <<" = " << fPMs[i] << endl;
//cout << "StartPm = "<< StartPm << endl;
if (StartPm == 0)
aPms = fPMs;
else
{
aPms.push_back(StartPm);
uint32_t aLast = fPMs.back();
uint32_t aFirst = fPMs.front();
// Add all the PMs with index more than "StartPm"
for(uint32_t i=0; i<fPMs.size(); i++)
{
if((fPMs[i]>StartPm)&&(fPMs[i]<=aLast)) aPms.push_back(fPMs[i]);
}
// Add all the PMs with index less than "StartPm"
for(uint32_t i=0; i<fPMs.size(); i++)
{
if((fPMs[i]<StartPm)&&(fPMs[i]>=aFirst)) aPms.push_back(fPMs[i]);
}
}
if (StartPm == 0)
aPms = fPMs;
else
{
aPms.push_back(StartPm);
uint32_t aLast = fPMs.back();
uint32_t aFirst = fPMs.front();
// Add all the PMs with index more than "StartPm"
for (uint32_t i = 0; i < fPMs.size(); i++)
{
if ((fPMs[i] > StartPm) && (fPMs[i] <= aLast)) aPms.push_back(fPMs[i]);
}
// Add all the PMs with index less than "StartPm"
for (uint32_t i = 0; i < fPMs.size(); i++)
{
if ((fPMs[i] < StartPm) && (fPMs[i] >= aFirst)) aPms.push_back(fPMs[i]);
}
}
std::map<int, OamCache::dbRoots>::iterator iter = fPmDbrootMap->begin();
for (uint32_t i=0; i < aPms.size(); i++)
{
iter = fPmDbrootMap->find(aPms[i]);
if ((iter != fPmDbrootMap->end()) && ((iter->second).begin()!=(iter->second).end()))
{
aDbCntVec[i] = (iter->second).size();
//cout << "PM - "<<aPms[i] << " Size = " << aDbCntVec[i] << endl;
}
else
aDbCntVec[i] = 0;
}
std::map<int, OamCache::dbRoots>::iterator iter = fPmDbrootMap->begin();
int aTotDbRoots = 0;
for (uint32_t i=0; i<aDbCntVec.size(); i++) aTotDbRoots+=aDbCntVec[i];
for (uint32_t i = 0; i < aPms.size(); i++)
{
iter = fPmDbrootMap->find(aPms[i]);
//cout << "DbCntVec Size = " << aDbCntVec.size() << " TotDbRoots = "<<aTotDbRoots << endl;
if ((iter != fPmDbrootMap->end()) && ((iter->second).begin() != (iter->second).end()))
{
aDbCntVec[i] = (iter->second).size();
//cout << "PM - "<<aPms[i] << " Size = " << aDbCntVec[i] << endl;
}
else
aDbCntVec[i] = 0;
}
int aIdx=0;
while(aIdx < aTotDbRoots)
{
uint32_t aMax=0;
uint32_t aPmId=0;
uint32_t aRefIdx=0;
for (uint32_t i=0; i<aDbCntVec.size(); i++)
{
if(aDbCntVec[i] > aMax)
{
aMax = aDbCntVec[i];
aPmId = aPms[i];
aRefIdx = i;
}
}
if(aMax>0)
{
fPmDistSeq.push_back(aPmId);
aDbCntVec[aRefIdx]--;
}
aIdx++;
}
int aTotDbRoots = 0;
//cout <<"PM Distribution vector size "<< fPmDistSeq.size() << endl;
//for (uint32_t i=0; i<fPmDistSeq.size(); i++)
// cout <<"PM Distribution vector "<<i <<" = " << fPmDistSeq[i] << endl;
for (uint32_t i = 0; i < aDbCntVec.size(); i++) aTotDbRoots += aDbCntVec[i];
//cout << "DbCntVec Size = " << aDbCntVec.size() << " TotDbRoots = "<<aTotDbRoots << endl;
int aIdx = 0;
while (aIdx < aTotDbRoots)
{
uint32_t aMax = 0;
uint32_t aPmId = 0;
uint32_t aRefIdx = 0;
for (uint32_t i = 0; i < aDbCntVec.size(); i++)
{
if (aDbCntVec[i] > aMax)
{
aMax = aDbCntVec[i];
aPmId = aPms[i];
aRefIdx = i;
}
}
if (aMax > 0)
{
fPmDistSeq.push_back(aPmId);
aDbCntVec[aRefIdx]--;
}
aIdx++;
}
//cout <<"PM Distribution vector size "<< fPmDistSeq.size() << endl;
//for (uint32_t i=0; i<fPmDistSeq.size(); i++)
// cout <<"PM Distribution vector "<<i <<" = " << fPmDistSeq[i] << endl;
}
@ -522,38 +563,40 @@ void BatchLoader::buildBatchDistSeqVector(uint32_t StartPm)
uint32_t BatchLoader::selectNextPM()
{
if(0 == fPmDistSeq.size()) //Dist sequence not ready. First time the function is called
{
uint32_t PMId = 0;
//cout << "selectNextPM: size is 0. " << endl;
selectFirstPM(PMId);
return PMId;
}
if(fNextIdx >= fPmDistSeq.size()) fNextIdx=0; //reset it
return fPmDistSeq[fNextIdx++];
if (0 == fPmDistSeq.size()) //Dist sequence not ready. First time the function is called
{
uint32_t PMId = 0;
//cout << "selectNextPM: size is 0. " << endl;
selectFirstPM(PMId);
return PMId;
}
if (fNextIdx >= fPmDistSeq.size()) fNextIdx = 0; //reset it
return fPmDistSeq[fNextIdx++];
}
//------------------------------------------------------------------------------
void BatchLoader::reverseSequence()
{
if(0 == fNextIdx) fNextIdx = fPmDistSeq.size()-1;
else fNextIdx--;
if (0 == fNextIdx) fNextIdx = fPmDistSeq.size() - 1;
else fNextIdx--;
}
//------------------------------------------------------------------------------
void BatchLoader::prepareForSecondPM()
{
// We loop thru by calling the selectNextPM()
// When we get the aSecPm == aFirstPM, we will break so that when
// we call the same function again when we come back get the next PM
if((fFirstPm != 0)&&(fPMs.size()>1))
{
unsigned int aSecPm = selectNextPM();
while(fFirstPm!=aSecPm ) aSecPm = selectNextPM();
}
// We loop thru by calling the selectNextPM()
// When we get the aSecPm == aFirstPM, we will break so that when
// we call the same function again when we come back get the next PM
if ((fFirstPm != 0) && (fPMs.size() > 1))
{
unsigned int aSecPm = selectNextPM();
while (fFirstPm != aSecPm ) aSecPm = selectNextPM();
}
}
} // end of namespace

View File

@ -34,7 +34,7 @@
namespace batchloader
{
//------------------------------------------------------------------------------
/** @brief Class to find the PM id to send a batch of row
*/
@ -58,22 +58,22 @@ public:
uint32_t selectNextPM();
/**
* @brief Move to previous Sequence in the array.
* This can be used when we find that we cannot use the PM right now
* and want to use it later. for example the queue is full of the
* current PM and we want to get the same PM Id when we call selectNextPM()
* next time also.
*/
* @brief Move to previous Sequence in the array.
* This can be used when we find that we cannot use the PM right now
* and want to use it later. for example the queue is full of the
* current PM and we want to get the same PM Id when we call selectNextPM()
* next time also.
*/
void reverseSequence();
/*
/*
* @brief After calling selectFirstPM(), if we need to keep continuing to
* the next PM in the list, we need to call this. If we just want to start
* distributing from dbroot 1 onwards, no need to call this function.
*/
void prepareForSecondPM();
struct RootExtentsBlocks
struct RootExtentsBlocks
{
/** @brief the dbroot
*/
@ -81,20 +81,20 @@ public:
/** @brief the number of extents
*/
uint64_t numExtents;
/** @brief the number of blocks in the last partition
*/
uint64_t numBlocks;
/** @brief the number of blocks in the last partition
*/
uint64_t numBlocks;
};
struct PMRootInfo
{
/** @brief the module id
struct PMRootInfo
{
/** @brief the module id
*/
uint32_t PMId;
/** @brief the dbroot info
*/
std::vector<RootExtentsBlocks> rootInfo;
};
/** @brief the dbroot info
*/
std::vector<RootExtentsBlocks> rootInfo;
};
private:
/** @brief Select the first PM to send the first batch of rows.
@ -104,9 +104,9 @@ private:
*/
void selectFirstPM ( uint32_t& PMId);
/** @brief build the batch distribution sequence in a vector
* return void
*/
/** @brief build the batch distribution sequence in a vector
* return void
*/
void buildBatchDistSeqVector();
/** @brief build the batch distribution sequence in a vector
@ -115,15 +115,15 @@ private:
void buildBatchDistSeqVector(uint32_t StartPm);
typedef std::vector<uint32_t> BlIntVec;
BlIntVec fPMs;
BlIntVec fDbRoots;
BlIntVec fPmDistSeq;
uint32_t fNextIdx;
uint32_t fFirstPm;
execplan::CalpontSystemCatalog::SCN fSessionId;
uint32_t fTableOid;
oam::OamCache::PMDbrootsMap_t fPmDbrootMap;
oam::OamCache::dbRootPMMap_t fDbrootPMmap;
BlIntVec fPMs;
BlIntVec fDbRoots;
BlIntVec fPmDistSeq;
uint32_t fNextIdx;
uint32_t fFirstPm;
execplan::CalpontSystemCatalog::SCN fSessionId;
uint32_t fTableOid;
oam::OamCache::PMDbrootsMap_t fPmDbrootMap;
oam::OamCache::dbRootPMMap_t fDbrootPMmap;
};
} //end of namespace

View File

@ -59,77 +59,83 @@ volatile uint32_t MultiReturnCode;
int32_t extractRespCode(const ByteStream& bs)
{
if (bs.length() < (sizeof(ISMPacketHeader) + sizeof(int32_t)))
return 1;
const uint8_t* bytePtr = bs.buf();
const ISMPacketHeader* hdrp = reinterpret_cast<const ISMPacketHeader*>(bytePtr);
if (hdrp->Command != CACHE_OP_RESULTS)
return 1;
const int32_t* resp = reinterpret_cast<const int32_t*>(bytePtr + sizeof(ISMPacketHeader));
return *resp;
if (bs.length() < (sizeof(ISMPacketHeader) + sizeof(int32_t)))
return 1;
const uint8_t* bytePtr = bs.buf();
const ISMPacketHeader* hdrp = reinterpret_cast<const ISMPacketHeader*>(bytePtr);
if (hdrp->Command != CACHE_OP_RESULTS)
return 1;
const int32_t* resp = reinterpret_cast<const int32_t*>(bytePtr + sizeof(ISMPacketHeader));
return *resp;
}
class CacheOpThread
{
public:
CacheOpThread(const string& svr, const ByteStream& outBs) : fServerName(svr), fOutBs(outBs) {}
~CacheOpThread() {}
void operator()()
{
struct timespec ts = { 10, 0 };
int32_t rc = 0;
scoped_ptr<MessageQueueClient> cl(new MessageQueueClient(fServerName));
try
{
cl->write(fOutBs);
rc = extractRespCode(cl->read(&ts));
}
catch(...)
{
rc = 1;
}
if (rc != 0)
atomicops::atomicCAS<uint32_t>(&MultiReturnCode, 0, 1);
}
CacheOpThread(const string& svr, const ByteStream& outBs) : fServerName(svr), fOutBs(outBs) {}
~CacheOpThread() {}
void operator()()
{
struct timespec ts = { 10, 0 };
int32_t rc = 0;
scoped_ptr<MessageQueueClient> cl(new MessageQueueClient(fServerName));
try
{
cl->write(fOutBs);
rc = extractRespCode(cl->read(&ts));
}
catch (...)
{
rc = 1;
}
if (rc != 0)
atomicops::atomicCAS<uint32_t>(&MultiReturnCode, 0, 1);
}
private:
//CacheOpThread(const CacheOpThread& rhs);
//CacheOpThread& operator=(const CacheOpThread& rhs);
//CacheOpThread(const CacheOpThread& rhs);
//CacheOpThread& operator=(const CacheOpThread& rhs);
string fServerName;
ByteStream fOutBs;
string fServerName;
ByteStream fOutBs;
};
int sendToAll(const ByteStream& outBs)
{
//Not thread-safe: external synchronization is needed!
//Not thread-safe: external synchronization is needed!
// added code here to flush any running primprocs that may be active
// TODO: we really only need to flush each unique PrimProc, but we can't tell from the
// config file which those are, so use the same logic as joblist::DistributedEngineComm
Config* cf = Config::makeConfig();
// added code here to flush any running primprocs that may be active
// TODO: we really only need to flush each unique PrimProc, but we can't tell from the
// config file which those are, so use the same logic as joblist::DistributedEngineComm
Config* cf = Config::makeConfig();
const string section = "PrimitiveServers";
int cnt = static_cast<int>(Config::fromText(cf->getConfig(section, "Count")));
if (cnt <= 0) cnt = 1;
const string section = "PrimitiveServers";
int cnt = static_cast<int>(Config::fromText(cf->getConfig(section, "Count")));
thread_group tg;
int rc = 0;
MultiReturnCode = 0;
if (cnt <= 0) cnt = 1;
for (int i = 0; i < cnt; i++)
{
ostringstream oss;
oss << "PMS" << (i + 1);
tg.create_thread(CacheOpThread(oss.str(), outBs));
}
thread_group tg;
int rc = 0;
MultiReturnCode = 0;
tg.join_all();
for (int i = 0; i < cnt; i++)
{
ostringstream oss;
oss << "PMS" << (i + 1);
tg.create_thread(CacheOpThread(oss.str(), outBs));
}
if (MultiReturnCode != 0)
rc = -1;
tg.join_all();
return rc;
if (MultiReturnCode != 0)
rc = -1;
return rc;
}
}
@ -142,24 +148,25 @@ namespace cacheutils
*/
int flushPrimProcCache()
{
mutex::scoped_lock lk(CacheOpsMutex);
mutex::scoped_lock lk(CacheOpsMutex);
try
{
const int msgsize = sizeof(ISMPacketHeader);
uint8_t msgbuf[msgsize];
memset(msgbuf, 0, sizeof(ISMPacketHeader));
ISMPacketHeader* hdrp = reinterpret_cast<ISMPacketHeader*>(&msgbuf[0]);
hdrp->Command = CACHE_FLUSH;
try
{
const int msgsize = sizeof(ISMPacketHeader);
uint8_t msgbuf[msgsize];
memset(msgbuf, 0, sizeof(ISMPacketHeader));
ISMPacketHeader* hdrp = reinterpret_cast<ISMPacketHeader*>(&msgbuf[0]);
hdrp->Command = CACHE_FLUSH;
ByteStream bs(msgbuf, msgsize);
int rc = sendToAll(bs);
return rc;
}
catch (...)
{
}
return -1;
ByteStream bs(msgbuf, msgsize);
int rc = sendToAll(bs);
return rc;
}
catch (...)
{
}
return -1;
}
/**
@ -167,165 +174,176 @@ int flushPrimProcCache()
*/
int flushPrimProcBlocks(const BRM::BlockList_t& list)
{
if (list.empty()) return 0;
if (list.empty()) return 0;
mutex::scoped_lock lk(CacheOpsMutex);
mutex::scoped_lock lk(CacheOpsMutex);
#if defined(__LP64__) || defined(_WIN64)
if (list.size() > numeric_limits<uint32_t>::max()) return -1;
if (list.size() > numeric_limits<uint32_t>::max()) return -1;
#endif
try
{
const size_t msgsize = sizeof(ISMPacketHeader) + sizeof(uint32_t) + sizeof(LbidAtVer) * list.size();
scoped_array<uint8_t> msgbuf(new uint8_t[msgsize]);
memset(msgbuf.get(), 0, sizeof(ISMPacketHeader));
ISMPacketHeader* hdrp = reinterpret_cast<ISMPacketHeader*>(msgbuf.get());
hdrp->Command = CACHE_CLEAN_VSS;
uint32_t* cntp = reinterpret_cast<uint32_t*>(msgbuf.get() + sizeof(ISMPacketHeader));
*cntp = static_cast<uint32_t>(list.size());
LbidAtVer* itemp = reinterpret_cast<LbidAtVer*>(msgbuf.get() + sizeof(ISMPacketHeader) + sizeof(uint32_t));
BlockList_t::const_iterator iter = list.begin();
BlockList_t::const_iterator end = list.end();
while (iter != end)
{
itemp->LBID = static_cast<uint64_t>(iter->first);
itemp->Ver = static_cast<uint32_t>(iter->second);
++itemp;
++iter;
}
try
{
const size_t msgsize = sizeof(ISMPacketHeader) + sizeof(uint32_t) + sizeof(LbidAtVer) * list.size();
scoped_array<uint8_t> msgbuf(new uint8_t[msgsize]);
memset(msgbuf.get(), 0, sizeof(ISMPacketHeader));
ISMPacketHeader* hdrp = reinterpret_cast<ISMPacketHeader*>(msgbuf.get());
hdrp->Command = CACHE_CLEAN_VSS;
uint32_t* cntp = reinterpret_cast<uint32_t*>(msgbuf.get() + sizeof(ISMPacketHeader));
*cntp = static_cast<uint32_t>(list.size());
LbidAtVer* itemp = reinterpret_cast<LbidAtVer*>(msgbuf.get() + sizeof(ISMPacketHeader) + sizeof(uint32_t));
BlockList_t::const_iterator iter = list.begin();
BlockList_t::const_iterator end = list.end();
ByteStream bs(msgbuf.get(), msgsize);
int rc = sendToAll(bs);
return rc;
}
catch (...)
{
}
return -1;
while (iter != end)
{
itemp->LBID = static_cast<uint64_t>(iter->first);
itemp->Ver = static_cast<uint32_t>(iter->second);
++itemp;
++iter;
}
ByteStream bs(msgbuf.get(), msgsize);
int rc = sendToAll(bs);
return rc;
}
catch (...)
{
}
return -1;
}
int flushPrimProcAllverBlocks(const vector<LBID_t> &list)
int flushPrimProcAllverBlocks(const vector<LBID_t>& list)
{
if (list.empty()) return 0;
ByteStream bs(sizeof(ISMPacketHeader) + sizeof(uint32_t) + (sizeof(LBID_t) * list.size()));
ISMPacketHeader *hdr;
ISMPacketHeader* hdr;
int rc;
hdr = (ISMPacketHeader *) bs.getInputPtr();
hdr = (ISMPacketHeader*) bs.getInputPtr();
hdr->Command = FLUSH_ALL_VERSION;
bs.advanceInputPtr(sizeof(ISMPacketHeader));
bs << (uint32_t) list.size();
bs.append((uint8_t *) &list[0], sizeof(LBID_t) * list.size());
bs.append((uint8_t*) &list[0], sizeof(LBID_t) * list.size());
try {
mutex::scoped_lock lk(CacheOpsMutex);
try
{
mutex::scoped_lock lk(CacheOpsMutex);
rc = sendToAll(bs);
return rc;
}
catch (...)
catch (...)
{
}
return -1;
}
int flushOIDsFromCache(const vector<BRM::OID_t> &oids)
int flushOIDsFromCache(const vector<BRM::OID_t>& oids)
{
/* Message format:
* ISMPacketHeader
* uint32_t - OID count
* uint32_t * - OID array
*/
/* Message format:
* ISMPacketHeader
* uint32_t - OID count
* uint32_t * - OID array
*/
mutex::scoped_lock lk(CacheOpsMutex, defer_lock_t());
mutex::scoped_lock lk(CacheOpsMutex, defer_lock_t());
ByteStream bs;
ISMPacketHeader ism;
uint32_t i;
ByteStream bs;
ISMPacketHeader ism;
uint32_t i;
memset(&ism, 0, sizeof(ISMPacketHeader));
ism.Command = CACHE_FLUSH_BY_OID;
bs.load((uint8_t *) &ism, sizeof(ISMPacketHeader));
bs << (uint32_t) oids.size();
for (i = 0; i < oids.size(); i++)
bs << (uint32_t) oids[i];
memset(&ism, 0, sizeof(ISMPacketHeader));
ism.Command = CACHE_FLUSH_BY_OID;
bs.load((uint8_t*) &ism, sizeof(ISMPacketHeader));
bs << (uint32_t) oids.size();
lk.lock();
return sendToAll(bs);
for (i = 0; i < oids.size(); i++)
bs << (uint32_t) oids[i];
lk.lock();
return sendToAll(bs);
}
int flushPartition(const std::vector<BRM::OID_t> &oids, set<BRM::LogicalPartition>& partitionNums)
int flushPartition(const std::vector<BRM::OID_t>& oids, set<BRM::LogicalPartition>& partitionNums)
{
/* Message format:
* ISMPacketHeader
* uint32_t - partition count
* LogicalPartition * - partitionNum
* uint32_t - OID count
* uint32_t * - OID array
*/
/* Message format:
* ISMPacketHeader
* uint32_t - partition count
* LogicalPartition * - partitionNum
* uint32_t - OID count
* uint32_t * - OID array
*/
mutex::scoped_lock lk(CacheOpsMutex, defer_lock_t());
mutex::scoped_lock lk(CacheOpsMutex, defer_lock_t());
ByteStream bs;
ISMPacketHeader ism;
ByteStream bs;
ISMPacketHeader ism;
memset(&ism, 0, sizeof(ISMPacketHeader));
ism.Command = CACHE_FLUSH_PARTITION;
bs.load((uint8_t *) &ism, sizeof(ISMPacketHeader));
serializeSet<BRM::LogicalPartition>(bs, partitionNums);
serializeInlineVector<BRM::OID_t>(bs, oids);
memset(&ism, 0, sizeof(ISMPacketHeader));
ism.Command = CACHE_FLUSH_PARTITION;
bs.load((uint8_t*) &ism, sizeof(ISMPacketHeader));
serializeSet<BRM::LogicalPartition>(bs, partitionNums);
serializeInlineVector<BRM::OID_t>(bs, oids);
lk.lock();
return sendToAll(bs);
lk.lock();
return sendToAll(bs);
}
int dropPrimProcFdCache()
{
const int msgsize = sizeof(ISMPacketHeader);
uint8_t msgbuf[msgsize];
memset(msgbuf, 0, sizeof(ISMPacketHeader));
ISMPacketHeader* hdrp = reinterpret_cast<ISMPacketHeader*>(&msgbuf[0]);
hdrp->Command = CACHE_DROP_FDS;
ByteStream bs(msgbuf, msgsize);
try
{
mutex::scoped_lock lk(CacheOpsMutex);
int rc = sendToAll(bs);
return rc;
}
catch (...)
{
}
return -1;
const int msgsize = sizeof(ISMPacketHeader);
uint8_t msgbuf[msgsize];
memset(msgbuf, 0, sizeof(ISMPacketHeader));
ISMPacketHeader* hdrp = reinterpret_cast<ISMPacketHeader*>(&msgbuf[0]);
hdrp->Command = CACHE_DROP_FDS;
ByteStream bs(msgbuf, msgsize);
try
{
mutex::scoped_lock lk(CacheOpsMutex);
int rc = sendToAll(bs);
return rc;
}
catch (...)
{
}
return -1;
}
int purgePrimProcFdCache(const std::vector<BRM::FileInfo> files, const int pmId)
{
const int msgsize = sizeof(ISMPacketHeader);
uint8_t msgbuf[msgsize];
memset(msgbuf, 0, sizeof(ISMPacketHeader));
ISMPacketHeader* hdrp = reinterpret_cast<ISMPacketHeader*>(&msgbuf[0]);
hdrp->Command = CACHE_PURGE_FDS;
ByteStream bs(msgbuf, msgsize);
serializeInlineVector<FileInfo>(bs, files);
int32_t rc = 0;
try
{
struct timespec ts = { 10, 0 };
ostringstream oss;
oss << "PMS" << pmId;
scoped_ptr<MessageQueueClient> cl(new MessageQueueClient(oss.str()));
cl->write(bs);
rc = extractRespCode(cl->read(&ts));
}
catch (...)
{
rc = -1;
}
return rc;
const int msgsize = sizeof(ISMPacketHeader);
uint8_t msgbuf[msgsize];
memset(msgbuf, 0, sizeof(ISMPacketHeader));
ISMPacketHeader* hdrp = reinterpret_cast<ISMPacketHeader*>(&msgbuf[0]);
hdrp->Command = CACHE_PURGE_FDS;
ByteStream bs(msgbuf, msgsize);
serializeInlineVector<FileInfo>(bs, files);
int32_t rc = 0;
try
{
struct timespec ts = { 10, 0 };
ostringstream oss;
oss << "PMS" << pmId;
scoped_ptr<MessageQueueClient> cl(new MessageQueueClient(oss.str()));
cl->write(bs);
rc = extractRespCode(cl->read(&ts));
}
catch (...)
{
rc = -1;
}
return rc;
}
}

View File

@ -29,48 +29,48 @@
*/
namespace cacheutils
{
/** @brief flush the block cache
*
* Use the config file and messaging to signal all PrimProc's to flush their caches.
*/
int flushPrimProcCache();
/** @brief flush the block cache
*
* Use the config file and messaging to signal all PrimProc's to flush their caches.
*/
int flushPrimProcCache();
/** @brief flush these blocks from cache
*
* Use the config file and messaging to signal all PrimProc's to flush their caches of any of
* the specified LBID@@Vers.
*/
int flushPrimProcBlocks(const BRM::BlockList_t& list);
/** @brief flush all version of blocks from cache
*
* Use the config file and messaging to signal all PrimProc's to flush their caches of any of
* the specified LBIDs.
*/
int flushPrimProcAllverBlocks(const std::vector<BRM::LBID_t> &list);
/** @brief flush these blocks from cache
*
* Use the config file and messaging to signal all PrimProc's to flush their caches of any of
* the specified LBID@@Vers.
*/
int flushPrimProcBlocks(const BRM::BlockList_t& list);
/** @brief flush all versions of all lbids belonging to the given oids.
*
* Flush all versions of all lbids belonging to the given oids.
*/
int flushOIDsFromCache(const std::vector<BRM::OID_t> &);
/** @brief flush all version of blocks from cache
*
* Use the config file and messaging to signal all PrimProc's to flush their caches of any of
* the specified LBIDs.
*/
int flushPrimProcAllverBlocks(const std::vector<BRM::LBID_t>& list);
/** @brief Flush all versions of all lbids for the given OIDs and partition number.
*
* Flush all versions of all lbids for the given OIDs and partition number.
*/
int flushPartition(const std::vector<BRM::OID_t> &, std::set<BRM::LogicalPartition>& partitionNum);
/** @brief flush all versions of all lbids belonging to the given oids.
*
* Flush all versions of all lbids belonging to the given oids.
*/
int flushOIDsFromCache(const std::vector<BRM::OID_t>&);
/** @brief drop file descriptor cache
*
* Use the config file and messaging to signal all PrimProc's to drop the fd cache
*/
int dropPrimProcFdCache();
/** @brief drop the files from file descriptor cache
*
* Use the config file and messaging to signal all PrimProc's to drop the fd cache
*/
int purgePrimProcFdCache(const std::vector<BRM::FileInfo> files, const int pmId);
/** @brief Flush all versions of all lbids for the given OIDs and partition number.
*
* Flush all versions of all lbids for the given OIDs and partition number.
*/
int flushPartition(const std::vector<BRM::OID_t>&, std::set<BRM::LogicalPartition>& partitionNum);
/** @brief drop file descriptor cache
*
* Use the config file and messaging to signal all PrimProc's to drop the fd cache
*/
int dropPrimProcFdCache();
/** @brief drop the files from file descriptor cache
*
* Use the config file and messaging to signal all PrimProc's to drop the fd cache
*/
int purgePrimProcFdCache(const std::vector<BRM::FileInfo> files, const int pmId);
}
// vim:ts=4 sw=4:

View File

@ -57,11 +57,12 @@ int MonitorProcMem::fMemPctCheck = 0;
//------------------------------------------------------------------------------
void MonitorProcMem::operator()() const
{
while (1)
{
while (1)
{
if (fMaxPct > 0)
{
size_t pct = rss() * 100 / fMemTotal;
if (pct > fMaxPct)
{
cerr << "PrimProc: Too much memory allocated!" << endl;
@ -78,8 +79,8 @@ void MonitorProcMem::operator()() const
fMemFree = cg.getFreeMemory();
//calculateFreeMem();
pause_();
}
pause_();
}
}
//------------------------------------------------------------------------------
@ -97,48 +98,49 @@ size_t MonitorProcMem::memTotal() const
//------------------------------------------------------------------------------
size_t MonitorProcMem::rss() const
{
uint64_t rss;
uint64_t rss;
#if defined(_MSC_VER)
HANDLE hProcess;
PROCESS_MEMORY_COUNTERS pmc;
hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, fPid );
if (NULL == hProcess)
return 0;
HANDLE hProcess;
PROCESS_MEMORY_COUNTERS pmc;
hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, fPid );
if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) )
rss = pmc.WorkingSetSize;
else
rss = 0;
if (NULL == hProcess)
return 0;
CloseHandle( hProcess );
if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) )
rss = pmc.WorkingSetSize;
else
rss = 0;
CloseHandle( hProcess );
#elif defined(__FreeBSD__)
ostringstream cmd;
cmd << "ps -a -o rss -p " << getpid() << " | tail +2";
FILE* cmdPipe;
char input[80];
cmdPipe = popen(cmd.str().c_str(), "r");
input[0] = '\0';
fgets(input, 80, cmdPipe);
input[79] = '\0';
pclose(cmdPipe);
rss = atoi(input) * 1024LL;
ostringstream cmd;
cmd << "ps -a -o rss -p " << getpid() << " | tail +2";
FILE* cmdPipe;
char input[80];
cmdPipe = popen(cmd.str().c_str(), "r");
input[0] = '\0';
fgets(input, 80, cmdPipe);
input[79] = '\0';
pclose(cmdPipe);
rss = atoi(input) * 1024LL;
#else
ostringstream pstat;
pstat << "/proc/" << fPid << "/statm";
ifstream in(pstat.str().c_str());
size_t x;
ostringstream pstat;
pstat << "/proc/" << fPid << "/statm";
ifstream in(pstat.str().c_str());
size_t x;
in >> x;
in >> rss;
in >> x;
in >> rss;
//rss is now in pages, convert to bytes
rss *= fPageSize;
//rss is now in pages, convert to bytes
rss *= fPageSize;
#endif
return static_cast<size_t>(rss);
return static_cast<size_t>(rss);
}
//------------------------------------------------------------------------------
@ -146,31 +148,33 @@ size_t MonitorProcMem::rss() const
//------------------------------------------------------------------------------
void MonitorProcMem::pause_( ) const
{
struct timespec req;
struct timespec rem;
struct timespec req;
struct timespec rem;
req.tv_sec = fSleepSec;
req.tv_nsec = 0;
req.tv_sec = fSleepSec;
req.tv_nsec = 0;
rem.tv_sec = 0;
rem.tv_nsec = 0;
rem.tv_sec = 0;
rem.tv_nsec = 0;
while (1)
{
while (1)
{
#ifdef _MSC_VER
Sleep(req.tv_sec * 1000);
Sleep(req.tv_sec * 1000);
#else
if (nanosleep(&req, &rem) != 0)
{
if (rem.tv_sec > 0 || rem.tv_nsec > 0)
{
req = rem;
continue;
}
}
if (nanosleep(&req, &rem) != 0)
{
if (rem.tv_sec > 0 || rem.tv_nsec > 0)
{
req = rem;
continue;
}
}
#endif
break;
}
break;
}
}
//------------------------------------------------------------------------------
@ -178,7 +182,7 @@ void MonitorProcMem::pause_( ) const
//------------------------------------------------------------------------------
unsigned MonitorProcMem::memUsedPct()
{
return ((100 * (fMemTotal- fMemFree)) / fMemTotal);
return ((100 * (fMemTotal - fMemFree)) / fMemTotal);
}
//------------------------------------------------------------------------------
@ -187,7 +191,7 @@ unsigned MonitorProcMem::memUsedPct()
bool MonitorProcMem::isMemAvailable(size_t memRequest)
{
int memAvailPct = ((100 * (fMemFree - memRequest)) / fMemTotal);
return (memAvailPct < fMemPctCheck);
return (memAvailPct < fMemPctCheck);
}
} // end of namespace

View File

@ -44,78 +44,85 @@ namespace utils
*/
class MonitorProcMem
{
public:
/** @brief MonitorProcMem constructor
*
* @param maxPct (in) maximum allowable memory usage
* @param memChk (in) monitor total system physical memory usage
* @param msgLog (in) message logger to log msg to
* @param sec (in) number of seconds between memory checks
*/
explicit MonitorProcMem(size_t maxPct,
size_t memChk,
uint32_t subsystemID,
unsigned sec=1) :
fPid ( getpid() ),
fMaxPct ( maxPct ),
fSleepSec ( sec ),
fSubsystemID ( subsystemID ),
fPageSize ( getpagesize() ) { fMemPctCheck = memChk; fMemTotal = memTotal(); }
public:
/** @brief MonitorProcMem constructor
*
* @param maxPct (in) maximum allowable memory usage
* @param memChk (in) monitor total system physical memory usage
* @param msgLog (in) message logger to log msg to
* @param sec (in) number of seconds between memory checks
*/
explicit MonitorProcMem(size_t maxPct,
size_t memChk,
uint32_t subsystemID,
unsigned sec = 1) :
fPid ( getpid() ),
fMaxPct ( maxPct ),
fSleepSec ( sec ),
fSubsystemID ( subsystemID ),
fPageSize ( getpagesize() )
{
fMemPctCheck = memChk;
fMemTotal = memTotal();
}
virtual ~MonitorProcMem() {};
virtual ~MonitorProcMem() {};
/** @brief Thread entry point
*
* Entry point for this thread that monitors memory usage.
*/
virtual void operator()() const;
/** @brief Thread entry point
*
* Entry point for this thread that monitors memory usage.
*/
virtual void operator()() const;
/* Accessor to return the free memory
*
*/
size_t getFreeMem() const {return fMemFree;}
/* Accessor to return the free memory
*
*/
size_t getFreeMem() const
{
return fMemFree;
}
/* return the % of total memory used
*
*/
static unsigned memUsedPct();
/* return the % of total memory used
*
*/
static unsigned memUsedPct();
/* return true if memory usage is below configured limit
*
*/
static bool isMemAvailable(size_t memRequest = 0);
/* return true if memory usage is below configured limit
*
*/
static bool isMemAvailable(size_t memRequest = 0);
protected:
//Defaults are okay
//MonitorProcMem (const MonitorProcMem& rhs);
//MonitorProcMem& operator=(const MonitorProcMem& rhs);
//Defaults are okay
//MonitorProcMem (const MonitorProcMem& rhs);
//MonitorProcMem& operator=(const MonitorProcMem& rhs);
/** return the current process RSS size in MB
*
*/
size_t rss() const;
/** return the current process RSS size in MB
*
*/
size_t rss() const;
/* return the system RAM size in MB
*
*/
size_t memTotal() const;
/* return the system RAM size in MB
*
*/
size_t memTotal() const;
/* pause for fSleepSec seconds between memory usage checks
*
*/
void pause_() const;
/* pause for fSleepSec seconds between memory usage checks
*
*/
void pause_() const;
pid_t fPid; // process pid
size_t fMaxPct; // max allowable % memory use
unsigned fSleepSec; // sleep interval in seconds
uint32_t fSubsystemID; // Subsystem ID for Logger
int fPageSize; // page size for this host (in bytes)
pid_t fPid; // process pid
size_t fMaxPct; // max allowable % memory use
unsigned fSleepSec; // sleep interval in seconds
uint32_t fSubsystemID; // Subsystem ID for Logger
int fPageSize; // page size for this host (in bytes)
// @bug4507, monitor % of total used system memory
static uint64_t fMemTotal;
static uint64_t fMemFree;
static int fMemPctCheck;
mutable CGroupConfigurator cg;
// @bug4507, monitor % of total used system memory
static uint64_t fMemTotal;
static uint64_t fMemFree;
static int fMemPctCheck;
mutable CGroupConfigurator cg;
};
}

View File

@ -41,17 +41,19 @@ template <typename T>
inline T atomicInc(volatile T* mem)
{
#ifdef _MSC_VER
switch (sizeof(T))
{
case 4:
default:
return InterlockedIncrement(reinterpret_cast<volatile LONG*>(mem));
case 8:
return InterlockedIncrement64(reinterpret_cast<volatile LONGLONG*>(mem));
}
switch (sizeof(T))
{
case 4:
default:
return InterlockedIncrement(reinterpret_cast<volatile LONG*>(mem));
case 8:
return InterlockedIncrement64(reinterpret_cast<volatile LONGLONG*>(mem));
}
#else
return __sync_add_and_fetch(mem, 1);
return __sync_add_and_fetch(mem, 1);
#endif
}
@ -60,17 +62,19 @@ template <typename T>
inline T atomicDec(volatile T* mem)
{
#ifdef _MSC_VER
switch (sizeof(T))
{
case 4:
default:
return InterlockedDecrement(reinterpret_cast<volatile LONG*>(mem))+1;
case 8:
return InterlockedDecrement64(reinterpret_cast<volatile LONGLONG*>(mem))+1;
}
switch (sizeof(T))
{
case 4:
default:
return InterlockedDecrement(reinterpret_cast<volatile LONG*>(mem)) + 1;
case 8:
return InterlockedDecrement64(reinterpret_cast<volatile LONGLONG*>(mem)) + 1;
}
#else
return __sync_fetch_and_add(mem, -1);
return __sync_fetch_and_add(mem, -1);
#endif
}
@ -79,20 +83,22 @@ template <typename T>
inline T atomicAdd(volatile T* mem, T val)
{
#ifdef _MSC_VER
switch (sizeof(T))
{
case 4:
default:
InterlockedExchangeAdd(reinterpret_cast<volatile LONG*>(mem), val);
break;
case 8:
InterlockedExchangeAdd64(reinterpret_cast<volatile LONGLONG*>(mem), val);
break;
}
return *mem;
switch (sizeof(T))
{
case 4:
default:
InterlockedExchangeAdd(reinterpret_cast<volatile LONG*>(mem), val);
break;
case 8:
InterlockedExchangeAdd64(reinterpret_cast<volatile LONGLONG*>(mem), val);
break;
}
return *mem;
#else
return __sync_add_and_fetch(mem, val);
return __sync_add_and_fetch(mem, val);
#endif
}
@ -101,19 +107,22 @@ template <typename T>
inline T atomicSub(volatile T* mem, T val)
{
#ifdef _MSC_VER
switch (sizeof(T))
{
case 4:
default:
InterlockedExchangeAdd(reinterpret_cast<volatile LONG*>(mem), -(static_cast<LONG>(val)));
break;
case 8:
InterlockedExchangeAdd64(reinterpret_cast<volatile LONGLONG*>(mem), -(static_cast<LONGLONG>(val)));
break;
}
return *mem;
switch (sizeof(T))
{
case 4:
default:
InterlockedExchangeAdd(reinterpret_cast<volatile LONG*>(mem), -(static_cast<LONG>(val)));
break;
case 8:
InterlockedExchangeAdd64(reinterpret_cast<volatile LONGLONG*>(mem), -(static_cast<LONGLONG>(val)));
break;
}
return *mem;
#else
return __sync_sub_and_fetch(mem, val);
return __sync_sub_and_fetch(mem, val);
#endif
}
@ -121,9 +130,9 @@ inline T atomicSub(volatile T* mem, T val)
inline void atomicMb()
{
#ifdef _MSC_VER
MemoryBarrier();
MemoryBarrier();
#else
__sync_synchronize();
__sync_synchronize();
#endif
}
@ -138,19 +147,21 @@ template <typename T>
inline bool atomicCAS(volatile T* mem, T comp, T swap)
{
#ifdef _MSC_VER
switch (sizeof(T))
{
case 4:
default:
//The function returns the initial value of the mem parameter
return (InterlockedCompareExchange(reinterpret_cast<volatile LONG*>(mem), swap, comp) == comp);
case 8:
return (InterlockedCompareExchange64(reinterpret_cast<volatile LONGLONG*>(mem), swap, comp) == comp);
}
switch (sizeof(T))
{
case 4:
default:
//The function returns the initial value of the mem parameter
return (InterlockedCompareExchange(reinterpret_cast<volatile LONG*>(mem), swap, comp) == comp);
case 8:
return (InterlockedCompareExchange64(reinterpret_cast<volatile LONGLONG*>(mem), swap, comp) == comp);
}
#else
//If the current value of *mem is comp, then write swap into *comp. Return true if the comparison is successful and swap was written.
return __sync_bool_compare_and_swap(mem, comp, swap);
//If the current value of *mem is comp, then write swap into *comp. Return true if the comparison is successful and swap was written.
return __sync_bool_compare_and_swap(mem, comp, swap);
#endif
}
@ -158,9 +169,9 @@ inline bool atomicCAS(volatile T* mem, T comp, T swap)
inline void atomicYield()
{
#ifdef _MSC_VER
SwitchToThread();
SwitchToThread();
#else
sched_yield();
sched_yield();
#endif
}

View File

@ -53,17 +53,19 @@ using namespace std;
return err; \
} while (0)
namespace {
void log(logging::LOG_TYPE whichLogFile, const string &msg)
namespace
{
logging::Logger logger(12); //12 = configcpp
logger.logMessage(whichLogFile, msg, logging::LoggingID(12));
void log(logging::LOG_TYPE whichLogFile, const string& msg)
{
logging::Logger logger(12); //12 = configcpp
logger.logMessage(whichLogFile, msg, logging::LoggingID(12));
}
}
namespace utils {
namespace utils
{
CGroupConfigurator::CGroupConfigurator()
{
@ -75,6 +77,7 @@ CGroupConfigurator::CGroupConfigurator()
cGroupDefined = false;
else
cGroupDefined = true;
totalMemory = 0;
totalSwap = 0;
printedWarning = false;
@ -96,24 +99,31 @@ uint32_t CGroupConfigurator::getNumCoresFromCGroup()
if (!in)
RETURN_NO_GROUP(0);
try {
try
{
// Need to parse & count how many CPUs we have access to
in >> cpusString;
}
catch (...) {
catch (...)
{
RETURN_READ_ERROR(0);
}
// the file has comma-deliminted CPU ranges like "0-7,9,11-12".
size_t first = 0, last;
bool lastRange = false;
while (!lastRange) {
while (!lastRange)
{
size_t dash;
string oneRange;
last = cpusString.find(',', first);
if (last == string::npos) {
if (last == string::npos)
{
lastRange = true;
oneRange = cpusString.substr(first);
}
@ -122,14 +132,17 @@ uint32_t CGroupConfigurator::getNumCoresFromCGroup()
if ((dash = oneRange.find('-')) == string::npos) // single-cpu range
cpus++;
else {
const char *data = oneRange.c_str();
else
{
const char* data = oneRange.c_str();
uint32_t firstCPU = strtol(data, NULL, 10);
uint32_t lastCPU = strtol(&data[dash+1], NULL, 10);
uint32_t lastCPU = strtol(&data[dash + 1], NULL, 10);
cpus += lastCPU - firstCPU + 1;
}
first = last + 1;
}
//cout << "found " << cpus << " CPUS in the string " << cpusString << endl;
return cpus;
}
@ -137,13 +150,13 @@ uint32_t CGroupConfigurator::getNumCoresFromCGroup()
uint32_t CGroupConfigurator::getNumCoresFromProc()
{
#ifdef _MSC_VER
SYSTEM_INFO siSysInfo;
GetSystemInfo(&siSysInfo);
return siSysInfo.dwNumberOfProcessors;
SYSTEM_INFO siSysInfo;
GetSystemInfo(&siSysInfo);
return siSysInfo.dwNumberOfProcessors;
#else
uint32_t nc = sysconf(_SC_NPROCESSORS_ONLN);
return nc;
return nc;
#endif
}
@ -160,11 +173,14 @@ uint32_t CGroupConfigurator::getNumCores()
if (!cGroupDefined)
ret = getNumCoresFromProc();
else {
else
{
ret = getNumCoresFromCGroup();
if (ret == 0)
ret = getNumCoresFromProc();
}
//cout << "There are " << ret << " cores available" << endl;
return ret;
}
@ -178,11 +194,14 @@ uint64_t CGroupConfigurator::getTotalMemory()
if (!cGroupDefined)
ret = getTotalMemoryFromProc();
else {
else
{
ret = getTotalMemoryFromCGroup();
if (ret == 0)
ret = getTotalMemoryFromProc();
}
//cout << "Total mem available is " << ret << endl;
totalMemory = ret;
return totalMemory;
@ -190,44 +209,46 @@ uint64_t CGroupConfigurator::getTotalMemory()
uint64_t CGroupConfigurator::getTotalMemoryFromProc()
{
size_t memTot;
size_t memTot;
#if defined(_MSC_VER)
MEMORYSTATUSEX memStat;
memStat.dwLength = sizeof(memStat);
if (GlobalMemoryStatusEx(&memStat) == 0)
//FIXME: Assume 2GB?
memTot = 2 * 1024 * 1024;
else
{
MEMORYSTATUSEX memStat;
memStat.dwLength = sizeof(memStat);
if (GlobalMemoryStatusEx(&memStat) == 0)
//FIXME: Assume 2GB?
memTot = 2 * 1024 * 1024;
else
{
#ifndef _WIN64
memStat.ullTotalPhys = std::min(memStat.ullTotalVirtual, memStat.ullTotalPhys);
memStat.ullTotalPhys = std::min(memStat.ullTotalVirtual, memStat.ullTotalPhys);
#endif
//We now have the total phys mem in bytes
memTot = memStat.ullTotalPhys / 1024;
}
//We now have the total phys mem in bytes
memTot = memStat.ullTotalPhys / 1024;
}
#elif defined(__FreeBSD__)
string cmd("sysctl -a | awk '/realmem/ {print int(($2+1023)/1024);}'");
FILE* cmdPipe;
char input[80];
cmdPipe = popen(cmd.c_str(), "r");
input[0] = '\0';
fgets(input, 80, cmdPipe);
input[79] = '\0';
pclose(cmdPipe);
memTot = atoi(input);
string cmd("sysctl -a | awk '/realmem/ {print int(($2+1023)/1024);}'");
FILE* cmdPipe;
char input[80];
cmdPipe = popen(cmd.c_str(), "r");
input[0] = '\0';
fgets(input, 80, cmdPipe);
input[79] = '\0';
pclose(cmdPipe);
memTot = atoi(input);
#else
ifstream in("/proc/meminfo");
string x;
ifstream in("/proc/meminfo");
string x;
in >> x;
in >> memTot;
in >> x;
in >> memTot;
#endif
//memTot is now in KB, convert to bytes
memTot *= 1024;
//memTot is now in KB, convert to bytes
memTot *= 1024;
return memTot;
return memTot;
}
uint64_t CGroupConfigurator::getTotalMemoryFromCGroup()
@ -241,15 +262,19 @@ uint64_t CGroupConfigurator::getTotalMemoryFromCGroup()
filename = os.str();
in.open(filename.c_str());
if (!in)
RETURN_NO_GROUP(0);
try {
try
{
in >> ret;
}
catch (...) {
catch (...)
{
RETURN_READ_ERROR(0);
}
return ret;
}
@ -259,13 +284,16 @@ uint64_t CGroupConfigurator::getFreeMemory()
if (!cGroupDefined)
ret = getFreeMemoryFromProc();
else {
else
{
uint64_t usage = getMemUsageFromCGroup();
if (usage == 0)
ret = getFreeMemoryFromProc();
else
ret = getTotalMemory() - usage;
}
//cout << "free memory = " << ret << endl;
return ret;
}
@ -276,28 +304,34 @@ uint64_t CGroupConfigurator::getMemUsageFromCGroup()
bool found = false;
char oneline[80];
if (memUsageFilename.empty()) {
if (memUsageFilename.empty())
{
ostringstream filename;
filename << "/sys/fs/cgroup/memory/" << cGroupName << "/memory.stat";
memUsageFilename = filename.str();
}
ifstream in(memUsageFilename.c_str());
string &filename = memUsageFilename;
string& filename = memUsageFilename;
if (!in)
RETURN_NO_GROUP(0);
try {
while (in && !found) {
try
{
while (in && !found)
{
in.getline(oneline, 80);
if (strncmp(oneline, "rss", 2) == 0) {
if (strncmp(oneline, "rss", 2) == 0)
{
ret = atoll(&oneline[3]);
found = true;
}
}
}
catch(...) {
catch (...)
{
RETURN_READ_ERROR(0);
}
@ -306,59 +340,66 @@ uint64_t CGroupConfigurator::getMemUsageFromCGroup()
uint64_t CGroupConfigurator::getFreeMemoryFromProc()
{
uint64_t memFree = 0;
uint64_t buffers = 0;
uint64_t cached = 0;
uint64_t memTotal = 0;
uint64_t memAvailable = 0;
uint64_t memFree = 0;
uint64_t buffers = 0;
uint64_t cached = 0;
uint64_t memTotal = 0;
uint64_t memAvailable = 0;
#if defined(_MSC_VER)
MEMORYSTATUSEX memStat;
memStat.dwLength = sizeof(memStat);
if (GlobalMemoryStatusEx(&memStat))
{
memAvailable = memStat.ullAvailPhys;
MEMORYSTATUSEX memStat;
memStat.dwLength = sizeof(memStat);
if (GlobalMemoryStatusEx(&memStat))
{
memAvailable = memStat.ullAvailPhys;
#ifndef _WIN64
uint64_t tmp = getTotalMemoryFromProc();
if (memFree > tmp)
memAvailable = tmp;
if (memFree > tmp)
memAvailable = tmp;
#endif
}
}
#elif defined(__FreeBSD__)
// FreeBSD is not supported, no optimization.
memAvailable = 0;
// FreeBSD is not supported, no optimization.
memAvailable = 0;
#else
ifstream in("/proc/meminfo");
string x;
ifstream in("/proc/meminfo");
string x;
in >> x; // MemTotal:
in >> memTotal;
in >> x; // kB
in >> x; // MemTotal:
in >> memTotal;
in >> x; // kB
in >> x; // MemFree:
in >> memFree;
in >> x; // kB
in >> x; // MemFree:
in >> memFree;
in >> x; // kB
//check if available or buffers is passed
in >> x;
if ( x == "MemAvailable:")
{
in >> memAvailable; // MemAvailable
}
else
{ // centos 6 and older OSs
in >> buffers;
in >> x; // kB
//check if available or buffers is passed
in >> x;
if ( x == "MemAvailable:")
{
in >> memAvailable; // MemAvailable
}
else
{
// centos 6 and older OSs
in >> buffers;
in >> x; // kB
in >> x; // Cached:
in >> cached;
memAvailable = memFree + buffers + cached;
}
in >> x; // Cached:
in >> cached;
memAvailable = memFree + buffers + cached;
}
#endif
// amount available for application
memAvailable *= 1024;
// amount available for application
memAvailable *= 1024;
return memAvailable;
}
@ -371,14 +412,17 @@ uint64_t CGroupConfigurator::getTotalSwapSpace()
if (!cGroupDefined)
ret = getTotalSwapFromSysinfo();
else {
else
{
ret = getTotalMemAndSwapFromCGroup();
// if no limit is set in the cgroup, the file contains maxint64. Use sysinfo in that case.
if (ret == -1 || ret == numeric_limits<int64_t>::max())
ret = getTotalSwapFromSysinfo();
else
ret -= getTotalMemory();
}
//cout << "total swap=" << ret << endl;
totalSwap = ret;
return ret;
@ -402,15 +446,19 @@ int64_t CGroupConfigurator::getTotalMemAndSwapFromCGroup()
os << "/sys/fs/cgroup/memory/" << cGroupName << "/memory.memsw.limit_in_bytes";
filename = os.str();
in.open(filename.c_str());
if (!in)
RETURN_NO_GROUP(-1);
try {
try
{
in >> ret;
}
catch(...) {
catch (...)
{
RETURN_READ_ERROR(-1);
}
return ret;
}
@ -420,11 +468,14 @@ uint64_t CGroupConfigurator::getSwapInUse()
if (!cGroupDefined)
ret = getSwapInUseFromSysinfo();
else {
else
{
ret = getSwapInUseFromCGroup();
if (ret == -1)
ret = getSwapInUseFromSysinfo();
}
//cout << "current swap in use=" << ret << endl;
return ret;
}
@ -436,29 +487,37 @@ int64_t CGroupConfigurator::getSwapInUseFromCGroup()
bool found = false;
char oneline[80];
if (usedSwapFilename.empty()) {
if (usedSwapFilename.empty())
{
ostringstream os;
os << "/sys/fs/cgroup/memory/" << cGroupName << "/memory.stat";
usedSwapFilename = os.str();
}
string &filename = usedSwapFilename;
string& filename = usedSwapFilename;
in.open(filename.c_str());
if (!in)
RETURN_NO_GROUP(-1);
try {
while (in && !found) {
try
{
while (in && !found)
{
in.getline(oneline, 80);
if (strncmp(oneline, "swap", 4) == 0) {
if (strncmp(oneline, "swap", 4) == 0)
{
ret = atoll(&oneline[5]);
found = true;
}
}
}
catch(...) {
catch (...)
{
RETURN_READ_ERROR(-1);
}
return ret;
}

View File

@ -24,12 +24,14 @@
#include "configcpp.h"
namespace utils {
namespace utils
{
/* This class wraps a few methods for getting configuration variables that potentially
come from a cgroup. Might move it to utils/configcpp, and/or change the name. */
class CGroupConfigurator {
class CGroupConfigurator
{
public:
CGroupConfigurator();
virtual ~CGroupConfigurator();
@ -40,7 +42,10 @@ public:
uint64_t getTotalSwapSpace();
uint64_t getSwapInUse();
bool usingCGroup() { return cGroupDefined; }
bool usingCGroup()
{
return cGroupDefined;
}
private:
uint32_t getNumCoresFromProc();
@ -59,7 +64,7 @@ private:
std::string cGroupName;
bool cGroupDefined;
config::Config *config;
config::Config* config;
uint64_t totalMemory;
uint64_t totalSwap;
bool printedWarning;

View File

@ -40,83 +40,91 @@
using namespace std;
using namespace boost;
namespace utils {
FixedAllocator::FixedAllocator(const FixedAllocator &f)
namespace utils
{
elementCount = f.elementCount;
elementSize = f.elementSize;
tmpSpace = f.tmpSpace;
capacityRemaining = 0;
currentlyStored = 0;
FixedAllocator::FixedAllocator(const FixedAllocator& f)
{
elementCount = f.elementCount;
elementSize = f.elementSize;
tmpSpace = f.tmpSpace;
capacityRemaining = 0;
currentlyStored = 0;
}
FixedAllocator & FixedAllocator::operator=(const FixedAllocator &f)
FixedAllocator& FixedAllocator::operator=(const FixedAllocator& f)
{
elementCount = f.elementCount;
elementSize = f.elementSize;
tmpSpace = f.tmpSpace;
deallocateAll();
return *this;
elementCount = f.elementCount;
elementSize = f.elementSize;
tmpSpace = f.tmpSpace;
deallocateAll();
return *this;
}
void FixedAllocator::newBlock()
{
shared_array<uint8_t> next;
shared_array<uint8_t> next;
capacityRemaining = elementCount * elementSize;
if (!tmpSpace || mem.size() == 0) {
next.reset(new uint8_t[elementCount * elementSize]);
mem.push_back(next);
nextAlloc = next.get();
}
else {
currentlyStored = 0;
nextAlloc = mem.front().get();
}
capacityRemaining = elementCount * elementSize;
if (!tmpSpace || mem.size() == 0)
{
next.reset(new uint8_t[elementCount * elementSize]);
mem.push_back(next);
nextAlloc = next.get();
}
else
{
currentlyStored = 0;
nextAlloc = mem.front().get();
}
}
void * FixedAllocator::allocate()
void* FixedAllocator::allocate()
{
void *ret;
if (capacityRemaining < elementSize)
newBlock();
ret = nextAlloc;
nextAlloc += elementSize;
capacityRemaining -= elementSize;
currentlyStored += elementSize;
return ret;
void* ret;
if (capacityRemaining < elementSize)
newBlock();
ret = nextAlloc;
nextAlloc += elementSize;
capacityRemaining -= elementSize;
currentlyStored += elementSize;
return ret;
}
void * FixedAllocator::allocate(uint32_t len)
void* FixedAllocator::allocate(uint32_t len)
{
void *ret;
if (capacityRemaining < len)
newBlock();
ret = nextAlloc;
nextAlloc += len;
capacityRemaining -= len;
currentlyStored += len;
return ret;
void* ret;
if (capacityRemaining < len)
newBlock();
ret = nextAlloc;
nextAlloc += len;
capacityRemaining -= len;
currentlyStored += len;
return ret;
}
void FixedAllocator::truncateBy(uint32_t amt)
{
nextAlloc -= amt;
capacityRemaining += amt;
currentlyStored -= amt;
nextAlloc -= amt;
capacityRemaining += amt;
currentlyStored -= amt;
}
void FixedAllocator::deallocateAll()
{
mem.clear();
currentlyStored = 0;
capacityRemaining = 0;
mem.clear();
currentlyStored = 0;
capacityRemaining = 0;
}
uint64_t FixedAllocator::getMemUsage() const
uint64_t FixedAllocator::getMemUsage() const
{
return (mem.size() * elementCount * elementSize);
return (mem.size() * elementCount * elementSize);
}
}

View File

@ -22,7 +22,7 @@
/* This allocator is for frequent small allocations that all get deallocated at once.
It allocates large blocks of memory from the system and distributes 'allocsize'
units to the caller. When the large allocation is used up, it will allocate
units to the caller. When the large allocation is used up, it will allocate
more unless the 'tmpspace' flag is set. If it is, it will reuse the memory it
already allocated. This is useful for short-lived vars that are guaranteed to be
out of scope by the time the allocator wraps around.
@ -45,49 +45,50 @@
#define EXPORT
#endif
namespace utils {
namespace utils
{
class FixedAllocator
{
public:
EXPORT static const unsigned long DEFAULT_NUM_ELEMENTS=(4096 * 4); // should be a multiple of pagesize
EXPORT static const unsigned long DEFAULT_NUM_ELEMENTS = (4096 * 4); // should be a multiple of pagesize
EXPORT FixedAllocator() :
capacityRemaining(0),
elementCount(std::numeric_limits<unsigned long>::max()),
elementSize(0),
currentlyStored(0),
tmpSpace(false),
nextAlloc(0) {}
EXPORT explicit FixedAllocator(unsigned long allocSize, bool isTmpSpace = false,
unsigned long numElements = DEFAULT_NUM_ELEMENTS) :
capacityRemaining(0),
elementCount(numElements),
elementSize(allocSize),
currentlyStored(0),
tmpSpace(isTmpSpace),
nextAlloc(0) {}
EXPORT FixedAllocator(const FixedAllocator &);
EXPORT FixedAllocator & operator=(const FixedAllocator &);
virtual ~FixedAllocator() {}
EXPORT FixedAllocator() :
capacityRemaining(0),
elementCount(std::numeric_limits<unsigned long>::max()),
elementSize(0),
currentlyStored(0),
tmpSpace(false),
nextAlloc(0) {}
EXPORT explicit FixedAllocator(unsigned long allocSize, bool isTmpSpace = false,
unsigned long numElements = DEFAULT_NUM_ELEMENTS) :
capacityRemaining(0),
elementCount(numElements),
elementSize(allocSize),
currentlyStored(0),
tmpSpace(isTmpSpace),
nextAlloc(0) {}
EXPORT FixedAllocator(const FixedAllocator&);
EXPORT FixedAllocator& operator=(const FixedAllocator&);
virtual ~FixedAllocator() {}
EXPORT void* allocate();
EXPORT void* allocate(uint32_t len); // a hack to make it work more like a pool allocator (use PoolAllocator instead)
EXPORT void truncateBy(uint32_t amt); // returns a portion of mem just allocated; use with caution
void deallocate() { } // does nothing
EXPORT void deallocateAll(); // drops all memory in use
EXPORT uint64_t getMemUsage() const;
EXPORT void * allocate();
EXPORT void * allocate(uint32_t len); // a hack to make it work more like a pool allocator (use PoolAllocator instead)
EXPORT void truncateBy(uint32_t amt); // returns a portion of mem just allocated; use with caution
void deallocate() { } // does nothing
EXPORT void deallocateAll(); // drops all memory in use
EXPORT uint64_t getMemUsage() const;
private:
void newBlock();
void newBlock();
std::vector<boost::shared_array<uint8_t> > mem;
unsigned long capacityRemaining;
uint64_t elementCount;
unsigned long elementSize;
uint64_t currentlyStored;
bool tmpSpace;
uint8_t* nextAlloc;
std::vector<boost::shared_array<uint8_t> > mem;
unsigned long capacityRemaining;
uint64_t elementCount;
unsigned long elementSize;
uint64_t currentlyStored;
bool tmpSpace;
uint8_t* nextAlloc;
};
}

View File

@ -20,7 +20,7 @@
*
*****************************************************************************/
/** @file
/** @file
* class Hasher interface
*/
@ -38,241 +38,296 @@ namespace utils
inline uint32_t rotl32(uint32_t x, int8_t r)
{
return (x << r) | (x >> (32 - r));
return (x << r) | (x >> (32 - r));
}
inline uint32_t fmix(uint32_t h)
{
h ^= h >> 16;
h *= 0x85ebca6b;
h ^= h >> 13;
h *= 0xc2b2ae35;
h ^= h >> 16;
h ^= h >> 16;
h *= 0x85ebca6b;
h ^= h >> 13;
h *= 0xc2b2ae35;
h ^= h >> 16;
return h;
return h;
}
inline uint64_t fmix(uint64_t k)
{
k ^= k >> 33;
k *= 0xff51afd7ed558ccdULL;
k ^= k >> 33;
k *= 0xc4ceb9fe1a85ec53ULL;
k ^= k >> 33;
k ^= k >> 33;
k *= 0xff51afd7ed558ccdULL;
k ^= k >> 33;
k *= 0xc4ceb9fe1a85ec53ULL;
k ^= k >> 33;
return k;
return k;
}
inline uint64_t rotl64(uint64_t x, int8_t r)
{
return (x << r) | (x >> (64 - r));
return (x << r) | (x >> (64 - r));
}
class Hasher {
class Hasher
{
public:
inline uint32_t operator()(const std::string &s) const
{
return operator()(s.data(), s.length());
}
inline uint32_t operator()(const std::string& s) const
{
return operator()(s.data(), s.length());
}
inline uint32_t operator()(const char *data, uint64_t len) const
{
const int nblocks = len / 4;
inline uint32_t operator()(const char* data, uint64_t len) const
{
const int nblocks = len / 4;
uint32_t h1 = 0;
uint32_t h1 = 0;
const uint32_t c1 = 0xcc9e2d51;
const uint32_t c2 = 0x1b873593;
const uint32_t c1 = 0xcc9e2d51;
const uint32_t c2 = 0x1b873593;
//----------
// body
//----------
// body
const uint32_t * blocks = (const uint32_t *) (data + nblocks * 4);
const uint32_t* blocks = (const uint32_t*) (data + nblocks * 4);
for (int i = -nblocks; i; i++) {
uint32_t k1 = blocks[i];
for (int i = -nblocks; i; i++)
{
uint32_t k1 = blocks[i];
k1 *= c1;
k1 = rotl32(k1, 15);
k1 *= c2;
k1 *= c1;
k1 = rotl32(k1, 15);
k1 *= c2;
h1 ^= k1;
h1 = rotl32(h1, 13);
h1 = h1 * 5 + 0xe6546b64;
}
h1 ^= k1;
h1 = rotl32(h1, 13);
h1 = h1 * 5 + 0xe6546b64;
}
//----------
// tail
//----------
// tail
const uint8_t * tail = (const uint8_t*) (data + nblocks * 4);
const uint8_t* tail = (const uint8_t*) (data + nblocks * 4);
uint32_t k1 = 0;
uint32_t k1 = 0;
switch (len & 3) {
case 3: k1 ^= tail[2] << 16;
case 2: k1 ^= tail[1] << 8;
case 1: k1 ^= tail[0];
k1 *= c1;
k1 = rotl32(k1, 15);
k1 *= c2;
h1 ^= k1;
};
switch (len & 3)
{
case 3:
k1 ^= tail[2] << 16;
//----------
// finalization
case 2:
k1 ^= tail[1] << 8;
h1 ^= len;
h1 = fmix(h1);
return h1;
}
case 1:
k1 ^= tail[0];
k1 *= c1;
k1 = rotl32(k1, 15);
k1 *= c2;
h1 ^= k1;
};
//----------
// finalization
h1 ^= len;
h1 = fmix(h1);
return h1;
}
};
class Hasher_r {
class Hasher_r
{
public:
inline uint32_t operator()(const char *data, uint64_t len, uint32_t seed) const
{
const int nblocks = len / 4;
inline uint32_t operator()(const char* data, uint64_t len, uint32_t seed) const
{
const int nblocks = len / 4;
uint32_t h1 = seed;
uint32_t h1 = seed;
const uint32_t c1 = 0xcc9e2d51;
const uint32_t c2 = 0x1b873593;
const uint32_t c1 = 0xcc9e2d51;
const uint32_t c2 = 0x1b873593;
//----------
// body
//----------
// body
const uint32_t * blocks = (const uint32_t *) (data + nblocks * 4);
const uint32_t* blocks = (const uint32_t*) (data + nblocks * 4);
for (int i = -nblocks; i; i++) {
uint32_t k1 = blocks[i];
for (int i = -nblocks; i; i++)
{
uint32_t k1 = blocks[i];
k1 *= c1;
k1 = rotl32(k1, 15);
k1 *= c2;
k1 *= c1;
k1 = rotl32(k1, 15);
k1 *= c2;
h1 ^= k1;
h1 = rotl32(h1, 13);
h1 = h1 * 5 + 0xe6546b64;
}
h1 ^= k1;
h1 = rotl32(h1, 13);
h1 = h1 * 5 + 0xe6546b64;
}
//----------
// tail
//----------
// tail
const uint8_t * tail = (const uint8_t*) (data + nblocks * 4);
const uint8_t* tail = (const uint8_t*) (data + nblocks * 4);
uint32_t k1 = 0;
uint32_t k1 = 0;
switch (len & 3) {
case 3: k1 ^= tail[2] << 16;
case 2: k1 ^= tail[1] << 8;
case 1: k1 ^= tail[0];
k1 *= c1;
k1 = rotl32(k1, 15);
k1 *= c2;
h1 ^= k1;
};
switch (len & 3)
{
case 3:
k1 ^= tail[2] << 16;
return h1;
}
inline uint32_t finalize(uint32_t seed, uint32_t len) const {
seed ^= len;
seed = fmix(seed);
return seed;
}
case 2:
k1 ^= tail[1] << 8;
case 1:
k1 ^= tail[0];
k1 *= c1;
k1 = rotl32(k1, 15);
k1 *= c2;
h1 ^= k1;
};
return h1;
}
inline uint32_t finalize(uint32_t seed, uint32_t len) const
{
seed ^= len;
seed = fmix(seed);
return seed;
}
};
class Hasher128 {
class Hasher128
{
public:
inline uint64_t operator()(const char *data, uint64_t len) const
{
const int nblocks = len / 16;
inline uint64_t operator()(const char* data, uint64_t len) const
{
const int nblocks = len / 16;
uint64_t h1 = 0;
uint64_t h2 = 0;
uint64_t h1 = 0;
uint64_t h2 = 0;
const uint64_t c1 = 0x87c37b91114253d5ULL;
const uint64_t c2 = 0x4cf5ad432745937fULL;
const uint64_t c1 = 0x87c37b91114253d5ULL;
const uint64_t c2 = 0x4cf5ad432745937fULL;
//----------
// body
//----------
// body
const uint64_t * blocks = (const uint64_t *) (data);
const uint64_t* blocks = (const uint64_t*) (data);
for (int i = 0; i < nblocks; i++) {
uint64_t k1 = blocks[i * 2 + 0];
uint64_t k2 = blocks[i * 2 + 1];
for (int i = 0; i < nblocks; i++)
{
uint64_t k1 = blocks[i * 2 + 0];
uint64_t k2 = blocks[i * 2 + 1];
k1 *= c1;
k1 = rotl64(k1, 31);
k1 *= c2;
h1 ^= k1;
k1 *= c1;
k1 = rotl64(k1, 31);
k1 *= c2;
h1 ^= k1;
h1 = rotl64(h1, 27);
h1 += h2;
h1 = h1 * 5 + 0x52dce729;
h1 = rotl64(h1, 27);
h1 += h2;
h1 = h1 * 5 + 0x52dce729;
k2 *= c2;
k2 = rotl64(k2, 33);
k2 *= c1;
h2 ^= k2;
k2 *= c2;
k2 = rotl64(k2, 33);
k2 *= c1;
h2 ^= k2;
h2 = rotl64(h2, 31);
h2 += h1;
h2 = h2 * 5 + 0x38495ab5;
}
h2 = rotl64(h2, 31);
h2 += h1;
h2 = h2 * 5 + 0x38495ab5;
}
//----------
// tail
//----------
// tail
const uint8_t * tail = (const uint8_t*) (data + nblocks * 16);
const uint8_t* tail = (const uint8_t*) (data + nblocks * 16);
uint64_t k1 = 0;
uint64_t k2 = 0;
uint64_t k1 = 0;
uint64_t k2 = 0;
switch (len & 15) {
case 15: k2 ^= uint64_t(tail[14]) << 48;
case 14: k2 ^= uint64_t(tail[13]) << 40;
case 13: k2 ^= uint64_t(tail[12]) << 32;
case 12: k2 ^= uint64_t(tail[11]) << 24;
case 11: k2 ^= uint64_t(tail[10]) << 16;
case 10: k2 ^= uint64_t(tail[9]) << 8;
case 9: k2 ^= uint64_t(tail[8]) << 0;
k2 *= c2;
k2 = rotl64(k2, 33);
k2 *= c1;
h2 ^= k2;
case 8: k1 ^= uint64_t(tail[7]) << 56;
case 7: k1 ^= uint64_t(tail[6]) << 48;
case 6: k1 ^= uint64_t(tail[5]) << 40;
case 5: k1 ^= uint64_t(tail[4]) << 32;
case 4: k1 ^= uint64_t(tail[3]) << 24;
case 3: k1 ^= uint64_t(tail[2]) << 16;
case 2: k1 ^= uint64_t(tail[1]) << 8;
case 1: k1 ^= uint64_t(tail[0]) << 0;
k1 *= c1;
k1 = rotl64(k1, 31);
k1 *= c2;
h1 ^= k1;
};
switch (len & 15)
{
case 15:
k2 ^= uint64_t(tail[14]) << 48;
//----------
// finalization
case 14:
k2 ^= uint64_t(tail[13]) << 40;
h1 ^= len;
h2 ^= len;
case 13:
k2 ^= uint64_t(tail[12]) << 32;
h1 += h2;
h2 += h1;
case 12:
k2 ^= uint64_t(tail[11]) << 24;
h1 = fmix(h1);
h2 = fmix(h2);
case 11:
k2 ^= uint64_t(tail[10]) << 16;
h1 += h2;
h2 += h1;
case 10:
k2 ^= uint64_t(tail[9]) << 8;
return h1;
}
case 9:
k2 ^= uint64_t(tail[8]) << 0;
k2 *= c2;
k2 = rotl64(k2, 33);
k2 *= c1;
h2 ^= k2;
case 8:
k1 ^= uint64_t(tail[7]) << 56;
case 7:
k1 ^= uint64_t(tail[6]) << 48;
case 6:
k1 ^= uint64_t(tail[5]) << 40;
case 5:
k1 ^= uint64_t(tail[4]) << 32;
case 4:
k1 ^= uint64_t(tail[3]) << 24;
case 3:
k1 ^= uint64_t(tail[2]) << 16;
case 2:
k1 ^= uint64_t(tail[1]) << 8;
case 1:
k1 ^= uint64_t(tail[0]) << 0;
k1 *= c1;
k1 = rotl64(k1, 31);
k1 *= c2;
h1 ^= k1;
};
//----------
// finalization
h1 ^= len;
h2 ^= len;
h1 += h2;
h2 += h1;
h1 = fmix(h1);
h2 = fmix(h2);
h1 += h2;
h2 += h1;
return h1;
}
};
//------------------------------------------------------------------------------
@ -282,15 +337,15 @@ public:
//------------------------------------------------------------------------------
class TupleHasher
{
public:
TupleHasher(uint32_t len) : fHashLen(len) {}
inline uint64_t operator()(const uint8_t* hashKey) const
{
return fHasher(reinterpret_cast<const char*>(hashKey), fHashLen);
}
private:
Hasher fHasher;
uint32_t fHashLen;
public:
TupleHasher(uint32_t len) : fHashLen(len) {}
inline uint64_t operator()(const uint8_t* hashKey) const
{
return fHasher(reinterpret_cast<const char*>(hashKey), fHashLen);
}
private:
Hasher fHasher;
uint32_t fHashLen;
};
@ -301,14 +356,14 @@ class TupleHasher
//------------------------------------------------------------------------------
class TupleComparator
{
public:
TupleComparator(uint32_t len) : fCmpLen(len) {}
inline bool operator()(const uint8_t* hashKey1, const uint8_t* hashKey2) const
{
return (memcmp(hashKey1, hashKey2, fCmpLen) == 0);
}
private:
uint32_t fCmpLen;
public:
TupleComparator(uint32_t len) : fCmpLen(len) {}
inline bool operator()(const uint8_t* hashKey1, const uint8_t* hashKey2) const
{
return (memcmp(hashKey1, hashKey2, fCmpLen) == 0);
}
private:
uint32_t fCmpLen;
};

View File

@ -22,146 +22,220 @@
using namespace std;
using namespace execplan;
namespace utils {
namespace utils
{
uint64_t getNullValue(CalpontSystemCatalog::ColDataType t, uint32_t colWidth)
{
switch (t) {
case CalpontSystemCatalog::TINYINT:
return joblist::TINYINTNULL;
case CalpontSystemCatalog::SMALLINT:
return joblist::SMALLINTNULL;
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::INT:
return joblist::INTNULL;
case CalpontSystemCatalog::FLOAT:
switch (t)
{
case CalpontSystemCatalog::TINYINT:
return joblist::TINYINTNULL;
case CalpontSystemCatalog::SMALLINT:
return joblist::SMALLINTNULL;
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::INT:
return joblist::INTNULL;
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::UFLOAT:
return joblist::FLOATNULL;
case CalpontSystemCatalog::DATE:
return joblist::DATENULL;
case CalpontSystemCatalog::BIGINT:
return joblist::BIGINTNULL;
case CalpontSystemCatalog::DOUBLE:
return joblist::FLOATNULL;
case CalpontSystemCatalog::DATE:
return joblist::DATENULL;
case CalpontSystemCatalog::BIGINT:
return joblist::BIGINTNULL;
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::UDOUBLE:
return joblist::DOUBLENULL;
case CalpontSystemCatalog::DATETIME:
return joblist::DATETIMENULL;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::VARCHAR:
case CalpontSystemCatalog::STRINT: {
switch (colWidth) {
case 1: return joblist::CHAR1NULL;
case 2: return joblist::CHAR2NULL;
case 3:
case 4: return joblist::CHAR4NULL;
case 5:
case 6:
case 7:
case 8: return joblist::CHAR8NULL;
default:
throw logic_error("getNullValue() Can't return the NULL string");
}
break;
}
case CalpontSystemCatalog::DECIMAL:
return joblist::DOUBLENULL;
case CalpontSystemCatalog::DATETIME:
return joblist::DATETIMENULL;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::VARCHAR:
case CalpontSystemCatalog::STRINT:
{
switch (colWidth)
{
case 1:
return joblist::CHAR1NULL;
case 2:
return joblist::CHAR2NULL;
case 3:
case 4:
return joblist::CHAR4NULL;
case 5:
case 6:
case 7:
case 8:
return joblist::CHAR8NULL;
default:
throw logic_error("getNullValue() Can't return the NULL string");
}
break;
}
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
{
switch (colWidth) {
case 1 : return joblist::TINYINTNULL;
case 2 : return joblist::SMALLINTNULL;
case 4 : return joblist::INTNULL;
default: return joblist::BIGINTNULL;
}
break;
}
switch (colWidth)
{
case 1 :
return joblist::TINYINTNULL;
case 2 :
return joblist::SMALLINTNULL;
case 4 :
return joblist::INTNULL;
default:
return joblist::BIGINTNULL;
}
break;
}
case CalpontSystemCatalog::UTINYINT:
return joblist::UTINYINTNULL;
case CalpontSystemCatalog::USMALLINT:
return joblist::USMALLINTNULL;
case CalpontSystemCatalog::UMEDINT:
case CalpontSystemCatalog::UINT:
return joblist::UINTNULL;
case CalpontSystemCatalog::UBIGINT:
return joblist::UBIGINTNULL;
case CalpontSystemCatalog::LONGDOUBLE:
return -1; // no NULL value for long double yet, this is a nan.
case CalpontSystemCatalog::VARBINARY:
default:
ostringstream os;
os << "getNullValue(): got bad column type (" << t <<
"). Width=" << colWidth << endl;
throw logic_error(os.str());
}
case CalpontSystemCatalog::LONGDOUBLE:
return -1; // no NULL value for long double yet, this is a nan.
case CalpontSystemCatalog::VARBINARY:
default:
ostringstream os;
os << "getNullValue(): got bad column type (" << t <<
"). Width=" << colWidth << endl;
throw logic_error(os.str());
}
}
int64_t getSignedNullValue(CalpontSystemCatalog::ColDataType t, uint32_t colWidth)
{
switch (t) {
case CalpontSystemCatalog::TINYINT:
return (int64_t) ((int8_t) joblist::TINYINTNULL);
case CalpontSystemCatalog::SMALLINT:
return (int64_t) ((int16_t) joblist::SMALLINTNULL);
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::INT:
return (int64_t) ((int32_t) joblist::INTNULL);
case CalpontSystemCatalog::FLOAT:
switch (t)
{
case CalpontSystemCatalog::TINYINT:
return (int64_t) ((int8_t) joblist::TINYINTNULL);
case CalpontSystemCatalog::SMALLINT:
return (int64_t) ((int16_t) joblist::SMALLINTNULL);
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::INT:
return (int64_t) ((int32_t) joblist::INTNULL);
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::UFLOAT:
return (int64_t) ((int32_t) joblist::FLOATNULL);
case CalpontSystemCatalog::DATE:
return (int64_t) ((int32_t) joblist::DATENULL);
case CalpontSystemCatalog::BIGINT:
return joblist::BIGINTNULL;
case CalpontSystemCatalog::DOUBLE:
return (int64_t) ((int32_t) joblist::FLOATNULL);
case CalpontSystemCatalog::DATE:
return (int64_t) ((int32_t) joblist::DATENULL);
case CalpontSystemCatalog::BIGINT:
return joblist::BIGINTNULL;
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::UDOUBLE:
return joblist::DOUBLENULL;
case CalpontSystemCatalog::DATETIME:
return joblist::DATETIMENULL;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::VARCHAR:
case CalpontSystemCatalog::STRINT: {
switch (colWidth) {
case 1: return (int64_t) ((int8_t) joblist::CHAR1NULL);
case 2: return (int64_t) ((int16_t) joblist::CHAR2NULL);
case 3:
case 4: return (int64_t) ((int32_t) joblist::CHAR4NULL);
case 5:
case 6:
case 7:
case 8: return joblist::CHAR8NULL;
default:
throw logic_error("getSignedNullValue() Can't return the NULL string");
}
break;
}
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL: {
switch (colWidth) {
case 1 : return (int64_t) ((int8_t) joblist::TINYINTNULL);
case 2 : return (int64_t) ((int16_t) joblist::SMALLINTNULL);
case 4 : return (int64_t) ((int32_t) joblist::INTNULL);
default: return joblist::BIGINTNULL;
}
break;
}
return joblist::DOUBLENULL;
case CalpontSystemCatalog::DATETIME:
return joblist::DATETIMENULL;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::VARCHAR:
case CalpontSystemCatalog::STRINT:
{
switch (colWidth)
{
case 1:
return (int64_t) ((int8_t) joblist::CHAR1NULL);
case 2:
return (int64_t) ((int16_t) joblist::CHAR2NULL);
case 3:
case 4:
return (int64_t) ((int32_t) joblist::CHAR4NULL);
case 5:
case 6:
case 7:
case 8:
return joblist::CHAR8NULL;
default:
throw logic_error("getSignedNullValue() Can't return the NULL string");
}
break;
}
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
{
switch (colWidth)
{
case 1 :
return (int64_t) ((int8_t) joblist::TINYINTNULL);
case 2 :
return (int64_t) ((int16_t) joblist::SMALLINTNULL);
case 4 :
return (int64_t) ((int32_t) joblist::INTNULL);
default:
return joblist::BIGINTNULL;
}
break;
}
case CalpontSystemCatalog::UTINYINT:
return (int64_t) ((int8_t) joblist::UTINYINTNULL);
case CalpontSystemCatalog::USMALLINT:
return (int64_t) ((int16_t) joblist::USMALLINTNULL);
case CalpontSystemCatalog::UMEDINT:
case CalpontSystemCatalog::UINT:
return (int64_t) ((int32_t) joblist::UINTNULL);
case CalpontSystemCatalog::UBIGINT:
return (int64_t)joblist::UBIGINTNULL;
case CalpontSystemCatalog::LONGDOUBLE:
return -1; // no NULL value for long double yet, this is a nan.
case CalpontSystemCatalog::VARBINARY:
default:
ostringstream os;
os << "getSignedNullValue(): got bad column type (" << t <<
"). Width=" << colWidth << endl;
throw logic_error(os.str());
}
case CalpontSystemCatalog::LONGDOUBLE:
return -1; // no NULL value for long double yet, this is a nan.
case CalpontSystemCatalog::VARBINARY:
default:
ostringstream os;
os << "getSignedNullValue(): got bad column type (" << t <<
"). Width=" << colWidth << endl;
throw logic_error(os.str());
}
}

View File

@ -21,7 +21,8 @@
#include "../../dbcon/execplan/calpontsystemcatalog.h"
namespace utils {
namespace utils
{
// returns the NULL value for our 'numeric' types including short strings.
// The width is only relevant for long string columns.

View File

@ -32,69 +32,74 @@ using namespace boost;
namespace utils
{
PoolAllocator & PoolAllocator::operator=(const PoolAllocator &v)
PoolAllocator& PoolAllocator::operator=(const PoolAllocator& v)
{
allocSize = v.allocSize;
tmpSpace = v.tmpSpace;
deallocateAll();
return *this;
allocSize = v.allocSize;
tmpSpace = v.tmpSpace;
deallocateAll();
return *this;
}
void PoolAllocator::deallocateAll()
{
capacityRemaining = 0;
nextAlloc = NULL;
memUsage = 0;
mem.clear();
oob.clear();
capacityRemaining = 0;
nextAlloc = NULL;
memUsage = 0;
mem.clear();
oob.clear();
}
void PoolAllocator::newBlock()
{
shared_array<uint8_t> next;
shared_array<uint8_t> next;
capacityRemaining = allocSize;
if (!tmpSpace || mem.size() == 0) {
next.reset(new uint8_t[allocSize]);
mem.push_back(next);
nextAlloc = next.get();
}
else
nextAlloc = mem.front().get();
capacityRemaining = allocSize;
if (!tmpSpace || mem.size() == 0)
{
next.reset(new uint8_t[allocSize]);
mem.push_back(next);
nextAlloc = next.get();
}
else
nextAlloc = mem.front().get();
}
void * PoolAllocator::allocate(uint64_t size)
void* PoolAllocator::allocate(uint64_t size)
{
void *ret;
void* ret;
if (size > allocSize) {
OOBMemInfo memInfo;
memUsage += size;
memInfo.mem.reset(new uint8_t[size]);
memInfo.size = size;
ret = (void *) memInfo.mem.get();
oob[ret] = memInfo;
return ret;
}
if (size > allocSize)
{
OOBMemInfo memInfo;
if (size > capacityRemaining)
newBlock();
ret = (void *) nextAlloc;
nextAlloc += size;
capacityRemaining -= size;
memUsage += size;
return ret;
memUsage += size;
memInfo.mem.reset(new uint8_t[size]);
memInfo.size = size;
ret = (void*) memInfo.mem.get();
oob[ret] = memInfo;
return ret;
}
if (size > capacityRemaining)
newBlock();
ret = (void*) nextAlloc;
nextAlloc += size;
capacityRemaining -= size;
memUsage += size;
return ret;
}
void PoolAllocator::deallocate(void *p)
void PoolAllocator::deallocate(void* p)
{
OutOfBandMap::iterator it = oob.find(p);
if (it == oob.end())
return;
memUsage -= it->second.size;
oob.erase(it);
OutOfBandMap::iterator it = oob.find(p);
if (it == oob.end())
return;
memUsage -= it->second.size;
oob.erase(it);
}
}

View File

@ -32,52 +32,60 @@
#include <map>
#include <boost/shared_array.hpp>
namespace utils {
namespace utils
{
class PoolAllocator
{
public:
static const unsigned DEFAULT_WINDOW_SIZE = 4096 * 40; // should be an integral # of pages
static const unsigned DEFAULT_WINDOW_SIZE = 4096 * 40; // should be an integral # of pages
explicit PoolAllocator(unsigned windowSize = DEFAULT_WINDOW_SIZE, bool isTmpSpace = false) :
allocSize(windowSize),
tmpSpace(isTmpSpace),
capacityRemaining(0),
memUsage(0),
nextAlloc(0) { }
PoolAllocator(const PoolAllocator &p) :
allocSize(p.allocSize),
tmpSpace(p.tmpSpace),
capacityRemaining(0),
memUsage(0),
nextAlloc(0) { }
virtual ~PoolAllocator() {}
explicit PoolAllocator(unsigned windowSize = DEFAULT_WINDOW_SIZE, bool isTmpSpace = false) :
allocSize(windowSize),
tmpSpace(isTmpSpace),
capacityRemaining(0),
memUsage(0),
nextAlloc(0) { }
PoolAllocator(const PoolAllocator& p) :
allocSize(p.allocSize),
tmpSpace(p.tmpSpace),
capacityRemaining(0),
memUsage(0),
nextAlloc(0) { }
virtual ~PoolAllocator() {}
PoolAllocator & operator=(const PoolAllocator &);
PoolAllocator& operator=(const PoolAllocator&);
void *allocate(uint64_t size);
void deallocate(void *p);
void deallocateAll();
void* allocate(uint64_t size);
void deallocate(void* p);
void deallocateAll();
inline uint64_t getMemUsage() const { return memUsage; }
unsigned getWindowSize() const { return allocSize; }
inline uint64_t getMemUsage() const
{
return memUsage;
}
unsigned getWindowSize() const
{
return allocSize;
}
private:
void newBlock();
void newBlock();
unsigned allocSize;
std::vector<boost::shared_array<uint8_t> > mem;
bool tmpSpace;
unsigned capacityRemaining;
uint64_t memUsage;
uint8_t *nextAlloc;
struct OOBMemInfo {
boost::shared_array<uint8_t> mem;
uint64_t size;
};
typedef std::map<void *, OOBMemInfo> OutOfBandMap;
OutOfBandMap oob; // for mem chunks bigger than the window size; these can be dealloc'd
unsigned allocSize;
std::vector<boost::shared_array<uint8_t> > mem;
bool tmpSpace;
unsigned capacityRemaining;
uint64_t memUsage;
uint8_t* nextAlloc;
struct OOBMemInfo
{
boost::shared_array<uint8_t> mem;
uint64_t size;
};
typedef std::map<void*, OOBMemInfo> OutOfBandMap;
OutOfBandMap oob; // for mem chunks bigger than the window size; these can be dealloc'd
};
}

View File

@ -51,154 +51,212 @@ template<typename T> class SimpleAllocator;
#define OPT_NODE_UNITS 10
class SimplePool
{
public:
SimplePool() : fNext(NULL), fEnd(NULL), fTableMemSize(0) {}
~SimplePool() { reset(); }
public:
SimplePool() : fNext(NULL), fEnd(NULL), fTableMemSize(0) {}
~SimplePool()
{
reset();
}
inline void* allocate(size_t n, const void* = 0);
inline void deallocate(void* p, size_t n);
inline size_t max_size() const throw();
inline uint64_t getMemUsage() const;
inline void* allocate(size_t n, const void* = 0);
inline void deallocate(void* p, size_t n);
inline size_t max_size() const throw();
inline uint64_t getMemUsage() const;
private:
static const size_t fUnitPerChunk = OPT_NODE_UNITS*10240;
static const size_t fUnitPerChunk = OPT_NODE_UNITS * 10240;
inline void reset();
inline void allocateNewChunk();
inline void reset();
inline void allocateNewChunk();
// MemUnit stores a pointer to next unit before allocated, and T after allocated.
union MemUnit
{
MemUnit* fNext;
uint64_t fData;
} *fNext, *fEnd; // fNext: next available unit, fEnd: one off the last unit
// MemUnit stores a pointer to next unit before allocated, and T after allocated.
union MemUnit
{
MemUnit* fNext;
uint64_t fData;
}* fNext, *fEnd; // fNext: next available unit, fEnd: one off the last unit
std::list<MemUnit*> fBlockList;
uint64_t fTableMemSize;
std::list<MemUnit*> fBlockList;
uint64_t fTableMemSize;
static const size_t fUnitSize = sizeof(MemUnit);
static const size_t fMaxNodeSize = fUnitSize * OPT_NODE_UNITS;
static const size_t fChunkSize = fUnitSize * fUnitPerChunk;
static const size_t fUnitSize = sizeof(MemUnit);
static const size_t fMaxNodeSize = fUnitSize * OPT_NODE_UNITS;
static const size_t fChunkSize = fUnitSize * fUnitPerChunk;
};
template<typename T>
class SimpleAllocator
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T *pointer;
typedef const T *const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef T value_type;
template<typename U> struct rebind { typedef SimpleAllocator<U> other; };
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef T value_type;
template<typename U> struct rebind
{
typedef SimpleAllocator<U> other;
};
SimpleAllocator() throw() {}
SimpleAllocator(boost::shared_ptr<SimplePool> pool) throw() { fPool = pool; }
SimpleAllocator(const SimpleAllocator& alloc) { fPool = alloc.fPool; }
template<class U> SimpleAllocator(const SimpleAllocator<U>& alloc) { fPool = alloc.fPool; }
SimpleAllocator() throw() {}
SimpleAllocator(boost::shared_ptr<SimplePool> pool) throw()
{
fPool = pool;
}
SimpleAllocator(const SimpleAllocator& alloc)
{
fPool = alloc.fPool;
}
template<class U> SimpleAllocator(const SimpleAllocator<U>& alloc)
{
fPool = alloc.fPool;
}
~SimpleAllocator() throw() { }
~SimpleAllocator() throw() { }
pointer address(reference x) const { return &x; }
const_pointer address(const_reference x) const { return &x; }
pointer address(reference x) const
{
return &x;
}
const_pointer address(const_reference x) const
{
return &x;
}
pointer allocate(size_type n, const void* = 0)
{ return static_cast<pointer>(fPool->allocate(n*sizeof(T))); }
void deallocate(pointer p, size_type n)
{ fPool->deallocate(p, n*sizeof(T)); }
pointer allocate(size_type n, const void* = 0)
{
return static_cast<pointer>(fPool->allocate(n * sizeof(T)));
}
void deallocate(pointer p, size_type n)
{
fPool->deallocate(p, n * sizeof(T));
}
#ifdef _MSC_VER
//The MSVC STL library really needs this to return a big number...
size_type max_size() const throw() { return std::numeric_limits<size_type>::max(); }
//The MSVC STL library really needs this to return a big number...
size_type max_size() const throw()
{
return std::numeric_limits<size_type>::max();
}
#else
size_type max_size() const throw() { return fPool->max_size()/sizeof(T); }
size_type max_size() const throw()
{
return fPool->max_size() / sizeof(T);
}
#endif
void construct(pointer ptr, const T& val) { new ((void *)ptr) T(val); }
void destroy(pointer ptr) { ptr->T::~T(); }
void construct(pointer ptr, const T& val)
{
new ((void*)ptr) T(val);
}
void destroy(pointer ptr)
{
ptr->T::~T();
}
SimplePool* getPool() { return fPool; }
void setPool(SimplePool* pool) { fPool = pool; }
SimplePool* getPool()
{
return fPool;
}
void setPool(SimplePool* pool)
{
fPool = pool;
}
boost::shared_ptr<SimplePool> fPool;
boost::shared_ptr<SimplePool> fPool;
};
// inlines
inline void * SimplePool::allocate(size_t n, const void *dur)
inline void* SimplePool::allocate(size_t n, const void* dur)
{
// make sure the block allocated is on unit boundary
size_t unitCount = n / fUnitSize;
if ((n % fUnitSize) != 0)
unitCount += 1;
// make sure the block allocated is on unit boundary
size_t unitCount = n / fUnitSize;
// if for control table, let new allocator handle it.
if (unitCount > OPT_NODE_UNITS) {
fTableMemSize += n;
return new uint8_t[n];
}
// allocate node
MemUnit *curr = fNext;
do {
if (curr == NULL) {
allocateNewChunk();
curr = fNext;
}
fNext = curr + unitCount;
if (fNext > fEnd)
curr = NULL;
} while (!curr);
if ((n % fUnitSize) != 0)
unitCount += 1;
return curr;
// if for control table, let new allocator handle it.
if (unitCount > OPT_NODE_UNITS)
{
fTableMemSize += n;
return new uint8_t[n];
}
// allocate node
MemUnit* curr = fNext;
do
{
if (curr == NULL)
{
allocateNewChunk();
curr = fNext;
}
fNext = curr + unitCount;
if (fNext > fEnd)
curr = NULL;
}
while (!curr);
return curr;
}
inline void SimplePool::deallocate(void* p, size_t n)
{
// only delete the old control table, which is allocated by new allocator.
if (n > fMaxNodeSize)
{
fTableMemSize -= n;
delete [] (static_cast<uint8_t*>(p));
}
// only delete the old control table, which is allocated by new allocator.
if (n > fMaxNodeSize)
{
fTableMemSize -= n;
delete [] (static_cast<uint8_t*>(p));
}
}
inline size_t SimplePool::max_size() const throw()
inline size_t SimplePool::max_size() const throw()
{
return fUnitSize * fUnitPerChunk;
return fUnitSize * fUnitPerChunk;
}
inline uint64_t SimplePool::getMemUsage() const
{
return fTableMemSize + fBlockList.size() * fChunkSize +
// add list overhead, element type is a pointer, and
// lists store a next pointer.
fBlockList.size() * 2 * sizeof(void *);
return fTableMemSize + fBlockList.size() * fChunkSize +
// add list overhead, element type is a pointer, and
// lists store a next pointer.
fBlockList.size() * 2 * sizeof(void*);
}
inline void SimplePool::reset()
{
for (std::list<MemUnit*>::iterator i = fBlockList.begin(); i != fBlockList.end(); i++)
delete [] (*i);
fNext = NULL;
fEnd = NULL;
for (std::list<MemUnit*>::iterator i = fBlockList.begin(); i != fBlockList.end(); i++)
delete [] (*i);
fNext = NULL;
fEnd = NULL;
}
inline void SimplePool::allocateNewChunk()
{
MemUnit* chunk = new MemUnit[fUnitPerChunk];
fBlockList.push_back(chunk);
fNext = chunk;
fEnd = chunk + fUnitPerChunk;
MemUnit* chunk = new MemUnit[fUnitPerChunk];
fBlockList.push_back(chunk);
fNext = chunk;
fEnd = chunk + fUnitPerChunk;
}
template <typename T1, typename T2>
inline bool operator==(const SimpleAllocator<T1>&, const SimpleAllocator<T2>&) {return true;}
inline bool operator==(const SimpleAllocator<T1>&, const SimpleAllocator<T2>&)
{
return true;
}
template <typename T1, typename T2>
inline bool operator!=(const SimpleAllocator<T1>&, const SimpleAllocator<T2>&) {return false;}
inline bool operator!=(const SimpleAllocator<T1>&, const SimpleAllocator<T2>&)
{
return false;
}
}
#endif // UTILS_SIMPLEALLOCATOR_H

View File

@ -32,13 +32,14 @@
#ifndef STLPOOLALLOCATOR_H_
#define STLPOOLALLOCATOR_H_
namespace utils {
namespace utils
{
/* If using the pool allocator with a boost smart ptr, use an instance of this
as the deleter. */
struct BoostPoolDeallocator
{
inline void operator()(void *ptr) { };
inline void operator()(void* ptr) { };
};
/* This is an STL-compliant wrapper for PoolAllocator + an optimization for containers
@ -47,63 +48,69 @@ struct BoostPoolDeallocator
template<class T>
class STLPoolAllocator
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T *pointer;
typedef const T *const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef T value_type;
template<class U> struct rebind { typedef STLPoolAllocator<U> other; };
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef T value_type;
template<class U> struct rebind
{
typedef STLPoolAllocator<U> other;
};
STLPoolAllocator() throw();
STLPoolAllocator(const STLPoolAllocator &) throw();
STLPoolAllocator(uint32_t capacity) throw();
template<class U> STLPoolAllocator(const STLPoolAllocator<U> &) throw();
~STLPoolAllocator();
STLPoolAllocator() throw();
STLPoolAllocator(const STLPoolAllocator&) throw();
STLPoolAllocator(uint32_t capacity) throw();
template<class U> STLPoolAllocator(const STLPoolAllocator<U>&) throw();
~STLPoolAllocator();
STLPoolAllocator<T>& operator=(const STLPoolAllocator<T> &);
STLPoolAllocator<T>& operator=(const STLPoolAllocator<T>&);
void usePoolAllocator(boost::shared_ptr<PoolAllocator> b);
boost::shared_ptr<utils::PoolAllocator> getPoolAllocator();
void usePoolAllocator(boost::shared_ptr<PoolAllocator> b);
boost::shared_ptr<utils::PoolAllocator> getPoolAllocator();
pointer allocate(size_type, const void *hint = 0);
void deallocate(pointer p, size_type n);
size_type max_size() const throw();
inline uint64_t getMemUsage() const { return pa->getMemUsage(); }
pointer allocate(size_type, const void* hint = 0);
void deallocate(pointer p, size_type n);
size_type max_size() const throw();
inline uint64_t getMemUsage() const
{
return pa->getMemUsage();
}
void construct(pointer p, const T& val);
void destroy(pointer p);
void construct(pointer p, const T& val);
void destroy(pointer p);
static const uint32_t DEFAULT_SIZE = 4096*sizeof(T);
static const uint32_t DEFAULT_SIZE = 4096 * sizeof(T);
boost::shared_ptr<utils::PoolAllocator> pa;
boost::shared_ptr<utils::PoolAllocator> pa;
};
template<class T>
STLPoolAllocator<T>::STLPoolAllocator() throw()
{
pa.reset(new PoolAllocator(DEFAULT_SIZE));
pa.reset(new PoolAllocator(DEFAULT_SIZE));
}
template<class T>
STLPoolAllocator<T>::STLPoolAllocator(const STLPoolAllocator<T> &s) throw()
STLPoolAllocator<T>::STLPoolAllocator(const STLPoolAllocator<T>& s) throw()
{
pa = s.pa;
pa = s.pa;
}
template<class T>
STLPoolAllocator<T>::STLPoolAllocator(uint32_t capacity) throw()
{
pa.reset(new PoolAllocator(capacity));
pa.reset(new PoolAllocator(capacity));
}
template<class T>
template<class U>
STLPoolAllocator<T>::STLPoolAllocator(const STLPoolAllocator<U> &s) throw()
STLPoolAllocator<T>::STLPoolAllocator(const STLPoolAllocator<U>& s) throw()
{
pa = s.pa;
pa = s.pa;
}
template<class T>
@ -114,64 +121,64 @@ STLPoolAllocator<T>::~STLPoolAllocator()
template<class T>
void STLPoolAllocator<T>::usePoolAllocator(boost::shared_ptr<PoolAllocator> p)
{
pa = p;
pa = p;
}
template<class T>
boost::shared_ptr<utils::PoolAllocator> STLPoolAllocator<T>::getPoolAllocator()
{
return pa;
return pa;
}
template<class T>
typename STLPoolAllocator<T>::pointer
STLPoolAllocator<T>::allocate(typename STLPoolAllocator<T>::size_type s,
typename std::allocator<void>::const_pointer hint)
typename std::allocator<void>::const_pointer hint)
{
return (pointer) pa->allocate(s*sizeof(T));
return (pointer) pa->allocate(s * sizeof(T));
}
template<class T>
void STLPoolAllocator<T>::deallocate(typename STLPoolAllocator<T>::pointer p,
typename STLPoolAllocator<T>::size_type n)
typename STLPoolAllocator<T>::size_type n)
{
pa->deallocate((void *) p);
pa->deallocate((void*) p);
}
template<class T>
typename STLPoolAllocator<T>::size_type STLPoolAllocator<T>::max_size() const throw()
{
return std::numeric_limits<uint64_t>::max()/sizeof(T);
return std::numeric_limits<uint64_t>::max() / sizeof(T);
}
template<class T>
void STLPoolAllocator<T>::construct(typename STLPoolAllocator<T>::pointer p, const T& val)
{
new((void *)p) T(val);
new ((void*)p) T(val);
}
template<class T>
void STLPoolAllocator<T>::destroy(typename STLPoolAllocator<T>::pointer p)
{
p->T::~T();
p->T::~T();
}
template<class T>
STLPoolAllocator<T>& STLPoolAllocator<T>::operator=(const STLPoolAllocator<T> &c)
STLPoolAllocator<T>& STLPoolAllocator<T>::operator=(const STLPoolAllocator<T>& c)
{
pa = c.pa;
return *this;
pa = c.pa;
return *this;
}
template<typename T>
bool operator==(const STLPoolAllocator<T> &, const STLPoolAllocator<T> &)
bool operator==(const STLPoolAllocator<T>&, const STLPoolAllocator<T>&)
{
return true;
return true;
}
template<typename T>
bool operator!=(const STLPoolAllocator<T> &, const STLPoolAllocator<T> &)
bool operator!=(const STLPoolAllocator<T>&, const STLPoolAllocator<T>&)
{
return false;
return false;
}
}

View File

@ -71,70 +71,79 @@ namespace syncstream
class syncbuf : public std::streambuf
{
public:
/** ctor */
syncbuf(FILE* f) : std::streambuf(), fptr(f) {}
/** ctor */
syncbuf(FILE* f) : std::streambuf(), fptr(f) {}
protected:
/** Write character in the case of overflow */
virtual int overflow(int c = EOF) {
return (c != EOF ? fputc(c, fptr) : EOF);
}
/** Get character in the case of overflow */
virtual int underflow() {
int c = getc(fptr);
if (c != EOF)
ungetc(c, fptr);
return c;
}
/** Get character in the case of overflow and advance get pointer */
virtual int uflow() {
return getc(fptr);
}
/** put character back in the case of backup underflow */
virtual int pbackfail(int c = EOF) {
return (c != EOF ? ungetc(c, fptr) : EOF);
}
/** Synchronize stream buffer */
virtual int sync() {
return fflush(fptr);
}
/** Write character in the case of overflow */
virtual int overflow(int c = EOF)
{
return (c != EOF ? fputc(c, fptr) : EOF);
}
/** Get character in the case of overflow */
virtual int underflow()
{
int c = getc(fptr);
if (c != EOF)
ungetc(c, fptr);
return c;
}
/** Get character in the case of overflow and advance get pointer */
virtual int uflow()
{
return getc(fptr);
}
/** put character back in the case of backup underflow */
virtual int pbackfail(int c = EOF)
{
return (c != EOF ? ungetc(c, fptr) : EOF);
}
/** Synchronize stream buffer */
virtual int sync()
{
return fflush(fptr);
}
private:
FILE* fptr;
FILE* fptr;
};
/** An istream adaptor for input FILE* streams */
class isyncstream : public std::istream
{
public:
/** ctor */
isyncstream() : istream(&buf), buf(0) {}
/** ctor */
isyncstream(FILE* fptr) : istream(&buf), buf(fptr) {}
/** const streambuf accessor */
const syncbuf* rdbuf() const {
return &buf;
}
/** ctor */
isyncstream() : istream(&buf), buf(0) {}
/** ctor */
isyncstream(FILE* fptr) : istream(&buf), buf(fptr) {}
/** const streambuf accessor */
const syncbuf* rdbuf() const
{
return &buf;
}
private:
syncbuf buf;
syncbuf buf;
};
/** An ostream adaptor for output FILE* streams */
class osyncstream : public std::ostream
{
public:
/** ctor */
osyncstream() : ostream(&buf), buf(0) {}
/** ctor */
osyncstream(FILE* fptr) : ostream(&buf), buf(fptr) {}
/** const streambuf accessor */
const syncbuf* rdbuf() const {
return &buf;
}
/** ctor */
osyncstream() : ostream(&buf), buf(0) {}
/** ctor */
osyncstream(FILE* fptr) : ostream(&buf), buf(fptr) {}
/** const streambuf accessor */
const syncbuf* rdbuf() const
{
return &buf;
}
private:
syncbuf buf;
syncbuf buf;
};
}

View File

@ -65,39 +65,39 @@ const uint8_t CHUNK_MAGIC3 = 0xfd;
struct CompressedDBFileHeader
{
uint64_t fMagicNumber;
uint64_t fVersionNum;
uint64_t fCompressionType;
uint64_t fHeaderSize;
uint64_t fBlockCount;
uint64_t fMagicNumber;
uint64_t fVersionNum;
uint64_t fCompressionType;
uint64_t fHeaderSize;
uint64_t fBlockCount;
};
// Make the header to be 4K, regardless number of fields being defined/used in header.
union CompressedDBFileHeaderBlock
{
CompressedDBFileHeader fHeader;
char fDummy[compress::IDBCompressInterface::HDR_BUF_LEN];
CompressedDBFileHeader fHeader;
char fDummy[compress::IDBCompressInterface::HDR_BUF_LEN];
};
void initCompressedDBFileHeader(void* hdrBuf, int compressionType, int hdrSize)
{
CompressedDBFileHeaderBlock* hdr = reinterpret_cast<CompressedDBFileHeaderBlock*>(hdrBuf);
hdr->fHeader.fMagicNumber = MAGIC_NUMBER;
hdr->fHeader.fVersionNum = VERSION_NUM2;
hdr->fHeader.fCompressionType = compressionType;
hdr->fHeader.fBlockCount = 0;
hdr->fHeader.fHeaderSize = hdrSize;
CompressedDBFileHeaderBlock* hdr = reinterpret_cast<CompressedDBFileHeaderBlock*>(hdrBuf);
hdr->fHeader.fMagicNumber = MAGIC_NUMBER;
hdr->fHeader.fVersionNum = VERSION_NUM2;
hdr->fHeader.fCompressionType = compressionType;
hdr->fHeader.fBlockCount = 0;
hdr->fHeader.fHeaderSize = hdrSize;
}
void log(const string &s)
void log(const string& s)
{
logging::MessageLog logger((logging::LoggingID()));
logging::Message message;
logging::Message::Args args;
logging::MessageLog logger((logging::LoggingID()));
logging::Message message;
logging::Message::Args args;
args.add(s);
message.format(args);
logger.logErrorMessage(message);
args.add(s);
message.format(args);
logger.logErrorMessage(message);
}
} // namespace
@ -108,7 +108,7 @@ namespace compress
#ifndef SKIP_IDB_COMPRESSION
IDBCompressInterface::IDBCompressInterface(unsigned int numUserPaddingBytes) :
fNumUserPaddingBytes(numUserPaddingBytes)
fNumUserPaddingBytes(numUserPaddingBytes)
{ }
IDBCompressInterface::~IDBCompressInterface()
@ -120,144 +120,169 @@ IDBCompressInterface::~IDBCompressInterface()
*/
bool IDBCompressInterface::isCompressionAvail(int compressionType) const
{
if ( (compressionType == 0) ||
(compressionType == 1) ||
(compressionType == 2) )
return true;
return false;
if ( (compressionType == 0) ||
(compressionType == 1) ||
(compressionType == 2) )
return true;
return false;
}
//------------------------------------------------------------------------------
// Compress a block of data
//------------------------------------------------------------------------------
int IDBCompressInterface::compressBlock(const char* in,
const size_t inLen,
unsigned char* out,
unsigned int& outLen) const
const size_t inLen,
unsigned char* out,
unsigned int& outLen) const
{
size_t snaplen = 0;
utils::Hasher128 hasher;
size_t snaplen = 0;
utils::Hasher128 hasher;
// loose input checking.
if (outLen < snappy::MaxCompressedLength(inLen) + HEADER_SIZE)
{
cerr << "got outLen = " << outLen << " for inLen = " << inLen << ", needed " <<
(snappy::MaxCompressedLength(inLen) + HEADER_SIZE) << endl;
return ERR_BADOUTSIZE;
}
// loose input checking.
if (outLen < snappy::MaxCompressedLength(inLen) + HEADER_SIZE)
{
cerr << "got outLen = " << outLen << " for inLen = " << inLen << ", needed " <<
(snappy::MaxCompressedLength(inLen) + HEADER_SIZE) << endl;
return ERR_BADOUTSIZE;
}
//apparently this never fails?
snappy::RawCompress(in, inLen, reinterpret_cast<char*>(&out[HEADER_SIZE]), &snaplen);
//apparently this never fails?
snappy::RawCompress(in, inLen, reinterpret_cast<char*>(&out[HEADER_SIZE]), &snaplen);
uint8_t *signature = (uint8_t *) &out[SIG_OFFSET];
uint32_t *checksum = (uint32_t *) &out[CHECKSUM_OFFSET];
uint32_t *len = (uint32_t *) &out[LEN_OFFSET];
*signature = CHUNK_MAGIC3;
*checksum = hasher((char *) &out[HEADER_SIZE], snaplen);
*len = snaplen;
uint8_t* signature = (uint8_t*) &out[SIG_OFFSET];
uint32_t* checksum = (uint32_t*) &out[CHECKSUM_OFFSET];
uint32_t* len = (uint32_t*) &out[LEN_OFFSET];
*signature = CHUNK_MAGIC3;
*checksum = hasher((char*) &out[HEADER_SIZE], snaplen);
*len = snaplen;
//cerr << "cb: " << inLen << '/' << outLen << '/' << (snappy::MaxCompressedLength(inLen) + HEADER_SIZE) <<
// " : " << (snaplen + HEADER_SIZE) << endl;
//cerr << "cb: " << inLen << '/' << outLen << '/' << (snappy::MaxCompressedLength(inLen) + HEADER_SIZE) <<
// " : " << (snaplen + HEADER_SIZE) << endl;
outLen = snaplen + HEADER_SIZE;
outLen = snaplen + HEADER_SIZE;
return ERR_OK;
return ERR_OK;
}
//------------------------------------------------------------------------------
// Decompress a block of data
//------------------------------------------------------------------------------
int IDBCompressInterface::uncompressBlock(const char* in, const size_t inLen, unsigned char* out,
unsigned int& outLen) const
unsigned int& outLen) const
{
bool comprc = false;
size_t ol = 0;
bool comprc = false;
size_t ol = 0;
uint32_t realChecksum;
uint32_t storedChecksum;
uint32_t storedLen;
uint8_t storedMagic;
utils::Hasher128 hasher;
uint32_t realChecksum;
uint32_t storedChecksum;
uint32_t storedLen;
uint8_t storedMagic;
utils::Hasher128 hasher;
outLen = 0;
if (inLen < 1) {
return ERR_BADINPUT;
}
storedMagic = *((uint8_t *) &in[SIG_OFFSET]);
outLen = 0;
if (storedMagic == CHUNK_MAGIC3)
{
if (inLen < HEADER_SIZE) {
return ERR_BADINPUT;
}
storedChecksum = *((uint32_t *) &in[CHECKSUM_OFFSET]);
storedLen = *((uint32_t *) (&in[LEN_OFFSET]));
if (inLen < storedLen + HEADER_SIZE) {
return ERR_BADINPUT;
}
if (inLen < 1)
{
return ERR_BADINPUT;
}
realChecksum = hasher(&in[HEADER_SIZE], storedLen);
if (storedChecksum != realChecksum) {
return ERR_CHECKSUM;
}
storedMagic = *((uint8_t*) &in[SIG_OFFSET]);
comprc = snappy::GetUncompressedLength(&in[HEADER_SIZE], storedLen, &ol) &&
snappy::RawUncompress(&in[HEADER_SIZE], storedLen, reinterpret_cast<char*>(out));
}
else if (storedMagic == CHUNK_MAGIC1 || storedMagic == CHUNK_MAGIC2)
{
if (inLen < HEADER_SIZE) {
return ERR_BADINPUT;
}
storedChecksum = *((uint32_t *) &in[CHECKSUM_OFFSET]);
storedLen = *((uint32_t *) (&in[LEN_OFFSET]));
if (inLen < storedLen + HEADER_SIZE) {
return ERR_BADINPUT;
}
/* We can no longer verify the checksum on ver 1.1 */
if (storedMagic == CHUNK_MAGIC2) {
realChecksum = hasher(&in[HEADER_SIZE], storedLen);
if (storedChecksum != realChecksum) {
return ERR_CHECKSUM;
}
}
if (storedMagic == CHUNK_MAGIC3)
{
if (inLen < HEADER_SIZE)
{
return ERR_BADINPUT;
}
try {
comprc = v1::decompress(&in[HEADER_SIZE], storedLen, out, &ol);
} catch (runtime_error& rex) {
//cerr << "decomp caught exception: " << rex.what() << endl;
ostringstream os;
os << "decomp caught exception: " << rex.what();
log(os.str());
comprc = false;
} catch (exception& ex) {
ostringstream os;
os << "decomp caught exception: " << ex.what();
log(os.str());
comprc = false;
} catch (...) {
comprc = false;
}
}
else if ((storedMagic & 0x80) != 0)
{
return ERR_BADINPUT;
}
else
{
comprc = v1::decompress(in, inLen, out, &ol);
}
storedChecksum = *((uint32_t*) &in[CHECKSUM_OFFSET]);
storedLen = *((uint32_t*) (&in[LEN_OFFSET]));
if (!comprc)
{
cerr << "decomp failed!" << endl;
return ERR_DECOMPRESS;
}
if (inLen < storedLen + HEADER_SIZE)
{
return ERR_BADINPUT;
}
outLen = ol;
//cerr << "ub: " << inLen << " : " << outLen << endl;
realChecksum = hasher(&in[HEADER_SIZE], storedLen);
return ERR_OK;
if (storedChecksum != realChecksum)
{
return ERR_CHECKSUM;
}
comprc = snappy::GetUncompressedLength(&in[HEADER_SIZE], storedLen, &ol) &&
snappy::RawUncompress(&in[HEADER_SIZE], storedLen, reinterpret_cast<char*>(out));
}
else if (storedMagic == CHUNK_MAGIC1 || storedMagic == CHUNK_MAGIC2)
{
if (inLen < HEADER_SIZE)
{
return ERR_BADINPUT;
}
storedChecksum = *((uint32_t*) &in[CHECKSUM_OFFSET]);
storedLen = *((uint32_t*) (&in[LEN_OFFSET]));
if (inLen < storedLen + HEADER_SIZE)
{
return ERR_BADINPUT;
}
/* We can no longer verify the checksum on ver 1.1 */
if (storedMagic == CHUNK_MAGIC2)
{
realChecksum = hasher(&in[HEADER_SIZE], storedLen);
if (storedChecksum != realChecksum)
{
return ERR_CHECKSUM;
}
}
try
{
comprc = v1::decompress(&in[HEADER_SIZE], storedLen, out, &ol);
}
catch (runtime_error& rex)
{
//cerr << "decomp caught exception: " << rex.what() << endl;
ostringstream os;
os << "decomp caught exception: " << rex.what();
log(os.str());
comprc = false;
}
catch (exception& ex)
{
ostringstream os;
os << "decomp caught exception: " << ex.what();
log(os.str());
comprc = false;
}
catch (...)
{
comprc = false;
}
}
else if ((storedMagic & 0x80) != 0)
{
return ERR_BADINPUT;
}
else
{
comprc = v1::decompress(in, inLen, out, &ol);
}
if (!comprc)
{
cerr << "decomp failed!" << endl;
return ERR_DECOMPRESS;
}
outLen = ol;
//cerr << "ub: " << inLen << " : " << outLen << endl;
return ERR_OK;
}
//------------------------------------------------------------------------------
@ -265,13 +290,15 @@ int IDBCompressInterface::uncompressBlock(const char* in, const size_t inLen, un
//------------------------------------------------------------------------------
int IDBCompressInterface::verifyHdr(const void* hdrBuf) const
{
const CompressedDBFileHeader* hdr = reinterpret_cast<const CompressedDBFileHeader*>(hdrBuf);
if (hdr->fMagicNumber != MAGIC_NUMBER)
return -1;
if (!isCompressionAvail(hdr->fCompressionType))
return -2;
const CompressedDBFileHeader* hdr = reinterpret_cast<const CompressedDBFileHeader*>(hdrBuf);
return 0;
if (hdr->fMagicNumber != MAGIC_NUMBER)
return -1;
if (!isCompressionAvail(hdr->fCompressionType))
return -2;
return 0;
}
//------------------------------------------------------------------------------
@ -279,26 +306,27 @@ int IDBCompressInterface::verifyHdr(const void* hdrBuf) const
// passed in. ptrBuf points to the pointer section of the compression hdr.
//------------------------------------------------------------------------------
int IDBCompressInterface::getPtrList(const char* ptrBuf,
const int ptrBufSize,
CompChunkPtrList& chunkPtrs ) const
const int ptrBufSize,
CompChunkPtrList& chunkPtrs ) const
{
int rc = 0;
chunkPtrs.clear();
int rc = 0;
chunkPtrs.clear();
const uint64_t* ptrs = reinterpret_cast<const uint64_t*>(ptrBuf);
const unsigned int NUM_PTRS = ptrBufSize / sizeof(uint64_t);
for (unsigned int i = 0; (i < NUM_PTRS) && (rc == 0); i++)
{
if (ptrs[i+1] == 0) // 0 offset means end of data
break;
const uint64_t* ptrs = reinterpret_cast<const uint64_t*>(ptrBuf);
const unsigned int NUM_PTRS = ptrBufSize / sizeof(uint64_t);
if (ptrs[i+1] > ptrs[i])
chunkPtrs.push_back(make_pair( ptrs[i], (ptrs[i+1]-ptrs[i])));
else
rc = -1;
}
for (unsigned int i = 0; (i < NUM_PTRS) && (rc == 0); i++)
{
if (ptrs[i + 1] == 0) // 0 offset means end of data
break;
return rc;
if (ptrs[i + 1] > ptrs[i])
chunkPtrs.push_back(make_pair( ptrs[i], (ptrs[i + 1] - ptrs[i])));
else
rc = -1;
}
return rc;
}
//------------------------------------------------------------------------------
@ -309,28 +337,29 @@ int IDBCompressInterface::getPtrList(const char* ptrBuf,
//------------------------------------------------------------------------------
int IDBCompressInterface::getPtrList(const char* hdrBuf, CompChunkPtrList& chunkPtrs ) const
{
return getPtrList(hdrBuf+HDR_BUF_LEN, HDR_BUF_LEN, chunkPtrs);
return getPtrList(hdrBuf + HDR_BUF_LEN, HDR_BUF_LEN, chunkPtrs);
}
//------------------------------------------------------------------------------
// Count the number of chunk pointers in the pointer header(s)
//------------------------------------------------------------------------------
unsigned int IDBCompressInterface::getPtrCount(const char* ptrBuf,
const int ptrBufSize) const
const int ptrBufSize) const
{
unsigned int chunkCount = 0;
unsigned int chunkCount = 0;
const uint64_t* ptrs = reinterpret_cast<const uint64_t*>(ptrBuf);
const unsigned int NUM_PTRS = ptrBufSize / sizeof(uint64_t);
for (unsigned int i = 0; i < NUM_PTRS; i++)
{
if (ptrs[i+1] == 0) // 0 offset means end of data
break;
const uint64_t* ptrs = reinterpret_cast<const uint64_t*>(ptrBuf);
const unsigned int NUM_PTRS = ptrBufSize / sizeof(uint64_t);
chunkCount++;
}
for (unsigned int i = 0; i < NUM_PTRS; i++)
{
if (ptrs[i + 1] == 0) // 0 offset means end of data
break;
return chunkCount;
chunkCount++;
}
return chunkCount;
}
//------------------------------------------------------------------------------
@ -341,23 +370,23 @@ unsigned int IDBCompressInterface::getPtrCount(const char* ptrBuf,
//------------------------------------------------------------------------------
unsigned int IDBCompressInterface::getPtrCount(const char* hdrBuf) const
{
return getPtrCount(hdrBuf+HDR_BUF_LEN, HDR_BUF_LEN);
return getPtrCount(hdrBuf + HDR_BUF_LEN, HDR_BUF_LEN);
}
//------------------------------------------------------------------------------
// Store list of compression pointers into the specified header.
//------------------------------------------------------------------------------
void IDBCompressInterface::storePtrs(const std::vector<uint64_t>& ptrs,
void* ptrBuf,
int ptrSectionSize) const
void* ptrBuf,
int ptrSectionSize) const
{
memset((ptrBuf), 0, ptrSectionSize); // reset the pointer section to 0
uint64_t* hdrPtrs = reinterpret_cast<uint64_t*>(ptrBuf);
memset((ptrBuf), 0, ptrSectionSize); // reset the pointer section to 0
uint64_t* hdrPtrs = reinterpret_cast<uint64_t*>(ptrBuf);
for (unsigned i=0; i<ptrs.size(); i++)
{
hdrPtrs[i] = ptrs[i];
}
for (unsigned i = 0; i < ptrs.size(); i++)
{
hdrPtrs[i] = ptrs[i];
}
}
//------------------------------------------------------------------------------
@ -365,7 +394,7 @@ void IDBCompressInterface::storePtrs(const std::vector<uint64_t>& ptrs,
//------------------------------------------------------------------------------
void IDBCompressInterface::storePtrs(const std::vector<uint64_t>& ptrs, void* ptrBuf) const
{
storePtrs(ptrs, reinterpret_cast<char*>(ptrBuf) + HDR_BUF_LEN, HDR_BUF_LEN);
storePtrs(ptrs, reinterpret_cast<char*>(ptrBuf) + HDR_BUF_LEN, HDR_BUF_LEN);
}
//------------------------------------------------------------------------------
@ -373,16 +402,16 @@ void IDBCompressInterface::storePtrs(const std::vector<uint64_t>& ptrs, void* pt
//------------------------------------------------------------------------------
void IDBCompressInterface::initHdr(void* hdrBuf, int compressionType) const
{
memset(hdrBuf, 0, HDR_BUF_LEN*2);
initCompressedDBFileHeader(hdrBuf, compressionType, HDR_BUF_LEN*2);
memset(hdrBuf, 0, HDR_BUF_LEN * 2);
initCompressedDBFileHeader(hdrBuf, compressionType, HDR_BUF_LEN * 2);
}
//------------------------------------------------------------------------------
// Initialize the header blocks to be written at the start of a dictionary file.
//------------------------------------------------------------------------------
void IDBCompressInterface::initHdr(void* hdrBuf,void* ptrBuf,int compressionType,int hdrSize) const
void IDBCompressInterface::initHdr(void* hdrBuf, void* ptrBuf, int compressionType, int hdrSize) const
{
memset(hdrBuf, 0, HDR_BUF_LEN);
memset(hdrBuf, 0, HDR_BUF_LEN);
memset(ptrBuf, 0, hdrSize - HDR_BUF_LEN);
initCompressedDBFileHeader(hdrBuf, compressionType, hdrSize);
}
@ -392,7 +421,7 @@ void IDBCompressInterface::initHdr(void* hdrBuf,void* ptrBuf,int compressionType
//------------------------------------------------------------------------------
void IDBCompressInterface::setBlockCount(void* hdrBuf, uint64_t count) const
{
reinterpret_cast<CompressedDBFileHeader*>(hdrBuf)->fBlockCount = count;
reinterpret_cast<CompressedDBFileHeader*>(hdrBuf)->fBlockCount = count;
}
//------------------------------------------------------------------------------
@ -400,7 +429,7 @@ void IDBCompressInterface::setBlockCount(void* hdrBuf, uint64_t count) const
//------------------------------------------------------------------------------
uint64_t IDBCompressInterface::getBlockCount(const void* hdrBuf) const
{
return (reinterpret_cast<const CompressedDBFileHeader*>(hdrBuf)->fBlockCount);
return (reinterpret_cast<const CompressedDBFileHeader*>(hdrBuf)->fBlockCount);
}
//------------------------------------------------------------------------------
@ -408,7 +437,7 @@ uint64_t IDBCompressInterface::getBlockCount(const void* hdrBuf) const
//------------------------------------------------------------------------------
void IDBCompressInterface::setHdrSize(void* hdrBuf, uint64_t size) const
{
reinterpret_cast<CompressedDBFileHeader*>(hdrBuf)->fHeaderSize = size;
reinterpret_cast<CompressedDBFileHeader*>(hdrBuf)->fHeaderSize = size;
}
//------------------------------------------------------------------------------
@ -416,7 +445,7 @@ void IDBCompressInterface::setHdrSize(void* hdrBuf, uint64_t size) const
//------------------------------------------------------------------------------
uint64_t IDBCompressInterface::getHdrSize(const void* hdrBuf) const
{
return (reinterpret_cast<const CompressedDBFileHeader*>(hdrBuf)->fHeaderSize);
return (reinterpret_cast<const CompressedDBFileHeader*>(hdrBuf)->fHeaderSize);
}
//------------------------------------------------------------------------------
@ -424,17 +453,17 @@ uint64_t IDBCompressInterface::getHdrSize(const void* hdrBuf) const
// block number.
//------------------------------------------------------------------------------
void IDBCompressInterface::locateBlock(unsigned int block,
unsigned int& chunkIndex,
unsigned int& blockOffsetWithinChunk) const
unsigned int& chunkIndex,
unsigned int& blockOffsetWithinChunk) const
{
const uint64_t BUFLEN = UNCOMPRESSED_INBUF_LEN;
const uint64_t BUFLEN = UNCOMPRESSED_INBUF_LEN;
uint64_t byteOffset = (uint64_t)block * BLOCK_SIZE;
uint64_t chunk = byteOffset / BUFLEN;
uint64_t blockInChunk = (byteOffset % BUFLEN) / BLOCK_SIZE;
uint64_t byteOffset = (uint64_t)block * BLOCK_SIZE;
uint64_t chunk = byteOffset / BUFLEN;
uint64_t blockInChunk = (byteOffset % BUFLEN) / BLOCK_SIZE;
chunkIndex = chunk;
blockOffsetWithinChunk = blockInChunk;
chunkIndex = chunk;
blockOffsetWithinChunk = blockInChunk;
}
//------------------------------------------------------------------------------
@ -443,52 +472,53 @@ void IDBCompressInterface::locateBlock(unsigned int block,
// bytes to 0.
//------------------------------------------------------------------------------
int IDBCompressInterface::padCompressedChunks(unsigned char* buf,
unsigned int& len,
unsigned int maxLen) const
unsigned int& len,
unsigned int maxLen) const
{
int nPaddingBytes = 0;
int nRem = len % COMPRESSED_CHUNK_INCREMENT_SIZE;
if (nRem != 0)
{
nPaddingBytes = COMPRESSED_CHUNK_INCREMENT_SIZE - nRem;
}
int nPaddingBytes = 0;
int nRem = len % COMPRESSED_CHUNK_INCREMENT_SIZE;
nPaddingBytes = nPaddingBytes + fNumUserPaddingBytes;
if (nRem != 0)
{
nPaddingBytes = COMPRESSED_CHUNK_INCREMENT_SIZE - nRem;
}
if (nPaddingBytes > 0)
{
if ((len + nPaddingBytes) > maxLen)
return -1;
nPaddingBytes = nPaddingBytes + fNumUserPaddingBytes;
memset(buf+len, 0, nPaddingBytes);
len = len + nPaddingBytes;
}
if (nPaddingBytes > 0)
{
if ((len + nPaddingBytes) > maxLen)
return -1;
return 0;
memset(buf + len, 0, nPaddingBytes);
len = len + nPaddingBytes;
}
return 0;
}
/* static */
uint64_t IDBCompressInterface::maxCompressedSize(uint64_t uncompSize)
{
return (snappy::MaxCompressedLength(uncompSize) + HEADER_SIZE);
return (snappy::MaxCompressedLength(uncompSize) + HEADER_SIZE);
}
int IDBCompressInterface::compress(const char *in, size_t inLen, char *out,
size_t *outLen) const
int IDBCompressInterface::compress(const char* in, size_t inLen, char* out,
size_t* outLen) const
{
snappy::RawCompress(in, inLen, out, outLen);
return 0;
snappy::RawCompress(in, inLen, out, outLen);
return 0;
}
int IDBCompressInterface::uncompress(const char *in, size_t inLen, char *out) const
int IDBCompressInterface::uncompress(const char* in, size_t inLen, char* out) const
{
return !(snappy::RawUncompress(in, inLen, out));
return !(snappy::RawUncompress(in, inLen, out));
}
/* static */
bool IDBCompressInterface::getUncompressedSize(char *in, size_t inLen, size_t *outLen)
bool IDBCompressInterface::getUncompressedSize(char* in, size_t inLen, size_t* outLen)
{
return snappy::GetUncompressedLength(in, inLen, outLen);
return snappy::GetUncompressedLength(in, inLen, outLen);
}
#endif

View File

@ -36,242 +36,293 @@
namespace compress
{
typedef std::pair<uint64_t,uint64_t> CompChunkPtr;
typedef std::pair<uint64_t, uint64_t> CompChunkPtr;
typedef std::vector<CompChunkPtr> CompChunkPtrList;
class IDBCompressInterface
{
public:
static const unsigned int HDR_BUF_LEN = 4096;
static const unsigned int UNCOMPRESSED_INBUF_LEN = 512 * 1024 * 8;
static const unsigned int HDR_BUF_LEN = 4096;
static const unsigned int UNCOMPRESSED_INBUF_LEN = 512 * 1024 * 8;
// error codes from uncompressBlock()
static const int ERR_OK = 0;
static const int ERR_CHECKSUM = -1;
static const int ERR_DECOMPRESS = -2;
static const int ERR_BADINPUT = -3;
static const int ERR_BADOUTSIZE = -4;
// error codes from uncompressBlock()
static const int ERR_OK = 0;
static const int ERR_CHECKSUM = -1;
static const int ERR_DECOMPRESS = -2;
static const int ERR_BADINPUT = -3;
static const int ERR_BADOUTSIZE = -4;
/**
* When IDBCompressInterface object is being used to compress a chunk, this
* construct can be used to specify the padding added by padCompressedChunks
*/
EXPORT explicit IDBCompressInterface(unsigned int numUserPaddingBytes=0);
/**
* When IDBCompressInterface object is being used to compress a chunk, this
* construct can be used to specify the padding added by padCompressedChunks
*/
EXPORT explicit IDBCompressInterface(unsigned int numUserPaddingBytes = 0);
/**
* dtor
*/
EXPORT virtual ~IDBCompressInterface();
/**
* dtor
*/
EXPORT virtual ~IDBCompressInterface();
/**
* see if the algo is available in this lib
*/
EXPORT bool isCompressionAvail(int compressionType = 0) const;
/**
* see if the algo is available in this lib
*/
EXPORT bool isCompressionAvail(int compressionType = 0) const;
/**
* Compresses specified "in" buffer of length "inLen" bytes.
* Compressed data and size are returned in "out" and "outLen".
* "out" should be sized using maxCompressedSize() to allow for incompressible data.
* Returns 0 if success.
*/
EXPORT int compressBlock(const char* in,
const size_t inLen,
unsigned char* out,
unsigned int& outLen) const;
/**
* Compresses specified "in" buffer of length "inLen" bytes.
* Compressed data and size are returned in "out" and "outLen".
* "out" should be sized using maxCompressedSize() to allow for incompressible data.
* Returns 0 if success.
*/
EXPORT int compressBlock(const char* in,
const size_t inLen,
unsigned char* out,
unsigned int& outLen) const;
/**
* outLen must be initialized with the size of the out buffer before calling uncompressBlock.
* On return, outLen will have the number of bytes used in out.
*/
EXPORT int uncompressBlock(const char* in, const size_t inLen, unsigned char* out,
unsigned int& outLen) const;
/**
* outLen must be initialized with the size of the out buffer before calling uncompressBlock.
* On return, outLen will have the number of bytes used in out.
*/
EXPORT int uncompressBlock(const char* in, const size_t inLen, unsigned char* out,
unsigned int& outLen) const;
/**
* This fcn wraps whatever compression algorithm we're using at the time, and
* is not specific to blocks on disk.
*/
EXPORT int compress(const char *in, size_t inLen, char *out, size_t *outLen) const;
/**
* This fcn wraps whatever compression algorithm we're using at the time, and
* is not specific to blocks on disk.
*/
EXPORT int compress(const char* in, size_t inLen, char* out, size_t* outLen) const;
/**
* This fcn wraps whatever compression algorithm we're using at the time, and
* is not specific to blocks on disk. The caller needs to make sure out is big
* enough to contain the output by using getUncompressedSize().
*/
EXPORT int uncompress(const char *in, size_t inLen, char *out) const;
/**
* This fcn wraps whatever compression algorithm we're using at the time, and
* is not specific to blocks on disk. The caller needs to make sure out is big
* enough to contain the output by using getUncompressedSize().
*/
EXPORT int uncompress(const char* in, size_t inLen, char* out) const;
/**
* Initialize header buffer at start of compressed db file.
*
* @warning hdrBuf must be at least HDR_BUF_LEN*2 bytes
*/
EXPORT void initHdr(void* hdrBuf, int compressionType) const;
/**
* Initialize header buffer at start of compressed db file.
*
* @warning hdrBuf must be at least HDR_BUF_LEN*2 bytes
*/
EXPORT void initHdr(void* hdrBuf, int compressionType) const;
/**
* Initialize header buffer at start of compressed db file.
*
* @warning hdrBuf must be at least HDR_BUF_LEN bytes
* @warning ptrBuf must be at least (hdrSize-HDR_BUF_LEN) bytes
*/
EXPORT void initHdr(void* hdrBuf, void* ptrBuf, int compressionType, int hdrSize) const;
/**
* Initialize header buffer at start of compressed db file.
*
* @warning hdrBuf must be at least HDR_BUF_LEN bytes
* @warning ptrBuf must be at least (hdrSize-HDR_BUF_LEN) bytes
*/
EXPORT void initHdr(void* hdrBuf, void* ptrBuf, int compressionType, int hdrSize) const;
/**
* Verify the passed in buffer contains a compressed db file header.
*/
EXPORT int verifyHdr(const void* hdrBuf) const;
/**
* Verify the passed in buffer contains a compressed db file header.
*/
EXPORT int verifyHdr(const void* hdrBuf) const;
/**
* Extracts list of compression pointers from the specified ptr buffer.
* ptrBuf points to the pointer section taken from the headers.
* chunkPtrs is a vector of offset, size pairs for the compressed chunks.
* Returns 0 if success.
*/
EXPORT int getPtrList(const char* ptrBuf,
const int ptrBufSize,
CompChunkPtrList& chunkPtrs) const;
/**
* Extracts list of compression pointers from the specified ptr buffer.
* ptrBuf points to the pointer section taken from the headers.
* chunkPtrs is a vector of offset, size pairs for the compressed chunks.
* Returns 0 if success.
*/
EXPORT int getPtrList(const char* ptrBuf,
const int ptrBufSize,
CompChunkPtrList& chunkPtrs) const;
/**
* Extracts list of compression pointers from the specified header.
* hdrBuf points to start of 2 buffer headers from compressed db file.
* Overloaded for backward compatibility. For none dictionary columns.
* Note: the pointer passed in is the beginning of the header,
* not the pointer section as above.
*/
EXPORT int getPtrList(const char* hdrBuf, CompChunkPtrList& chunkPtrs) const;
/**
* Extracts list of compression pointers from the specified header.
* hdrBuf points to start of 2 buffer headers from compressed db file.
* Overloaded for backward compatibility. For none dictionary columns.
* Note: the pointer passed in is the beginning of the header,
* not the pointer section as above.
*/
EXPORT int getPtrList(const char* hdrBuf, CompChunkPtrList& chunkPtrs) const;
/**
* Return the number of chunk pointers contained in the specified ptr buffer.
* ptrBuf points to the pointer section taken from the headers.
*/
EXPORT unsigned int getPtrCount(const char* ptrBuf,
const int ptrBufSize) const;
/**
* Return the number of chunk pointers contained in the specified ptr buffer.
* ptrBuf points to the pointer section taken from the headers.
*/
EXPORT unsigned int getPtrCount(const char* ptrBuf,
const int ptrBufSize) const;
/**
* Return the number of chunk pointers contained in the specified header.
* hdrBuf points to start of 2 buffer headers from compressed db file.
* For non-dictionary columns.
*/
EXPORT unsigned int getPtrCount(const char* hdrBuf) const;
/**
* Return the number of chunk pointers contained in the specified header.
* hdrBuf points to start of 2 buffer headers from compressed db file.
* For non-dictionary columns.
*/
EXPORT unsigned int getPtrCount(const char* hdrBuf) const;
/**
* Store vector of pointers into the specified buffer header's pointer section.
*/
EXPORT void storePtrs(const std::vector<uint64_t>& ptrs,
void* hdrBuf,
int ptrSectionSize) const;
/**
* Store vector of pointers into the specified buffer header's pointer section.
*/
EXPORT void storePtrs(const std::vector<uint64_t>& ptrs,
void* hdrBuf,
int ptrSectionSize) const;
/**
* Store vector of pointers into the specified buffer header.
* Overloaded for backward compatibility. For none dictionary columns.
* Note: the pointer passed in is the beginning of the header,
* not the pointer section as above.
*/
EXPORT void storePtrs(const std::vector<uint64_t>& ptrs, void* hdrBuf) const;
/**
* Store vector of pointers into the specified buffer header.
* Overloaded for backward compatibility. For none dictionary columns.
* Note: the pointer passed in is the beginning of the header,
* not the pointer section as above.
*/
EXPORT void storePtrs(const std::vector<uint64_t>& ptrs, void* hdrBuf) const;
/**
* Calculates the chunk, and the block offset within the chunk, for the
* specified block number.
*/
EXPORT void locateBlock(unsigned int block,
unsigned int& chunkIndex,
unsigned int& blockOffsetWithinChunk) const;
/**
* Calculates the chunk, and the block offset within the chunk, for the
* specified block number.
*/
EXPORT void locateBlock(unsigned int block,
unsigned int& chunkIndex,
unsigned int& blockOffsetWithinChunk) const;
/**
* Pads the specified compressed chunk to the nearest compressed chunk
* increment, by padding buf with 0's, and updating len accordingly.
* maxLen is the maximum size for buf. nonzero return code means the
* result output buffer length is > than maxLen.
*/
EXPORT int padCompressedChunks(unsigned char* buf,
unsigned int& len,
unsigned int maxLen ) const;
/**
* Pads the specified compressed chunk to the nearest compressed chunk
* increment, by padding buf with 0's, and updating len accordingly.
* maxLen is the maximum size for buf. nonzero return code means the
* result output buffer length is > than maxLen.
*/
EXPORT int padCompressedChunks(unsigned char* buf,
unsigned int& len,
unsigned int maxLen ) const;
/*
* Mutator methods for the block count in the file
*/
/**
* setBlockCount
*/
EXPORT void setBlockCount(void* hdrBuf, uint64_t count) const;
/*
* Mutator methods for the block count in the file
*/
/**
* setBlockCount
*/
EXPORT void setBlockCount(void* hdrBuf, uint64_t count) const;
/**
* getBlockCount
*/
EXPORT uint64_t getBlockCount(const void* hdrBuf) const;
/**
* getBlockCount
*/
EXPORT uint64_t getBlockCount(const void* hdrBuf) const;
/*
* Mutator methods for the overall header size
*/
/**
* setHdrSize
*/
EXPORT void setHdrSize(void* hdrBuf, uint64_t size) const;
/*
* Mutator methods for the overall header size
*/
/**
* setHdrSize
*/
EXPORT void setHdrSize(void* hdrBuf, uint64_t size) const;
/**
* getHdrSize
*/
EXPORT uint64_t getHdrSize(const void* hdrBuf) const;
/**
* getHdrSize
*/
EXPORT uint64_t getHdrSize(const void* hdrBuf) const;
/**
* Mutator methods for the user padding bytes
*/
/**
* set numUserPaddingBytes
*/
EXPORT void numUserPaddingBytes(uint64_t num) { fNumUserPaddingBytes = num; }
/**
* Mutator methods for the user padding bytes
*/
/**
* set numUserPaddingBytes
*/
EXPORT void numUserPaddingBytes(uint64_t num)
{
fNumUserPaddingBytes = num;
}
/**
* get numUserPaddingBytes
*/
EXPORT uint64_t numUserPaddingBytes() const { return fNumUserPaddingBytes; }
/**
* get numUserPaddingBytes
*/
EXPORT uint64_t numUserPaddingBytes() const
{
return fNumUserPaddingBytes;
}
/**
* Given an input, uncompressed block, what's the maximum possible output,
* compressed size?
*/
EXPORT static uint64_t maxCompressedSize(uint64_t uncompSize);
/**
* Given an input, uncompressed block, what's the maximum possible output,
* compressed size?
*/
EXPORT static uint64_t maxCompressedSize(uint64_t uncompSize);
/**
* Given a compressed block, returns the uncompressed size in outLen.
* Returns false on error, true on success.
*/
EXPORT static bool getUncompressedSize(char *in, size_t inLen, size_t *outLen);
/**
* Given a compressed block, returns the uncompressed size in outLen.
* Returns false on error, true on success.
*/
EXPORT static bool getUncompressedSize(char* in, size_t inLen, size_t* outLen);
protected:
private:
//defaults okay
//IDBCompressInterface(const IDBCompressInterface& rhs);
//IDBCompressInterface& operator=(const IDBCompressInterface& rhs);
//defaults okay
//IDBCompressInterface(const IDBCompressInterface& rhs);
//IDBCompressInterface& operator=(const IDBCompressInterface& rhs);
unsigned int fNumUserPaddingBytes; // Num bytes to pad compressed chunks
unsigned int fNumUserPaddingBytes; // Num bytes to pad compressed chunks
};
#ifdef SKIP_IDB_COMPRESSION
inline IDBCompressInterface::IDBCompressInterface(unsigned int /*numUserPaddingBytes*/) {}
inline IDBCompressInterface::~IDBCompressInterface() {}
inline bool IDBCompressInterface::isCompressionAvail(int c) const { return (c == 0); }
inline int IDBCompressInterface::compressBlock(const char*,const size_t,unsigned char*,unsigned int&) const { return -1; }
inline int IDBCompressInterface::uncompressBlock(const char* in, const size_t inLen, unsigned char* out, unsigned int& outLen) const { return -1; }
inline int IDBCompressInterface::compress(const char* in, size_t inLen, char* out, size_t* outLen) const { return -1; }
inline int IDBCompressInterface::uncompress(const char* in, size_t inLen, char* out) const { return 0; }
inline void IDBCompressInterface::initHdr(void*,int) const {}
inline void IDBCompressInterface::initHdr(void*, void*, int,int) const {}
inline int IDBCompressInterface::verifyHdr(const void*) const { return -1; }
inline int IDBCompressInterface::getPtrList(const char*, const int, CompChunkPtrList&) const { return -1; }
inline int IDBCompressInterface::getPtrList(const char*, CompChunkPtrList&) const { return -1; }
inline unsigned int IDBCompressInterface::getPtrCount(const char*, const int) const { return 0; }
inline unsigned int IDBCompressInterface::getPtrCount(const char*) const { return 0; }
inline void IDBCompressInterface::storePtrs(const std::vector<uint64_t>&,void*,int) const {}
inline bool IDBCompressInterface::isCompressionAvail(int c) const
{
return (c == 0);
}
inline int IDBCompressInterface::compressBlock(const char*, const size_t, unsigned char*, unsigned int&) const
{
return -1;
}
inline int IDBCompressInterface::uncompressBlock(const char* in, const size_t inLen, unsigned char* out, unsigned int& outLen) const
{
return -1;
}
inline int IDBCompressInterface::compress(const char* in, size_t inLen, char* out, size_t* outLen) const
{
return -1;
}
inline int IDBCompressInterface::uncompress(const char* in, size_t inLen, char* out) const
{
return 0;
}
inline void IDBCompressInterface::initHdr(void*, int) const {}
inline void IDBCompressInterface::initHdr(void*, void*, int, int) const {}
inline int IDBCompressInterface::verifyHdr(const void*) const
{
return -1;
}
inline int IDBCompressInterface::getPtrList(const char*, const int, CompChunkPtrList&) const
{
return -1;
}
inline int IDBCompressInterface::getPtrList(const char*, CompChunkPtrList&) const
{
return -1;
}
inline unsigned int IDBCompressInterface::getPtrCount(const char*, const int) const
{
return 0;
}
inline unsigned int IDBCompressInterface::getPtrCount(const char*) const
{
return 0;
}
inline void IDBCompressInterface::storePtrs(const std::vector<uint64_t>&, void*, int) const {}
inline void IDBCompressInterface::storePtrs(const std::vector<uint64_t>&, void*) const {}
inline void IDBCompressInterface::locateBlock(unsigned int block,
unsigned int& chunkIndex, unsigned int& blockOffsetWithinChunk) const {}
inline int IDBCompressInterface::padCompressedChunks(unsigned char* buf, unsigned int& len, unsigned int maxLen) const { return -1; }
unsigned int& chunkIndex, unsigned int& blockOffsetWithinChunk) const {}
inline int IDBCompressInterface::padCompressedChunks(unsigned char* buf, unsigned int& len, unsigned int maxLen) const
{
return -1;
}
inline void IDBCompressInterface::setBlockCount(void* hdrBuf, uint64_t count) const {}
inline uint64_t IDBCompressInterface::getBlockCount(const void* hdrBuf) const { return 0; }
inline uint64_t IDBCompressInterface::getBlockCount(const void* hdrBuf) const
{
return 0;
}
inline void IDBCompressInterface::setHdrSize(void*, uint64_t) const {}
inline uint64_t IDBCompressInterface::getHdrSize(const void*) const { return 0; }
inline uint64_t IDBCompressInterface::maxCompressedSize(uint64_t uncompSize) { return uncompSize; }
inline bool IDBCompressInterface::getUncompressedSize(char* in, size_t inLen, size_t* outLen) { return false; }
inline uint64_t IDBCompressInterface::getHdrSize(const void*) const
{
return 0;
}
inline uint64_t IDBCompressInterface::maxCompressedSize(uint64_t uncompSize)
{
return uncompSize;
}
inline bool IDBCompressInterface::getUncompressedSize(char* in, size_t inLen, size_t* outLen)
{
return false;
}
#endif
}

View File

@ -47,7 +47,7 @@ using namespace std;
#include <boost/interprocess/mapped_region.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
namespace bi=boost::interprocess;
namespace bi = boost::interprocess;
#include <boost/thread.hpp>
@ -90,62 +90,69 @@ namespace
{
short DSPort = 9199;
void log(const string &s)
void log(const string& s)
{
logging::MessageLog logger((logging::LoggingID()));
logging::Message message;
logging::Message::Args args;
logging::MessageLog logger((logging::LoggingID()));
logging::Message message;
logging::Message::Args args;
args.add(s);
message.format(args);
logger.logErrorMessage(message);
args.add(s);
message.format(args);
logger.logErrorMessage(message);
}
struct ScopedCleaner
{
#ifdef _MSC_VER
ScopedCleaner() : ctlsock(INVALID_SOCKET),
cpipeh(INVALID_HANDLE_VALUE),
upipeh(INVALID_HANDLE_VALUE)
{ }
ScopedCleaner() : ctlsock(INVALID_SOCKET),
cpipeh(INVALID_HANDLE_VALUE),
upipeh(INVALID_HANDLE_VALUE)
{ }
~ScopedCleaner()
{
if (cpipeh != INVALID_HANDLE_VALUE)
CloseHandle(cpipeh);
if (upipeh != INVALID_HANDLE_VALUE)
CloseHandle(upipeh);
if (ctlsock != INVALID_SOCKET) {
shutdown(ctlsock, SHUT_RDWR);
closesocket(ctlsock);
}
}
~ScopedCleaner()
{
if (cpipeh != INVALID_HANDLE_VALUE)
CloseHandle(cpipeh);
SOCKET ctlsock;
HANDLE cpipeh;
HANDLE upipeh;
if (upipeh != INVALID_HANDLE_VALUE)
CloseHandle(upipeh);
if (ctlsock != INVALID_SOCKET)
{
shutdown(ctlsock, SHUT_RDWR);
closesocket(ctlsock);
}
}
SOCKET ctlsock;
HANDLE cpipeh;
HANDLE upipeh;
#else
ScopedCleaner() : fd(-1), ctlsock(-1)
{ }
ScopedCleaner() : fd(-1), ctlsock(-1)
{ }
~ScopedCleaner()
{
if (fd >= 0)
close(fd);
if (!cpipename.empty())
unlink(cpipename.c_str());
if (!upipename.empty())
unlink(upipename.c_str());
if (ctlsock >= 0) {
shutdown(ctlsock, SHUT_RDWR);
close(ctlsock);
}
}
~ScopedCleaner()
{
if (fd >= 0)
close(fd);
int fd;
int ctlsock;
string cpipename;
string upipename;
if (!cpipename.empty())
unlink(cpipename.c_str());
if (!upipename.empty())
unlink(upipename.c_str());
if (ctlsock >= 0)
{
shutdown(ctlsock, SHUT_RDWR);
close(ctlsock);
}
}
int fd;
int ctlsock;
string cpipename;
string upipename;
#endif
};
@ -153,7 +160,7 @@ boost::mutex CtlShmMutex;
struct CtlShmImage
{
bi::interprocess_mutex controlFifoMutex;
bi::interprocess_mutex controlFifoMutex;
};
CtlShmImage* Ctlshmptr = 0;
bi::shared_memory_object Ctlshmobj;
@ -161,117 +168,129 @@ bi::mapped_region Ctlshmregion;
void initCtlShm()
{
BRM::ShmKeys shmKeys;
string DecomShmName(BRM::ShmKeys::keyToName(shmKeys.DECOMSVRMUTEX_SYSVKEY));
BRM::ShmKeys shmKeys;
string DecomShmName(BRM::ShmKeys::keyToName(shmKeys.DECOMSVRMUTEX_SYSVKEY));
boost::mutex::scoped_lock Ctlshmlk(CtlShmMutex);
if (Ctlshmptr)
return;
boost::mutex::scoped_lock Ctlshmlk(CtlShmMutex);
CtlShmImage* tmpptr = 0;
if (Ctlshmptr)
return;
try {
bi::shared_memory_object shm(bi::open_only, DecomShmName.c_str(), bi::read_write);
bi::mapped_region region(shm, bi::read_write);
tmpptr = reinterpret_cast<CtlShmImage*>(region.get_address());
Ctlshmobj.swap(shm);
Ctlshmregion.swap(region);
} catch (bi::interprocess_exception&) {
CtlShmImage* tmpptr = 0;
try
{
bi::shared_memory_object shm(bi::open_only, DecomShmName.c_str(), bi::read_write);
bi::mapped_region region(shm, bi::read_write);
tmpptr = reinterpret_cast<CtlShmImage*>(region.get_address());
Ctlshmobj.swap(shm);
Ctlshmregion.swap(region);
}
catch (bi::interprocess_exception&)
{
#if BOOST_VERSION < 104500
bi::shared_memory_object shm(bi::create_only, DecomShmName.c_str(), bi::read_write);
bi::shared_memory_object shm(bi::create_only, DecomShmName.c_str(), bi::read_write);
#else
bi::permissions perms;
perms.set_unrestricted();
bi::shared_memory_object shm(bi::create_only, DecomShmName.c_str(), bi::read_write, perms);
bi::permissions perms;
perms.set_unrestricted();
bi::shared_memory_object shm(bi::create_only, DecomShmName.c_str(), bi::read_write, perms);
#endif
shm.truncate(sizeof(CtlShmImage));
bi::mapped_region region(shm, bi::read_write);
tmpptr = new (region.get_address()) CtlShmImage;
Ctlshmobj.swap(shm);
Ctlshmregion.swap(region);
}
const string pname("DecomSvr");
string srvrpath(startup::StartUp::installDir());
srvrpath += "/bin/" + pname;
shm.truncate(sizeof(CtlShmImage));
bi::mapped_region region(shm, bi::read_write);
tmpptr = new (region.get_address()) CtlShmImage;
Ctlshmobj.swap(shm);
Ctlshmregion.swap(region);
}
const string pname("DecomSvr");
string srvrpath(startup::StartUp::installDir());
srvrpath += "/bin/" + pname;
#ifndef OAM_FORKS_DECOMSVR
#ifndef _MSC_VER
int rc;
int rc;
rc = fork();
idbassert_s(rc >= 0, "couldn't fork DecomSvr");
rc = fork();
idbassert_s(rc >= 0, "couldn't fork DecomSvr");
// if (rc < 0)
// throw runtime_error("couldn't fork DecomSvr");
// else if (rc == 0)
if (rc == 0)
{
for (int fd = 0; fd < sysconf(_SC_OPEN_MAX); fd++)
close(fd);
open("/dev/null", O_RDONLY);
open("/dev/null", O_WRONLY);
open("/dev/null", O_WRONLY);
execl(srvrpath.c_str(), pname.c_str(), (char*)NULL);
idbassert_s(0, "couldn't exec DecomSvr");
//throw runtime_error("couldn't exec DecomSvr");
}
if (rc == 0)
{
for (int fd = 0; fd < sysconf(_SC_OPEN_MAX); fd++)
close(fd);
open("/dev/null", O_RDONLY);
open("/dev/null", O_WRONLY);
open("/dev/null", O_WRONLY);
execl(srvrpath.c_str(), pname.c_str(), (char*)NULL);
idbassert_s(0, "couldn't exec DecomSvr");
//throw runtime_error("couldn't exec DecomSvr");
}
#else
srvrpath += ".exe";
PROCESS_INFORMATION pInfo;
ZeroMemory(&pInfo, sizeof(pInfo));
STARTUPINFO sInfo;
ZeroMemory(&sInfo, sizeof(sInfo));
srvrpath += ".exe";
PROCESS_INFORMATION pInfo;
ZeroMemory(&pInfo, sizeof(pInfo));
STARTUPINFO sInfo;
ZeroMemory(&sInfo, sizeof(sInfo));
idbassert_s(CreateProcess(0, (LPSTR)srvrpath.c_str(), 0, 0, false, DETACHED_PROCESS, 0, 0, &sInfo, &pInfo) != 0,
"couldn't exec DecomSvr");
//if (CreateProcess(0, (LPSTR)srvrpath.c_str(), 0, 0, false, 0, 0, 0, &sInfo, &pInfo) == 0)
// throw runtime_error("couldn't exec DecomSvr");
CloseHandle(pInfo.hProcess);
idbassert_s(CreateProcess(0, (LPSTR)srvrpath.c_str(), 0, 0, false, DETACHED_PROCESS, 0, 0, &sInfo, &pInfo) != 0,
"couldn't exec DecomSvr");
//if (CreateProcess(0, (LPSTR)srvrpath.c_str(), 0, 0, false, 0, 0, 0, &sInfo, &pInfo) == 0)
// throw runtime_error("couldn't exec DecomSvr");
CloseHandle(pInfo.hProcess);
sleep(5);
sleep(5);
#endif
#endif
char* p = getenv("IDB_DECOMSVR_PORT");
if (p && *p)
{
DSPort = atoi(p);
if (DSPort <= 0)
DSPort = 9199;
}
char* p = getenv("IDB_DECOMSVR_PORT");
Ctlshmptr = tmpptr;
if (p && *p)
{
DSPort = atoi(p);
if (DSPort <= 0)
DSPort = 9199;
}
Ctlshmptr = tmpptr;
}
void sendn(int fd, const char* p, size_t wanted)
{
size_t needed = wanted;
size_t sofar = 0;
ssize_t rrc = -1;
pollfd fds[1];
int en = 0;
size_t needed = wanted;
size_t sofar = 0;
ssize_t rrc = -1;
pollfd fds[1];
int en = 0;
fds[0].fd = fd;
fds[0].events = POLLOUT;
fds[0].fd = fd;
fds[0].events = POLLOUT;
while (wanted > sofar)
{
fds[0].revents = 0;
poll(fds, 1, -1);
errno = 0;
rrc = send(fd, (p + sofar), needed, 0);
en = errno;
if (rrc < 0)
{
if (en == EAGAIN || en == EINTR || en == 512)
continue;
ostringstream oss;
oss << "send() returned " << rrc << " (" << strerror(en) << ")";
idbassert_s(0, oss.str());
//throw runtime_error(oss.str());
}
needed -= rrc;
sofar += rrc;
}
while (wanted > sofar)
{
fds[0].revents = 0;
poll(fds, 1, -1);
errno = 0;
rrc = send(fd, (p + sofar), needed, 0);
en = errno;
if (rrc < 0)
{
if (en == EAGAIN || en == EINTR || en == 512)
continue;
ostringstream oss;
oss << "send() returned " << rrc << " (" << strerror(en) << ")";
idbassert_s(0, oss.str());
//throw runtime_error(oss.str());
}
needed -= rrc;
sofar += rrc;
}
}
}
@ -284,272 +303,292 @@ namespace v1
#ifndef _MSC_VER
void readn(int fd, void* buf, const size_t wanted)
{
size_t needed = wanted;
size_t sofar = 0;
char* p = reinterpret_cast<char*>(buf);
ssize_t rrc = -1;
pollfd fds[1];
int en = 0;
int prc = 0;
ostringstream oss;
unsigned zerocount=0;
size_t needed = wanted;
size_t sofar = 0;
char* p = reinterpret_cast<char*>(buf);
ssize_t rrc = -1;
pollfd fds[1];
int en = 0;
int prc = 0;
ostringstream oss;
unsigned zerocount = 0;
fds[0].fd = fd;
fds[0].events = POLLIN;
fds[0].fd = fd;
fds[0].events = POLLIN;
while (wanted > sofar)
{
fds[0].revents = 0;
errno = 0;
prc = poll(fds, 1, -1);
en = errno;
if (prc <= 0)
{
if (en == EAGAIN || en == EINTR || en == 512)
continue;
oss << "compress::v1::readn: poll() returned " << prc << " (" << strerror(en) << ")";
idbassert_s(0, oss.str());
}
//Check if there's data to be read
if ((fds[0].revents & POLLIN) == 0)
{
oss << "compress::v1::readn: revents for fd " << fds[0].fd << " was " << fds[0].revents;
idbassert_s(0, oss.str());
}
errno = 0;
rrc = read(fd, (p + sofar), needed);
en = errno;
if (rrc < 0)
{
if (en == EAGAIN || en == EINTR || en == 512)
continue;
oss << "compress::v1::readn(): read() returned " << rrc << " (" << strerror(en) << ")";
//this throws logging::IDBExcept()
idbassert_s(0, oss.str());
}
if (rrc == 0)
{
ostringstream os;
zerocount++;
if (zerocount >= 10)
{
os << "compress::v1::readn(): too many zero-length reads!";
idbassert_s(0, oss.str());
}
logging::MessageLog logger((logging::LoggingID()));
logging::Message message;
logging::Message::Args args;
os << "compress::v1::readn(): zero-length read on fd " << fd;
args.add(os.str());
message.format(args);
logger.logWarningMessage(message);
sleep(1);
}
else
zerocount = 0;
needed -= rrc;
sofar += rrc;
}
while (wanted > sofar)
{
fds[0].revents = 0;
errno = 0;
prc = poll(fds, 1, -1);
en = errno;
if (prc <= 0)
{
if (en == EAGAIN || en == EINTR || en == 512)
continue;
oss << "compress::v1::readn: poll() returned " << prc << " (" << strerror(en) << ")";
idbassert_s(0, oss.str());
}
//Check if there's data to be read
if ((fds[0].revents & POLLIN) == 0)
{
oss << "compress::v1::readn: revents for fd " << fds[0].fd << " was " << fds[0].revents;
idbassert_s(0, oss.str());
}
errno = 0;
rrc = read(fd, (p + sofar), needed);
en = errno;
if (rrc < 0)
{
if (en == EAGAIN || en == EINTR || en == 512)
continue;
oss << "compress::v1::readn(): read() returned " << rrc << " (" << strerror(en) << ")";
//this throws logging::IDBExcept()
idbassert_s(0, oss.str());
}
if (rrc == 0)
{
ostringstream os;
zerocount++;
if (zerocount >= 10)
{
os << "compress::v1::readn(): too many zero-length reads!";
idbassert_s(0, oss.str());
}
logging::MessageLog logger((logging::LoggingID()));
logging::Message message;
logging::Message::Args args;
os << "compress::v1::readn(): zero-length read on fd " << fd;
args.add(os.str());
message.format(args);
logger.logWarningMessage(message);
sleep(1);
}
else
zerocount = 0;
needed -= rrc;
sofar += rrc;
}
}
size_t writen(int fd, const void *data, size_t nbytes)
size_t writen(int fd, const void* data, size_t nbytes)
{
size_t nleft;
ssize_t nwritten;
const char *bufp = (const char *) data;
nleft = nbytes;
size_t nleft;
ssize_t nwritten;
const char* bufp = (const char*) data;
nleft = nbytes;
while (nleft > 0)
{
// the O_NONBLOCK flag is not set, this is a blocking I/O.
if ((nwritten = ::write(fd, bufp, nleft)) < 0)
{
if (errno == EINTR)
nwritten = 0;
else {
// save the error no first
int e = errno;
string errorMsg = "v1::writen() error: ";
boost::scoped_array<char> buf(new char[80]);
while (nleft > 0)
{
// the O_NONBLOCK flag is not set, this is a blocking I/O.
if ((nwritten = ::write(fd, bufp, nleft)) < 0)
{
if (errno == EINTR)
nwritten = 0;
else
{
// save the error no first
int e = errno;
string errorMsg = "v1::writen() error: ";
boost::scoped_array<char> buf(new char[80]);
#if STRERROR_R_CHAR_P
const char* p;
if ((p = strerror_r(e, buf.get(), 80)) != 0)
errorMsg += p;
const char* p;
if ((p = strerror_r(e, buf.get(), 80)) != 0)
errorMsg += p;
#else
int p;
if ((p = strerror_r(e, buf.get(), 80)) == 0)
errorMsg += buf.get();
int p;
if ((p = strerror_r(e, buf.get(), 80)) == 0)
errorMsg += buf.get();
#endif
idbassert_s(0, errorMsg);
//throw runtime_error(errorMsg);
}
}
nleft -= nwritten;
bufp += nwritten;
}
return nbytes;
idbassert_s(0, errorMsg);
//throw runtime_error(errorMsg);
}
}
nleft -= nwritten;
bufp += nwritten;
}
return nbytes;
}
#endif
bool decompress(const char* in, const uint32_t inLen, unsigned char* out, size_t* ol)
{
uint32_t u32;
uint64_t u64;
ostringstream oss;
string s;
string cpipe;
string upipe;
ScopedCleaner cleaner;
int fd = -1;
uint32_t u32;
uint64_t u64;
ostringstream oss;
string s;
string cpipe;
string upipe;
ScopedCleaner cleaner;
int fd = -1;
if (!Ctlshmptr)
initCtlShm();
if (!Ctlshmptr)
initCtlShm();
bi::scoped_lock<bi::interprocess_mutex> cfLock(Ctlshmptr->controlFifoMutex, bi::defer_lock);
bi::scoped_lock<bi::interprocess_mutex> cfLock(Ctlshmptr->controlFifoMutex, bi::defer_lock);
#ifndef _MSC_VER
pthread_t thdid = pthread_self();
pthread_t thdid = pthread_self();
#else
DWORD thdid = GetCurrentThreadId();
DWORD thdid = GetCurrentThreadId();
#endif
#ifdef _MSC_VER
oss << "\\\\.\\pipe\\cdatafifo" << thdid;
s = oss.str();
cpipe = s + ".c";
upipe = s + ".u";
oss << "\\\\.\\pipe\\cdatafifo" << thdid;
s = oss.str();
cpipe = s + ".c";
upipe = s + ".u";
HANDLE cpipeh;
cpipeh = CreateNamedPipe(cpipe.c_str(), PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE|PIPE_READMODE_BYTE|PIPE_WAIT,
1, 0, 8192, 0, 0);
idbassert_s(cpipeh != INVALID_HANDLE_VALUE, "while creating cdata fifo");
//if (cpipeh == INVALID_HANDLE_VALUE)
// throw runtime_error("while creating cdata fifo");
cleaner.cpipeh = cpipeh;
HANDLE cpipeh;
cpipeh = CreateNamedPipe(cpipe.c_str(), PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
1, 0, 8192, 0, 0);
idbassert_s(cpipeh != INVALID_HANDLE_VALUE, "while creating cdata fifo");
//if (cpipeh == INVALID_HANDLE_VALUE)
// throw runtime_error("while creating cdata fifo");
cleaner.cpipeh = cpipeh;
HANDLE upipeh;
upipeh = CreateNamedPipe(upipe.c_str(), PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE|PIPE_READMODE_BYTE|PIPE_WAIT,
1, 8192, 0, 0, 0);
idbassert_s(upipeh != INVALID_HANDLE_VALUE, "while creating udata fifo");
//if (upipeh == INVALID_HANDLE_VALUE)
// throw runtime_error("while creating udata fifo");
cleaner.upipeh = upipeh;
HANDLE upipeh;
upipeh = CreateNamedPipe(upipe.c_str(), PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
1, 8192, 0, 0, 0);
idbassert_s(upipeh != INVALID_HANDLE_VALUE, "while creating udata fifo");
//if (upipeh == INVALID_HANDLE_VALUE)
// throw runtime_error("while creating udata fifo");
cleaner.upipeh = upipeh;
#else
oss << "/tmp/cdatafifo" << hex << thdid;
s = oss.str();
cpipe = s + ".c";
upipe = s + ".u";
cleaner.cpipename = cpipe;
cleaner.upipename = upipe;
unlink(cpipe.c_str());
idbassert_s(mknod(cpipe.c_str(), S_IFIFO|0666, 0) == 0, "while creating cdata fifo");
//if (mknod(cpipe.c_str(), S_IFIFO|0666, 0) != 0)
// throw runtime_error("while creating cdata fifo");
unlink(upipe.c_str());
idbassert_s(mknod(upipe.c_str(), S_IFIFO|0666, 0) == 0, "while creating udata fifo");
//if (mknod(upipe.c_str(), S_IFIFO|0666, 0) != 0)
// throw runtime_error("while creating udata fifo");
oss << "/tmp/cdatafifo" << hex << thdid;
s = oss.str();
cpipe = s + ".c";
upipe = s + ".u";
cleaner.cpipename = cpipe;
cleaner.upipename = upipe;
unlink(cpipe.c_str());
idbassert_s(mknod(cpipe.c_str(), S_IFIFO | 0666, 0) == 0, "while creating cdata fifo");
//if (mknod(cpipe.c_str(), S_IFIFO|0666, 0) != 0)
// throw runtime_error("while creating cdata fifo");
unlink(upipe.c_str());
idbassert_s(mknod(upipe.c_str(), S_IFIFO | 0666, 0) == 0, "while creating udata fifo");
//if (mknod(upipe.c_str(), S_IFIFO|0666, 0) != 0)
// throw runtime_error("while creating udata fifo");
#endif
int rc = -1;
fd = ::socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
int rc = -1;
fd = ::socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
#ifdef _MSC_VER
idbassert_s(fd != INVALID_SOCKET,
string("socket create error: ") + strerror(errno));
idbassert_s(fd != INVALID_SOCKET,
string("socket create error: ") + strerror(errno));
#else
idbassert_s(fd >= 0,
string("socket create error: ") + strerror(errno));
idbassert_s(fd >= 0,
string("socket create error: ") + strerror(errno));
#endif
cleaner.ctlsock = fd;
struct sockaddr_in serv_addr;
struct in_addr la;
::inet_aton("127.0.0.1", &la);
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = la.s_addr;
serv_addr.sin_port = htons(DSPort);
const int MaxTries = 30;
int tries = 0;
cleaner.ctlsock = fd;
struct sockaddr_in serv_addr;
struct in_addr la;
::inet_aton("127.0.0.1", &la);
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = la.s_addr;
serv_addr.sin_port = htons(DSPort);
const int MaxTries = 30;
int tries = 0;
again:
cfLock.lock();
rc = ::connect(fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
if (rc < 0)
{
cfLock.lock();
rc = ::connect(fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
if (rc < 0)
{
#ifdef _MSC_VER
int x = WSAGetLastError();
if (x == WSAECONNREFUSED)
int x = WSAGetLastError();
if (x == WSAECONNREFUSED)
#else
if (errno == ECONNREFUSED)
if (errno == ECONNREFUSED)
#endif
{
idbassert_s(++tries < MaxTries, string("socket connect error: ") + strerror(errno));
//if (++tries >= MaxTries)
// throw runtime_error(string("socket connect error: ") + strerror(errno));
cfLock.unlock();
sleep(2);
goto again;
}
idbassert_s(0, string("socket connect error: ") + strerror(errno));
//throw runtime_error(string("socket connect error: ") + strerror(errno));
}
{
idbassert_s(++tries < MaxTries, string("socket connect error: ") + strerror(errno));
//if (++tries >= MaxTries)
// throw runtime_error(string("socket connect error: ") + strerror(errno));
cfLock.unlock();
sleep(2);
goto again;
}
u32 = s.length();
idbassert_s(0, string("socket connect error: ") + strerror(errno));
//throw runtime_error(string("socket connect error: ") + strerror(errno));
}
sendn(fd, reinterpret_cast<const char*>(&u32), 4);
u32 = s.length();
sendn(fd, s.c_str(), u32);
sendn(fd, reinterpret_cast<const char*>(&u32), 4);
shutdown(fd, SHUT_RDWR);
sendn(fd, s.c_str(), u32);
shutdown(fd, SHUT_RDWR);
#ifdef _MSC_VER
closesocket(fd);
cleaner.ctlsock = INVALID_SOCKET;
closesocket(fd);
cleaner.ctlsock = INVALID_SOCKET;
#else
close(fd);
cleaner.ctlsock = -1;
close(fd);
cleaner.ctlsock = -1;
#endif
cfLock.unlock();
cfLock.unlock();
#ifdef _MSC_VER
BOOL dwrc;
BOOL dwrc;
dwrc = ConnectNamedPipe(cpipeh, 0);
idbassert_s(!(dwrc == 0 && GetLastError() != ERROR_PIPE_CONNECTED), "connecting to cpipe");
//if (dwrc == 0 && GetLastError() != ERROR_PIPE_CONNECTED)
// throw runtime_error("connecting to cpipe");
dwrc = ConnectNamedPipe(cpipeh, 0);
idbassert_s(!(dwrc == 0 && GetLastError() != ERROR_PIPE_CONNECTED), "connecting to cpipe");
//if (dwrc == 0 && GetLastError() != ERROR_PIPE_CONNECTED)
// throw runtime_error("connecting to cpipe");
u64 = static_cast<uint64_t>(inLen);
idbassert_s(u64 < 8 * 1024 * 1024, "preposterous inLen!");
//if (!(u64 < 8 * 1024 * 1024))
// throw runtime_error("preposterous inLen!");
u64 = static_cast<uint64_t>(inLen);
idbassert_s(u64 < 8 * 1024 * 1024, "preposterous inLen!");
//if (!(u64 < 8 * 1024 * 1024))
// throw runtime_error("preposterous inLen!");
DWORD nwrite;
dwrc = WriteFile(cpipeh, &u64, 8, &nwrite, 0);
idbassert_s(dwrc != 0 && nwrite == 8, "while writing to cpipe");
//if (!(dwrc != 0 && nwrite == 8))
// throw runtime_error("while writing to cpipe");
DWORD nwrite;
dwrc = WriteFile(cpipeh, &u64, 8, &nwrite, 0);
idbassert_s(dwrc != 0 && nwrite == 8, "while writing to cpipe");
//if (!(dwrc != 0 && nwrite == 8))
// throw runtime_error("while writing to cpipe");
dwrc = WriteFile(cpipeh, in, u64, &nwrite, 0);
idbassert_s(dwrc != 0 && nwrite == u64, "while writing to cpipe");
//if (!(dwrc != 0 && nwrite == u64))
// throw runtime_error("while writing to cpipe");
dwrc = WriteFile(cpipeh, in, u64, &nwrite, 0);
idbassert_s(dwrc != 0 && nwrite == u64, "while writing to cpipe");
//if (!(dwrc != 0 && nwrite == u64))
// throw runtime_error("while writing to cpipe");
FlushFileBuffers(cpipeh);
CloseHandle(cpipeh);
cleaner.cpipeh = INVALID_HANDLE_VALUE;
FlushFileBuffers(cpipeh);
CloseHandle(cpipeh);
cleaner.cpipeh = INVALID_HANDLE_VALUE;
#else
ssize_t wrc;
fd = open(cpipe.c_str(), O_WRONLY);
idbassert_s(fd >= 0, "while opening data fifo for write");
//if (fd < 0)
// throw runtime_error("while opening data fifo for write");
ssize_t wrc;
fd = open(cpipe.c_str(), O_WRONLY);
idbassert_s(fd >= 0, "while opening data fifo for write");
//if (fd < 0)
// throw runtime_error("while opening data fifo for write");
cleaner.fd = fd;
cleaner.fd = fd;
u64 = static_cast<uint64_t>(inLen);
errno = 0;
wrc = writen(fd, &u64, 8);
int err = errno;
idbassert_s(wrc == 8, string("while writing compressed len to the DS: ") + strerror(err));
u64 = static_cast<uint64_t>(inLen);
errno = 0;
wrc = writen(fd, &u64, 8);
int err = errno;
idbassert_s(wrc == 8, string("while writing compressed len to the DS: ") + strerror(err));
// if (wrc != 8)
// {
// ostringstream oss;
@ -557,52 +596,52 @@ again:
// throw runtime_error(oss.str());
// }
wrc = writen(fd, in, u64);
idbassert_s(wrc == static_cast<ssize_t>(u64), "while writing compressed data to the DS");
wrc = writen(fd, in, u64);
idbassert_s(wrc == static_cast<ssize_t>(u64), "while writing compressed data to the DS");
// if (wrc != static_cast<ssize_t>(u64))
// throw runtime_error("while writing compressed data to the DS");
close(fd);
cleaner.fd = -1;
close(fd);
cleaner.fd = -1;
#endif
#ifdef _MSC_VER
dwrc = ConnectNamedPipe(upipeh, 0);
idbassert_s(!(dwrc == 0 && GetLastError() != ERROR_PIPE_CONNECTED), "connecting to upipe");
//if (dwrc == 0 && GetLastError() != ERROR_PIPE_CONNECTED)
// throw runtime_error("connecting to upipe");
dwrc = ConnectNamedPipe(upipeh, 0);
idbassert_s(!(dwrc == 0 && GetLastError() != ERROR_PIPE_CONNECTED), "connecting to upipe");
//if (dwrc == 0 && GetLastError() != ERROR_PIPE_CONNECTED)
// throw runtime_error("connecting to upipe");
DWORD nread;
dwrc = ReadFile(upipeh, &u64, 8, &nread, 0);
idbassert_s(dwrc != 0 && nread == 8, "while reading from upipe");
//if (!(dwrc != 0 && nread == 8))
// throw runtime_error("while reading from upipe");
DWORD nread;
dwrc = ReadFile(upipeh, &u64, 8, &nread, 0);
idbassert_s(dwrc != 0 && nread == 8, "while reading from upipe");
//if (!(dwrc != 0 && nread == 8))
// throw runtime_error("while reading from upipe");
dwrc = ReadFile(upipeh, out, u64, &nread, 0);
idbassert_s(dwrc != 0 && nread == u64, "while reading from upipe");
//if (!(dwrc != 0 && nread == u64))
// throw runtime_error("while reading from upipe");
dwrc = ReadFile(upipeh, out, u64, &nread, 0);
idbassert_s(dwrc != 0 && nread == u64, "while reading from upipe");
//if (!(dwrc != 0 && nread == u64))
// throw runtime_error("while reading from upipe");
CloseHandle(upipeh);
cleaner.upipeh = INVALID_HANDLE_VALUE;
CloseHandle(upipeh);
cleaner.upipeh = INVALID_HANDLE_VALUE;
#else
fd = open(upipe.c_str(), O_RDONLY);
idbassert_s(fd >= 0, "while opening data fifo for read");
fd = open(upipe.c_str(), O_RDONLY);
idbassert_s(fd >= 0, "while opening data fifo for read");
// if (fd < 0)
// throw runtime_error("while opening data fifo for read");
cleaner.fd = fd;
cleaner.fd = fd;
readn(fd, &u64, 8);
readn(fd, out, u64);
readn(fd, &u64, 8);
readn(fd, out, u64);
close(fd);
cleaner.fd = -1;
close(fd);
cleaner.fd = -1;
#endif
*ol = static_cast<size_t>(u64);
*ol = static_cast<size_t>(u64);
return (u64 != 0);
return (u64 != 0);
}
} //namespace v1

View File

@ -27,12 +27,12 @@
namespace compress
{
namespace v1
{
namespace v1
{
bool decompress(const char* in, const uint32_t inLen, unsigned char* out, size_t* ol);
bool decompress(const char* in, const uint32_t inLen, unsigned char* out, size_t* ol);
} //namespace v1
} //namespace v1
} // namespace compress
#endif

View File

@ -34,7 +34,7 @@ using namespace std;
#include <boost/filesystem.hpp>
#include <boost/unordered_map.hpp>
using namespace boost;
namespace fs=boost::filesystem;
namespace fs = boost::filesystem;
#include <sys/types.h>
#include <sys/stat.h>
@ -76,549 +76,609 @@ boost::mutex Config::fWriteXmlLock;
Config* Config::makeConfig(const string& cf)
{
return makeConfig(cf.c_str());
return makeConfig(cf.c_str());
}
Config* Config::makeConfig(const char* cf)
{
mutex::scoped_lock lk(fInstanceMapMutex);
mutex::scoped_lock lk(fInstanceMapMutex);
static string installDir;
static string installDir;
if (installDir.empty())
installDir = startup::StartUp::installDir();
if (cf == 0)
{
if (cf == 0)
{
#ifdef _MSC_VER
string cfStr = IDBreadRegistry("ConfigFile");
if (!cfStr.empty())
cf = cfStr.c_str();
string cfStr = IDBreadRegistry("ConfigFile");
if (!cfStr.empty())
cf = cfStr.c_str();
#else
cf = getenv("CALPONT_CONFIG_FILE");
cf = getenv("CALPONT_CONFIG_FILE");
#endif
if (cf == 0 || *cf == 0)
{
if (cf == 0 || *cf == 0)
{
static string defaultFilePath;
if (defaultFilePath.empty())
{
fs::path configFilePath;
configFilePath = fs::path(installDir) / fs::path("etc") / defaultCalpontConfigFile;
defaultFilePath = configFilePath.string();
}
if (fInstanceMap.find(defaultFilePath) == fInstanceMap.end())
{
Config* instance = new Config(defaultFilePath, installDir);
fInstanceMap[defaultFilePath] = instance;
}
{
Config* instance = new Config(defaultFilePath, installDir);
fInstanceMap[defaultFilePath] = instance;
}
return fInstanceMap[defaultFilePath];
}
}
string configFile(cf);
}
}
if (fInstanceMap.find(configFile) == fInstanceMap.end())
{
Config* instance = new Config(configFile, installDir);
fInstanceMap[configFile] = instance;
}
string configFile(cf);
return fInstanceMap[configFile];
if (fInstanceMap.find(configFile) == fInstanceMap.end())
{
Config* instance = new Config(configFile, installDir);
fInstanceMap[configFile] = instance;
}
return fInstanceMap[configFile];
}
Config::Config(const string& configFile, const string& installDir) :
fDoc(0), fConfigFile(configFile), fMtime(0), fInstallDir(installDir), fParser(fInstallDir)
fDoc(0), fConfigFile(configFile), fMtime(0), fInstallDir(installDir), fParser(fInstallDir)
{
for ( int i = 0 ; i < 20 ; i++ )
{
if (access(fConfigFile.c_str(), R_OK) != 0) {
if ( i >= 15 )
throw runtime_error("Config::Config: error accessing config file " + fConfigFile);
sleep (1);
}
else
break;
}
for ( int i = 0 ; i < 20 ; i++ )
{
if (access(fConfigFile.c_str(), R_OK) != 0)
{
if ( i >= 15 )
throw runtime_error("Config::Config: error accessing config file " + fConfigFile);
struct stat statbuf;
if (stat(configFile.c_str(), &statbuf) == 0)
fMtime = statbuf.st_mtime;
sleep (1);
}
else
break;
}
parseDoc();
struct stat statbuf;
if (stat(configFile.c_str(), &statbuf) == 0)
fMtime = statbuf.st_mtime;
parseDoc();
}
Config::~Config()
{
if (fDoc != 0)
closeConfig();
if (fDoc != 0)
closeConfig();
}
void Config::parseDoc(void)
{
struct flock fl;
int fd;
struct flock fl;
int fd;
memset(&fl, 0, sizeof(fl));
fl.l_type = F_RDLCK; // read lock
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0; //lock whole file
memset(&fl, 0, sizeof(fl));
fl.l_type = F_RDLCK; // read lock
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0; //lock whole file
// lock file if exist
if ((fd = open(fConfigFile.c_str(), O_RDONLY)) >= 0)
{
if (fcntl(fd, F_SETLKW, &fl) != 0)
{
ostringstream oss;
oss << "Config::parseDoc: error locking file " <<
fConfigFile <<
": " <<
strerror(errno) <<
", proceding anyway.";
cerr << oss.str() << endl;
}
// lock file if exist
if ((fd = open(fConfigFile.c_str(), O_RDONLY)) >= 0)
{
if (fcntl(fd, F_SETLKW, &fl) != 0)
{
ostringstream oss;
oss << "Config::parseDoc: error locking file " <<
fConfigFile <<
": " <<
strerror(errno) <<
", proceding anyway.";
cerr << oss.str() << endl;
}
fXmlLock.lock();
fDoc = xmlParseFile(fConfigFile.c_str());
fXmlLock.lock();
fDoc = xmlParseFile(fConfigFile.c_str());
fXmlLock.unlock();
fl.l_type = F_UNLCK; //unlock
fcntl(fd, F_SETLK, &fl);
fl.l_type = F_UNLCK; //unlock
fcntl(fd, F_SETLK, &fl);
close(fd);
}
else
{
ostringstream oss;
oss << "Config::parseDoc: error opening file " <<
fConfigFile <<
": " <<
strerror(errno);
throw runtime_error(oss.str());
}
close(fd);
}
else
{
ostringstream oss;
oss << "Config::parseDoc: error opening file " <<
fConfigFile <<
": " <<
strerror(errno);
throw runtime_error(oss.str());
}
if (fDoc == 0 ) {
throw runtime_error("Config::parseDoc: error parsing config file " + fConfigFile);
}
if (fDoc == 0 )
{
throw runtime_error("Config::parseDoc: error parsing config file " + fConfigFile);
}
xmlNodePtr cur = xmlDocGetRootElement(fDoc);
xmlNodePtr cur = xmlDocGetRootElement(fDoc);
if (cur == NULL)
{
xmlFreeDoc(fDoc);
fDoc = 0;
throw runtime_error("Config::parseDoc: error parsing config file " + fConfigFile);
}
if (cur == NULL)
{
xmlFreeDoc(fDoc);
fDoc = 0;
throw runtime_error("Config::parseDoc: error parsing config file " + fConfigFile);
}
if (xmlStrcmp(cur->name, (const xmlChar *)"Columnstore"))
{
xmlFreeDoc(fDoc);
fDoc = 0;
throw runtime_error("Config::parseDoc: error parsing config file " + fConfigFile);
}
if (xmlStrcmp(cur->name, (const xmlChar*)"Columnstore"))
{
xmlFreeDoc(fDoc);
fDoc = 0;
throw runtime_error("Config::parseDoc: error parsing config file " + fConfigFile);
}
return;
return;
}
void Config::closeConfig(void)
{
xmlFreeDoc(fDoc);
fDoc = 0;
xmlFreeDoc(fDoc);
fDoc = 0;
}
const string Config::getConfig(const string& section, const string& name)
{
mutex::scoped_lock lk(fLock);
mutex::scoped_lock lk(fLock);
if (section.length() == 0 || name.length() == 0)
throw invalid_argument("Config::getConfig: both section and name must have a length");
if (section.length() == 0 || name.length() == 0)
throw invalid_argument("Config::getConfig: both section and name must have a length");
if (fDoc == 0){
throw runtime_error("Config::getConfig: no XML document!");
}
if (fDoc == 0)
{
throw runtime_error("Config::getConfig: no XML document!");
}
struct stat statbuf;
if (stat(fConfigFile.c_str(), &statbuf) == 0)
{
if (statbuf.st_mtime != fMtime)
{
closeConfig();
fMtime = statbuf.st_mtime;
parseDoc();
}
}
struct stat statbuf;
if (stat(fConfigFile.c_str(), &statbuf) == 0)
{
if (statbuf.st_mtime != fMtime)
{
closeConfig();
fMtime = statbuf.st_mtime;
parseDoc();
}
}
return fParser.getConfig(fDoc, section, name);
}
void Config::getConfig(const string& section, const string& name, vector<string>& values)
{
mutex::scoped_lock lk(fLock);
mutex::scoped_lock lk(fLock);
if (section.length() == 0)
throw invalid_argument("Config::getConfig: section must have a length");
if (section.length() == 0)
throw invalid_argument("Config::getConfig: section must have a length");
if (fDoc == 0)
throw runtime_error("Config::getConfig: no XML document!");
if (fDoc == 0)
throw runtime_error("Config::getConfig: no XML document!");
struct stat statbuf;
if (stat(fConfigFile.c_str(), &statbuf) == 0)
{
if (statbuf.st_mtime != fMtime)
{
closeConfig();
fMtime = statbuf.st_mtime;
parseDoc();
}
}
struct stat statbuf;
fParser.getConfig(fDoc, section, name, values);
if (stat(fConfigFile.c_str(), &statbuf) == 0)
{
if (statbuf.st_mtime != fMtime)
{
closeConfig();
fMtime = statbuf.st_mtime;
parseDoc();
}
}
fParser.getConfig(fDoc, section, name, values);
}
void Config::setConfig(const string& section, const string& name, const string& value)
{
mutex::scoped_lock lk(fLock);
mutex::scoped_lock lk(fLock);
if (section.length() == 0 || name.length() == 0 )
throw invalid_argument("Config::setConfig: all of section and name must have a length");
if (section.length() == 0 || name.length() == 0 )
throw invalid_argument("Config::setConfig: all of section and name must have a length");
if (fDoc == 0) {
throw runtime_error("Config::setConfig: no XML document!");
}
if (fDoc == 0)
{
throw runtime_error("Config::setConfig: no XML document!");
}
struct stat statbuf;
memset(&statbuf, 0, sizeof(statbuf));
if (stat(fConfigFile.c_str(), &statbuf) == 0)
{
if (statbuf.st_mtime != fMtime)
{
closeConfig();
fMtime = statbuf.st_mtime;
parseDoc();
}
}
struct stat statbuf;
fParser.setConfig(fDoc, section, name, value);
return;
memset(&statbuf, 0, sizeof(statbuf));
if (stat(fConfigFile.c_str(), &statbuf) == 0)
{
if (statbuf.st_mtime != fMtime)
{
closeConfig();
fMtime = statbuf.st_mtime;
parseDoc();
}
}
fParser.setConfig(fDoc, section, name, value);
return;
}
void Config::delConfig(const string& section, const string& name)
{
mutex::scoped_lock lk(fLock);
mutex::scoped_lock lk(fLock);
if (section.length() == 0 || name.length() == 0)
throw invalid_argument("Config::delConfig: both section and name must have a length");
if (section.length() == 0 || name.length() == 0)
throw invalid_argument("Config::delConfig: both section and name must have a length");
if (fDoc == 0){
throw runtime_error("Config::delConfig: no XML document!");
}
if (fDoc == 0)
{
throw runtime_error("Config::delConfig: no XML document!");
}
struct stat statbuf;
if (stat(fConfigFile.c_str(), &statbuf) == 0)
{
if (statbuf.st_mtime != fMtime)
{
closeConfig();
fMtime = statbuf.st_mtime;
parseDoc();
}
}
struct stat statbuf;
fParser.delConfig(fDoc, section, name);
return;
if (stat(fConfigFile.c_str(), &statbuf) == 0)
{
if (statbuf.st_mtime != fMtime)
{
closeConfig();
fMtime = statbuf.st_mtime;
parseDoc();
}
}
fParser.delConfig(fDoc, section, name);
return;
}
void Config::writeConfig(const string& configFile) const
{
mutex::scoped_lock lk(fLock);
FILE *fi;
if (fDoc == 0)
throw runtime_error("Config::writeConfig: no XML document!");
mutex::scoped_lock lk(fLock);
FILE* fi;
if (fDoc == 0)
throw runtime_error("Config::writeConfig: no XML document!");
#ifdef _MSC_VER
fs::path configFilePth(configFile);
fs::path outFilePth(configFilePth);
outFilePth.replace_extension("temp");
if ((fi = fopen(outFilePth.string().c_str(), "wt")) == NULL)
throw runtime_error("Config::writeConfig: error opening config file for write " + outFilePth.string());
int rc = -1;
rc = xmlDocDump(fi, fDoc);
if (rc < 0) {
throw runtime_error("Config::writeConfig: error writing config file " + outFilePth.string());
}
fclose(fi);
if (fs::exists(configFilePth))
fs::remove(configFilePth);
fs::rename(outFilePth, configFilePth);
fs::path configFilePth(configFile);
fs::path outFilePth(configFilePth);
outFilePth.replace_extension("temp");
if ((fi = fopen(outFilePth.string().c_str(), "wt")) == NULL)
throw runtime_error("Config::writeConfig: error opening config file for write " + outFilePth.string());
int rc = -1;
rc = xmlDocDump(fi, fDoc);
if (rc < 0)
{
throw runtime_error("Config::writeConfig: error writing config file " + outFilePth.string());
}
fclose(fi);
if (fs::exists(configFilePth))
fs::remove(configFilePth);
fs::rename(outFilePth, configFilePth);
#else
const fs::path defaultCalpontConfigFileTemp("Columnstore.xml.temp");
const fs::path saveCalpontConfigFileTemp("Columnstore.xml.columnstoreSave");
const fs::path tmpCalpontConfigFileTemp("Columnstore.xml.temp1");
const fs::path defaultCalpontConfigFileTemp("Columnstore.xml.temp");
const fs::path saveCalpontConfigFileTemp("Columnstore.xml.columnstoreSave");
const fs::path tmpCalpontConfigFileTemp("Columnstore.xml.temp1");
fs::path etcdir = fs::path(fInstallDir) / fs::path("etc");
fs::path etcdir = fs::path(fInstallDir) / fs::path("etc");
fs::path dcf = etcdir / fs::path(defaultCalpontConfigFile);
fs::path dcft = etcdir / fs::path(defaultCalpontConfigFileTemp);
fs::path scft = etcdir / fs::path(saveCalpontConfigFileTemp);
fs::path tcft = etcdir / fs::path(tmpCalpontConfigFileTemp);
//perform a temp write first if Columnstore.xml file to prevent possible corruption
if ( configFile == dcf ) {
fs::path dcf = etcdir / fs::path(defaultCalpontConfigFile);
fs::path dcft = etcdir / fs::path(defaultCalpontConfigFileTemp);
fs::path scft = etcdir / fs::path(saveCalpontConfigFileTemp);
fs::path tcft = etcdir / fs::path(tmpCalpontConfigFileTemp);
if (exists(dcft)) fs::remove(dcft);
if ((fi = fopen(dcft.string().c_str(), "w+")) == NULL)
throw runtime_error("Config::writeConfig: error writing config file " + configFile);
//perform a temp write first if Columnstore.xml file to prevent possible corruption
if ( configFile == dcf )
{
int rc;
rc = xmlDocDump(fi, fDoc);
if ( rc < 0) {
throw runtime_error("Config::writeConfig: error writing config file " + configFile);
//cout << "xmlDocDump " << rc << " " << errno << endl;
}
if (exists(dcft)) fs::remove(dcft);
fclose(fi);
if ((fi = fopen(dcft.string().c_str(), "w+")) == NULL)
throw runtime_error("Config::writeConfig: error writing config file " + configFile);
//check temp file
try {
Config* c1 = makeConfig(dcft.string().c_str());
int rc;
rc = xmlDocDump(fi, fDoc);
string value;
value = c1->getConfig("SystemConfig", "SystemName");
if ( rc < 0)
{
throw runtime_error("Config::writeConfig: error writing config file " + configFile);
//cout << "xmlDocDump " << rc << " " << errno << endl;
}
//good read, save copy, copy temp file tp tmp then to Columnstore.xml
//move to /tmp to get around a 'same file error' in mv command
try {
if (exists(scft)) fs::remove(scft);
} catch (fs::filesystem_error&) { }
fs::copy_file(dcf, scft, fs::copy_option::overwrite_if_exists);
try {
fs::permissions(scft, fs::add_perms | fs::owner_read | fs::owner_write |
fs::group_read | fs::group_write |
fs::others_read | fs::others_write);
} catch (fs::filesystem_error&) { }
fclose(fi);
if (exists(tcft)) fs::remove(tcft);
fs::rename(dcft, tcft);
//check temp file
try
{
Config* c1 = makeConfig(dcft.string().c_str());
if (exists(dcf)) fs::remove(dcf);
fs::rename(tcft, dcf);
}
catch (...)
{
throw runtime_error("Config::writeConfig: error writing config file " + configFile);
}
}
else
{ // non Columnstore.xml, perform update
if ((fi = fopen(configFile.c_str(), "w")) == NULL)
throw runtime_error("Config::writeConfig: error writing config file " + configFile);
string value;
value = c1->getConfig("SystemConfig", "SystemName");
xmlDocDump(fi, fDoc);
//good read, save copy, copy temp file tp tmp then to Columnstore.xml
//move to /tmp to get around a 'same file error' in mv command
try
{
if (exists(scft)) fs::remove(scft);
}
catch (fs::filesystem_error&) { }
fs::copy_file(dcf, scft, fs::copy_option::overwrite_if_exists);
try
{
fs::permissions(scft, fs::add_perms | fs::owner_read | fs::owner_write |
fs::group_read | fs::group_write |
fs::others_read | fs::others_write);
}
catch (fs::filesystem_error&) { }
if (exists(tcft)) fs::remove(tcft);
fs::rename(dcft, tcft);
if (exists(dcf)) fs::remove(dcf);
fs::rename(tcft, dcf);
}
catch (...)
{
throw runtime_error("Config::writeConfig: error writing config file " + configFile);
}
}
else
{
// non Columnstore.xml, perform update
if ((fi = fopen(configFile.c_str(), "w")) == NULL)
throw runtime_error("Config::writeConfig: error writing config file " + configFile);
xmlDocDump(fi, fDoc);
fclose(fi);
}
fclose(fi);
}
#endif
return;
return;
}
void Config::write(void) const
{
mutex::scoped_lock lk(fWriteXmlLock);
mutex::scoped_lock lk(fWriteXmlLock);
#ifdef _MSC_VER
writeConfig(fConfigFile);
writeConfig(fConfigFile);
#else
write(fConfigFile);
write(fConfigFile);
#endif
}
void Config::write(const string& configFile) const
{
struct flock fl;
int fd;
struct flock fl;
int fd;
fl.l_type = F_WRLCK; // write lock
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
fl.l_pid = getpid();
fl.l_type = F_WRLCK; // write lock
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
fl.l_pid = getpid();
// lock file if it exists
if ((fd = open(configFile.c_str(), O_WRONLY)) >= 0)
{
if (fcntl(fd, F_SETLKW, &fl) == -1)
throw runtime_error("Config::write: file lock error " + configFile);
// lock file if it exists
if ((fd = open(configFile.c_str(), O_WRONLY)) >= 0)
{
if (fcntl(fd, F_SETLKW, &fl) == -1)
throw runtime_error("Config::write: file lock error " + configFile);
try
{
writeConfig(configFile);
}
catch(...)
catch (...)
{
fl.l_type = F_UNLCK; //unlock
if (fcntl(fd, F_SETLK, &fl) == -1)
throw runtime_error("Config::write: file unlock error after exception in writeConfig " + configFile);
throw;
}
fl.l_type = F_UNLCK; //unlock
if (fcntl(fd, F_SETLK, &fl) == -1)
throw runtime_error("Config::write: file unlock error " + configFile);
fl.l_type = F_UNLCK; //unlock
close(fd);
}
else
{
writeConfig(configFile);
}
if (fcntl(fd, F_SETLK, &fl) == -1)
throw runtime_error("Config::write: file unlock error " + configFile);
close(fd);
}
else
{
writeConfig(configFile);
}
}
void Config::writeConfigFile(messageqcpp::ByteStream msg) const
{
struct flock fl;
int fd;
struct flock fl;
int fd;
//get config file name being udated
string fileName;
msg >> fileName;
//get config file name being udated
string fileName;
msg >> fileName;
fl.l_type = F_WRLCK; // write lock
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
fl.l_pid = getpid();
fl.l_type = F_WRLCK; // write lock
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
fl.l_pid = getpid();
// lock file if it exists
if ((fd = open(fileName.c_str(), O_WRONLY)) >= 0)
{
if (fcntl(fd, F_SETLKW, &fl) == -1)
throw runtime_error("Config::write: file lock error " + fileName);
// lock file if it exists
if ((fd = open(fileName.c_str(), O_WRONLY)) >= 0)
{
if (fcntl(fd, F_SETLKW, &fl) == -1)
throw runtime_error("Config::write: file lock error " + fileName);
ofstream out(fileName.c_str());
out << msg;
ofstream out(fileName.c_str());
out << msg;
fl.l_type = F_UNLCK; //unlock
if (fcntl(fd, F_SETLK, &fl) == -1)
throw runtime_error("Config::write: file unlock error " + fileName);
fl.l_type = F_UNLCK; //unlock
close(fd);
}
else
{
ofstream out(fileName.c_str());
out << msg;
}
if (fcntl(fd, F_SETLK, &fl) == -1)
throw runtime_error("Config::write: file unlock error " + fileName);
close(fd);
}
else
{
ofstream out(fileName.c_str());
out << msg;
}
}
/* static */
void Config::deleteInstanceMap()
{
mutex::scoped_lock lk(fInstanceMapMutex);
for (Config::configMap_t::iterator iter = fInstanceMap.begin();
iter != fInstanceMap.end(); ++iter)
{
Config* instance = iter->second;
delete instance;
}
fInstanceMap.clear();
mutex::scoped_lock lk(fInstanceMapMutex);
for (Config::configMap_t::iterator iter = fInstanceMap.begin();
iter != fInstanceMap.end(); ++iter)
{
Config* instance = iter->second;
delete instance;
}
fInstanceMap.clear();
}
/* static */
int64_t Config::fromText(const std::string& text)
{
if (text.length() == 0) return 0;
if (text.length() == 0) return 0;
int64_t val = 0;
char* ctext = static_cast<char*>(alloca(text.length() + 1));
strcpy(ctext, text.c_str());
char* cptr;
int64_t val = 0;
char* ctext = static_cast<char*>(alloca(text.length() + 1));
strcpy(ctext, text.c_str());
char* cptr;
val = strtoll(ctext, &cptr, 0);
val = strtoll(ctext, &cptr, 0);
switch (*cptr)
{
case 'T':
case 't':
val *= 1024;
/* fallthru */
case 'G':
case 'g':
val *= 1024;
/* fallthru */
case 'M':
case 'm':
val *= 1024;
/* fallthru */
case 'K':
case 'k':
val *= 1024;
/* fallthru */
case '\0':
break;
default:
ostringstream oss;
oss << "Invalid character '" << *cptr << "' found in numeric parameter '" << text <<
"'. Since this will not do what you want it is fatal." << endl;
throw runtime_error(oss.str());
break;
}
switch (*cptr)
{
case 'T':
case 't':
val *= 1024;
return val;
/* fallthru */
case 'G':
case 'g':
val *= 1024;
/* fallthru */
case 'M':
case 'm':
val *= 1024;
/* fallthru */
case 'K':
case 'k':
val *= 1024;
/* fallthru */
case '\0':
break;
default:
ostringstream oss;
oss << "Invalid character '" << *cptr << "' found in numeric parameter '" << text <<
"'. Since this will not do what you want it is fatal." << endl;
throw runtime_error(oss.str());
break;
}
return val;
}
time_t Config::getCurrentMTime()
{
mutex::scoped_lock lk(fLock);
mutex::scoped_lock lk(fLock);
struct stat statbuf;
if (stat(fConfigFile.c_str(), &statbuf) == 0)
return statbuf.st_mtime;
else
return 0;
struct stat statbuf;
if (stat(fConfigFile.c_str(), &statbuf) == 0)
return statbuf.st_mtime;
else
return 0;
}
const vector<string> Config::enumConfig()
{
mutex::scoped_lock lk(fLock);
mutex::scoped_lock lk(fLock);
if (fDoc == 0){
throw runtime_error("Config::getConfig: no XML document!");
}
if (fDoc == 0)
{
throw runtime_error("Config::getConfig: no XML document!");
}
struct stat statbuf;
if (stat(fConfigFile.c_str(), &statbuf) == 0)
{
if (statbuf.st_mtime != fMtime)
{
closeConfig();
fMtime = statbuf.st_mtime;
parseDoc();
}
}
struct stat statbuf;
return fParser.enumConfig(fDoc);
if (stat(fConfigFile.c_str(), &statbuf) == 0)
{
if (statbuf.st_mtime != fMtime)
{
closeConfig();
fMtime = statbuf.st_mtime;
parseDoc();
}
}
return fParser.enumConfig(fDoc);
}
const vector<string> Config::enumSection(const string& section)
{
mutex::scoped_lock lk(fLock);
mutex::scoped_lock lk(fLock);
if (fDoc == 0){
throw runtime_error("Config::getConfig: no XML document!");
}
if (fDoc == 0)
{
throw runtime_error("Config::getConfig: no XML document!");
}
struct stat statbuf;
if (stat(fConfigFile.c_str(), &statbuf) == 0)
{
if (statbuf.st_mtime != fMtime)
{
closeConfig();
fMtime = statbuf.st_mtime;
parseDoc();
}
}
struct stat statbuf;
return fParser.enumSection(fDoc, section);
if (stat(fConfigFile.c_str(), &statbuf) == 0)
{
if (statbuf.st_mtime != fMtime)
{
closeConfig();
fMtime = statbuf.st_mtime;
parseDoc();
}
}
return fParser.enumSection(fDoc, section);
}
} //namespace config

View File

@ -50,7 +50,8 @@ class ByteStream;
#define EXPORT
#endif
namespace config {
namespace config
{
/** @brief a config file I/F class
*
@ -62,167 +63,176 @@ namespace config {
class Config
{
public:
/** @brief Config factory method
*
* Creates a singleton Config object
*/
EXPORT static Config* makeConfig(const char* cf=0);
/** @brief Config factory method
*
* Creates a singleton Config object
*/
EXPORT static Config* makeConfig(const char* cf = 0);
/** @brief Config factory method
*
* Creates a singleton Config object
*/
EXPORT static Config* makeConfig(const std::string& cf);
/** @brief Config factory method
*
* Creates a singleton Config object
*/
EXPORT static Config* makeConfig(const std::string& cf);
/** @brief dtor
*/
EXPORT virtual ~Config();
/** @brief dtor
*/
EXPORT virtual ~Config();
/** @brief get name's value from section
*
* get name's value from section in the current config file.
* @param section the name of the config file section to search
* @param name the param name whose value is to be returned
*/
EXPORT const std::string getConfig(const std::string& section, const std::string& name);
/** @brief get name's value from section
*
* get name's value from section in the current config file.
* @param section the name of the config file section to search
* @param name the param name whose value is to be returned
*/
EXPORT const std::string getConfig(const std::string& section, const std::string& name);
/** @brief get all name's values from a section
*
* get name's values from section in the current config file.
* @param section the name of the config file section to search
* @param name the param name whose value is to be returned
* @param values the values in the section are returned in this vector
*/
EXPORT void getConfig(const std::string& section, const std::string& name,
std::vector<std::string>& values);
/** @brief get all name's values from a section
*
* get name's values from section in the current config file.
* @param section the name of the config file section to search
* @param name the param name whose value is to be returned
* @param values the values in the section are returned in this vector
*/
EXPORT void getConfig(const std::string& section, const std::string& name,
std::vector<std::string>& values);
/** @brief set name's value in section
*
* set name's value in section in the current config file.
* @param section the name of the config file section to update
* @param name the param name whose value is to be updated
* @param value the param value
*/
EXPORT void setConfig(const std::string& section, const std::string& name, const std::string& value);
/** @brief set name's value in section
*
* set name's value in section in the current config file.
* @param section the name of the config file section to update
* @param name the param name whose value is to be updated
* @param value the param value
*/
EXPORT void setConfig(const std::string& section, const std::string& name, const std::string& value);
/** @brief delete name from section
*
* delete name from section in the current config file.
* @param section the name of the config file section to search
* @param name the param name whose entry is to be deleted
* @note if you delete the last param from a section, the section will still remain
*/
EXPORT void delConfig(const std::string& section, const std::string& name);
/** @brief delete name from section
*
* delete name from section in the current config file.
* @param section the name of the config file section to search
* @param name the param name whose entry is to be deleted
* @note if you delete the last param from a section, the section will still remain
*/
EXPORT void delConfig(const std::string& section, const std::string& name);
/** @brief write the config file back out to disk
*
* write the config file back out to disk using the current filename.
*/
EXPORT void write(void) const;
/** @brief write the config file back out to disk
*
* write the config file back out to disk using the current filename.
*/
EXPORT void write(void) const;
/** @brief write the config file back out to disk as fileName
*
* write the config file out to disk as a new file fileName. Does not affect the current
* config filename.
*/
EXPORT void write(const std::string& fileName) const;
/** @brief write the config file back out to disk as fileName
*
* write the config file out to disk as a new file fileName. Does not affect the current
* config filename.
*/
EXPORT void write(const std::string& fileName) const;
/** @brief write a stream copy of config file to disk
*
* write a stream copy of config file to disk. used to distributed mass updates to system nodes
*
*/
EXPORT void writeConfigFile(messageqcpp::ByteStream msg) const;
/** @brief write a stream copy of config file to disk
*
* write a stream copy of config file to disk. used to distributed mass updates to system nodes
*
*/
EXPORT void writeConfigFile(messageqcpp::ByteStream msg) const;
/** @brief return the name of this config file
*
* return the name of this config file.
*/
EXPORT inline const std::string& configFile() const { return fConfigFile; }
/** @brief return the name of this config file
*
* return the name of this config file.
*/
EXPORT inline const std::string& configFile() const
{
return fConfigFile;
}
/** @brief delete all config file instances
*
* deletes \b all config file maps
*/
EXPORT static void deleteInstanceMap();
/** @brief delete all config file instances
*
* deletes \b all config file maps
*/
EXPORT static void deleteInstanceMap();
/** @brief parse config file numerics
*
* Convert human-friendly number formats to machine-friendly. Handle suffixes 'K', 'M', 'G'.
* Handle decimal, hex and octal notation in the same way as the C compiler.
* Ignore any 'B' following [KMG]. Ignore case in suffixes.
* An empty string or an unparseable string returns 0.
* Return a signed numeric value.
*/
EXPORT static int64_t fromText(const std::string& text);
/** @brief parse config file numerics
*
* Convert human-friendly number formats to machine-friendly. Handle suffixes 'K', 'M', 'G'.
* Handle decimal, hex and octal notation in the same way as the C compiler.
* Ignore any 'B' following [KMG]. Ignore case in suffixes.
* An empty string or an unparseable string returns 0.
* Return a signed numeric value.
*/
EXPORT static int64_t fromText(const std::string& text);
/** @brief parse config file numerics
*
* Return an unsigned numeric value.
*/
EXPORT static inline uint64_t uFromText(const std::string& text) { return static_cast<uint64_t>(fromText(text)); }
/** @brief parse config file numerics
*
* Return an unsigned numeric value.
*/
EXPORT static inline uint64_t uFromText(const std::string& text)
{
return static_cast<uint64_t>(fromText(text));
}
/** @brief Used externally to check whether there has been a config change without loading everything
*
*/
inline time_t getLastMTime() const { return fMtime; }
/** @brief Used externally to check whether there has been a config change without loading everything
*
*/
inline time_t getLastMTime() const
{
return fMtime;
}
/** @brief Used externally to check whether there has been a config change without loading everything
*
*/
EXPORT time_t getCurrentMTime();
/** @brief Used externally to check whether there has been a config change without loading everything
*
*/
EXPORT time_t getCurrentMTime();
/** @brief Enumerate all the sections in the config file
*
*/
EXPORT const std::vector<std::string> enumConfig();
/** @brief Enumerate all the sections in the config file
*
*/
EXPORT const std::vector<std::string> enumConfig();
/** @brief Enumerate all the names in a section in the config file
*
*/
EXPORT const std::vector<std::string> enumSection(const std::string& section);
/** @brief Enumerate all the names in a section in the config file
*
*/
EXPORT const std::vector<std::string> enumSection(const std::string& section);
protected:
/** @brief parse the XML file
*
*/
void parseDoc(void);
/** @brief parse the XML file
*
*/
void parseDoc(void);
/** @brief write the XML tree to disk
*
*/
EXPORT void writeConfig(const std::string& fileName) const;
/** @brief write the XML tree to disk
*
*/
EXPORT void writeConfig(const std::string& fileName) const;
/** @brief stop processing this XML file
*
*/
void closeConfig(void);
/** @brief stop processing this XML file
*
*/
void closeConfig(void);
private:
typedef std::map<std::string, Config*> configMap_t;
typedef std::map<std::string, Config*> configMap_t;
/*
*/
Config(const Config& rhs);
/*
*/
Config& operator=(const Config& rhs);
/*
*/
Config(const Config& rhs);
/*
*/
Config& operator=(const Config& rhs);
/** @brief ctor with config file specified
*/
Config(const std::string& configFile, const std::string& installDir);
/** @brief ctor with config file specified
*/
Config(const std::string& configFile, const std::string& installDir);
static configMap_t fInstanceMap;
static boost::mutex fInstanceMapMutex;
static boost::mutex fXmlLock;
static boost::mutex fWriteXmlLock;
static configMap_t fInstanceMap;
static boost::mutex fInstanceMapMutex;
static boost::mutex fXmlLock;
static boost::mutex fWriteXmlLock;
xmlDocPtr fDoc;
const std::string fConfigFile;
time_t fMtime;
mutable boost::mutex fLock;
const std::string fInstallDir;
XMLParser fParser;
xmlDocPtr fDoc;
const std::string fConfigFile;
time_t fMtime;
mutable boost::mutex fLock;
const std::string fInstallDir;
XMLParser fParser;
};

View File

@ -36,34 +36,35 @@ namespace config
{
ConfigStream::ConfigStream(const ByteStream& bs, const string& installDir) :
fParser(installDir)
fParser(installDir)
{
init(reinterpret_cast<const xmlChar*>(bs.buf()));
init(reinterpret_cast<const xmlChar*>(bs.buf()));
}
ConfigStream::ConfigStream(const string& str, const string& installDir) :
fParser(installDir)
fParser(installDir)
{
init(reinterpret_cast<const xmlChar*>(str.c_str()));
init(reinterpret_cast<const xmlChar*>(str.c_str()));
}
ConfigStream::ConfigStream(const char* cptr, const string& installDir) :
fParser(installDir)
fParser(installDir)
{
init(reinterpret_cast<const xmlChar*>(cptr));
init(reinterpret_cast<const xmlChar*>(cptr));
}
ConfigStream::~ConfigStream()
{
if (fDoc != NULL)
xmlFreeDoc(fDoc);
if (fDoc != NULL)
xmlFreeDoc(fDoc);
}
void ConfigStream::init(const xmlChar* xp)
{
fDoc = xmlParseDoc(xp);
if (fDoc == NULL)
throw runtime_error("ConfigStream::ConfigStream: bad XML stream");
fDoc = xmlParseDoc(xp);
if (fDoc == NULL)
throw runtime_error("ConfigStream::ConfigStream: bad XML stream");
}
} //namespace

View File

@ -41,22 +41,24 @@ namespace config
class ConfigStream
{
public:
ConfigStream(const messageqcpp::ByteStream& bs, const std::string& installDir);
ConfigStream(const std::string& str, const std::string& installDir);
ConfigStream(const char* cptr, const std::string& installDir);
~ConfigStream();
ConfigStream(const messageqcpp::ByteStream& bs, const std::string& installDir);
ConfigStream(const std::string& str, const std::string& installDir);
ConfigStream(const char* cptr, const std::string& installDir);
~ConfigStream();
const std::string getConfig(const std::string& section, const std::string& name) const
{ return fParser.getConfig(fDoc, section, name); }
const std::string getConfig(const std::string& section, const std::string& name) const
{
return fParser.getConfig(fDoc, section, name);
}
private:
ConfigStream(const ConfigStream& rhs);
ConfigStream& operator=(const ConfigStream& rhs);
ConfigStream(const ConfigStream& rhs);
ConfigStream& operator=(const ConfigStream& rhs);
void init(const xmlChar* xp);
void init(const xmlChar* xp);
XMLParser fParser;
xmlDocPtr fDoc;
XMLParser fParser;
xmlDocPtr fDoc;
};
} //namespace

View File

@ -7,7 +7,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
@ -148,18 +148,18 @@
# if defined(__POWERPC__)
# define ROTATE(a,n) __rlwinm(a,n,0,31)
# elif defined(__MC68K__)
/* Motorola specific tweak. <appro@fy.chalmers.se> */
/* Motorola specific tweak. <appro@fy.chalmers.se> */
# define ROTATE(a,n) ( n<24 ? __rol(a,n) : __ror(a,32-n) )
# else
# define ROTATE(a,n) __rol(a,n)
# endif
# elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
/*
* Some GNU C inline assembler templates. Note that these are
* rotates by *constant* number of bits! But that's exactly
* what we need here...
* <appro@fy.chalmers.se>
*/
/*
* Some GNU C inline assembler templates. Note that these are
* rotates by *constant* number of bits! But that's exactly
* what we need here...
* <appro@fy.chalmers.se>
*/
# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
# define ROTATE(a,n) ({ register unsigned int ret; \
asm ( \
@ -200,12 +200,12 @@
# if ((defined(__i386) || defined(__i386__)) && !defined(I386_ONLY)) || \
(defined(__x86_64) || defined(__x86_64__))
# if !defined(B_ENDIAN)
/*
* This gives ~30-40% performance improvement in SHA-256 compiled
* with gcc [on P4]. Well, first macro to be frank. We can pull
* this trick on x86* platforms only, because these CPUs can fetch
* unaligned data without raising an exception.
*/
/*
* This gives ~30-40% performance improvement in SHA-256 compiled
* with gcc [on P4]. Well, first macro to be frank. We can pull
* this trick on x86* platforms only, because these CPUs can fetch
* unaligned data without raising an exception.
*/
# define HOST_c2l(c,l) ({ unsigned int r=*((const unsigned int *)(c)); \
asm ("bswapl %0":"=r"(r):"0"(r)); \
(c)+=4; (l)=r; })
@ -252,7 +252,7 @@
#endif
#if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
# ifndef B_ENDIAN
/* See comment in DATA_ORDER_IS_BIG_ENDIAN section. */
/* See comment in DATA_ORDER_IS_BIG_ENDIAN section. */
# define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, l)
# define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, l)
# endif
@ -279,108 +279,114 @@
* Time for some action:-)
*/
int HASH_UPDATE (HASH_CTX *c, const void *data_, size_t len)
{
const unsigned char *data=data_;
unsigned char *p;
HASH_LONG l;
size_t n;
int HASH_UPDATE (HASH_CTX* c, const void* data_, size_t len)
{
const unsigned char* data = data_;
unsigned char* p;
HASH_LONG l;
size_t n;
if (len==0) return 1;
if (len == 0) return 1;
l=(c->Nl+(((HASH_LONG)len)<<3))&0xffffffffUL;
/* 95-05-24 eay Fixed a bug with the overflow handling, thanks to
* Wei Dai <weidai@eskimo.com> for pointing it out. */
if (l < c->Nl) /* overflow */
c->Nh++;
c->Nh+=(HASH_LONG)(len>>29); /* might cause compiler warning on 16-bit */
c->Nl=l;
l = (c->Nl + (((HASH_LONG)len) << 3)) & 0xffffffffUL;
n = c->num;
if (n != 0)
{
p=(unsigned char *)c->data;
/* 95-05-24 eay Fixed a bug with the overflow handling, thanks to
* Wei Dai <weidai@eskimo.com> for pointing it out. */
if (l < c->Nl) /* overflow */
c->Nh++;
if (len >= HASH_CBLOCK || len+n >= HASH_CBLOCK)
{
memcpy (p+n,data,HASH_CBLOCK-n);
HASH_BLOCK_DATA_ORDER (c,p,1);
n = HASH_CBLOCK-n;
data += n;
len -= n;
c->num = 0;
memset (p,0,HASH_CBLOCK); /* keep it zeroed */
}
else
{
memcpy (p+n,data,len);
c->num += (unsigned int)len;
return 1;
}
}
c->Nh += (HASH_LONG)(len >> 29); /* might cause compiler warning on 16-bit */
c->Nl = l;
n = len/HASH_CBLOCK;
if (n > 0)
{
HASH_BLOCK_DATA_ORDER (c,data,n);
n *= HASH_CBLOCK;
data += n;
len -= n;
}
n = c->num;
if (len != 0)
{
p = (unsigned char *)c->data;
c->num = (unsigned int)len;
memcpy (p,data,len);
}
return 1;
}
if (n != 0)
{
p = (unsigned char*)c->data;
if (len >= HASH_CBLOCK || len + n >= HASH_CBLOCK)
{
memcpy (p + n, data, HASH_CBLOCK - n);
HASH_BLOCK_DATA_ORDER (c, p, 1);
n = HASH_CBLOCK - n;
data += n;
len -= n;
c->num = 0;
memset (p, 0, HASH_CBLOCK); /* keep it zeroed */
}
else
{
memcpy (p + n, data, len);
c->num += (unsigned int)len;
return 1;
}
}
n = len / HASH_CBLOCK;
if (n > 0)
{
HASH_BLOCK_DATA_ORDER (c, data, n);
n *= HASH_CBLOCK;
data += n;
len -= n;
}
if (len != 0)
{
p = (unsigned char*)c->data;
c->num = (unsigned int)len;
memcpy (p, data, len);
}
return 1;
}
void HASH_TRANSFORM (HASH_CTX *c, const unsigned char *data)
{
HASH_BLOCK_DATA_ORDER (c,data,1);
}
void HASH_TRANSFORM (HASH_CTX* c, const unsigned char* data)
{
HASH_BLOCK_DATA_ORDER (c, data, 1);
}
int HASH_FINAL (unsigned char *md, HASH_CTX *c)
{
unsigned char *p = (unsigned char *)c->data;
size_t n = c->num;
int HASH_FINAL (unsigned char* md, HASH_CTX* c)
{
unsigned char* p = (unsigned char*)c->data;
size_t n = c->num;
p[n] = 0x80; /* there is always room for one */
n++;
p[n] = 0x80; /* there is always room for one */
n++;
if (n > (HASH_CBLOCK-8))
{
memset (p+n,0,HASH_CBLOCK-n);
n=0;
HASH_BLOCK_DATA_ORDER (c,p,1);
}
memset (p+n,0,HASH_CBLOCK-8-n);
if (n > (HASH_CBLOCK - 8))
{
memset (p + n, 0, HASH_CBLOCK - n);
n = 0;
HASH_BLOCK_DATA_ORDER (c, p, 1);
}
p += HASH_CBLOCK-8;
memset (p + n, 0, HASH_CBLOCK - 8 - n);
p += HASH_CBLOCK - 8;
#if defined(DATA_ORDER_IS_BIG_ENDIAN)
(void)HOST_l2c(c->Nh,p);
(void)HOST_l2c(c->Nl,p);
(void)HOST_l2c(c->Nh, p);
(void)HOST_l2c(c->Nl, p);
#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
(void)HOST_l2c(c->Nl,p);
(void)HOST_l2c(c->Nh,p);
(void)HOST_l2c(c->Nl, p);
(void)HOST_l2c(c->Nh, p);
#endif
p -= HASH_CBLOCK;
HASH_BLOCK_DATA_ORDER (c,p,1);
c->num=0;
memset (p,0,HASH_CBLOCK);
p -= HASH_CBLOCK;
HASH_BLOCK_DATA_ORDER (c, p, 1);
c->num = 0;
memset (p, 0, HASH_CBLOCK);
#ifndef HASH_MAKE_STRING
#error "HASH_MAKE_STRING must be defined!"
#else
HASH_MAKE_STRING(c,md);
HASH_MAKE_STRING(c, md);
#endif
return 1;
}
return 1;
}
#ifndef MD32_REG_T
#if defined(__alpha) || defined(__sparcv9) || defined(__mips)
@ -398,7 +404,7 @@ int HASH_FINAL (unsigned char *md, HASH_CTX *c)
* *either* case. Now declaring 'em long excuses the compiler
* from keeping 32 MSBs zeroed resulting in 13% performance
* improvement under SPARC Solaris7/64 and 5% under AlphaLinux.
* Well, to be honest it should say that this *prevents*
* Well, to be honest it should say that this *prevents*
* performance degradation.
* <appro@fy.chalmers.se>
*/

View File

@ -5,21 +5,21 @@
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@ -34,10 +34,10 @@
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@ -49,7 +49,7 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
@ -97,18 +97,18 @@ extern "C" {
#define MD5_DIGEST_LENGTH 16
typedef struct MD5state_st
{
MD5_LONG A,B,C,D;
MD5_LONG Nl,Nh;
MD5_LONG data[MD5_LBLOCK];
unsigned int num;
} MD5_CTX;
{
MD5_LONG A, B, C, D;
MD5_LONG Nl, Nh;
MD5_LONG data[MD5_LBLOCK];
unsigned int num;
} MD5_CTX;
int MD5_Init(MD5_CTX *c);
int MD5_Update(MD5_CTX *c, const void *data, size_t len);
int MD5_Final(unsigned char *md, MD5_CTX *c);
unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md);
void MD5_Transform(MD5_CTX *c, const unsigned char *b);
int MD5_Init(MD5_CTX* c);
int MD5_Update(MD5_CTX* c, const void* data, size_t len);
int MD5_Final(unsigned char* md, MD5_CTX* c);
unsigned char* MD5(const unsigned char* d, size_t n, unsigned char* md);
void MD5_Transform(MD5_CTX* c, const unsigned char* b);
#ifdef __cplusplus
}
#endif

View File

@ -5,21 +5,21 @@
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@ -34,10 +34,10 @@
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@ -49,7 +49,7 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
@ -76,7 +76,7 @@
# endif
#endif
void md5_block_data_order (MD5_CTX *c, const void *p,size_t num);
void md5_block_data_order (MD5_CTX* c, const void* p, size_t num);
#define DATA_ORDER_IS_LITTLE_ENDIAN

View File

@ -1,14 +1,14 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by libconfigcpp.rc
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 101
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by libconfigcpp.rc
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 101
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@ -37,322 +37,341 @@ using namespace messageqcpp;
#include "configstream.h"
using namespace config;
class ConfigFileTest : public CppUnit::TestFixture {
class ConfigFileTest : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE( ConfigFileTest );
CPPUNIT_TEST_SUITE( ConfigFileTest );
CPPUNIT_TEST( test1 );
CPPUNIT_TEST( test1 );
CPPUNIT_TEST_EXCEPTION( test2, std::runtime_error );
CPPUNIT_TEST( test3 );
CPPUNIT_TEST( test4 );
CPPUNIT_TEST_EXCEPTION( test5, std::runtime_error );
CPPUNIT_TEST_EXCEPTION( test6, std::runtime_error );
CPPUNIT_TEST_EXCEPTION( test7, std::invalid_argument );
CPPUNIT_TEST_EXCEPTION( test8, std::invalid_argument );
CPPUNIT_TEST( test9 );
CPPUNIT_TEST( test10 );
CPPUNIT_TEST( test11 );
CPPUNIT_TEST( test12 );
CPPUNIT_TEST_EXCEPTION( test13_1, std::runtime_error );
CPPUNIT_TEST_EXCEPTION( test13_2, std::runtime_error );
CPPUNIT_TEST( test14 );
CPPUNIT_TEST_SUITE_END();
CPPUNIT_TEST_EXCEPTION( test2, std::runtime_error );
CPPUNIT_TEST( test3 );
CPPUNIT_TEST( test4 );
CPPUNIT_TEST_EXCEPTION( test5, std::runtime_error );
CPPUNIT_TEST_EXCEPTION( test6, std::runtime_error );
CPPUNIT_TEST_EXCEPTION( test7, std::invalid_argument );
CPPUNIT_TEST_EXCEPTION( test8, std::invalid_argument );
CPPUNIT_TEST( test9 );
CPPUNIT_TEST( test10 );
CPPUNIT_TEST( test11 );
CPPUNIT_TEST( test12 );
CPPUNIT_TEST_EXCEPTION( test13_1, std::runtime_error );
CPPUNIT_TEST_EXCEPTION( test13_2, std::runtime_error );
CPPUNIT_TEST( test14 );
CPPUNIT_TEST_SUITE_END();
private:
public:
void setUp() {
}
void setUp()
{
}
void tearDown() {
}
void tearDown()
{
}
void test1() {
Config* c1 = Config::makeConfig("./Columnstore.xml");
string value;
value = c1->getConfig("Message", "Name");
CPPUNIT_ASSERT(value == "Message");
void test1()
{
Config* c1 = Config::makeConfig("./Columnstore.xml");
string value;
value = c1->getConfig("Message", "Name");
CPPUNIT_ASSERT(value == "Message");
value = c1->getConfig("Message", "xName");
CPPUNIT_ASSERT(value.size() == 0);
Config::deleteInstanceMap();
}
value = c1->getConfig("Message", "xName");
CPPUNIT_ASSERT(value.size() == 0);
Config::deleteInstanceMap();
}
void test2() {
Config* c1 = Config::makeConfig("./yadayada.xml");
string value;
void test2()
{
Config* c1 = Config::makeConfig("./yadayada.xml");
string value;
value = c1->getConfig("Message", "Name");
CPPUNIT_ASSERT(value.size() == 0);
value = c1->getConfig("Message", "Name");
CPPUNIT_ASSERT(value.size() == 0);
value = c1->getConfig("Message", "xName");
CPPUNIT_ASSERT(value.size() == 0);
value = c1->getConfig("Message", "xName");
CPPUNIT_ASSERT(value.size() == 0);
Config::deleteInstanceMap();
}
Config::deleteInstanceMap();
}
void test3() {
Config* c1;
string value;
void test3()
{
Config* c1;
string value;
for (int i = 0; i < 1000; i++)
{
c1 = Config::makeConfig("./Columnstore.xml");
value = c1->getConfig("Message", "Name");
assert(value == "Message");
}
Config::deleteInstanceMap();
}
for (int i = 0; i < 1000; i++)
{
c1 = Config::makeConfig("./Columnstore.xml");
value = c1->getConfig("Message", "Name");
assert(value == "Message");
}
void test4() {
Config* c1 = Config::makeConfig("./Columnstore.xml");
string value;
Config::deleteInstanceMap();
}
value = c1->getConfig("SystemConfig", "SystemVersion");
c1->setConfig("SystemConfig", "SystemVersion", "2.2.versionversionversion");
value = c1->getConfig("SystemConfig", "SystemVersion");
CPPUNIT_ASSERT(value == "2.2.versionversionversion");
void test4()
{
Config* c1 = Config::makeConfig("./Columnstore.xml");
string value;
::unlink("./Columnstore.xml.new");
c1->write("./Columnstore.xml.new");
value = c1->getConfig("SystemConfig", "SystemVersion");
c1->setConfig("SystemConfig", "SystemVersion", "2.2.versionversionversion");
value = c1->getConfig("SystemConfig", "SystemVersion");
CPPUNIT_ASSERT(value == "2.2.versionversionversion");
value = c1->getConfig("SystemConfig", "SystemVersion");
CPPUNIT_ASSERT(value == "2.2.versionversionversion");
::unlink("./Columnstore.xml.new");
c1->write("./Columnstore.xml.new");
c1->setConfig("SystemConfig", "SystemVersion1", "V1.x");
value = c1->getConfig("SystemConfig", "SystemVersion1");
CPPUNIT_ASSERT(value == "V1.x");
value = c1->getConfig("SystemConfig", "SystemVersion");
CPPUNIT_ASSERT(value == "2.2.versionversionversion");
c1->setConfig("SystemConfig1", "SystemVersion1", "Vx.x");
value = c1->getConfig("SystemConfig1", "SystemVersion1");
CPPUNIT_ASSERT(value == "Vx.x");
c1->setConfig("SystemConfig", "SystemVersion1", "V1.x");
value = c1->getConfig("SystemConfig", "SystemVersion1");
CPPUNIT_ASSERT(value == "V1.x");
c1->write("./Columnstore.xml.new");
Config* c2 = Config::makeConfig("./Columnstore.xml.new");
value = c2->getConfig("SystemConfig1", "SystemVersion1");
CPPUNIT_ASSERT(value == "Vx.x");
c2->setConfig("SystemConfig", "SystemVersion1", "V1.1");
value = c2->getConfig("SystemConfig", "SystemVersion1");
CPPUNIT_ASSERT(value == "V1.1");
c2->write();
Config::deleteInstanceMap();
}
c1->setConfig("SystemConfig1", "SystemVersion1", "Vx.x");
value = c1->getConfig("SystemConfig1", "SystemVersion1");
CPPUNIT_ASSERT(value == "Vx.x");
void test5() {
Config* c1 = Config::makeConfig("./Columnstore.xml");
c1->write("/cantwritethis");
Config::deleteInstanceMap();
}
c1->write("./Columnstore.xml.new");
Config* c2 = Config::makeConfig("./Columnstore.xml.new");
value = c2->getConfig("SystemConfig1", "SystemVersion1");
CPPUNIT_ASSERT(value == "Vx.x");
c2->setConfig("SystemConfig", "SystemVersion1", "V1.1");
value = c2->getConfig("SystemConfig", "SystemVersion1");
CPPUNIT_ASSERT(value == "V1.1");
c2->write();
Config::deleteInstanceMap();
}
void test6() {
Config* c1 = Config::makeConfig("./XColumnstore.xml");
// compiler warning...we won't actually get here
c1 = 0;
}
void test5()
{
Config* c1 = Config::makeConfig("./Columnstore.xml");
c1->write("/cantwritethis");
Config::deleteInstanceMap();
}
void test7() {
Config* c1 = Config::makeConfig("./Columnstore.xml");
string s;
string n;
string v;
c1->setConfig(s, n, v);
Config::deleteInstanceMap();
}
void test6()
{
Config* c1 = Config::makeConfig("./XColumnstore.xml");
// compiler warning...we won't actually get here
c1 = 0;
}
void test8() {
Config* c1 = Config::makeConfig("./Columnstore.xml");
string s;
string n;
string v;
v = c1->getConfig(s, n);
Config::deleteInstanceMap();
}
void test7()
{
Config* c1 = Config::makeConfig("./Columnstore.xml");
string s;
string n;
string v;
c1->setConfig(s, n, v);
Config::deleteInstanceMap();
}
void test9() {
string value;
void test8()
{
Config* c1 = Config::makeConfig("./Columnstore.xml");
string s;
string n;
string v;
v = c1->getConfig(s, n);
Config::deleteInstanceMap();
}
Config* c1 = Config::makeConfig("./Columnstore.xml");
Config* c2 = Config::makeConfig("./Columnstore.xml.new");
void test9()
{
string value;
value = c1->getConfig("Message", "Name");
CPPUNIT_ASSERT(value == "Message");
Config* c1 = Config::makeConfig("./Columnstore.xml");
Config* c2 = Config::makeConfig("./Columnstore.xml.new");
value = c2->getConfig("SystemConfig", "SystemVersion1");
CPPUNIT_ASSERT(value == "V1.1");
Config::deleteInstanceMap();
}
value = c1->getConfig("Message", "Name");
CPPUNIT_ASSERT(value == "Message");
void test10() {
string value;
value = c2->getConfig("SystemConfig", "SystemVersion1");
CPPUNIT_ASSERT(value == "V1.1");
Config::deleteInstanceMap();
}
setenv("CALPONT_CONFIG_FILE", "./Columnstore.xml", 1);
Config* c1 = Config::makeConfig();
void test10()
{
string value;
value = c1->getConfig("Message", "Name");
CPPUNIT_ASSERT(value == "Message");
Config::deleteInstanceMap();
setenv("CALPONT_CONFIG_FILE", "./Columnstore.xml", 1);
Config* c1 = Config::makeConfig();
}
value = c1->getConfig("Message", "Name");
CPPUNIT_ASSERT(value == "Message");
Config::deleteInstanceMap();
void test11() {
string value;
struct stat stat_buf;
struct utimbuf utime_buf;
}
CPPUNIT_ASSERT(stat("./Columnstore.xml.new", &stat_buf) == 0);
void test11()
{
string value;
struct stat stat_buf;
struct utimbuf utime_buf;
Config* c1 = Config::makeConfig("./Columnstore.xml.new");
CPPUNIT_ASSERT(stat("./Columnstore.xml.new", &stat_buf) == 0);
value = c1->getConfig("Message", "Name");
CPPUNIT_ASSERT(value == "Message");
Config* c1 = Config::makeConfig("./Columnstore.xml.new");
utime_buf.actime = utime_buf.modtime = stat_buf.st_mtime + 1;
CPPUNIT_ASSERT(utime("./Columnstore.xml.new", &utime_buf) == 0);
value = c1->getConfig("Message", "Name");
CPPUNIT_ASSERT(value == "Message");
value = c1->getConfig("Message", "Name");
CPPUNIT_ASSERT(value == "Message");
Config::deleteInstanceMap();
}
utime_buf.actime = utime_buf.modtime = stat_buf.st_mtime + 1;
CPPUNIT_ASSERT(utime("./Columnstore.xml.new", &utime_buf) == 0);
void test12() {
string value;
int64_t ival;
uint64_t uval;
value = c1->getConfig("Message", "Name");
CPPUNIT_ASSERT(value == "Message");
Config::deleteInstanceMap();
}
value = "10";
ival = Config::fromText(value);
CPPUNIT_ASSERT(ival == 10);
uval = Config::uFromText(value);
CPPUNIT_ASSERT(uval == 10);
void test12()
{
string value;
int64_t ival;
uint64_t uval;
value = "0x10";
ival = Config::fromText(value);
CPPUNIT_ASSERT(ival == 0x10);
uval = Config::uFromText(value);
CPPUNIT_ASSERT(uval == 0x10);
value = "10";
ival = Config::fromText(value);
CPPUNIT_ASSERT(ival == 10);
uval = Config::uFromText(value);
CPPUNIT_ASSERT(uval == 10);
value = "010";
ival = Config::fromText(value);
CPPUNIT_ASSERT(ival == 010);
uval = Config::uFromText(value);
CPPUNIT_ASSERT(uval == 010);
value = "0x10";
ival = Config::fromText(value);
CPPUNIT_ASSERT(ival == 0x10);
uval = Config::uFromText(value);
CPPUNIT_ASSERT(uval == 0x10);
value = "-10";
ival = Config::fromText(value);
CPPUNIT_ASSERT(ival == -10);
value = "010";
ival = Config::fromText(value);
CPPUNIT_ASSERT(ival == 010);
uval = Config::uFromText(value);
CPPUNIT_ASSERT(uval == 010);
value = "10K";
ival = Config::fromText(value);
CPPUNIT_ASSERT(ival == (10 * 1024));
uval = Config::uFromText(value);
CPPUNIT_ASSERT(uval == (10 * 1024));
value = "-10";
ival = Config::fromText(value);
CPPUNIT_ASSERT(ival == -10);
value = "10k";
ival = Config::fromText(value);
CPPUNIT_ASSERT(ival == (10 * 1024));
uval = Config::uFromText(value);
CPPUNIT_ASSERT(uval == (10 * 1024));
value = "10K";
ival = Config::fromText(value);
CPPUNIT_ASSERT(ival == (10 * 1024));
uval = Config::uFromText(value);
CPPUNIT_ASSERT(uval == (10 * 1024));
value = "10M";
ival = Config::fromText(value);
CPPUNIT_ASSERT(ival == (10 * 1024 * 1024));
uval = Config::uFromText(value);
CPPUNIT_ASSERT(uval == (10 * 1024 * 1024));
value = "10k";
ival = Config::fromText(value);
CPPUNIT_ASSERT(ival == (10 * 1024));
uval = Config::uFromText(value);
CPPUNIT_ASSERT(uval == (10 * 1024));
value = "10m";
ival = Config::fromText(value);
CPPUNIT_ASSERT(ival == (10 * 1024 * 1024));
uval = Config::uFromText(value);
CPPUNIT_ASSERT(uval == (10 * 1024 * 1024));
value = "10M";
ival = Config::fromText(value);
CPPUNIT_ASSERT(ival == (10 * 1024 * 1024));
uval = Config::uFromText(value);
CPPUNIT_ASSERT(uval == (10 * 1024 * 1024));
value = "10G";
ival = Config::fromText(value);
CPPUNIT_ASSERT(ival == (10 * 1024 * 1024 * 1024LL));
uval = Config::uFromText(value);
CPPUNIT_ASSERT(uval == (10 * 1024 * 1024 * 1024ULL));
value = "10m";
ival = Config::fromText(value);
CPPUNIT_ASSERT(ival == (10 * 1024 * 1024));
uval = Config::uFromText(value);
CPPUNIT_ASSERT(uval == (10 * 1024 * 1024));
value = "10g";
ival = Config::fromText(value);
CPPUNIT_ASSERT(ival == (10 * 1024 * 1024 * 1024LL));
uval = Config::uFromText(value);
CPPUNIT_ASSERT(uval == (10 * 1024 * 1024 * 1024ULL));
value = "10G";
ival = Config::fromText(value);
CPPUNIT_ASSERT(ival == (10 * 1024 * 1024 * 1024LL));
uval = Config::uFromText(value);
CPPUNIT_ASSERT(uval == (10 * 1024 * 1024 * 1024ULL));
value = "10MB";
ival = Config::fromText(value);
CPPUNIT_ASSERT(ival == (10 * 1024 * 1024));
uval = Config::uFromText(value);
CPPUNIT_ASSERT(uval == (10 * 1024 * 1024));
value = "10g";
ival = Config::fromText(value);
CPPUNIT_ASSERT(ival == (10 * 1024 * 1024 * 1024LL));
uval = Config::uFromText(value);
CPPUNIT_ASSERT(uval == (10 * 1024 * 1024 * 1024ULL));
value = "0x7afafafafafafafa";
ival = Config::fromText(value);
CPPUNIT_ASSERT(ival == 0x7afafafafafafafaLL);
uval = Config::uFromText(value);
CPPUNIT_ASSERT(uval == 0x7afafafafafafafaULL);
value = "10MB";
ival = Config::fromText(value);
CPPUNIT_ASSERT(ival == (10 * 1024 * 1024));
uval = Config::uFromText(value);
CPPUNIT_ASSERT(uval == (10 * 1024 * 1024));
value = "-0x7afafafafafafafa";
uval = Config::uFromText(value);
CPPUNIT_ASSERT(uval == 0x8505050505050506ULL);
value = "0x7afafafafafafafa";
ival = Config::fromText(value);
CPPUNIT_ASSERT(ival == 0x7afafafafafafafaLL);
uval = Config::uFromText(value);
CPPUNIT_ASSERT(uval == 0x7afafafafafafafaULL);
value = "-1";
uval = Config::uFromText(value);
CPPUNIT_ASSERT(uval == 0xffffffffffffffffULL);
value = "-0x7afafafafafafafa";
uval = Config::uFromText(value);
CPPUNIT_ASSERT(uval == 0x8505050505050506ULL);
}
value = "-1";
uval = Config::uFromText(value);
CPPUNIT_ASSERT(uval == 0xffffffffffffffffULL);
void test13_1() {
string value;
int64_t ival;
}
value = "2.2MB"; //invalid char causes throw
ival = Config::fromText(value);
}
void test13_1()
{
string value;
int64_t ival;
void test13_2() {
string value;
int64_t ival;
value = "2.2MB"; //invalid char causes throw
ival = Config::fromText(value);
}
value = "10,000"; //invalid char causes throw
ival = Config::fromText(value);
}
void test13_2()
{
string value;
int64_t ival;
void test14() {
ByteStream bs;
ifstream ifs("./Columnstore.xml");
ifs >> bs;
string id(".");
string value;
{
ConfigStream cs(bs, id);
value = cs.getConfig("Message", "Name");
CPPUNIT_ASSERT(value == "Message");
}
string bss(reinterpret_cast<const char*>(bs.buf()), bs.length());
{
ConfigStream cs(bss, id);
value = cs.getConfig("Message", "Name");
CPPUNIT_ASSERT(value == "Message");
}
{
ConfigStream cs(bss.c_str(), id);
value = cs.getConfig("Message", "Name");
CPPUNIT_ASSERT(value == "Message");
}
}
value = "10,000"; //invalid char causes throw
ival = Config::fromText(value);
}
};
void test14()
{
ByteStream bs;
ifstream ifs("./Columnstore.xml");
ifs >> bs;
string id(".");
string value;
{
ConfigStream cs(bs, id);
value = cs.getConfig("Message", "Name");
CPPUNIT_ASSERT(value == "Message");
}
string bss(reinterpret_cast<const char*>(bs.buf()), bs.length());
{
ConfigStream cs(bss, id);
value = cs.getConfig("Message", "Name");
CPPUNIT_ASSERT(value == "Message");
}
{
ConfigStream cs(bss.c_str(), id);
value = cs.getConfig("Message", "Name");
CPPUNIT_ASSERT(value == "Message");
}
}
};
CPPUNIT_TEST_SUITE_REGISTRATION( ConfigFileTest );
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/ui/text/TestRunner.h>
int main( int argc, char **argv)
int main( int argc, char** argv)
{
CppUnit::TextUi::TestRunner runner;
CppUnit::TestFactoryRegistry &registry = CppUnit::TestFactoryRegistry::getRegistry();
runner.addTest( registry.makeTest() );
bool wasSuccessful = runner.run( "", false );
return (wasSuccessful ? 0 : 1);
CppUnit::TextUi::TestRunner runner;
CppUnit::TestFactoryRegistry& registry = CppUnit::TestFactoryRegistry::getRegistry();
runner.addTest( registry.makeTest() );
bool wasSuccessful = runner.run( "", false );
return (wasSuccessful ? 0 : 1);
}

View File

@ -38,86 +38,94 @@ namespace
const string cf("./woparms.dat");
}
class WOConfigFileTest : public CppUnit::TestFixture {
class WOConfigFileTest : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE( WOConfigFileTest );
CPPUNIT_TEST_SUITE( WOConfigFileTest );
CPPUNIT_TEST( test1 );
CPPUNIT_TEST_EXCEPTION( test2, std::runtime_error );
CPPUNIT_TEST_EXCEPTION( test3, std::runtime_error );
CPPUNIT_TEST_EXCEPTION( test4, std::runtime_error );
CPPUNIT_TEST( test5 );
CPPUNIT_TEST( test1 );
CPPUNIT_TEST_EXCEPTION( test2, std::runtime_error );
CPPUNIT_TEST_EXCEPTION( test3, std::runtime_error );
CPPUNIT_TEST_EXCEPTION( test4, std::runtime_error );
CPPUNIT_TEST( test5 );
CPPUNIT_TEST_SUITE_END();
CPPUNIT_TEST_SUITE_END();
private:
public:
void setUp() {
unlink(cf.c_str());
}
void setUp()
{
unlink(cf.c_str());
}
void tearDown() {
unlink(cf.c_str());
}
void tearDown()
{
unlink(cf.c_str());
}
void test1() {
WriteOnceConfig woc(cf);
CPPUNIT_ASSERT(woc.owns("PrimitiveServers", "LBID_Shift"));
CPPUNIT_ASSERT(woc.owns("SystemConfig", "DBRootCount"));
CPPUNIT_ASSERT(woc.owns("SystemConfig", "DBRMRoot"));
void test1()
{
WriteOnceConfig woc(cf);
CPPUNIT_ASSERT(woc.owns("PrimitiveServers", "LBID_Shift"));
CPPUNIT_ASSERT(woc.owns("SystemConfig", "DBRootCount"));
CPPUNIT_ASSERT(woc.owns("SystemConfig", "DBRMRoot"));
CPPUNIT_ASSERT(!woc.owns("dummy", "dummy"));
CPPUNIT_ASSERT(!woc.owns("dummy", "dummy"));
int vali;
int vali;
vali = Config::fromText(woc.getConfig("PrimitiveServers", "LBID_Shift"));
CPPUNIT_ASSERT(vali == 13);
vali = Config::fromText(woc.getConfig("PrimitiveServers", "LBID_Shift"));
CPPUNIT_ASSERT(vali == 13);
woc.setConfig("SystemConfig", "DBRootCount", "10");
vali = Config::fromText(woc.getConfig("SystemConfig", "DBRootCount"));
CPPUNIT_ASSERT(vali == 10);
woc.setConfig("SystemConfig", "DBRootCount", "10");
vali = Config::fromText(woc.getConfig("SystemConfig", "DBRootCount"));
CPPUNIT_ASSERT(vali == 10);
WriteOnceConfig woc2(cf.c_str());
vali = Config::fromText(woc2.getConfig("SystemConfig", "DBRootCount"));
CPPUNIT_ASSERT(vali == 10);
}
WriteOnceConfig woc2(cf.c_str());
vali = Config::fromText(woc2.getConfig("SystemConfig", "DBRootCount"));
CPPUNIT_ASSERT(vali == 10);
}
void test2() {
WriteOnceConfig woc(cf);
woc.getConfig("dummy", "dummy");
}
void test2()
{
WriteOnceConfig woc(cf);
woc.getConfig("dummy", "dummy");
}
void test3() {
WriteOnceConfig woc(cf);
woc.setConfig("dummy", "dummy", "100");
}
void test3()
{
WriteOnceConfig woc(cf);
woc.setConfig("dummy", "dummy", "100");
}
void test4() {
WriteOnceConfig woc(cf);
woc.setConfig("SystemConfig", "DBRootCount", "10");
woc.setConfig("SystemConfig", "DBRootCount", "11");
}
void test4()
{
WriteOnceConfig woc(cf);
woc.setConfig("SystemConfig", "DBRootCount", "10");
woc.setConfig("SystemConfig", "DBRootCount", "11");
}
void test5() {
WriteOnceConfig woc(cf);
woc.setConfig("SystemConfig", "DBRootCount", "10");
woc.setConfig("SystemConfig", "DBRootCount", "11", true);
}
void test5()
{
WriteOnceConfig woc(cf);
woc.setConfig("SystemConfig", "DBRootCount", "10");
woc.setConfig("SystemConfig", "DBRootCount", "11", true);
}
};
};
CPPUNIT_TEST_SUITE_REGISTRATION( WOConfigFileTest );
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/ui/text/TestRunner.h>
int main( int argc, char **argv)
int main( int argc, char** argv)
{
CppUnit::TextUi::TestRunner runner;
CppUnit::TestFactoryRegistry &registry = CppUnit::TestFactoryRegistry::getRegistry();
runner.addTest( registry.makeTest() );
bool wasSuccessful = runner.run( "", false );
return (wasSuccessful ? 0 : 1);
CppUnit::TextUi::TestRunner runner;
CppUnit::TestFactoryRegistry& registry = CppUnit::TestFactoryRegistry::getRegistry();
runner.addTest( registry.makeTest() );
bool wasSuccessful = runner.run( "", false );
return (wasSuccessful ? 0 : 1);
}

View File

@ -1,8 +1,8 @@
#ifndef VERSIONNUMBER_H_
#define VERSIONNUMBER_H_
#include <string>
const std::string idb_version("4.6");
const std::string idb_release("0");
#endif
#ifndef VERSIONNUMBER_H_
#define VERSIONNUMBER_H_
#include <string>
const std::string idb_version("4.6");
const std::string idb_release("0");
#endif

View File

@ -50,68 +50,75 @@ namespace config
void WriteOnceConfig::initializeDefaults()
{
fLBID_Shift = make_pair("13", false);
fDBRootCount = make_pair("1", false);
fDBRMRoot = make_pair("/mnt/OAM/dbrm/BRM_saves", false);
fSharedMemoryTmpFile1 = make_pair("/tmp/CalpontShm,", false);
fTxnIDFile = make_pair("/mnt/OAM/dbrm/SMTxnID", false);
fSharedMemoryTmpFile2 = make_pair("/tmp/CalpontSessionMonitorShm", false);
fLBID_Shift = make_pair("13", false);
fDBRootCount = make_pair("1", false);
fDBRMRoot = make_pair("/mnt/OAM/dbrm/BRM_saves", false);
fSharedMemoryTmpFile1 = make_pair("/tmp/CalpontShm,", false);
fTxnIDFile = make_pair("/mnt/OAM/dbrm/SMTxnID", false);
fSharedMemoryTmpFile2 = make_pair("/tmp/CalpontSessionMonitorShm", false);
}
void WriteOnceConfig::setup()
{
typedef EntryMap_t::value_type VT;
typedef EntryMap_t::value_type VT;
fEntryMap.insert(VT("PrimitiveServers.LBID_Shift", &fLBID_Shift));
fEntryMap.insert(VT("SystemConfig.DBRootCount", &fDBRootCount));
fEntryMap.insert(VT("SystemConfig.DBRMRoot", &fDBRMRoot));
fEntryMap.insert(VT("SessionManager.SharedMemoryTmpFile", &fSharedMemoryTmpFile1));
fEntryMap.insert(VT("SessionManager.TxnIDFile", &fTxnIDFile));
fEntryMap.insert(VT("SessionMonitor.SharedMemoryTmpFile", &fSharedMemoryTmpFile2));
fEntryMap.insert(VT("PrimitiveServers.LBID_Shift", &fLBID_Shift));
fEntryMap.insert(VT("SystemConfig.DBRootCount", &fDBRootCount));
fEntryMap.insert(VT("SystemConfig.DBRMRoot", &fDBRMRoot));
fEntryMap.insert(VT("SessionManager.SharedMemoryTmpFile", &fSharedMemoryTmpFile1));
fEntryMap.insert(VT("SessionManager.TxnIDFile", &fTxnIDFile));
fEntryMap.insert(VT("SessionMonitor.SharedMemoryTmpFile", &fSharedMemoryTmpFile2));
ByteStream ibs = load();
if (ibs.length() > 0)
unserialize(ibs);
else
initializeDefaults();
ByteStream ibs = load();
if (ibs.length() > 0)
unserialize(ibs);
else
initializeDefaults();
}
void WriteOnceConfig::serialize(ByteStream& obs) const
{
obs << WriteOnceConfigVersion;
obs << WriteOnceConfigVersion;
obs << fLBID_Shift.first;
obs << fDBRootCount.first;
obs << fDBRMRoot.first;
obs << fSharedMemoryTmpFile1.first;
obs << fTxnIDFile.first;
obs << fSharedMemoryTmpFile2.first;
obs << fLBID_Shift.first;
obs << fDBRootCount.first;
obs << fDBRMRoot.first;
obs << fSharedMemoryTmpFile1.first;
obs << fTxnIDFile.first;
obs << fSharedMemoryTmpFile2.first;
}
void WriteOnceConfig::unserialize(ByteStream& ibs)
{
uint32_t version;
ibs >> version;
uint32_t version;
ibs >> version;
if (version < WriteOnceConfigVersion)
{
ostringstream oss;
oss << "Invalid version found in WriteOnceConfig file: " << version;
throw runtime_error(oss.str().c_str());
}
else if (version > WriteOnceConfigVersion)
{
ostringstream oss;
oss << "Invalid version found in WriteOnceConfig file: " << version;
throw runtime_error(oss.str().c_str());
}
if (version < WriteOnceConfigVersion)
{
ostringstream oss;
oss << "Invalid version found in WriteOnceConfig file: " << version;
throw runtime_error(oss.str().c_str());
}
else if (version > WriteOnceConfigVersion)
{
ostringstream oss;
oss << "Invalid version found in WriteOnceConfig file: " << version;
throw runtime_error(oss.str().c_str());
}
ibs >> fLBID_Shift.first; fLBID_Shift.second = true;
ibs >> fDBRootCount.first; fDBRootCount.second = true;
ibs >> fDBRMRoot.first; fDBRMRoot.second = true;
ibs >> fSharedMemoryTmpFile1.first; fSharedMemoryTmpFile1.second = true;
ibs >> fTxnIDFile.first; fTxnIDFile.second = true;
ibs >> fSharedMemoryTmpFile2.first; fSharedMemoryTmpFile2.second = true;
ibs >> fLBID_Shift.first;
fLBID_Shift.second = true;
ibs >> fDBRootCount.first;
fDBRootCount.second = true;
ibs >> fDBRMRoot.first;
fDBRMRoot.second = true;
ibs >> fSharedMemoryTmpFile1.first;
fSharedMemoryTmpFile1.second = true;
ibs >> fTxnIDFile.first;
fTxnIDFile.second = true;
ibs >> fSharedMemoryTmpFile2.first;
fSharedMemoryTmpFile2.second = true;
}
@ -119,95 +126,102 @@ void WriteOnceConfig::unserialize(ByteStream& ibs)
ByteStream WriteOnceConfig::load()
{
ByteStream bs;
if (access(fConfigFileName.c_str(), F_OK) != 0)
{
initializeDefaults();
return bs;
}
ByteStream bs;
idbassert(access(fConfigFileName.c_str(), F_OK) == 0);
if (access(fConfigFileName.c_str(), F_OK) != 0)
{
initializeDefaults();
return bs;
}
ifstream ifs(fConfigFileName.c_str());
int e = errno;
if (!ifs.good())
{
ostringstream oss;
oss << "Error opening WriteOnceConfig file " << fConfigFileName << ": " << strerror(e);
throw runtime_error(oss.str().c_str());
}
ifs >> bs;
return bs;
idbassert(access(fConfigFileName.c_str(), F_OK) == 0);
ifstream ifs(fConfigFileName.c_str());
int e = errno;
if (!ifs.good())
{
ostringstream oss;
oss << "Error opening WriteOnceConfig file " << fConfigFileName << ": " << strerror(e);
throw runtime_error(oss.str().c_str());
}
ifs >> bs;
return bs;
}
void WriteOnceConfig::save(ByteStream& ibs) const
{
ofstream ofs(fConfigFileName.c_str());
int e = errno;
if (!ofs.good())
{
ostringstream oss;
oss << "Error opening WriteOnceConfig file " << fConfigFileName << ": " << strerror(e);
throw runtime_error(oss.str().c_str());
}
ofs << ibs;
ofstream ofs(fConfigFileName.c_str());
int e = errno;
if (!ofs.good())
{
ostringstream oss;
oss << "Error opening WriteOnceConfig file " << fConfigFileName << ": " << strerror(e);
throw runtime_error(oss.str().c_str());
}
ofs << ibs;
}
WriteOnceConfig::WriteOnceConfig(const char* cf)
{
string cfs;
string cfs;
if (cf != 0)
cfs = cf;
else
cfs = startup::StartUp::installDir() + "/etc/" + DefaultWriteOnceConfigFilename;
if (cf != 0)
cfs = cf;
else
cfs = startup::StartUp::installDir() + "/etc/" + DefaultWriteOnceConfigFilename;
fConfigFileName = cfs;
fConfigFileName = cfs;
setup();
setup();
}
void WriteOnceConfig::setConfig(const string& section, const string& name, const string& value, bool force)
{
EntryMap_t::iterator iter;
iter = fEntryMap.find(string(section + "." + name));
if (iter == fEntryMap.end())
{
ostringstream oss;
oss << "Invalid request for " << section << '.' << name;
throw runtime_error(oss.str().c_str());
}
EntryMap_t::iterator iter;
iter = fEntryMap.find(string(section + "." + name));
if ((*iter->second).second && !force)
{
ostringstream oss;
oss << "Invalid attempt to write read-only " << section << '.' << name;
throw runtime_error(oss.str().c_str());
}
if (iter == fEntryMap.end())
{
ostringstream oss;
oss << "Invalid request for " << section << '.' << name;
throw runtime_error(oss.str().c_str());
}
(*iter->second).first = value;
(*iter->second).second = true;
if ((*iter->second).second && !force)
{
ostringstream oss;
oss << "Invalid attempt to write read-only " << section << '.' << name;
throw runtime_error(oss.str().c_str());
}
ByteStream obs;
serialize(obs);
save(obs);
(*iter->second).first = value;
(*iter->second).second = true;
ByteStream obs;
serialize(obs);
save(obs);
}
const string WriteOnceConfig::getConfig(const string& section, const string& name) const
{
string val;
EntryMap_t::const_iterator iter;
iter = fEntryMap.find(string(section + "." + name));
if (iter == fEntryMap.end())
{
ostringstream oss;
oss << "Invalid request for " << section << '.' << name;
throw runtime_error(oss.str().c_str());
}
string val;
EntryMap_t::const_iterator iter;
iter = fEntryMap.find(string(section + "." + name));
val = (*iter->second).first;
if (iter == fEntryMap.end())
{
ostringstream oss;
oss << "Invalid request for " << section << '.' << name;
throw runtime_error(oss.str().c_str());
}
return val;
val = (*iter->second).first;
return val;
}
}

View File

@ -36,7 +36,8 @@
#include "bytestream.h"
namespace config {
namespace config
{
/** @brief a write-once config file I/F class
*
@ -45,94 +46,95 @@ namespace config {
class WriteOnceConfig
{
public:
/** @brief ctor
*
*/
explicit WriteOnceConfig(const char* cf=0);
/** @brief ctor
*
*/
explicit WriteOnceConfig(const char* cf = 0);
/** @brief ctor
*
*/
explicit WriteOnceConfig(const std::string& cf) :
fConfigFileName(cf)
{
setup();
}
/** @brief ctor
*
*/
explicit WriteOnceConfig(const std::string& cf) :
fConfigFileName(cf)
{
setup();
}
/** @brief dtor
*
*/
virtual ~WriteOnceConfig() {}
/** @brief dtor
*
*/
virtual ~WriteOnceConfig() {}
/** @brief check if this class owns parm
*
*/
bool owns(const std::string& section, const std::string& name) const {
return (fEntryMap.find(std::string(section + "." + name)) != fEntryMap.end());
}
/** @brief check if this class owns parm
*
*/
bool owns(const std::string& section, const std::string& name) const
{
return (fEntryMap.find(std::string(section + "." + name)) != fEntryMap.end());
}
/** @brief set parm to value
*
* If you attempt to set a value more than once, and force is false, this will throw a runtime_error.
*/
void setConfig(const std::string& section, const std::string& name, const std::string& value, bool force=false);
/** @brief set parm to value
*
* If you attempt to set a value more than once, and force is false, this will throw a runtime_error.
*/
void setConfig(const std::string& section, const std::string& name, const std::string& value, bool force = false);
/** @brief get value of parm
*
*/
const std::string getConfig(const std::string& section, const std::string& name) const;
/** @brief get value of parm
*
*/
const std::string getConfig(const std::string& section, const std::string& name) const;
protected:
/** @brief load from file
*
*/
messageqcpp::ByteStream load();
/** @brief load from file
*
*/
messageqcpp::ByteStream load();
/** @brief save to file
*
*/
void save(messageqcpp::ByteStream& ibs) const;
/** @brief save to file
*
*/
void save(messageqcpp::ByteStream& ibs) const;
/** @brief serialize to ByteStream
*
*/
virtual void serialize(messageqcpp::ByteStream& obs) const;
/** @brief serialize to ByteStream
*
*/
virtual void serialize(messageqcpp::ByteStream& obs) const;
/** @brief load from ByteStream
*
*/
virtual void unserialize(messageqcpp::ByteStream& ibs);
/** @brief load from ByteStream
*
*/
virtual void unserialize(messageqcpp::ByteStream& ibs);
private:
typedef std::pair<std::string, bool> ConfigItem_t;
typedef std::tr1::unordered_map<std::string, ConfigItem_t*> EntryMap_t;
typedef std::pair<std::string, bool> ConfigItem_t;
typedef std::tr1::unordered_map<std::string, ConfigItem_t*> EntryMap_t;
static const uint32_t WriteOnceConfigVersion = 1;
static const uint32_t WriteOnceConfigVersion = 1;
//defaults okay
//WriteOnceConfig(const WriteOnceConfig& rhs);
//WriteOnceConfig& operator=(const WriteOnceConfig& rhs);
//defaults okay
//WriteOnceConfig(const WriteOnceConfig& rhs);
//WriteOnceConfig& operator=(const WriteOnceConfig& rhs);
/** @brief ctor helper
*
*/
void setup();
/** @brief ctor helper
*
*/
void setup();
/** @brief setup defaults when file doesn't exist
*
*/
void initializeDefaults();
/** @brief setup defaults when file doesn't exist
*
*/
void initializeDefaults();
EntryMap_t fEntryMap;
EntryMap_t fEntryMap;
std::string fConfigFileName;
std::string fConfigFileName;
ConfigItem_t fLBID_Shift;
ConfigItem_t fDBRootCount;
ConfigItem_t fDBRMRoot;
ConfigItem_t fSharedMemoryTmpFile1;
ConfigItem_t fTxnIDFile;
ConfigItem_t fSharedMemoryTmpFile2;
ConfigItem_t fLBID_Shift;
ConfigItem_t fDBRootCount;
ConfigItem_t fDBRMRoot;
ConfigItem_t fSharedMemoryTmpFile1;
ConfigItem_t fTxnIDFile;
ConfigItem_t fSharedMemoryTmpFile2;
};

View File

@ -35,213 +35,254 @@ namespace config
const string XMLParser::getConfig(const xmlDocPtr doc, const string& section, const string& name) const
{
string res;
xmlNodePtr cur1 = xmlDocGetRootElement(doc);
if (cur1 == NULL)
throw runtime_error("XMLParser::getConfig: error accessing XML root");
string res;
xmlNodePtr cur1 = xmlDocGetRootElement(doc);
cur1 = cur1->xmlChildrenNode;
while (cur1 != NULL)
{
if ((!xmlStrcmp(cur1->name, (const xmlChar *)section.c_str())))
{
xmlNodePtr cur2 = cur1->xmlChildrenNode;
while (cur2 != NULL)
{
if ((!xmlStrcmp(cur2->name, (const xmlChar*)name.c_str())))
{
xmlNodePtr cur3 = cur2->xmlChildrenNode;
if (cur3)
res = (const char*)cur3->content;
return expand(res);
}
cur2 = cur2->next;
}
}
cur1 = cur1->next;
}
// maybe nullstr if not found
return expand(res);
if (cur1 == NULL)
throw runtime_error("XMLParser::getConfig: error accessing XML root");
cur1 = cur1->xmlChildrenNode;
while (cur1 != NULL)
{
if ((!xmlStrcmp(cur1->name, (const xmlChar*)section.c_str())))
{
xmlNodePtr cur2 = cur1->xmlChildrenNode;
while (cur2 != NULL)
{
if ((!xmlStrcmp(cur2->name, (const xmlChar*)name.c_str())))
{
xmlNodePtr cur3 = cur2->xmlChildrenNode;
if (cur3)
res = (const char*)cur3->content;
return expand(res);
}
cur2 = cur2->next;
}
}
cur1 = cur1->next;
}
// maybe nullstr if not found
return expand(res);
}
void XMLParser::getConfig(const xmlDocPtr doc, const string& section, const string& name, vector<string>& values) const
{
string res;
string res;
xmlNodePtr cur1 = xmlDocGetRootElement(doc);
if (cur1 == NULL)
throw runtime_error("XMLParser::getConfig: error accessing XML root");
xmlNodePtr cur1 = xmlDocGetRootElement(doc);
cur1 = cur1->xmlChildrenNode;
while (cur1 != NULL)
{
if ((!xmlStrcmp(cur1->name, (const xmlChar *)section.c_str())))
{
xmlNodePtr cur2 = cur1->xmlChildrenNode;
while (cur2 != NULL)
{
if ((!xmlStrcmp(cur2->name, (const xmlChar*)name.c_str())))
{
res.clear();
xmlNodePtr cur3 = cur2->xmlChildrenNode;
if (cur3)
res = (const char*)cur3->content;
values.push_back(expand(res));
}
cur2 = cur2->next;
}
}
cur1 = cur1->next;
}
if (cur1 == NULL)
throw runtime_error("XMLParser::getConfig: error accessing XML root");
cur1 = cur1->xmlChildrenNode;
while (cur1 != NULL)
{
if ((!xmlStrcmp(cur1->name, (const xmlChar*)section.c_str())))
{
xmlNodePtr cur2 = cur1->xmlChildrenNode;
while (cur2 != NULL)
{
if ((!xmlStrcmp(cur2->name, (const xmlChar*)name.c_str())))
{
res.clear();
xmlNodePtr cur3 = cur2->xmlChildrenNode;
if (cur3)
res = (const char*)cur3->content;
values.push_back(expand(res));
}
cur2 = cur2->next;
}
}
cur1 = cur1->next;
}
}
void XMLParser::setConfig(xmlDocPtr doc, const string& section, const string& name, const string& value)
{
xmlNodePtr cur1 = xmlDocGetRootElement(doc);
if (cur1 == NULL)
throw runtime_error("XMLParser::setConfig: error accessing XML root");
xmlNodePtr cur1 = xmlDocGetRootElement(doc);
xmlNodePtr cur2;
if (cur1 == NULL)
throw runtime_error("XMLParser::setConfig: error accessing XML root");
cur1 = cur1->xmlChildrenNode;
while (cur1 != NULL)
{
if (xmlStrcmp(cur1->name, (const xmlChar *)section.c_str()) == 0)
{
cur2 = cur1->xmlChildrenNode;
while (cur2 != NULL)
{
if (xmlStrcmp(cur2->name, (const xmlChar*)name.c_str()) == 0)
{
xmlNodePtr cur3 = cur2->xmlChildrenNode;
if (cur3 == NULL)
{
xmlAddChild(cur2, xmlNewText((const xmlChar*)"\t"));
cur3 = cur2->xmlChildrenNode;
}
else
{
xmlFree(cur3->content);
}
cur3->content = xmlStrdup((const xmlChar*)value.c_str());
return;
}
cur2 = cur2->next;
}
// We found the section, but not the name, so we need to add a new node here
xmlAddChild(cur1, xmlNewText((const xmlChar*)"\t"));
xmlNewTextChild(cur1, NULL, (const xmlChar*)name.c_str(), (const xmlChar*)value.c_str());
xmlAddChild(cur1, xmlNewText((const xmlChar*)"\n\t"));
return;
}
cur1 = cur1->next;
}
xmlNodePtr cur2;
// We did not find the section, so we need to add it and the name here
cur1 = xmlDocGetRootElement(doc);
xmlAddChild(cur1, xmlNewText((const xmlChar*)"\t"));
cur2 = xmlNewChild(cur1, NULL, (const xmlChar*)section.c_str(), NULL);
xmlAddChild(cur2, xmlNewText((const xmlChar*)"\n\t\t"));
xmlNewTextChild(cur2, NULL, (const xmlChar*)name.c_str(), (const xmlChar*)value.c_str());
xmlAddChild(cur2, xmlNewText((const xmlChar*)"\n\t"));
xmlAddChild(cur1, xmlNewText((const xmlChar*)"\n"));
cur1 = cur1->xmlChildrenNode;
return;
while (cur1 != NULL)
{
if (xmlStrcmp(cur1->name, (const xmlChar*)section.c_str()) == 0)
{
cur2 = cur1->xmlChildrenNode;
while (cur2 != NULL)
{
if (xmlStrcmp(cur2->name, (const xmlChar*)name.c_str()) == 0)
{
xmlNodePtr cur3 = cur2->xmlChildrenNode;
if (cur3 == NULL)
{
xmlAddChild(cur2, xmlNewText((const xmlChar*)"\t"));
cur3 = cur2->xmlChildrenNode;
}
else
{
xmlFree(cur3->content);
}
cur3->content = xmlStrdup((const xmlChar*)value.c_str());
return;
}
cur2 = cur2->next;
}
// We found the section, but not the name, so we need to add a new node here
xmlAddChild(cur1, xmlNewText((const xmlChar*)"\t"));
xmlNewTextChild(cur1, NULL, (const xmlChar*)name.c_str(), (const xmlChar*)value.c_str());
xmlAddChild(cur1, xmlNewText((const xmlChar*)"\n\t"));
return;
}
cur1 = cur1->next;
}
// We did not find the section, so we need to add it and the name here
cur1 = xmlDocGetRootElement(doc);
xmlAddChild(cur1, xmlNewText((const xmlChar*)"\t"));
cur2 = xmlNewChild(cur1, NULL, (const xmlChar*)section.c_str(), NULL);
xmlAddChild(cur2, xmlNewText((const xmlChar*)"\n\t\t"));
xmlNewTextChild(cur2, NULL, (const xmlChar*)name.c_str(), (const xmlChar*)value.c_str());
xmlAddChild(cur2, xmlNewText((const xmlChar*)"\n\t"));
xmlAddChild(cur1, xmlNewText((const xmlChar*)"\n"));
return;
}
void XMLParser::delConfig(xmlDocPtr doc, const string& section, const string& name)
{
string res;
string res;
xmlNodePtr cur1 = xmlDocGetRootElement(doc);
if (cur1 == NULL)
throw runtime_error("XMLParser::delConfig: error accessing XML root");
xmlNodePtr cur1 = xmlDocGetRootElement(doc);
cur1 = cur1->xmlChildrenNode;
while (cur1 != NULL)
{
if ((!xmlStrcmp(cur1->name, (const xmlChar *)section.c_str())))
{
xmlNodePtr cur2 = cur1->xmlChildrenNode;
while (cur2 != NULL)
{
xmlNodePtr tmp = cur2;
cur2 = cur2->next;
if ((!xmlStrcmp(tmp->name, (const xmlChar*)name.c_str())))
{
xmlUnlinkNode(tmp);
xmlFreeNode(tmp);
}
}
}
cur1 = cur1->next;
}
if (cur1 == NULL)
throw runtime_error("XMLParser::delConfig: error accessing XML root");
return;
cur1 = cur1->xmlChildrenNode;
while (cur1 != NULL)
{
if ((!xmlStrcmp(cur1->name, (const xmlChar*)section.c_str())))
{
xmlNodePtr cur2 = cur1->xmlChildrenNode;
while (cur2 != NULL)
{
xmlNodePtr tmp = cur2;
cur2 = cur2->next;
if ((!xmlStrcmp(tmp->name, (const xmlChar*)name.c_str())))
{
xmlUnlinkNode(tmp);
xmlFreeNode(tmp);
}
}
}
cur1 = cur1->next;
}
return;
}
const string XMLParser::expand(const std::string& in) const
{
string out(in);
string::size_type pos;
const string::size_type len=11;
string out(in);
string::size_type pos;
const string::size_type len = 11;
pos = out.find("$INSTALLDIR");
while (pos != string::npos)
{
out.replace(pos, len, fInstallDir);
pos = out.find("$INSTALLDIR");
}
pos = out.find("$INSTALLDIR");
return out;
while (pos != string::npos)
{
out.replace(pos, len, fInstallDir);
pos = out.find("$INSTALLDIR");
}
return out;
}
const vector<string> XMLParser::enumConfig(const xmlDocPtr doc) const
{
vector<string> resv;
string res;
vector<string> resv;
string res;
xmlNodePtr cur1 = xmlDocGetRootElement(doc);
if (cur1 == NULL)
throw runtime_error("XMLParser::getConfig: error accessing XML root");
xmlNodePtr cur1 = xmlDocGetRootElement(doc);
cur1 = cur1->xmlChildrenNode;
while (cur1 != NULL)
{
res = reinterpret_cast<const char*>(cur1->name);
if (res != "text" && res != "comment")
resv.push_back(res);
cur1 = cur1->next;
}
return resv;
if (cur1 == NULL)
throw runtime_error("XMLParser::getConfig: error accessing XML root");
cur1 = cur1->xmlChildrenNode;
while (cur1 != NULL)
{
res = reinterpret_cast<const char*>(cur1->name);
if (res != "text" && res != "comment")
resv.push_back(res);
cur1 = cur1->next;
}
return resv;
}
const vector<string> XMLParser::enumSection(const xmlDocPtr doc, const string& section) const
{
vector<string> resv;
string res;
vector<string> resv;
string res;
xmlNodePtr cur1 = xmlDocGetRootElement(doc);
if (cur1 == NULL)
throw runtime_error("XMLParser::getConfig: error accessing XML root");
xmlNodePtr cur1 = xmlDocGetRootElement(doc);
cur1 = cur1->xmlChildrenNode;
while (cur1 != NULL)
{
if ((!xmlStrcmp(cur1->name, (const xmlChar *)section.c_str())))
{
xmlNodePtr cur2 = cur1->xmlChildrenNode;
while (cur2 != NULL)
{
res = reinterpret_cast<const char*>(cur2->name);
if (res != "text" && res != "comment")
resv.push_back(expand(res));
cur2 = cur2->next;
}
}
cur1 = cur1->next;
}
return resv;
if (cur1 == NULL)
throw runtime_error("XMLParser::getConfig: error accessing XML root");
cur1 = cur1->xmlChildrenNode;
while (cur1 != NULL)
{
if ((!xmlStrcmp(cur1->name, (const xmlChar*)section.c_str())))
{
xmlNodePtr cur2 = cur1->xmlChildrenNode;
while (cur2 != NULL)
{
res = reinterpret_cast<const char*>(cur2->name);
if (res != "text" && res != "comment")
resv.push_back(expand(res));
cur2 = cur2->next;
}
}
cur1 = cur1->next;
}
return resv;
}
} //namespace

View File

@ -36,33 +36,33 @@ namespace config
class XMLParser
{
public:
XMLParser(const std::string& installDir) : fInstallDir(installDir) { }
~XMLParser() { }
XMLParser(const std::string& installDir) : fInstallDir(installDir) { }
~XMLParser() { }
const std::string getConfig(const xmlDocPtr doc, const std::string& section, const std::string& name) const;
const std::string getConfig(const xmlDocPtr doc, const std::string& section, const std::string& name) const;
void getConfig(const xmlDocPtr doc, const std::string& section, const std::string& name,
std::vector<std::string>& values) const;
void getConfig(const xmlDocPtr doc, const std::string& section, const std::string& name,
std::vector<std::string>& values) const;
void setConfig(xmlDocPtr doc, const std::string& section, const std::string& name,
const std::string& value);
void setConfig(xmlDocPtr doc, const std::string& section, const std::string& name,
const std::string& value);
void delConfig(xmlDocPtr doc, const std::string& section, const std::string& name);
void delConfig(xmlDocPtr doc, const std::string& section, const std::string& name);
const std::vector<std::string> enumConfig(const xmlDocPtr doc) const;
const std::vector<std::string> enumConfig(const xmlDocPtr doc) const;
const std::vector<std::string> enumSection(const xmlDocPtr doc, const std::string& section) const;
const std::vector<std::string> enumSection(const xmlDocPtr doc, const std::string& section) const;
private:
//defaults okay
//XMLParser(const XMLParser& rhs);
//XMLParser& operator=(const XMLParser& rhs);
//defaults okay
//XMLParser(const XMLParser& rhs);
//XMLParser& operator=(const XMLParser& rhs);
/** @brief expand macros in config file to actual values
*/
const std::string expand(const std::string& in) const;
/** @brief expand macros in config file to actual values
*/
const std::string expand(const std::string& in) const;
const std::string fInstallDir;
const std::string fInstallDir;
};

File diff suppressed because it is too large Load Diff

View File

@ -47,11 +47,13 @@
#include <endian.h>
#if __BYTE_ORDER == __BIG_ENDIAN // 4312
inline uint64_t htonll(uint64_t n)
{ return n; }
{
return n;
}
#elif __BYTE_ORDER == __LITTLE_ENDIAN // 1234
inline uint64_t htonll(uint64_t n)
{
return ((((uint64_t) htonl(n & 0xFFFFFFFFLLU)) << 32) | (htonl((n & 0xFFFFFFFF00000000LLU) >> 32)));
return ((((uint64_t) htonl(n & 0xFFFFFFFFLLU)) << 32) | (htonl((n & 0xFFFFFFFF00000000LLU) >> 32)));
}
#else // __BYTE_ORDER == __PDP_ENDIAN 3412
inline uint64_t htonll(uint64_t n);
@ -62,14 +64,16 @@ inline uint64_t htonll(uint64_t n);
//Assume we're on little-endian
inline uint64_t htonll(uint64_t n)
{
return ((((uint64_t) htonl(n & 0xFFFFFFFFULL)) << 32) | (htonl((n & 0xFFFFFFFF00000000ULL) >> 32)));
return ((((uint64_t) htonl(n & 0xFFFFFFFFULL)) << 32) | (htonl((n & 0xFFFFFFFF00000000ULL) >> 32)));
}
#endif //_MSC_VER
#endif //__linux__
// this method evalutes the uint64 that stores a char[] to expected value
inline uint64_t uint64ToStr(uint64_t n)
{ return htonll(n); }
{
return htonll(n);
}
#if defined(_MSC_VER) && defined(xxxDATACONVERT_DLLEXPORT)
@ -78,26 +82,27 @@ inline uint64_t uint64ToStr(uint64_t n)
#define EXPORT
#endif
const int64_t IDB_pow[19] = {
1,
10,
100,
1000,
10000,
100000,
1000000,
10000000,
100000000,
1000000000,
10000000000LL,
100000000000LL,
1000000000000LL,
10000000000000LL,
100000000000000LL,
1000000000000000LL,
10000000000000000LL,
100000000000000000LL,
1000000000000000000LL
const int64_t IDB_pow[19] =
{
1,
10,
100,
1000,
10000,
100000,
1000000,
10000000,
100000000,
1000000000,
10000000000LL,
100000000000LL,
1000000000000LL,
10000000000000LL,
100000000000000LL,
1000000000000000LL,
10000000000000000LL,
100000000000000000LL,
1000000000000000000LL
};
@ -134,7 +139,7 @@ struct Date
inline
int32_t Date::convertToMySQLint() const
{
return (int32_t) (year*10000)+(month*100)+day;
return (int32_t) (year * 10000) + (month * 100) + day;
}
/** @brief a structure to hold a datetime
@ -167,7 +172,7 @@ struct DateTime
inline
int64_t DateTime::convertToMySQLint() const
{
return (int64_t) (year*10000000000LL)+(month*100000000)+(day*1000000)+(hour*10000)+(minute*100)+second;
return (int64_t) (year * 10000000000LL) + (month * 100000000) + (day * 1000000) + (hour * 10000) + (minute * 100) + second;
}
inline
@ -192,13 +197,13 @@ struct Time
signed minute : 8;
signed hour : 12;
signed day : 12;
// NULL column value = 0xFFFFFFFFFFFFFFFE
Time() : msecond (0xFFFFFE),
second (0xFF),
minute (0xFF),
hour (0xFFF),
day (0xFFF){}
second (0xFF),
minute (0xFF),
hour (0xFFF),
day (0xFFF) {}
// Construct a Time from a 64 bit integer InfiniDB time.
Time(int64_t val) :
@ -207,20 +212,24 @@ struct Time
minute((val >> 32) & 0xff),
hour((val >> 40) & 0xfff),
day((val >> 52) & 0xfff)
{}
{}
};
static uint32_t daysInMonth[13] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0};
inline uint32_t getDaysInMonth(uint32_t month)
{ return ( (month < 1 || month > 12) ? 0 : daysInMonth[month-1]);}
{
return ( (month < 1 || month > 12) ? 0 : daysInMonth[month - 1]);
}
inline bool isLeapYear ( int year)
{
if( year % 400 == 0 )
if ( year % 400 == 0 )
return true;
if( ( year % 4 == 0 ) && ( year % 100 != 0 ) )
if ( ( year % 4 == 0 ) && ( year % 100 != 0 ) )
return true;
return false;
}
@ -229,21 +238,24 @@ bool isDateValid ( int day, int month, int year)
{
bool valid = true;
if ( year == 0 && month == 0 && year == 0 )
{
return true;
}
if ( year == 0 && month == 0 && year == 0 )
{
return true;
}
int daycheck = getDaysInMonth( month );
if( month == 2 && isLeapYear( year ) )
if ( month == 2 && isLeapYear( year ) )
// 29 days in February in a leap year
daycheck = 29;
if ( ( year < 1000 ) || ( year > 9999 ) )
valid = false;
else if ( month < 1 || month > 12 )
valid = false;
else if ( day < 1 || day > daycheck )
valid = false;
return ( valid );
}
@ -251,6 +263,7 @@ inline
bool isDateTimeValid ( int hour, int minute, int second, int microSecond)
{
bool valid = false;
if ( hour >= 0 && hour <= 24 )
{
if ( minute >= 0 && minute < 60 )
@ -264,6 +277,7 @@ bool isDateTimeValid ( int hour, int minute, int second, int microSecond)
}
}
}
return valid;
}
@ -272,8 +286,8 @@ int64_t string_to_ll( const std::string& data, bool& bSaturate )
{
// This function doesn't take into consideration our special values
// for NULL and EMPTY when setting the saturation point. Should it?
char *ep = NULL;
const char *str = data.c_str();
char* ep = NULL;
const char* str = data.c_str();
errno = 0;
int64_t value = strtoll(str, &ep, 10);
@ -292,8 +306,8 @@ uint64_t string_to_ull( const std::string& data, bool& bSaturate )
{
// This function doesn't take into consideration our special values
// for NULL and EMPTY when setting the saturation point. Should it?
char *ep = NULL;
const char *str = data.c_str();
char* ep = NULL;
const char* str = data.c_str();
errno = 0;
// check for negative number. saturate to 0;
@ -302,7 +316,9 @@ uint64_t string_to_ull( const std::string& data, bool& bSaturate )
bSaturate = true;
return 0;
}
uint64_t value = strtoull(str, &ep, 10);
// (no digits) || (more chars) || (other errors & value = 0)
if ((ep == str) || (*ep != '\0') || (errno != 0 && value == 0))
throw logging::QueryDataExcept("value is not numerical.", logging::formatErr);
@ -327,43 +343,43 @@ public:
* @param data the columns string representation of it's data
*/
EXPORT static boost::any convertColumnData( const execplan::CalpontSystemCatalog::ColType& colType,
const std::string& dataOrig, bool& bSaturate,
bool nulFlag = false, bool noRoundup = false, bool isUpdate = false);
const std::string& dataOrig, bool& bSaturate,
bool nulFlag = false, bool noRoundup = false, bool isUpdate = false);
/**
* @brief convert a columns data from native format to a string
*
* @param type the columns database type
* @param data the columns string representation of it's data
*/
EXPORT static std::string dateToString( int datevalue );
/**
* @brief convert a columns data from native format to a string
*
* @param type the columns database type
* @param data the columns string representation of it's data
*/
EXPORT static std::string dateToString( int datevalue );
static inline void dateToString( int datevalue, char* buf, unsigned int buflen );
/**
* @brief convert a columns data from native format to a string
*
* @param type the columns database type
* @param data the columns string representation of it's data
*/
EXPORT static std::string datetimeToString( long long datetimevalue );
/**
* @brief convert a columns data from native format to a string
*
* @param type the columns database type
* @param data the columns string representation of it's data
*/
EXPORT static std::string datetimeToString( long long datetimevalue );
static inline void datetimeToString( long long datetimevalue, char* buf, unsigned int buflen );
/**
* @brief convert a columns data from native format to a string
*
* @param type the columns database type
* @param data the columns string representation of it's data
*/
EXPORT static std::string dateToString1( int datevalue );
/**
* @brief convert a columns data from native format to a string
*
* @param type the columns database type
* @param data the columns string representation of it's data
*/
EXPORT static std::string dateToString1( int datevalue );
static inline void dateToString1( int datevalue, char* buf, unsigned int buflen );
/**
* @brief convert a columns data from native format to a string
*
* @param type the columns database type
* @param data the columns string representation of it's data
*/
EXPORT static std::string datetimeToString1( long long datetimevalue );
/**
* @brief convert a columns data from native format to a string
*
* @param type the columns database type
* @param data the columns string representation of it's data
*/
EXPORT static std::string datetimeToString1( long long datetimevalue );
static inline void datetimeToString1( long long datetimevalue, char* buf, unsigned int buflen );
/**
@ -377,14 +393,14 @@ public:
* @param dataOrgLen length specification of dataOrg
*/
EXPORT static int32_t convertColumnDate( const char* dataOrg,
CalpontDateTimeFormat dateFormat,
int& status, unsigned int dataOrgLen );
CalpontDateTimeFormat dateFormat,
int& status, unsigned int dataOrgLen );
/**
* @brief Is specified date valid; used by binary bulk load
*/
EXPORT static bool isColumnDateValid( int32_t date );
/**
* @brief convert a datetime column data, represented as a string,
* to it's native format. This function is for bulkload to use.
@ -396,8 +412,8 @@ public:
* @param dataOrgLen length specification of dataOrg
*/
EXPORT static int64_t convertColumnDatetime( const char* dataOrg,
CalpontDateTimeFormat datetimeFormat,
int& status, unsigned int dataOrgLen );
CalpontDateTimeFormat datetimeFormat,
int& status, unsigned int dataOrgLen );
/**
* @brief Is specified datetime valid; used by binary bulk load
@ -408,8 +424,11 @@ public:
static inline std::string decimalToString(int64_t value, uint8_t scale, execplan::CalpontSystemCatalog::ColDataType colDataType);
static inline void decimalToString(int64_t value, uint8_t scale, char* buf, unsigned int buflen, execplan::CalpontSystemCatalog::ColDataType colDataType);
static inline std::string constructRegexp(const std::string& str);
static inline bool isEscapedChar(char c) { return ('%' == c || '_' == c); }
static inline bool isEscapedChar(char c)
{
return ('%' == c || '_' == c);
}
// convert string to date
EXPORT static int64_t stringToDate(const std::string& data);
// convert string to datetime
@ -418,7 +437,7 @@ public:
EXPORT static int64_t intToDate(int64_t data);
// convert integer to datetime
EXPORT static int64_t intToDatetime(int64_t data, bool* isDate = NULL);
// convert string to date. alias to stringToDate
EXPORT static int64_t dateToInt(const std::string& date);
// convert string to datetime. alias to datetimeToInt
@ -431,43 +450,43 @@ public:
inline void DataConvert::dateToString( int datevalue, char* buf, unsigned int buflen)
{
snprintf( buf, buflen, "%04d-%02d-%02d",
(unsigned)((datevalue >> 16) & 0xffff),
(unsigned)((datevalue >> 12) & 0xf),
(unsigned)((datevalue >> 6) & 0x3f)
(unsigned)((datevalue >> 16) & 0xffff),
(unsigned)((datevalue >> 12) & 0xf),
(unsigned)((datevalue >> 6) & 0x3f)
);
}
inline void DataConvert::datetimeToString( long long datetimevalue, char* buf, unsigned int buflen )
{
snprintf( buf, buflen, "%04d-%02d-%02d %02d:%02d:%02d",
(unsigned)((datetimevalue >> 48) & 0xffff),
(unsigned)((datetimevalue >> 44) & 0xf),
(unsigned)((datetimevalue >> 38) & 0x3f),
(unsigned)((datetimevalue >> 32) & 0x3f),
(unsigned)((datetimevalue >> 26) & 0x3f),
(unsigned)((datetimevalue >> 20) & 0x3f)
);
snprintf( buf, buflen, "%04d-%02d-%02d %02d:%02d:%02d",
(unsigned)((datetimevalue >> 48) & 0xffff),
(unsigned)((datetimevalue >> 44) & 0xf),
(unsigned)((datetimevalue >> 38) & 0x3f),
(unsigned)((datetimevalue >> 32) & 0x3f),
(unsigned)((datetimevalue >> 26) & 0x3f),
(unsigned)((datetimevalue >> 20) & 0x3f)
);
}
inline void DataConvert::dateToString1( int datevalue, char* buf, unsigned int buflen)
{
snprintf( buf, buflen, "%04d%02d%02d",
(unsigned)((datevalue >> 16) & 0xffff),
(unsigned)((datevalue >> 12) & 0xf),
(unsigned)((datevalue >> 6) & 0x3f)
(unsigned)((datevalue >> 16) & 0xffff),
(unsigned)((datevalue >> 12) & 0xf),
(unsigned)((datevalue >> 6) & 0x3f)
);
}
inline void DataConvert::datetimeToString1( long long datetimevalue, char* buf, unsigned int buflen )
{
snprintf( buf, buflen, "%04d%02d%02d%02d%02d%02d",
(unsigned)((datetimevalue >> 48) & 0xffff),
(unsigned)((datetimevalue >> 44) & 0xf),
(unsigned)((datetimevalue >> 38) & 0x3f),
(unsigned)((datetimevalue >> 32) & 0x3f),
(unsigned)((datetimevalue >> 26) & 0x3f),
(unsigned)((datetimevalue >> 20) & 0x3f)
);
snprintf( buf, buflen, "%04d%02d%02d%02d%02d%02d",
(unsigned)((datetimevalue >> 48) & 0xffff),
(unsigned)((datetimevalue >> 44) & 0xf),
(unsigned)((datetimevalue >> 38) & 0x3f),
(unsigned)((datetimevalue >> 32) & 0x3f),
(unsigned)((datetimevalue >> 26) & 0x3f),
(unsigned)((datetimevalue >> 20) & 0x3f)
);
}
inline std::string DataConvert::decimalToString(int64_t value, uint8_t scale, execplan::CalpontSystemCatalog::ColDataType colDataType)
@ -478,13 +497,13 @@ inline std::string DataConvert::decimalToString(int64_t value, uint8_t scale, ex
}
inline void DataConvert::decimalToString(int64_t int_val, uint8_t scale, char* buf, unsigned int buflen,
execplan::CalpontSystemCatalog::ColDataType colDataType)
execplan::CalpontSystemCatalog::ColDataType colDataType)
{
// Need to convert a string with a binary unsigned number in it to a 64-bit signed int
// MySQL seems to round off values unless we use the string store method. Groan.
// Taken from ha_calpont_impl.cpp
//biggest Calpont supports is DECIMAL(18,x), or 18 total digits+dp+sign for column
// Need 19 digits maxium to hold a sum result of 18 digits decimal column.
if (isUnsigned(colDataType))
@ -511,25 +530,31 @@ inline void DataConvert::decimalToString(int64_t int_val, uint8_t scale, char* b
//we want to move the trailing null as well, so it's really dt_scale+1 chars
size_t l1 = strlen(buf);
char* ptr = &buf[0];
if (int_val < 0)
{
ptr++;
idbassert(l1 >= 2);
l1--;
}
//need to make sure we have enough leading zeros for this to work...
//at this point scale is always > 0
size_t l2 = 1;
if ((unsigned)scale > l1)
{
const char* zeros = "00000000000000000000"; //20 0's
size_t diff=0;
size_t diff = 0;
if (int_val != 0)
diff = scale - l1; //this will always be > 0
else
diff = scale;
memmove((ptr + diff), ptr, l1 + 1); //also move null
memcpy(ptr, zeros, diff);
if (int_val != 0)
l1 = 0;
else
@ -544,6 +569,7 @@ inline void DataConvert::decimalToString(int64_t int_val, uint8_t scale, char* b
{
l1 -= scale;
}
memmove((ptr + l1 + l2), (ptr + l1), scale + 1); //also move null
if (l2 == 2)
@ -562,15 +588,20 @@ inline std::string DataConvert::constructRegexp(const std::string& str)
uint32_t i, cBufIdx = 0;
// translate to regexp symbols
cBuf[cBufIdx++] = '^'; // implicit leading anchor
for (i = 0; i < str.length(); i++) {
for (i = 0; i < str.length(); i++)
{
c = (char) str.c_str()[i];
switch (c) {
switch (c)
{
// chars to substitute
case '%':
cBuf[cBufIdx++] = '.';
cBuf[cBufIdx++] = '*';
break;
case '_':
cBuf[cBufIdx++] = '.';
break;
@ -581,45 +612,49 @@ inline std::string DataConvert::constructRegexp(const std::string& str)
case '*':
case '^':
case '$':
case '?':
case '+':
case '|':
case '[':
case '{':
case '}':
case '(':
case ')':
case '?':
case '+':
case '|':
case '[':
case '{':
case '}':
case '(':
case ')':
cBuf[cBufIdx++] = '\\';
cBuf[cBufIdx++] = c;
break;
case '\\': //this is the sql escape char
if ( i + 1 < str.length())
{
if (isEscapedChar(str.c_str()[i+1]))
if (isEscapedChar(str.c_str()[i + 1]))
{
cBuf[cBufIdx++] = str.c_str()[++i];
break;
}
else if ('\\' == str.c_str()[i+1])
else if ('\\' == str.c_str()[i + 1])
{
cBuf[cBufIdx++] = c;
cBuf[cBufIdx++] = str.c_str()[++i];
break;
}
} //single slash
cBuf[cBufIdx++] = '\\';
cBuf[cBufIdx++] = c;
break;
default:
cBuf[cBufIdx++] = c;
}
}
cBuf[cBufIdx++] = '$'; // implicit trailing anchor
cBuf[cBufIdx++] = '\0';
#ifdef VERBOSE
cerr << "regexified string is " << cBuf << endl;
cerr << "regexified string is " << cBuf << endl;
#endif
return cBuf;
}

File diff suppressed because it is too large Load Diff

View File

@ -68,180 +68,201 @@ namespace ddlcleanuputil
int ddl_cleanup()
{
scoped_ptr<DBRM> dbrmp(new DBRM());
DDLPackageProcessor ddlpackageprocessor(dbrmp.get());
DDLPackageProcessor::TableLogInfo tableLogs;
int rc = 0;
uint64_t uniqueId = dbrmp->getUnique64();
logging::LoggingID lid(20); // This is running in the DMLProc space, so we use DML's lid
logging::MessageLog ml(lid);
//Get the logs information back first.
try {
ddlpackageprocessor.fetchLogFile(tableLogs, uniqueId);
}
catch (runtime_error& ex)
{
//Log to err.log
ostringstream oss;
oss << "DDLProc cannot get clean up information from DDL log files due to " << ex.what();
logging::Message::Args args1;
logging::Message message1(2);
args1.add(oss.str());
message1.format( args1 );
ml.logErrorMessage( message1 );
}
scoped_ptr<DBRM> dbrmp(new DBRM());
DDLPackageProcessor ddlpackageprocessor(dbrmp.get());
DDLPackageProcessor::TableLogInfo tableLogs;
int rc = 0;
uint64_t uniqueId = dbrmp->getUnique64();
logging::LoggingID lid(20); // This is running in the DMLProc space, so we use DML's lid
logging::MessageLog ml(lid);
DDLPackageProcessor::TableLogInfo::const_iterator it ;
for (it = tableLogs.begin(); it != tableLogs.end(); it++)
{
ostringstream oss;
oss << "DDLCleanup is cleaning table with oid " << it->first;
logging::Message::Args args1;
logging::Message message1(2);
args1.add(oss.str());
message1.format( args1 );
ml.logInfoMessage( message1 );
DDLPackageProcessor::LogInfo aLogInfo = it->second;
switch (aLogInfo.fileType)
{
case DDLPackageProcessor::DROPTABLE_LOG:
{
try {
ddlpackageprocessor.flushPrimprocCache ( aLogInfo.oids );
ddlpackageprocessor.removeExtents( aLogInfo.oids );
ddlpackageprocessor.removeFiles( uniqueId, aLogInfo.oids );
//delete log file
ddlpackageprocessor.deleteLogFile(DDLPackageProcessor::DROPTABLE_LOG, it->first, uniqueId);
ostringstream oss;
oss << "DDLProc has cleaned up drop table left over for table " << it->first;
logging::Message::Args args1;
logging::Message message1(2);
args1.add(oss.str());
message1.format( args1 );
ml.logInfoMessage( message1 );
}
catch (runtime_error& ex)
{
ostringstream oss;
oss << "DDLProc cannot clean up drop table for table " << it->first << " due to " << ex.what();
logging::Message::Args args1;
logging::Message message1(2);
args1.add(oss.str());
message1.format( args1 );
ml.logErrorMessage( message1 );
}
break;
}
case DDLPackageProcessor::DROPPART_LOG:
{
string emsg;
rc = dbrmp->markPartitionForDeletion( aLogInfo.oids, aLogInfo.partitionNums, emsg);
if (( rc != 0 ) && ( rc !=BRM::ERR_PARTITION_DISABLED ))
{
continue;
}
try {
ddlpackageprocessor.removePartitionFiles( aLogInfo.oids, aLogInfo.partitionNums, uniqueId );
cacheutils::flushPartition( aLogInfo.oids, aLogInfo.partitionNums );
emsg.clear();
rc = dbrmp->deletePartition( aLogInfo.oids, aLogInfo.partitionNums, emsg);
ddlpackageprocessor.deleteLogFile(DDLPackageProcessor::DROPPART_LOG, it->first, uniqueId);
ostringstream oss;
oss << "DDLProc has cleaned up drop partitions left over for table " << it->first;
logging::Message::Args args1;
logging::Message message1(2);
args1.add(oss.str());
message1.format( args1 );
ml.logInfoMessage( message1 );
}
catch (runtime_error& ex)
{
ostringstream oss;
oss << "DDLProc cannot clean up drop partitions for table " << it->first << " due to " << ex.what();
logging::Message::Args args1;
logging::Message message1(2);
args1.add(oss.str());
message1.format( args1 );
ml.logErrorMessage( message1 );
}
break;
}
case DDLPackageProcessor::TRUNCATE_LOG:
{
rc = dbrmp->markAllPartitionForDeletion( aLogInfo.oids);
if (rc != 0) //Log a message to err.log
{
string errMsg;
BRM::errString(rc, errMsg);
ostringstream oss;
oss << "DDLProc didn't clean up files for truncate table with oid " << it->first << " due to "<< errMsg;
logging::Message::Args args1;
logging::Message message1(2);
args1.add(oss.str());
message1.format( args1 );
ml.logErrorMessage( message1 );
continue;
}
try {
ddlpackageprocessor.removeFiles(uniqueId, aLogInfo.oids);
rc = cacheutils::flushOIDsFromCache(aLogInfo.oids);
ddlpackageprocessor.removeExtents( aLogInfo.oids );
//create a new sets of files. Just find a dbroot according th the number of tables in syscat-1.
boost::shared_ptr<CalpontSystemCatalog> systemCatalogPtr =
CalpontSystemCatalog::makeCalpontSystemCatalog(1);
int tableCount = systemCatalogPtr->getTableCount();
int dbRootCnt = 1;
int useDBRoot = 1;
string DBRootCount = config::Config::makeConfig()->getConfig("SystemConfig", "DBRootCount");
if (DBRootCount.length() != 0)
dbRootCnt = static_cast<int>(config::Config::fromText(DBRootCount));
//Get the logs information back first.
try
{
ddlpackageprocessor.fetchLogFile(tableLogs, uniqueId);
}
catch (runtime_error& ex)
{
//Log to err.log
ostringstream oss;
oss << "DDLProc cannot get clean up information from DDL log files due to " << ex.what();
logging::Message::Args args1;
logging::Message message1(2);
args1.add(oss.str());
message1.format( args1 );
ml.logErrorMessage( message1 );
}
useDBRoot = ((tableCount-1) % dbRootCnt) + 1;
//Create all column and dictionary files
CalpontSystemCatalog::TableName aTableName = systemCatalogPtr->tableName(it->first);
ddlpackageprocessor.createFiles(aTableName,useDBRoot,uniqueId, static_cast<uint32_t>(aLogInfo.oids.size()));
ddlpackageprocessor.deleteLogFile(DDLPackageProcessor::TRUNCATE_LOG, it->first, uniqueId);
ostringstream oss;
oss << "DDLProc has cleaned up truncate table left over for table " << it->first << " and the table lock is released.";
logging::Message::Args args1;
logging::Message message1(2);
args1.add(oss.str());
message1.format( args1 );
ml.logInfoMessage( message1 );
}
catch (std::exception& ex)
{
logging::Message::Args args1;
logging::Message message1(2);
ostringstream oss;
oss << "DDLProc didn't clean up truncate table left over for table with oid " << it->first << " due to " << ex.what();
args1.add(oss.str());
message1.format( args1 );
ml.logErrorMessage( message1 );
continue;
}
break;
}
default:
break;
}
}
//unlock the table
std::vector<BRM::TableLockInfo> tableLocks;
tableLocks = dbrmp->getAllTableLocks();
for (unsigned idx=0; idx<tableLocks.size(); idx++)
{
if (tableLocks[idx].ownerName == "DDLProc")
{
try
{
(void)dbrmp->releaseTableLock(tableLocks[idx].id);
}
catch ( ... ) {}
}
}
return 0;
DDLPackageProcessor::TableLogInfo::const_iterator it ;
for (it = tableLogs.begin(); it != tableLogs.end(); it++)
{
ostringstream oss;
oss << "DDLCleanup is cleaning table with oid " << it->first;
logging::Message::Args args1;
logging::Message message1(2);
args1.add(oss.str());
message1.format( args1 );
ml.logInfoMessage( message1 );
DDLPackageProcessor::LogInfo aLogInfo = it->second;
switch (aLogInfo.fileType)
{
case DDLPackageProcessor::DROPTABLE_LOG:
{
try
{
ddlpackageprocessor.flushPrimprocCache ( aLogInfo.oids );
ddlpackageprocessor.removeExtents( aLogInfo.oids );
ddlpackageprocessor.removeFiles( uniqueId, aLogInfo.oids );
//delete log file
ddlpackageprocessor.deleteLogFile(DDLPackageProcessor::DROPTABLE_LOG, it->first, uniqueId);
ostringstream oss;
oss << "DDLProc has cleaned up drop table left over for table " << it->first;
logging::Message::Args args1;
logging::Message message1(2);
args1.add(oss.str());
message1.format( args1 );
ml.logInfoMessage( message1 );
}
catch (runtime_error& ex)
{
ostringstream oss;
oss << "DDLProc cannot clean up drop table for table " << it->first << " due to " << ex.what();
logging::Message::Args args1;
logging::Message message1(2);
args1.add(oss.str());
message1.format( args1 );
ml.logErrorMessage( message1 );
}
break;
}
case DDLPackageProcessor::DROPPART_LOG:
{
string emsg;
rc = dbrmp->markPartitionForDeletion( aLogInfo.oids, aLogInfo.partitionNums, emsg);
if (( rc != 0 ) && ( rc != BRM::ERR_PARTITION_DISABLED ))
{
continue;
}
try
{
ddlpackageprocessor.removePartitionFiles( aLogInfo.oids, aLogInfo.partitionNums, uniqueId );
cacheutils::flushPartition( aLogInfo.oids, aLogInfo.partitionNums );
emsg.clear();
rc = dbrmp->deletePartition( aLogInfo.oids, aLogInfo.partitionNums, emsg);
ddlpackageprocessor.deleteLogFile(DDLPackageProcessor::DROPPART_LOG, it->first, uniqueId);
ostringstream oss;
oss << "DDLProc has cleaned up drop partitions left over for table " << it->first;
logging::Message::Args args1;
logging::Message message1(2);
args1.add(oss.str());
message1.format( args1 );
ml.logInfoMessage( message1 );
}
catch (runtime_error& ex)
{
ostringstream oss;
oss << "DDLProc cannot clean up drop partitions for table " << it->first << " due to " << ex.what();
logging::Message::Args args1;
logging::Message message1(2);
args1.add(oss.str());
message1.format( args1 );
ml.logErrorMessage( message1 );
}
break;
}
case DDLPackageProcessor::TRUNCATE_LOG:
{
rc = dbrmp->markAllPartitionForDeletion( aLogInfo.oids);
if (rc != 0) //Log a message to err.log
{
string errMsg;
BRM::errString(rc, errMsg);
ostringstream oss;
oss << "DDLProc didn't clean up files for truncate table with oid " << it->first << " due to " << errMsg;
logging::Message::Args args1;
logging::Message message1(2);
args1.add(oss.str());
message1.format( args1 );
ml.logErrorMessage( message1 );
continue;
}
try
{
ddlpackageprocessor.removeFiles(uniqueId, aLogInfo.oids);
rc = cacheutils::flushOIDsFromCache(aLogInfo.oids);
ddlpackageprocessor.removeExtents( aLogInfo.oids );
//create a new sets of files. Just find a dbroot according th the number of tables in syscat-1.
boost::shared_ptr<CalpontSystemCatalog> systemCatalogPtr =
CalpontSystemCatalog::makeCalpontSystemCatalog(1);
int tableCount = systemCatalogPtr->getTableCount();
int dbRootCnt = 1;
int useDBRoot = 1;
string DBRootCount = config::Config::makeConfig()->getConfig("SystemConfig", "DBRootCount");
if (DBRootCount.length() != 0)
dbRootCnt = static_cast<int>(config::Config::fromText(DBRootCount));
useDBRoot = ((tableCount - 1) % dbRootCnt) + 1;
//Create all column and dictionary files
CalpontSystemCatalog::TableName aTableName = systemCatalogPtr->tableName(it->first);
ddlpackageprocessor.createFiles(aTableName, useDBRoot, uniqueId, static_cast<uint32_t>(aLogInfo.oids.size()));
ddlpackageprocessor.deleteLogFile(DDLPackageProcessor::TRUNCATE_LOG, it->first, uniqueId);
ostringstream oss;
oss << "DDLProc has cleaned up truncate table left over for table " << it->first << " and the table lock is released.";
logging::Message::Args args1;
logging::Message message1(2);
args1.add(oss.str());
message1.format( args1 );
ml.logInfoMessage( message1 );
}
catch (std::exception& ex)
{
logging::Message::Args args1;
logging::Message message1(2);
ostringstream oss;
oss << "DDLProc didn't clean up truncate table left over for table with oid " << it->first << " due to " << ex.what();
args1.add(oss.str());
message1.format( args1 );
ml.logErrorMessage( message1 );
continue;
}
break;
}
default:
break;
}
}
//unlock the table
std::vector<BRM::TableLockInfo> tableLocks;
tableLocks = dbrmp->getAllTableLocks();
for (unsigned idx = 0; idx < tableLocks.size(); idx++)
{
if (tableLocks[idx].ownerName == "DDLProc")
{
try
{
(void)dbrmp->releaseTableLock(tableLocks[idx].id);
}
catch ( ... ) {}
}
}
return 0;
}
} //namespace ddlcleanuputil

View File

@ -28,7 +28,7 @@
*/
namespace ddlcleanuputil
{
int ddl_cleanup();
int ddl_cleanup();
}
// vim:ts=4 sw=4:

View File

@ -37,45 +37,45 @@ namespace funcexp
{
CalpontSystemCatalog::ColType Func_abs::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
int64_t Func_abs::getIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
// null value is indicated by isNull
return llabs(parm[0]->data()->getIntVal(row, isNull));
// null value is indicated by isNull
return llabs(parm[0]->data()->getIntVal(row, isNull));
}
uint64_t Func_abs::getUintVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
// null value is indicated by isNull
return parm[0]->data()->getIntVal(row, isNull);
// null value is indicated by isNull
return parm[0]->data()->getIntVal(row, isNull);
}
IDB_Decimal Func_abs::getDecimalVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
d.value = llabs(d.value);
return d;
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
d.value = llabs(d.value);
return d;
}
double Func_abs::getDoubleVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
return fabs(parm[0]->data()->getDoubleVal(row, isNull));
return fabs(parm[0]->data()->getDoubleVal(row, isNull));
}

View File

@ -42,84 +42,101 @@ using namespace funcexp;
int64_t addTime(DateTime& dt1, Time& dt2)
{
DateTime dt;
dt.year = 0;
dt.month = 0;
dt.day = 0;
dt.hour = 0;
dt.minute = 0;
dt.second = 0;
dt.msecond = 0;
DateTime dt;
dt.year = 0;
dt.month = 0;
dt.day = 0;
dt.hour = 0;
dt.minute = 0;
dt.second = 0;
dt.msecond = 0;
int64_t month, day, hour, min, sec, msec, tmp;
msec = (signed)(dt1.msecond + dt2.msecond);
dt.msecond = tmp = msec % 1000000;
if (tmp < 0)
{
dt.msecond = tmp + 1000000;
dt2.second--;
}
sec = (signed)(dt1.second + dt2.second + msec / 1000000);
dt.second = tmp = sec % 60;
if (tmp < 0)
{
dt.second = tmp + 60;
dt2.minute--;
}
min = (signed)(dt1.minute + dt2.minute + sec / 60);
dt.minute = tmp = min % 60;
if (tmp < 0)
{
dt.minute = tmp + 60;
dt2.hour--;
}
hour = (signed)(dt1.hour + dt2.hour + min / 60);
dt.hour = tmp = hour % 24;
int64_t month, day, hour, min, sec, msec, tmp;
msec = (signed)(dt1.msecond + dt2.msecond);
dt.msecond = tmp = msec % 1000000;
if (tmp < 0)
{
dt.msecond = tmp + 1000000;
dt2.second--;
}
sec = (signed)(dt1.second + dt2.second + msec/1000000);
dt.second = tmp = sec % 60;
if (tmp < 0)
{
dt.second = tmp + 60;
dt2.minute--;
}
min = (signed)(dt1.minute + dt2.minute + sec/60);
dt.minute = tmp = min % 60;
if (tmp < 0)
{
dt.minute = tmp + 60;
dt2.hour--;
}
hour = (signed)(dt1.hour + dt2.hour + min/60);
dt.hour = tmp = hour % 24;
// if (tmp < -1)
if (tmp < 0) // fix for subtime dlh
{
dt.hour = tmp + 24;
dt2.day--;
}
day = (signed)(dt1.day + dt2.day + hour/24);
if (isLeapYear(dt1.year) && dt1.month == 2)
day--;
month = dt1.month;
int addyear = 0;
if (dt2.day < 0 || dt2.hour < 0)
{
int monthSave = month;
while (day <= 0)
{
month = (month == 1? 12: month-1);
for (; day <= 0 && month > 0; month--)
day += getDaysInMonth(month);
month++;
if (tmp < 0) // fix for subtime dlh
{
dt.hour = tmp + 24;
dt2.day--;
}
day = (signed)(dt1.day + dt2.day + hour / 24);
if (isLeapYear(dt1.year) && dt1.month == 2)
day--;
month = dt1.month;
int addyear = 0;
if (dt2.day < 0 || dt2.hour < 0)
{
int monthSave = month;
while (day <= 0)
{
month = (month == 1 ? 12 : month - 1);
for (; day <= 0 && month > 0; month--)
day += getDaysInMonth(month);
month++;
// month=12;
}
if ( month > monthSave )
addyear--;
}
else
{
int monthSave = month;
while (day > getDaysInMonth(month))
{
for (; day > getDaysInMonth(month) && month <= 12; month++)
day -= getDaysInMonth(month);
if (month > 12)
month = 1;
}
if ( month < monthSave )
addyear++;
}
dt.day = day;
dt.month = month;
dt.year = dt1.year + addyear;
return *(reinterpret_cast<int64_t*>(&dt));
}
if ( month > monthSave )
addyear--;
}
else
{
int monthSave = month;
while (day > getDaysInMonth(month))
{
for (; day > getDaysInMonth(month) && month <= 12; month++)
day -= getDaysInMonth(month);
if (month > 12)
month = 1;
}
if ( month < monthSave )
addyear++;
}
dt.day = day;
dt.month = month;
dt.year = dt1.year + addyear;
return *(reinterpret_cast<int64_t*>(&dt));
}
}
@ -128,107 +145,113 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_add_time::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_add_time::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
return getDatetimeIntVal(row, parm, isNull, op_ct);
return getDatetimeIntVal(row, parm, isNull, op_ct);
}
string Func_add_time::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
return intToString(getIntVal(row, parm, isNull, ct));
return intToString(getIntVal(row, parm, isNull, ct));
}
int32_t Func_add_time::getDateIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
return (((getDatetimeIntVal(row, parm, isNull, ct) >> 32) & 0xFFFFFFC0) | 0x3E);
return (((getDatetimeIntVal(row, parm, isNull, ct) >> 32) & 0xFFFFFFC0) | 0x3E);
}
int64_t Func_add_time::getDatetimeIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
int64_t val1 = parm[0]->data()->getDatetimeIntVal(row, isNull);
if (isNull)
return -1;
int64_t val1 = parm[0]->data()->getDatetimeIntVal(row, isNull);
const string& val2 = parm[1]->data()->getStrVal(row, isNull);
int sign = parm[2]->data()->getIntVal(row, isNull);
DateTime dt1;
dt1.year = (val1 >> 48) & 0xffff;
dt1.month = (val1 >> 44) & 0xf;
dt1.day = (val1 >> 38) & 0x3f;
dt1.hour = (val1 >> 32) & 0x3f;
dt1.minute = (val1 >> 26) & 0x3f;
dt1.second = (val1 >> 20) & 0x3f;
dt1.msecond = val1 & 0xfffff;
int64_t time = DataConvert::stringToTime(val2);
if (time == -1)
{
isNull = true;
return -1;
}
Time t2 = *(reinterpret_cast<Time*>(&time));
// MySQL TIME type range '-838:59:59' and '838:59:59'
if (t2.minute > 59 || t2.second > 59 || t2.msecond > 999999)
{
isNull = true;
return -1;
}
int val_sign = 1;
if (t2.day != 0 && t2.hour < 0)
{
isNull = true;
return -1;
}
else if (t2.day < 0 || t2.hour < 0)
{
val_sign = -1;
}
if ((abs(t2.day) * 24 + abs(t2.hour)) > 838)
{
t2.hour = 838;
t2.minute = 59;
t2.second = 59;
if (isNull)
return -1;
const string& val2 = parm[1]->data()->getStrVal(row, isNull);
int sign = parm[2]->data()->getIntVal(row, isNull);
DateTime dt1;
dt1.year = (val1 >> 48) & 0xffff;
dt1.month = (val1 >> 44) & 0xf;
dt1.day = (val1 >> 38) & 0x3f;
dt1.hour = (val1 >> 32) & 0x3f;
dt1.minute = (val1 >> 26) & 0x3f;
dt1.second = (val1 >> 20) & 0x3f;
dt1.msecond = val1 & 0xfffff;
int64_t time = DataConvert::stringToTime(val2);
if (time == -1)
{
isNull = true;
return -1;
}
Time t2 = *(reinterpret_cast<Time*>(&time));
// MySQL TIME type range '-838:59:59' and '838:59:59'
if (t2.minute > 59 || t2.second > 59 || t2.msecond > 999999)
{
isNull = true;
return -1;
}
int val_sign = 1;
if (t2.day != 0 && t2.hour < 0)
{
isNull = true;
return -1;
}
else if (t2.day < 0 || t2.hour < 0)
{
val_sign = -1;
}
if ((abs(t2.day) * 24 + abs(t2.hour)) > 838)
{
t2.hour = 838;
t2.minute = 59;
t2.second = 59;
t2.msecond = 999999;
}
else
{
t2.hour = abs(t2.day) * 24 + t2.hour;
}
t2.day = 0;
if (val_sign * sign < 0)
{
t2.hour = -abs(t2.hour);
t2.minute = -abs(t2.minute);
t2.second = -abs(t2.second);
t2.msecond = -abs(t2.msecond);
}
else
{
t2.hour = abs(t2.hour);
t2.minute = abs(t2.minute);
t2.second = abs(t2.second);
t2.msecond = abs(t2.msecond);
}
}
else
{
t2.hour = abs(t2.day) * 24 + t2.hour;
}
return addTime(dt1, t2);
t2.day = 0;
if (val_sign * sign < 0)
{
t2.hour = -abs(t2.hour);
t2.minute = -abs(t2.minute);
t2.second = -abs(t2.second);
t2.msecond = -abs(t2.msecond);
}
else
{
t2.hour = abs(t2.hour);
t2.minute = abs(t2.minute);
t2.second = abs(t2.second);
t2.msecond = abs(t2.msecond);
}
return addTime(dt1, t2);
}

View File

@ -40,18 +40,20 @@ namespace funcexp
{
CalpontSystemCatalog::ColType Func_ascii::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_ascii::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
if (str.empty())
return 0;
return (unsigned char)str[0];
const string& str = parm[0]->data()->getStrVal(row, isNull);
if (str.empty())
return 0;
return (unsigned char)str[0];
}

View File

@ -44,158 +44,186 @@ using namespace funcexp;
namespace
{
template<typename result_t>
inline bool numericGE(result_t op1, result_t op2)
{
return op1 >= op2;
}
template<typename result_t>
inline bool numericGE(result_t op1, result_t op2)
{
return op1 >= op2;
}
template<typename result_t>
inline bool numericLE(result_t op1, result_t op2)
{
return op1 <= op2;
}
template<typename result_t>
inline bool numericLE(result_t op1, result_t op2)
{
return op1 <= op2;
}
inline bool strGE(const string& op1, const string& op2)
{
//return strcoll(op1.c_str(), op2.c_str()) >= 0;
return utf8::idb_strcoll(op1.c_str(), op2.c_str()) >= 0;
}
inline bool strGE(const string& op1, const string& op2)
{
//return strcoll(op1.c_str(), op2.c_str()) >= 0;
return utf8::idb_strcoll(op1.c_str(), op2.c_str()) >= 0;
}
inline bool strLE(const string& op1, const string& op2)
{
//return strcoll(op1.c_str(), op2.c_str()) <= 0;
return utf8::idb_strcoll(op1.c_str(), op2.c_str()) <= 0;
}
inline bool strLE(const string& op1, const string& op2)
{
//return strcoll(op1.c_str(), op2.c_str()) <= 0;
return utf8::idb_strcoll(op1.c_str(), op2.c_str()) <= 0;
}
inline bool getBool(rowgroup::Row& row,
funcexp::FunctionParm& pm,
bool& isNull,
CalpontSystemCatalog::ColType& ct,
bool notBetween)
{
switch (ct.colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
{
int64_t val = pm[0]->data()->getIntVal(row, isNull);
if (notBetween)
{
if (!numericGE(val, pm[1]->data()->getIntVal(row, isNull)) && !isNull)
return true;
isNull = false;
return (!numericLE(val, pm[2]->data()->getIntVal(row, isNull)) && !isNull);
}
return !isNull &&
numericGE(val, pm[1]->data()->getIntVal(row, isNull)) &&
numericLE(val, pm[2]->data()->getIntVal(row, isNull)) && !isNull;
}
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
inline bool getBool(rowgroup::Row& row,
funcexp::FunctionParm& pm,
bool& isNull,
CalpontSystemCatalog::ColType& ct,
bool notBetween)
{
switch (ct.colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
{
int64_t val = pm[0]->data()->getIntVal(row, isNull);
if (notBetween)
{
uint64_t val = pm[0]->data()->getUintVal(row, isNull);
if (notBetween)
{
if (!numericGE(val, pm[1]->data()->getUintVal(row, isNull)) && !isNull)
return true;
isNull = false;
return (!numericLE(val, pm[2]->data()->getUintVal(row, isNull)) && !isNull);
}
return !isNull &&
numericGE(val, pm[1]->data()->getUintVal(row, isNull)) &&
numericLE(val, pm[2]->data()->getUintVal(row, isNull)) && !isNull;
if (!numericGE(val, pm[1]->data()->getIntVal(row, isNull)) && !isNull)
return true;
isNull = false;
return (!numericLE(val, pm[2]->data()->getIntVal(row, isNull)) && !isNull);
}
case execplan::CalpontSystemCatalog::DATE:
{
int32_t val = pm[0]->data()->getDateIntVal(row, isNull);
if (notBetween)
{
if (!numericGE(val, pm[1]->data()->getDateIntVal(row, isNull)) && !isNull)
return true;
isNull = false;
return (!numericLE(val, pm[2]->data()->getDateIntVal(row, isNull)) && !isNull);
}
return !isNull &&
numericGE(val, pm[1]->data()->getDateIntVal(row, isNull)) &&
numericLE(val, pm[2]->data()->getDateIntVal(row, isNull));
}
case execplan::CalpontSystemCatalog::DATETIME:
{
int64_t val = pm[0]->data()->getDatetimeIntVal(row, isNull);
if (notBetween)
{
if (!numericGE(val, pm[1]->data()->getDatetimeIntVal(row, isNull)) && !isNull)
return true;
isNull = false;
return (!numericLE(val, pm[2]->data()->getDatetimeIntVal(row, isNull)) && !isNull);
}
return !isNull &&
numericGE(val, pm[1]->data()->getDatetimeIntVal(row, isNull)) &&
numericLE(val, pm[2]->data()->getDatetimeIntVal(row, isNull));
}
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
{
double val = pm[0]->data()->getDoubleVal(row, isNull);
if (notBetween)
{
if (!numericGE(val, pm[1]->data()->getDoubleVal(row, isNull)) && !isNull)
return true;
isNull = false;
return (!numericLE(val, pm[2]->data()->getDoubleVal(row, isNull)) && !isNull);
}
return !isNull &&
numericGE(val, pm[1]->data()->getDoubleVal(row, isNull)) &&
numericLE(val, pm[2]->data()->getDoubleVal(row, isNull));
}
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal val = pm[0]->data()->getDecimalVal(row, isNull);
if (notBetween)
{
if (!numericGE(val, pm[1]->data()->getDecimalVal(row, isNull)) && !isNull)
return true;
isNull = false;
return (!numericLE(val, pm[2]->data()->getDecimalVal(row, isNull)) && !isNull);
}
return !isNull &&
numericGE(val, pm[1]->data()->getDecimalVal(row, isNull)) &&
numericLE(val, pm[2]->data()->getDecimalVal(row, isNull));
}
case execplan::CalpontSystemCatalog::VARCHAR: // including CHAR'
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
const string& val = pm[0]->data()->getStrVal(row, isNull);
if (notBetween)
{
if (!strGE(val, pm[1]->data()->getStrVal(row, isNull)) && !isNull)
return true;
isNull = false;
return (!strLE(val, pm[2]->data()->getStrVal(row, isNull)) && !isNull);
}
return !isNull &&
strGE(val, pm[1]->data()->getStrVal(row, isNull)) &&
strLE(val, pm[2]->data()->getStrVal(row, isNull));
}
default:
{
std::ostringstream oss;
oss << "between: datatype of " << execplan::colDataTypeToString(ct.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
}
return !isNull &&
numericGE(val, pm[1]->data()->getIntVal(row, isNull)) &&
numericLE(val, pm[2]->data()->getIntVal(row, isNull)) && !isNull;
}
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
{
uint64_t val = pm[0]->data()->getUintVal(row, isNull);
if (notBetween)
{
if (!numericGE(val, pm[1]->data()->getUintVal(row, isNull)) && !isNull)
return true;
isNull = false;
return (!numericLE(val, pm[2]->data()->getUintVal(row, isNull)) && !isNull);
}
return !isNull &&
numericGE(val, pm[1]->data()->getUintVal(row, isNull)) &&
numericLE(val, pm[2]->data()->getUintVal(row, isNull)) && !isNull;
}
case execplan::CalpontSystemCatalog::DATE:
{
int32_t val = pm[0]->data()->getDateIntVal(row, isNull);
if (notBetween)
{
if (!numericGE(val, pm[1]->data()->getDateIntVal(row, isNull)) && !isNull)
return true;
isNull = false;
return (!numericLE(val, pm[2]->data()->getDateIntVal(row, isNull)) && !isNull);
}
return !isNull &&
numericGE(val, pm[1]->data()->getDateIntVal(row, isNull)) &&
numericLE(val, pm[2]->data()->getDateIntVal(row, isNull));
}
case execplan::CalpontSystemCatalog::DATETIME:
{
int64_t val = pm[0]->data()->getDatetimeIntVal(row, isNull);
if (notBetween)
{
if (!numericGE(val, pm[1]->data()->getDatetimeIntVal(row, isNull)) && !isNull)
return true;
isNull = false;
return (!numericLE(val, pm[2]->data()->getDatetimeIntVal(row, isNull)) && !isNull);
}
return !isNull &&
numericGE(val, pm[1]->data()->getDatetimeIntVal(row, isNull)) &&
numericLE(val, pm[2]->data()->getDatetimeIntVal(row, isNull));
}
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
{
double val = pm[0]->data()->getDoubleVal(row, isNull);
if (notBetween)
{
if (!numericGE(val, pm[1]->data()->getDoubleVal(row, isNull)) && !isNull)
return true;
isNull = false;
return (!numericLE(val, pm[2]->data()->getDoubleVal(row, isNull)) && !isNull);
}
return !isNull &&
numericGE(val, pm[1]->data()->getDoubleVal(row, isNull)) &&
numericLE(val, pm[2]->data()->getDoubleVal(row, isNull));
}
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal val = pm[0]->data()->getDecimalVal(row, isNull);
if (notBetween)
{
if (!numericGE(val, pm[1]->data()->getDecimalVal(row, isNull)) && !isNull)
return true;
isNull = false;
return (!numericLE(val, pm[2]->data()->getDecimalVal(row, isNull)) && !isNull);
}
return !isNull &&
numericGE(val, pm[1]->data()->getDecimalVal(row, isNull)) &&
numericLE(val, pm[2]->data()->getDecimalVal(row, isNull));
}
case execplan::CalpontSystemCatalog::VARCHAR: // including CHAR'
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
const string& val = pm[0]->data()->getStrVal(row, isNull);
if (notBetween)
{
if (!strGE(val, pm[1]->data()->getStrVal(row, isNull)) && !isNull)
return true;
isNull = false;
return (!strLE(val, pm[2]->data()->getStrVal(row, isNull)) && !isNull);
}
return !isNull &&
strGE(val, pm[1]->data()->getStrVal(row, isNull)) &&
strLE(val, pm[2]->data()->getStrVal(row, isNull));
}
default:
{
std::ostringstream oss;
oss << "between: datatype of " << execplan::colDataTypeToString(ct.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
}
}
@ -204,56 +232,59 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_between::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
PredicateOperator op;
CalpontSystemCatalog::ColType ct = fp[0]->data()->resultType();
//op.operationType(fp[0]->data()->resultType());
bool allString = true;
PredicateOperator op;
CalpontSystemCatalog::ColType ct = fp[0]->data()->resultType();
//op.operationType(fp[0]->data()->resultType());
bool allString = true;
for (uint32_t i = 1; i < fp.size(); i++)
{
//op.setOpType(op.operationType(), fp[i]->data()->resultType());
op.setOpType(ct, fp[i]->data()->resultType());
ct = op.operationType();
for (uint32_t i = 1; i < fp.size(); i++)
{
//op.setOpType(op.operationType(), fp[i]->data()->resultType());
op.setOpType(ct, fp[i]->data()->resultType());
ct = op.operationType();
if ((fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::CHAR &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::TEXT &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::VARCHAR) ||
ct.colDataType == CalpontSystemCatalog::DATE ||
ct.colDataType == CalpontSystemCatalog::DATETIME)
{
allString = false;
}
}
if ((fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::CHAR &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::TEXT &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::VARCHAR) ||
ct.colDataType == CalpontSystemCatalog::DATE ||
ct.colDataType == CalpontSystemCatalog::DATETIME)
{
allString = false;
}
}
if (allString)
{
ct.colDataType = CalpontSystemCatalog::VARCHAR;
ct.colWidth = 255;
}
if (allString)
{
ct.colDataType = CalpontSystemCatalog::VARCHAR;
ct.colWidth = 255;
}
else if (op.operationType().colDataType == CalpontSystemCatalog::DATETIME)
{
ConstantColumn *cc = NULL;
for (uint32_t i = 1; i < fp.size(); i++)
{
cc = dynamic_cast<ConstantColumn*>(fp[i]->data());
if (cc)
{
Result result = cc->result();
result.intVal = dataconvert::DataConvert::datetimeToInt(result.strVal);
cc->result(result);
}
}
}
return ct;
else if (op.operationType().colDataType == CalpontSystemCatalog::DATETIME)
{
ConstantColumn* cc = NULL;
for (uint32_t i = 1; i < fp.size(); i++)
{
cc = dynamic_cast<ConstantColumn*>(fp[i]->data());
if (cc)
{
Result result = cc->result();
result.intVal = dataconvert::DataConvert::datetimeToInt(result.strVal);
cc->result(result);
}
}
}
return ct;
}
bool Func_between::getBoolVal(rowgroup::Row& row,
FunctionParm& pm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& pm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
return getBool(row, pm, isNull, ct, false) && !isNull;
return getBool(row, pm, isNull, ct, false) && !isNull;
}
@ -262,19 +293,19 @@ bool Func_between::getBoolVal(rowgroup::Row& row,
CalpontSystemCatalog::ColType Func_notbetween::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
PredicateOperator *op = new PredicateOperator();
CalpontSystemCatalog::ColType ct;
op->setOpType(fp[0]->data()->resultType(), fp[1]->data()->resultType());
op->setOpType(op->resultType(), fp[2]->data()->resultType());
return op->operationType();
PredicateOperator* op = new PredicateOperator();
CalpontSystemCatalog::ColType ct;
op->setOpType(fp[0]->data()->resultType(), fp[1]->data()->resultType());
op->setOpType(op->resultType(), fp[2]->data()->resultType());
return op->operationType();
}
bool Func_notbetween::getBoolVal(rowgroup::Row& row,
FunctionParm& pm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& pm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
return getBool(row, pm, isNull, ct, true) && !isNull;
return getBool(row, pm, isNull, ct, true) && !isNull;
}

View File

@ -44,130 +44,137 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_bitand::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_bitand::getIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
vector<int64_t> values;
vector<int64_t> values;
if ( parm.size() < 2 ) {
isNull = true;
return 0;
}
if ( parm.size() < 2 )
{
isNull = true;
return 0;
}
for (uint32_t i = 0; i < parm.size(); i++)
{
switch (parm[i]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
for (uint32_t i = 0; i < parm.size(); i++)
{
switch (parm[i]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::UFLOAT:
{
values.push_back(parm[i]->data()->getIntVal(row, isNull));
}
break;
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
int64_t value = parm[i]->data()->getIntVal(row, isNull);
if (isNull)
{
isNull = true;
return value;
}
values.push_back(0);
}
break;
case execplan::CalpontSystemCatalog::DECIMAL:
{
IDB_Decimal d = parm[i]->data()->getDecimalVal(row, isNull);
int64_t value = d.value / power(d.scale);
int lefto = (d.value - value * power(d.scale)) / power(d.scale-1);
if ( value >= 0 && lefto > 4 )
value++;
if ( value < 0 && lefto < -4 )
value--;
values.push_back(value);
}
break;
case execplan::CalpontSystemCatalog::DATE:
{
int64_t time = parm[i]->data()->getDateIntVal(row, isNull);
int32_t year = 0,
month = 0,
day = 0;
year = (uint32_t)((time >> 16) & 0xffff);
month = (uint32_t)((time >> 12) & 0xf);
day = (uint32_t)((time >> 6) & 0x3f);
values.push_back((year*10000)+(month*100)+day);
}
break;
case execplan::CalpontSystemCatalog::DATETIME:
{
int64_t time = parm[i]->data()->getDatetimeIntVal(row, isNull);
int32_t year = 0,
month = 0,
day = 0,
hour = 0,
min = 0,
sec = 0;
year = (uint32_t)((time >> 48) & 0xffff);
month = (uint32_t)((time >> 44) & 0xf);
day = (uint32_t)((time >> 38) & 0x3f);
hour = (uint32_t)((time >> 32) & 0x3f);
min = (uint32_t)((time >> 26) & 0x3f);
sec = (uint32_t)((time >> 20) & 0x3f);
// return (int64_t) (year*1000000000000)+(month*100000000)+(day*1000000)+(hour*10000)+(min*100)+sec;
values.push_back((month*100000000)+(day*1000000)+(hour*10000)+(min*100)+sec);
}
break;
default:
{
std::ostringstream oss;
oss << "bitand: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
}
{
values.push_back(parm[i]->data()->getIntVal(row, isNull));
}
break;
vector<int64_t>::iterator p = values.begin();
int64_t retValue = *p;
p++;
while ( p != values.end() )
{
retValue = retValue & *p;
p++;
}
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
int64_t value = parm[i]->data()->getIntVal(row, isNull);
return retValue;
if (isNull)
{
isNull = true;
return value;
}
values.push_back(0);
}
break;
case execplan::CalpontSystemCatalog::DECIMAL:
{
IDB_Decimal d = parm[i]->data()->getDecimalVal(row, isNull);
int64_t value = d.value / power(d.scale);
int lefto = (d.value - value * power(d.scale)) / power(d.scale - 1);
if ( value >= 0 && lefto > 4 )
value++;
if ( value < 0 && lefto < -4 )
value--;
values.push_back(value);
}
break;
case execplan::CalpontSystemCatalog::DATE:
{
int64_t time = parm[i]->data()->getDateIntVal(row, isNull);
int32_t year = 0,
month = 0,
day = 0;
year = (uint32_t)((time >> 16) & 0xffff);
month = (uint32_t)((time >> 12) & 0xf);
day = (uint32_t)((time >> 6) & 0x3f);
values.push_back((year * 10000) + (month * 100) + day);
}
break;
case execplan::CalpontSystemCatalog::DATETIME:
{
int64_t time = parm[i]->data()->getDatetimeIntVal(row, isNull);
int32_t year = 0,
month = 0,
day = 0,
hour = 0,
min = 0,
sec = 0;
year = (uint32_t)((time >> 48) & 0xffff);
month = (uint32_t)((time >> 44) & 0xf);
day = (uint32_t)((time >> 38) & 0x3f);
hour = (uint32_t)((time >> 32) & 0x3f);
min = (uint32_t)((time >> 26) & 0x3f);
sec = (uint32_t)((time >> 20) & 0x3f);
// return (int64_t) (year*1000000000000)+(month*100000000)+(day*1000000)+(hour*10000)+(min*100)+sec;
values.push_back((month * 100000000) + (day * 1000000) + (hour * 10000) + (min * 100) + sec);
}
break;
default:
{
std::ostringstream oss;
oss << "bitand: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
}
vector<int64_t>::iterator p = values.begin();
int64_t retValue = *p;
p++;
while ( p != values.end() )
{
retValue = retValue & *p;
p++;
}
return retValue;
}

View File

@ -52,26 +52,26 @@ using namespace funcexp;
// and could be extracted into a utility class with its own header
// if that is the case - this is left as future exercise
bool getUIntValFromParm(
Row& row,
const execplan::SPTP& parm,
uint64_t& value,
bool& isNull)
Row& row,
const execplan::SPTP& parm,
uint64_t& value,
bool& isNull)
{
switch (parm->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
switch (parm->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::UFLOAT:
{
value = parm->data()->getIntVal(row, isNull);
}
break;
{
value = parm->data()->getIntVal(row, isNull);
}
break;
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
@ -84,65 +84,72 @@ bool getUIntValFromParm(
break;
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
value = parm->data()->getIntVal(row, isNull);
if (isNull)
{
isNull = true;
}
else
{
value = 0;
}
}
break;
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
value = parm->data()->getIntVal(row, isNull);
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal d = parm->data()->getDecimalVal(row, isNull);
if (parm->data()->resultType().colDataType == execplan::CalpontSystemCatalog::UDECIMAL &&
d.value < 0)
{
d.value = 0;
}
int64_t tmpval = d.value / helpers::power(d.scale);
int lefto = (d.value - tmpval * helpers::power(d.scale)) / helpers::power(d.scale-1);
if ( tmpval >= 0 && lefto > 4 )
tmpval++;
if ( tmpval < 0 && lefto < -4 )
tmpval--;
value = tmpval;
}
break;
if (isNull)
{
isNull = true;
}
else
{
value = 0;
}
}
break;
case execplan::CalpontSystemCatalog::DATE:
{
int32_t time = parm->data()->getDateIntVal(row, isNull);
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal d = parm->data()->getDecimalVal(row, isNull);
Date d(time);
value = d.convertToMySQLint();
}
break;
if (parm->data()->resultType().colDataType == execplan::CalpontSystemCatalog::UDECIMAL &&
d.value < 0)
{
d.value = 0;
}
case execplan::CalpontSystemCatalog::DATETIME:
{
int64_t time = parm->data()->getDatetimeIntVal(row, isNull);
int64_t tmpval = d.value / helpers::power(d.scale);
int lefto = (d.value - tmpval * helpers::power(d.scale)) / helpers::power(d.scale - 1);
// @bug 4703 - missing year when convering to int
DateTime dt(time);
value = dt.convertToMySQLint();
}
break;
if ( tmpval >= 0 && lefto > 4 )
tmpval++;
default:
{
return false;
}
}
return true;
if ( tmpval < 0 && lefto < -4 )
tmpval--;
value = tmpval;
}
break;
case execplan::CalpontSystemCatalog::DATE:
{
int32_t time = parm->data()->getDateIntVal(row, isNull);
Date d(time);
value = d.convertToMySQLint();
}
break;
case execplan::CalpontSystemCatalog::DATETIME:
{
int64_t time = parm->data()->getDatetimeIntVal(row, isNull);
// @bug 4703 - missing year when convering to int
DateTime dt(time);
value = dt.convertToMySQLint();
}
break;
default:
{
return false;
}
}
return true;
}
}
@ -156,30 +163,32 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_bitand::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_bitand::getIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
if ( parm.size() < 2 ) {
isNull = true;
return 0;
}
if ( parm.size() < 2 )
{
isNull = true;
return 0;
}
uint64_t val1 = 0;
uint64_t val2 = 0;
if (!getUIntValFromParm(row, parm[0], val1, isNull) ||
!getUIntValFromParm(row, parm[1], val2, isNull))
{
std::ostringstream oss;
oss << "bitand: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
uint64_t val1 = 0;
uint64_t val2 = 0;
return val1 & val2;
if (!getUIntValFromParm(row, parm[0], val1, isNull) ||
!getUIntValFromParm(row, parm[1], val2, isNull))
{
std::ostringstream oss;
oss << "bitand: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
return val1 & val2;
}
@ -190,30 +199,32 @@ int64_t Func_bitand::getIntVal(Row& row,
CalpontSystemCatalog::ColType Func_leftshift::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_leftshift::getIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
if ( parm.size() < 2 ) {
isNull = true;
return 0;
}
if ( parm.size() < 2 )
{
isNull = true;
return 0;
}
uint64_t val1 = 0;
uint64_t val2 = 0;
if (!getUIntValFromParm(row, parm[0], val1, isNull) ||
!getUIntValFromParm(row, parm[1], val2, isNull))
{
std::ostringstream oss;
oss << "leftshift: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
uint64_t val1 = 0;
uint64_t val2 = 0;
return val1 << val2;
if (!getUIntValFromParm(row, parm[0], val1, isNull) ||
!getUIntValFromParm(row, parm[1], val2, isNull))
{
std::ostringstream oss;
oss << "leftshift: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
return val1 << val2;
}
@ -224,30 +235,32 @@ int64_t Func_leftshift::getIntVal(Row& row,
CalpontSystemCatalog::ColType Func_rightshift::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_rightshift::getIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
if ( parm.size() < 2 ) {
isNull = true;
return 0;
}
if ( parm.size() < 2 )
{
isNull = true;
return 0;
}
uint64_t val1 = 0;
uint64_t val2 = 0;
if (!getUIntValFromParm(row, parm[0], val1, isNull) ||
!getUIntValFromParm(row, parm[1], val2, isNull))
{
std::ostringstream oss;
oss << "rightshift: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
uint64_t val1 = 0;
uint64_t val2 = 0;
return val1 >> val2;
if (!getUIntValFromParm(row, parm[0], val1, isNull) ||
!getUIntValFromParm(row, parm[1], val2, isNull))
{
std::ostringstream oss;
oss << "rightshift: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
return val1 >> val2;
}
@ -258,7 +271,7 @@ int64_t Func_rightshift::getIntVal(Row& row,
CalpontSystemCatalog::ColType Func_bitor::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_bitor::getIntVal(Row& row,
@ -266,30 +279,32 @@ int64_t Func_bitor::getIntVal(Row& row,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
if ( parm.size() < 2 ) {
isNull = true;
return 0;
}
if ( parm.size() < 2 )
{
isNull = true;
return 0;
}
uint64_t val1 = 0;
uint64_t val2 = 0;
if (!getUIntValFromParm(row, parm[0], val1, isNull) ||
!getUIntValFromParm(row, parm[1], val2, isNull))
{
std::ostringstream oss;
oss << "bitor: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
uint64_t val1 = 0;
uint64_t val2 = 0;
return val1 | val2;
if (!getUIntValFromParm(row, parm[0], val1, isNull) ||
!getUIntValFromParm(row, parm[1], val2, isNull))
{
std::ostringstream oss;
oss << "bitor: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
return val1 | val2;
}
uint64_t Func_bitor::getUintVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
return static_cast<uint64_t>(getIntVal(row,fp,isNull,op_ct));
{
return static_cast<uint64_t>(getIntVal(row, fp, isNull, op_ct));
}
@ -300,30 +315,32 @@ uint64_t Func_bitor::getUintVal(rowgroup::Row& row,
CalpontSystemCatalog::ColType Func_bitxor::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_bitxor::getIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
if ( parm.size() < 2 ) {
isNull = true;
return 0;
}
if ( parm.size() < 2 )
{
isNull = true;
return 0;
}
uint64_t val1 = 0;
uint64_t val2 = 0;
if (!getUIntValFromParm(row, parm[0], val1, isNull) ||
!getUIntValFromParm(row, parm[1], val2, isNull))
{
std::ostringstream oss;
oss << "bitxor: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
uint64_t val1 = 0;
uint64_t val2 = 0;
return val1 ^ val2;
if (!getUIntValFromParm(row, parm[0], val1, isNull) ||
!getUIntValFromParm(row, parm[1], val2, isNull))
{
std::ostringstream oss;
oss << "bitxor: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
return val1 ^ val2;
}

View File

@ -47,38 +47,40 @@ namespace
using namespace funcexp;
inline uint64_t simple_case_cmp(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
uint64_t i = 0; // index to the parm list
uint64_t n = parm.size() - 1; // remove expression from count of expression_i + result_i
uint64_t hasElse = n % 2; // if 1, then ELSE exist
n -= hasElse; // index to expression
uint64_t i = 0; // index to the parm list
uint64_t n = parm.size() - 1; // remove expression from count of expression_i + result_i
uint64_t hasElse = n % 2; // if 1, then ELSE exist
n -= hasElse; // index to expression
switch (operationColType.colDataType)
{
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::DATE:
case execplan::CalpontSystemCatalog::DATETIME:
{
int64_t ev = parm[n]->data()->getIntVal(row, isNull);
if (isNull)
break;
switch (operationColType.colDataType)
{
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::DATE:
case execplan::CalpontSystemCatalog::DATETIME:
{
int64_t ev = parm[n]->data()->getIntVal(row, isNull);
for (; i < n; i += 2)
{
if (ev == parm[i]->data()->getIntVal(row, isNull) && !isNull)
break;
else
isNull = false;
}
break;
}
if (isNull)
break;
for (; i < n; i += 2)
{
if (ev == parm[i]->data()->getIntVal(row, isNull) && !isNull)
break;
else
isNull = false;
}
break;
}
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
@ -87,6 +89,7 @@ inline uint64_t simple_case_cmp(Row& row,
case execplan::CalpontSystemCatalog::USMALLINT:
{
uint64_t ev = parm[n]->data()->getUintVal(row, isNull);
if (isNull)
break;
@ -97,227 +100,243 @@ inline uint64_t simple_case_cmp(Row& row,
else
isNull = false;
}
break;
}
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
case execplan::CalpontSystemCatalog::VARCHAR:
{
const string& ev = parm[n]->data()->getStrVal(row, isNull);
if (isNull)
break;
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
case execplan::CalpontSystemCatalog::VARCHAR:
{
const string& ev = parm[n]->data()->getStrVal(row, isNull);
for (; i < n; i += 2)
{
//BUG 5362
if (utf8::idb_strcoll(ev.c_str(), parm[i]->data()->getStrVal(row, isNull).c_str()) == 0 && !isNull)
break;
else
isNull = false;
}
break;
}
if (isNull)
break;
case execplan::CalpontSystemCatalog::DECIMAL:
for (; i < n; i += 2)
{
//BUG 5362
if (utf8::idb_strcoll(ev.c_str(), parm[i]->data()->getStrVal(row, isNull).c_str()) == 0 && !isNull)
break;
else
isNull = false;
}
break;
}
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal ev = parm[n]->data()->getDecimalVal(row, isNull);
if (isNull)
break;
{
IDB_Decimal ev = parm[n]->data()->getDecimalVal(row, isNull);
for (; i < n; i += 2)
{
if (ev == parm[i]->data()->getDecimalVal(row, isNull) && !isNull)
break;
else
isNull = false;
}
break;
}
if (isNull)
break;
case execplan::CalpontSystemCatalog::DOUBLE:
for (; i < n; i += 2)
{
if (ev == parm[i]->data()->getDecimalVal(row, isNull) && !isNull)
break;
else
isNull = false;
}
break;
}
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
{
double ev = parm[n]->data()->getDoubleVal(row, isNull);
if (isNull)
break;
{
double ev = parm[n]->data()->getDoubleVal(row, isNull);
for (; i < n; i += 2)
{
if (ev == parm[i]->data()->getDoubleVal(row, isNull) && !isNull)
break;
else
isNull = false;
}
break;
}
if (isNull)
break;
for (; i < n; i += 2)
{
if (ev == parm[i]->data()->getDoubleVal(row, isNull) && !isNull)
break;
else
isNull = false;
}
break;
}
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
{
float ev = parm[n]->data()->getFloatVal(row, isNull);
if (isNull)
break;
case execplan::CalpontSystemCatalog::UFLOAT:
{
float ev = parm[n]->data()->getFloatVal(row, isNull);
for (; i < n; i += 2)
{
if (ev == parm[i]->data()->getFloatVal(row, isNull) && !isNull)
break;
else
isNull = false;
}
break;
}
if (isNull)
break;
default:
{
std::ostringstream oss;
oss << "case: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
for (; i < n; i += 2)
{
if (ev == parm[i]->data()->getFloatVal(row, isNull) && !isNull)
break;
else
isNull = false;
}
if (i == n && !hasElse)
isNull = true;
else if (isNull && hasElse)
// BUG 5110. Only way we can exit above with isNull == true is when ev is NULL
// if so and we have else condition we need to use it by setting i = n
{
i = n;
isNull = false;
}
break;
}
default:
{
std::ostringstream oss;
oss << "case: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
if (i == n && !hasElse)
isNull = true;
else if (isNull && hasElse)
// BUG 5110. Only way we can exit above with isNull == true is when ev is NULL
// if so and we have else condition we need to use it by setting i = n
{
i = n;
isNull = false;
}
return i;
return i;
}
inline uint64_t searched_case_cmp(Row& row,
FunctionParm& parm,
bool& isNull)
FunctionParm& parm,
bool& isNull)
{
uint64_t i = 0; // index to the parm list
uint64_t n = parm.size(); // count of boolean_expression_i + result_i
uint64_t hasElse = n % 2; // if 1, then ELSE exist
n -= hasElse; // index to expression
uint64_t i = 0; // index to the parm list
uint64_t n = parm.size(); // count of boolean_expression_i + result_i
uint64_t hasElse = n % 2; // if 1, then ELSE exist
n -= hasElse; // index to expression
for (; i < n; i += 2)
{
if (parm[i]->getBoolVal(row, isNull))
break;
}
for (; i < n; i += 2)
{
if (parm[i]->getBoolVal(row, isNull))
break;
}
isNull = false;
if (i == n && !hasElse)
isNull = true;
isNull = false;
return (i == n ? i-1 : i);
if (i == n && !hasElse)
isNull = true;
return (i == n ? i - 1 : i);
}
CalpontSystemCatalog::ColType caseOperationType(FunctionParm& fp,
CalpontSystemCatalog::ColType& resultType,
bool simpleCase)
CalpontSystemCatalog::ColType& resultType,
bool simpleCase)
{
// ... expression_i + result_i + ... [[expression] + result_N]
FunctionParm::size_type n = fp.size();
// ... expression_i + result_i + ... [[expression] + result_N]
FunctionParm::size_type n = fp.size();
if (simpleCase) // simple case has an expression
n -= 1; // remove expression from count of expression_i + result_i
bool hasElse = ((n % 2) != 0); // if 1, then ELSE exist
if (hasElse)
--n; // n now is an even number
idbassert((n % 2) == 0);
if (simpleCase) // simple case has an expression
n -= 1; // remove expression from count of expression_i + result_i
bool allStringO = true;
bool allStringR = true;
bool hasElse = ((n % 2) != 0); // if 1, then ELSE exist
FunctionParm::size_type l = fp.size() - 1; // last fp index
idbassert(fp[l]->data());
CalpontSystemCatalog::ColType oct = fp[l]->data()->resultType();
CalpontSystemCatalog::ColType rct = resultType;
bool operation = true;
for (uint64_t i = 0; i <= n; i++)
{
// operation or result type
operation = ((i % 2) == 0);
if (hasElse)
--n; // n now is an even number
// the result type of ELSE, if exists.
if (i == n)
{
if (!hasElse)
break;
idbassert((n % 2) == 0);
if (simpleCase)
{
// the case expression
if (fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::CHAR &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::TEXT &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::VARCHAR)
{
PredicateOperator op;
op.setOpType(oct, fp[i]->data()->resultType());
allStringO = false;
oct = op.operationType();
}
bool allStringO = true;
bool allStringR = true;
i += 1;
}
FunctionParm::size_type l = fp.size() - 1; // last fp index
idbassert(fp[l]->data());
CalpontSystemCatalog::ColType oct = fp[l]->data()->resultType();
CalpontSystemCatalog::ColType rct = resultType;
bool operation = true;
operation = false;
}
for (uint64_t i = 0; i <= n; i++)
{
// operation or result type
operation = ((i % 2) == 0);
if (fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::CHAR &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::TEXT &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::VARCHAR)
{
// this is not a string column
PredicateOperator op;
if (operation)
{
op.setOpType(oct, fp[i]->data()->resultType());
allStringO = false;
oct = op.operationType();
}
// the result type of ELSE, if exists.
if (i == n)
{
if (!hasElse)
break;
// If any parm is of string type, the result type should be string. (same as if)
else if (rct.colDataType != CalpontSystemCatalog::CHAR &&
rct.colDataType != CalpontSystemCatalog::TEXT &&
rct.colDataType != CalpontSystemCatalog::VARCHAR)
{
op.setOpType(rct, fp[i]->data()->resultType());
allStringR = false;
rct = op.operationType();
}
}
else
{
// this is a string
// If any parm is of string type, the result type should be string. (same as if)
allStringR = true;
}
}
if (simpleCase)
{
// the case expression
if (fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::CHAR &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::TEXT &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::VARCHAR)
{
PredicateOperator op;
op.setOpType(oct, fp[i]->data()->resultType());
allStringO = false;
oct = op.operationType();
}
if (allStringO)
{
oct.colDataType = CalpontSystemCatalog::VARCHAR;
oct.colWidth = 255;
}
i += 1;
}
if (allStringR)
{
rct.colDataType = CalpontSystemCatalog::VARCHAR;
rct.colWidth = 255;
}
operation = false;
}
if (rct.scale != 0 && rct.colDataType == CalpontSystemCatalog::BIGINT)
rct.colDataType = CalpontSystemCatalog::DECIMAL;
if (oct.scale != 0 && oct.colDataType == CalpontSystemCatalog::BIGINT)
oct.colDataType = CalpontSystemCatalog::DECIMAL;
if (fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::CHAR &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::TEXT &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::VARCHAR)
{
// this is not a string column
PredicateOperator op;
resultType = rct;
return oct;
if (operation)
{
op.setOpType(oct, fp[i]->data()->resultType());
allStringO = false;
oct = op.operationType();
}
// If any parm is of string type, the result type should be string. (same as if)
else if (rct.colDataType != CalpontSystemCatalog::CHAR &&
rct.colDataType != CalpontSystemCatalog::TEXT &&
rct.colDataType != CalpontSystemCatalog::VARCHAR)
{
op.setOpType(rct, fp[i]->data()->resultType());
allStringR = false;
rct = op.operationType();
}
}
else
{
// this is a string
// If any parm is of string type, the result type should be string. (same as if)
allStringR = true;
}
}
if (allStringO)
{
oct.colDataType = CalpontSystemCatalog::VARCHAR;
oct.colWidth = 255;
}
if (allStringR)
{
rct.colDataType = CalpontSystemCatalog::VARCHAR;
rct.colWidth = 255;
}
if (rct.scale != 0 && rct.colDataType == CalpontSystemCatalog::BIGINT)
rct.colDataType = CalpontSystemCatalog::DECIMAL;
if (oct.scale != 0 && oct.colDataType == CalpontSystemCatalog::BIGINT)
oct.colDataType = CalpontSystemCatalog::DECIMAL;
resultType = rct;
return oct;
}
}
@ -339,92 +358,92 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_simple_case::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
return caseOperationType(fp, resultType, true);
return caseOperationType(fp, resultType, true);
}
int64_t Func_simple_case::getIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
uint64_t i = simple_case_cmp(row, parm, isNull, operationColType);
uint64_t i = simple_case_cmp(row, parm, isNull, operationColType);
if (isNull)
return joblist::BIGINTNULL;
if (isNull)
return joblist::BIGINTNULL;
return parm[i+1]->data()->getIntVal(row, isNull);
return parm[i + 1]->data()->getIntVal(row, isNull);
}
string Func_simple_case::getStrVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
uint64_t i = simple_case_cmp(row, parm, isNull, operationColType);
uint64_t i = simple_case_cmp(row, parm, isNull, operationColType);
if (isNull)
return string("");
if (isNull)
return string("");
return parm[i+1]->data()->getStrVal(row, isNull);
return parm[i + 1]->data()->getStrVal(row, isNull);
}
IDB_Decimal Func_simple_case::getDecimalVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
uint64_t i = simple_case_cmp(row, parm, isNull, operationColType);
uint64_t i = simple_case_cmp(row, parm, isNull, operationColType);
if (isNull)
return IDB_Decimal(); // need a null value for IDB_Decimal??
if (isNull)
return IDB_Decimal(); // need a null value for IDB_Decimal??
return parm[i+1]->data()->getDecimalVal(row, isNull);
return parm[i + 1]->data()->getDecimalVal(row, isNull);
}
double Func_simple_case::getDoubleVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
uint64_t i = simple_case_cmp(row, parm, isNull, operationColType);
uint64_t i = simple_case_cmp(row, parm, isNull, operationColType);
if (isNull)
return doubleNullVal();
if (isNull)
return doubleNullVal();
return parm[i+1]->data()->getDoubleVal(row, isNull);
return parm[i + 1]->data()->getDoubleVal(row, isNull);
}
int32_t Func_simple_case::getDateIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
uint64_t i = simple_case_cmp(row, parm, isNull, op_ct);
uint64_t i = simple_case_cmp(row, parm, isNull, op_ct);
if (isNull)
return joblist::DATENULL;
if (isNull)
return joblist::DATENULL;
return parm[i + 1]->data()->getDateIntVal(row, isNull);
}
return parm[i+1]->data()->getDateIntVal(row, isNull);
}
int64_t Func_simple_case::getDatetimeIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
uint64_t i = simple_case_cmp(row, parm, isNull, op_ct);
uint64_t i = simple_case_cmp(row, parm, isNull, op_ct);
if (isNull)
return joblist::DATETIMENULL;
if (isNull)
return joblist::DATETIMENULL;
return parm[i+1]->data()->getDatetimeIntVal(row, isNull);
}
return parm[i + 1]->data()->getDatetimeIntVal(row, isNull);
}
@ -441,94 +460,94 @@ int64_t Func_simple_case::getDatetimeIntVal(rowgroup::Row& row,
//
CalpontSystemCatalog::ColType Func_searched_case::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type not used by this functor.
// return fp[1]->data()->resultType();
return caseOperationType(fp, resultType, false);
// operation type not used by this functor.
// return fp[1]->data()->resultType();
return caseOperationType(fp, resultType, false);
}
int64_t Func_searched_case::getIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
uint64_t i = searched_case_cmp(row, parm, isNull);
uint64_t i = searched_case_cmp(row, parm, isNull);
if (isNull)
return joblist::BIGINTNULL;
if (isNull)
return joblist::BIGINTNULL;
return parm[i+1]->data()->getIntVal(row, isNull);
return parm[i + 1]->data()->getIntVal(row, isNull);
}
string Func_searched_case::getStrVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
uint64_t i = searched_case_cmp(row, parm, isNull);
uint64_t i = searched_case_cmp(row, parm, isNull);
if (isNull)
return string("");
if (isNull)
return string("");
return parm[i+1]->data()->getStrVal(row, isNull);
return parm[i + 1]->data()->getStrVal(row, isNull);
}
IDB_Decimal Func_searched_case::getDecimalVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
uint64_t i = searched_case_cmp(row, parm, isNull);
uint64_t i = searched_case_cmp(row, parm, isNull);
if (isNull)
return IDB_Decimal(); // need a null value for IDB_Decimal??
if (isNull)
return IDB_Decimal(); // need a null value for IDB_Decimal??
return parm[i+1]->data()->getDecimalVal(row, isNull);
return parm[i + 1]->data()->getDecimalVal(row, isNull);
}
double Func_searched_case::getDoubleVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
uint64_t i = searched_case_cmp(row, parm, isNull);
uint64_t i = searched_case_cmp(row, parm, isNull);
if (isNull)
return doubleNullVal();
if (isNull)
return doubleNullVal();
return parm[i+1]->data()->getDoubleVal(row, isNull);
return parm[i + 1]->data()->getDoubleVal(row, isNull);
}
int32_t Func_searched_case::getDateIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
uint64_t i = simple_case_cmp(row, parm, isNull, op_ct);
uint64_t i = simple_case_cmp(row, parm, isNull, op_ct);
if (isNull)
return joblist::DATENULL;
if (isNull)
return joblist::DATENULL;
return parm[i + 1]->data()->getDateIntVal(row, isNull);
}
return parm[i+1]->data()->getDateIntVal(row, isNull);
}
int64_t Func_searched_case::getDatetimeIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
uint64_t i = simple_case_cmp(row, parm, isNull, op_ct);
uint64_t i = simple_case_cmp(row, parm, isNull, op_ct);
if (isNull)
return joblist::DATETIMENULL;
if (isNull)
return joblist::DATETIMENULL;
return parm[i+1]->data()->getDatetimeIntVal(row, isNull);
}
return parm[i + 1]->data()->getDatetimeIntVal(row, isNull);
}
} // namespace funcexp

File diff suppressed because it is too large Load Diff

View File

@ -46,62 +46,64 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_ceil::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
return fp[0]->data()->resultType();
return fp[0]->data()->resultType();
}
int64_t Func_ceil::getIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
int64_t ret = 0;
int64_t ret = 0;
switch (op_ct.colDataType)
{
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::DECIMAL:
switch (op_ct.colDataType)
{
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
{
{
if (op_ct.scale == 0)
{
ret = parm[0]->data()->getIntVal(row, isNull);
break;
}
IDB_Decimal decimal = parm[0]->data()->getDecimalVal(row, isNull);
IDB_Decimal decimal = parm[0]->data()->getDecimalVal(row, isNull);
if (isNull)
break;
if (isNull)
break;
ret = decimal.value;
// negative scale is not supported by CNX yet
if (decimal.scale > 0)
{
ret = decimal.value;
if (decimal.scale >= 19)
{
std::ostringstream oss;
oss << "ceil: datatype of " << colDataTypeToString(op_ct.colDataType)
<< " with scale " << (int) decimal.scale << " is beyond supported scale";
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
// negative scale is not supported by CNX yet
if (decimal.scale > 0)
{
// Adjust to an int based on the scale.
int64_t tmp = ret;
ret /= helpers::powerOf10_c[decimal.scale];
if (decimal.scale >= 19)
{
std::ostringstream oss;
oss << "ceil: datatype of " << colDataTypeToString(op_ct.colDataType)
<< " with scale " << (int) decimal.scale << " is beyond supported scale";
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
// Adjust to an int based on the scale.
int64_t tmp = ret;
ret /= helpers::powerOf10_c[decimal.scale];
// Add 1 if this is a positive number and there were values to the right of the
// decimal point so that we return the largest integer value not less than X.
if ((tmp - (ret * helpers::powerOf10_c[decimal.scale]) > 0))
ret += 1;
}
}
break;
// Add 1 if this is a positive number and there were values to the right of the
// decimal point so that we return the largest integer value not less than X.
if ((tmp - (ret * helpers::powerOf10_c[decimal.scale]) > 0))
ret += 1;
}
}
break;
case CalpontSystemCatalog::UBIGINT:
case CalpontSystemCatalog::UINT:
case CalpontSystemCatalog::UMEDINT:
@ -111,73 +113,78 @@ int64_t Func_ceil::getIntVal(Row& row,
ret = (int64_t)(parm[0]->data()->getUintVal(row, isNull));
}
break;
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::UDOUBLE:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::UFLOAT:
{
ret = (int64_t) ceil(parm[0]->data()->getDoubleVal(row, isNull));
}
break;
{
ret = (int64_t) ceil(parm[0]->data()->getDoubleVal(row, isNull));
}
break;
case CalpontSystemCatalog::VARCHAR:
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
if (!isNull)
ret = (int64_t) ceil(strtod(str.c_str(), 0));
}
break;
case CalpontSystemCatalog::VARCHAR:
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
case CalpontSystemCatalog::DATE:
{
Date d (parm[0]->data()->getDateIntVal(row, isNull));
if (!isNull)
ret = d.convertToMySQLint();
}
break;
if (!isNull)
ret = (int64_t) ceil(strtod(str.c_str(), 0));
}
break;
case CalpontSystemCatalog::DATETIME:
{
DateTime dt(parm[0]->data()->getDatetimeIntVal(row, isNull));
case CalpontSystemCatalog::DATE:
{
Date d (parm[0]->data()->getDateIntVal(row, isNull));
if (!isNull)
ret = dt.convertToMySQLint();
}
break;
if (!isNull)
ret = d.convertToMySQLint();
}
break;
default:
{
std::ostringstream oss;
oss << "ceil: datatype of " << colDataTypeToString(op_ct.colDataType)
<< " is not supported";
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
return ret;
case CalpontSystemCatalog::DATETIME:
{
DateTime dt(parm[0]->data()->getDatetimeIntVal(row, isNull));
if (!isNull)
ret = dt.convertToMySQLint();
}
break;
default:
{
std::ostringstream oss;
oss << "ceil: datatype of " << colDataTypeToString(op_ct.colDataType)
<< " is not supported";
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
return ret;
}
uint64_t Func_ceil::getUintVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
uint64_t ret = 0;
uint64_t ret = 0;
switch (op_ct.colDataType)
{
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::DECIMAL:
switch (op_ct.colDataType)
{
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
{
{
ret = (uint64_t)parm[0]->data()->getIntVal(row, isNull);
}
break;
break;
case CalpontSystemCatalog::UBIGINT:
case CalpontSystemCatalog::UINT:
case CalpontSystemCatalog::UMEDINT:
@ -187,77 +194,83 @@ uint64_t Func_ceil::getUintVal(Row& row,
ret = (parm[0]->data()->getUintVal(row, isNull));
}
break;
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::UDOUBLE:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::UFLOAT:
{
ret = (uint64_t) ceil(parm[0]->data()->getDoubleVal(row, isNull));
}
break;
{
ret = (uint64_t) ceil(parm[0]->data()->getDoubleVal(row, isNull));
}
break;
case CalpontSystemCatalog::VARCHAR:
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
if (!isNull)
ret = (uint64_t) ceil(strtod(str.c_str(), 0));
}
break;
case CalpontSystemCatalog::VARCHAR:
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
case CalpontSystemCatalog::DATE:
{
if (!isNull)
ret = (uint64_t) ceil(strtod(str.c_str(), 0));
}
break;
case CalpontSystemCatalog::DATE:
{
Date d (parm[0]->data()->getDateIntVal(row, isNull));
if (!isNull)
ret = d.convertToMySQLint();
}
break;
}
break;
case CalpontSystemCatalog::DATETIME:
{
case CalpontSystemCatalog::DATETIME:
{
DateTime dt(parm[0]->data()->getDatetimeIntVal(row, isNull));
if (!isNull)
ret = dt.convertToMySQLint();
}
break;
}
break;
default:
{
std::ostringstream oss;
oss << "ceil: datatype of " << colDataTypeToString(op_ct.colDataType)
<< " is not supported";
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
return ret;
default:
{
std::ostringstream oss;
oss << "ceil: datatype of " << colDataTypeToString(op_ct.colDataType)
<< " is not supported";
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
return ret;
}
double Func_ceil::getDoubleVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
double ret = 0.0;
if (op_ct.colDataType == CalpontSystemCatalog::DOUBLE ||
op_ct.colDataType == CalpontSystemCatalog::UDOUBLE ||
op_ct.colDataType == CalpontSystemCatalog::FLOAT ||
op_ct.colDataType == CalpontSystemCatalog::UFLOAT)
{
ret = ceil(parm[0]->data()->getDoubleVal(row, isNull));
}
else if (op_ct.colDataType == CalpontSystemCatalog::VARCHAR ||
op_ct.colDataType == CalpontSystemCatalog::CHAR ||
op_ct.colDataType == CalpontSystemCatalog::TEXT)
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
if (!isNull)
ret = ceil(strtod(str.c_str(), 0));
}
else
{
double ret = 0.0;
if (op_ct.colDataType == CalpontSystemCatalog::DOUBLE ||
op_ct.colDataType == CalpontSystemCatalog::UDOUBLE ||
op_ct.colDataType == CalpontSystemCatalog::FLOAT ||
op_ct.colDataType == CalpontSystemCatalog::UFLOAT)
{
ret = ceil(parm[0]->data()->getDoubleVal(row, isNull));
}
else if (op_ct.colDataType == CalpontSystemCatalog::VARCHAR ||
op_ct.colDataType == CalpontSystemCatalog::CHAR ||
op_ct.colDataType == CalpontSystemCatalog::TEXT)
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
if (!isNull)
ret = ceil(strtod(str.c_str(), 0));
}
else
{
if (isUnsigned(op_ct.colDataType))
{
ret = (double) getUintVal(row, parm, isNull, op_ct);
@ -266,34 +279,37 @@ double Func_ceil::getDoubleVal(Row& row,
{
ret = (double) getIntVal(row, parm, isNull, op_ct);
}
}
}
return ret;
return ret;
}
string Func_ceil::getStrVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
char tmp[512] = {'\0'};
if (op_ct.colDataType == CalpontSystemCatalog::DOUBLE ||
op_ct.colDataType == CalpontSystemCatalog::UDOUBLE ||
op_ct.colDataType == CalpontSystemCatalog::FLOAT ||
op_ct.colDataType == CalpontSystemCatalog::UFLOAT ||
op_ct.colDataType == CalpontSystemCatalog::VARCHAR ||
op_ct.colDataType == CalpontSystemCatalog::CHAR ||
op_ct.colDataType == CalpontSystemCatalog::TEXT)
{
snprintf(tmp, 511, "%f", getDoubleVal(row, parm, isNull, op_ct));
char tmp[512] = {'\0'};
// remove the decimals in the oss string.
char *d = tmp;
while ((*d != '.') && (*d != '\0'))
d++;
*d = '\0';
}
if (op_ct.colDataType == CalpontSystemCatalog::DOUBLE ||
op_ct.colDataType == CalpontSystemCatalog::UDOUBLE ||
op_ct.colDataType == CalpontSystemCatalog::FLOAT ||
op_ct.colDataType == CalpontSystemCatalog::UFLOAT ||
op_ct.colDataType == CalpontSystemCatalog::VARCHAR ||
op_ct.colDataType == CalpontSystemCatalog::CHAR ||
op_ct.colDataType == CalpontSystemCatalog::TEXT)
{
snprintf(tmp, 511, "%f", getDoubleVal(row, parm, isNull, op_ct));
// remove the decimals in the oss string.
char* d = tmp;
while ((*d != '.') && (*d != '\0'))
d++;
*d = '\0';
}
else if (isUnsigned(op_ct.colDataType))
{
#ifndef __LP64__
@ -302,16 +318,16 @@ string Func_ceil::getStrVal(Row& row,
snprintf(tmp, 511, "%lu", getUintVal(row, parm, isNull, op_ct));
#endif
}
else
{
else
{
#ifndef __LP64__
snprintf(tmp, 511, "%lld", getIntVal(row, parm, isNull, op_ct));
#else
snprintf(tmp, 511, "%ld", getIntVal(row, parm, isNull, op_ct));
#endif
}
}
return string(tmp);
return string(tmp);
}

View File

@ -48,26 +48,28 @@ inline bool getChar( uint64_t value, char* buf )
uint32_t cur_offset = 0; // current index into buf
int cur_bitpos = 56; // 8th octet in input val
while( cur_bitpos >= 0 )
{
if( ( ( value >> cur_bitpos ) & 0xff ) != 0 )
{
buf[cur_offset++] = char( ( value >> cur_bitpos ) & 0xff );
}
cur_bitpos -= 8;
}
buf[cur_offset] = '\0';
while ( cur_bitpos >= 0 )
{
if ( ( ( value >> cur_bitpos ) & 0xff ) != 0 )
{
buf[cur_offset++] = char( ( value >> cur_bitpos ) & 0xff );
}
return true;
cur_bitpos -= 8;
}
buf[cur_offset] = '\0';
return true;
}
// see comment above regarding buf assumptions
inline bool getChar( int64_t value, char* buf )
{
if ( value < 0 )
return false;
else
return getChar( (uint64_t) value, buf );
if ( value < 0 )
return false;
else
return getChar( (uint64_t) value, buf );
}
}
@ -75,35 +77,36 @@ namespace funcexp
{
CalpontSystemCatalog::ColType Func_char::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
string Func_char::getStrVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
const int BUF_SIZE = 9; // see comment above for size requirement
const int BUF_SIZE = 9; // see comment above for size requirement
char buf[BUF_SIZE];
switch (ct.colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
{
int64_t value = parm[0]->data()->getIntVal(row, isNull);
switch (ct.colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
{
int64_t value = parm[0]->data()->getIntVal(row, isNull);
if ( !getChar(value, buf) )
{
isNull = true;
return "";
}
}
break;
if ( !getChar(value, buf) ) {
isNull = true;
return "";
}
}
break;
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
@ -112,7 +115,8 @@ string Func_char::getStrVal(Row& row,
{
uint64_t value = parm[0]->data()->getUintVal(row, isNull);
if ( !getChar(value, buf) ) {
if ( !getChar(value, buf) )
{
isNull = true;
return "";
}
@ -120,72 +124,80 @@ string Func_char::getStrVal(Row& row,
break;
case execplan::CalpontSystemCatalog::VARCHAR: // including CHAR'
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
{
double value = parm[0]->data()->getDoubleVal(row, isNull);
if ( !getChar((int64_t)value, buf) ) {
isNull = true;
return "";
}
}
break;
{
double value = parm[0]->data()->getDoubleVal(row, isNull);
if ( !getChar((int64_t)value, buf) )
{
isNull = true;
return "";
}
}
break;
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
{
float value = parm[0]->data()->getFloatVal(row, isNull);
if ( !getChar((int64_t)value, buf) ) {
isNull = true;
return "";
}
}
break;
case execplan::CalpontSystemCatalog::UFLOAT:
{
float value = parm[0]->data()->getFloatVal(row, isNull);
if ( !getChar((int64_t)value, buf) )
{
isNull = true;
return "";
}
}
break;
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
// get decimal and round up
int value = d.value / helpers::power(d.scale);
int lefto = (d.value - value * helpers::power(d.scale)) / helpers::power(d.scale-1);
if ( lefto > 4 )
value++;
if ( !getChar((int64_t)value, buf) ) {
isNull = true;
return "";
}
}
break;
case execplan::CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
// get decimal and round up
int value = d.value / helpers::power(d.scale);
int lefto = (d.value - value * helpers::power(d.scale)) / helpers::power(d.scale - 1);
case execplan::CalpontSystemCatalog::DATE:
case execplan::CalpontSystemCatalog::DATETIME:
{
isNull = true;
return "";
}
break;
if ( lefto > 4 )
value++;
default:
{
std::ostringstream oss;
oss << "char: datatype of " << execplan::colDataTypeToString(ct.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
// Bug 5110 : Here the data in col is null. But there might have other
// non-null columns we processed before and we do not want entire value
// to become null. Therefore we set isNull flag to false.
if(isNull)
{
isNull = false;
return "";
}
if ( !getChar((int64_t)value, buf) )
{
isNull = true;
return "";
}
}
break;
return buf;
case execplan::CalpontSystemCatalog::DATE:
case execplan::CalpontSystemCatalog::DATETIME:
{
isNull = true;
return "";
}
break;
default:
{
std::ostringstream oss;
oss << "char: datatype of " << execplan::colDataTypeToString(ct.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
// Bug 5110 : Here the data in col is null. But there might have other
// non-null columns we processed before and we do not want entire value
// to become null. Therefore we set isNull flag to false.
if (isNull)
{
isNull = false;
return "";
}
return buf;
}

View File

@ -45,70 +45,71 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_char_length::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_char_length::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
CalpontSystemCatalog::ColDataType type = parm[0]->data()->resultType().colDataType;
CalpontSystemCatalog::ColDataType type = parm[0]->data()->resultType().colDataType;
switch (type)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
switch (type)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
case execplan::CalpontSystemCatalog::VARCHAR: // including CHAR
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::VARCHAR: // including CHAR
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
const string& tstr = parm[0]->data()->getStrVal(row, isNull);
if (isNull)
return 0;
{
const string& tstr = parm[0]->data()->getStrVal(row, isNull);
size_t strwclen = utf8::idb_mbstowcs(0, tstr.c_str(), 0) + 1;
wchar_t* wcbuf = (wchar_t*)alloca(strwclen * sizeof(wchar_t));
strwclen = utf8::idb_mbstowcs(wcbuf, tstr.c_str(), strwclen);
if (isNull)
return 0;
return (int64_t)strwclen;
}
size_t strwclen = utf8::idb_mbstowcs(0, tstr.c_str(), 0) + 1;
wchar_t* wcbuf = (wchar_t*)alloca(strwclen * sizeof(wchar_t));
strwclen = utf8::idb_mbstowcs(wcbuf, tstr.c_str(), strwclen);
case execplan::CalpontSystemCatalog::DATE:
{
string date = dataconvert::DataConvert::dateToString(parm[0]->data()->getDateIntVal(row, isNull));
return (int64_t)date.size();
}
return (int64_t)strwclen;
}
case execplan::CalpontSystemCatalog::DATETIME:
{
string date = dataconvert::DataConvert::datetimeToString(parm[0]->data()->getDatetimeIntVal(row, isNull));
return (int64_t)date.size();
}
case execplan::CalpontSystemCatalog::DATE:
{
string date = dataconvert::DataConvert::dateToString(parm[0]->data()->getDateIntVal(row, isNull));
return (int64_t)date.size();
}
default:
{
std::ostringstream oss;
oss << "char_length: datatype of " << execplan::colDataTypeToString(type);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
case execplan::CalpontSystemCatalog::DATETIME:
{
string date = dataconvert::DataConvert::datetimeToString(parm[0]->data()->getDatetimeIntVal(row, isNull));
return (int64_t)date.size();
}
return 0;
default:
{
std::ostringstream oss;
oss << "char_length: datatype of " << execplan::colDataTypeToString(type);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
return 0;
}

View File

@ -40,128 +40,152 @@ namespace funcexp
{
CalpontSystemCatalog::ColType Func_coalesce::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_coalesce::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
int64_t val = 0;
for (uint32_t i = 0; i < parm.size(); i++)
{
val = parm[i]->data()->getIntVal(row, isNull);
if (isNull)
{
isNull = false;
continue;
}
return val;
}
isNull = true;
return val;
int64_t val = 0;
for (uint32_t i = 0; i < parm.size(); i++)
{
val = parm[i]->data()->getIntVal(row, isNull);
if (isNull)
{
isNull = false;
continue;
}
return val;
}
isNull = true;
return val;
}
string Func_coalesce::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
string val;
for (uint32_t i = 0; i < parm.size(); i++)
{
val = parm[i]->data()->getStrVal(row, isNull);
if (isNull)
{
isNull = false;
continue;
}
return val;
}
isNull = true;
return "";
string val;
for (uint32_t i = 0; i < parm.size(); i++)
{
val = parm[i]->data()->getStrVal(row, isNull);
if (isNull)
{
isNull = false;
continue;
}
return val;
}
isNull = true;
return "";
}
int32_t Func_coalesce::getDateIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
int64_t val = 0;
for (uint32_t i = 0; i < parm.size(); i++)
{
val = parm[i]->data()->getDateIntVal(row, isNull);
if (isNull)
{
isNull = false;
continue;
}
return val;
}
isNull = true;
return val;
int64_t val = 0;
for (uint32_t i = 0; i < parm.size(); i++)
{
val = parm[i]->data()->getDateIntVal(row, isNull);
if (isNull)
{
isNull = false;
continue;
}
return val;
}
isNull = true;
return val;
}
int64_t Func_coalesce::getDatetimeIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
int64_t val = 0;
for (uint32_t i = 0; i < parm.size(); i++)
{
val = parm[i]->data()->getDatetimeIntVal(row, isNull);
if (isNull)
{
isNull = false;
continue;
}
return val;
}
isNull = true;
return val;
int64_t val = 0;
for (uint32_t i = 0; i < parm.size(); i++)
{
val = parm[i]->data()->getDatetimeIntVal(row, isNull);
if (isNull)
{
isNull = false;
continue;
}
return val;
}
isNull = true;
return val;
}
double Func_coalesce::getDoubleVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& ct)
{
double d = 0.0;
for (uint32_t i = 0; i < parm.size(); i++)
{
d = parm[i]->data()->getDoubleVal(row, isNull);
if (isNull)
{
isNull = false;
continue;
}
return d;
}
isNull = true;
return d;
double d = 0.0;
for (uint32_t i = 0; i < parm.size(); i++)
{
d = parm[i]->data()->getDoubleVal(row, isNull);
if (isNull)
{
isNull = false;
continue;
}
return d;
}
isNull = true;
return d;
}
execplan::IDB_Decimal Func_coalesce::getDecimalVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& ct)
{
IDB_Decimal d;
for (uint32_t i = 0; i < parm.size(); i++)
{
d = parm[i]->data()->getDecimalVal(row, isNull);
if (isNull)
{
isNull = false;
continue;
}
return d;
}
isNull = true;
return d;
IDB_Decimal d;
for (uint32_t i = 0; i < parm.size(); i++)
{
d = parm[i]->data()->getDecimalVal(row, isNull);
if (isNull)
{
isNull = false;
continue;
}
return d;
}
isNull = true;
return d;
}

View File

@ -42,8 +42,8 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_concat::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
@ -51,17 +51,18 @@ CalpontSystemCatalog::ColType Func_concat::operationType(FunctionParm& fp, Calpo
// concat() returns NULL if any argument is NULL.
//
string Func_concat::getStrVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
string ret = stringValue(parm[0], row, isNull);
string ret = stringValue(parm[0], row, isNull);
for ( unsigned int id = 1 ; id < parm.size() ; id++) {
ret.append( stringValue(parm[id], row, isNull) );
}
for ( unsigned int id = 1 ; id < parm.size() ; id++)
{
ret.append( stringValue(parm[id], row, isNull) );
}
return ret;
return ret;
}
} // namespace funcexp

View File

@ -39,72 +39,82 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_concat_ws::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
string Func_concat_ws::getStrVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
string delim = stringValue(parm[0], row, isNull);
if (isNull)
return "";
string delim = stringValue(parm[0], row, isNull);
if (isNull)
return "";
#ifdef STRCOLL_ENH__
wstring wstr;
size_t strwclen = utf8::idb_mbstowcs(0,delim.c_str(),0) + 1;
wchar_t* wcbuf = (wchar_t*)alloca(strwclen * sizeof(wchar_t));
strwclen = utf8::idb_mbstowcs(wcbuf, delim.c_str(), strwclen);
wstring wdelim(wcbuf, strwclen);
wstring wstr;
size_t strwclen = utf8::idb_mbstowcs(0, delim.c_str(), 0) + 1;
wchar_t* wcbuf = (wchar_t*)alloca(strwclen * sizeof(wchar_t));
strwclen = utf8::idb_mbstowcs(wcbuf, delim.c_str(), strwclen);
wstring wdelim(wcbuf, strwclen);
for ( unsigned int id = 1 ; id < parm.size() ; id++)
{
string tstr = stringValue(parm[id], row, isNull);
if (isNull)
{
isNull = false;
continue;
}
if (!wstr.empty())
wstr += wdelim;
size_t strwclen1 = utf8::idb_mbstowcs(0, tstr.c_str(), 0) + 1;
wchar_t* wcbuf1 = (wchar_t*)alloca(strwclen1 * sizeof(wchar_t));
strwclen1 = utf8::idb_mbstowcs(wcbuf1, tstr.c_str(), strwclen1);
wstring str1(wcbuf1, strwclen1);
wstr += str1;
}
for ( unsigned int id = 1 ; id < parm.size() ; id++)
{
string tstr = stringValue(parm[id], row, isNull);
size_t strmblen = utf8::idb_wcstombs(0, wstr.c_str(), 0) + 1;
char* outbuf = (char*)alloca(strmblen * sizeof(char));
strmblen = utf8::idb_wcstombs(outbuf, wstr.c_str(), strmblen);
if (strmblen == 0)
isNull = true;
else
isNull = false;
return string(outbuf, strmblen);
if (isNull)
{
isNull = false;
continue;
}
if (!wstr.empty())
wstr += wdelim;
size_t strwclen1 = utf8::idb_mbstowcs(0, tstr.c_str(), 0) + 1;
wchar_t* wcbuf1 = (wchar_t*)alloca(strwclen1 * sizeof(wchar_t));
strwclen1 = utf8::idb_mbstowcs(wcbuf1, tstr.c_str(), strwclen1);
wstring str1(wcbuf1, strwclen1);
wstr += str1;
}
size_t strmblen = utf8::idb_wcstombs(0, wstr.c_str(), 0) + 1;
char* outbuf = (char*)alloca(strmblen * sizeof(char));
strmblen = utf8::idb_wcstombs(outbuf, wstr.c_str(), strmblen);
if (strmblen == 0)
isNull = true;
else
isNull = false;
return string(outbuf, strmblen);
#else
string str;
for ( uint32_t i = 1 ; i < parm.size() ; i++)
{
str += string(stringValue(parm[i], row, isNull).c_str());
string str;
if (isNull)
{
isNull = false;
continue;
}
if (!str.empty() && !isNull)
str += delim;
}
if (str.empty())
isNull = true;
else
isNull = false;
return str;
for ( uint32_t i = 1 ; i < parm.size() ; i++)
{
str += string(stringValue(parm[i], row, isNull).c_str());
if (isNull)
{
isNull = false;
continue;
}
if (!str.empty() && !isNull)
str += delim;
}
if (str.empty())
isNull = true;
else
isNull = false;
return str;
#endif
}

View File

@ -38,85 +38,90 @@ namespace
{
int64_t convStrToNum(const string& str, int base, bool unsignedFlag)
{
int negative;
uint64_t cutoff, cutlim, i, j, save;
int overflow;
// to skip the leading spaces.
for (i = 0; i < str.length() && str.c_str()[i] == ' '; i++)
{}
int negative;
uint64_t cutoff, cutlim, i, j, save;
int overflow;
if (i == str.length())
{
return 0L;
}
// to skip the leading spaces.
for (i = 0; i < str.length() && str.c_str()[i] == ' '; i++)
{}
if (str.c_str()[i] == '-')
{
negative = 1;
++i;
}
else if (str.c_str()[i] == '+')
{
negative = 0;
++i;
}
else
negative = 0;
if (i == str.length())
{
return 0L;
}
save = i;
cutoff = (~(uint64_t) 0) / (uint64_t) base;
cutlim = (uint32_t) ((~(uint64_t) 0) % (uint64_t) base);
overflow = 0;
j = 0;
for (; i < str.length(); i++)
{
unsigned char c= str.c_str()[i];
if (c>='0' && c<='9')
c -= '0';
else if (c>='A' && c<='Z')
c = c - 'A' + 10;
else if (c>='a' && c<='z')
c = c - 'a' + 10;
else
break;
if (c >= base)
break;
if (j > cutoff || (j == cutoff && c > cutlim))
overflow = 1;
else
{
j *= (uint64_t) base;
j += c;
}
}
if (i == save)
return 0L;
if (str.c_str()[i] == '-')
{
negative = 1;
++i;
}
else if (str.c_str()[i] == '+')
{
negative = 0;
++i;
}
else
negative = 0;
if (!unsignedFlag)
{
if (negative)
{
if (j > (uint64_t) numeric_limits<int64_t>::min())
overflow = 1;
}
else if (j > (uint64_t) numeric_limits<int64_t>::max())
{
overflow = 1;
}
}
save = i;
if (overflow)
{
if (unsignedFlag)
return (~(uint64_t) 0);
return negative ? numeric_limits<int64_t>::min() : numeric_limits<int64_t>::max();
}
cutoff = (~(uint64_t) 0) / (uint64_t) base;
cutlim = (uint32_t) ((~(uint64_t) 0) % (uint64_t) base);
return (negative ? -((int64_t) j) : (int64_t) j);
overflow = 0;
j = 0;
for (; i < str.length(); i++)
{
unsigned char c = str.c_str()[i];
if (c >= '0' && c <= '9')
c -= '0';
else if (c >= 'A' && c <= 'Z')
c = c - 'A' + 10;
else if (c >= 'a' && c <= 'z')
c = c - 'a' + 10;
else
break;
if (c >= base)
break;
if (j > cutoff || (j == cutoff && c > cutlim))
overflow = 1;
else
{
j *= (uint64_t) base;
j += c;
}
}
if (i == save)
return 0L;
if (!unsignedFlag)
{
if (negative)
{
if (j > (uint64_t) numeric_limits<int64_t>::min())
overflow = 1;
}
else if (j > (uint64_t) numeric_limits<int64_t>::max())
{
overflow = 1;
}
}
if (overflow)
{
if (unsignedFlag)
return (~(uint64_t) 0);
return negative ? numeric_limits<int64_t>::min() : numeric_limits<int64_t>::max();
}
return (negative ? -((int64_t) j) : (int64_t) j);
}
}
@ -124,170 +129,196 @@ namespace funcexp
{
namespace helpers
{
const char *convNumToStr(int64_t val,char *dst,int radix)
const char* convNumToStr(int64_t val, char* dst, int radix)
{
if (radix == 16 || radix == -16)
if (radix == 16 || radix == -16)
#ifdef _MSC_VER
sprintf(dst, "%llX", val);
sprintf(dst, "%llX", val);
#else
sprintf(dst, "%lX", val);
sprintf(dst, "%lX", val);
#endif
else if (radix == 8 || radix == -8)
else if (radix == 8 || radix == -8)
#ifdef _MSC_VER
sprintf(dst, "%llo", val);
sprintf(dst, "%llo", val);
#else
sprintf(dst, "%lo", val);
sprintf(dst, "%lo", val);
#endif
else if (radix == 10)
{
uint64_t uval = static_cast<uint64_t>(val);
else if (radix == 10)
{
uint64_t uval = static_cast<uint64_t>(val);
#ifdef _MSC_VER
sprintf(dst, "%llu", uval);
sprintf(dst, "%llu", uval);
#else
sprintf(dst, "%lu", uval);
sprintf(dst, "%lu", uval);
#endif
}
else if (radix == -10)
}
else if (radix == -10)
#ifdef _MSC_VER
sprintf(dst, "%lld", val);
sprintf(dst, "%lld", val);
#else
sprintf(dst, "%ld", val);
sprintf(dst, "%ld", val);
#endif
else if (radix == 2 || radix == -2)
{
char tmp[65];
char* ptr = &tmp[64];
*ptr-- = 0;
for (int i = 0; i < 64; i++)
{
if (val&1)
*ptr-- = '1';
else
*ptr-- = '0';
val >>= 1;
}
ptr = strchr(tmp, '1');
if (ptr == 0)
strcpy(dst, &tmp[63]);
else
strcpy(dst, ptr);
}
else if (radix == 4 || radix == -4)
{
char tmp[33];
char* ptr = &tmp[32];
*ptr-- = 0;
for (int i = 0; i < 32; i++)
{
*ptr-- = '0' + (val&3);
val >>= 2;
}
ptr = strpbrk(tmp, "123");
if (ptr == 0)
strcpy(dst, &tmp[31]);
else
strcpy(dst, ptr);
}
else if (radix == 2 || radix == -2)
{
char tmp[65];
char* ptr = &tmp[64];
*ptr-- = 0;
for (int i = 0; i < 64; i++)
{
if (val & 1)
*ptr-- = '1';
else
*ptr-- = '0';
val >>= 1;
}
ptr = strchr(tmp, '1');
if (ptr == 0)
strcpy(dst, &tmp[63]);
else
strcpy(dst, ptr);
}
else if (radix == 4 || radix == -4)
{
char tmp[33];
char* ptr = &tmp[32];
*ptr-- = 0;
for (int i = 0; i < 32; i++)
{
*ptr-- = '0' + (val & 3);
val >>= 2;
}
ptr = strpbrk(tmp, "123");
if (ptr == 0)
strcpy(dst, &tmp[31]);
else
strcpy(dst, ptr);
}
#if 0
else if (radix == 8 || radix == -8)
{
char tmp[23];
char* ptr = &tmp[22];
*ptr-- = 0;
for (int i = 0; i < 22; i++)
{
*ptr-- = '0' + (val&7);
val >>= 3;
}
ptr = strpbrk(tmp, "1234567");
if (ptr == 0)
strcpy(dst, &tmp[21]);
else
strcpy(dst, ptr);
}
else if (radix == 16 || radix == -16)
{
char tmp[17];
char* ptr = &tmp[16];
*ptr-- = 0;
for (int i = 0; i < 16; i++)
{
int v = val&0xf;
if (v > 9)
*ptr-- = 'A' + v - 10;
else
*ptr-- = '0' + v;
val >>= 4;
}
ptr = strpbrk(tmp, "123456789ABCDEF");
if (ptr == 0)
strcpy(dst, &tmp[15]);
else
strcpy(dst, ptr);
}
else if (radix == 8 || radix == -8)
{
char tmp[23];
char* ptr = &tmp[22];
*ptr-- = 0;
for (int i = 0; i < 22; i++)
{
*ptr-- = '0' + (val & 7);
val >>= 3;
}
ptr = strpbrk(tmp, "1234567");
if (ptr == 0)
strcpy(dst, &tmp[21]);
else
strcpy(dst, ptr);
}
else if (radix == 16 || radix == -16)
{
char tmp[17];
char* ptr = &tmp[16];
*ptr-- = 0;
for (int i = 0; i < 16; i++)
{
int v = val & 0xf;
if (v > 9)
*ptr-- = 'A' + v - 10;
else
*ptr-- = '0' + v;
val >>= 4;
}
ptr = strpbrk(tmp, "123456789ABCDEF");
if (ptr == 0)
strcpy(dst, &tmp[15]);
else
strcpy(dst, ptr);
}
#endif
else if (radix == 32 || radix == -32)
{
char tmp[14];
char* ptr = &tmp[13];
*ptr-- = 0;
for (int i = 0; i < 13; i++)
{
int v = val&0x1f;
if (v > 9)
*ptr-- = 'A' + v - 10;
else
*ptr-- = '0' + v;
val >>= 5;
}
ptr = strpbrk(tmp, "123456789ABCDEFGHIJKLMNOPQRSTUV");
if (ptr == 0)
strcpy(dst, &tmp[12]);
else
strcpy(dst, ptr);
}
else
*dst = 0;
return dst;
else if (radix == 32 || radix == -32)
{
char tmp[14];
char* ptr = &tmp[13];
*ptr-- = 0;
for (int i = 0; i < 13; i++)
{
int v = val & 0x1f;
if (v > 9)
*ptr-- = 'A' + v - 10;
else
*ptr-- = '0' + v;
val >>= 5;
}
ptr = strpbrk(tmp, "123456789ABCDEFGHIJKLMNOPQRSTUV");
if (ptr == 0)
strcpy(dst, &tmp[12]);
else
strcpy(dst, ptr);
}
else
*dst = 0;
return dst;
}
} //namespace funcexp::helpers
CalpontSystemCatalog::ColType Func_conv::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
string Func_conv::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
const string& res= parm[0]->data()->getStrVal(row, isNull);
string str;
char ans[65];
int64_t dec;
int64_t from_base = parm[1]->data()->getIntVal(row, isNull);
int64_t to_base = parm[2]->data()->getIntVal(row, isNull);
const string& res = parm[0]->data()->getStrVal(row, isNull);
string str;
char ans[65];
int64_t dec;
int64_t from_base = parm[1]->data()->getIntVal(row, isNull);
int64_t to_base = parm[2]->data()->getIntVal(row, isNull);
if (isNull || abs(static_cast<int>(to_base)) > 36 || abs(static_cast<int>(to_base)) < 2 ||
abs(static_cast<int>(from_base)) > 36 || abs(static_cast<int>(from_base)) < 2 || !(res.length()))
{
isNull = true;
return "";
}
if (isNull || abs(static_cast<int>(to_base)) > 36 || abs(static_cast<int>(to_base)) < 2 ||
abs(static_cast<int>(from_base)) > 36 || abs(static_cast<int>(from_base)) < 2 || !(res.length()))
{
isNull = true;
return "";
}
if (from_base < 0)
dec= convStrToNum(res, -from_base, false);
else
dec= (int64_t) convStrToNum( res, from_base, true);
if (from_base < 0)
dec = convStrToNum(res, -from_base, false);
else
dec = (int64_t) convStrToNum( res, from_base, true);
str = helpers::convNumToStr(dec, ans, to_base);
str = helpers::convNumToStr(dec, ans, to_base);
isNull = str.empty();
isNull = str.empty();
return str;
return str;
}

View File

@ -41,17 +41,17 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_crc32::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_crc32::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
const string& val = parm[0]->data()->getStrVal(row, isNull);
return (int64_t) crc32(0L, (unsigned char*)val.c_str(), strlen(val.c_str()));
const string& val = parm[0]->data()->getStrVal(row, isNull);
return (int64_t) crc32(0L, (unsigned char*)val.c_str(), strlen(val.c_str()));
}

View File

@ -44,78 +44,78 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_date::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_date::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
CalpontSystemCatalog::ColDataType type = parm[0]->data()->resultType().colDataType;
CalpontSystemCatalog::ColDataType type = parm[0]->data()->resultType().colDataType;
string value = "";
string value = "";
switch (type)
{
case execplan::CalpontSystemCatalog::DATE:
{
return parm[0]->data()->getDatetimeIntVal(row, isNull);
break;
}
switch (type)
{
case execplan::CalpontSystemCatalog::DATE:
{
return parm[0]->data()->getDatetimeIntVal(row, isNull);
break;
}
case execplan::CalpontSystemCatalog::DATETIME:
{
int64_t val1 = parm[0]->data()->getDatetimeIntVal(row, isNull);
value = dataconvert::DataConvert::datetimeToString(val1);
value = value.substr(0,10);
break;
}
case execplan::CalpontSystemCatalog::DATETIME:
{
int64_t val1 = parm[0]->data()->getDatetimeIntVal(row, isNull);
value = dataconvert::DataConvert::datetimeToString(val1);
value = value.substr(0, 10);
break;
}
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
isNull = true;
return 0;
}
break;
{
isNull = true;
return 0;
}
break;
default:
{
std::ostringstream oss;
oss << "date: datatype of " << execplan::colDataTypeToString(type);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
default:
{
std::ostringstream oss;
oss << "date: datatype of " << execplan::colDataTypeToString(type);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
return dataconvert::DataConvert::datetimeToInt(value);
return dataconvert::DataConvert::datetimeToInt(value);
}
string Func_date::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
const string& val = parm[0]->data()->getStrVal(row, isNull);
const string& val = parm[0]->data()->getStrVal(row, isNull);
return val.substr(0,10);
return val.substr(0, 10);
}

File diff suppressed because it is too large Load Diff

View File

@ -40,291 +40,333 @@ namespace helpers
{
const string IDB_date_format(const DateTime& dt, const string& format)
{
// assume 256 is enough. assume not allowing incomplete date
char buf[256];
char* ptr = buf;
uint32_t weekday = 0;
uint32_t dayval = 0;
uint32_t weekval = 0;
uint32_t weekyear = 0;
// assume 256 is enough. assume not allowing incomplete date
char buf[256];
char* ptr = buf;
uint32_t weekday = 0;
uint32_t dayval = 0;
uint32_t weekval = 0;
uint32_t weekyear = 0;
for (uint32_t i = 0; i < format.length(); i++)
{
if (format[i] != '%')
*ptr++ = format[i];
else
{
i++;
switch (format[i])
{
case 'M':
sprintf(ptr, "%s", helpers::monthFullNames[dt.month].c_str());
ptr += helpers::monthFullNames[dt.month].length();
break;
case 'b':
sprintf(ptr, "%s", helpers::monthAbNames[dt.month].c_str());
ptr += helpers::monthAbNames[dt.month].length();
break;
case 'W':
weekday= helpers::calc_mysql_weekday( dt.year, dt.month, dt.day, false);
sprintf(ptr, "%s", helpers::weekdayFullNames[weekday].c_str());
ptr += helpers::weekdayFullNames[weekday].length();
break;
case 'w':
weekday= helpers::calc_mysql_weekday( dt.year, dt.month, dt.day, true);
sprintf(ptr, "%01d", weekday);
ptr += 1;
break;
case 'a':
weekday= helpers::calc_mysql_weekday( dt.year, dt.month, dt.day, false);
sprintf(ptr, "%s", helpers::weekdayAbNames[weekday].c_str());
ptr += helpers::weekdayAbNames[weekday].length();
break;
case 'D':
sprintf(ptr, "%s", helpers::dayOfMonth[dt.day].c_str());
ptr += helpers::dayOfMonth[dt.day].length();
break;
case 'Y':
sprintf(ptr, "%04d", dt.year);
ptr += 4;
break;
case 'y':
sprintf(ptr, "%02d", dt.year % 100);
ptr += 2;
break;
case 'm':
sprintf(ptr, "%02d", dt.month);
ptr += 2;
break;
case 'c':
sprintf(ptr, "%d", dt.month);
ptr = ptr + (dt.month >= 10 ? 2 : 1);
break;
case 'd':
sprintf(ptr, "%02d", dt.day);
ptr += 2;
break;
case 'e':
sprintf(ptr, "%d", dt.day);
ptr = ptr + (dt.day >= 10 ? 2 : 1);
break;
case 'f':
sprintf(ptr, "%06d", dt.msecond);
ptr += 6;
break;
case 'H':
sprintf(ptr, "%02d", dt.hour);
ptr += 2;
break;
case 'h':
case 'I':
sprintf(ptr, "%02d", (dt.hour%24 + 11)%12+1);
ptr += 2;
break;
case 'i': /* minutes */
sprintf(ptr, "%02d", dt.minute);
ptr += 2;
break;
case 'j':
dayval = helpers::calc_mysql_daynr( dt.year, dt.month, dt.day ) -
helpers::calc_mysql_daynr( dt.year, 1, 1 ) + 1;
sprintf(ptr, "%03d", dayval);
ptr += 3;
break;
case 'k':
sprintf(ptr, "%d", dt.hour);
ptr += (dt.hour >= 10 ? 2 : 1);
break;
case 'l':
sprintf(ptr, "%d", (dt.hour%24 + 11)%12+1);
ptr += ((dt.hour%24 + 11)%12+1 >= 10 ? 2 : 1);
break;
case 'p':
sprintf(ptr, "%s", (dt.hour % 24 < 12 ? "AM" : "PM"));
ptr += 2;
break;
case 'r':
sprintf(ptr, (dt.hour % 24 < 12 ? "%02d:%02d:%02d AM" : "%02d:%02d:%02d PM"),
(dt.hour + 11) % 12 + 1, dt.minute, dt.second);
ptr += 11;
break;
case 'S':
case 's':
sprintf(ptr, "%02d", dt.second);
ptr += 2;
break;
case 'T':
sprintf (ptr, "%02d:%02d:%02d", dt.hour, dt.minute, dt.second);
ptr += 8;
break;
case 'U':
weekval = helpers::calc_mysql_week( dt.year, dt.month, dt.day, 0);
sprintf(ptr, "%02d", weekval);
ptr += 2;
break;
case 'V':
weekval = helpers::calc_mysql_week( dt.year, dt.month, dt.day,
helpers::WEEK_NO_ZERO );
sprintf(ptr, "%02d", weekval);
ptr += 2;
break;
case 'u':
weekval = helpers::calc_mysql_week( dt.year, dt.month, dt.day,
helpers::WEEK_MONDAY_FIRST | helpers::WEEK_GT_THREE_DAYS);
sprintf(ptr, "%02d", weekval);
ptr += 2;
break;
case 'v':
weekval = helpers::calc_mysql_week( dt.year, dt.month, dt.day,
helpers::WEEK_NO_ZERO | helpers::WEEK_MONDAY_FIRST| helpers::WEEK_GT_THREE_DAYS);
sprintf(ptr, "%02d", weekval);
ptr += 2;
break;
case 'x':
helpers::calc_mysql_week( dt.year, dt.month, dt.day,
helpers::WEEK_NO_ZERO | helpers::WEEK_MONDAY_FIRST | helpers::WEEK_GT_THREE_DAYS, &weekyear);
sprintf(ptr, "%04d", weekyear);
ptr += 4;
break;
case 'X':
helpers::calc_mysql_week( dt.year, dt.month, dt.day,
helpers::WEEK_NO_ZERO, &weekyear);
sprintf(ptr, "%04d", weekyear);
ptr += 4;
break;
default:
*ptr++ = format[i];
}
}
}
*ptr = 0;
return string(buf);
for (uint32_t i = 0; i < format.length(); i++)
{
if (format[i] != '%')
*ptr++ = format[i];
else
{
i++;
switch (format[i])
{
case 'M':
sprintf(ptr, "%s", helpers::monthFullNames[dt.month].c_str());
ptr += helpers::monthFullNames[dt.month].length();
break;
case 'b':
sprintf(ptr, "%s", helpers::monthAbNames[dt.month].c_str());
ptr += helpers::monthAbNames[dt.month].length();
break;
case 'W':
weekday = helpers::calc_mysql_weekday( dt.year, dt.month, dt.day, false);
sprintf(ptr, "%s", helpers::weekdayFullNames[weekday].c_str());
ptr += helpers::weekdayFullNames[weekday].length();
break;
case 'w':
weekday = helpers::calc_mysql_weekday( dt.year, dt.month, dt.day, true);
sprintf(ptr, "%01d", weekday);
ptr += 1;
break;
case 'a':
weekday = helpers::calc_mysql_weekday( dt.year, dt.month, dt.day, false);
sprintf(ptr, "%s", helpers::weekdayAbNames[weekday].c_str());
ptr += helpers::weekdayAbNames[weekday].length();
break;
case 'D':
sprintf(ptr, "%s", helpers::dayOfMonth[dt.day].c_str());
ptr += helpers::dayOfMonth[dt.day].length();
break;
case 'Y':
sprintf(ptr, "%04d", dt.year);
ptr += 4;
break;
case 'y':
sprintf(ptr, "%02d", dt.year % 100);
ptr += 2;
break;
case 'm':
sprintf(ptr, "%02d", dt.month);
ptr += 2;
break;
case 'c':
sprintf(ptr, "%d", dt.month);
ptr = ptr + (dt.month >= 10 ? 2 : 1);
break;
case 'd':
sprintf(ptr, "%02d", dt.day);
ptr += 2;
break;
case 'e':
sprintf(ptr, "%d", dt.day);
ptr = ptr + (dt.day >= 10 ? 2 : 1);
break;
case 'f':
sprintf(ptr, "%06d", dt.msecond);
ptr += 6;
break;
case 'H':
sprintf(ptr, "%02d", dt.hour);
ptr += 2;
break;
case 'h':
case 'I':
sprintf(ptr, "%02d", (dt.hour % 24 + 11) % 12 + 1);
ptr += 2;
break;
case 'i': /* minutes */
sprintf(ptr, "%02d", dt.minute);
ptr += 2;
break;
case 'j':
dayval = helpers::calc_mysql_daynr( dt.year, dt.month, dt.day ) -
helpers::calc_mysql_daynr( dt.year, 1, 1 ) + 1;
sprintf(ptr, "%03d", dayval);
ptr += 3;
break;
case 'k':
sprintf(ptr, "%d", dt.hour);
ptr += (dt.hour >= 10 ? 2 : 1);
break;
case 'l':
sprintf(ptr, "%d", (dt.hour % 24 + 11) % 12 + 1);
ptr += ((dt.hour % 24 + 11) % 12 + 1 >= 10 ? 2 : 1);
break;
case 'p':
sprintf(ptr, "%s", (dt.hour % 24 < 12 ? "AM" : "PM"));
ptr += 2;
break;
case 'r':
sprintf(ptr, (dt.hour % 24 < 12 ? "%02d:%02d:%02d AM" : "%02d:%02d:%02d PM"),
(dt.hour + 11) % 12 + 1, dt.minute, dt.second);
ptr += 11;
break;
case 'S':
case 's':
sprintf(ptr, "%02d", dt.second);
ptr += 2;
break;
case 'T':
sprintf (ptr, "%02d:%02d:%02d", dt.hour, dt.minute, dt.second);
ptr += 8;
break;
case 'U':
weekval = helpers::calc_mysql_week( dt.year, dt.month, dt.day, 0);
sprintf(ptr, "%02d", weekval);
ptr += 2;
break;
case 'V':
weekval = helpers::calc_mysql_week( dt.year, dt.month, dt.day,
helpers::WEEK_NO_ZERO );
sprintf(ptr, "%02d", weekval);
ptr += 2;
break;
case 'u':
weekval = helpers::calc_mysql_week( dt.year, dt.month, dt.day,
helpers::WEEK_MONDAY_FIRST | helpers::WEEK_GT_THREE_DAYS);
sprintf(ptr, "%02d", weekval);
ptr += 2;
break;
case 'v':
weekval = helpers::calc_mysql_week( dt.year, dt.month, dt.day,
helpers::WEEK_NO_ZERO | helpers::WEEK_MONDAY_FIRST | helpers::WEEK_GT_THREE_DAYS);
sprintf(ptr, "%02d", weekval);
ptr += 2;
break;
case 'x':
helpers::calc_mysql_week( dt.year, dt.month, dt.day,
helpers::WEEK_NO_ZERO | helpers::WEEK_MONDAY_FIRST | helpers::WEEK_GT_THREE_DAYS, &weekyear);
sprintf(ptr, "%04d", weekyear);
ptr += 4;
break;
case 'X':
helpers::calc_mysql_week( dt.year, dt.month, dt.day,
helpers::WEEK_NO_ZERO, &weekyear);
sprintf(ptr, "%04d", weekyear);
ptr += 4;
break;
default:
*ptr++ = format[i];
}
}
}
*ptr = 0;
return string(buf);
}
}
CalpontSystemCatalog::ColType Func_date_format::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
CalpontSystemCatalog::ColType ct;
ct.colDataType = CalpontSystemCatalog::VARCHAR;
ct.colWidth = 255;
return ct;
CalpontSystemCatalog::ColType ct;
ct.colDataType = CalpontSystemCatalog::VARCHAR;
ct.colWidth = 255;
return ct;
}
string Func_date_format::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
int64_t val = 0;
DateTime dt = 0;
int64_t val = 0;
DateTime dt = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
dt.year = (uint32_t)((val >> 16) & 0xffff);
dt.month = (uint32_t)((val >> 12) & 0xf);
dt.day = (uint32_t)((val >> 6) & 0x3f);
break;
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getDatetimeIntVal(row, isNull);
dt.year = (uint32_t)((val >> 48) & 0xffff);
dt.month = (uint32_t)((val >> 44) & 0xf);
dt.day = (uint32_t)((val >> 38) & 0x3f);
dt.hour = (uint32_t)((val >> 32) & 0x3f);
dt.minute = (uint32_t)((val >> 26) & 0x3f);
dt.second = (uint32_t)((val >> 20) & 0x3f);
dt.msecond = (uint32_t)((val & 0xfffff));
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::VARCHAR:
case CalpontSystemCatalog::TEXT:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return "";
}
else
{
dt.year = (uint32_t)((val >> 48) & 0xffff);
dt.month = (uint32_t)((val >> 44) & 0xf);
dt.day = (uint32_t)((val >> 38) & 0x3f);
dt.hour = (uint32_t)((val >> 32) & 0x3f);
dt.minute = (uint32_t)((val >> 26) & 0x3f);
dt.second = (uint32_t)((val >> 20) & 0x3f);
dt.msecond = (uint32_t)((val & 0xfffff));
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return "";
}
else
{
dt.year = (uint32_t)((val >> 48) & 0xffff);
dt.month = (uint32_t)((val >> 44) & 0xf);
dt.day = (uint32_t)((val >> 38) & 0x3f);
dt.hour = (uint32_t)((val >> 32) & 0x3f);
dt.minute = (uint32_t)((val >> 26) & 0x3f);
dt.second = (uint32_t)((val >> 20) & 0x3f);
dt.msecond = (uint32_t)((val & 0xfffff));
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return "";
}
else
{
dt.year = (uint32_t)((val >> 48) & 0xffff);
dt.month = (uint32_t)((val >> 44) & 0xf);
dt.day = (uint32_t)((val >> 38) & 0x3f);
dt.hour = (uint32_t)((val >> 32) & 0x3f);
dt.minute = (uint32_t)((val >> 26) & 0x3f);
dt.second = (uint32_t)((val >> 20) & 0x3f);
dt.msecond = (uint32_t)((val & 0xfffff));
}
}
break;
default:
isNull = true;
return "";
}
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
dt.year = (uint32_t)((val >> 16) & 0xffff);
dt.month = (uint32_t)((val >> 12) & 0xf);
dt.day = (uint32_t)((val >> 6) & 0x3f);
break;
const string& format = parm[1]->data()->getStrVal(row, isNull);
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getDatetimeIntVal(row, isNull);
dt.year = (uint32_t)((val >> 48) & 0xffff);
dt.month = (uint32_t)((val >> 44) & 0xf);
dt.day = (uint32_t)((val >> 38) & 0x3f);
dt.hour = (uint32_t)((val >> 32) & 0x3f);
dt.minute = (uint32_t)((val >> 26) & 0x3f);
dt.second = (uint32_t)((val >> 20) & 0x3f);
dt.msecond = (uint32_t)((val & 0xfffff));
break;
return helpers::IDB_date_format(dt, format);
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::VARCHAR:
case CalpontSystemCatalog::TEXT:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return "";
}
else
{
dt.year = (uint32_t)((val >> 48) & 0xffff);
dt.month = (uint32_t)((val >> 44) & 0xf);
dt.day = (uint32_t)((val >> 38) & 0x3f);
dt.hour = (uint32_t)((val >> 32) & 0x3f);
dt.minute = (uint32_t)((val >> 26) & 0x3f);
dt.second = (uint32_t)((val >> 20) & 0x3f);
dt.msecond = (uint32_t)((val & 0xfffff));
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return "";
}
else
{
dt.year = (uint32_t)((val >> 48) & 0xffff);
dt.month = (uint32_t)((val >> 44) & 0xf);
dt.day = (uint32_t)((val >> 38) & 0x3f);
dt.hour = (uint32_t)((val >> 32) & 0x3f);
dt.minute = (uint32_t)((val >> 26) & 0x3f);
dt.second = (uint32_t)((val >> 20) & 0x3f);
dt.msecond = (uint32_t)((val & 0xfffff));
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return "";
}
else
{
dt.year = (uint32_t)((val >> 48) & 0xffff);
dt.month = (uint32_t)((val >> 44) & 0xf);
dt.day = (uint32_t)((val >> 38) & 0x3f);
dt.hour = (uint32_t)((val >> 32) & 0x3f);
dt.minute = (uint32_t)((val >> 26) & 0x3f);
dt.second = (uint32_t)((val >> 20) & 0x3f);
dt.msecond = (uint32_t)((val & 0xfffff));
}
}
break;
default:
isNull = true;
return "";
}
const string& format = parm[1]->data()->getStrVal(row, isNull);
return helpers::IDB_date_format(dt, format);
}
int32_t Func_date_format::getDateIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
return dataconvert::DataConvert::dateToInt(getStrVal(row, parm, isNull, ct));
return dataconvert::DataConvert::dateToInt(getStrVal(row, parm, isNull, ct));
}
int64_t Func_date_format::getDatetimeIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
return dataconvert::DataConvert::datetimeToInt(getStrVal(row, parm, isNull, ct));
return dataconvert::DataConvert::datetimeToInt(getStrVal(row, parm, isNull, ct));
}

View File

@ -38,76 +38,87 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_day::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_day::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
int64_t val = 0;
int64_t val = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
return (uint32_t)((val >> 6) & 0x3f);
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
return (uint32_t)((val >> 38) & 0x3f);
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
return (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
return (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
return (uint32_t)((val >> 38) & 0x3f);
}
}
break;
default:
isNull = true;
return -1;
}
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
return (uint32_t)((val >> 6) & 0x3f);
return -1;
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
return (uint32_t)((val >> 38) & 0x3f);
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
return (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
return (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
return (uint32_t)((val >> 38) & 0x3f);
}
}
break;
default:
isNull = true;
return -1;
}
return -1;
}

View File

@ -39,101 +39,114 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_dayname::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_dayname::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
uint32_t year = 0;
uint32_t month = 0;
uint32_t day = 0;
int64_t val = 0;
int32_t dayofweek= 0;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
year = (uint32_t)((val >> 16) & 0xffff);
month = (uint32_t)((val >> 12) & 0xf);
day = (uint32_t)((val >> 6) & 0x3f);
break;
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
}
break;
default:
isNull = true;
return -1;
}
dayofweek= helpers::calc_mysql_weekday( year, month, day, false);
return dayofweek;
uint32_t year = 0;
uint32_t month = 0;
uint32_t day = 0;
int64_t val = 0;
int32_t dayofweek = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
year = (uint32_t)((val >> 16) & 0xffff);
month = (uint32_t)((val >> 12) & 0xf);
day = (uint32_t)((val >> 6) & 0x3f);
break;
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
}
break;
default:
isNull = true;
return -1;
}
dayofweek = helpers::calc_mysql_weekday( year, month, day, false);
return dayofweek;
}
string Func_dayname::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
uint32_t weekday= getIntVal(row, parm, isNull, op_ct);
return helpers::weekdayFullNames[weekday];
uint32_t weekday = getIntVal(row, parm, isNull, op_ct);
return helpers::weekdayFullNames[weekday];
}

View File

@ -39,90 +39,102 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_dayofweek::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_dayofweek::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
uint32_t year = 0;
uint32_t month = 0;
uint32_t day = 0;
int64_t val = 0;
uint32_t year = 0;
uint32_t month = 0;
uint32_t day = 0;
int64_t val = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
year = (uint32_t)((val >> 16) & 0xffff);
month = (uint32_t)((val >> 12) & 0xf);
day = (uint32_t)((val >> 6) & 0x3f);
break;
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
}
break;
default:
isNull = true;
return -1;
}
return helpers::calc_mysql_weekday(year, month, day, true) + 1;
}
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
year = (uint32_t)((val >> 16) & 0xffff);
month = (uint32_t)((val >> 12) & 0xf);
day = (uint32_t)((val >> 6) & 0x3f);
break;
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
}
break;
default:
isNull = true;
return -1;
}
return helpers::calc_mysql_weekday(year, month, day, true) + 1;
}
} // namespace funcexp

View File

@ -39,91 +39,103 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_dayofyear::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_dayofyear::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
uint32_t year = 0;
uint32_t month = 0;
uint32_t day = 0;
int64_t val = 0;
uint32_t year = 0;
uint32_t month = 0;
uint32_t day = 0;
int64_t val = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
year = (uint32_t)((val >> 16) & 0xffff);
month = (uint32_t)((val >> 12) & 0xf);
day = (uint32_t)((val >> 6) & 0x3f);
break;
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
}
break;
default:
isNull = true;
return -1;
}
return helpers::calc_mysql_daynr(year, month, day) -
helpers::calc_mysql_daynr(year,1,1) + 1;
}
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
year = (uint32_t)((val >> 16) & 0xffff);
month = (uint32_t)((val >> 12) & 0xf);
day = (uint32_t)((val >> 6) & 0x3f);
break;
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
}
break;
default:
isNull = true;
return -1;
}
return helpers::calc_mysql_daynr(year, month, day) -
helpers::calc_mysql_daynr(year, 1, 1) + 1;
}
} // namespace funcexp

View File

@ -41,64 +41,70 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_div::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_div::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
double val1 = parm[0]->data()->getDoubleVal(row, isNull);
double val2 = parm[1]->data()->getDoubleVal(row, isNull);
int64_t int_val2 = (int64_t)(val2 > 0 ? val2 + 0.5 : val2 - 0.5);
if (int_val2 == 0)
{
isNull = true;
double val1 = parm[0]->data()->getDoubleVal(row, isNull);
double val2 = parm[1]->data()->getDoubleVal(row, isNull);
int64_t int_val2 = (int64_t)(val2 > 0 ? val2 + 0.5 : val2 - 0.5);
if (int_val2 == 0)
{
isNull = true;
return 0;
}
int64_t int_val1 = (int64_t)(val1 > 0 ? val1 + 0.5 : val1 - 0.5);
// MCOL-176 If abs(int_val2) is small enough (like -1), then, this may cause overflow.
// This kludge stops the crash.
if (int_val1 == INT64_MIN)
{
--int_val1;
}
return int_val1 / int_val2;
}
int64_t int_val1 = (int64_t)(val1 > 0 ? val1 + 0.5 : val1 - 0.5);
// MCOL-176 If abs(int_val2) is small enough (like -1), then, this may cause overflow.
// This kludge stops the crash.
if (int_val1 == INT64_MIN)
{
--int_val1;
}
return int_val1 / int_val2;
}
uint64_t Func_div::getUintVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
uint64_t val1 = parm[0]->data()->getUintVal(row, isNull);
uint64_t val2 = parm[1]->data()->getUintVal(row, isNull);
if (val2 == 0)
{
isNull = true;
uint64_t val1 = parm[0]->data()->getUintVal(row, isNull);
uint64_t val2 = parm[1]->data()->getUintVal(row, isNull);
if (val2 == 0)
{
isNull = true;
return 0;
}
return val1 / val2;
}
return val1 / val2;
}
double Func_div::getDoubleVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& ct)
{
return getIntVal(row, parm, isNull, ct);
return getIntVal(row, parm, isNull, ct);
}
string Func_div::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
return intToString(getIntVal(row, parm, isNull, ct));
return intToString(getIntVal(row, parm, isNull, ct));
}

View File

@ -39,63 +39,68 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_elt::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
string Func_elt::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
uint64_t number = 0;
uint64_t number = 0;
//get number
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
{
double value = parm[0]->data()->getDoubleVal(row, isNull);
number = (int64_t) value;
break;
}
case CalpontSystemCatalog::DECIMAL:
{
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
number = d.value / helpers::power(d.scale);
int lefto = (d.value - number * helpers::power(d.scale)) / helpers::power(d.scale-1);
if ( number >= 0 && lefto > 4 )
number++;
if ( number < 0 && lefto < -4 )
number--;
break;
}
default:
isNull = true;
return "";
}
//get number
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
{
double value = parm[0]->data()->getDoubleVal(row, isNull);
number = (int64_t) value;
break;
}
if (number < 1)
{
isNull = true;
return "";
}
case CalpontSystemCatalog::DECIMAL:
{
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
number = d.value / helpers::power(d.scale);
int lefto = (d.value - number * helpers::power(d.scale)) / helpers::power(d.scale - 1);
if (number > parm.size()-1 )
{
isNull = true;
return "";
}
if ( number >= 0 && lefto > 4 )
number++;
return stringValue(parm[number], row, isNull);
if ( number < 0 && lefto < -4 )
number--;
break;
}
default:
isNull = true;
return "";
}
if (number < 1)
{
isNull = true;
return "";
}
if (number > parm.size() - 1 )
{
isNull = true;
return "";
}
return stringValue(parm[number], row, isNull);
}

View File

@ -43,40 +43,42 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_exp::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
double Func_exp::getDoubleVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
// null value is indicated by isNull
double x = parm[0]->data()->getDoubleVal(row, isNull);
double ret = 0.0;
if (!isNull)
{
errno = 0;
ret = exp(x);
if (errno == ERANGE) // display NULL for out range value
{
if (x > 0)
{
isNull = true;
Message::Args args;
args.add("exp");
args.add(x);
unsigned errcode = ERR_FUNC_OUT_OF_RANGE_RESULT;
throw IDBExcept(IDBErrorInfo::instance()->errorMsg(errcode, args), errcode);
}
else
ret = 0.0;
}
}
// null value is indicated by isNull
double x = parm[0]->data()->getDoubleVal(row, isNull);
double ret = 0.0;
return ret;
if (!isNull)
{
errno = 0;
ret = exp(x);
if (errno == ERANGE) // display NULL for out range value
{
if (x > 0)
{
isNull = true;
Message::Args args;
args.add("exp");
args.add(x);
unsigned errcode = ERR_FUNC_OUT_OF_RANGE_RESULT;
throw IDBExcept(IDBErrorInfo::instance()->errorMsg(errcode, args), errcode);
}
else
ret = 0.0;
}
}
return ret;
}

View File

@ -40,56 +40,96 @@ using namespace funcexp;
long long dateGet( uint64_t time, IntervalColumn::interval_type unit, bool dateType )
{
uint64_t year = 0,
month = 0,
day = 0,
hour = 0,
min = 0,
sec = 0,
msec = 0;
uint64_t year = 0,
month = 0,
day = 0,
hour = 0,
min = 0,
sec = 0,
msec = 0;
if (dateType)
{
year = (uint32_t)((time >> 16) & 0xffff);
month = (uint32_t)((time >> 12) & 0xf);
day = (uint32_t)((time >> 6) & 0x3f);
}
else
{
year = (uint32_t)((time >> 48) & 0xffff);
month = (uint32_t)((time >> 44) & 0xf);
day = (uint32_t)((time >> 38) & 0x3f);
hour = (uint32_t)((time >> 32) & 0x3f);
min = (uint32_t)((time >> 26) & 0x3f);
sec = (uint32_t)((time >> 20) & 0x3f);
msec = (uint32_t)((time & 0xfffff));
}
if (dateType)
{
year = (uint32_t)((time >> 16) & 0xffff);
month = (uint32_t)((time >> 12) & 0xf);
day = (uint32_t)((time >> 6) & 0x3f);
}
else
{
year = (uint32_t)((time >> 48) & 0xffff);
month = (uint32_t)((time >> 44) & 0xf);
day = (uint32_t)((time >> 38) & 0x3f);
hour = (uint32_t)((time >> 32) & 0x3f);
min = (uint32_t)((time >> 26) & 0x3f);
sec = (uint32_t)((time >> 20) & 0x3f);
msec = (uint32_t)((time & 0xfffff));
}
switch ( unit )
{
case IntervalColumn::INTERVAL_YEAR:
return year;
case IntervalColumn::INTERVAL_MONTH:
return month;
case IntervalColumn::INTERVAL_DAY:
return day;
case IntervalColumn::INTERVAL_HOUR:
return hour;
case IntervalColumn::INTERVAL_MINUTE:
return min;
case IntervalColumn::INTERVAL_SECOND:
return sec;
case IntervalColumn::INTERVAL_MICROSECOND:
return msec;
case IntervalColumn::INTERVAL_QUARTER:
return month / 4 + 1;
switch( unit ) {
case IntervalColumn::INTERVAL_YEAR: return year;
case IntervalColumn::INTERVAL_MONTH: return month;
case IntervalColumn::INTERVAL_DAY: return day;
case IntervalColumn::INTERVAL_HOUR: return hour;
case IntervalColumn::INTERVAL_MINUTE: return min;
case IntervalColumn::INTERVAL_SECOND: return sec;
case IntervalColumn::INTERVAL_MICROSECOND: return msec;
case IntervalColumn::INTERVAL_QUARTER: return month/4+1;
case IntervalColumn::INTERVAL_WEEK:
return helpers::calc_mysql_week(year, month, day, 0);
case IntervalColumn::INTERVAL_YEAR_MONTH: return (year*100)+month;
case IntervalColumn::INTERVAL_DAY_HOUR: return (day*100)+hour;
case IntervalColumn::INTERVAL_DAY_MINUTE: return (day*10000)+(hour*100)+min;
case IntervalColumn::INTERVAL_DAY_SECOND: return (day*1000000)+(hour*10000)+(min*100)+sec;
case IntervalColumn::INTERVAL_HOUR_MINUTE: return (hour*100)+min;
case IntervalColumn::INTERVAL_HOUR_SECOND: return (hour*10000)+(min*100)+sec;
case IntervalColumn::INTERVAL_MINUTE_SECOND: return (min*100)+sec;
case IntervalColumn::INTERVAL_DAY_MICROSECOND: return (((day*1000000)+(hour*10000)+(min*100)+sec)*1000000)+msec;
case IntervalColumn::INTERVAL_HOUR_MICROSECOND: return (((hour*10000)+(min*100)+sec)*1000000)+msec;
case IntervalColumn::INTERVAL_MINUTE_MICROSECOND: return (((min*100)+sec)*1000000)+msec;
case IntervalColumn::INTERVAL_SECOND_MICROSECOND: return (sec*1000000)+msec;
return helpers::calc_mysql_week(year, month, day, 0);
case IntervalColumn::INTERVAL_YEAR_MONTH:
return (year * 100) + month;
case IntervalColumn::INTERVAL_DAY_HOUR:
return (day * 100) + hour;
case IntervalColumn::INTERVAL_DAY_MINUTE:
return (day * 10000) + (hour * 100) + min;
case IntervalColumn::INTERVAL_DAY_SECOND:
return (day * 1000000) + (hour * 10000) + (min * 100) + sec;
case IntervalColumn::INTERVAL_HOUR_MINUTE:
return (hour * 100) + min;
case IntervalColumn::INTERVAL_HOUR_SECOND:
return (hour * 10000) + (min * 100) + sec;
case IntervalColumn::INTERVAL_MINUTE_SECOND:
return (min * 100) + sec;
case IntervalColumn::INTERVAL_DAY_MICROSECOND:
return (((day * 1000000) + (hour * 10000) + (min * 100) + sec) * 1000000) + msec;
case IntervalColumn::INTERVAL_HOUR_MICROSECOND:
return (((hour * 10000) + (min * 100) + sec) * 1000000) + msec;
case IntervalColumn::INTERVAL_MINUTE_MICROSECOND:
return (((min * 100) + sec) * 1000000) + msec;
case IntervalColumn::INTERVAL_SECOND_MICROSECOND:
return (sec * 1000000) + msec;
default:
throw runtime_error("unit type is not supported: " + unit);
};
throw runtime_error("unit type is not supported: " + unit);
};
}
}
@ -98,49 +138,52 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_extract::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_extract::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
IntervalColumn::interval_type unit = static_cast<IntervalColumn::interval_type>(parm[1]->data()->getIntVal(row, isNull));
uint64_t time;
//@bug4678 handle conversion from non date/datetime datatype
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
case CalpontSystemCatalog::DATETIME:
time = parm[0]->data()->getDatetimeIntVal(row, isNull);
break;
case CalpontSystemCatalog::VARCHAR:
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
{
const string& val = parm[0]->data()->getStrVal(row, isNull);
time = dataconvert::DataConvert::stringToDatetime(val);
break;
}
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::SMALLINT:
{
int64_t val = parm[0]->data()->getIntVal(row, isNull);
time = dataconvert::DataConvert::intToDatetime(val);
break;
}
default:
time = parm[0]->data()->getIntVal(row, isNull);
}
uint64_t time;
long long value = dateGet( time, unit, false );
//@bug4678 handle conversion from non date/datetime datatype
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
case CalpontSystemCatalog::DATETIME:
time = parm[0]->data()->getDatetimeIntVal(row, isNull);
break;
return value;
case CalpontSystemCatalog::VARCHAR:
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
{
const string& val = parm[0]->data()->getStrVal(row, isNull);
time = dataconvert::DataConvert::stringToDatetime(val);
break;
}
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::SMALLINT:
{
int64_t val = parm[0]->data()->getIntVal(row, isNull);
time = dataconvert::DataConvert::intToDatetime(val);
break;
}
default:
time = parm[0]->data()->getIntVal(row, isNull);
}
long long value = dateGet( time, unit, false );
return value;
}

View File

@ -47,70 +47,75 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_find_in_set::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_find_in_set::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
const string& searchStr = parm[0]->data()->getStrVal(row, isNull);
if (isNull)
return 0;
const string& setString = parm[1]->data()->getStrVal(row, isNull);
if (isNull)
return 0;
if (searchStr.find(",") != string::npos)
return 0;
string newSearchStr(searchStr.substr(0, strlen(searchStr.c_str())));
string newSetString(setString.substr(0, strlen(setString.c_str())));
//tokenize the setStr with comma as seprator.
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
boost::char_separator<char> sep( ",");
tokenizer tokens(newSetString, sep);
unsigned i = 0;
size_t pos = 0;
for (tokenizer::iterator tok_iter = tokens.begin(); tok_iter != tokens.end(); ++tok_iter)
{
pos = (*tok_iter).find(newSearchStr);
i++;
if (( pos != string::npos) && (newSearchStr.length() == (*tok_iter).length()))
return i;
}
return 0;
const string& searchStr = parm[0]->data()->getStrVal(row, isNull);
if (isNull)
return 0;
const string& setString = parm[1]->data()->getStrVal(row, isNull);
if (isNull)
return 0;
if (searchStr.find(",") != string::npos)
return 0;
string newSearchStr(searchStr.substr(0, strlen(searchStr.c_str())));
string newSetString(setString.substr(0, strlen(setString.c_str())));
//tokenize the setStr with comma as seprator.
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
boost::char_separator<char> sep( ",");
tokenizer tokens(newSetString, sep);
unsigned i = 0;
size_t pos = 0;
for (tokenizer::iterator tok_iter = tokens.begin(); tok_iter != tokens.end(); ++tok_iter)
{
pos = (*tok_iter).find(newSearchStr);
i++;
if (( pos != string::npos) && (newSearchStr.length() == (*tok_iter).length()))
return i;
}
return 0;
}
double Func_find_in_set::getDoubleVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& ct)
{
return (double)getIntVal(row, parm, isNull, ct);
return (double)getIntVal(row, parm, isNull, ct);
}
string Func_find_in_set::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
return intToString(getIntVal(row, parm, isNull, ct));
return intToString(getIntVal(row, parm, isNull, ct));
}
execplan::IDB_Decimal Func_find_in_set::getDecimalVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
IDB_Decimal decimal;
decimal.value = getIntVal(row, fp, isNull, op_ct);
decimal.scale = op_ct.scale;
return decimal;
IDB_Decimal decimal;
decimal.value = getIntVal(row, fp, isNull, op_ct);
decimal.scale = op_ct.scale;
return decimal;
}
} // namespace funcexp

View File

@ -43,60 +43,62 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_floor::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
return fp[0]->data()->resultType();
return fp[0]->data()->resultType();
}
int64_t Func_floor::getIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
int64_t ret = 0;
int64_t ret = 0;
switch (op_ct.colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::DECIMAL:
switch (op_ct.colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
{
if (op_ct.scale == 0)
{
ret = parm[0]->data()->getIntVal(row, isNull);
break;
}
IDB_Decimal decimal = parm[0]->data()->getDecimalVal(row, isNull);
if (isNull)
break;
IDB_Decimal decimal = parm[0]->data()->getDecimalVal(row, isNull);
ret = decimal.value;
// negative scale is not supported by CNX yet
if (decimal.scale > 0)
{
if (isNull)
break;
if (decimal.scale >= 19)
{
std::ostringstream oss;
oss << "floor: datatype of " << execplan::colDataTypeToString(op_ct.colDataType)
<< " with scale " << (int) decimal.scale << " is beyond supported scale";
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
ret = decimal.value;
int64_t tmp = ret;
ret /= helpers::powerOf10_c[decimal.scale];
// negative scale is not supported by CNX yet
if (decimal.scale > 0)
{
if (decimal.scale >= 19)
{
std::ostringstream oss;
oss << "floor: datatype of " << execplan::colDataTypeToString(op_ct.colDataType)
<< " with scale " << (int) decimal.scale << " is beyond supported scale";
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
int64_t tmp = ret;
ret /= helpers::powerOf10_c[decimal.scale];
// Largest integer value not greater than X.
if (tmp < 0 && tmp < ret)
ret -= 1;
}
}
break;
// Largest integer value not greater than X.
if (tmp < 0 && tmp < ret)
ret -= 1;
}
}
break;
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
@ -109,77 +111,79 @@ int64_t Func_floor::getIntVal(Row& row,
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
{
ret = (int64_t) floor(parm[0]->data()->getDoubleVal(row, isNull));
}
break;
{
ret = (int64_t) floor(parm[0]->data()->getDoubleVal(row, isNull));
}
break;
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
if (!isNull)
ret = (int64_t) floor(strtod(str.c_str(), 0));
}
break;
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
case execplan::CalpontSystemCatalog::DATE:
{
string str = DataConvert::dateToString1(parm[0]->data()->getDateIntVal(row, isNull));
if (!isNull)
ret = atoll(str.c_str());
}
break;
if (!isNull)
ret = (int64_t) floor(strtod(str.c_str(), 0));
}
break;
case execplan::CalpontSystemCatalog::DATETIME:
{
string str =
DataConvert::datetimeToString1(parm[0]->data()->getDatetimeIntVal(row, isNull));
case execplan::CalpontSystemCatalog::DATE:
{
string str = DataConvert::dateToString1(parm[0]->data()->getDateIntVal(row, isNull));
// strip off micro seconds
str = str.substr(0,14);
if (!isNull)
ret = atoll(str.c_str());
}
break;
if (!isNull)
ret = atoll(str.c_str());
}
break;
case execplan::CalpontSystemCatalog::DATETIME:
{
string str =
DataConvert::datetimeToString1(parm[0]->data()->getDatetimeIntVal(row, isNull));
default:
{
std::ostringstream oss;
oss << "floor: datatype of " << execplan::colDataTypeToString(op_ct.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
// strip off micro seconds
str = str.substr(0, 14);
return ret;
if (!isNull)
ret = atoll(str.c_str());
}
break;
default:
{
std::ostringstream oss;
oss << "floor: datatype of " << execplan::colDataTypeToString(op_ct.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
return ret;
}
uint64_t Func_floor::getUintVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
int64_t ret = 0;
int64_t ret = 0;
switch (op_ct.colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::DECIMAL:
switch (op_ct.colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
ret = parm[0]->data()->getIntVal(row, isNull);
}
break;
{
ret = parm[0]->data()->getIntVal(row, isNull);
}
break;
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
@ -192,124 +196,131 @@ uint64_t Func_floor::getUintVal(Row& row,
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
{
ret = (uint64_t)floor(parm[0]->data()->getDoubleVal(row, isNull));
}
break;
{
ret = (uint64_t)floor(parm[0]->data()->getDoubleVal(row, isNull));
}
break;
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
if (!isNull)
ret = (uint64_t)floor(strtod(str.c_str(), 0));
}
break;
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
case execplan::CalpontSystemCatalog::DATE:
{
string str = DataConvert::dateToString1(parm[0]->data()->getDateIntVal(row, isNull));
if (!isNull)
ret = strtoull(str.c_str(), NULL, 10);
}
break;
if (!isNull)
ret = (uint64_t)floor(strtod(str.c_str(), 0));
}
break;
case execplan::CalpontSystemCatalog::DATETIME:
{
string str =
DataConvert::datetimeToString1(parm[0]->data()->getDatetimeIntVal(row, isNull));
case execplan::CalpontSystemCatalog::DATE:
{
string str = DataConvert::dateToString1(parm[0]->data()->getDateIntVal(row, isNull));
// strip off micro seconds
str = str.substr(0,14);
if (!isNull)
if (!isNull)
ret = strtoull(str.c_str(), NULL, 10);
}
break;
}
break;
default:
{
std::ostringstream oss;
oss << "floor: datatype of " << execplan::colDataTypeToString(op_ct.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
case execplan::CalpontSystemCatalog::DATETIME:
{
string str =
DataConvert::datetimeToString1(parm[0]->data()->getDatetimeIntVal(row, isNull));
return ret;
// strip off micro seconds
str = str.substr(0, 14);
if (!isNull)
ret = strtoull(str.c_str(), NULL, 10);
}
break;
default:
{
std::ostringstream oss;
oss << "floor: datatype of " << execplan::colDataTypeToString(op_ct.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
return ret;
}
double Func_floor::getDoubleVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
double ret = 0.0;
if (op_ct.colDataType == CalpontSystemCatalog::DOUBLE ||
op_ct.colDataType == CalpontSystemCatalog::FLOAT)
{
ret = floor(parm[0]->data()->getDoubleVal(row, isNull));
}
else if (op_ct.colDataType == CalpontSystemCatalog::VARCHAR ||
op_ct.colDataType == CalpontSystemCatalog::CHAR ||
op_ct.colDataType == CalpontSystemCatalog::TEXT)
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
if (!isNull)
ret = floor(strtod(str.c_str(), 0));
}
else
{
ret = (double) getIntVal(row, parm, isNull, op_ct);
}
double ret = 0.0;
return ret;
if (op_ct.colDataType == CalpontSystemCatalog::DOUBLE ||
op_ct.colDataType == CalpontSystemCatalog::FLOAT)
{
ret = floor(parm[0]->data()->getDoubleVal(row, isNull));
}
else if (op_ct.colDataType == CalpontSystemCatalog::VARCHAR ||
op_ct.colDataType == CalpontSystemCatalog::CHAR ||
op_ct.colDataType == CalpontSystemCatalog::TEXT)
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
if (!isNull)
ret = floor(strtod(str.c_str(), 0));
}
else
{
ret = (double) getIntVal(row, parm, isNull, op_ct);
}
return ret;
}
string Func_floor::getStrVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
char tmp[512] = {'\0'};
if (op_ct.colDataType == CalpontSystemCatalog::DOUBLE ||
op_ct.colDataType == CalpontSystemCatalog::UDOUBLE ||
op_ct.colDataType == CalpontSystemCatalog::FLOAT ||
op_ct.colDataType == CalpontSystemCatalog::UFLOAT ||
op_ct.colDataType == CalpontSystemCatalog::VARCHAR ||
op_ct.colDataType == CalpontSystemCatalog::CHAR ||
op_ct.colDataType == CalpontSystemCatalog::TEXT)
{
snprintf(tmp, 511, "%f", getDoubleVal(row, parm, isNull, op_ct));
char tmp[512] = {'\0'};
// remove the decimals in the oss string.
char *d = tmp;
while ((*d != '.') && (*d != '\0'))
d++;
*d = '\0';
}
else if (isUnsigned(op_ct.colDataType))
{
if (op_ct.colDataType == CalpontSystemCatalog::DOUBLE ||
op_ct.colDataType == CalpontSystemCatalog::UDOUBLE ||
op_ct.colDataType == CalpontSystemCatalog::FLOAT ||
op_ct.colDataType == CalpontSystemCatalog::UFLOAT ||
op_ct.colDataType == CalpontSystemCatalog::VARCHAR ||
op_ct.colDataType == CalpontSystemCatalog::CHAR ||
op_ct.colDataType == CalpontSystemCatalog::TEXT)
{
snprintf(tmp, 511, "%f", getDoubleVal(row, parm, isNull, op_ct));
// remove the decimals in the oss string.
char* d = tmp;
while ((*d != '.') && (*d != '\0'))
d++;
*d = '\0';
}
else if (isUnsigned(op_ct.colDataType))
{
#ifndef __LP64__
snprintf(tmp, 511, "%llu", getUintVal(row, parm, isNull, op_ct));
#else
snprintf(tmp, 511, "%lu", getUintVal(row, parm, isNull, op_ct));
#endif
}
else
{
else
{
#ifndef __LP64__
snprintf(tmp, 511, "%lld", getIntVal(row, parm, isNull, op_ct));
#else
snprintf(tmp, 511, "%ld", getIntVal(row, parm, isNull, op_ct));
#endif
}
}
return string(tmp);
return string(tmp);
}

View File

@ -40,51 +40,51 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_from_days::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_from_days::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
return getDatetimeIntVal(row, parm, isNull, op_ct);
return getDatetimeIntVal(row, parm, isNull, op_ct);
}
string Func_from_days::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
return intToString(getIntVal(row, parm, isNull, ct));
return intToString(getIntVal(row, parm, isNull, ct));
}
int32_t Func_from_days::getDateIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
return (((getDatetimeIntVal(row, parm, isNull, ct) >> 32) & 0xFFFFFFC0) | 0x3E);
return (((getDatetimeIntVal(row, parm, isNull, ct) >> 32) & 0xFFFFFFC0) | 0x3E);
}
int64_t Func_from_days::getDatetimeIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
double val1 = parm[0]->data()->getDoubleVal(row, isNull);
int64_t daynr = (int64_t)(val1 > 0 ? val1 + 0.5 : val1 - 0.5);
double val1 = parm[0]->data()->getDoubleVal(row, isNull);
int64_t daynr = (int64_t)(val1 > 0 ? val1 + 0.5 : val1 - 0.5);
DateTime aDaytime;
helpers::get_date_from_mysql_daynr( daynr, aDaytime );
// to be safe
aDaytime.hour = 0;
aDaytime.minute = 0;
aDaytime.second = 0;
aDaytime.msecond = 0;
DateTime aDaytime;
helpers::get_date_from_mysql_daynr( daynr, aDaytime );
return (*(reinterpret_cast<uint64_t *> (&aDaytime)));
// to be safe
aDaytime.hour = 0;
aDaytime.minute = 0;
aDaytime.second = 0;
aDaytime.msecond = 0;
return (*(reinterpret_cast<uint64_t*> (&aDaytime)));
}

View File

@ -42,46 +42,50 @@ namespace
using namespace funcexp;
DateTime getDateTime(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull)
FunctionParm& parm,
bool& isNull)
{
int64_t val;
switch (parm[0]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::DECIMAL:
{
double value = parm[0]->data()->getDoubleVal(row, isNull);
if (value > 0)
value += 0.5;
else if (value < 0)
value -= 0.5;
val = (int64_t)value;
break;
}
default:
val = parm[0]->data()->getDatetimeIntVal(row, isNull);
}
if (val < 0 || val > helpers::TIMESTAMP_MAX_VALUE)
return 0;
int64_t val;
DateTime dt;
switch (parm[0]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::DECIMAL:
{
double value = parm[0]->data()->getDoubleVal(row, isNull);
struct tm tmp_tm;
time_t tmp_t= (time_t)val;
localtime_r(&tmp_t, &tmp_tm);
if (value > 0)
value += 0.5;
else if (value < 0)
value -= 0.5;
//to->neg=0;
dt.year = (int64_t) ((tmp_tm.tm_year+1900) % 10000);
dt.month = (int64_t) tmp_tm.tm_mon+1;
dt.day = (int64_t) tmp_tm.tm_mday;
dt.hour = (int64_t) tmp_tm.tm_hour;
dt.minute = (int64_t) tmp_tm.tm_min;
dt.second = (int64_t) tmp_tm.tm_sec;
dt.msecond = 0;
return dt;
val = (int64_t)value;
break;
}
default:
val = parm[0]->data()->getDatetimeIntVal(row, isNull);
}
if (val < 0 || val > helpers::TIMESTAMP_MAX_VALUE)
return 0;
DateTime dt;
struct tm tmp_tm;
time_t tmp_t = (time_t)val;
localtime_r(&tmp_t, &tmp_tm);
//to->neg=0;
dt.year = (int64_t) ((tmp_tm.tm_year + 1900) % 10000);
dt.month = (int64_t) tmp_tm.tm_mon + 1;
dt.day = (int64_t) tmp_tm.tm_mday;
dt.hour = (int64_t) tmp_tm.tm_hour;
dt.minute = (int64_t) tmp_tm.tm_min;
dt.second = (int64_t) tmp_tm.tm_sec;
dt.msecond = 0;
return dt;
}
}
@ -90,96 +94,103 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_from_unixtime::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
CalpontSystemCatalog::ColType ct;
ct.colDataType = CalpontSystemCatalog::VARCHAR;
ct.colWidth = 255;
return ct;
CalpontSystemCatalog::ColType ct;
ct.colDataType = CalpontSystemCatalog::VARCHAR;
ct.colWidth = 255;
return ct;
}
string Func_from_unixtime::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
DateTime dt = getDateTime(row, parm, isNull);
if (*reinterpret_cast<int64_t*>(&dt) == 0)
{
isNull = true;
return "";
}
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
DateTime dt = getDateTime(row, parm, isNull);
if (parm.size() == 2)
{
const string& format = parm[1]->data()->getStrVal(row, isNull);
return helpers::IDB_date_format(dt, format);
}
char buf[256] = {0};
DataConvert::datetimeToString(*(reinterpret_cast<int64_t*>(&dt)), buf, 255);
return string(buf, 255);
if (*reinterpret_cast<int64_t*>(&dt) == 0)
{
isNull = true;
return "";
}
if (parm.size() == 2)
{
const string& format = parm[1]->data()->getStrVal(row, isNull);
return helpers::IDB_date_format(dt, format);
}
char buf[256] = {0};
DataConvert::datetimeToString(*(reinterpret_cast<int64_t*>(&dt)), buf, 255);
return string(buf, 255);
}
int32_t Func_from_unixtime::getDateIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
return (((getDatetimeIntVal(row, parm, isNull, ct) >> 32) & 0xFFFFFFC0) | 0x3E);
}
return (((getDatetimeIntVal(row, parm, isNull, ct) >> 32) & 0xFFFFFFC0) | 0x3E);
}
int64_t Func_from_unixtime::getDatetimeIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
DateTime dt = getDateTime(row, parm, isNull);
if (*reinterpret_cast<int64_t*>(&dt) == 0)
{
isNull = true;
return 0;
}
return *reinterpret_cast<int64_t*>(&dt);
DateTime dt = getDateTime(row, parm, isNull);
if (*reinterpret_cast<int64_t*>(&dt) == 0)
{
isNull = true;
return 0;
}
return *reinterpret_cast<int64_t*>(&dt);
}
int64_t Func_from_unixtime::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
DateTime dt = getDateTime(row, parm, isNull);
if (*reinterpret_cast<int64_t*>(&dt) == 0)
{
isNull = true;
return 0;
}
char buf[32]; // actual string guaranteed to be 22
snprintf( buf, 32, "%04d%02d%02d%02d%02d%02d",
dt.year, dt.month, dt.day, dt.hour,
dt.minute, dt.second );
return atoll(buf);
DateTime dt = getDateTime(row, parm, isNull);
if (*reinterpret_cast<int64_t*>(&dt) == 0)
{
isNull = true;
return 0;
}
char buf[32]; // actual string guaranteed to be 22
snprintf( buf, 32, "%04d%02d%02d%02d%02d%02d",
dt.year, dt.month, dt.day, dt.hour,
dt.minute, dt.second );
return atoll(buf);
}
double Func_from_unixtime::getDoubleVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
if (parm.size() == 1)
{
DateTime dt = getDateTime(row, parm, isNull);
if (*reinterpret_cast<int64_t*>(&dt) == 0)
{
isNull = true;
return 0;
}
if (parm.size() == 1)
{
DateTime dt = getDateTime(row, parm, isNull);
if (*reinterpret_cast<int64_t*>(&dt) == 0)
{
isNull = true;
return 0;
}
char buf[32]; // actual string guaranteed to be 22
snprintf( buf, 32, "%04d%02d%02d%02d%02d%02d.%06d",
dt.year, dt.month, dt.day, dt.hour,
dt.minute, dt.second, dt.msecond );
return atof(buf);
}
dt.minute, dt.second, dt.msecond );
return atof(buf);
}
return (double) atoi(getStrVal(row, parm, isNull, ct).c_str());
return (double) atoi(getStrVal(row, parm, isNull, ct).c_str());
}

View File

@ -36,81 +36,86 @@ using namespace dataconvert;
class to_upper
{
public:
char operator() (char c) const // notice the return type
{
return toupper(c);
}
public:
char operator() (char c) const // notice the return type
{
return toupper(c);
}
};
namespace funcexp
{
string known_date_time_formats[5][4]=
string known_date_time_formats[5][4] =
{
{"USA", "%m.%d.%Y", "%Y-%m-%d %H.%i.%s", "%h:%i:%s %p" },
{"JIS", "%Y-%m-%d", "%Y-%m-%d %H:%i:%s", "%H:%i:%s" },
{"ISO", "%Y-%m-%d", "%Y-%m-%d %H:%i:%s", "%H:%i:%s" },
{"EUR", "%d.%m.%Y", "%Y-%m-%d %H.%i.%s", "%H.%i.%s" },
{"INTERNAL", "%Y%m%d", "%Y%m%d%H%i%s", "%H%i%s" }
{"USA", "%m.%d.%Y", "%Y-%m-%d %H.%i.%s", "%h:%i:%s %p" },
{"JIS", "%Y-%m-%d", "%Y-%m-%d %H:%i:%s", "%H:%i:%s" },
{"ISO", "%Y-%m-%d", "%Y-%m-%d %H:%i:%s", "%H:%i:%s" },
{"EUR", "%d.%m.%Y", "%Y-%m-%d %H.%i.%s", "%H.%i.%s" },
{"INTERNAL", "%Y%m%d", "%Y%m%d%H%i%s", "%H%i%s" }
};
string know_types[3]=
string know_types[3] =
{
"DATE", "DATETIME", "TIME"
"DATE", "DATETIME", "TIME"
};
CalpontSystemCatalog::ColType Func_get_format::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
string Func_get_format::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
// parm[0] -- format
// parm[1] -- type
string format = parm[0]->data()->getStrVal(row, isNull);
if (isNull)
return "";
// parm[0] -- format
// parm[1] -- type
string format = parm[0]->data()->getStrVal(row, isNull);
transform (format.begin(), format.end(), format.begin(), to_upper());
if (isNull)
return "";
string type = parm[1]->data()->getStrVal(row, isNull);
if (isNull)
return "";
transform (format.begin(), format.end(), format.begin(), to_upper());
transform (type.begin(), type.end(), type.begin(), to_upper());
string type = parm[1]->data()->getStrVal(row, isNull);
int itype = 0;
for ( ; itype < 3 ; itype++ )
{
if ( know_types[itype] == type )
break;
}
if (isNull)
return "";
// check for match
if ( itype == 3 )
return "";
transform (type.begin(), type.end(), type.begin(), to_upper());
for ( int i = 0 ; i < 5 ; i ++ )
{
if ( known_date_time_formats[i][0] == format )
{
switch (itype) {
case 0:
return known_date_time_formats[i][2];
break;
default:
return "";
}
}
}
int itype = 0;
return "";
for ( ; itype < 3 ; itype++ )
{
if ( know_types[itype] == type )
break;
}
// check for match
if ( itype == 3 )
return "";
for ( int i = 0 ; i < 5 ; i ++ )
{
if ( known_date_time_formats[i][0] == format )
{
switch (itype)
{
case 0:
return known_date_time_formats[i][2];
break;
default:
return "";
}
}
}
return "";
}

View File

@ -42,11 +42,11 @@ using namespace funcexp;
class to_lower
{
public:
char operator() (char c) const // notice the return type
{
return tolower(c);
}
public:
char operator() (char c) const // notice the return type
{
return tolower(c);
}
};
@ -55,146 +55,155 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_greatest::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
//return fp[0]->data()->resultType();
return resultType;
// operation type is not used by this functor
//return fp[0]->data()->resultType();
return resultType;
}
int64_t Func_greatest::getIntVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
double str = fp[0]->data()->getDoubleVal(row, isNull);
double str = fp[0]->data()->getDoubleVal(row, isNull);
double greatestStr = str;
for (uint32_t i = 1; i < fp.size(); i++)
{
double str1 = fp[i]->data()->getDoubleVal(row, isNull);
double greatestStr = str;
for (uint32_t i = 1; i < fp.size(); i++)
{
double str1 = fp[i]->data()->getDoubleVal(row, isNull);
if ( greatestStr < str1 )
greatestStr = str1;
}
if ( greatestStr < str1 )
greatestStr = str1;
}
uint64_t tmp = (uint64_t)greatestStr;
return (int64_t) tmp;
return (int64_t) tmp;
}
uint64_t Func_greatest::getUintVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
double str = fp[0]->data()->getDoubleVal(row, isNull);
double str = fp[0]->data()->getDoubleVal(row, isNull);
double greatestStr = str;
for (uint32_t i = 1; i < fp.size(); i++)
{
double str1 = fp[i]->data()->getDoubleVal(row, isNull);
double greatestStr = str;
if ( greatestStr < str1 )
greatestStr = str1;
}
for (uint32_t i = 1; i < fp.size(); i++)
{
double str1 = fp[i]->data()->getDoubleVal(row, isNull);
return (uint64_t) greatestStr;
if ( greatestStr < str1 )
greatestStr = str1;
}
return (uint64_t) greatestStr;
}
double Func_greatest::getDoubleVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
double str = fp[0]->data()->getDoubleVal(row, isNull);
double str = fp[0]->data()->getDoubleVal(row, isNull);
double greatestStr = str;
for (uint32_t i = 1; i < fp.size(); i++)
{
double str1 = fp[i]->data()->getDoubleVal(row, isNull);
double greatestStr = str;
if ( greatestStr < str1 )
greatestStr = str1;
}
for (uint32_t i = 1; i < fp.size(); i++)
{
double str1 = fp[i]->data()->getDoubleVal(row, isNull);
return (double) greatestStr;
if ( greatestStr < str1 )
greatestStr = str1;
}
return (double) greatestStr;
}
std::string Func_greatest::getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
const string& str = fp[0]->data()->getStrVal(row, isNull);
const string& str = fp[0]->data()->getStrVal(row, isNull);
string greatestStr = str;
for (uint32_t i = 1; i < fp.size(); i++)
{
const string& str1 = fp[i]->data()->getStrVal(row, isNull);
string greatestStr = str;
int tmp = utf8::idb_strcoll(greatestStr.c_str(), str1.c_str());
if ( tmp < 0 )
for (uint32_t i = 1; i < fp.size(); i++)
{
const string& str1 = fp[i]->data()->getStrVal(row, isNull);
int tmp = utf8::idb_strcoll(greatestStr.c_str(), str1.c_str());
if ( tmp < 0 )
// if ( greatestStr < str1 )
greatestStr = str1;
}
greatestStr = str1;
}
return greatestStr;
return greatestStr;
}
IDB_Decimal Func_greatest::getDecimalVal(Row& row,
FunctionParm& fp,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& fp,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
// double str = fp[0]->data()->getDoubleVal(row, isNull);
IDB_Decimal str = fp[0]->data()->getDecimalVal(row, isNull);
IDB_Decimal str = fp[0]->data()->getDecimalVal(row, isNull);
IDB_Decimal greatestStr = str;
for (uint32_t i = 1; i < fp.size(); i++)
{
IDB_Decimal str1 = fp[i]->data()->getDecimalVal(row, isNull);
IDB_Decimal greatestStr = str;
if ( greatestStr < str1 )
greatestStr = str1;
}
for (uint32_t i = 1; i < fp.size(); i++)
{
IDB_Decimal str1 = fp[i]->data()->getDecimalVal(row, isNull);
return greatestStr;
if ( greatestStr < str1 )
greatestStr = str1;
}
return greatestStr;
}
int32_t Func_greatest::getDateIntVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& ct)
{
int32_t str = fp[0]->data()->getDateIntVal(row, isNull);
int32_t str = fp[0]->data()->getDateIntVal(row, isNull);
int32_t greatestStr = str;
for (uint32_t i = 1; i < fp.size(); i++)
{
int32_t str1 = fp[i]->data()->getDateIntVal(row, isNull);
int32_t greatestStr = str;
if ( greatestStr < str1 )
greatestStr = str1;
}
for (uint32_t i = 1; i < fp.size(); i++)
{
int32_t str1 = fp[i]->data()->getDateIntVal(row, isNull);
return greatestStr;
if ( greatestStr < str1 )
greatestStr = str1;
}
return greatestStr;
}
int64_t Func_greatest::getDatetimeIntVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& ct)
{
int64_t str = fp[0]->data()->getDatetimeIntVal(row, isNull);
int64_t str = fp[0]->data()->getDatetimeIntVal(row, isNull);
int64_t greatestStr = str;
for (uint32_t i = 1; i < fp.size(); i++)
{
int64_t str1 = fp[i]->data()->getDatetimeIntVal(row, isNull);
int64_t greatestStr = str;
if ( greatestStr < str1 )
greatestStr = str1;
}
for (uint32_t i = 1; i < fp.size(); i++)
{
int64_t str1 = fp[i]->data()->getDatetimeIntVal(row, isNull);
return greatestStr;
if ( greatestStr < str1 )
greatestStr = str1;
}
return greatestStr;
}
} // namespace funcexp

View File

@ -41,15 +41,17 @@ namespace
{
char digit_upper[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
void octet2hex(char *to, const char *str, uint32_t len)
void octet2hex(char* to, const char* str, uint32_t len)
{
const char *str_end= str + len;
for (; str != str_end; ++str)
{
*to++= digit_upper[((uint8_t) *str) >> 4];
*to++= digit_upper[((uint8_t) *str) & 0x0F];
}
*to = '\0';
const char* str_end = str + len;
for (; str != str_end; ++str)
{
*to++ = digit_upper[((uint8_t) * str) >> 4];
*to++ = digit_upper[((uint8_t) * str) & 0x0F];
}
*to = '\0';
}
}
@ -57,64 +59,70 @@ namespace funcexp
{
CalpontSystemCatalog::ColType Func_hex::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
string Func_hex::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
string retval;
uint64_t dec;
char ans[65];
uint64_t dec;
char ans[65];
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
case CalpontSystemCatalog::DATETIME:
case CalpontSystemCatalog::DATE:
{
const string& arg= parm[0]->data()->getStrVal(row, isNull);
scoped_array<char> hexPtr(new char[strlen(arg.c_str())*2+1]);
octet2hex(hexPtr.get(), arg.c_str(), strlen(arg.c_str()));
return string(hexPtr.get(), strlen(arg.c_str())*2);
}
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::DECIMAL:
{
/* Return hex of unsigned longlong value */
double val= parm[0]->data()->getDoubleVal(row, isNull);
if ((val <= (double) numeric_limits<int64_t>::min()) ||
(val >= (double) numeric_limits<int64_t>::max()))
dec= ~(int64_t) 0;
else
dec= (uint64_t) (val + (val > 0 ? 0.5 : -0.5));
retval = helpers::convNumToStr(dec, ans, 16);
break;
}
case CalpontSystemCatalog::VARBINARY:
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
case CalpontSystemCatalog::DATETIME:
case CalpontSystemCatalog::DATE:
{
const string& arg = parm[0]->data()->getStrVal(row, isNull);
scoped_array<char> hexPtr(new char[strlen(arg.c_str()) * 2 + 1]);
octet2hex(hexPtr.get(), arg.c_str(), strlen(arg.c_str()));
return string(hexPtr.get(), strlen(arg.c_str()) * 2);
}
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::DECIMAL:
{
/* Return hex of unsigned longlong value */
double val = parm[0]->data()->getDoubleVal(row, isNull);
if ((val <= (double) numeric_limits<int64_t>::min()) ||
(val >= (double) numeric_limits<int64_t>::max()))
dec = ~(int64_t) 0;
else
dec = (uint64_t) (val + (val > 0 ? 0.5 : -0.5));
retval = helpers::convNumToStr(dec, ans, 16);
break;
}
case CalpontSystemCatalog::VARBINARY:
case CalpontSystemCatalog::BLOB:
{
const string& arg = parm[0]->data()->getStrVal(row, isNull);
uint64_t hexLen = arg.size() * 2;
scoped_array<char> hexPtr(new char[hexLen + 1]); // "+ 1" for the last \0
octet2hex(hexPtr.get(), arg.data(), arg.size());
return string(hexPtr.get(), hexLen);
}
default:
{
dec= (uint64_t)parm[0]->data()->getIntVal(row, isNull);
retval = helpers::convNumToStr(dec, ans, 16);
if (retval.length() > (uint32_t)ct.colWidth)
retval = retval.substr(retval.length()-ct.colWidth, ct.colWidth);
}
}
{
const string& arg = parm[0]->data()->getStrVal(row, isNull);
uint64_t hexLen = arg.size() * 2;
scoped_array<char> hexPtr(new char[hexLen + 1]); // "+ 1" for the last \0
octet2hex(hexPtr.get(), arg.data(), arg.size());
return string(hexPtr.get(), hexLen);
}
return retval;
default:
{
dec = (uint64_t)parm[0]->data()->getIntVal(row, isNull);
retval = helpers::convNumToStr(dec, ans, 16);
if (retval.length() > (uint32_t)ct.colWidth)
retval = retval.substr(retval.length() - ct.colWidth, ct.colWidth);
}
}
return retval;
}

View File

@ -38,74 +38,89 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_hour::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_hour::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
int64_t val = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
isNull = true;
break;
}
case execplan::CalpontSystemCatalog::DECIMAL:
{
if (parm[0]->data()->resultType().scale)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
isNull = true;
}
break;
}
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
{
isNull = true;
}
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
isNull = true;
break;
}
case execplan::CalpontSystemCatalog::DATE:
{
val = parm[0]->data()->getDatetimeIntVal(row, isNull);
break;
}
case execplan::CalpontSystemCatalog::DATETIME:
{
val = parm[0]->data()->getDatetimeIntVal(row, isNull);
break;
}
default:
{
isNull = true;
}
}
if (isNull)
return -1;
if ( val < 1000000000 )
return 0;
return (uint32_t)((val >> 32) & 0x3f);
int64_t val = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
isNull = true;
break;
}
case execplan::CalpontSystemCatalog::DECIMAL:
{
if (parm[0]->data()->resultType().scale)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
isNull = true;
}
break;
}
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
{
isNull = true;
}
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
isNull = true;
break;
}
case execplan::CalpontSystemCatalog::DATE:
{
val = parm[0]->data()->getDatetimeIntVal(row, isNull);
break;
}
case execplan::CalpontSystemCatalog::DATETIME:
{
val = parm[0]->data()->getDatetimeIntVal(row, isNull);
break;
}
default:
{
isNull = true;
}
}
if (isNull)
return -1;
if ( val < 1000000000 )
return 0;
return (uint32_t)((val >> 32) & 0x3f);
}

View File

@ -45,24 +45,24 @@ namespace funcexp
{
CalpontSystemCatalog::ColType Func_idbpartition::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// all integer
CalpontSystemCatalog::ColType ct;
ct.colDataType = CalpontSystemCatalog::BIGINT;
ct.colWidth = 8;
return ct;
// all integer
CalpontSystemCatalog::ColType ct;
ct.colDataType = CalpontSystemCatalog::BIGINT;
ct.colWidth = 8;
return ct;
}
string Func_idbpartition::getStrVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
LogicalPartition part(
parm[0]->data()->getIntVal(row, isNull),
parm[1]->data()->getIntVal(row, isNull),
parm[2]->data()->getIntVal(row, isNull));
LogicalPartition part(
parm[0]->data()->getIntVal(row, isNull),
parm[1]->data()->getIntVal(row, isNull),
parm[2]->data()->getIntVal(row, isNull));
return part.toString();
return part.toString();
}

View File

@ -37,45 +37,50 @@ namespace
bool boolVal(SPTP& parm, Row& row)
{
bool ret = true;
bool isNull = false; // Keep it local. We don't want to mess with the global one here.
try
{
ret = parm->getBoolVal(row, isNull);
}
catch (logging::NotImplementedExcept&)
{
switch (parm->data()->resultType().colDataType)
{
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
ret = (atoi((char*)(parm->data()->getStrVal().c_str())) != 0);
bool ret = true;
bool isNull = false; // Keep it local. We don't want to mess with the global one here.
try
{
ret = parm->getBoolVal(row, isNull);
}
catch (logging::NotImplementedExcept&)
{
switch (parm->data()->resultType().colDataType)
{
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
ret = (atoi((char*)(parm->data()->getStrVal().c_str())) != 0);
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::UFLOAT:
ret = (parm->data()->getFloatVal(row, isNull) != 0);
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::UFLOAT:
ret = (parm->data()->getFloatVal(row, isNull) != 0);
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::UDOUBLE:
ret = (parm->data()->getDoubleVal(row, isNull) != 0);
ret = (parm->data()->getDoubleVal(row, isNull) != 0);
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
ret = (parm->data()->getDecimalVal(row, isNull).value != 0);
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::INT:
ret = (parm->data()->getDecimalVal(row, isNull).value != 0);
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::UBIGINT:
case CalpontSystemCatalog::USMALLINT:
case CalpontSystemCatalog::UMEDINT:
case CalpontSystemCatalog::UINT:
case CalpontSystemCatalog::DATE:
case CalpontSystemCatalog::DATETIME:
default:
ret = (parm->data()->getIntVal(row, isNull) != 0);
}
}
case CalpontSystemCatalog::DATE:
case CalpontSystemCatalog::DATETIME:
default:
ret = (parm->data()->getIntVal(row, isNull) != 0);
}
}
return ret;
return ret;
}
}
@ -91,127 +96,127 @@ namespace funcexp
//
CalpontSystemCatalog::ColType Func_if::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
// The result type given by the connector may not be right if there's derived table (MySQL bug?)
// We want to double check on our own.
// If any parm is of string type, the result type should be string.
if (fp[1]->data()->resultType().colDataType == CalpontSystemCatalog::CHAR ||
fp[1]->data()->resultType().colDataType == CalpontSystemCatalog::VARCHAR ||
fp[1]->data()->resultType().colDataType == CalpontSystemCatalog::TEXT ||
fp[2]->data()->resultType().colDataType == CalpontSystemCatalog::CHAR ||
fp[2]->data()->resultType().colDataType == CalpontSystemCatalog::TEXT ||
fp[2]->data()->resultType().colDataType == CalpontSystemCatalog::VARCHAR)
{
CalpontSystemCatalog::ColType ct;
ct.colDataType = CalpontSystemCatalog::VARCHAR;
ct.colWidth = 255;
resultType = ct;
return ct;
}
// operation type is not used by this functor
// The result type given by the connector may not be right if there's derived table (MySQL bug?)
// We want to double check on our own.
// If any parm is of string type, the result type should be string.
if (fp[1]->data()->resultType().colDataType == CalpontSystemCatalog::CHAR ||
fp[1]->data()->resultType().colDataType == CalpontSystemCatalog::VARCHAR ||
fp[1]->data()->resultType().colDataType == CalpontSystemCatalog::TEXT ||
fp[2]->data()->resultType().colDataType == CalpontSystemCatalog::CHAR ||
fp[2]->data()->resultType().colDataType == CalpontSystemCatalog::TEXT ||
fp[2]->data()->resultType().colDataType == CalpontSystemCatalog::VARCHAR)
{
CalpontSystemCatalog::ColType ct;
ct.colDataType = CalpontSystemCatalog::VARCHAR;
ct.colWidth = 255;
resultType = ct;
return ct;
}
CalpontSystemCatalog::ColType ct = fp[1]->data()->resultType();
PredicateOperator op;
op.setOpType(ct, fp[2]->data()->resultType());
ct = op.operationType();
resultType = ct;
return ct;
CalpontSystemCatalog::ColType ct = fp[1]->data()->resultType();
PredicateOperator op;
op.setOpType(ct, fp[2]->data()->resultType());
ct = op.operationType();
resultType = ct;
return ct;
}
int64_t Func_if::getIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
if (boolVal(parm[0], row))
{
return parm[1]->data()->getIntVal(row, isNull);
}
else
{
return parm[2]->data()->getIntVal(row, isNull);
}
if (boolVal(parm[0], row))
{
return parm[1]->data()->getIntVal(row, isNull);
}
else
{
return parm[2]->data()->getIntVal(row, isNull);
}
}
string Func_if::getStrVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
if (boolVal(parm[0], row))
{
return parm[1]->data()->getStrVal(row, isNull);
}
else
{
return parm[2]->data()->getStrVal(row, isNull);
}
if (boolVal(parm[0], row))
{
return parm[1]->data()->getStrVal(row, isNull);
}
else
{
return parm[2]->data()->getStrVal(row, isNull);
}
}
IDB_Decimal Func_if::getDecimalVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
if (boolVal(parm[0], row))
{
return parm[1]->data()->getDecimalVal(row, isNull);
}
else
{
return parm[2]->data()->getDecimalVal(row, isNull);
}
if (boolVal(parm[0], row))
{
return parm[1]->data()->getDecimalVal(row, isNull);
}
else
{
return parm[2]->data()->getDecimalVal(row, isNull);
}
}
double Func_if::getDoubleVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
if (boolVal(parm[0], row))
{
return parm[1]->data()->getDoubleVal(row, isNull);
}
else
{
return parm[2]->data()->getDoubleVal(row, isNull);
}
if (boolVal(parm[0], row))
{
return parm[1]->data()->getDoubleVal(row, isNull);
}
else
{
return parm[2]->data()->getDoubleVal(row, isNull);
}
}
int32_t Func_if::getDateIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
if (boolVal(parm[0], row))
{
return parm[1]->data()->getDateIntVal(row, isNull);
}
else
{
return parm[2]->data()->getDateIntVal(row, isNull);
}
if (boolVal(parm[0], row))
{
return parm[1]->data()->getDateIntVal(row, isNull);
}
else
{
return parm[2]->data()->getDateIntVal(row, isNull);
}
}
int64_t Func_if::getDatetimeIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
if (boolVal(parm[0], row))
{
return parm[1]->data()->getDatetimeIntVal(row, isNull);
}
else
{
return parm[2]->data()->getDatetimeIntVal(row, isNull);
}
if (boolVal(parm[0], row))
{
return parm[1]->data()->getDatetimeIntVal(row, isNull);
}
else
{
return parm[2]->data()->getDatetimeIntVal(row, isNull);
}
}

View File

@ -45,130 +45,136 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_ifnull::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
int64_t Func_ifnull::getIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
if (isNull)
return 0;
if (isNull)
return 0;
int64_t r = parm[0]->data()->getIntVal(row, isNull);
if (isNull)
{
isNull = false;
return parm[1]->data()->getIntVal(row, isNull);
}
int64_t r = parm[0]->data()->getIntVal(row, isNull);
return r;
if (isNull)
{
isNull = false;
return parm[1]->data()->getIntVal(row, isNull);
}
return r;
}
string Func_ifnull::getStrVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
if (isNull)
return string();
if (isNull)
return string();
const string& r = parm[0]->data()->getStrVal(row, isNull);
if (isNull)
{
isNull = false;
return parm[1]->data()->getStrVal(row, isNull);
}
const string& r = parm[0]->data()->getStrVal(row, isNull);
return r;
if (isNull)
{
isNull = false;
return parm[1]->data()->getStrVal(row, isNull);
}
return r;
}
IDB_Decimal Func_ifnull::getDecimalVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
if (isNull)
return IDB_Decimal();
if (isNull)
return IDB_Decimal();
IDB_Decimal r = parm[0]->data()->getDecimalVal(row, isNull);
if (isNull)
{
isNull = false;
return parm[1]->data()->getDecimalVal(row, isNull);
}
IDB_Decimal r = parm[0]->data()->getDecimalVal(row, isNull);
return r;
if (isNull)
{
isNull = false;
return parm[1]->data()->getDecimalVal(row, isNull);
}
return r;
}
double Func_ifnull::getDoubleVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
if (isNull)
return 0.0;
if (isNull)
return 0.0;
double r = parm[0]->data()->getDoubleVal(row, isNull);
if (isNull)
{
isNull = false;
return parm[1]->data()->getDoubleVal(row, isNull);
}
double r = parm[0]->data()->getDoubleVal(row, isNull);
return r;
if (isNull)
{
isNull = false;
return parm[1]->data()->getDoubleVal(row, isNull);
}
return r;
}
int32_t Func_ifnull::getDateIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
if (isNull)
return 0;
if (isNull)
return 0;
int64_t r = parm[0]->data()->getDateIntVal(row, isNull);
if (isNull)
{
isNull = false;
return parm[1]->data()->getDateIntVal(row, isNull);
}
int64_t r = parm[0]->data()->getDateIntVal(row, isNull);
return r;
if (isNull)
{
isNull = false;
return parm[1]->data()->getDateIntVal(row, isNull);
}
return r;
}
int64_t Func_ifnull::getDatetimeIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
if (isNull)
return 0;
if (isNull)
return 0;
int64_t r = parm[0]->data()->getDatetimeIntVal(row, isNull);
if (isNull)
{
isNull = false;
return parm[1]->data()->getDatetimeIntVal(row, isNull);
}
int64_t r = parm[0]->data()->getDatetimeIntVal(row, isNull);
return r;
if (isNull)
{
isNull = false;
return parm[1]->data()->getDatetimeIntVal(row, isNull);
}
return r;
}
bool Func_ifnull::getBoolVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
int64_t ret = getIntVal(row, parm, isNull, ct);
return (ret == 0 ? false : true);
int64_t ret = getIntVal(row, parm, isNull, ct);
return (ret == 0 ? false : true);
}
} // namespace funcexp

View File

@ -45,154 +45,197 @@ using namespace funcexp;
namespace
{
template<typename result_t>
inline bool numericEQ(result_t op1, result_t op2)
{
return op1 == op2;
}
inline bool strEQ(string op1, string op2)
{
return utf8::idb_strcoll(op1.c_str(), op2.c_str()) == 0;
}
inline bool getBoolForIn(rowgroup::Row& row,
funcexp::FunctionParm& pm,
bool& isNull,
CalpontSystemCatalog::ColType& ct,
bool isNotIn)
{
IDB_Decimal d; // to be removed;
switch (ct.colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
{
int64_t val = pm[0]->data()->getIntVal(row, isNull);
if (isNull)
return false;
for (uint32_t i = 1; i < pm.size(); i++)
{
isNull = false;
if (val == pm[i]->data()->getIntVal(row, isNull) && !isNull )
return true;
if (isNull && isNotIn)
return true; // will be reversed to false by the caller
}
return false;
}
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
template<typename result_t>
inline bool numericEQ(result_t op1, result_t op2)
{
return op1 == op2;
}
inline bool strEQ(string op1, string op2)
{
return utf8::idb_strcoll(op1.c_str(), op2.c_str()) == 0;
}
inline bool getBoolForIn(rowgroup::Row& row,
funcexp::FunctionParm& pm,
bool& isNull,
CalpontSystemCatalog::ColType& ct,
bool isNotIn)
{
IDB_Decimal d; // to be removed;
switch (ct.colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
{
int64_t val = pm[0]->data()->getIntVal(row, isNull);
if (isNull)
return false;
for (uint32_t i = 1; i < pm.size(); i++)
{
uint64_t val = pm[0]->data()->getUintVal(row, isNull);
if (isNull)
return false;
for (uint32_t i = 1; i < pm.size(); i++)
{
isNull = false;
if (val == pm[i]->data()->getUintVal(row, isNull) && !isNull )
return true;
if (isNull && isNotIn)
return true; // will be reversed to false by the caller
}
return false;
isNull = false;
if (val == pm[i]->data()->getIntVal(row, isNull) && !isNull )
return true;
if (isNull && isNotIn)
return true; // will be reversed to false by the caller
}
case execplan::CalpontSystemCatalog::DATE:
{
int32_t val = pm[0]->data()->getDateIntVal(row, isNull);
if (isNull)
return false;
for (uint32_t i = 1; i < pm.size(); i++)
{
isNull = false;
if ( val == pm[i]->data()->getDateIntVal(row, isNull) && !isNull )
return true;
if (isNull && isNotIn)
return true; // will be reversed to false by the caller
}
return false;
}
case execplan::CalpontSystemCatalog::DATETIME:
{
int64_t val = pm[0]->data()->getDatetimeIntVal(row, isNull);
if (isNull)
return false;
for (uint32_t i = 1; i < pm.size(); i++)
{
isNull = false;
if ( val == pm[i]->data()->getDatetimeIntVal(row, isNull) && !isNull )
return true;
if (isNull && isNotIn)
return true; // will be reversed to false by the caller
}
return false;
}
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
{
double val = pm[0]->data()->getDoubleVal(row, isNull);
if (isNull)
return false;
for (uint32_t i = 1; i < pm.size(); i++)
{
isNull = false;
if ( val == pm[i]->data()->getDoubleVal(row, isNull) && !isNull )
return true;
if (isNull && isNotIn)
return true; // will be reversed to false by the caller
}
return false;
}
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal val = pm[0]->data()->getDecimalVal(row, isNull);
if (isNull)
return false;
for (uint32_t i = 1; i < pm.size(); i++)
{
isNull = false;
if ( val == pm[i]->data()->getDecimalVal(row, isNull) && !isNull )
return true;
if (isNull && isNotIn)
return true; // will be reversed to false by the caller
}
return false;
}
case execplan::CalpontSystemCatalog::VARCHAR: // including CHAR'
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
const string& val = pm[0]->data()->getStrVal(row, isNull);
if (isNull)
return false;
for (uint32_t i = 1; i < pm.size(); i++)
{
isNull = false;
if ( utf8::idb_strcoll(val.c_str(), pm[i]->data()->getStrVal(row, isNull).c_str()) == 0 && !isNull)
return true;
if (isNull && isNotIn)
return true; // will be reversed to false by the caller
}
return false;
}
default:
{
std::ostringstream oss;
oss << "regexo: datatype of " << execplan::colDataTypeToString(ct.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
}
return false;
}
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
{
uint64_t val = pm[0]->data()->getUintVal(row, isNull);
if (isNull)
return false;
for (uint32_t i = 1; i < pm.size(); i++)
{
isNull = false;
if (val == pm[i]->data()->getUintVal(row, isNull) && !isNull )
return true;
if (isNull && isNotIn)
return true; // will be reversed to false by the caller
}
return false;
}
case execplan::CalpontSystemCatalog::DATE:
{
int32_t val = pm[0]->data()->getDateIntVal(row, isNull);
if (isNull)
return false;
for (uint32_t i = 1; i < pm.size(); i++)
{
isNull = false;
if ( val == pm[i]->data()->getDateIntVal(row, isNull) && !isNull )
return true;
if (isNull && isNotIn)
return true; // will be reversed to false by the caller
}
return false;
}
case execplan::CalpontSystemCatalog::DATETIME:
{
int64_t val = pm[0]->data()->getDatetimeIntVal(row, isNull);
if (isNull)
return false;
for (uint32_t i = 1; i < pm.size(); i++)
{
isNull = false;
if ( val == pm[i]->data()->getDatetimeIntVal(row, isNull) && !isNull )
return true;
if (isNull && isNotIn)
return true; // will be reversed to false by the caller
}
return false;
}
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
{
double val = pm[0]->data()->getDoubleVal(row, isNull);
if (isNull)
return false;
for (uint32_t i = 1; i < pm.size(); i++)
{
isNull = false;
if ( val == pm[i]->data()->getDoubleVal(row, isNull) && !isNull )
return true;
if (isNull && isNotIn)
return true; // will be reversed to false by the caller
}
return false;
}
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal val = pm[0]->data()->getDecimalVal(row, isNull);
if (isNull)
return false;
for (uint32_t i = 1; i < pm.size(); i++)
{
isNull = false;
if ( val == pm[i]->data()->getDecimalVal(row, isNull) && !isNull )
return true;
if (isNull && isNotIn)
return true; // will be reversed to false by the caller
}
return false;
}
case execplan::CalpontSystemCatalog::VARCHAR: // including CHAR'
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
const string& val = pm[0]->data()->getStrVal(row, isNull);
if (isNull)
return false;
for (uint32_t i = 1; i < pm.size(); i++)
{
isNull = false;
if ( utf8::idb_strcoll(val.c_str(), pm[i]->data()->getStrVal(row, isNull).c_str()) == 0 && !isNull)
return true;
if (isNull && isNotIn)
return true; // will be reversed to false by the caller
}
return false;
}
default:
{
std::ostringstream oss;
oss << "regexo: datatype of " << execplan::colDataTypeToString(ct.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
}
}
namespace funcexp
@ -200,89 +243,95 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_in::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
PredicateOperator op;
CalpontSystemCatalog::ColType ct;
// @bug 4230. Initialize ct to be the first argument.
if (!fp.empty())
ct = fp[0]->data()->resultType();
bool allString = true;
bool allNonToken = true;
for (uint32_t i = 0; i < fp.size(); i++)
{
//op.setOpType(op.operationType(), fp[i]->data()->resultType());
if (fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::CHAR &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::VARCHAR &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::TEXT)
{
allString = false;
op.setOpType(ct, fp[i]->data()->resultType());
ct = op.operationType();
}
else
{
if ((fp[i]->data()->resultType().colDataType == CalpontSystemCatalog::CHAR &&
fp[i]->data()->resultType().colWidth > 8) ||
(fp[i]->data()->resultType().colDataType == CalpontSystemCatalog::VARCHAR &&
fp[i]->data()->resultType().colWidth >= 8) ||
(fp[i]->data()->resultType().colDataType == CalpontSystemCatalog::TEXT &&
fp[i]->data()->resultType().colWidth >= 8))
allNonToken = false;
}
}
if (allString && !allNonToken)
{
ct.colDataType = CalpontSystemCatalog::VARCHAR;
ct.colWidth = 255;
}
else if (allString && allNonToken)
{
ct.colDataType = CalpontSystemCatalog::BIGINT;
ct.colWidth = 8;
}
PredicateOperator op;
CalpontSystemCatalog::ColType ct;
// convert date const value according to the compare type here.
if (op.operationType().colDataType == CalpontSystemCatalog::DATE)
{
ConstantColumn *cc = NULL;
for (uint32_t i = 1; i < fp.size(); i++)
{
cc = dynamic_cast<ConstantColumn*>(fp[i]->data());
if (cc)
{
Result result = cc->result();
result.intVal = dataconvert::DataConvert::dateToInt(result.strVal);
cc->result(result);
}
}
}
else if (op.operationType().colDataType == CalpontSystemCatalog::DATETIME)
{
ConstantColumn *cc = NULL;
for (uint32_t i = 1; i < fp.size(); i++)
{
cc = dynamic_cast<ConstantColumn*>(fp[i]->data());
if (cc)
{
Result result = cc->result();
result.intVal = dataconvert::DataConvert::datetimeToInt(result.strVal);
cc->result(result);
}
}
}
return ct;
// @bug 4230. Initialize ct to be the first argument.
if (!fp.empty())
ct = fp[0]->data()->resultType();
bool allString = true;
bool allNonToken = true;
for (uint32_t i = 0; i < fp.size(); i++)
{
//op.setOpType(op.operationType(), fp[i]->data()->resultType());
if (fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::CHAR &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::VARCHAR &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::TEXT)
{
allString = false;
op.setOpType(ct, fp[i]->data()->resultType());
ct = op.operationType();
}
else
{
if ((fp[i]->data()->resultType().colDataType == CalpontSystemCatalog::CHAR &&
fp[i]->data()->resultType().colWidth > 8) ||
(fp[i]->data()->resultType().colDataType == CalpontSystemCatalog::VARCHAR &&
fp[i]->data()->resultType().colWidth >= 8) ||
(fp[i]->data()->resultType().colDataType == CalpontSystemCatalog::TEXT &&
fp[i]->data()->resultType().colWidth >= 8))
allNonToken = false;
}
}
if (allString && !allNonToken)
{
ct.colDataType = CalpontSystemCatalog::VARCHAR;
ct.colWidth = 255;
}
else if (allString && allNonToken)
{
ct.colDataType = CalpontSystemCatalog::BIGINT;
ct.colWidth = 8;
}
// convert date const value according to the compare type here.
if (op.operationType().colDataType == CalpontSystemCatalog::DATE)
{
ConstantColumn* cc = NULL;
for (uint32_t i = 1; i < fp.size(); i++)
{
cc = dynamic_cast<ConstantColumn*>(fp[i]->data());
if (cc)
{
Result result = cc->result();
result.intVal = dataconvert::DataConvert::dateToInt(result.strVal);
cc->result(result);
}
}
}
else if (op.operationType().colDataType == CalpontSystemCatalog::DATETIME)
{
ConstantColumn* cc = NULL;
for (uint32_t i = 1; i < fp.size(); i++)
{
cc = dynamic_cast<ConstantColumn*>(fp[i]->data());
if (cc)
{
Result result = cc->result();
result.intVal = dataconvert::DataConvert::datetimeToInt(result.strVal);
cc->result(result);
}
}
}
return ct;
}
bool Func_in::getBoolVal(rowgroup::Row& row,
FunctionParm& pm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& pm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
return getBoolForIn(row, pm, isNull, ct, false) && !isNull;
return getBoolForIn(row, pm, isNull, ct, false) && !isNull;
}
@ -291,18 +340,18 @@ bool Func_in::getBoolVal(rowgroup::Row& row,
CalpontSystemCatalog::ColType Func_notin::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
PredicateOperator *op = new PredicateOperator();
CalpontSystemCatalog::ColType ct;
op->setOpType(fp[0]->data()->resultType(), fp[1]->data()->resultType());
return op->operationType();
PredicateOperator* op = new PredicateOperator();
CalpontSystemCatalog::ColType ct;
op->setOpType(fp[0]->data()->resultType(), fp[1]->data()->resultType());
return op->operationType();
}
bool Func_notin::getBoolVal(rowgroup::Row& row,
FunctionParm& pm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& pm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
return (!getBoolForIn(row, pm, isNull, ct, true) && !isNull);
return (!getBoolForIn(row, pm, isNull, ct, true) && !isNull);
}

View File

@ -37,10 +37,10 @@ namespace funcexp
// See mcs_add in udfsdk.h for explanation of this function.
//------------------------------------------------------------------------------
execplan::CalpontSystemCatalog::ColType Func_inet_aton::operationType(
FunctionParm& fp,
execplan::CalpontSystemCatalog::ColType& resultType)
FunctionParm& fp,
execplan::CalpontSystemCatalog::ColType& resultType)
{
return fp[0]->data()->resultType(); // input type
return fp[0]->data()->resultType(); // input type
}
//------------------------------------------------------------------------------
@ -48,23 +48,25 @@ execplan::CalpontSystemCatalog::ColType Func_inet_aton::operationType(
// SELECT ... WHERE inet_aton(ipstring) = 11111111 will call getIntVal()
//------------------------------------------------------------------------------
int64_t Func_inet_aton::getIntVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
// std::cout << "In Func_inet_aton::getIntVal" << std::endl;
int64_t iValue = joblist::NULL_INT64;
int64_t iValue = joblist::NULL_INT64;
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
if (!isNull)
{
int64_t iVal = convertAton( sValue, isNull );
if (!isNull)
iValue = iVal;
}
return iValue;
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
if (!isNull)
{
int64_t iVal = convertAton( sValue, isNull );
if (!isNull)
iValue = iVal;
}
return iValue;
}
//------------------------------------------------------------------------------
@ -72,23 +74,25 @@ int64_t Func_inet_aton::getIntVal(rowgroup::Row& row,
// SELECT ... WHERE inet_aton(ipstring) = '11111111' will call getDoubleVal()
//------------------------------------------------------------------------------
double Func_inet_aton::getDoubleVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
// std::cout << "In Func_inet_aton::getDoubleVal" << std::endl;
double dValue = doubleNullVal();
double dValue = doubleNullVal();
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
if (!isNull)
{
int64_t iValue = convertAton( sValue, isNull );
if (!isNull)
dValue = iValue;
}
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
return dValue;
if (!isNull)
{
int64_t iValue = convertAton( sValue, isNull );
if (!isNull)
dValue = iValue;
}
return dValue;
}
//------------------------------------------------------------------------------
@ -100,19 +104,20 @@ double Func_inet_aton::getDoubleVal(rowgroup::Row& row,
// Don't know if this function will ever be called.
//------------------------------------------------------------------------------
std::string Func_inet_aton::getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
// std::cout << "In Func_inet_aton::getStrVal" << std::endl;
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
if (!isNull)
{
convertAton( sValue, isNull ); // ignore return value
}
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
return sValue;
if (!isNull)
{
convertAton( sValue, isNull ); // ignore return value
}
return sValue;
}
//------------------------------------------------------------------------------
@ -121,21 +126,23 @@ std::string Func_inet_aton::getStrVal(rowgroup::Row& row,
// Don't know if this function will ever be called.
//------------------------------------------------------------------------------
bool Func_inet_aton::getBoolVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
bool bValue = false;
bool bValue = false;
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
if (!isNull)
{
int64_t iVal = convertAton( sValue, isNull );
if ((!isNull) && (iVal != 0))
bValue = true;
}
return bValue;
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
if (!isNull)
{
int64_t iVal = convertAton( sValue, isNull );
if ((!isNull) && (iVal != 0))
bValue = true;
}
return bValue;
}
//------------------------------------------------------------------------------
@ -143,23 +150,25 @@ bool Func_inet_aton::getBoolVal(rowgroup::Row& row,
// SELECT ... WHERE inet_aton(ipstring) = 11111111. will call getDecimalVal()
//------------------------------------------------------------------------------
execplan::IDB_Decimal Func_inet_aton::getDecimalVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
// std::cout << "In Func_inet_aton::getDecimalVal" << std::endl;
execplan::IDB_Decimal dValue ( joblist::NULL_INT64, 0, 0 );
execplan::IDB_Decimal dValue ( joblist::NULL_INT64, 0, 0 );
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
if (!isNull)
{
int64_t iValue = convertAton( sValue, isNull );
if (!isNull)
return execplan::IDB_Decimal( iValue, 0, 0 );
}
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
return dValue;
if (!isNull)
{
int64_t iValue = convertAton( sValue, isNull );
if (!isNull)
return execplan::IDB_Decimal( iValue, 0, 0 );
}
return dValue;
}
//------------------------------------------------------------------------------
@ -168,21 +177,23 @@ execplan::IDB_Decimal Func_inet_aton::getDecimalVal(rowgroup::Row& row,
// Don't know if this function will ever be called.
//------------------------------------------------------------------------------
int32_t Func_inet_aton::getDateIntVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
int32_t iValue = joblist::DATENULL;
int32_t iValue = joblist::DATENULL;
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
if (!isNull)
{
int64_t iVal = convertAton( sValue, isNull );
if (!isNull)
iValue = iVal;
}
return iValue;
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
if (!isNull)
{
int64_t iVal = convertAton( sValue, isNull );
if (!isNull)
iValue = iVal;
}
return iValue;
}
//------------------------------------------------------------------------------
@ -192,21 +203,23 @@ int32_t Func_inet_aton::getDateIntVal(rowgroup::Row& row,
// Don't know if this function will ever be called.
//------------------------------------------------------------------------------
int64_t Func_inet_aton::getDatetimeIntVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
int64_t iValue = joblist::DATETIMENULL;
int64_t iValue = joblist::DATETIMENULL;
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
if (!isNull)
{
int64_t iVal = convertAton( sValue, isNull );
if (!isNull)
iValue = iVal;
}
return iValue;
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
if (!isNull)
{
int64_t iVal = convertAton( sValue, isNull );
if (!isNull)
iValue = iVal;
}
return iValue;
}
//------------------------------------------------------------------------------
@ -215,78 +228,82 @@ int64_t Func_inet_aton::getDatetimeIntVal(rowgroup::Row& row,
// Source code based on MySQL source (Item_func_inet_aton() in item_func.cc).
//------------------------------------------------------------------------------
int64_t Func_inet_aton::convertAton(
const std::string& ipString,
bool& isNull )
const std::string& ipString,
bool& isNull )
{
char c = '.';
int dot_count = 0;
unsigned int byte_result = 0;
unsigned long long result = 0;
char c = '.';
int dot_count = 0;
unsigned int byte_result = 0;
unsigned long long result = 0;
const char* p = ipString.c_str();
const char* end = p + ipString.length();
const char* p = ipString.c_str();
const char* end = p + ipString.length();
// Loop through bytes in the IP address string
while (p < end)
{
c = *p++;
// Loop through bytes in the IP address string
while (p < end)
{
c = *p++;
int digit = (int) (c - '0'); // Assume ascii
if (digit >= 0 && digit <= 9)
{
// Add the next digit from the string to byte_result
if ((byte_result = byte_result * 10 + digit) > 255)
{
// Wrong address
isNull = true;
return 0;
}
}
// Detect end of one portion of the IP address.
// Shift current result over 8 bits, and add next byte (byte_result)
else if (c == '.')
{
dot_count++;
result= (result << 8) + (unsigned long long) byte_result;
byte_result = 0;
}
// Exit loop if/when we encounter end of string for fixed length column,
// that is padded with '\0' at the end.
else if (c == '\0')
{
break;
}
else
{
// Invalid character
isNull = true;
return 0;
}
}
int digit = (int) (c - '0'); // Assume ascii
if (c != '.') // IP number can't end on '.'
{
//
// Handle short-forms addresses according to standard. Examples:
// 127 -> 0.0.0.127
// 127.1 -> 127.0.0.1
// 127.2.1 -> 127.2.0.1
//
switch (dot_count)
{
case 1: result<<= 8; /* Fall through */
case 2: result<<= 8; /* Fall through */
}
if (digit >= 0 && digit <= 9)
{
// Add the next digit from the string to byte_result
if ((byte_result = byte_result * 10 + digit) > 255)
{
// Wrong address
isNull = true;
return 0;
}
}
// Detect end of one portion of the IP address.
// Shift current result over 8 bits, and add next byte (byte_result)
else if (c == '.')
{
dot_count++;
result = (result << 8) + (unsigned long long) byte_result;
byte_result = 0;
}
// Exit loop if/when we encounter end of string for fixed length column,
// that is padded with '\0' at the end.
else if (c == '\0')
{
break;
}
else
{
// Invalid character
isNull = true;
return 0;
}
}
if (c != '.') // IP number can't end on '.'
{
//
// Handle short-forms addresses according to standard. Examples:
// 127 -> 0.0.0.127
// 127.1 -> 127.0.0.1
// 127.2.1 -> 127.2.0.1
//
switch (dot_count)
{
case 1:
result <<= 8; /* Fall through */
case 2:
result <<= 8; /* Fall through */
}
// std::cout << "aton: " <<
// (result << 8) + (unsigned long long) byte_result << std::endl;
return (result << 8) + (unsigned long long) byte_result;
}
return (result << 8) + (unsigned long long) byte_result;
}
// Invalid IP address ended in '.'
isNull = true;
return 0;
// Invalid IP address ended in '.'
isNull = true;
return 0;
}
}

View File

@ -57,10 +57,10 @@ namespace funcexp
// See mcs_add in udfsdk.h for explanation of this function.
//------------------------------------------------------------------------------
execplan::CalpontSystemCatalog::ColType Func_inet_ntoa::operationType(
FunctionParm& fp,
execplan::CalpontSystemCatalog::ColType& resultType)
FunctionParm& fp,
execplan::CalpontSystemCatalog::ColType& resultType)
{
return fp[0]->data()->resultType(); // input type
return fp[0]->data()->resultType(); // input type
}
//------------------------------------------------------------------------------
@ -69,30 +69,33 @@ execplan::CalpontSystemCatalog::ColType Func_inet_ntoa::operationType(
// to be safe. (See getDoubleVal() description)
//------------------------------------------------------------------------------
int64_t Func_inet_ntoa::getIntVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
// std::cout << "In Func_inet_ntoa::getIntVal" << std::endl;
std::string sValue = getStrVal( row, fp, isNull, op_ct );
int64_t iValue = joblist::NULL_INT64;
if ( !isNull )
{
unsigned int newLength = sValue.length();
std::string::size_type dot1 = sValue.find('.');
if (dot1 != std::string::npos)
{
newLength = dot1;
}
std::string sValue = getStrVal( row, fp, isNull, op_ct );
int64_t iValue = joblist::NULL_INT64;
if (newLength != sValue.length())
sValue.resize(newLength);
std::istringstream iss( sValue );
iss >> iValue;
}
if ( !isNull )
{
unsigned int newLength = sValue.length();
std::string::size_type dot1 = sValue.find('.');
return iValue;
if (dot1 != std::string::npos)
{
newLength = dot1;
}
if (newLength != sValue.length())
sValue.resize(newLength);
std::istringstream iss( sValue );
iss >> iValue;
}
return iValue;
}
//------------------------------------------------------------------------------
@ -101,34 +104,38 @@ int64_t Func_inet_ntoa::getIntVal(rowgroup::Row& row,
// SELECT ... WHERE inet_ntoa(ipstring) = 1 will also call getDoubleVal()
//------------------------------------------------------------------------------
double Func_inet_ntoa::getDoubleVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
// std::cout << "In Func_inet_ntoa::getDoubleVal" << std::endl;
std::string sValue = getStrVal( row, fp, isNull, op_ct );
double dValue = doubleNullVal();
if ( !isNull )
{
unsigned int newLength = sValue.length();
std::string::size_type dot1 = sValue.find('.');
if ((dot1 != std::string::npos) && (sValue.length() > dot1+1))
{
std::string::size_type dot2 = sValue.find('.', dot1+1);
if (dot2 != std::string::npos)
{
newLength = dot2;
}
}
std::string sValue = getStrVal( row, fp, isNull, op_ct );
double dValue = doubleNullVal();
if (newLength != sValue.length())
sValue.resize(newLength);
std::istringstream iss( sValue );
iss >> dValue;
}
if ( !isNull )
{
unsigned int newLength = sValue.length();
std::string::size_type dot1 = sValue.find('.');
return dValue;
if ((dot1 != std::string::npos) && (sValue.length() > dot1 + 1))
{
std::string::size_type dot2 = sValue.find('.', dot1 + 1);
if (dot2 != std::string::npos)
{
newLength = dot2;
}
}
if (newLength != sValue.length())
sValue.resize(newLength);
std::istringstream iss( sValue );
iss >> dValue;
}
return dValue;
}
//------------------------------------------------------------------------------
@ -136,46 +143,47 @@ double Func_inet_ntoa::getDoubleVal(rowgroup::Row& row,
// This is the get function that makes sense to use.
//------------------------------------------------------------------------------
std::string Func_inet_ntoa::getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
// std::cout << "In Func_inet_ntoa::getStrVal" << std::endl;
std::string sValue;
std::string sValue;
int64_t iValue = 0;
int64_t iValue = 0;
// @bug 3628 reopened: get double and round up, if necessary;
// else just get integer value
if ((fp[0]->data()->resultType().colDataType ==
execplan::CalpontSystemCatalog::DECIMAL) ||
(fp[0]->data()->resultType().colDataType ==
execplan::CalpontSystemCatalog::FLOAT) ||
(fp[0]->data()->resultType().colDataType ==
execplan::CalpontSystemCatalog::DOUBLE))
{
double d = fp[0]->data()->getDoubleVal(row, isNull);
if (d >= 0.0)
iValue = (int64_t)(d + 0.5);
else
iValue = (int64_t)(d - 0.5);
}
else
{
iValue = fp[0]->data()->getIntVal(row, isNull);
}
// @bug 3628 reopened: get double and round up, if necessary;
// else just get integer value
if ((fp[0]->data()->resultType().colDataType ==
execplan::CalpontSystemCatalog::DECIMAL) ||
(fp[0]->data()->resultType().colDataType ==
execplan::CalpontSystemCatalog::FLOAT) ||
(fp[0]->data()->resultType().colDataType ==
execplan::CalpontSystemCatalog::DOUBLE))
{
double d = fp[0]->data()->getDoubleVal(row, isNull);
if (!isNull)
{
// @bug 3628 reopened: add check for out of range values
if ((iValue < 0) || (iValue > UINT_MAX))
isNull = true;
else
convertNtoa( iValue, sValue );
}
if (d >= 0.0)
iValue = (int64_t)(d + 0.5);
else
iValue = (int64_t)(d - 0.5);
}
else
{
iValue = fp[0]->data()->getIntVal(row, isNull);
}
return sValue;
if (!isNull)
{
// @bug 3628 reopened: add check for out of range values
if ((iValue < 0) || (iValue > UINT_MAX))
isNull = true;
else
convertNtoa( iValue, sValue );
}
return sValue;
}
//------------------------------------------------------------------------------
@ -183,15 +191,15 @@ std::string Func_inet_ntoa::getStrVal(rowgroup::Row& row,
// N/A so returning null. See explanation at the top of this source file.
//------------------------------------------------------------------------------
bool Func_inet_ntoa::getBoolVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
// std::cout << "In Func_inet_ntoa::getBoolVal" << std::endl;
bool bValue = false;
isNull = true;
bool bValue = false;
isNull = true;
return bValue;
return bValue;
}
//------------------------------------------------------------------------------
@ -199,17 +207,17 @@ bool Func_inet_ntoa::getBoolVal(rowgroup::Row& row,
// N/A so returning null. See explanation at the top of this source file.
//------------------------------------------------------------------------------
execplan::IDB_Decimal Func_inet_ntoa::getDecimalVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
// std::cout << "In Func_inet_ntoa::getDecimalVal" << std::endl;
// IDB_Decimal dValue = fp[0]->data()->getDecimalVal(row, isNull);
execplan::IDB_Decimal dValue ( joblist::NULL_INT64, 0, 0 );
isNull = true;
execplan::IDB_Decimal dValue ( joblist::NULL_INT64, 0, 0 );
isNull = true;
return dValue;
return dValue;
}
//------------------------------------------------------------------------------
@ -217,17 +225,17 @@ execplan::IDB_Decimal Func_inet_ntoa::getDecimalVal(rowgroup::Row& row,
// N/A so returning null. See explanation at the top of this source file.
//------------------------------------------------------------------------------
int32_t Func_inet_ntoa::getDateIntVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
// std::cout << "In Func_inet_ntoa::getDateIntVal" << std::endl;
// int32_t iValue = fp[0]->data()->getDateIntVal(row, isNull);
int32_t iValue = joblist::DATENULL;
isNull = true;
int32_t iValue = joblist::DATENULL;
isNull = true;
return iValue;
return iValue;
}
//------------------------------------------------------------------------------
@ -235,17 +243,17 @@ int32_t Func_inet_ntoa::getDateIntVal(rowgroup::Row& row,
// N/A so returning null. See explanation at the top of this source file.
//------------------------------------------------------------------------------
int64_t Func_inet_ntoa::getDatetimeIntVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
// std::cout << "In Func_inet_ntoa::getDatetimeVal" << std::endl;
// int64t iValue = fp[0]->data()->getDatetimeIntVal(row, isNull);
int64_t iValue = joblist::DATETIMENULL;
isNull = true;
int64_t iValue = joblist::DATETIMENULL;
isNull = true;
return iValue;
return iValue;
}
//------------------------------------------------------------------------------
@ -253,8 +261,8 @@ int64_t Func_inet_ntoa::getDatetimeIntVal(rowgroup::Row& row,
// Source code based on MySQL source (Item_func_inet_ntoa() in item_strfunc.cc).
//------------------------------------------------------------------------------
void Func_inet_ntoa::convertNtoa(
int64_t ipNum,
std::string& ipString )
int64_t ipNum,
std::string& ipString )
{
struct sockaddr_in sa;
sa.sin_addr.s_addr = htonl(ipNum);

View File

@ -44,66 +44,71 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_insert::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
string insertStr(const string& src, int pos, int len, const string& targ)
{
int64_t strLen = static_cast<int64_t>(src.length());
int64_t strLen = static_cast<int64_t>(src.length());
if ((pos <= 0) || ((pos-1) >= strLen))
if ((pos <= 0) || ((pos - 1) >= strLen))
return src;
if ((len < 0) || (len > strLen))
len = strLen;
const char* srcptr = src.c_str();
advance(srcptr,pos-1,srcptr+strLen);
advance(srcptr, pos - 1, srcptr + strLen);
// srcptr now pointing to where we need to insert targ string
uint32_t srcPos = srcptr - src.c_str();
uint32_t finPos = strLen;
const char* finptr = src.c_str();
if ((strLen - (pos-1+len)) >= 0)
const char* finptr = src.c_str();
if ((strLen - (pos - 1 + len)) >= 0)
{
advance(finptr,(pos-1+len),finptr+strLen);
// finptr now pointing to the end of the string to replace
finPos = finptr - src.c_str();
advance(finptr, (pos - 1 + len), finptr + strLen);
// finptr now pointing to the end of the string to replace
finPos = finptr - src.c_str();
}
string out;
out.reserve(srcPos + targ.length() + strLen-finPos + 1);
out.reserve(srcPos + targ.length() + strLen - finPos + 1);
out.append( src.c_str(), srcPos );
out.append( targ.c_str(), targ.length() );
out.append( src.c_str() + finPos, strLen-finPos );
out.append( src.c_str() + finPos, strLen - finPos );
return out;
}
std::string Func_insert::getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
{
const string& tstr = stringValue(fp[0], row, isNull);
if (isNull)
return "";
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
{
const string& tstr = stringValue(fp[0], row, isNull);
const string& tnewstr = stringValue(fp[3], row, isNull);
if (isNull)
return "";
if (isNull)
return "";
int64_t pos = fp[1]->data()->getIntVal(row, isNull);
if (isNull)
return "";
const string& tnewstr = stringValue(fp[3], row, isNull);
int64_t len = fp[2]->data()->getIntVal(row, isNull);
if (isNull)
return "";
if (isNull)
return "";
return insertStr( tstr, pos, len, tnewstr );
int64_t pos = fp[1]->data()->getIntVal(row, isNull);
if (isNull)
return "";
int64_t len = fp[2]->data()->getIntVal(row, isNull);
if (isNull)
return "";
return insertStr( tstr, pos, len, tnewstr );
}

View File

@ -36,41 +36,42 @@ namespace funcexp
{
CalpontSystemCatalog::ColType Func_instr::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
CalpontSystemCatalog::ColType ct;
ct.colDataType = CalpontSystemCatalog::VARCHAR;
ct.colWidth = 255;
return ct;
CalpontSystemCatalog::ColType ct;
ct.colDataType = CalpontSystemCatalog::VARCHAR;
ct.colWidth = 255;
return ct;
}
size_t Func_instr::in_str(const string& str, const string& substr, size_t start)
{
// convert both inputs to wide character strings
std::wstring wcstr = utf8::utf8_to_wstring(str);
std::wstring wcsubstr = utf8::utf8_to_wstring(substr);
// convert both inputs to wide character strings
std::wstring wcstr = utf8::utf8_to_wstring(str);
std::wstring wcsubstr = utf8::utf8_to_wstring(substr);
if ((str.length() && !wcstr.length()) ||
(substr.length() && !wcsubstr.length()))
// this means one or both of the strings had conversion errors to wide character
return 0;
if ((str.length() && !wcstr.length()) ||
(substr.length() && !wcsubstr.length()))
// this means one or both of the strings had conversion errors to wide character
return 0;
size_t pos = wcstr.find(wcsubstr, start-1);
return (pos != string::npos ? pos+1 : 0);
size_t pos = wcstr.find(wcsubstr, start - 1);
return (pos != string::npos ? pos + 1 : 0);
}
int64_t Func_instr::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
uint64_t start = 1;
if (parm.size() == 3)
start = parm[2]->data()->getIntVal(row, isNull);
uint64_t start = 1;
if (isNull || start == 0)
return 0;
if (parm.size() == 3)
start = parm[2]->data()->getIntVal(row, isNull);
//Bug 5110 : to support utf8 char type, we have to convert and search
return in_str(parm[0]->data()->getStrVal(row, isNull), parm[1]->data()->getStrVal(row, isNull), start);
if (isNull || start == 0)
return 0;
//Bug 5110 : to support utf8 char type, we have to convert and search
return in_str(parm[0]->data()->getStrVal(row, isNull), parm[1]->data()->getStrVal(row, isNull), start);
}

View File

@ -37,12 +37,12 @@ using namespace rowgroup;
namespace funcexp
{
CalpontSystemCatalog::ColType Func_isnull::operationType (FunctionParm& fp,
CalpontSystemCatalog::ColType& resultType)
CalpontSystemCatalog::ColType Func_isnull::operationType (FunctionParm& fp,
CalpontSystemCatalog::ColType& resultType)
{
// operation type of idb_isnull should be the same as the argument type
assert (fp.size() == 1);
return fp[0]->data()->resultType();
// operation type of idb_isnull should be the same as the argument type
assert (fp.size() == 1);
return fp[0]->data()->resultType();
}
/**
@ -51,34 +51,37 @@ CalpontSystemCatalog::ColType Func_isnull::operationType (FunctionParm& fp,
* This would be the most commonly called API for idb_isnull function
*/
bool Func_isnull::getBoolVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
switch (op_ct.colDataType)
{
// For the purpose of this function, one does not need to get the value of
// the argument. One only need to know if the argument is NULL. The passed
// in parameter isNull will be set if the parameter is evaluated NULL.
// Please note that before this function returns, isNull should be set to
// false, otherwise the result of the function would be considered NULL,
// which is not possible for idb_isnull().
switch (op_ct.colDataType)
{
// For the purpose of this function, one does not need to get the value of
// the argument. One only need to know if the argument is NULL. The passed
// in parameter isNull will be set if the parameter is evaluated NULL.
// Please note that before this function returns, isNull should be set to
// false, otherwise the result of the function would be considered NULL,
// which is not possible for idb_isnull().
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
parm[0]->data()->getDecimalVal(row, isNull);
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
parm[0]->data()->getStrVal(row, isNull);
break;
default:
parm[0]->data()->getIntVal(row, isNull);
}
bool ret = isNull;
// It's important to reset isNull indicator.
isNull = false;
return (fIsNotNull? !ret : ret);
case CalpontSystemCatalog::UDECIMAL:
parm[0]->data()->getDecimalVal(row, isNull);
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
parm[0]->data()->getStrVal(row, isNull);
break;
default:
parm[0]->data()->getIntVal(row, isNull);
}
bool ret = isNull;
// It's important to reset isNull indicator.
isNull = false;
return (fIsNotNull ? !ret : ret);
}

View File

@ -40,117 +40,132 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_last_day::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_last_day::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
uint32_t year = 0;
uint32_t month = 0;
uint32_t day = 0;
int64_t val = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
year = (uint32_t)((val >> 16) & 0xffff);
month = (uint32_t)((val >> 12) & 0xf);
day = (uint32_t)((val >> 6) & 0x3f);
break;
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
}
break;
default:
isNull = true;
return -1;
}
uint32_t lastday = day;
if (isLeapYear(year) && (month == 2))
{
lastday = 29;
}
else if ( month == 2)
{
lastday = 28;
}
else
{
lastday = daysInMonth[month-1];
}
if (day > lastday)
{
isNull = true;
return -1;
}
dataconvert::DateTime aDay;
aDay.year = year;
aDay.month = month;
aDay.day = lastday;
aDay.hour = 0;
aDay.minute = 0;
aDay.second = 0;
aDay.msecond = 0;
val = *(reinterpret_cast<uint64_t*>(&aDay));
return val;
uint32_t year = 0;
uint32_t month = 0;
uint32_t day = 0;
int64_t val = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
year = (uint32_t)((val >> 16) & 0xffff);
month = (uint32_t)((val >> 12) & 0xf);
day = (uint32_t)((val >> 6) & 0x3f);
break;
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
}
break;
default:
isNull = true;
return -1;
}
uint32_t lastday = day;
if (isLeapYear(year) && (month == 2))
{
lastday = 29;
}
else if ( month == 2)
{
lastday = 28;
}
else
{
lastday = daysInMonth[month - 1];
}
if (day > lastday)
{
isNull = true;
return -1;
}
dataconvert::DateTime aDay;
aDay.year = year;
aDay.month = month;
aDay.day = lastday;
aDay.hour = 0;
aDay.minute = 0;
aDay.second = 0;
aDay.msecond = 0;
val = *(reinterpret_cast<uint64_t*>(&aDay));
return val;
}

View File

@ -37,47 +37,49 @@ using namespace joblist;
class to_lower
{
public:
char operator() (char c) const // notice the return type
{
return tolower(c);
}
public:
char operator() (char c) const // notice the return type
{
return tolower(c);
}
};
namespace funcexp
{
CalpontSystemCatalog::ColType Func_lcase::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType){
// operation type is not used by this functor
return fp[0]->data()->resultType();
CalpontSystemCatalog::ColType Func_lcase::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
std::string Func_lcase::getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
{
// string str = fp[0]->data()->getStrVal(row, isNull);
// transform (str.begin(), str.end(), str.begin(), to_lower());
const string& tstr = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
return "";
const string& tstr = fp[0]->data()->getStrVal(row, isNull);
size_t strwclen = utf8::idb_mbstowcs(0, tstr.c_str(), 0) + 1;
wchar_t* wcbuf = (wchar_t*)alloca(strwclen * sizeof(wchar_t));
strwclen = utf8::idb_mbstowcs(wcbuf, tstr.c_str(), strwclen);
wstring wstr(wcbuf, strwclen);
if (isNull)
return "";
for (uint32_t i = 0; i < strwclen; i++)
wstr[i] = std::towlower(wstr[i]);
size_t strwclen = utf8::idb_mbstowcs(0, tstr.c_str(), 0) + 1;
wchar_t* wcbuf = (wchar_t*)alloca(strwclen * sizeof(wchar_t));
strwclen = utf8::idb_mbstowcs(wcbuf, tstr.c_str(), strwclen);
wstring wstr(wcbuf, strwclen);
size_t strmblen = utf8::idb_wcstombs(0, wstr.c_str(), 0) + 1;
char* outbuf = (char*)alloca(strmblen * sizeof(char));
strmblen = utf8::idb_wcstombs(outbuf, wstr.c_str(), strmblen);
return string(outbuf, strmblen);
}
for (uint32_t i = 0; i < strwclen; i++)
wstr[i] = std::towlower(wstr[i]);
size_t strmblen = utf8::idb_wcstombs(0, wstr.c_str(), 0) + 1;
char* outbuf = (char*)alloca(strmblen * sizeof(char));
strmblen = utf8::idb_wcstombs(outbuf, wstr.c_str(), strmblen);
return string(outbuf, strmblen);
}
} // namespace funcexp

View File

@ -41,11 +41,11 @@ using namespace funcexp;
class to_lower
{
public:
char operator() (char c) const // notice the return type
{
return tolower(c);
}
public:
char operator() (char c) const // notice the return type
{
return tolower(c);
}
};
@ -55,124 +55,131 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_least::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
//return fp[0]->data()->resultType();
return resultType;
// operation type is not used by this functor
//return fp[0]->data()->resultType();
return resultType;
}
int64_t Func_least::getIntVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
double str = fp[0]->data()->getDoubleVal(row, isNull);
double str = fp[0]->data()->getDoubleVal(row, isNull);
double leastStr = str;
for (uint32_t i = 1; i < fp.size(); i++)
{
double str1 = fp[i]->data()->getDoubleVal(row, isNull);
double leastStr = str;
if ( leastStr > str1 )
leastStr = str1;
}
for (uint32_t i = 1; i < fp.size(); i++)
{
double str1 = fp[i]->data()->getDoubleVal(row, isNull);
return (int64_t) leastStr;
if ( leastStr > str1 )
leastStr = str1;
}
return (int64_t) leastStr;
}
double Func_least::getDoubleVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
double str = fp[0]->data()->getDoubleVal(row, isNull);
double str = fp[0]->data()->getDoubleVal(row, isNull);
double leastStr = str;
for (uint32_t i = 1; i < fp.size(); i++)
{
double str1 = fp[i]->data()->getDoubleVal(row, isNull);
double leastStr = str;
if ( leastStr > str1 )
leastStr = str1;
}
for (uint32_t i = 1; i < fp.size(); i++)
{
double str1 = fp[i]->data()->getDoubleVal(row, isNull);
return (double) leastStr;
if ( leastStr > str1 )
leastStr = str1;
}
return (double) leastStr;
}
std::string Func_least::getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
string leastStr = fp[0]->data()->getStrVal(row, isNull);
for (uint32_t i = 1; i < fp.size(); i++)
{
const string& str1 = fp[i]->data()->getStrVal(row, isNull);
string leastStr = fp[0]->data()->getStrVal(row, isNull);
int tmp = utf8::idb_strcoll(leastStr.c_str(), str1.c_str());
if ( tmp > 0 )
for (uint32_t i = 1; i < fp.size(); i++)
{
const string& str1 = fp[i]->data()->getStrVal(row, isNull);
int tmp = utf8::idb_strcoll(leastStr.c_str(), str1.c_str());
if ( tmp > 0 )
// if ( leastStr > str1 )
leastStr = str1;
}
leastStr = str1;
}
return leastStr;
return leastStr;
}
IDB_Decimal Func_least::getDecimalVal(Row& row,
FunctionParm& fp,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& fp,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
IDB_Decimal str = fp[0]->data()->getDecimalVal(row, isNull);
IDB_Decimal str = fp[0]->data()->getDecimalVal(row, isNull);
IDB_Decimal leastStr = str;
for (uint32_t i = 1; i < fp.size(); i++)
{
IDB_Decimal str1 = fp[i]->data()->getDecimalVal(row, isNull);
IDB_Decimal leastStr = str;
if ( leastStr > str1 )
leastStr = str1;
}
for (uint32_t i = 1; i < fp.size(); i++)
{
IDB_Decimal str1 = fp[i]->data()->getDecimalVal(row, isNull);
return leastStr;
if ( leastStr > str1 )
leastStr = str1;
}
return leastStr;
}
int32_t Func_least::getDateIntVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
int32_t str = fp[0]->data()->getDateIntVal(row, isNull);
int32_t str = fp[0]->data()->getDateIntVal(row, isNull);
int32_t leastStr = str;
for (uint32_t i = 1; i < fp.size(); i++)
{
int32_t str1 = fp[i]->data()->getDateIntVal(row, isNull);
int32_t leastStr = str;
if ( leastStr > str1 )
leastStr = str1;
}
for (uint32_t i = 1; i < fp.size(); i++)
{
int32_t str1 = fp[i]->data()->getDateIntVal(row, isNull);
return leastStr;
if ( leastStr > str1 )
leastStr = str1;
}
return leastStr;
}
int64_t Func_least::getDatetimeIntVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
int64_t str = fp[0]->data()->getDatetimeIntVal(row, isNull);
int64_t str = fp[0]->data()->getDatetimeIntVal(row, isNull);
int64_t leastStr = str;
for (uint32_t i = 1; i < fp.size(); i++)
{
int64_t str1 = fp[i]->data()->getDatetimeIntVal(row, isNull);
int64_t leastStr = str;
if ( leastStr > str1 )
leastStr = str1;
}
for (uint32_t i = 1; i < fp.size(); i++)
{
int64_t str1 = fp[i]->data()->getDatetimeIntVal(row, isNull);
return leastStr;
if ( leastStr > str1 )
leastStr = str1;
}
return leastStr;
}

View File

@ -40,40 +40,42 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_left::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
std::string Func_left::getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
{
const string& tstr = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
return "";
const string& tstr = fp[0]->data()->getStrVal(row, isNull);
size_t strwclen = utf8::idb_mbstowcs(0, tstr.c_str(), 0) + 1;
wchar_t* wcbuf = (wchar_t*)alloca(strwclen * sizeof(wchar_t));
strwclen = utf8::idb_mbstowcs(wcbuf, tstr.c_str(), strwclen);
wstring str(wcbuf, strwclen);
if (isNull)
return "";
int64_t pos = fp[1]->data()->getIntVal(row, isNull) - 1;
if (isNull)
return "";
size_t strwclen = utf8::idb_mbstowcs(0, tstr.c_str(), 0) + 1;
wchar_t* wcbuf = (wchar_t*)alloca(strwclen * sizeof(wchar_t));
strwclen = utf8::idb_mbstowcs(wcbuf, tstr.c_str(), strwclen);
wstring str(wcbuf, strwclen);
if (pos == -1) // pos == 0
return "";
int64_t pos = fp[1]->data()->getIntVal(row, isNull) - 1;
wstring out = str.substr(0, pos+1);
size_t strmblen = utf8::idb_wcstombs(0, out.c_str(), 0) + 1;
char* outbuf = (char*)alloca(strmblen * sizeof(char));
strmblen = utf8::idb_wcstombs(outbuf, out.c_str(), strmblen);
return string(outbuf, strmblen);
if (isNull)
return "";
if (pos == -1) // pos == 0
return "";
wstring out = str.substr(0, pos + 1);
size_t strmblen = utf8::idb_wcstombs(0, out.c_str(), 0) + 1;
char* outbuf = (char*)alloca(strmblen * sizeof(char));
strmblen = utf8::idb_wcstombs(outbuf, out.c_str(), strmblen);
return string(outbuf, strmblen);
// return str.substr(0, pos+1);
}
}
} // namespace funcexp

View File

@ -37,22 +37,22 @@ namespace funcexp
{
CalpontSystemCatalog::ColType Func_length::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
CalpontSystemCatalog::ColType ct;
ct.colDataType = CalpontSystemCatalog::VARCHAR;
ct.colWidth = 255;
return ct;
CalpontSystemCatalog::ColType ct;
ct.colDataType = CalpontSystemCatalog::VARCHAR;
ct.colWidth = 255;
return ct;
}
int64_t Func_length::getIntVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& fp,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
if ((fp[0]->data()->resultType().colDataType == CalpontSystemCatalog::VARBINARY) ||
(fp[0]->data()->resultType().colDataType == CalpontSystemCatalog::BLOB))
return fp[0]->data()->getStrVal(row, isNull).length();
if ((fp[0]->data()->resultType().colDataType == CalpontSystemCatalog::VARBINARY) ||
(fp[0]->data()->resultType().colDataType == CalpontSystemCatalog::BLOB))
return fp[0]->data()->getStrVal(row, isNull).length();
return strlen(fp[0]->data()->getStrVal(row, isNull).c_str());
return strlen(fp[0]->data()->getStrVal(row, isNull).c_str());
}

156
utils/funcexp/func_lpad.cpp Executable file → Normal file
View File

@ -41,21 +41,21 @@ namespace funcexp
{
CalpontSystemCatalog::ColType Func_lpad::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
std::string Func_lpad::getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
{
unsigned i;
// The number of characters (not bytes) in our input str.
// Not all of these are necessarily significant. We need to search for the
// Not all of these are necessarily significant. We need to search for the
// NULL terminator to be sure.
size_t strwclen;
size_t strwclen;
// this holds the number of characters (not bytes) in our pad str.
size_t padwclen;
@ -64,59 +64,63 @@ std::string Func_lpad::getStrVal(rowgroup::Row& row,
// The result length in number of characters
size_t len = 0;
switch (fp[1]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
{
len = fp[1]->data()->getIntVal(row, isNull);
}
break;
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
{
len = fp[1]->data()->getUintVal(row, isNull);
}
break;
switch (fp[1]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
{
len = fp[1]->data()->getIntVal(row, isNull);
}
break;
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
double value = fp[1]->data()->getDoubleVal(row, isNull);
if (value > 0)
value += 0.5;
else if (value < 0)
value -= 0.5;
else if (value < 0)
value -= 0.5;
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
{
len = fp[1]->data()->getUintVal(row, isNull);
}
break;
int64_t ret = (int64_t) value;
if (value > (double) numeric_limits<int64_t>::max())
ret = numeric_limits<int64_t>::max();
else if (value < (double) (numeric_limits<int64_t>::min()+2))
ret = numeric_limits<int64_t>::min() + 2; // IDB min for bigint
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
double value = fp[1]->data()->getDoubleVal(row, isNull);
len = ret;
}
break;
default:
{
len = fp[1]->data()->getIntVal(row, isNull);
}
}
if (value > 0)
value += 0.5;
else if (value < 0)
value -= 0.5;
else if (value < 0)
value -= 0.5;
if (len < 1)
int64_t ret = (int64_t) value;
if (value > (double) numeric_limits<int64_t>::max())
ret = numeric_limits<int64_t>::max();
else if (value < (double) (numeric_limits<int64_t>::min() + 2))
ret = numeric_limits<int64_t>::min() + 2; // IDB min for bigint
len = ret;
}
break;
default:
{
len = fp[1]->data()->getIntVal(row, isNull);
}
}
if (len < 1)
return "";
// The pad characters.
@ -125,24 +129,28 @@ std::string Func_lpad::getStrVal(rowgroup::Row& row,
if (isNull)
return "";
// Rather than calling the wideconvert functions with a null buffer to
// Rather than calling the wideconvert functions with a null buffer to
// determine the size of buffer to allocate, we can be sure the wide
// char string won't be longer than
strwclen = tstr.length(); // a guess to start with. This will be >= to the real count.
size_t alen = len;
if(strwclen > len)
alen = strwclen;
size_t bufsize = (alen+1) * sizeof(wchar_t);
if (strwclen > len)
alen = strwclen;
size_t bufsize = (alen + 1) * sizeof(wchar_t);
// Convert to wide characters. Do all further work in wide characters
wchar_t* wcbuf = (wchar_t*)alloca(bufsize);
strwclen = utf8::idb_mbstowcs(wcbuf, tstr.c_str(), strwclen+1);
strwclen = utf8::idb_mbstowcs(wcbuf, tstr.c_str(), strwclen + 1);
size_t strSize = strwclen; // The number of significant characters
const wchar_t* pWChar = wcbuf;
for (i = 0; *pWChar != '\0' && i < strwclen; ++pWChar, ++i)
{
}
strSize = i;
// If the incoming str is exactly the len of the result str,
@ -154,22 +162,22 @@ std::string Func_lpad::getStrVal(rowgroup::Row& row,
// If the incoming str is too big for the result str
// truncate the widechar buffer and return as a string
if (strSize > len)
if (strSize > len)
{
// Trim the excess length of the buffer
wstring trimmed = wstring(wcbuf, len);
return utf8::wstring_to_utf8(trimmed.c_str());
// Trim the excess length of the buffer
wstring trimmed = wstring(wcbuf, len);
return utf8::wstring_to_utf8(trimmed.c_str());
}
// This is the case where there's room to pad.
// Convert the pad string to wide
padwclen = pad.length(); // A guess to start.
size_t padbufsize = (padwclen+1) * sizeof(wchar_t);
size_t padbufsize = (padwclen + 1) * sizeof(wchar_t);
wchar_t* wcpad = (wchar_t*)alloca(padbufsize);
// padwclen+1 is for giving count for the terminating null
size_t padlen = utf8::idb_mbstowcs(wcpad, pad.c_str(), padwclen+1);
// padwclen+1 is for giving count for the terminating null
size_t padlen = utf8::idb_mbstowcs(wcpad, pad.c_str(), padwclen + 1);
// How many chars do we need?
size_t padspace = len - strSize;
@ -180,6 +188,7 @@ std::string Func_lpad::getStrVal(rowgroup::Row& row,
// Testing has shown that this loop is faster than memmove
wchar_t* newchar = wcbuf + len; // Last spot to put a char in buf
wchar_t* pChar = wcbuf + strSize; // terminal NULL of our str
while (pChar >= wcbuf)
{
*newchar-- = *pChar--;
@ -187,25 +196,28 @@ std::string Func_lpad::getStrVal(rowgroup::Row& row,
// Fill in the front of the buffer with the pad chars
wchar_t* firstpadchar = wcbuf;
for (wchar_t* pch = wcbuf; pch < startofstr && padlen > 0;)
for (wchar_t* pch = wcbuf; pch < startofstr && padlen > 0;)
{
// Truncate the number of fill chars if running out of space
if (padlen > padspace)
{
padlen = padspace;
}
// Move the fill chars to buffer
for (wchar_t* padchar = wcpad; padchar < wcpad + padlen; ++padchar)
{
*firstpadchar++ = *padchar;
}
padspace -= padlen;
pch += padlen;
}
wstring padded = wstring(wcbuf, len);
// Turn back to a string
return utf8::wstring_to_utf8(padded.c_str());
wstring padded = wstring(wcbuf, len);
// Turn back to a string
return utf8::wstring_to_utf8(padded.c_str());
}

View File

@ -41,20 +41,20 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_ltrim::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
std::string Func_ltrim::getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
{
// The number of characters (not bytes) in our input tstr.
// Not all of these are necessarily significant. We need to search for the
// Not all of these are necessarily significant. We need to search for the
// NULL terminator to be sure.
size_t strwclen;
size_t strwclen;
// this holds the number of characters (not bytes) in ourtrim tstr.
size_t trimwclen;
@ -66,59 +66,65 @@ std::string Func_ltrim::getStrVal(rowgroup::Row& row,
if (isNull)
return "";
if (tstr.empty() || tstr.length() == 0)
return tstr;
// Rather than calling the wideconvert functions with a null buffer to
// Rather than calling the wideconvert functions with a null buffer to
// determine the size of buffer to allocate, we can be sure the wide
// char string won't be longer than:
strwclen = tstr.length(); // a guess to start with. This will be >= to the real count.
int bufsize = (strwclen+1) * sizeof(wchar_t);
int bufsize = (strwclen + 1) * sizeof(wchar_t);
// Convert the string to wide characters. Do all further work in wide characters
wchar_t* wcbuf = (wchar_t*)alloca(bufsize);
strwclen = utf8::idb_mbstowcs(wcbuf, tstr.c_str(), strwclen+1);
// idb_mbstowcs can return -1 if there is bad mbs char in tstr
if(strwclen == static_cast<size_t>(-1))
strwclen = 0;
strwclen = utf8::idb_mbstowcs(wcbuf, tstr.c_str(), strwclen + 1);
// idb_mbstowcs can return -1 if there is bad mbs char in tstr
if (strwclen == static_cast<size_t>(-1))
strwclen = 0;
// Convert the trim string to wide
trimwclen = trim.length(); // A guess to start.
int trimbufsize = (trimwclen+1) * sizeof(wchar_t);
int trimbufsize = (trimwclen + 1) * sizeof(wchar_t);
wchar_t* wctrim = (wchar_t*)alloca(trimbufsize);
size_t trimlen = utf8::idb_mbstowcs(wctrim,trim.c_str(), trimwclen+1);
// idb_mbstowcs can return -1 if there is bad mbs char in tstr
if(trimlen == static_cast<size_t>(-1))
trimlen = 0;
size_t trimlen = utf8::idb_mbstowcs(wctrim, trim.c_str(), trimwclen + 1);
// idb_mbstowcs can return -1 if there is bad mbs char in tstr
if (trimlen == static_cast<size_t>(-1))
trimlen = 0;
size_t trimCmpLen = trimlen * sizeof(wchar_t);
const wchar_t* oPtr = wcbuf; // To remember the start of the string
const wchar_t* aPtr = oPtr;
const wchar_t* aEnd = wcbuf+strwclen-1;
const wchar_t* aEnd = wcbuf + strwclen - 1;
if(trimlen>0)
{
if (trimlen == 1)
{
// If trim is a single char, then don't spend the overhead for memcmp.
wchar_t chr=wctrim[0];
while (aPtr <= aEnd && *aPtr == chr)
aPtr++;
}
else
{
aEnd-=(trimlen-1); // So we don't compare past the end of the string.
while (aPtr <= aEnd && !memcmp(aPtr, wctrim, trimCmpLen))
aPtr+=trimlen;
}
}
if (trimlen > 0)
{
if (trimlen == 1)
{
// If trim is a single char, then don't spend the overhead for memcmp.
wchar_t chr = wctrim[0];
// Bug 5110 - error in allocating enough memory for utf8 chars
size_t aLen = strwclen-(aPtr-oPtr);
wstring trimmed = wstring(aPtr, aLen);
// Turn back to a string
return utf8::wstring_to_utf8(trimmed.c_str());
}
while (aPtr <= aEnd && *aPtr == chr)
aPtr++;
}
else
{
aEnd -= (trimlen - 1); // So we don't compare past the end of the string.
while (aPtr <= aEnd && !memcmp(aPtr, wctrim, trimCmpLen))
aPtr += trimlen;
}
}
// Bug 5110 - error in allocating enough memory for utf8 chars
size_t aLen = strwclen - (aPtr - oPtr);
wstring trimmed = wstring(aPtr, aLen);
// Turn back to a string
return utf8::wstring_to_utf8(trimmed.c_str());
}
} // namespace funcexp

View File

@ -40,45 +40,51 @@ using namespace funcexp;
namespace
{
uint64_t makedate(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull)
FunctionParm& parm,
bool& isNull)
{
int64_t year = 0;
string dayofyear;
int64_t year = 0;
string dayofyear;
//get year
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
{
double value = parm[0]->data()->getDoubleVal(row, isNull);
year = (int64_t) value;
break;
}
case CalpontSystemCatalog::DECIMAL:
{
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
year = d.value / helpers::power(d.scale);
int lefto = (d.value - year * helpers::power(d.scale)) / helpers::power(d.scale - 1);
if ( year >= 0 && lefto > 4 )
year++;
if ( year < 0 && lefto < -4 )
year--;
break;
}
default:
isNull = true;
return 0;
}
//get year
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
{
double value = parm[0]->data()->getDoubleVal(row, isNull);
year = (int64_t) value;
break;
}
case CalpontSystemCatalog::DECIMAL:
{
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
year = d.value / helpers::power(d.scale);
int lefto = (d.value - year * helpers::power(d.scale)) / helpers::power(d.scale-1);
if ( year >= 0 && lefto > 4 )
year++;
if ( year < 0 && lefto < -4 )
year--;
break;
}
default:
isNull = true;
return 0;
}
if (year < 70)
{
year = 2000 + year;
@ -87,74 +93,80 @@ uint64_t makedate(rowgroup::Row& row,
{
year = 1900 + year;
}
else if (year < 1000 || year > 9999) {
isNull = true;
return 0;
}
else if (year < 1000 || year > 9999)
{
isNull = true;
return 0;
}
//get dayofyear
switch (parm[1]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
{
dayofyear = parm[1]->data()->getStrVal(row, isNull);
//get dayofyear
switch (parm[1]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
{
dayofyear = parm[1]->data()->getStrVal(row, isNull);
if (atoi(dayofyear.c_str()) < 1)
{
isNull = true;
return 0;
}
if (atoi(dayofyear.c_str()) < 1)
{
isNull = true;
return 0;
}
break;
}
case CalpontSystemCatalog::DECIMAL:
{
IDB_Decimal d = parm[1]->data()->getDecimalVal(row, isNull);
int64_t tmp = d.value / helpers::power(d.scale);
int lefto = (d.value - tmp * helpers::power(d.scale)) / helpers::power(d.scale-1);
if ( tmp >= 0 && lefto > 4 )
tmp++;
if ( tmp < 0 && lefto < -4 )
tmp--;
break;
}
if (tmp < 1)
{
isNull = true;
return 0;
}
case CalpontSystemCatalog::DECIMAL:
{
IDB_Decimal d = parm[1]->data()->getDecimalVal(row, isNull);
int64_t tmp = d.value / helpers::power(d.scale);
int lefto = (d.value - tmp * helpers::power(d.scale)) / helpers::power(d.scale - 1);
if ( tmp >= 0 && lefto > 4 )
tmp++;
if ( tmp < 0 && lefto < -4 )
tmp--;
if (tmp < 1)
{
isNull = true;
return 0;
}
dayofyear = helpers::intToString(tmp);
break;
}
default:
isNull = true;
return 0;
}
break;
}
default:
isNull = true;
return 0;
}
// convert the year to a date in our internal format, then subtract
// one since we are about to add the day of year back in
Date d(year,1,1);
Date d(year, 1, 1);
//@Bug 5232. spare bit is set, cannot use regular substraction
d.day -= 1;
//uint64_t intDate = ((*(reinterpret_cast<uint32_t *> (&d))) & 0xFFFFFFC) - 1;
uint64_t intDate = *(reinterpret_cast<uint32_t *> (&d));
uint64_t intDate = *(reinterpret_cast<uint32_t*> (&d));
uint64_t value = helpers::dateAdd( intDate, dayofyear, IntervalColumn::INTERVAL_DAY, true, OP_ADD );
uint64_t value = helpers::dateAdd( intDate, dayofyear, IntervalColumn::INTERVAL_DAY, true, OP_ADD );
if ( value == 0 ) {
isNull = true;
}
if ( value == 0 )
{
isNull = true;
}
return value;
return value;
}
}
@ -165,29 +177,30 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_makedate::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_makedate::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
return makedate(row, parm, isNull);
return makedate(row, parm, isNull);
}
string Func_makedate::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
uint64_t value = makedate(row, parm, isNull);
if (isNull)
return "";
uint64_t value = makedate(row, parm, isNull);
return dataconvert::DataConvert::dateToString(value);
if (isNull)
return "";
return dataconvert::DataConvert::dateToString(value);
}

View File

@ -40,147 +40,162 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_maketime::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
string Func_maketime::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
int64_t hour = 0;
int64_t min = 0;
int64_t sec = 0;
int64_t hour = 0;
int64_t min = 0;
int64_t sec = 0;
//get hour
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
{
double value = parm[0]->data()->getDoubleVal(row, isNull);
hour = (int64_t) value;
break;
}
case CalpontSystemCatalog::DECIMAL:
{
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
hour = d.value / helpers::power(d.scale);
int lefto = (d.value - hour * helpers::power(d.scale)) / helpers::power(d.scale-1);
if ( hour >= 0 && lefto > 4 )
hour++;
if ( hour < 0 && lefto < -4 )
hour--;
break;
}
default:
isNull = true;
return "";
}
//get hour
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
{
double value = parm[0]->data()->getDoubleVal(row, isNull);
hour = (int64_t) value;
break;
}
//get minute
switch (parm[1]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
{
double value = parm[1]->data()->getDoubleVal(row, isNull);
min = (int64_t) value;
break;
}
case CalpontSystemCatalog::DECIMAL:
{
IDB_Decimal d = parm[1]->data()->getDecimalVal(row, isNull);
min = d.value / helpers::power(d.scale);
int lefto = (d.value - min * helpers::power(d.scale)) / helpers::power(d.scale-1);
if ( min >= 0 && lefto > 4 )
min++;
if ( min < 0 && lefto < -4 )
min--;
break;
}
default:
isNull = true;
return "";
}
case CalpontSystemCatalog::DECIMAL:
{
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
hour = d.value / helpers::power(d.scale);
int lefto = (d.value - hour * helpers::power(d.scale)) / helpers::power(d.scale - 1);
if (min < 0 || min > 59)
{
isNull = true;
return "";
}
if ( hour >= 0 && lefto > 4 )
hour++;
//get second
switch (parm[2]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
{
double value = parm[2]->data()->getDoubleVal(row, isNull);
sec = (int64_t) value;
break;
}
case CalpontSystemCatalog::DECIMAL:
{
IDB_Decimal d = parm[2]->data()->getDecimalVal(row, isNull);
sec = d.value / helpers::power(d.scale);
int lefto = (d.value - sec * helpers::power(d.scale)) / helpers::power(d.scale-1);
if ( sec >= 0 && lefto > 4 )
sec++;
if ( sec < 0 && lefto < -4 )
sec--;
break;
}
default:
isNull = true;
return "";
}
if ( hour < 0 && lefto < -4 )
hour--;
if (sec < 0 || sec > 59)
{
isNull = true;
return "";
}
break;
}
if (hour > 838)
{
hour = 838;
min = 59;
sec = 59;
}
default:
isNull = true;
return "";
}
if (hour < -838)
{
hour = -838;
min = 59;
sec = 59;
}
//get minute
switch (parm[1]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
{
double value = parm[1]->data()->getDoubleVal(row, isNull);
min = (int64_t) value;
break;
}
// in worst case hour is 4 characters (3 digits + '-') so max
case CalpontSystemCatalog::DECIMAL:
{
IDB_Decimal d = parm[1]->data()->getDecimalVal(row, isNull);
min = d.value / helpers::power(d.scale);
int lefto = (d.value - min * helpers::power(d.scale)) / helpers::power(d.scale - 1);
if ( min >= 0 && lefto > 4 )
min++;
if ( min < 0 && lefto < -4 )
min--;
break;
}
default:
isNull = true;
return "";
}
if (min < 0 || min > 59)
{
isNull = true;
return "";
}
//get second
switch (parm[2]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
{
double value = parm[2]->data()->getDoubleVal(row, isNull);
sec = (int64_t) value;
break;
}
case CalpontSystemCatalog::DECIMAL:
{
IDB_Decimal d = parm[2]->data()->getDecimalVal(row, isNull);
sec = d.value / helpers::power(d.scale);
int lefto = (d.value - sec * helpers::power(d.scale)) / helpers::power(d.scale - 1);
if ( sec >= 0 && lefto > 4 )
sec++;
if ( sec < 0 && lefto < -4 )
sec--;
break;
}
default:
isNull = true;
return "";
}
if (sec < 0 || sec > 59)
{
isNull = true;
return "";
}
if (hour > 838)
{
hour = 838;
min = 59;
sec = 59;
}
if (hour < -838)
{
hour = -838;
min = 59;
sec = 59;
}
// in worst case hour is 4 characters (3 digits + '-') so max
// string length is 11 (4:2:2 + '\0')
char buf[11];
snprintf(buf, 11, "%02d:%02d:%02d", (int) hour, (int) min, (int) sec);

File diff suppressed because it is too large Load Diff

View File

@ -88,53 +88,85 @@ class md5
{
// Methods
public:
md5() { Init(); }
void Init();
void Update(uchar* chInput, uint4 nInputLen);
void Finalize();
uchar* Digest() { return m_Digest; }
md5()
{
Init();
}
void Init();
void Update(uchar* chInput, uint4 nInputLen);
void Finalize();
uchar* Digest()
{
return m_Digest;
}
private:
void Transform(uchar* block);
void Encode(uchar* dest, uint4* src, uint4 nLength);
void Decode(uint4* dest, uchar* src, uint4 nLength);
void Transform(uchar* block);
void Encode(uchar* dest, uint4* src, uint4 nLength);
void Decode(uint4* dest, uchar* src, uint4 nLength);
inline uint4 rotate_left(uint4 x, uint4 n)
{ return ((x << n) | (x >> (32-n))); }
inline uint4 rotate_left(uint4 x, uint4 n)
{
return ((x << n) | (x >> (32 - n)));
}
inline uint4 F(uint4 x, uint4 y, uint4 z)
{ return ((x & y) | (~x & z)); }
inline uint4 F(uint4 x, uint4 y, uint4 z)
{
return ((x & y) | (~x & z));
}
inline uint4 G(uint4 x, uint4 y, uint4 z)
{ return ((x & z) | (y & ~z)); }
inline uint4 G(uint4 x, uint4 y, uint4 z)
{
return ((x & z) | (y & ~z));
}
inline uint4 H(uint4 x, uint4 y, uint4 z)
{ return (x ^ y ^ z); }
inline uint4 H(uint4 x, uint4 y, uint4 z)
{
return (x ^ y ^ z);
}
inline uint4 I(uint4 x, uint4 y, uint4 z)
{ return (y ^ (x | ~z)); }
inline uint4 I(uint4 x, uint4 y, uint4 z)
{
return (y ^ (x | ~z));
}
inline void FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
{ a += F(b, c, d) + x + ac; a = rotate_left(a, s); a += b; }
inline void FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
{
a += F(b, c, d) + x + ac;
a = rotate_left(a, s);
a += b;
}
inline void GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
{ a += G(b, c, d) + x + ac; a = rotate_left(a, s); a += b; }
inline void GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
{
a += G(b, c, d) + x + ac;
a = rotate_left(a, s);
a += b;
}
inline void HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
{ a += H(b, c, d) + x + ac; a = rotate_left(a, s); a += b; }
inline void HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
{
a += H(b, c, d) + x + ac;
a = rotate_left(a, s);
a += b;
}
inline void II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
{ a += I(b, c, d) + x + ac; a = rotate_left(a, s); a += b; }
inline void II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
{
a += I(b, c, d) + x + ac;
a = rotate_left(a, s);
a += b;
}
// Data
private:
uint4 m_State[4];
uint4 m_Count[2];
uchar m_Buffer[64];
uchar m_Digest[16];
uchar m_Finalized;
uint4 m_State[4];
uint4 m_Count[2];
uchar m_Buffer[64];
uchar m_Digest[16];
uchar m_Finalized;
};
@ -175,9 +207,9 @@ private:
static unsigned char PADDING[64] =
{
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
#define S11 7
@ -201,33 +233,33 @@ static unsigned char PADDING[64] =
// PrintMD5: Converts a completed md5 digest into a char* string.
char* PrintMD5(uchar md5Digest[16])
{
char chBuffer[256];
char chEach[10];
int nCount;
char chBuffer[256];
char chEach[10];
int nCount;
memset(chBuffer,0,256);
memset(chEach, 0, 10);
memset(chBuffer, 0, 256);
memset(chEach, 0, 10);
for (nCount = 0; nCount < 16; nCount++)
{
sprintf(chEach, "%02x", md5Digest[nCount]);
strncat(chBuffer, chEach, sizeof(chEach));
}
for (nCount = 0; nCount < 16; nCount++)
{
sprintf(chEach, "%02x", md5Digest[nCount]);
strncat(chBuffer, chEach, sizeof(chEach));
}
return strdup(chBuffer);
return strdup(chBuffer);
}
// MD5String: Performs the MD5 algorithm on a char* string, returning
// the results as a char*.
char* MD5String(const char* szString)
{
int nLen = strlen(szString);
md5 alg;
int nLen = strlen(szString);
md5 alg;
alg.Update((unsigned char*)szString, (unsigned int)nLen);
alg.Finalize();
alg.Update((unsigned char*)szString, (unsigned int)nLen);
alg.Finalize();
return PrintMD5(alg.Digest());
return PrintMD5(alg.Digest());
}
@ -235,33 +267,33 @@ char* MD5String(const char* szString)
// returning the results as a char*. Returns NULL if it fails.
char* MD5File(char* szFilename)
{
FILE* file;
md5 alg;
int nLen;
unsigned char chBuffer[1024];
FILE* file;
md5 alg;
int nLen;
unsigned char chBuffer[1024];
try
{
memset(chBuffer, 0, 1024);
try
{
memset(chBuffer, 0, 1024);
if ((file = fopen (szFilename, "rb")) != NULL)
{
while ((nLen = fread (chBuffer, 1, 1024, file)))
alg.Update(chBuffer, nLen);
if ((file = fopen (szFilename, "rb")) != NULL)
{
while ((nLen = fread (chBuffer, 1, 1024, file)))
alg.Update(chBuffer, nLen);
alg.Finalize();
alg.Finalize();
fclose (file);
fclose (file);
return PrintMD5(alg.Digest());
}
}
catch(...)
{
return PrintMD5(alg.Digest());
}
}
catch (...)
{
}
}
return NULL; // failed
return NULL; // failed
}
@ -269,12 +301,12 @@ char* MD5File(char* szFilename)
// Initializes a new context.
void md5::Init()
{
memset(m_Count, 0, 2 * sizeof(uint4));
memset(m_Count, 0, 2 * sizeof(uint4));
m_State[0] = 0x67452301;
m_State[1] = 0xefcdab89;
m_State[2] = 0x98badcfe;
m_State[3] = 0x10325476;
m_State[0] = 0x67452301;
m_State[1] = 0xefcdab89;
m_State[2] = 0x98badcfe;
m_State[3] = 0x10325476;
}
// md5::Update
@ -283,35 +315,35 @@ void md5::Init()
// context.
void md5::Update(uchar* chInput, uint4 nInputLen)
{
uint4 i, index, partLen;
uint4 i, index, partLen;
// Compute number of bytes mod 64
index = (unsigned int)((m_Count[0] >> 3) & 0x3F);
// Compute number of bytes mod 64
index = (unsigned int)((m_Count[0] >> 3) & 0x3F);
// Update number of bits
if ((m_Count[0] += (nInputLen << 3)) < (nInputLen << 3))
m_Count[1]++;
// Update number of bits
if ((m_Count[0] += (nInputLen << 3)) < (nInputLen << 3))
m_Count[1]++;
m_Count[1] += (nInputLen >> 29);
m_Count[1] += (nInputLen >> 29);
partLen = 64 - index;
partLen = 64 - index;
// Transform as many times as possible.
if (nInputLen >= partLen)
{
memcpy( &m_Buffer[index], chInput, partLen );
Transform(m_Buffer);
// Transform as many times as possible.
if (nInputLen >= partLen)
{
memcpy( &m_Buffer[index], chInput, partLen );
Transform(m_Buffer);
for (i = partLen; i + 63 < nInputLen; i += 64)
Transform(&chInput[i]);
for (i = partLen; i + 63 < nInputLen; i += 64)
Transform(&chInput[i]);
index = 0;
}
else
i = 0;
index = 0;
}
else
i = 0;
// Buffer remaining input
memcpy( &m_Buffer[index], &chInput[i], nInputLen-i );
// Buffer remaining input
memcpy( &m_Buffer[index], &chInput[i], nInputLen - i );
}
// md5::Finalize
@ -319,114 +351,114 @@ void md5::Update(uchar* chInput, uint4 nInputLen)
// the message digest and zeroizing the context.
void md5::Finalize()
{
uchar bits[8];
uint4 index, padLen;
uchar bits[8];
uint4 index, padLen;
// Save number of bits
Encode (bits, m_Count, 8);
// Save number of bits
Encode (bits, m_Count, 8);
// Pad out to 56 mod 64
index = (unsigned int)((m_Count[0] >> 3) & 0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index);
Update(PADDING, padLen);
// Pad out to 56 mod 64
index = (unsigned int)((m_Count[0] >> 3) & 0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index);
Update(PADDING, padLen);
// Append length (before padding)
Update (bits, 8);
// Append length (before padding)
Update (bits, 8);
// Store state in digest
Encode (m_Digest, m_State, 16);
// Store state in digest
Encode (m_Digest, m_State, 16);
memset(m_Count, 0, 2 * sizeof(uint4));
memset(m_State, 0, 4 * sizeof(uint4));
memset(m_Buffer,0, 64 * sizeof(uchar));
memset(m_Count, 0, 2 * sizeof(uint4));
memset(m_State, 0, 4 * sizeof(uint4));
memset(m_Buffer, 0, 64 * sizeof(uchar));
}
// md5::Transform
// MD5 basic transformation. Transforms state based on block.
void md5::Transform (uchar* block)
{
uint4 a = m_State[0], b = m_State[1], c = m_State[2], d = m_State[3], x[16];
uint4 a = m_State[0], b = m_State[1], c = m_State[2], d = m_State[3], x[16];
Decode (x, block, 64);
Decode (x, block, 64);
// Round 1
FF (a, b, c, d, x[ 0], S11, 0xd76aa478);
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756);
FF (c, d, a, b, x[ 2], S13, 0x242070db);
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee);
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf);
FF (d, a, b, c, x[ 5], S12, 0x4787c62a);
FF (c, d, a, b, x[ 6], S13, 0xa8304613);
FF (b, c, d, a, x[ 7], S14, 0xfd469501);
FF (a, b, c, d, x[ 8], S11, 0x698098d8);
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af);
FF (c, d, a, b, x[10], S13, 0xffff5bb1);
FF (b, c, d, a, x[11], S14, 0x895cd7be);
FF (a, b, c, d, x[12], S11, 0x6b901122);
FF (d, a, b, c, x[13], S12, 0xfd987193);
FF (c, d, a, b, x[14], S13, 0xa679438e);
FF (b, c, d, a, x[15], S14, 0x49b40821);
// Round 1
FF (a, b, c, d, x[ 0], S11, 0xd76aa478);
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756);
FF (c, d, a, b, x[ 2], S13, 0x242070db);
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee);
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf);
FF (d, a, b, c, x[ 5], S12, 0x4787c62a);
FF (c, d, a, b, x[ 6], S13, 0xa8304613);
FF (b, c, d, a, x[ 7], S14, 0xfd469501);
FF (a, b, c, d, x[ 8], S11, 0x698098d8);
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af);
FF (c, d, a, b, x[10], S13, 0xffff5bb1);
FF (b, c, d, a, x[11], S14, 0x895cd7be);
FF (a, b, c, d, x[12], S11, 0x6b901122);
FF (d, a, b, c, x[13], S12, 0xfd987193);
FF (c, d, a, b, x[14], S13, 0xa679438e);
FF (b, c, d, a, x[15], S14, 0x49b40821);
// Round 2
GG (a, b, c, d, x[ 1], S21, 0xf61e2562);
GG (d, a, b, c, x[ 6], S22, 0xc040b340);
GG (c, d, a, b, x[11], S23, 0x265e5a51);
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa);
GG (a, b, c, d, x[ 5], S21, 0xd62f105d);
GG (d, a, b, c, x[10], S22, 0x2441453);
GG (c, d, a, b, x[15], S23, 0xd8a1e681);
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8);
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6);
GG (d, a, b, c, x[14], S22, 0xc33707d6);
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87);
GG (b, c, d, a, x[ 8], S24, 0x455a14ed);
GG (a, b, c, d, x[13], S21, 0xa9e3e905);
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8);
GG (c, d, a, b, x[ 7], S23, 0x676f02d9);
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a);
// Round 2
GG (a, b, c, d, x[ 1], S21, 0xf61e2562);
GG (d, a, b, c, x[ 6], S22, 0xc040b340);
GG (c, d, a, b, x[11], S23, 0x265e5a51);
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa);
GG (a, b, c, d, x[ 5], S21, 0xd62f105d);
GG (d, a, b, c, x[10], S22, 0x2441453);
GG (c, d, a, b, x[15], S23, 0xd8a1e681);
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8);
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6);
GG (d, a, b, c, x[14], S22, 0xc33707d6);
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87);
GG (b, c, d, a, x[ 8], S24, 0x455a14ed);
GG (a, b, c, d, x[13], S21, 0xa9e3e905);
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8);
GG (c, d, a, b, x[ 7], S23, 0x676f02d9);
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a);
// Round 3
HH (a, b, c, d, x[ 5], S31, 0xfffa3942);
HH (d, a, b, c, x[ 8], S32, 0x8771f681);
HH (c, d, a, b, x[11], S33, 0x6d9d6122);
HH (b, c, d, a, x[14], S34, 0xfde5380c);
HH (a, b, c, d, x[ 1], S31, 0xa4beea44);
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9);
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60);
HH (b, c, d, a, x[10], S34, 0xbebfbc70);
HH (a, b, c, d, x[13], S31, 0x289b7ec6);
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa);
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085);
HH (b, c, d, a, x[ 6], S34, 0x4881d05);
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039);
HH (d, a, b, c, x[12], S32, 0xe6db99e5);
HH (c, d, a, b, x[15], S33, 0x1fa27cf8);
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665);
// Round 3
HH (a, b, c, d, x[ 5], S31, 0xfffa3942);
HH (d, a, b, c, x[ 8], S32, 0x8771f681);
HH (c, d, a, b, x[11], S33, 0x6d9d6122);
HH (b, c, d, a, x[14], S34, 0xfde5380c);
HH (a, b, c, d, x[ 1], S31, 0xa4beea44);
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9);
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60);
HH (b, c, d, a, x[10], S34, 0xbebfbc70);
HH (a, b, c, d, x[13], S31, 0x289b7ec6);
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa);
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085);
HH (b, c, d, a, x[ 6], S34, 0x4881d05);
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039);
HH (d, a, b, c, x[12], S32, 0xe6db99e5);
HH (c, d, a, b, x[15], S33, 0x1fa27cf8);
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665);
// Round 4
II (a, b, c, d, x[ 0], S41, 0xf4292244);
II (d, a, b, c, x[ 7], S42, 0x432aff97);
II (c, d, a, b, x[14], S43, 0xab9423a7);
II (b, c, d, a, x[ 5], S44, 0xfc93a039);
II (a, b, c, d, x[12], S41, 0x655b59c3);
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92);
II (c, d, a, b, x[10], S43, 0xffeff47d);
II (b, c, d, a, x[ 1], S44, 0x85845dd1);
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f);
II (d, a, b, c, x[15], S42, 0xfe2ce6e0);
II (c, d, a, b, x[ 6], S43, 0xa3014314);
II (b, c, d, a, x[13], S44, 0x4e0811a1);
II (a, b, c, d, x[ 4], S41, 0xf7537e82);
II (d, a, b, c, x[11], S42, 0xbd3af235);
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb);
II (b, c, d, a, x[ 9], S44, 0xeb86d391);
// Round 4
II (a, b, c, d, x[ 0], S41, 0xf4292244);
II (d, a, b, c, x[ 7], S42, 0x432aff97);
II (c, d, a, b, x[14], S43, 0xab9423a7);
II (b, c, d, a, x[ 5], S44, 0xfc93a039);
II (a, b, c, d, x[12], S41, 0x655b59c3);
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92);
II (c, d, a, b, x[10], S43, 0xffeff47d);
II (b, c, d, a, x[ 1], S44, 0x85845dd1);
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f);
II (d, a, b, c, x[15], S42, 0xfe2ce6e0);
II (c, d, a, b, x[ 6], S43, 0xa3014314);
II (b, c, d, a, x[13], S44, 0x4e0811a1);
II (a, b, c, d, x[ 4], S41, 0xf7537e82);
II (d, a, b, c, x[11], S42, 0xbd3af235);
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb);
II (b, c, d, a, x[ 9], S44, 0xeb86d391);
m_State[0] += a;
m_State[1] += b;
m_State[2] += c;
m_State[3] += d;
m_State[0] += a;
m_State[1] += b;
m_State[2] += c;
m_State[3] += d;
memset(x, 0, sizeof(x));
memset(x, 0, sizeof(x));
}
// md5::Encode
@ -434,17 +466,17 @@ void md5::Transform (uchar* block)
// a multiple of 4.
void md5::Encode(uchar* dest, uint4* src, uint4 nLength)
{
uint4 i, j;
uint4 i, j;
idbassert(nLength % 4 == 0);
idbassert(nLength % 4 == 0);
for (i = 0, j = 0; j < nLength; i++, j += 4)
{
dest[j] = (uchar)(src[i] & 0xff);
dest[j+1] = (uchar)((src[i] >> 8) & 0xff);
dest[j+2] = (uchar)((src[i] >> 16) & 0xff);
dest[j+3] = (uchar)((src[i] >> 24) & 0xff);
}
for (i = 0, j = 0; j < nLength; i++, j += 4)
{
dest[j] = (uchar)(src[i] & 0xff);
dest[j + 1] = (uchar)((src[i] >> 8) & 0xff);
dest[j + 2] = (uchar)((src[i] >> 16) & 0xff);
dest[j + 3] = (uchar)((src[i] >> 24) & 0xff);
}
}
// md5::Decode
@ -452,38 +484,38 @@ void md5::Encode(uchar* dest, uint4* src, uint4 nLength)
// a multiple of 4.
void md5::Decode(uint4* dest, uchar* src, uint4 nLength)
{
uint4 i, j;
uint4 i, j;
idbassert(nLength % 4 == 0);
idbassert(nLength % 4 == 0);
for (i = 0, j = 0; j < nLength; i++, j += 4)
{
dest[i] = ((uint4)src[j]) | (((uint4)src[j+1])<<8) |
(((uint4)src[j+2])<<16) | (((uint4)src[j+3])<<24);
}
for (i = 0, j = 0; j < nLength; i++, j += 4)
{
dest[i] = ((uint4)src[j]) | (((uint4)src[j + 1]) << 8) |
(((uint4)src[j + 2]) << 16) | (((uint4)src[j + 3]) << 24);
}
}
}
namespace funcexp
namespace funcexp
{
CalpontSystemCatalog::ColType Func_md5::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
string Func_md5::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
const string& arg = parm[0]->data()->getStrVal(row, isNull);
return MD5String(arg.c_str());
//return str;
const string& arg = parm[0]->data()->getStrVal(row, isNull);
return MD5String(arg.c_str());
//return str;
}

View File

@ -39,79 +39,90 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_microsecond::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_microsecond::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
int64_t val = 0;
uint32_t microSecond = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
microSecond = 0;
break;
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
microSecond = (uint32_t)((val & 0xfffff));
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
microSecond = (uint32_t)((val & 0xfffff));
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
microSecond = (uint32_t)((val & 0xfffff));
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
microSecond = (uint32_t)((val & 0xfffff));
}
}
break;
default:
isNull = true;
return -1;
}
return microSecond;
int64_t val = 0;
uint32_t microSecond = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
microSecond = 0;
break;
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
microSecond = (uint32_t)((val & 0xfffff));
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
microSecond = (uint32_t)((val & 0xfffff));
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
microSecond = (uint32_t)((val & 0xfffff));
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
microSecond = (uint32_t)((val & 0xfffff));
}
}
break;
default:
isNull = true;
return -1;
}
return microSecond;
}

View File

@ -38,75 +38,89 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_minute::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_minute::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
int64_t val = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
isNull = true;
break;
}
case execplan::CalpontSystemCatalog::DECIMAL:
{
if (parm[0]->data()->resultType().scale)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
isNull = true;
}
break;
}
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
{
isNull = true;
}
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
isNull = true;
break;
}
case execplan::CalpontSystemCatalog::DATE:
{
val = parm[0]->data()->getDatetimeIntVal(row, isNull);
break;
}
case execplan::CalpontSystemCatalog::DATETIME:
{
val = parm[0]->data()->getDatetimeIntVal(row, isNull);
break;
}
default:
{
isNull = true;
}
}
if (isNull)
return -1;
if ( val < 1000000000 )
return 0;
int64_t val = 0;
return (unsigned)((val >> 26) & 0x3f);
switch (parm[0]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
isNull = true;
break;
}
case execplan::CalpontSystemCatalog::DECIMAL:
{
if (parm[0]->data()->resultType().scale)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
isNull = true;
}
break;
}
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
{
isNull = true;
}
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
isNull = true;
break;
}
case execplan::CalpontSystemCatalog::DATE:
{
val = parm[0]->data()->getDatetimeIntVal(row, isNull);
break;
}
case execplan::CalpontSystemCatalog::DATETIME:
{
val = parm[0]->data()->getDatetimeIntVal(row, isNull);
break;
}
default:
{
isNull = true;
}
}
if (isNull)
return -1;
if ( val < 1000000000 )
return 0;
return (unsigned)((val >> 26) & 0x3f);
}

Some files were not shown because too many files have changed in this diff Show More