/* ---- This file is part of SECONDO. Copyright (C) 2015, Faculty of Mathematics and Computer Science, Database Systems for New Applications. SECONDO 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 2 of the License, or (at your option) any later version. SECONDO 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 SECONDO; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ---- //[$][\$] 1 Implementation of the secondo operators drelfilter, project, drelprojectextend, drellsortby, drellgroupby, lsort, lrdup, lrename, head and drelextend This operators have the same value mapping witch calls the dmap operator of the Distributed2Algebra. */ //#define DRELDEBUG #include "NestedList.h" #include "ListUtils.h" #include "QueryProcessor.h" #include "StandardTypes.h" #include "SecParser.h" #include "Stream.h" #include "Algebras/Relation-C++/OperatorProject.h" #include "Algebras/Relation-C++/OperatorFilter.h" #include "Algebras/Rectangle/RectangleAlgebra.h" #include "Algebras/Distributed2/CommandLogger.h" #include "Algebras/Distributed2/Distributed2Algebra.h" #include "Algebras/FText/FTextAlgebra.h" #include "DRelHelpers.h" #include "DRel.h" #include "drelport.h" extern NestedList* nl; extern QueryProcessor* qp; ListExpr RenameTypeMap( ListExpr args ); template ListExpr IndexQueryTypeMap( ListExpr args ); namespace distributed2 { extern Distributed2Algebra* algInstance; ListExpr dmapTM( ListExpr args ); template ListExpr dmapXTMT( ListExpr args ); template int dmapVMT( Word* args, Word& result, int message, Word& local, Supplier s ); int dmapXVM(Word* args, Word& result, int message, Word& local, Supplier s ); template int shareVMT(Word* args, Word& result, int message, Word& local, Supplier s ); } namespace extrelationalg { ListExpr ExtendTypeMap( ListExpr args ); ListExpr ExtProjectExtendTypeMap( ListExpr args ); ListExpr SortByTypeMap( ListExpr args ); ListExpr GroupByTypeMap( ListExpr args ); } using namespace distributed2; namespace drel { /* 1.1 Type Mappings for all operators using dmapVM 1.1.1 Type Mapping ~drelfilterTM~ Expect a d[f]rel with a function to filter the tuples. Type mapping for the drelfilter operator. */ ListExpr drelfilterTM( ListExpr args ) { #ifdef DRELDEBUG cout << "drelfilterTM" << endl; cout << "args" << endl; cout << nl->ToString( args ) << endl; #endif std::string err = "d[f]rel(X) x fun expected"; if( !nl->HasLength( args, 2 ) ) { return listutils::typeError( err + ": two arguments are expected" ); } if( !DRelHelpers::isListOfTwoElemLists( args ) ) { return listutils::typeError( "internal Error" ); } ListExpr drelType, relType, distType, drelValue, darrayType; if( !DRelHelpers::isDRelDescr( nl->First( args ), drelType, relType, distType, drelValue, darrayType ) ) { return listutils::typeError( err + ": first argument is not a d[f]rel" ); } ListExpr fun, map; if( !DRelHelpers::replaceDRELFUNARG( nl->Second( args ), "STREAMELEM", fun, map ) ) { return listutils::typeError( err + ": error in the function format" ); } ListExpr result = OperatorFilter::FilterTypeMap( nl->TwoElemList( nl->TwoElemList( nl->TwoElemList( listutils::basicSymbol >( ), nl->Second( relType ) ), nl->TwoElemList( nl->SymbolAtom( "feed" ), drelValue ) ), // only dummy for the filter TM nl->TwoElemList( map, fun ) ) ); #ifdef DRELDEBUG cout << "filter tm" << endl; cout << nl->ToString( result ) << endl; #endif // filter TM ok? if( !listutils::isTupleStream( result ) ) { return result; } // create string to call dmap the call is devided in two parts // the argument for the drel is missing and will be filled in the // value mapping std::string funText1 = "(dmap "; std::string funText2 = "\"\" (fun (dmapelem_1 ARRAYFUNARG1) " "(filter (feed dmapelem_1)" + nl->ToString( fun ) + ") ) )"; #ifdef DRELDEBUG cout << "funText1" << endl; cout << funText1 << endl; cout << "funText2" << endl; cout << funText2 << endl; #endif ListExpr resultType = nl->ThreeElemList( listutils::basicSymbol( ), relType, nl->Third( drelType ) ); // disttype ListExpr append = nl->TwoElemList( nl->TextAtom( funText1 ), nl->TextAtom( funText2 ) ); return nl->ThreeElemList( nl->SymbolAtom( Symbols::APPEND( ) ), append, resultType ); } /* 1.1.2 Type Mapping ~projectTM~ Expect a d[f]rel an attribute list. Type mapping for the project operator. */ ListExpr projectTM( ListExpr args ) { #ifdef DRELDEBUG cout << "projectTM" << endl; cout << "args" << endl; cout << nl->ToString( args ) << endl; #endif std::string err = "d[f]rel(X) x attrlist expected"; if( !nl->HasLength( args, 2 ) ) { return listutils::typeError( err + ": two arguments are expected" ); } if( !DRelHelpers::isListOfTwoElemLists( args ) ) { return listutils::typeError( "internal Error" ); } ListExpr drelType, relType, distType, drelValue, darrayType; if( !DRelHelpers::isDRelDescr( nl->First( args ), drelType, relType, distType, drelValue, darrayType ) ) { return listutils::typeError( err + ": first argument is not a d[f]rel" ); } ListExpr attrlist = nl->First( nl->Second( args ) ); ListExpr result = OperatorProject::ProjectTypeMap( nl->TwoElemList( nl->TwoElemList( listutils::basicSymbol >( ), nl->Second( relType ) ), attrlist ) ); #ifdef DRELDEBUG cout << "project tm" << endl; cout << nl->ToString( result ) << endl; #endif // project TM ok? if( !nl->HasLength( result, 3 ) ) { return result; } if( !listutils::isTupleStream( nl->Third( result ) ) ) { return result; } relType = nl->TwoElemList( listutils::basicSymbol( ), nl->Second( nl->Third( result ) ) ); #ifdef DRELDEBUG cout << "distType with attr pos to check" << endl; cout << nl->ToString( distType ) << endl; #endif // distribution by an attribute? if( nl->HasMinLength( distType, 2 ) ) { int newPos = nl->IntValue( nl->Second( distType ) ) + 1; #ifdef DRELDEBUG cout << "distribution by attribute check for new position" << endl; cout << "newPos" << endl; cout << newPos << endl; #endif if( DistTypeHash::computeNewAttrPos( nl->Second( nl->Second( result ) ), newPos ) ) { switch( nl->ListLength( distType ) ) { case 3: distType = nl->ThreeElemList( nl->First( distType ), nl->IntAtom( newPos ), nl->Third( distType ) ); break; case 4: distType = nl->FourElemList( nl->First( distType ), nl->IntAtom( newPos ), nl->Third( distType ), nl->Fourth( distType ) ); break; default: distType = nl->TwoElemList( nl->First( distType ), nl->IntAtom( newPos ) ); } #ifdef DRELDEBUG cout << "new distType" << endl; cout << nl->ToString( distType ) << endl; #endif } else { return listutils::typeError( err + ": it is not allowed to project without the " "distribution attribute" ); } } // create string to call dmap the call is devided in two parts // the argument for the drel is missing and will be filled in the // value mapping std::string funText1 = "(dmap "; std::string funText2 = "\"\" (fun (dmapelem_1 ARRAYFUNARG1) " "(project (feed dmapelem_1)" + nl->ToString( attrlist ) + ") ) )"; #ifdef DRELDEBUG cout << "funText1" << endl; cout << funText1 << endl; cout << "funText2" << endl; cout << funText2 << endl; #endif ListExpr resultType = nl->ThreeElemList( listutils::basicSymbol( ), relType, distType ); ListExpr append = nl->TwoElemList( nl->TextAtom( funText1 ), nl->TextAtom( funText2 ) ); return nl->ThreeElemList( nl->SymbolAtom( Symbols::APPEND( ) ), append, resultType ); } /* 1.1.3 Type Mapping ~drelprojectextendTM~ Expect a d[f]rel with an attribute list and a function list to extend the tuples. This is a combination of the operators project and extend. */ ListExpr drelprojectextendTM( ListExpr args ) { #ifdef DRELDEBUG cout << "drelprojectextendTM" << endl; cout << "args" << endl; cout << nl->ToString( args ) << endl; #endif std::string err = "d[f]rel(X) x attrlist x funlist expected"; if( !nl->HasLength( args, 3 ) ) { return listutils::typeError( err + ": three arguments are expected" ); } if( !DRelHelpers::isListOfTwoElemLists( args ) ) { return listutils::typeError( "internal Error" ); } ListExpr drelType, relType, distType, drelValue, darrayType; if( !DRelHelpers::isDRelDescr( nl->First( args ), drelType, relType, distType, drelValue, darrayType ) ) { return listutils::typeError( err + ": first argument is not a d[f]rel" ); } ListExpr attrlist = nl->First( nl->Second( args ) ); if( !nl->HasMinLength( nl->First( nl->Third( args ) ), 1 ) || !nl->HasMinLength( nl->Second( nl->Third( args ) ), 1 ) ) { return listutils::typeError( err + ": error in the function format" ); } ListExpr map = nl->First( nl->Third( args ) ); ListExpr tempfun; ListExpr fun = nl->TheEmptyList( ); ListExpr temp = nl->Second( nl->Third( args ) ); while( !nl->IsEmpty( temp ) ) { if( !nl->HasLength( nl->First( temp ), 2 ) ) { return listutils::typeError( "internal Error" ); } if( !DRelHelpers::replaceDRELFUNARG( nl->Second( nl->First( temp ) ), "TUPLE", tempfun ) ) { return listutils::typeError( err + ": error in the function format" ); } if( nl->IsEmpty( fun ) ) { fun = nl->OneElemList( nl->TwoElemList( nl->First( nl->First( temp ) ), tempfun ) ); } else { fun = listutils::concat( fun, nl->OneElemList( nl->TwoElemList( nl->First( nl->First( temp ) ), tempfun ) ) ); } temp = nl->Rest( temp ); } ListExpr result = extrelationalg::ExtProjectExtendTypeMap( nl->ThreeElemList( nl->TwoElemList( listutils::basicSymbol >( ), nl->Second( relType ) ), attrlist, map ) ); #ifdef DRELDEBUG cout << "projectextend tm" << endl; cout << nl->ToString( result ) << endl; #endif // filter TM ok? if( !nl->HasLength( result, 3 ) ) { return result; } if( !listutils::isTupleStream( nl->Third( result ) ) ) { return result; } relType = nl->TwoElemList( listutils::basicSymbol( ), nl->Second( nl->Third( result ) ) ); // distribution by an attribute? if( nl->HasMinLength( distType, 2 ) ) { int newPos = nl->IntValue( nl->Second( distType ) ) + 1; #ifdef DRELDEBUG cout << "distribution by attribute check for new position" << endl; cout << "newPos" << endl; cout << newPos << endl; #endif if( DistTypeHash::computeNewAttrPos( nl->Second( nl->Second( result ) ), newPos ) ) { switch( nl->ListLength( distType ) ) { case 3: distType = nl->ThreeElemList( nl->First( distType ), nl->IntAtom( newPos ), nl->Third( distType ) ); break; case 4: distType = nl->FourElemList( nl->First( distType ), nl->IntAtom( newPos ), nl->Third( distType ), nl->Fourth( distType ) ); break; default: distType = nl->TwoElemList( nl->First( distType ), nl->IntAtom( newPos ) ); } drelType = nl->ThreeElemList( nl->First( drelType ), distType, nl->Third( drelType ) ); #ifdef DRELDEBUG cout << "new drelType" << endl; cout << nl->ToString( drelType ) << endl; #endif } else { return listutils::typeError( err + ": it is not allowed to project without the " "distribution attribute" ); } } // create string to call dmap the call is devided in two parts // the argument for the drel is missing and will be filled in the // value mapping std::string funText1 = "(dmap "; std::string funText2 = "\"\" (fun (dmapelem_1 ARRAYFUNARG1) " "(projectextend (feed dmapelem_1)" + nl->ToString( attrlist ) + nl->ToString( fun ) + ") ) )"; #ifdef DRELDEBUG cout << "funText1" << endl; cout << funText1 << endl; cout << "funText2" << endl; cout << funText2 << endl; #endif ListExpr resultType = nl->ThreeElemList( listutils::basicSymbol( ), relType, distType ); ListExpr append = nl->TwoElemList( nl->TextAtom( funText1 ), nl->TextAtom( funText2 ) ); return nl->ThreeElemList( nl->SymbolAtom( Symbols::APPEND( ) ), append, resultType ); } /* 1.1.4 Type Mapping ~drelextendTM~ Expect a d[f]rel with a function list to extend the tuples. This is a combination of the operator extend. */ ListExpr drelextendTM( ListExpr args ) { #ifdef DRELDEBUG cout << "drelextendTM" << endl; cout << "args" << endl; cout << nl->ToString( args ) << endl; #endif std::string err = "d[f]rel(X) x funlist expected"; if( !nl->HasLength( args, 2 ) ) { return listutils::typeError( err + ": three arguments are expected" ); } if( !DRelHelpers::isListOfTwoElemLists( args ) ) { return listutils::typeError( "internal Error" ); } ListExpr drelType, relType, distType, drelValue, darrayType; if( !DRelHelpers::isDRelDescr( nl->First( args ), drelType, relType, distType, drelValue, darrayType ) ) { return listutils::typeError( err + ": first argument is not a d[f]rel" ); } if( !nl->HasMinLength( nl->First( nl->Second( args ) ), 1 ) || !nl->HasMinLength( nl->Second( nl->Second( args ) ), 1 ) ) { return listutils::typeError( err + ": error in the function format" ); } ListExpr map = nl->First( nl->Second( args ) ); ListExpr tempfun; ListExpr fun = nl->TheEmptyList( ); ListExpr temp = nl->Second( nl->Second( args ) ); while( !nl->IsEmpty( temp ) ) { if( !nl->HasLength( nl->First( temp ), 2 ) ) { return listutils::typeError( "internal Error" ); } if( !DRelHelpers::replaceDRELFUNARG( nl->Second( nl->First( temp ) ), "TUPLE", tempfun ) ) { return listutils::typeError( err + ": error in the function format" ); } if( nl->IsEmpty( fun ) ) { fun = nl->OneElemList( nl->TwoElemList( nl->First( nl->First( temp ) ), tempfun ) ); } else { fun = listutils::concat( fun, nl->OneElemList( nl->TwoElemList( nl->First( nl->First( temp ) ), tempfun ) ) ); } temp = nl->Rest( temp ); } ListExpr result = extrelationalg::ExtendTypeMap( nl->TwoElemList( nl->TwoElemList( listutils::basicSymbol >( ), nl->Second( relType ) ), map ) ); #ifdef DRELDEBUG cout << "extend tm" << endl; cout << nl->ToString( result ) << endl; #endif // filter TM ok? if( !nl->HasLength( result, 2 ) ) { return result; } if( !listutils::isTupleStream( result ) ) { return result; } relType = nl->TwoElemList( listutils::basicSymbol( ), nl->Second( result ) ); // create string to call dmap the call is devided in two parts // the argument for the drel is missing and will be filled in the // value mapping std::string funText1 = "(dmap "; std::string funText2 = "\"\" (fun (dmapelem_1 ARRAYFUNARG1) " "(extend (feed dmapelem_1)" + nl->ToString( fun ) + ") ) )"; #ifdef DRELDEBUG cout << "funText1" << endl; cout << funText1 << endl; cout << "funText2" << endl; cout << funText2 << endl; #endif ListExpr resultType = nl->ThreeElemList( listutils::basicSymbol( ), relType, distType ); ListExpr append = nl->TwoElemList( nl->TextAtom( funText1 ), nl->TextAtom( funText2 ) ); return nl->ThreeElemList( nl->SymbolAtom( Symbols::APPEND( ) ), append, resultType ); } /* 1.1.5 Type Mapping ~headTM~ Expect a d[f]rel and an int value. Type mapping for the head operator. */ ListExpr headTM( ListExpr args ) { #ifdef DRELDEBUG cout << "headTM" << endl; cout << "args" << endl; cout << nl->ToString( args ) << endl; #endif std::string err = "d[f]rel(X) x int expected"; if( !nl->HasLength( args, 2 ) ) { return listutils::typeError( err + ": two arguments are expected" ); } if( !DRelHelpers::isListOfTwoElemLists( args ) ) { return listutils::typeError( "internal Error" ); } ListExpr drelType, relType, distType, drelValue, darrayType; if( !DRelHelpers::isDRelDescr( nl->First( args ), drelType, relType, distType, drelValue, darrayType ) ) { return listutils::typeError( err + ": first argument is not a d[f]rel" ); } ListExpr secondType = nl->First( nl->Second( args ) ); ListExpr secondValue = nl->Second( nl->Second( args ) ); if( !CcInt::checkType( secondType ) ) { return listutils::typeError( err + ": second argument is not an integer" ); } // create string to call dmap the call is devided in two parts // the argument for the drel is missing and will be filled in the // value mapping std::string funText1 = "(dmap "; std::string funText2 = "\"\" (fun (dmapelem_1 ARRAYFUNARG1) " "(head (feed dmapelem_1)" + nl->ToString( secondValue ) + ") ) )"; #ifdef DRELDEBUG cout << "funText1" << endl; cout << funText1 << endl; cout << "funText2" << endl; cout << funText2 << endl; #endif ListExpr resultType = nl->ThreeElemList( listutils::basicSymbol( ), relType, distType ); ListExpr append = nl->TwoElemList( nl->TextAtom( funText1 ), nl->TextAtom( funText2 ) ); return nl->ThreeElemList( nl->SymbolAtom( Symbols::APPEND( ) ), append, resultType ); } /* 1.1.6 Type Mapping ~renameTM~ Expect a d[f]rel and a symbol. Type mapping for the rename operator. */ ListExpr renameTM( ListExpr args ) { #ifdef DRELDEBUG cout << "renameTM" << endl; cout << "args" << endl; cout << nl->ToString( args ) << endl; #endif std::string err = "d[f]rel(X) x ar expected"; if( !nl->HasLength( args, 2 ) ) { return listutils::typeError( err + ": two arguments are expected" ); } if( !DRelHelpers::isListOfTwoElemLists( args ) ) { return listutils::typeError( "internal Error" ); } ListExpr drelType, relType, distType, drelValue, darrayType; if( !DRelHelpers::isDRelDescr( nl->First( args ), drelType, relType, distType, drelValue, darrayType ) ) { return listutils::typeError( err + ": first argument is not a d[f]rel" ); } distributionType dType; DRelHelpers::drelCheck( nl->First( nl->First( args ) ), dType ); if( dType == replicated || dType == spatial2d || dType == spatial3d ) { return listutils::typeError( err + ": replicated or spatial distributed d[f]rel is not allowed" ); } ListExpr secondType = nl->First( nl->Second( args ) ); ListExpr secondValue = nl->Second( nl->Second( args ) ); ListExpr result = RenameTypeMap( nl->TwoElemList( nl->TwoElemList( listutils::basicSymbol >( ), nl->Second( relType ) ), secondType ) ); // project TM ok? if( !nl->HasLength( result, 2 ) ) { return result; } if( !listutils::isTupleStream( result ) ) { return result; } relType = nl->TwoElemList( listutils::basicSymbol( ), nl->Second( result ) ); // create string to call dmap the call is devided in two parts // the argument for the drel is missing and will be filled in the // value mapping std::string funText1 = "(dmap "; std::string funText2 = "\"\" (fun (dmapelem_1 ARRAYFUNARG1) " "(rename (feed dmapelem_1)" + nl->ToString( secondValue ) + ") ) )"; #ifdef DRELDEBUG cout << "funText1" << endl; cout << funText1 << endl; cout << "funText2" << endl; cout << funText2 << endl; #endif ListExpr resultType = nl->ThreeElemList( listutils::basicSymbol( ), relType, distType ); ListExpr append = nl->TwoElemList( nl->TextAtom( funText1 ), nl->TextAtom( funText2 ) ); return nl->ThreeElemList( nl->SymbolAtom( Symbols::APPEND( ) ), append, resultType ); } /* 1.1.7 Type Mapping ~lrdupTM~ Expect a d[f]rel and a symbol. Type mapping for the lrdup operator. */ ListExpr lrdupTM( ListExpr args ) { #ifdef DRELDEBUG cout << "lrdupTM" << endl; cout << "args" << endl; cout << nl->ToString( args ) << endl; #endif std::string err = "d[f]rel(X) expected"; if( !nl->HasLength( args, 1 ) ) { return listutils::typeError( err + ": two arguments are expected" ); } if( !DRelHelpers::isListOfTwoElemLists( args ) ) { return listutils::typeError( "internal Error" ); } ListExpr drelType, relType, distType, drelValue, darrayType; if( !DRelHelpers::isDRelDescr( nl->First( args ), drelType, relType, distType, drelValue, darrayType ) ) { return listutils::typeError( err + ": first argument is not a d[f]rel" ); } // create string to call dmap the call is devided in two parts // the argument for the drel is missing and will be filled in the // value mapping std::string funText1 = "(dmap "; std::string funText2 = "\"\" (fun (dmapelem_1 ARRAYFUNARG1) " "(rdup (sort (feed dmapelem_1) ) ) ) )"; #ifdef DRELDEBUG cout << "funText1" << endl; cout << funText1 << endl; cout << "funText2" << endl; cout << funText2 << endl; #endif ListExpr resultType = nl->ThreeElemList( listutils::basicSymbol( ), relType, distType ); ListExpr append = nl->TwoElemList( nl->TextAtom( funText1 ), nl->TextAtom( funText2 ) ); return nl->ThreeElemList( nl->SymbolAtom( Symbols::APPEND( ) ), append, resultType ); } /* 1.1.8 Type Mapping ~lsortTM~ Expect a d[f]rel and a symbol. Type mapping for the lsort operator. */ ListExpr lsortTM( ListExpr args ) { #ifdef DRELDEBUG cout << "lsortTM" << endl; cout << "args" << endl; cout << nl->ToString( args ) << endl; #endif std::string err = "d[f]rel(X) expected"; if( !nl->HasLength( args, 1 ) ) { return listutils::typeError( err + ": two arguments are expected" ); } if( !DRelHelpers::isListOfTwoElemLists( args ) ) { return listutils::typeError( "internal Error" ); } ListExpr drelType, relType, distType, drelValue, darrayType; if( !DRelHelpers::isDRelDescr( nl->First( args ), drelType, relType, distType, drelValue, darrayType ) ) { return listutils::typeError( err + ": first argument is not a d[f]rel" ); } // create string to call dmap the call is devided in two parts // the argument for the drel is missing and will be filled in the // value mapping std::string funText1 = "(dmap "; std::string funText2 = "\"\" (fun (dmapelem_1 ARRAYFUNARG1) " "(sort (feed dmapelem_1) ) ) )"; #ifdef DRELDEBUG cout << "funText1" << endl; cout << funText1 << endl; cout << "funText2" << endl; cout << funText2 << endl; #endif ListExpr resultType = nl->ThreeElemList( listutils::basicSymbol( ), relType, distType ); ListExpr append = nl->TwoElemList( nl->TextAtom( funText1 ), nl->TextAtom( funText2 ) ); return nl->ThreeElemList( nl->SymbolAtom( Symbols::APPEND( ) ), append, resultType ); } /* 1.1.9 Type Mapping ~drellgroupbyTM~ Expect a d[f]rel, an attribute list to group the tuple and a function list. Type mapping for the drellgroup operator. */ template ListExpr drellgroupbyTM( ListExpr args ) { #ifdef DRELDEBUG cout << "drellgroupbyTM" << endl; cout << "args" << endl; cout << nl->ToString( args ) << endl; #endif std::string err = "d[f]rel(X) x attrlist x funlist expected"; if( !nl->HasLength( args, 3 ) ) { return listutils::typeError( err + ": three arguments are expected" ); } if( !DRelHelpers::isListOfTwoElemLists( args ) ) { return listutils::typeError( "internal Error" ); } ListExpr drelType, relType, distType, drelValue, darrayType; if( !DRelHelpers::isDRelDescr( nl->First( args ), drelType, relType, distType, drelValue, darrayType ) ) { return listutils::typeError( err + ": first argument is not a d[f]rel" ); } distributionType dType; DRelHelpers::drelCheck( nl->First( nl->First( args ) ), dType ); if( !global && ( dType == replicated || dType == spatial2d || dType == spatial3d ) ) { return listutils::typeError( err + ": replicated or spatial distributed d[f]rel is not allowed" ); } ListExpr attrlist = nl->First( nl->Second( args ) ); if( !nl->HasMinLength( nl->First( nl->Third( args ) ), 1 ) || !nl->HasMinLength( nl->Second( nl->Third( args ) ), 1 ) ) { return listutils::typeError( err + ": error in the function format" ); } ListExpr map = nl->First( nl->Third( args ) ); ListExpr tempfun; ListExpr fun = nl->TheEmptyList( ); ListExpr temp = nl->Second( nl->Third( args ) ); while( !nl->IsEmpty( temp ) ) { if( !nl->HasLength( nl->First( temp ), 2 ) ) { return listutils::typeError( "internal Error" ); } if( !DRelHelpers::replaceDRELFUNARG( nl->Second( nl->First( temp ) ), "GROUP", tempfun ) ) { return listutils::typeError( err + ": error in the function format" ); } if( nl->IsEmpty( fun ) ) { fun = nl->OneElemList( nl->TwoElemList( nl->First( nl->First( temp ) ), tempfun ) ); } else { fun = listutils::concat( fun, nl->OneElemList( nl->TwoElemList( nl->First( nl->First( temp ) ), tempfun ) ) ); } temp = nl->Rest( temp ); } ListExpr result = extrelationalg::GroupByTypeMap( nl->ThreeElemList( nl->TwoElemList( listutils::basicSymbol >( ), nl->Second( relType ) ), attrlist, map ) ); #ifdef DRELDEBUG cout << "groupby tm" << endl; cout << nl->ToString( result ) << endl; #endif // groupby TM ok? if( !nl->HasLength( result, 3 ) ) { return result; } if( !listutils::isTupleStream( nl->Third( result ) ) ) { return result; } relType = nl->TwoElemList( listutils::basicSymbol( ), nl->Second( nl->Third( result ) ) ); // distribution by an attribute? if( nl->HasMinLength( distType, 2 ) ) { int newPos = nl->IntValue( nl->Second( distType ) ) + 1; #ifdef DRELDEBUG cout << "distribution by attribute check for new position" << endl; cout << "newPos" << endl; cout << newPos << endl; #endif if( nl->HasMinLength( nl->Second( result ), 2 ) && DistTypeHash::computeNewAttrPos( nl->Rest( nl->Second( result ) ), newPos ) ) { switch( nl->ListLength( distType ) ) { case 3: distType = nl->ThreeElemList( nl->First( distType ), nl->IntAtom( newPos ), nl->Third( distType ) ); break; case 4: distType = nl->FourElemList( nl->First( distType ), nl->IntAtom( newPos ), nl->Third( distType ), nl->Fourth( distType ) ); break; default: distType = nl->TwoElemList( nl->First( distType ), nl->IntAtom( newPos ) ); } #ifdef DRELDEBUG cout << "new drelType" << endl; cout << nl->ToString( drelType ) << endl; #endif } else { if( !global ) { return listutils::typeError( err + ": it is not allowed to create a group without the " "distribution attribute" ); } } } // create string to call dmap the call is devided in two parts // the argument for the drel is missing and will be filled in the // value mapping std::string funText1 = "(dmap "; std::string funText2 = "\"\" (fun (dmapelem_1 ARRAYFUNARG1) " "(groupby (feed dmapelem_1) " + nl->ToString( attrlist ) + nl->ToString( fun ) + " ) ) )"; #ifdef DRELDEBUG cout << "funText1" << endl; cout << funText1 << endl; cout << "funText2" << endl; cout << funText2 << endl; #endif ListExpr resultType = nl->ThreeElemList( listutils::basicSymbol( ), relType, distType ); ListExpr append = nl->TwoElemList( nl->TextAtom( funText1 ), nl->TextAtom( funText2 ) ); return nl->ThreeElemList( nl->SymbolAtom( Symbols::APPEND( ) ), append, resultType ); } template ListExpr drellgroupbyTM( ListExpr args ); template ListExpr drellgroupbyTM( ListExpr args ); /* 1.1.10 Type Mapping ~lsortbyTM~ Expect a d[f]rel an attribute list. Type mapping for the lsortby operator. */ ListExpr lsortbyTM( ListExpr args ) { #ifdef DRELDEBUG cout << "lsortbyTM" << endl; cout << "args" << endl; cout << nl->ToString( args ) << endl; #endif std::string err = "d[f]rel(X) x attrlist expected"; if( !nl->HasLength( args, 2 ) ) { return listutils::typeError( err + ": two arguments are expected" ); } if( !DRelHelpers::isListOfTwoElemLists( args ) ) { return listutils::typeError( "internal Error" ); } ListExpr drelType, relType, distType, drelValue, darrayType; if( !DRelHelpers::isDRelDescr( nl->First( args ), drelType, relType, distType, drelValue, darrayType ) ) { return listutils::typeError( err + ": first argument is not a d[f]rel" ); } ListExpr attrlist = nl->First( nl->Second( args ) ); // TM sortby ListExpr result = extrelationalg::SortByTypeMap( nl->TwoElemList( nl->TwoElemList( listutils::basicSymbol >( ), nl->Second( relType ) ), attrlist ) ); // sortby tm okay? if( !nl->HasLength( result, 3 ) ) { return result; } // create string to call dmap the call is devided in two parts // the argument for the drel is missing and will be filled in the // value mapping std::string funText1 = "(dmap "; std::string funText2 = "\"\" (fun (dmapelem_1 ARRAYFUNARG1) " "(sortby (feed dmapelem_1) " + nl->ToString( attrlist ) + " ) ) )"; #ifdef DRELDEBUG cout << "funText1" << endl; cout << funText1 << endl; cout << "funText2" << endl; cout << funText2 << endl; #endif ListExpr resultType = nl->ThreeElemList( listutils::basicSymbol( ), relType, distType ); ListExpr append = nl->TwoElemList( nl->TextAtom( funText1 ), nl->TextAtom( funText2 ) ); return nl->ThreeElemList( nl->SymbolAtom( Symbols::APPEND( ) ), append, resultType ); } /* 1.1.13 Type Mapping rangeTM Expect a d[f]array with a btree and a d[f]rel and two values to define the range. */ ListExpr rangeTM( ListExpr args ) { std::string err = "drel(btree(X)) x drel(rel(X)) x ANY x ANY expected"; cout << "args" << endl; cout << nl->ToString( args ) << endl; if( !nl->HasLength( args, 4 ) ) { return listutils::typeError( err + ": four arguments are expected" ); } if( !DRelHelpers::isListOfTwoElemLists( args ) ) { return listutils::typeError( "internal Error" ); } ListExpr drelType, relType, distType, drelValue, darrayType; if( !DRelHelpers::isDRelDescr( nl->Second( args ), drelType, relType, distType, drelValue, darrayType ) ) { return listutils::typeError( err + ": second argument is not a d[f]rel" ); } ListExpr darrayBTreeType = nl->First( nl->First( args ) ); ListExpr range1Type = nl->First( nl->Third( args ) ); ListExpr range2Type = nl->First( nl->Fourth( args ) ); if( !DArray::checkType( darrayBTreeType ) ) { return listutils::typeError( err + ": first argument is not a darray" ); } ListExpr bTreeType = nl->Second( darrayBTreeType ); ListExpr result = IndexQueryTypeMap<2>( nl->FourElemList( bTreeType, relType, range1Type, range2Type ) ); if( !listutils::isTupleStream( result ) ) { return result; } ListExpr range1 = nl->Second( nl->Third( args ) ); ListExpr range2 = nl->Second( nl->Fourth( args ) ); // create string to call dmap the call is devided in two parts // the argument for the drel is missing and will be filled in the // value mapping std::string funText1 = "(dmap2 "; std::string funText2 = "\"\" (fun (elem1_1 ARRAYFUNARG1) " "(elem2_2 ARRAYFUNARG2) " "(range elem1_1 elem2_2 " + nl->ToString( range1 ) + " " + nl->ToString( range2 ) + " ) ) " + getDRelPortString() +" )"; #ifdef DRELDEBUG cout << "funText1" << endl; cout << funText1 << endl; cout << "funText2" << endl; cout << funText2 << endl; #endif ListExpr resultType = nl->ThreeElemList( listutils::basicSymbol( ), relType, distType ); ListExpr append = nl->TwoElemList( nl->TextAtom( funText1 ), nl->TextAtom( funText2 ) ); return nl->ThreeElemList( nl->SymbolAtom( Symbols::APPEND( ) ), append, resultType ); } /* 1.1.12 Type Mapping exactmatchTM Expect a d[f]array with a btree and a d[f]rel and a search value. */ ListExpr exactmatchTM( ListExpr args ) { std::string err = "drel(btree(X)) x drel(rel(X)) x ANY expected"; if( !nl->HasLength( args, 3 ) ) { return listutils::typeError( err + ": three arguments are expected" ); } if( !DRelHelpers::isListOfTwoElemLists( args ) ) { return listutils::typeError( "internal Error" ); } ListExpr darrayBTreeType = nl->First( nl->First( args ) ); if( !DArray::checkType( darrayBTreeType ) ) { return listutils::typeError( err + ": first argument is not a darray" ); } ListExpr drelType, relType, distType, drelValue, darrayType; if( !DRelHelpers::isDRelDescr( nl->Second( args ), drelType, relType, distType, drelValue, darrayType ) ) { return listutils::typeError( err + ": second argument is not a d[f]rel" ); } ListExpr searchType = nl->First( nl->Third( args ) ); ListExpr bTreeType = nl->Second( darrayBTreeType ); ListExpr result = IndexQueryTypeMap<3>( nl->ThreeElemList( bTreeType, relType, searchType ) ); if( !listutils::isTupleStream( result ) ) { return result; } ListExpr searchValue = nl->Second( nl->Third( args ) ); // create string to call dmap the call is devided in two parts // the argument for the drel is missing and will be filled in the // value mapping std::string funText1 = "(dmap2 "; std::string funText2 = "\"\" (fun (elem1_1 ARRAYFUNARG1) " "(elem2_2 ARRAYFUNARG2) " "(exactmatch elem1_1 elem2_2 " + nl->ToString( searchValue ) + " ) ) "+ getDRelPortString() + " )"; #ifdef DRELDEBUG cout << "funText1" << endl; cout << funText1 << endl; cout << "funText2" << endl; cout << funText2 << endl; #endif ListExpr resultType = nl->ThreeElemList( listutils::basicSymbol( ), relType, distType ); ListExpr append = nl->TwoElemList( nl->TextAtom( funText1 ), nl->TextAtom( funText2 ) ); return nl->ThreeElemList( nl->SymbolAtom( Symbols::APPEND( ) ), append, resultType ); } /* 1.1.13 Type Mapping ~windowintersectsTM~ Expect a d[f]rel and an attrtibute list to execute a mapped function on the the distributed relation. Type mapping for global simple operators with two arguments. */ ListExpr windowintersectsTM( ListExpr args ) { std::string err = "darray[rtree] x d[f]rel(X) x rect expected"; if( !nl->HasLength( args, 3 ) ) { return listutils::typeError( err + ": three arguments are expected" ); } if( !DRelHelpers::isListOfTwoElemLists( args ) ) { return listutils::typeError( "internal Error" ); } ListExpr darrayBTreeType = nl->First( nl->First( args ) ); if( !DArray::checkType( darrayBTreeType ) ) { return listutils::typeError( err + ": first argument is not a darray" ); } ListExpr drelType, relType, distType, drelValue, darrayType; if( !DRelHelpers::isDRelDescr( nl->Second( args ), drelType, relType, distType, drelValue, darrayType ) ) { return listutils::typeError( err + ": second argument is not a d[f]rel" ); } ListExpr arg3Type = nl->First( nl->Third( args ) ); ListExpr arg3Value = nl->Second( nl->Third( args ) ); if( !Rectangle<2>::checkType( arg3Type ) ) { return listutils::typeError( err + ": third argument is rectangle" ); } if( !nl->IsAtom( arg3Type ) ) { return listutils::typeError( err + ": third argument is not a saved rectangle" ); } //string tempName = distributed2::algInstance->getTempName( ); std::string tempName = nl->SymbolValue( arg3Value ); // Bring rect to the workers cout << "bring intersect argument to the workers" << endl; ListExpr shareQuery = nl->FourElemList( nl->SymbolAtom( "share" ), nl->StringAtom( nl->SymbolValue( arg3Value ) ), nl->BoolAtom( true ), nl->TwoElemList( nl->SymbolAtom( "drel2darray" ), drelValue ) ); Word result; bool correct, evaluable, defined, isFunction; std::string typeString, errorString; QueryProcessor::ExecuteQuery( shareQuery, result, typeString, errorString, correct, evaluable, defined, isFunction ); FText* shareResult = ( FText* )result.addr; if( !correct || !evaluable || !defined || !shareResult->IsDefined( ) ) { return listutils::typeError( "error while bring the argument to the workers" ); } cout << shareResult->GetValue( ) << endl; delete shareResult; // create string to call dmap the call is devided in two parts // the argument for the drel is missing and will be filled in the // value mapping std::string funText1 = "(dmap2 "; std::string funText2 = "\"\" (fun (elem1_1 ARRAYFUNARG1) " "(elem2_2 ARRAYFUNARG2) " "(windowintersects elem1_1 elem2_2 " + tempName + " ) ) " + getDRelPortString() + " )"; #ifdef DRELDEBUG cout << "funText1" << endl; cout << funText1 << endl; cout << "funText2" << endl; cout << funText2 << endl; #endif ListExpr resultType = nl->ThreeElemList( listutils::basicSymbol( ), relType, distType ); ListExpr append = nl->TwoElemList( nl->TextAtom( funText1 ), nl->TextAtom( funText2 ) ); return nl->ThreeElemList( nl->SymbolAtom( Symbols::APPEND( ) ), append, resultType ); } /* 1.1.13 Type Mapping inloopjoinTM Expect two DRels (one with btree and one with a relation) and a search value. */ ListExpr inloopjoinTM( ListExpr args ) { std::string err = "drel(rel(X)) x darray(btree(Y)) x drel(rel(Z)) " "x attr expected"; if( !nl->HasLength( args, 4 ) ) { return listutils::typeError( err + ": two arguments are expected" ); } if( !DRelHelpers::isListOfTwoElemLists( args ) ) { return listutils::typeError( "internal Error" ); } ListExpr drel1Type, rel1Type, dist1Type, drel1Value, darray1Type; if( !DRelHelpers::isDRelDescr( nl->First( args ), drel1Type, rel1Type, dist1Type, drel1Value, darray1Type ) ) { return listutils::typeError( err + ": first argument is not a d[f]rel" ); } ListExpr darrayBTreeType = nl->First( nl->Second( args ) ); if( !DArray::checkType( darrayBTreeType ) ) { return listutils::typeError( err + ": second argument is not a darray" ); } //ListExpr btreeType = nl->Second( nl->Second( args ) ); ListExpr drel2Type, rel2Type, dist2Type, drel2Value, darray2Type; if( !DRelHelpers::isDRelDescr( nl->Third( args ), drel2Type, rel2Type, dist2Type, drel2Value, darray2Type ) ) { return listutils::typeError( err + ": third argument is not a d[f]rel" ); } ListExpr arg4Type = nl->First( nl->Fourth( args ) ); if( !nl->IsAtom( arg4Type ) || nl->AtomType( arg4Type ) != SymbolType ) { return listutils::typeError( err + ": fourth argument is not an attribute" ); } // create string to call dmap the call is devided in two parts // the argument for the drel is missing and will be filled in the // value mapping ListExpr arg4Value = nl->Second( nl->Fourth( args ) ); std::string funText1 = "(dmap3 "; std::string funText2 = "\"\" (fun (elem1_1 ARRAYFUNARG1) " "(elem2_2 ARRAYFUNARG2) (elem3_3 ARRAYFUNARG3) " "(loopjoin (feed elem1_1) (fun (tuple_4 TUPLE) " "(exactmatch elem2_2 elem3_3 (attr tuple_4 " + nl->ToString( arg4Value ) + ") ) ) ) ) " + getDRelPortString() + " )"; #ifdef DRELDEBUG cout << "funText1" << endl; cout << funText1 << endl; cout << "funText2" << endl; cout << funText2 << endl; #endif ListExpr attr1List = nl->Second( nl->Second( rel1Type ) ); ListExpr attr2List = nl->Second( nl->Second( rel2Type ) ); ListExpr relType = nl->TwoElemList( listutils::basicSymbol( ), nl->TwoElemList( listutils::basicSymbol( ), ConcatLists( attr1List, attr2List ) ) ); ListExpr resultType = nl->ThreeElemList( listutils::basicSymbol( ), relType, dist2Type ); ListExpr append = nl->TwoElemList( nl->TextAtom( funText1 ), nl->TextAtom( funText2 ) ); return nl->ThreeElemList( nl->SymbolAtom( Symbols::APPEND( ) ), append, resultType ); } /* 1.2 Value Mapping ~dreldmapVMT~ Uses a d[f]rel and creates a new drel. The d[f]rel is created by calling the dmap operators of the Distributed2Algebra. The function is in the text arguments of the typemapping. */ template int dreldmapNewVMT( Word* args, Word& result, int message, Word& local, Supplier s ) { #ifdef DRELDEBUG cout << "dreldmapNewVMT" << endl; #endif int x = qp->GetNoSons( s ); R* drel = ( R* )args[ 0 ].addr; FText* fun1 = ( FText* )args[ x - 2 ].addr; FText* fun2 = ( FText* )args[ x - 1 ].addr; result = qp->ResultStorage(s); DFRel* resultDFRel = ( DFRel* )result.addr; if( !drel->IsDefined( ) ) { resultDFRel->makeUndefined( ); return 0; } // create dmap call with drel pointer std::string drelptr = nl->ToString( DRelHelpers::createdrel2darray( qp->GetType( qp->GetSon( s, 0 ) ), drel ) ); std::string funText = fun1->GetValue( ) + drelptr + fun2->GetValue( ); #ifdef DRELDEBUG cout << "funText" << endl; cout << funText << endl; #endif ListExpr funList; if( !nl->ReadFromString( funText, funList ) ) { resultDFRel->makeUndefined( ); } bool correct = false; bool evaluable = false; bool defined = false; bool isFunction = false; std::string typeString, errorString; Word dmapResult; if( !QueryProcessor::ExecuteQuery( funList, dmapResult, typeString, errorString, correct, evaluable, defined, isFunction ) ) { resultDFRel->makeUndefined( ); return 0; } if( !correct || !evaluable || !defined ) { resultDFRel->makeUndefined( ); return 0; } DFArray* dfarray = ( DFArray* )dmapResult.addr; if( !dfarray->IsDefined( ) ) { resultDFRel->makeUndefined( ); delete dfarray; return 0; } resultDFRel->copyFrom( *dfarray ); delete dfarray; if( setDType ) { resultDFRel->setDistType( drel->getDistType( )->copy( ) ); } return 0; } template int dreldmapNewVMT( Word* args, Word& result, int message, Word& local, Supplier s ); template int dreldmapNewVMT( Word* args, Word& result, int message, Word& local, Supplier s ); /* 1.3 Value Mapping ~dreldmap2VMT~ Uses a d[f]rel and a d[f]array and and creates a new drel. The d[f]rel is created by calling the dmap operators of the Distributed2Algebra. The function is in the text arguments of the typemapping. */ template int dreldmapNew2VMT( Word* args, Word& result, int message, Word& local, Supplier s ) { #ifdef DRELDEBUG cout << "dreldmapVMT" << endl; #endif int x = qp->GetNoSons( s ); DArray* darray = ( DArray* )args[ 0 ].addr; R* drel = ( R* )args[ 1 ].addr; FText* fun1 = ( FText* )args[ x - 2 ].addr; FText* fun2 = ( FText* )args[ x - 1 ].addr; result = qp->ResultStorage(s); DFRel* resultDFRel = ( DFRel* )result.addr; if( !drel->IsDefined( ) || !darray->IsDefined( ) ) { resultDFRel->makeUndefined( ); return 0; } // create dmap call with drel pointer std::string darrayptr = nl->ToString( DRelHelpers::createPointerList( qp->GetType( qp->GetSon( s, 0 ) ), darray ) ); std::string drelptr = nl->ToString( DRelHelpers::createdrel2darray( qp->GetType( qp->GetSon( s, 1 ) ), drel ) ); std::string funText = fun1->GetValue( ) + darrayptr + drelptr + fun2->GetValue( ); #ifdef DRELDEBUG cout << "funText" << endl; cout << funText << endl; #endif ListExpr funList; if( !nl->ReadFromString( funText, funList ) ) { resultDFRel->makeUndefined( ); } bool correct = false; bool evaluable = false; bool defined = false; bool isFunction = false; std::string typeString, errorString; Word dmapResult; if( !QueryProcessor::ExecuteQuery( funList, dmapResult, typeString, errorString, correct, evaluable, defined, isFunction ) ) { resultDFRel->makeUndefined( ); return 0; } if( !correct || !evaluable || !defined ) { resultDFRel->makeUndefined( ); return 0; } DFArray* dfarray = ( DFArray* )dmapResult.addr; if( !dfarray->IsDefined( ) ) { resultDFRel->makeUndefined( ); delete dfarray; return 0; } resultDFRel->copyFrom( *dfarray ); delete dfarray; resultDFRel->setDistType( drel->getDistType( )->copy( ) ); return 0; } /* 1.4 Value Mapping ~dreldmap3VMT~ Uses a d[f]rel and a d[f]array and and creates a new drel. The d[f]rel is created by calling the dmap operators of the Distributed2Algebra. The function is in the text arguments of the typemapping. */ template int dreldmap3VMT( Word* args, Word& result, int message, Word& local, Supplier s ) { #ifdef DRELDEBUG cout << "dreldmap3VMT" << endl; #endif int x = qp->GetNoSons( s ); R* drel1 = ( R* )args[ 0 ].addr; DArray* darray = ( DArray* )args[ 1 ].addr; T* drel2 = ( T* )args[ 2 ].addr; FText* fun1 = ( FText* )args[ x - 2 ].addr; FText* fun2 = ( FText* )args[ x - 1 ].addr; result = qp->ResultStorage(s); DFRel* resultDFRel = ( DFRel* )result.addr; if( !drel1->IsDefined( ) || !darray->IsDefined( ) || !drel2->IsDefined( ) ) { resultDFRel->makeUndefined( ); return 0; } // create dmap call with drel pointer std::string drel1ptr = nl->ToString( DRelHelpers::createdrel2darray( qp->GetType( qp->GetSon( s, 0 ) ), drel1 ) ); std::string darrayptr = nl->ToString( DRelHelpers::createPointerList( qp->GetType( qp->GetSon( s, 1 ) ), darray ) ); std::string drel2ptr = nl->ToString( DRelHelpers::createdrel2darray( qp->GetType( qp->GetSon( s, 2 ) ), drel2 ) ); std::string funText = fun1->GetValue( ) + drel1ptr + darrayptr + drel2ptr + " " + fun2->GetValue( ); #ifdef DRELDEBUG cout << "funText" << endl; cout << funText << endl; #endif ListExpr funList; if( !nl->ReadFromString( funText, funList ) ) { resultDFRel->makeUndefined( ); } bool correct = false; bool evaluable = false; bool defined = false; bool isFunction = false; std::string typeString, errorString; Word dmapResult; if( !QueryProcessor::ExecuteQuery( funList, dmapResult, typeString, errorString, correct, evaluable, defined, isFunction ) ) { resultDFRel->makeUndefined( ); return 0; } if( !correct || !evaluable || !defined ) { resultDFRel->makeUndefined( ); return 0; } DFArray* dfarray = ( DFArray* )dmapResult.addr; if( !dfarray->IsDefined( ) ) { resultDFRel->makeUndefined( ); delete dfarray; return 0; } resultDFRel->copyFrom( *dfarray ); delete dfarray; resultDFRel->setDistType( drel2->getDistType( )->copy( ) ); return 0; } /* 1.5 ValueMapping Array for dmap Used by the operators with only a d[f]rel input. */ ValueMapping dreldmapNewVM[ ] = { dreldmapNewVMT, dreldmapNewVMT }; /* 1.6 ValueMapping Array for dmap Used by the operators with a darray and a d[f]rel as input. */ ValueMapping dreldmapNew2VM[ ] = { dreldmapNew2VMT, dreldmapNew2VMT }; /* 1.8 ValueMapping Array for dmap Used by the operators with a darray and a d[f]rel as input. */ ValueMapping dreldmapNew3VM[ ] = { dreldmap3VMT, dreldmap3VMT, dreldmap3VMT, dreldmap3VMT }; /* 1.8 Selection functions for operators without repartitioning */ int dreldmapSelect( ListExpr args ) { return DRel::checkType( nl->First( args ) ) ? 0 : 1; } int dreldmap2Select( ListExpr args ) { return DRel::checkType( nl->Second( args ) ) ? 0 : 1; } int dreldmap3Select( ListExpr args ) { // first and third drels int x1 = DRel::checkType( nl->First( args ) ) ? 0 : 2; int x2 = DRel::checkType( nl->Third( args ) ) ? 0 : 2; return x1 + x2; } /* 1.9 Specification for all operators using dmapVM 1.9.1 Specification of project Operator specification of the porject operator. */ OperatorSpec projectSpec( " drel(X) x attrlist " "-> drel(Y) ", " _ project[attrlist]", "Passed only the listed attributes to a stream. It is not allowed to " "create a new d[f]rel without the partion attribute.", " query drel1 project[PLZ, Ort]" ); /* 1.9.2 Specification of drelfilter Operator specification of the drelfilter operator. */ OperatorSpec drelfilterSpec( " drel(X) x fun " "-> drel(X) ", " _ drelfilter[fun]", "Only tuples, fulfilling a certain condition are passed to the new " "d[f]rel", " query drel1 drelfilter[.PLZ=99998]" ); /* 1.9.3 Specification of drelprojectextend Operator specification of the drelprojectextend operator. */ OperatorSpec drelprojectextendSpec( " drel(X) x attrlist x funlist " "-> drel(X) ", " _ drelprojectextend[list; funlist]", "First projects the drel and then extends the drel with additional " "attributes specified by the funlist", " query drel1 drelprojectextend[No; Mult5: .No * 5]" ); /* 1.9.4 Specification of drelextend Operator specification of the drelextend operator. */ OperatorSpec drelextendSpec( " drel(X) x funlist " "-> drel(X) ", " _ drelextend[list]", "Extends the drel with additional attributes specified by the funlist", " query drel1 drelextend[Mult5: .No * 5]" ); /* 1.9.5 Specification of head Operator specification of the head operator. */ OperatorSpec headSpec( " drel(X) x int -> drel(X) ", " _ head[int]", " Reduces each slot to it's first n tuples. ", " query drel1 head[5]" ); /* 1.9.6 Specification of rename Operator specification of the rename operator. */ OperatorSpec renameSpec( " drel(X) x ar " "-> drel(X) ", " _ rename[symbol]", "Renames all attribute names by adding" " them with the postfix passed as parameter. " "NOTE: parameter must be of symbol type.", " query drel1 rename[A]" ); /* 1.9.7 Specification of lrdup Operator specification of the lrdup operator. */ OperatorSpec lrdupSpec( " drel(X) " "-> drel(X) ", " _ lrdup", "Removes duplicates in a d[f]rel. " "NOTE: Duplicates are only removed in a local array field " "and not in the global d[f]rel.", " query drel1 lrdup" ); /* 1.9.8 Specification of lsort Operator specification of the lsort operator. */ OperatorSpec lsortSpec( " drel(X) " "-> drel(X) ", " _ lsort", "Sorts a d[f]rel. " "NOTE: The operator only sorts the local array fields " "and not in global d[f]rel.", " query drel1 lsort" ); /* 1.9.9 Specification of drellgroupby Operator specification of the drellgroupby operator. */ OperatorSpec drellgroupbySpec( " drel(X) x attrlist x funlist " "-> drel(X) ", " _ drellgroupby[attrlist, funlist]", "Groups a d[f]rel according to attributes " "ai1, ..., aik and feeds the groups to other " "functions. The results of those functions are " "appended to the grouping attributes. The empty " "list is allowed for the grouping attributes (this " "results in a single group with all input tuples)." "NOTE: The operator only groups the local array fields " "and not in global d[f]rel.", " query drel1 drellgroupby[PLZ; Anz: group feed count]" ); /* 1.9.10 Specification of lsortby Operator specification of the lsortby operator. */ OperatorSpec lsortbySpec( " drel(X) " "-> drel(X) ", " _ lsortby[attrlist]", "Sorts a d[f]rel by a specific attribute list. " "NOTE: The operator only sorts the local array fields " "and not in global d[f]rel.", " query drel1 lsortby[PLZ]" ); /* 1.9.11 Specification of windowintersects Operator specification of the windowintersects operator. */ OperatorSpec windowintersectsSpec( " darray(rtree(X)) x d[f]rel[X]" "-> dfrel(X) ", " _ _ windowintersects[_]", "Computes a windowsintersects of a darray with an rtree, an " "d[f]rel and a rectangle.", " query darray1 drel1 windowintersects[rectangle]" ); /* 1.9.12 Specification of range */ OperatorSpec rangeSpec( " darray(btree(X)) x drel(X) x string " "-> darray(X) ", " _ _ range[_,_]", "Uses a distributed btree and a drel to call the range operator.", " query drel1_Name drel1 range[\"Berlin\",\"Mannheim\"]" ); /* 1.9.13 Specification of exactmatch */ OperatorSpec exactmatchSpec( " darray(btree(X)) x drel(X) x string " "-> darray(X) ", " _ _ exactmatch[_]", "Uses a distributed btree and a drel to call the exactmatch operator.", " query drel1_Name drel1 exactmatch[\"Berlin\"]" ); /* 1.9.14 Specification of inloopjoin */ OperatorSpec inloopjoinSpec( " d[f]rel(X) x fun -> dfrel(X) ", " _ _ _ inloopjoin[_]", "Uses a d[f]rel and computes a loop join with an other d[f]rel and a " "btree. The function is static with the exactmatch operator ", " query drel1 drel2_A drel2 inloopjoin[B]" ); /* 1.10 Operator instance of operators using dmapVM 1.10.1 Operator instance of drelfilter operator */ Operator drelfilterOp( "drelfilter", drelfilterSpec.getStr( ), 2, dreldmapNewVM, dreldmapSelect, drelfilterTM ); /* 1.10.2 Operator instance of drelproject operator */ Operator projectOp( "project", projectSpec.getStr( ), 2, dreldmapNewVM, dreldmapSelect, projectTM ); /* 1.10.3 Operator instance of drelprojectextend operator */ Operator drelprojectextendOp( "drelprojectextend", drelprojectextendSpec.getStr( ), 2, dreldmapNewVM, dreldmapSelect, drelprojectextendTM ); /* 1.10.4 Operator instance of drelextend operator */ Operator drelextendOp( "drelextend", drelextendSpec.getStr( ), 2, dreldmapNewVM, dreldmapSelect, drelextendTM ); /* 1.10.5 Operator instance of head operator */ Operator headOp( "head", headSpec.getStr( ), 2, dreldmapNewVM, dreldmapSelect, headTM ); /* 1.10.6 Operator instance of drelrename operator */ Operator renameOp( "rename", renameSpec.getStr( ), 2, dreldmapNewVM, dreldmapSelect, renameTM ); /* 1.10.7 Operator instance of lrdup operator */ Operator lrdupOp( "lrdup", lrdupSpec.getStr( ), 2, dreldmapNewVM, dreldmapSelect, lrdupTM ); /* 1.10.8 Operator instance of lsort operator */ Operator lsortOp( "lsort", lsortSpec.getStr( ), 2, dreldmapNewVM, dreldmapSelect, lsortTM ); /* 1.10.9 Operator instance of drellgroupby operator */ Operator drellgroupbyOp( "drellgroupby", drellgroupbySpec.getStr( ), 2, dreldmapNewVM, dreldmapSelect, drellgroupbyTM ); /* 1.10.10 Operator instance of lsortby operator */ Operator lsortbyOp( "lsortby", lsortbySpec.getStr( ), 2, dreldmapNewVM, dreldmapSelect, lsortbyTM ); /* 1.10.11 Operator instance of windowintersects operator */ Operator windowintersectsOp( "windowintersects", windowintersectsSpec.getStr( ), 2, dreldmapNew2VM, dreldmap2Select, windowintersectsTM ); /* 1.10.12 Operator instance of range operator */ Operator rangeOp( "range", rangeSpec.getStr( ), 2, dreldmapNew2VM, dreldmap2Select, rangeTM ); /* 1.10.13 Operator instance of exactmatch operator */ Operator exactmatchOp( "exactmatch", exactmatchSpec.getStr( ), 2, dreldmapNew2VM, dreldmap2Select, exactmatchTM ); /* 1.10.14 Operator instance of inloopjoin operator */ Operator inloopjoinOp( "inloopjoin", inloopjoinSpec.getStr( ), 4, dreldmapNew3VM, dreldmap3Select, inloopjoinTM ); } // end of namespace drel