Files
secondo/Algebras/DRel/dreldmap.cpp

2260 lines
66 KiB
C++
Raw Normal View History

2026-01-23 17:03:45 +08:00
/*
----
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<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 << "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<Stream<Tuple> >( ),
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<DFRel>( ),
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<Stream<Tuple> >( ),
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<Relation>( ),
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<DFRel>( ),
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<Stream<Tuple> >( ),
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<Relation>( ),
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<DFRel>( ),
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<Stream<Tuple> >( ),
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<Relation>( ),
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<DFRel>( ),
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<DFRel>( ),
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<Stream<Tuple> >( ),
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<Relation>( ),
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<DFRel>( ),
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<DFRel>( ),
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<DFRel>( ),
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<bool global>
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<Stream<Tuple> >( ),
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<Relation>( ),
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<DFRel>( ),
relType,
distType );
ListExpr append = nl->TwoElemList(
nl->TextAtom( funText1 ),
nl->TextAtom( funText2 ) );
return nl->ThreeElemList(
nl->SymbolAtom( Symbols::APPEND( ) ),
append,
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 << "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<Stream<Tuple> >( ),
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<DFRel>( ),
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<DFRel>( ),
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<DFRel>( ),
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<DFRel>( ),
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<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.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;
#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<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 << "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<class R, class T>
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<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 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<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
);
} // end of namespace drel