summaryrefslogtreecommitdiffstats
path: root/qlparser/qtselectioniterator.cc
diff options
context:
space:
mode:
Diffstat (limited to 'qlparser/qtselectioniterator.cc')
-rw-r--r--qlparser/qtselectioniterator.cc281
1 files changed, 281 insertions, 0 deletions
diff --git a/qlparser/qtselectioniterator.cc b/qlparser/qtselectioniterator.cc
new file mode 100644
index 0000000..f6d2529
--- /dev/null
+++ b/qlparser/qtselectioniterator.cc
@@ -0,0 +1,281 @@
+/*
+* 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 <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/*************************************************************
+ *
+ *
+ * PURPOSE:
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+static const char rcsid[] = "@(#)qlparser, QtSelectionIterator: $Id: qtselectioniterator.cc,v 1.24 2001/08/07 12:00:12 barbat Exp $";
+
+#include "raslib/rmdebug.hh"
+
+#include "qlparser/qtselectioniterator.hh"
+#include "qlparser/qtatomicdata.hh"
+
+#include "relcatalogif/type.hh"
+
+#include <iostream>
+#include <string>
+#include <vector>
+using namespace std;
+
+const QtNode::QtNodeType QtSelectionIterator::nodeType = QtNode::QT_SELECTION_ITERATOR;
+
+
+QtSelectionIterator::QtSelectionIterator()
+ : QtIterator(),
+ conditionTree(NULL)
+{
+}
+
+
+QtSelectionIterator::QtSelectionIterator( QtNode* node )
+ : QtIterator( node ),
+ conditionTree(NULL)
+{
+}
+
+
+QtSelectionIterator::~QtSelectionIterator()
+{
+ if( conditionTree )
+ {
+ delete conditionTree;
+ conditionTree=NULL;
+ }
+}
+
+
+QtNode::QtNodeList*
+QtSelectionIterator::getChilds( QtChildType flag )
+{
+ QtNodeList* resultList=NULL;
+ QtNodeList* subList=NULL;
+
+ RMDBGENTER( 1, RMDebug::module_qlparser, "QtSelectionIterator", " QtSelectionIterator::getChilds() ")
+
+ resultList = QtIterator::getChilds( flag );
+
+ RMDBGIF( 4, RMDebug::module_qlparser, "QtSelectionIterator", \
+ RMInit::dbgOut << "1. childs from stream subtree " << endl; \
+ list<QtNode*>::iterator debugIter; \
+ for( debugIter=resultList->begin(); debugIter!=resultList->end(); debugIter++ ) \
+ (*debugIter)->printTree( 2, RMInit::dbgOut, QtNode::QT_DIRECT_CHILDS ); \
+ )
+
+ if( conditionTree )
+ {
+ if( flag == QT_LEAF_NODES || flag == QT_ALL_NODES )
+ {
+ subList = conditionTree->getChilds( flag );
+
+ RMDBGIF( 4, RMDebug::module_qlparser, "QtSelectionIterator", \
+ RMInit::dbgOut << "2. childs from operation subtree (without direct childs) " << endl; \
+ list<QtNode*>::iterator debugIter; \
+ for( debugIter=subList->begin(); debugIter!=subList->end(); debugIter++ ) \
+ (*debugIter)->printTree( 2, RMInit::dbgOut, QtNode::QT_DIRECT_CHILDS ); \
+ )
+
+ // remove all elements in subList and insert them at the beginning in resultList
+ resultList->splice( resultList->begin(), *subList );
+
+ RMDBGIF( 4, RMDebug::module_qlparser, "QtSelectionIterator", \
+ RMInit::dbgOut << "3. merge of the lists " << endl; \
+ list<QtNode*>::iterator debugIter; \
+ for( debugIter=resultList->begin(); debugIter!=resultList->end(); debugIter++ ) \
+ (*debugIter)->printTree( 2, RMInit::dbgOut, QtNode::QT_DIRECT_CHILDS ); \
+ )
+
+
+ RMDBGIF( 4, RMDebug::module_qlparser, "QtSelectionIterator", \
+ RMInit::dbgOut << "4. old list (must be empty)" << endl; \
+ list<QtNode*>::iterator debugIter; \
+ for( debugIter=subList->begin(); debugIter!=subList->end(); debugIter++ ) \
+ (*debugIter)->printTree( 2, RMInit::dbgOut, QtNode::QT_DIRECT_CHILDS ); \
+ )
+
+ // delete temporary subList
+ delete subList;
+ subList=NULL;
+ };
+
+ // add nodes of next level
+ if( flag == QT_DIRECT_CHILDS || flag == QT_ALL_NODES )
+ resultList->push_back( conditionTree );
+
+ RMDBGIF( 4, RMDebug::module_qlparser, "QtSelectionIterator",
+ RMInit::dbgOut << "4. current child list including direct childs " << endl; \
+ list<QtNode*>::iterator debugIter; \
+ for( debugIter=resultList->begin(); debugIter!=resultList->end(); debugIter++ ) \
+ (*debugIter)->printTree( 2, RMInit::dbgOut, QtNode::QT_DIRECT_CHILDS ); \
+ )
+
+ };
+
+ return resultList;
+}
+
+
+void
+QtSelectionIterator::printTree( int tab, ostream& s, QtChildType mode )
+{
+ s << SPACE_STR(tab).c_str() << "QtSelectionIterator Object: type " << flush;
+ dataStreamType.printStatus( s );
+ s << endl;
+
+ if( mode != QtNode::QT_DIRECT_CHILDS )
+ {
+ if( conditionTree )
+ {
+ s << SPACE_STR(tab).c_str() << "condition : " << endl;
+ conditionTree->printTree( tab + 2, s );
+ }
+ else
+ s << SPACE_STR(tab).c_str() << "no condition" << endl;
+ }
+
+ QtIterator::printTree( tab, s, mode );
+}
+
+
+
+void
+QtSelectionIterator::printAlgebraicExpression( ostream& s )
+{
+ s << "sel<";
+
+ conditionTree->printAlgebraicExpression( s );
+
+ s << ">";
+
+ QtIterator::printAlgebraicExpression( s );
+}
+
+
+
+QtNode::QtDataList*
+QtSelectionIterator::next()
+{
+ RMDBGENTER( 1, RMDebug::module_qlparser, "QtSelectionIterator", "QtSelectionIterator::next()" )
+
+ QtDataList* returnValue = NULL;
+
+ if( inputs )
+ {
+ bool nextTupelValid = false;
+ QtDataList* actualTupel=NULL;
+
+ while( !nextTupelValid )
+ {
+ actualTupel = (*inputs)[0]->next();
+
+ if( actualTupel )
+ {
+ if( conditionTree )
+ {
+ // evaluate the condition tree
+ QtData* resultData = conditionTree->evaluate( actualTupel );
+
+ if( resultData )
+ {
+ if( resultData->getDataType() == QT_BOOL )
+ nextTupelValid = (bool)((QtAtomicData*)resultData)->getUnsignedValue();
+ else
+ {
+ RMInit::logOut << "Error: QtSelectionIterator::next() - result of the WHERE part must be of type Bool." << endl;
+ parseInfo.setErrorNo(359);
+ throw parseInfo;
+ }
+
+ resultData->deleteRef();
+
+ if( !nextTupelValid )
+ {
+ // delete transient objects
+ vector<QtData*>::iterator iter;
+
+ for( iter=actualTupel->begin(); iter!=actualTupel->end(); iter++)
+ if( *iter ) (*iter)->deleteRef();
+
+ // delete vector itself
+ delete actualTupel;
+ actualTupel = NULL;
+ };
+ }
+ }
+ else
+ nextTupelValid = true;
+ }
+ else
+ break;
+ }
+
+ returnValue = actualTupel;
+ }
+
+ RMDBGEXIT( 1, RMDebug::module_qlparser, "QtSelectionIterator", "QtSelectionIterator::next()" )
+
+ return returnValue;
+}
+
+/*
+inline void
+QtSelectionIterator::preOptimize()
+{
+ if( conditionTree )
+ conditionTree->optimizeLoad( new QtNode::QtTrimList );
+
+ // pass it to the input streams
+ QtIterator::preOptimize();
+};
+*/
+
+const QtTypeTuple&
+QtSelectionIterator::checkType()
+{
+ RMDBCLASS( "QtSelectionIterator", "checkType()", "qlparser", __FILE__, __LINE__ )
+
+ // concatenate types of inputs
+ getInputTypeTuple( dataStreamType );
+
+ // type check for condition tree
+ if( conditionTree )
+ {
+ const QtTypeElement& type = conditionTree->checkType( (QtTypeTuple*)&dataStreamType );
+
+ if( type.getDataType() != QT_BOOL )
+ {
+ RMInit::logOut << "Error: QtSelectionIterator::next() - result of the WHERE part must be of type Bool." << endl;
+ parseInfo.setErrorNo(359);
+ throw parseInfo;
+ }
+ }
+
+ // pass type tuple
+ return dataStreamType;
+}