/*
* This file is part of rasdaman community.
*
* Rasdaman community is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Rasdaman community is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with rasdaman community. If not, see .
*
* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
rasdaman GmbH.
*
* For more information please see
* or contact Peter Baumann via .
*/
/*************************************************************
*
*
* PURPOSE:
*
*
* COMMENTS:
*
************************************************************/
static const char rcsid[] = "@(#)qlparser, QtTrim: $Id: qtdomainoperation.cc,v 1.35 2002/06/15 20:16:42 coman Exp $";
#include
#include
using namespace std;
#include "raslib/rmdebug.hh"
#include "qlparser/qtmdd.hh"
#include "qlparser/qtunaryoperation.hh"
#include "qlparser/qtdomainoperation.hh"
#include "qlparser/qtnode.hh"
#include "qlparser/qtconst.hh"
#include "qlparser/qtmintervaldata.hh"
#include "qlparser/qtintervaldata.hh"
#include "qlparser/qtpointdata.hh"
#include "qlparser/qtatomicdata.hh"
#include "qlparser/qtcomplexdata.hh"
#include "mddmgr/mddobj.hh"
#include "tilemgr/tile.hh"
#include "catalogmgr/ops.hh"
#include "relcatalogif/mddbasetype.hh"
#include "relcatalogif/ulongtype.hh"
#include
const QtNode::QtNodeType QtDomainOperation::nodeType = QtNode::QT_DOMAIN_OPERATION;
QtDomainOperation::QtDomainOperation( QtOperation* mintOp )
: mintervalOp( mintOp ),
dynamicMintervalExpression( true )
{
RMDBCLASS( "QtDomainOperation", "QtDomainOperation( QtOperation* )", "qlparser", __FILE__, __LINE__ )
if( mintervalOp ) mintervalOp->setParent( this );
}
QtDomainOperation::QtDomainOperation( r_Minterval domainNew, const vector* newTrimFlags )
: mintervalOp(0),
dynamicMintervalExpression( false )
{
RMDBCLASS( "QtDomainOperation", "QtDomainOperation( r_Minterval, const vector* )", "qlparser", __FILE__, __LINE__ )
// make a copy
vector* trimFlags = new vector( *newTrimFlags );
mintervalOp = new QtConst( new QtMintervalData( domainNew, trimFlags ) );
mintervalOp->setParent( this );
}
QtDomainOperation::~QtDomainOperation()
{
RMDBCLASS( "QtDomainOperation", "~QtDomainOperation()", "qlparser", __FILE__, __LINE__ )
if( mintervalOp )
{
delete mintervalOp;
mintervalOp=NULL;
}
}
QtNode::QtNodeList*
QtDomainOperation::getChilds( QtChildType flag )
{
RMDBCLASS( "QtDomainOperation", "getChilds( QtChildType )", "qlparser", __FILE__, __LINE__ )
QtNodeList* resultList=NULL;
resultList = QtUnaryOperation::getChilds( flag );
if( mintervalOp )
{
if( flag == QT_LEAF_NODES || flag == QT_ALL_NODES )
{
QtNodeList* subList;
subList = mintervalOp->getChilds( flag );
// remove all elements in subList and insert them at the beginning in resultList
resultList->splice( resultList->begin(), *subList );
// delete temporary subList
delete subList;
subList=NULL;
}
// add the nodes of the current level
if( flag == QT_DIRECT_CHILDS || flag == QT_ALL_NODES )
resultList->push_back( mintervalOp );
}
return resultList;
}
bool
QtDomainOperation::equalMeaning( QtNode* node )
{
RMDBCLASS( "QtDomainOperation", "equalMeaning( QtNode* )", "qlparser", __FILE__, __LINE__ )
bool result = false;
if( nodeType == node->getNodeType() )
{
QtDomainOperation* domainNode;
domainNode = (QtDomainOperation*) node; // by force
result = input->equalMeaning( domainNode->getInput() ) &&
mintervalOp->equalMeaning( domainNode->getMintervalOp() );
};
return ( result );
}
string
QtDomainOperation::getSpelling()
{
char tempStr[20];
sprintf(tempStr, "%ud", (unsigned long)getNodeType());
string result = string(tempStr);
result.append( mintervalOp->getSpelling() );
result.append( "(" );
result.append( input->getSpelling() );
result.append( ")" );
return result;
}
void
QtDomainOperation::setInput( QtOperation* inputOld, QtOperation* inputNew )
{
QtUnaryOperation::setInput( inputOld, inputNew );
if( mintervalOp == inputOld )
{
mintervalOp = inputNew;
if( inputNew )
inputNew->setParent( this );
}
};
void
QtDomainOperation::optimizeLoad( QtTrimList* trimList )
{
RMDBCLASS( "QtDomainOperation", "optimizeLoad( QtTrimList* )", "qlparser", __FILE__, __LINE__ )
// test, if there is already a specification for that dimension
bool trimming = false;
if( mintervalOp )
{
// pass optimization to minterval tree
mintervalOp->optimizeLoad( new QtNode::QtTrimList );
// evaluate minterval tree
QtData* operand = mintervalOp->evaluate(NULL);
// if spatial operation could be determined, it is static
dynamicMintervalExpression = !operand;
if( operand )
{
if( operand->getDataType() == QT_MINTERVAL )
{
r_Minterval domain = ((QtMintervalData*)operand)->getMintervalData();
vector* trimFlags = new vector( *(((QtMintervalData*)operand)->getTrimFlags()) );
if( trimList && trimList->empty() )
{
// no previous specification for that dimension
trimming = true;
for( int i=0; i!=domain.dimension(); i++ )
{
// create a new element
QtTrimElement* elem = new QtTrimElement;
elem->interval = domain[i];
elem->intervalFlag = (*trimFlags)[i];
elem->dimension = i;
// and add it to the list
trimList->push_back( elem );
trimming &= (*trimFlags)[i];
}
}
else
{
// previous specification exists, test for compatibility
}
if( trimFlags )
{
delete trimFlags;
trimFlags = NULL;
}
}
// else if( operand->getDataType() == QtData::QT_POINT )
// delete the operand
operand->deleteRef();
}
}
// pass optimization process to the input tree
if( input ) input->optimizeLoad( trimList );
// Eliminate node QtDomainOperation if only trimming occurs.
if( trimming )
{
RMDBGMIDDLE(2, RMDebug::module_qlparser, "QtDomainOperation", "all trimming")
getParent()->setInput( this, input );
// Delete the node itself after resetting its input because
// otherwise the input is delete either.
setInput( input, NULL );
delete this;
}
}
QtData*
QtDomainOperation::evaluate( QtDataList* inputList )
{
RMDBCLASS( "QtDomainOperation", "evaluate( QtDataList* )", "qlparser", __FILE__, __LINE__ )
QtData* returnValue = NULL;
switch( input->getDataStreamType().getDataType() )
{
case QT_MDD:
{
if( mintervalOp->getDataStreamType().getDataType() == QT_POINT ||
mintervalOp->getDataStreamType().isInteger() )
{
//
// Projection to one cell.
//
QtData* indexData = mintervalOp->evaluate( inputList );
if( !indexData )
return 0;
#ifdef QT_RUNTIME_TYPE_CHECK
if( indexData->getDataType() != QT_POINT &&
!indexData->getDataType().isInteger() )
{
RMInit::logOut << "Internal error in QtDomainOperation::evaluate() - "
<< "runtime type checking failed (QT_POINT, INTEGER)." << endl;
// delete index data
indexData->deleteRef();
return 0;
}
#endif
// get projection point
r_Point projPoint;
if( indexData->getDataType() == QT_POINT )
{
projPoint = ((QtPointData*)indexData)->getPointData();
}
else
{
projPoint = r_Point(1);
if( indexData->getDataType() == QT_SHORT ||
indexData->getDataType() == QT_OCTET ||
indexData->getDataType() == QT_LONG )
projPoint[0] = ((QtAtomicData*)indexData)->getSignedValue();
else
projPoint[0] = ((QtAtomicData*)indexData)->getUnsignedValue();
}
//
// In case of dynamic index expressions, load optimization has to
// be performed for the current input expression.
//
/*
if( dynamicMintervalExpression )
{
QtNode::QtTrimList* trimList = new QtNode::QtTrimList;
for( int i=0; i!=domain.dimension(); i++ )
{
// create a new element
QtTrimElement* elem = new QtTrimElement;
elem->interval = domain[i];
elem->intervalFlag = (*trimFlags)[i];
elem->dimension = i;
// and add it to the list
trimList->push_back( elem );
}
// pass optimization process to the input tree
input->optimizeLoad( trimList );
}
*/
// get operand data
QtData* operand = input->evaluate( inputList );
if( !operand )
{
// delete indexData
indexData->deleteRef();
return 0;
}
#ifdef QT_RUNTIME_TYPE_CHECK
if( operand->getDataType() != QT_MDD )
{
RMInit::logOut << "Internal error in QtDomainOperation::evaluate() - runtime type checking failed (QT_MDD)." << endl;
// delete index and operand data
indexData->deleteRef();
operand ->deleteRef();
return 0;
}
#endif
QtMDD* qtMDD = (QtMDD*) operand;
MDDObj* currentMDDObj = qtMDD->getMDDObject();
if( currentMDDObj )
{
RMDBGMIDDLE(2, RMDebug::module_qlparser, "QtDomainOperation", " mdd domain: " << currentMDDObj->getCurrentDomain() )
RMDBGMIDDLE(2, RMDebug::module_qlparser, "QtDomainOperation", " mdd load domain: " << qtMDD->getLoadDomain() )
// reset loadDomain to intersection of domain and loadDomain
// if( domain.intersection_with( qtMDD->getLoadDomain() ) != qtMDD->getLoadDomain() )
// qtMDD->setLoadDomain( domain.intersection_with( qtMDD->getLoadDomain() ) );
// get type of cell
const BaseType* cellType = ((MDDBaseType*)(currentMDDObj->getMDDBaseType()))->getBaseType();
RMDBGMIDDLE(2, RMDebug::module_qlparser, "QtDomainOperation", " point access: " << projPoint )
const char* resultCell = NULL;
if (projPoint.dimension() == currentMDDObj->getDimension())
resultCell = currentMDDObj->pointQuery( projPoint );
if (resultCell == NULL)
{
RMInit::logOut << "Error: QtDomainOperation::evaluate() - projected cell is not defined." << endl;
parseInfo.setErrorNo(356);
// delete index and operand data
indexData->deleteRef();
operand ->deleteRef();
throw parseInfo;
}
// allocate cell buffer
char* resultBuffer = new char[ cellType->getSize() ];
// copy cell content
memcpy( (void*)resultBuffer, (void*)resultCell, cellType->getSize() );
// create data object for the cell
QtScalarData* scalarDataObj = NULL;
if( cellType->getType() == STRUCT )
scalarDataObj = new QtComplexData();
else
scalarDataObj = new QtAtomicData();
scalarDataObj->setValueType ( cellType );
scalarDataObj->setValueBuffer( resultBuffer );
// set return data object
returnValue = scalarDataObj;
}
// delete indexData
indexData->deleteRef();
// delete old operand
operand->deleteRef();
}
else // mintervalOp->getDataStreamType() == QT_MINTERVAL
{
//
// Trimming/Projection to an MDD object
//
QtData* indexData = mintervalOp->evaluate( inputList );
if( !indexData )
return 0;
#ifdef QT_RUNTIME_TYPE_CHECK
if( indexData->getDataType() != QT_MINTERVAL )
{
RMInit::logOut << "Internal error in QtDomainOperation::evaluate() - "
<< "runtime type checking failed (QT_MINTERVAL)." << endl;
// delete index data
indexData->deleteRef();
return 0;
}
#endif
// get minterval data
vector* trimFlags = new vector( *(((QtMintervalData*)indexData)->getTrimFlags()) );
r_Minterval domain = ((QtMintervalData*)indexData)->getMintervalData();
//
// In case of dynamic index expressions, load optimization has to
// be performed for the current input expression.
//
if( dynamicMintervalExpression )
{
QtNode::QtTrimList* trimList = new QtNode::QtTrimList;
for( int i=0; i!=domain.dimension(); i++ )
{
// create a new element
QtTrimElement* elem = new QtTrimElement;
elem->interval = domain[i];
elem->intervalFlag = (*trimFlags)[i];
elem->dimension = i;
// and add it to the list
trimList->push_back( elem );
}
// pass optimization process to the input tree
input->optimizeLoad( trimList );
}
// get operand data
QtData* operand = input->evaluate( inputList );
if( !operand )
{
// delete index data
indexData->deleteRef();
return 0;
}
#ifdef QT_RUNTIME_TYPE_CHECK
if( operand->getDataType() != QT_MDD )
{
RMInit::logOut << "Internal error in QtDomainOperation::evaluate() - runtime type checking failed (QT_MDD)." << endl;
// delete index and operand data
indexData->deleteRef();
operand ->deleteRef();
return 0;
}
#endif
QtMDD* qtMDD = (QtMDD*) operand;
MDDObj* currentMDDObj = qtMDD->getMDDObject();
if( currentMDDObj )
{
bool trimming = false;
bool projection = false;
// reset loadDomain to intersection of domain and loadDomain
if( domain.intersection_with( qtMDD->getLoadDomain() ) != qtMDD->getLoadDomain() )
qtMDD->setLoadDomain( domain.intersection_with( qtMDD->getLoadDomain() ) );
// Test, if trimming has to be done; trimming = 1 if !(load domain is subset of spatial operation)
trimming = ( domain.intersection_with( qtMDD->getLoadDomain() ) == qtMDD->getLoadDomain() );
// Test, if a projection has to be made and build the projSet in projection case
set< r_Dimension, less > projSet;
for( int i=0; isize(); i++ )
if( !(*trimFlags)[i] )
{
projection = true;
projSet.insert( i );
}
r_Minterval projectedDom( domain.dimension() - projSet.size() );
// build the projected domain
for( int i = 0; i < domain.dimension(); i++ )
// do not include dimensions projected away
if(projSet.find(i) == projSet.end())
projectedDom << domain[i];
if( trimFlags )
{
delete trimFlags;
trimFlags = NULL;
}
RMDBGMIDDLE(2, RMDebug::module_qlparser, "QtDomainOperation", " operation domain..: " << domain << " with projection " << projectedDom )
RMDBGMIDDLE(2, RMDebug::module_qlparser, "QtDomainOperation", " mdd load domain: " << qtMDD->getLoadDomain() )
RMDBGMIDDLE(2, RMDebug::module_qlparser, "QtDomainOperation", " mdd current domain: " << currentMDDObj->getCurrentDomain() )
if( trimming || projection )
{
// get relevant tiles
vector* relevantTiles = currentMDDObj->intersect( domain );
if( relevantTiles->size() > 0 )
{
// iterator for tiles
vector::iterator tileIt;
// create a transient MDD object for the query result
MDDObj* resultMDD = new MDDObj( currentMDDObj->getMDDBaseType(), projectedDom );
// and iterate over them
for( tileIt = relevantTiles->begin(); tileIt != relevantTiles->end(); tileIt++ )
{
// domain of the actual tile
r_Minterval tileDom = (*tileIt)->getDomain();
// domain of the relevant area of the actual tile
r_Minterval intersectDom = tileDom.create_intersection( domain );
RMDBGMIDDLE(2, RMDebug::module_qlparser, "QtDomainOperation", " trimming/projecting tile with domain " << tileDom << " to domain " << intersectDom )
// create projected tile
Tile* resTile = new Tile( (*tileIt), intersectDom, &projSet );
// insert Tile in result mddObj
resultMDD->insertTile( resTile );
}
// create a new QtMDD object as carrier object for the transient MDD object
returnValue = new QtMDD( (MDDObj*)resultMDD );
// delete the tile vector
delete relevantTiles;
relevantTiles=NULL;
}
else
{
RMInit::logOut << "Error: QtDomainOperation::evaluate() - the load domain does not intersect with tiles in the current MDD." << endl;
parseInfo.setErrorNo(356);
// delete index and operand data
indexData->deleteRef();
operand ->deleteRef();
throw parseInfo;
}
} // trimming || projection
else
// operand is passed through
returnValue = operand;
} // if( currentMDDObj )
// delete index and operand data
if( indexData ) indexData->deleteRef();
if( operand ) operand ->deleteRef();
}
break;
}
case QT_MINTERVAL:
{
QtData* operandData = NULL;
QtData* indexData = NULL;
operandData = input->evaluate( inputList );
if( operandData )
{
#ifdef QT_RUNTIME_TYPE_CHECK
if( operandData->getDataType() != QT_MINTERVAL )
{
RMInit::logOut << "Internal error in QtDomainOperation::evaluate() - runtime type checking failed (QT_MINTERVAL)." << endl;
return 0;
}
#endif
// get point
const r_Minterval& minterval = ((QtMintervalData*)operandData)->getMintervalData();
// get index
indexData = mintervalOp->evaluate( inputList );
#ifdef QT_RUNTIME_TYPE_CHECK
if( indexData->getDataType() != QT_POINT && indexData->getDataType() != QT_CHAR &&
indexData->getDataType() != QT_USHORT && indexData->getDataType() != QT_ULONG )
{
RMInit::logOut << "Internal error in QtDomainOperation::evaluate() - runtime type checking failed." << endl;
return 0;
}
#endif
r_Dimension indexValue = 0;
switch( indexData->getDataType() )
{
case QT_POINT:
{
// get first element as index
const r_Point& indexPoint = ((QtPointData*)indexData)->getPointData();
if( indexPoint.dimension() != 1 )
{
RMInit::logOut << "Error: QtDomainOperation::evaluate() - Operand of minterval selection must be of type unsigned integer." << endl;
parseInfo.setErrorNo(397);
// delete ressources
if( operandData ) operandData->deleteRef();
if( indexData ) indexData ->deleteRef();
throw parseInfo;
}
indexValue = indexPoint[0];
}
break;
case QT_CHAR:
case QT_USHORT:
case QT_ULONG:
indexValue = ((QtAtomicData*)indexData)->getUnsignedValue();
break;
case QT_OCTET:
case QT_SHORT:
case QT_LONG:
indexValue = ((QtAtomicData*)indexData)->getSignedValue();
break;
default:
RMDBGONCE(0, RMDebug::module_qlparser, "r_QtDomainOperation", "evaluate() bad type " << indexData->getDataType());
break;
}
//indexValue is a unsigned type -> there will never be a indexVAlue < 0
if( /*indexValue < 0 ||*/ indexValue >= minterval.dimension() )
{
RMInit::logOut << "Error: QtDomainOperation::evaluate() - index for minterval selection is out of range." << endl;
parseInfo.setErrorNo(398);
// delete ressources
if( operandData ) operandData->deleteRef();
if( indexData ) indexData ->deleteRef();
throw parseInfo;
}
returnValue = new QtIntervalData( minterval[indexValue] );
}
// delete ressources
if( operandData ) operandData->deleteRef();
if( indexData ) indexData ->deleteRef();
break;
}
case QT_POINT:
{
QtData* operandData = NULL;
QtData* indexData = NULL;
operandData = input->evaluate( inputList );
if( operandData )
{
#ifdef QT_RUNTIME_TYPE_CHECK
if( operandData->getDataType() != QT_POINT )
{
RMInit::logOut << "Internal error in QtDomainOperation::evaluate() - runtime type checking failed (QT_POINT)." << endl;
return 0;
}
#endif
// get point
const r_Point& pt = ((QtPointData*)operandData)->getPointData();
// get index
indexData = mintervalOp->evaluate( inputList );
#ifdef QT_RUNTIME_TYPE_CHECK
if( indexData->getDataType() != QT_POINT && indexData->getDataType() != QT_CHAR &&
indexData->getDataType() != QT_USHORT && indexData->getDataType() != QT_ULONG )
{
RMInit::logOut << "Internal error in QtDomainOperation::evaluate() - runtime type checking failed." << endl;
return 0;
}
#endif
r_Dimension indexValue = 0;
switch( indexData->getDataType() )
{
case QT_POINT:
{
// get first element as index
const r_Point& indexPoint = ((QtPointData*)indexData)->getPointData();
if( indexPoint.dimension() != 1 )
{
RMInit::logOut << "Error: QtDomainOperation::evaluate() - Operand of point selection must be of type unsigned integer." << endl;
parseInfo.setErrorNo(399);
// delete ressources
if( operandData ) operandData->deleteRef();
if( indexData ) indexData ->deleteRef();
throw parseInfo;
}
indexValue = indexPoint[0];
}
break;
case QT_CHAR:
case QT_USHORT:
case QT_ULONG:
indexValue = ((QtAtomicData*)indexData)->getUnsignedValue();
break;
case QT_OCTET:
case QT_SHORT:
case QT_LONG:
indexValue = ((QtAtomicData*)indexData)->getSignedValue();
break;
default:
RMDBGONCE(0, RMDebug::module_qlparser, "r_QtDomainOperation", "evaluate() 2 - bad type " << indexData->getDataType());
break;
}
//indexValue is a unsigned type -> there will never be a indexValue < 0
if( /*indexValue < 0 ||*/ indexValue >= pt.dimension() )
{
RMInit::logOut << "Error: QtDomainOperation::evaluate() - index for point selection is out of range." << endl;
parseInfo.setErrorNo(411);
// delete ressources
if( operandData ) operandData->deleteRef();
if( indexData ) indexData ->deleteRef();
throw parseInfo;
}
returnValue = new QtAtomicData( (r_Long)pt[indexValue], 4 );
}
// delete ressources
if( operandData ) operandData->deleteRef();
if( indexData ) indexData ->deleteRef();
break;
}
default:
{
RMInit::logOut << "Error: QtDomainOperation::evaluate() - selection operation is not supported on this data type." << endl;
parseInfo.setErrorNo(396);
throw parseInfo;
}
}
return returnValue;
}
void
QtDomainOperation::printTree( int tab, ostream& s, QtChildType mode )
{
s << SPACE_STR(tab).c_str() << "QtDomainOperation Object: type " << flush;
dataStreamType.printStatus( s );
s << endl;
if( mintervalOp )
{
s << SPACE_STR(tab).c_str() << "spatial operation: " << endl;
mintervalOp->printTree( tab + 2, s );
}
else
s << SPACE_STR(tab).c_str() << "no spatial operation" << endl;
QtUnaryOperation::printTree( tab, s, mode );
}
void
QtDomainOperation::printAlgebraicExpression( ostream& s )
{
s << "geo(";
if( mintervalOp )
mintervalOp->printAlgebraicExpression( s );
else
s << "";
s << ",";
if( input )
input->printAlgebraicExpression( s );
else
s << "";
s << ")";
}
const QtTypeElement&
QtDomainOperation::checkType( QtTypeTuple* typeTuple )
{
RMDBCLASS( "QtDomainOperation", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ )
dataStreamType.setDataType( QT_TYPE_UNKNOWN );
//
// operation signatures
//
// MDD x Minterval -> MDD
// // MDD x Interval -> MDD
// MDD x Point -> T
// MDD x Integer -> T
// Minterval x Integer -> Interval
// Minterval x Point(1) -> Interval
// Point x Integer -> Integer
// Point x Point(1) -> Integer
//
// check operand branches
if( input && mintervalOp )
{
// 1. check input expression type
const QtTypeElement& inputType = input->checkType( typeTuple );
// 2. check index expression type
const QtTypeElement& indexType = mintervalOp->checkType( typeTuple );
// 3. determine result type
if( inputType.getDataType() == QT_MDD )
{
// check index type
if( indexType.getDataType() != QT_MINTERVAL
// && indexType.getDataType() != QT_INTERVAL
&& indexType.getDataType() != QT_POINT
&& !indexType.isInteger()
)
{
RMInit::logOut << "Error: QtDomainOperation::checkType() - spatial domain expressions must be either of type minterval, point, or integer." << endl;
parseInfo.setErrorNo(391);
throw parseInfo;
}
// MDD
if( indexType.getDataType() == QT_MINTERVAL /* || indexType.getDataType() == QT_INTERVAL */ )
// pass MDD type
dataStreamType = inputType;
else
// use MDD cell type
dataStreamType.setType( ((MDDBaseType*)inputType.getType())->getBaseType() );
}
else if( inputType.getDataType() == QT_MINTERVAL )
{
// check index type
if( !indexType.isInteger() && indexType.getDataType() != QT_POINT )
{
RMInit::logOut << "Error: QtDomainOperation::checkType() - Operand of minterval selection must be of type integer." << endl;
parseInfo.setErrorNo(397);
throw parseInfo;
}
dataStreamType.setDataType( QT_INTERVAL );
}
else if( inputType.getDataType() == QT_POINT )
{
// check index type
if( !indexType.isInteger() && indexType.getDataType() != QT_POINT )
{
RMInit::logOut << "Error: QtDomainOperation::checkType() - Operand of point selection must be of type integer." << endl;
parseInfo.setErrorNo(399);
throw parseInfo;
}
dataStreamType.setDataType( QT_ULONG );
}
else
{
RMInit::logOut << "Error: QtDomainOperation::checkType() - selection operation is not supported on this data type." << endl;
parseInfo.setErrorNo(396);
throw parseInfo;
}
}
else
RMInit::logOut << "Error: QtDomainOperation::checkType() - input or index branch invalid." << endl;
return dataStreamType;
}