/* * 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, QtMarrayOp2: $Header: /home/rasdev/CVS-repository/rasdaman/qlparser/qtmarrayop2.cc,v 1.17 2003/12/27 20:51:28 rasdev Exp $"; #include "raslib/rmdebug.hh" #include "qlparser/qtmarrayop2.hh" #include "qlparser/qtdata.hh" #include "qlparser/qtmdd.hh" #include "qlparser/qtpointdata.hh" #include "qlparser/qtmintervaldata.hh" #include "qlparser/qtmintervalop.hh" #include "mddmgr/mddobj.hh" #include "qlparser/querytree.hh" #include "catalogmgr/typefactory.hh" #include "relcatalogif/basetype.hh" #include "relcatalogif/longtype.hh" #include "catalogmgr/algebraops.hh" #include #ifndef CPPSTDLIB #include // STL #else #include using namespace std; #endif extern QueryTree* parseQueryTree; QtMarrayOp2::QtMarrayOp2( mddIntervalListType* & aList, QtOperation* & cellExp ) : iterators( *aList ), qtOperation( cellExp ) { } QtMarrayOp2::~QtMarrayOp2(){ } bool QtMarrayOp2::concatenateIntervals() { QtData* data=NULL; RMDBGENTER( 2, RMDebug::module_qlparser, "QtMarrayOp2", "Validity Check: " ) // check for validity bool eflag=true; mddIntervalListType::const_iterator ii; QtNode::QtOperationList::const_iterator j; QtNode::QtOperationList *ddd=NULL; QtOperation *op1=NULL; QtOperation *op2=NULL; for (ii = iterators.begin(); ii != iterators.end() ; ii++) { ddd = ((QtMintervalOp *)(ii->tree))->getInputs(); for (j = ddd->begin(); j != ddd->end(); j++) { if((QtNode *)*j) { if ((((QtNode *)*j)->getNodeType() == QtNode::QT_INTERVALOP)) { op1 = ((QtBinaryOperation *)*j)->getInput1(); if (((QtNode *)op1)->getNodeType() != QtNode::QT_CONST) eflag=false; op2 = ((QtBinaryOperation *)*j)->getInput2(); if (((QtNode *)op2)->getNodeType() != QtNode::QT_CONST) eflag=false; } else if (((QtNode *)*j)->getNodeType() != QtNode::QT_CONST) eflag=false; } } } RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtMarrayOp2", "Validity check completed." ) if (eflag) { RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtMarrayOp2", "eflag is true!" << endl ) // compute total dimension RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtMarrayOp2", endl << "QtMarrayOp2: Dimensions: " ) greatDimension=0; mddIntervalListType::const_iterator i; for (i = iterators.begin(); i != iterators.end() ; i++) { // evaluate intervals data = (i->tree)->evaluate(0); r_Dimension dimension = ((QtMintervalData*)data)->getMintervalData().dimension(); RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtMarrayOp2", dimension << " | " ); greatDimension += dimension; } RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtMarrayOp2", " Total " << greatDimension << endl ) // concatenate the data of the intervals into one big interval RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtMarrayOp2", "QtMarray2: Domains: " ) greatDomain = r_Minterval( greatDimension ); for (i = iterators.begin(); i != iterators.end() ; i++) { // evaluate intervals data = i->tree->evaluate(0); r_Minterval domain = ((QtMintervalData*)data)->getMintervalData(); r_Dimension dimension = domain.dimension(); r_Dimension jj; for (jj=0; jj != dimension; jj++) { r_Sinterval part = domain[jj]; greatDomain << part; } RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtMarrayOp2", domain << " | " ) } RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtMarrayOp2", " Total: " << greatDomain << endl ) // concatenate the identifier names to one big identifier name RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtMarrayOp2", "QtMarray2: Iterators: " ) greatIterator = string(""); string iname(""); for (i = iterators.begin(); i != iterators.end() ; i++) { // get iterator name iname = string(i->variable); greatIterator = greatIterator + string(" ") + string(i->variable); RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtMarrayOp2", i->variable << " | " ) } RMDBGEXIT( 2, RMDebug::module_qlparser, "QtMarrayOp2", " Total: " << greatIterator << endl ) } else RMDBGEXIT( 2, RMDebug::module_qlparser, "QtMarrayOp2", " eflag is false! " << greatIterator << endl ) return eflag; } void QtMarrayOp2::rewriteVars( ) { if (!oldMarray) { RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtMarrayOp2", "concatenateIteratorNames: " ) mddIntervalListType::const_iterator i; // concatenate the identifier names to one big identifier name RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtMarrayOp2", "QtMarray2: Iterators: " ) greatIterator = string(""); string iname(""); for (i = iterators.begin(); i != iterators.end() ; i++) { // get iterator name iname = string(i->variable); greatIterator = greatIterator + string(" ") + string(i->variable); RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtMarrayOp2", i->variable << " | " ) } RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtMarrayOp2", " Total: " << greatIterator << endl ) } traverse(qtOperation); } void QtMarrayOp2::traverse(QtOperation *&node) { if (node != 0) { QtOperation* temp = NULL; if (((QtNode *)node)->getNodeType() == QtNode::QT_DOMAIN_OPERATION) { // syntax: dinput [ dmiop ] // traverse dmiop QtOperation *dmiop = ((QtDomainOperation *)node)->getMintervalOp(); temp = (QtOperation*)dmiop; traverse(temp); dmiop = temp; ((QtDomainOperation *)node)->setMintervalOp(dmiop); // if dinput == QtVariable then rewrite it QtOperation *dinput = ((QtDomainOperation *)node)->getInput(); // if not a variable, then recurse if (((QtNode *)dinput)->getNodeType() != QtNode::QT_MDD_VAR) { // traverse dinput temp = (QtOperation *)dinput; traverse(temp); dinput = temp; ((QtDomainOperation *)node)->setInput(dinput); // get childs and traverse them QtNode::QtNodeList* childList = node->getChilds(QtNode::QT_DIRECT_CHILDS); for( QtNode::QtNodeList::iterator iter = childList->begin(); iter != childList->end(); iter++ ) { temp = (QtOperation*)*iter; traverse(temp); *iter = temp; }; delete childList; childList=NULL; }; } else { if (node->getNodeType() == QtNode::QT_MDD_VAR) { if (QueryTree::symtab.lookupSymbol(((QtVariable *)node)->getIteratorName())) { if (!oldMarray) { RMDBGMIDDLE( 2, RMDebug::module_qlparser, "QtMarrayOp2", endl << "marray2 var identifier:" << ((QtVariable *)node)->getIteratorName() << " replacing with " << greatIterator << endl ) ((QtVariable *)node)->setIteratorName(greatIterator); }; // replace with var[0] QtDomainOperation *dop = new QtDomainOperation( new QtConst (new QtAtomicData((r_Long)0, sizeof(r_Long))) /*new QtPointOp( lop )*/ ); dop->setInput( (QtVariable *)node ); node = dop; parseQueryTree->addDomainObject( dop ); }; } else { // traverse inputs switch (((QtNode *)node)->getNodeType()) { /* // with no input case QtNode::QT_UNDEFINED_NODE: case QtNode::QT_MDD_ACCESS: case QtNode::QT_OPERATION_ITERATOR: case QtNode::QT_SELECTION_ITERATOR: case QtNode::QT_JOIN_ITERATOR: case QtNode::QT_UPDATE: case QtNode::QT_INSERT: case QtNode::QT_DELETE: case QtNode::QT_COMMAND: case QtNode::QT_PYRAMID: case QtNode::QT_MDD_VAR: case QtNode::QT_UDFCALLOP: case QtNode::QT_CONST: case QtNode::QT_MDD_STREAM: */ // from Unary case QtNode::QT_TANH: case QtNode::QT_TAN: case QtNode::QT_SQRT: case QtNode::QT_SINH: case QtNode::QT_SIN: case QtNode::QT_NOT: case QtNode::QT_LOG: case QtNode::QT_LN: case QtNode::QT_EXP: case QtNode::QT_DOT: case QtNode::QT_COSH: case QtNode::QT_COS: case QtNode::QT_ARCTAN: case QtNode::QT_ARCSIN: case QtNode::QT_ARCCOS: case QtNode::QT_ABS: case QtNode::QT_REALPART: case QtNode::QT_IMAGINARPART: case QtNode::QT_CAST: case QtNode::QT_SDOM: case QtNode::QT_OID: case QtNode::QT_LO: case QtNode::QT_HI: // case QtNode::QT_DOMAIN_OPERATION: case QtNode::QT_CONVERSION: case QtNode::QT_SOME: case QtNode::QT_MINCELLS: case QtNode::QT_MAXCELLS: case QtNode::QT_COUNTCELLS: case QtNode::QT_AVGCELLS: case QtNode::QT_ALL: case QtNode::QT_ADDCELLS: case QtNode::QT_CSE_ROOT: { QtOperation *uinput = ((QtUnaryOperation *)node)->getInput(); temp = (QtOperation *)uinput; traverse(temp); uinput = temp; ((QtUnaryOperation *)node)->setInput(uinput); }; break; // from Binary case QtNode::QT_SHIFT: case QtNode::QT_SCALE: case QtNode::QT_MARRAYOP: case QtNode::QT_INTERVALOP: case QtNode::QT_CONDENSEOP: case QtNode::QT_XOR: case QtNode::QT_PLUS: case QtNode::QT_OR: case QtNode::QT_NOT_EQUAL: case QtNode::QT_MULT: case QtNode::QT_MINUS: case QtNode::QT_LESS_EQUAL: case QtNode::QT_LESS: case QtNode::QT_IS: case QtNode::QT_EQUAL: case QtNode::QT_DIV: case QtNode::QT_AND: case QtNode::QT_OVERLAY: case QtNode::QT_BIT: { QtOperation *binput1 = ((QtBinaryOperation *)node)->getInput1(); QtOperation *binput2 = ((QtBinaryOperation *)node)->getInput2(); QtOperation* temp1 = 0; QtOperation* temp2 = 0; temp1 = (QtOperation *)binput1; temp2 = (QtOperation *)binput2; traverse(temp1); traverse(temp2); binput1 = temp1; binput2 = temp2; ((QtBinaryOperation *)node)->setInput1(binput1); ((QtBinaryOperation *)node)->setInput2(binput2); }; break; // from Nary case QtNode::QT_POINTOP: case QtNode::QT_MINTERVALOP: { QtNode::QtOperationList *ninput = ((QtNaryOperation *)node)->getInputs(); for( QtNode::QtOperationList::iterator iter = ninput->begin(); iter != ninput->end(); iter++ ) { temp = (QtOperation *)*iter; traverse(temp); *iter = temp; }; ((QtNaryOperation *)node)->setInputs(ninput); }; break; default: { // do nothing }; break; }; // get childs and traverse them QtNode::QtNodeList* childList = node->getChilds(QtNode::QT_DIRECT_CHILDS); for( QtNode::QtNodeList::iterator iter = childList->begin(); iter != childList->end(); iter++ ) { temp = (QtOperation*)*iter; traverse(temp); *iter = temp; }; delete childList; childList=NULL; }; }; }; }