Files
secondo/Algebras/DRel2/dreldmap.cpp
2026-01-23 17:03:45 +08:00

2529 lines
75 KiB
C++

/*
----
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
----
//[$][\$]
@author
T. Beckmann
@description
see OperatorSpec
@note
Checked - 2020
@history
Version 1.0 - Created - T. Beckmann - 2018
Version 1.1 - Small improvements - D. Selenyi - 19.08.2020
Version 1.2 - WindowIntersects2 - new fourth Parameter Worker Relation and any kind of spatial rect is allowed. - D. Selenyi - 19.08.2020
@todo
Workers Relation check didnt worked for WindowIntersects2
*/
/*
1 Implementation of the secondo operators:
drelfilter, project, drelprojectextend, drellsortby, drellgroupby, lsort, lrdup,
rename, head, exactmatch, inloopjoin, range, windowintersects 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<int operatorId>
ListExpr IndexQueryTypeMap( ListExpr args );
namespace distributed2 {
extern Distributed2Algebra* algInstance;
ListExpr dmapTM( ListExpr args );
template<int x>
ListExpr dmapXTMT( ListExpr args );
template<class A>
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<class A, bool fromCat>
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 << 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 resultList = OperatorFilter::FilterTypeMap(
nl->TwoElemList(
nl->TwoElemList(
nl->TwoElemList(
listutils::basicSymbol<Stream<Tuple> >( ),
nl->Second( relType ) ),
nl->TwoElemList(
nl->SymbolAtom( "feed" ),
drelValue ) ), // only dummy for the filter TM
nl->TwoElemList( map, fun ) ) );
#ifdef DRELDEBUG
cout << "Result: " << nl->ToString( resultList ) << endl;
#endif
// filter TM ok?
if( !listutils::isTupleStream( resultList ) ) {
return resultList;
}
// 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<DFRel>( ),
relType,
nl->Third( drelType ) ); // disttype
ListExpr appendList = nl->TwoElemList(
nl->TextAtom( funText1 ),
nl->TextAtom( funText2 ) );
return nl->ThreeElemList(
nl->SymbolAtom( Symbols::APPEND( ) ),
appendList,
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 << 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 resultList = OperatorProject::ProjectTypeMap(
nl->TwoElemList(
nl->TwoElemList(
listutils::basicSymbol<Stream<Tuple> >( ),
nl->Second( relType ) ),
attrlist ) );
#ifdef DRELDEBUG
cout << "Result: " << nl->ToString( resultList ) << endl;
#endif
// project TM ok?
if( !nl->HasLength( resultList, 3 ) ) {
return resultList;
}
if( !listutils::isTupleStream( nl->Third( resultList ) ) ) {
return resultList;
}
relType = nl->TwoElemList(
listutils::basicSymbol<Relation>( ),
nl->Second( nl->Third( resultList ) ) );
#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( resultList ) ), 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<DFRel>( ),
relType,
distType );
ListExpr appendList = nl->TwoElemList(
nl->TextAtom( funText1 ),
nl->TextAtom( funText2 ) );
return nl->ThreeElemList(
nl->SymbolAtom( Symbols::APPEND( ) ),
appendList,
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 << 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 resultList = extrelationalg::ExtProjectExtendTypeMap(
nl->ThreeElemList(
nl->TwoElemList(
listutils::basicSymbol<Stream<Tuple> >( ),
nl->Second( relType ) ),
attrlist,
map ) );
#ifdef DRELDEBUG
cout << "Result: " << nl->ToString( resultList ) << endl;
#endif
// filter TM ok?
if( !nl->HasLength( resultList, 3 ) ) {
return resultList;
}
if( !listutils::isTupleStream( nl->Third( resultList ) ) ) {
return resultList;
}
relType = nl->TwoElemList(
listutils::basicSymbol<Relation>( ),
nl->Second( nl->Third( resultList ) ) );
// 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( resultList ) ), 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<DFRel>( ),
relType,
distType );
ListExpr appendList = nl->TwoElemList(
nl->TextAtom( funText1 ),
nl->TextAtom( funText2 ) );
return nl->ThreeElemList(
nl->SymbolAtom( Symbols::APPEND( ) ),
appendList,
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 << 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 resultList = extrelationalg::ExtendTypeMap(
nl->TwoElemList(
nl->TwoElemList(
listutils::basicSymbol<Stream<Tuple> >( ),
nl->Second( relType ) ),
map ) );
#ifdef DRELDEBUG
cout << "Result: " << nl->ToString( resultList ) << endl;
#endif
// filter TM ok?
if( !nl->HasLength( resultList, 2 ) ) {
return resultList;
}
if( !listutils::isTupleStream( resultList ) ) {
return resultList;
}
relType = nl->TwoElemList(
listutils::basicSymbol<Relation>( ),
nl->Second( resultList ) );
// 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<DFRel>( ),
relType,
distType );
ListExpr appendList = nl->TwoElemList(
nl->TextAtom( funText1 ),
nl->TextAtom( funText2 ) );
return nl->ThreeElemList(
nl->SymbolAtom( Symbols::APPEND( ) ),
appendList,
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 << 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" );
}
if( !CcInt::checkType( nl->First( nl->Second( args ) ) ) ) {
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( nl->Second( nl->Second( args ) ) ) + ") ) )";
#ifdef DRELDEBUG
cout << "funText1" << endl;
cout << funText1 << endl;
cout << "funText2" << endl;
cout << funText2 << endl;
#endif
ListExpr resultType = nl->ThreeElemList(
listutils::basicSymbol<DFRel>( ),
relType,
distType );
ListExpr appendList = nl->TwoElemList(
nl->TextAtom( funText1 ),
nl->TextAtom( funText2 ) );
return nl->ThreeElemList(
nl->SymbolAtom( Symbols::APPEND( ) ),
appendList,
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 << 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 );
ListExpr secondType = nl->First( nl->Second( args ) );
ListExpr secondValue = nl->Second( nl->Second( args ) );
//Prepare remove Original and Cell
ListExpr attrList = nl->Second(nl->Second( relType ));
//Delete Attributes Original and Cell
if( dType == spatial2d || dType == spatial3d || dType == replicated ) {
attrList = DRelHelpers::removeAttrFromAttrList(
attrList, "Original" );
if( dType != replicated ) {
attrList = DRelHelpers::removeAttrFromAttrList(
attrList, "Cell" );
}
}
attrList = nl->TwoElemList(
listutils::basicSymbol<Tuple>( ),
attrList
);
ListExpr resultList = RenameTypeMap(
nl->TwoElemList(
nl->TwoElemList(
listutils::basicSymbol<Stream<Tuple> >( ),
attrList ),
secondType ) );
cout << "result: " << nl->ToString(resultList) << endl;
// project TM ok?
if( !nl->HasLength( resultList, 2 ) ) {
return resultList;
}
if( !listutils::isTupleStream( resultList ) ) {
return resultList;
}
relType = nl->TwoElemList(
listutils::basicSymbol<Relation>( ),
nl->Second( resultList ) );
// 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 ) + ") ) )";
// create string to call dmap.
//For Replicated where drelfilter is only Orignial = True
// Selenyi - Pointer not needed. Will be done in VM.
if ( dType == replicated ) {
funText2 = "\"\" (fun (dmapelem_1 ARRAYFUNARG1)"
"(rename (remove (filter (feed dmapelem_1) "
"(fun (streamelem_2 STREAMELEM) (= (attr streamelem_2 Original)"
" TRUE))) (Original)) "+ nl->ToString( secondValue ) + ")))";
}
if ( dType == spatial2d || dType == spatial3d ) {
cout << "spatial2d/3d funtext2: " << endl;
funText2 = "\"\" (fun (dmapelem_1 ARRAYFUNARG1)"
"(rename (remove (filter (feed dmapelem_1) "
"(fun (streamelem_2 STREAMELEM)"
"(= (attr streamelem_2 Original) TRUE))) (Original Cell)) " +
nl->ToString( secondValue ) + ")))";
}
#ifdef DRELDEBUG
cout << "funText1" << endl;
cout << funText1 << endl;
cout << "funText2" << endl;
cout << funText2 << endl;
#endif
ListExpr resultType = nl->ThreeElemList(
listutils::basicSymbol<DFRel>( ),
relType,
distType );
ListExpr appendList = nl->TwoElemList(
nl->TextAtom( funText1 ),
nl->TextAtom( funText2 ) );
return nl->ThreeElemList(
nl->SymbolAtom( Symbols::APPEND( ) ),
appendList,
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 << nl->ToString( args ) << endl;
#endif
std::string err = "d[f]rel(X) expected";
if( !nl->HasLength( args, 1 ) ) {
return listutils::typeError( err +
": one argument is 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<DFRel>( ),
relType,
distType );
ListExpr appendList = nl->TwoElemList(
nl->TextAtom( funText1 ),
nl->TextAtom( funText2 ) );
return nl->ThreeElemList(
nl->SymbolAtom( Symbols::APPEND( ) ),
appendList,
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 << nl->ToString( args ) << endl;
#endif
std::string err = "d[f]rel(X) expected";
if( !nl->HasLength( args, 1 ) ) {
return listutils::typeError( err +
": one argument is 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<DFRel>( ),
relType,
distType );
ListExpr appendList = nl->TwoElemList(
nl->TextAtom( funText1 ),
nl->TextAtom( funText2 ) );
return nl->ThreeElemList(
nl->SymbolAtom( Symbols::APPEND( ) ),
appendList,
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<bool global>
ListExpr drellgroupbyTM( ListExpr args ) {
#ifdef DRELDEBUG
cout << "drellgroupbyTM" << 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 resultList = extrelationalg::GroupByTypeMap(
nl->ThreeElemList(
nl->TwoElemList(
listutils::basicSymbol<Stream<Tuple> >( ),
nl->Second( relType ) ),
attrlist,
map ) );
#ifdef DRELDEBUG
cout << "groupby tm" << endl;
cout << nl->ToString( resultList ) << endl;
#endif
// groupby TM ok?
if( !nl->HasLength( resultList, 3 ) ) {
return resultList;
}
if( !listutils::isTupleStream( nl->Third( resultList ) ) ) {
return resultList;
}
relType = nl->TwoElemList(
listutils::basicSymbol<Relation>( ),
nl->Second( nl->Third( resultList ) ) );
// 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( resultList ), 2 )
&& DistTypeHash::computeNewAttrPos(
nl->Rest( nl->Second( resultList ) ), 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 ) + " ) ) )";
//Selenyi - added code if attributes are deleted
if (dType == replicated) {
#ifdef DRELDEBUG
cout << "dreldmap.ccp drellgroupby" << endl;
#endif
// without remove
funText2 = "\"\" (fun (dmapelem_1 ARRAYFUNARG1) "
"(groupby (filter (feed dmapelem_1) "
"(fun (streamelem_2 STREAMELEM) "
"(= (attr streamelem_2 Original) TRUE))) "
+ nl->ToString(attrlist ) +
nl->ToString( fun ) + " ) ) )";
/*with remove
funText2 ="\"\" (fun (dmapelem_1 ARRAYFUNARG1) "
"(groupby (remove (filter (feed dmapelem_1) "
"(fun (streamelem_2 STREAMELEM) (= (attr streamelem_2 Original)
" TRUE))) (Original)) " + 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<DFRel>( ),
relType,
distType );
ListExpr appendList = nl->TwoElemList(
nl->TextAtom( funText1 ),
nl->TextAtom( funText2 ) );
return nl->ThreeElemList(
nl->SymbolAtom( Symbols::APPEND( ) ),
appendList,
resultType );
}
template ListExpr drellgroupbyTM<true>( ListExpr args );
template ListExpr drellgroupbyTM<false>( 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 << 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 resultList = extrelationalg::SortByTypeMap(
nl->TwoElemList(
nl->TwoElemList(
listutils::basicSymbol<Stream<Tuple> >( ),
nl->Second( relType ) ),
attrlist ) );
// sortby tm okay?
if( !nl->HasLength( resultList, 3 ) ) {
return resultList;
}
// 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<DFRel>( ),
relType,
distType );
ListExpr appendList = nl->TwoElemList(
nl->TextAtom( funText1 ),
nl->TextAtom( funText2 ) );
return nl->ThreeElemList(
nl->SymbolAtom( Symbols::APPEND( ) ),
appendList,
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";
#ifdef DRELDEBUG
cout << "rangeTM" << endl;
cout << nl->ToString( args ) << endl;
#endif
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 resultList = IndexQueryTypeMap<2>(
nl->FourElemList(
bTreeType,
relType,
range1Type,
range2Type ) );
if( !listutils::isTupleStream( resultList ) ) {
return resultList;
}
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<DFRel>( ),
relType,
distType );
ListExpr appendList = nl->TwoElemList(
nl->TextAtom( funText1 ),
nl->TextAtom( funText2 ) );
return nl->ThreeElemList(
nl->SymbolAtom( Symbols::APPEND( ) ),
appendList,
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 ) {
#ifdef DRELDEBUG
cout << "exactmatchTM" << endl;
cout << nl->ToString( args ) << endl;
#endif
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 resultList = IndexQueryTypeMap<3>(
nl->ThreeElemList(
bTreeType,
relType,
searchType ) );
if( !listutils::isTupleStream( resultList ) ) {
return resultList;
}
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<DFRel>( ),
relType,
distType );
ListExpr appendList = nl->TwoElemList(
nl->TextAtom( funText1 ),
nl->TextAtom( funText2 ) );
return nl->ThreeElemList(
nl->SymbolAtom( Symbols::APPEND( ) ),
appendList,
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 ) {
#ifdef DRELDEBUG
cout << "windowintersectsTM" << endl;
cout << nl->ToString( args ) << endl;
#endif
std::string err = "darray[rtree] x d[f]rel(X) x Spatial|rect"
" Type expected";
if( !nl->HasLength( args, 3 ) ) {
return listutils::typeError( err +
": three arguments are expected" );
}
if( !DRelHelpers::isListOfTwoElemLists( args ) ) {
return listutils::typeError( "internal Error" );
}
ListExpr darrayRTreeType = nl->First( nl->First( args ) );
if( !DArray::checkType( darrayRTreeType ) ) {
cout << "dRTreeType: " << nl->ToString( darrayRTreeType) << endl;
return listutils::typeError( err +
": first argument >" + nl->ToString( darrayRTreeType) +
"< 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 ) );
// third a type with an MBR
if(!(listutils::isSpatialType(arg3Type)
|| listutils::isRectangle(arg3Type))){
return listutils::typeError("Expects 3nd argument to be of a type of "
"kind SPATIAL, SPATIAL3D, SPATIAL4D, SPATIAL8D; or of type 'rect'"
", 'rect3', 'rect4', or 'rect8'.");
}
if( !nl->IsAtom( arg3Type ) ) {
return listutils::typeError(err +
": third argument is not a saved any kind" );
}
std::string tempName = nl->ToString(arg3Value);
// Bring rect to the workers
cout << "bring intersect argument to the workers" << endl;
cout << "Fourth(args): " << nl->ToString(nl->Fourth(args)) << endl;
//Funktioniert nun. Workers ist aber fest vorgegeben. nicht gut.
ListExpr shareQuery = nl->FourElemList(
nl->SymbolAtom( "share" ),
nl->StringAtom( nl->ToString(arg3Value) ),
nl->BoolAtom( true ),
nl->SymbolAtom( "Workers" ));
cout << "shareQuery: " << nl->ToString(shareQuery) << endl;
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:" << 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<DFRel>( ),
relType,
distType );
ListExpr append = nl->TwoElemList(
nl->TextAtom( funText1 ),
nl->TextAtom( funText2 ) );
cout << "append: " << nl->ToString(append) << endl;
cout << "resultType: " << nl->ToString(resultType) << endl;
return nl->ThreeElemList(
nl->SymbolAtom( Symbols::APPEND( ) ),
append,
resultType );
}
/*
1.1.14 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";
cout << endl << "inloopjointm" << endl;
cout << "args: " << nl->ToString(args) << endl;
cout << "First( args ): " << nl->ToString(nl->First( 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 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<Relation>( ),
nl->TwoElemList(
listutils::basicSymbol<Tuple>( ),
ConcatLists( attr1List, attr2List ) ) );
ListExpr resultType = nl->ThreeElemList(
listutils::basicSymbol<DFRel>( ),
relType,
dist2Type );
ListExpr append = nl->TwoElemList(
nl->TextAtom( funText1 ),
nl->TextAtom( funText2 ) );
return nl->ThreeElemList(
nl->SymbolAtom( Symbols::APPEND( ) ),
append,
resultType );
}
/*
1.1.13 Type Mapping ~windowintersects2TM~
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 windowintersects2TM( ListExpr args ) {
#ifdef DRELDEBUG
cout << "windowintersects2TM" << endl;
cout << nl->ToString( args ) << endl;
#endif
std::string err = "darray[rtree] x d[f]rel(X) x Spatial|rect Type x "
"Workers Relation expected";
if( !nl->HasLength( args, 4 ) ) {
return listutils::typeError( err +
": fourth arguments are expected" );
}
if( !DRelHelpers::isListOfTwoElemLists( args ) ) {
return listutils::typeError( "internal Error" );
}
ListExpr darrayRTreeType = nl->First( nl->First( args ) );
if( !DArray::checkType( darrayRTreeType ) ) {
cout << "dRTreeType: " << nl->ToString( darrayRTreeType) << endl;
return listutils::typeError( err +
": first argument >" + nl->ToString( darrayRTreeType) +
"< 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 arg4Type = nl->First( nl->Fourth( args ) );
ListExpr arg4Value = nl->Second( nl->Fourth( args ) );
// third a type with an MBR
if(!(listutils::isSpatialType(arg4Type)
|| listutils::isRectangle(arg4Type))){
return listutils::typeError("Expects 4nd argument to be of a type of "
" kind SPATIAL, SPATIAL3D, SPATIAL4D, SPATIAL8D; or of type 'rect'"
", 'rect3', 'rect4', or 'rect8'.");
}
if( !nl->IsAtom( arg4Type ) ) {
return listutils::typeError(err +
": fourth argument is not a saved any kind" );
}
std::string tempName = nl->ToString(arg4Value);
// Bring rect to the workers
cout << "bring intersect argument to the workers" << endl;
//Funktioniert nun. Workers ist aber fest vorgegeben. nicht gut.
ListExpr shareQuery = nl->FourElemList(
nl->SymbolAtom( "share" ),
nl->StringAtom( nl->ToString(arg4Value) ),
nl->BoolAtom( true ),
nl->SymbolAtom( nl->ToString(nl->Second(nl->Third(args))) ));
cout << "shareQuery: " << nl->ToString(shareQuery) << endl;
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:" << 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<DFRel>( ),
relType,
distType );
ListExpr append = nl->TwoElemList(
nl->TextAtom( funText1 ),
nl->TextAtom( funText2 ) );
cout << "append: " << nl->ToString(append) << endl;
cout << "resultType: " << nl->ToString(resultType) << endl;
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<class R, bool setDType>
int dreldmapNewVMT( Word* args, Word& result, int message,
Word& local, Supplier s ) {
#ifdef DRELDEBUG
cout << "dreldmapNewVMT" << endl;
cout << args << 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 resultList;
if( !nl->ReadFromString( funText, resultList ) ) {
resultDFRel->makeUndefined( );
}
bool correct = false;
bool evaluable = false;
bool defined = false;
bool isFunction = false;
std::string typeString, errorString;
Word dmapResult;
if( !QueryProcessor::ExecuteQuery( resultList, 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;
}
#ifdef DRELDEBUG
cout << "Result:" << resultList << endl;
#endif
resultDFRel->copyFrom( *dfarray );
delete dfarray;
if( setDType ) {
resultDFRel->setDistType( drel->getDistType( )->copy( ) );
}
return 0;
}
template int dreldmapNewVMT<DRel, false>( Word* args, Word& result,
int message, Word& local, Supplier s );
template int dreldmapNewVMT<DFRel, false>( 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<class R>
int dreldmapNew2VMT( Word* args, Word& result, int message,
Word& local, Supplier s ) {
#ifdef DRELDEBUG
cout << "dreldmapNew2VMT" << endl;
cout << args << 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;
cout << "fun1: " << fun1 << endl;
cout << "fun2: " << fun2 << endl;
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 resultList;
if( !nl->ReadFromString( funText, resultList ) ) {
resultDFRel->makeUndefined( );
}
bool correct = false;
bool evaluable = false;
bool defined = false;
bool isFunction = false;
std::string typeString, errorString;
Word dmapResult;
if( !QueryProcessor::ExecuteQuery( resultList, 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;
}
#ifdef DRELDEBUG
cout << "Result:" << resultList << endl;
#endif
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<class R, class T>
int dreldmap3VMT( Word* args, Word& result, int message,
Word& local, Supplier s ) {
#ifdef DRELDEBUG
cout << "dreldmap3VMT" << endl;
cout << args << 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 resultList;
if( !nl->ReadFromString( funText, resultList ) ) {
resultDFRel->makeUndefined( );
}
bool correct = false;
bool evaluable = false;
bool defined = false;
bool isFunction = false;
std::string typeString, errorString;
Word dmapResult;
if( !QueryProcessor::ExecuteQuery( resultList, 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;
}
#ifdef DRELDEBUG
cout << "Result:" << resultList << endl;
#endif
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<DRel, true>,
dreldmapNewVMT<DFRel, true>
};
/*
1.6 ValueMapping Array for dmap
Used by the operators with a darray and a d[f]rel as input.
*/
ValueMapping dreldmapNew2VM[ ] = {
dreldmapNew2VMT<DRel>,
dreldmapNew2VMT<DFRel>
};
/*
1.8 ValueMapping Array for dmap
Used by the operators with a darray and a d[f]rel as input.
*/
ValueMapping dreldmapNew3VM[ ] = {
dreldmap3VMT<DRel, DRel>,
dreldmap3VMT<DRel, DFRel>,
dreldmap3VMT<DFRel, DRel>,
dreldmap3VMT<DFRel, DFRel>
};
/*
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 windowintersects 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.9.15 Specification of windowintersects2
Operator specification of the windowintersects2 operator.
*/
OperatorSpec windowintersects2Spec(
" darray(rtree(X)) x d[f]rel[X] x Relation(worker)"
"-> dfrel(X) ",
" _ _ _ windowintersects[_]",
"Computes a windowintersects of a darray with an rtree, an "
"d[f]rel, Workers Relation, and a rectangle.",
" query darray1 drel1 Workers windowintersects[rectangle]"
);
/*
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<false>
);
/*
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
);
/*
1.10.15 Operator instance of windowintersects2 operator
*/
Operator windowintersects2Op(
"windowintersects2",
windowintersects2Spec.getStr( ),
2,
dreldmapNew2VM,
dreldmap2Select,
windowintersects2TM
);
} // end of namespace drel