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

1062 lines
30 KiB
C++

/*
----
This file is part of SECONDO.
Copyright (C) 2004-2009, University in Hagen, 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
----
//paragraph [10] title: [{\Large \bf ] [}]
//paragraph [21] table1column: [\begin{quote}\begin{tabular}{l}] [\end{tabular}\end{quote}]
//paragraph [22] table2columns: [\begin{quote}\begin{tabular}{ll}] [\end{tabular}\end{quote}]
//paragraph [23] table3columns: [\begin{quote}\begin{tabular}{lll}] [\end{tabular}\end{quote}]
//paragraph [24] table4columns: [\begin{quote}\begin{tabular}{llll}] [\end{tabular}\end{quote}]
//[TOC] [\tableofcontents]
//[--------] [\hline]
//characters [1] verbatim: [$] [$]
//characters [2] formula: [$] [$]
//characters [3] capital: [\textsc{] [}]
//characters [4] teletype: [\texttt{] [}]
//[ae] [\"a]
//[oe] [\"o]
//[ue] [\"u]
//[ss] [{\ss}]
//[<=] [\leq]
//[#] [\neq]
//[tilde] [\verb|~|]
//[<] [$<$]
//[>] [$>$]
[10] Implementation file of the CEQueryProcessor
2016/2017 H.Brieschke created the new CompiledExpression Algebra
[TOC]
1 Overview
In this file the following 3 classes are implemented.
* CEQRuntimeError
* CEQuery
* CEQueryProcessor
The ~CEQRuntimeError~-class implements ~ERROR~-objects, which are required for the error treatment.
The ~CEQuery~-class implements a data structure in which all information required for the processing
of a data request is stored over the entire working flow.
The ~CEQueryProcessor~-class implements the interface to the ~QueryProcessor~ of the secondo kernel.
2 Defines, includes, and constants
*/
#include <set>
#include <string>
#include <algorithm>
#include <stdlib.h>
#include <fstream>
#include <iostream>
#include "NestedList.h"
#include "ListUtils.h"
#include "LogMsg.h"
#include "Symbols.h"
#include "Trace.h"
#include "StandardTypes.h"
#include "FileSystem.h"
#include "./CEQueryProcessor.h"
#include "./CompiledExpressionsAlgebra.h"
#include "./CECompiler.h"
#include "./CECodeGenerator.h"
extern NestedList* nl;
extern QueryProcessor* qp;
extern AlgebraManager *am;
using namespace std;
typedef Operator* OpPtr;
/*
3 Copied code from the ~QueryProcessor.cpp~-File
The following code has been copied from the ~QueryProcessor.cpp~-File because the
enum ~OpNodeType~ and struct ~OpNode~ is not declared in a header file, but in
the ~QueryProcessor.cpp~-file and the ~QueryProcessor.cpp~-file would be necessary to access
this data structure. Due to this code coupling, however, in return, if the original code is
changed, the following code must also be adapted. The current code is identical to the code
version, which was implemented in January 2017.
3.1 Enum ~OpNodeType~
In addition, the enum ~OpNodeType~ has been copied from the ~QueryProcessor.cpp~-file
because it is not declared in a header file, but in the implementation file.
*/
enum OpNodeType { Pointer, Object, IndirectObject, Operator };
/*
3.2 Struct ~OpNode~
In addition, the struct "OpNode" has been copied from the ~QueryProcessor.cpp~-file because
it is not declared in a header file, but in the implementation file, which means that access
to this data structure would not be possible.
*/
struct OpNode
{
bool evaluable;
ListExpr typeExpr;
ListExpr numTypeExpr;
const OpNodeType nodetype;
int id;
bool isRoot;
ArgVector tmpArg;
struct OpNodeStruct
{
/*
common members of OpNodeDirecObject and OpNodeOperator ~symbol~
common members of OpNodeInDirecObject and OpNodeOperator ~received~
*/
ListExpr symbol;
bool received;
struct OpNodeDirectObject
{
Word value;
int valNo; // needed for testing only
bool isConstant;
bool isModified;
} dobj;
struct OpNodeIndirectObject
{
ArgVectorPointer vector;
int funNumber; /* needed for testing only */
int argIndex;
/*
The three attributes below are used in the case when an
operator has a parameter function which may have streams as
arguments. In this case the operator must
*/
} iobj;
struct OpNodeOperator
{
int algebraId;
int opFunId;
int noSons;
ValueMapping valueMap;
OpPtr theOperator;
ArgVector sons;
ArgVector sonresults;
bool isFun;
ArgVectorPointer funArgs;
int funNo; // needed for testing only
bool isStream;
Word local;
Word local2; // can be used for init/finish messages
int resultAlgId;
int resultTypeId;
Word resultWord;
ObjectDeletion deleteFun; // substitute for the algebras
// delete function
int counterNo;
double selectivity; //these two fields can be used by operators
double predCost; //implementing predicates to get and set
//such properties, e.g. for progress est.
bool supportsProgress;
bool usesMemory; // true if the operator uses a memory buffer
size_t memorySize; // amount of memory assigned to this operator
// in MB
CostEstimation* costEstimation;
bool argsAvailable;
} op;
} u;
};
/*
End of copied code from the ~QueryProcessor.cpp~-File.
*/
using namespace CompiledExpressions;
namespace CompiledExpressions {
/*
4 Class ~CEQRuntimeError~
This class implements ~ERROR~-objects, which are required for the error treatment.
*/
CEQRuntimeError::CEQRuntimeError(std::string s) {
errMsg = s;
}
const char*
CEQRuntimeError::what() const throw() {
return errMsg.c_str();
}
/*
5 Class ~CEQuery~
This class implements a data structure in which all information required for the processing
of a data request is stored over the entire working flow. For each query, a new object will
be created which will be deleted after completion of the query processing.
5.1 The Constructor
*/
CEQuery::CEQuery(bool use)
: ptrQP(0),
ptrCEQP(0),
useCEQP(use),
delTempFiles(true),
isGeneratedQuery(false),
ptrCodeGenVisitor(new CECOpTreeVisitorGenerateCode()),
ceLibrary(new DynamicLibrary()),
ptrFuncCloseCELib(0) {
FuncPtrGetUseCEQP = &CEQuery::getUseCEQP;
FuncPtrSetPtrQueryProcessors = &CEQuery::setPtrQueryProcessors;
if (use) {
std::string cfgFileName = FileSystem::GetCurrentFolder();
FileSystem::AppendItem(cfgFileName, "..");
FileSystem::AppendItem(cfgFileName, "Algebras");
FileSystem::AppendItem(cfgFileName, "CompiledExpressions");
FileSystem::AppendItem(cfgFileName, "CEARunTime.cfg");
if (FileSystem::FileOrFolderExists(cfgFileName)) {
std::string line;
std::ifstream cfgFileStream;
bool foundUseCEQP, foundDeleteTempFiles;
foundUseCEQP = foundDeleteTempFiles = false;
cfgFileStream.open(cfgFileName.c_str(), ios::in);
while (!cfgFileStream.eof()
&& !(foundUseCEQP && foundDeleteTempFiles)) {
getline(cfgFileStream, line);
if (!foundUseCEQP && line.find("usedCEA=") == 0) {
if (line.substr(8, 5) == "FALSE"
|| line.substr(8, 5) == "false")
useCEQP = false;
else
useCEQP = true;
foundUseCEQP = true;
}
if (!foundDeleteTempFiles
&& line.find("deleteTempFiles=") == 0) {
if (line.substr(16, 5) == "FALSE"
|| line.substr(16, 5) == "false")
delTempFiles = false;
else
delTempFiles = true;
foundDeleteTempFiles = true;
}
}
cfgFileStream.close();
if (!foundUseCEQP)
useCEQP = true;
if (!foundDeleteTempFiles)
delTempFiles = true;
}
}
}
/*
5.2 The Destructor
*/
CEQuery::~CEQuery() {
if (ptrFuncCloseCELib)
ptrFuncCloseCELib();
if (ceLibrary)
delete ceLibrary;
if (ptrCodeGenVisitor)
delete ptrCodeGenVisitor;
mapResultTypes.clear();
FileSystem::SetCurrentFolder(currentPath);
if (delTempFiles)
FileSystem::EraseFolder(codeGenPath);
}
/*
5.3 Function ~setPtrQueryProcessors~
A ~set~-function for the pointers of the Secondo-~QueryProcessor~ and the ~CEQueryProcessor~.
*/
void
CEQuery::setPtrQueryProcessors(QueryProcessor* _ptrQP,
CEQueryProcessor* _ptrCEQP) {
ptrQP = _ptrQP;
ptrCEQP = _ptrCEQP;
}
/*
5.4 Function ~getPtrQP~
A ~get~-function for the pointers of the Secondo-~QueryProcessor~.
*/
QueryProcessor*
CEQuery::getPtrQP() {
return ptrQP;
}
/*
5.5 Function ~getPtrCEQP~
A ~get~-function for the pointers of the ~CEQueryProcessor~.
*/
CEQueryProcessor*
CEQuery::getPtrCEQP() {
return ptrCEQP;
}
/*
5.6 Function ~setCompilePath~
A ~set~-function for the path of the actual working directory and the directory
in that the code are generated and the shared library are generated.
*/
void
CEQuery::setCompilePath(std::string current, std::string codeGen) {
currentPath = current;
codeGenPath = codeGen;
}
/*
5.7 Function ~getCurrentPath~
A ~get~-function returned the name of the actual working directory.
*/
std::string
CEQuery::getCurrentPath() {
return currentPath;
}
/*
5.8 Function ~getCurrentPath~
A ~get~-function returned the name of the directory in which the code are
generated and the shared library are generated.
*/
std::string
CEQuery::getCodeGenPath() {
return codeGenPath;
}
/*
5.9 Function ~setGeneratedQuery~
This ~set~-function is called when the shared library is created successfully.
*/
void
CEQuery::setGeneratedQuery() {
isGeneratedQuery = true;
}
/*
5.10 Function ~getGeneratedQuery~
A ~get~-function returned if the shared library is created successfully.
*/
bool
CEQuery::getGeneratedQuery() {
return isGeneratedQuery;
}
/*
5.11 Function ~getUseCEQP~
A ~get~-function returned whether the functionality of the ~CEQueryProcessor~
should be used.
*/
bool
CEQuery::getUseCEQP() {
return useCEQP;
}
/*
5.12 Function ~getCodeGenVisitor~
A ~get~-function returned a ~CECOpTreeVisitorGenerateCode~-object.
*/
CECOpTreeVisitorGenerateCode&
CEQuery::getCodeGenVisitor() {
return *(ptrCodeGenVisitor);
}
/*
5.13 Function ~getPtrCEQYLibrary~
A ~get~-function returned a pointer to the ~DynamicLibrary~-object, which
handles the generated shared library.
*/
DynamicLibrary*
CEQuery::getPtrCEQYLibrary() {
if (!ceLibrary)
ceLibrary = new DynamicLibrary();
return ceLibrary;
}
/*
5.14 Function ~setFuncCloseCompiledExpressionsLib~
A ~set~-function for the function pointer of the function that is called
to close the generated shared library.
*/
void
CEQuery::setFuncCloseCompiledExpressionsLib(void*& ptrFunction) {
ptrFuncCloseCELib = (FuncCloseCompiledExpressionsLib_t) ptrFunction;
}
/*
5.15 Function ~addMapResultTypes~
This function creates a map in which the nested list is assigned the return type
for each node key in the operator tree from the ~CECompiler~.
*/
void
CEQuery::addMapResultTypes(std::string ceNodeKey, ListExpr list) {
mapResultTypes[ceNodeKey] = list;
}
/*
5.16 Function ~getMapResultTypes~
A ~get~-function returned the nested list is assigned the return type for
the given node key. If the node key not found, returned an empty list.
*/
ListExpr
CEQuery::getMapResultTypes(std::string ceNodeKey) {
std::map<std::string, ListExpr>::const_iterator it;
it = mapResultTypes.find(ceNodeKey);
if (it != mapResultTypes.end())
return it->second;
else
return nl->TheEmptyList();
}
/*
6 Class ~CEQueryProcessor~
This class implements the interface to the original ~QueryProcessor~ of the secondo kernel.
Here, all functions that are required for the functionality of the ~Compiled Expressions Algebra~
and which have not yet existed or whose functionality had to be changed or extended.
6.1 The Constructor
*/
CEQueryProcessor::CEQueryProcessor(QueryProcessor* _ptrQP)
: ptrQP(_ptrQP) {
FuncPtrTestOverloadedOperators =
&CEQueryProcessor::TestOverloadedOperators;
FuncPtrGenerateApplyopList =
&CEQueryProcessor::generateApplyopList;
FuncPtrGenerateCompiledExpressions =
&CEQueryProcessor::GenerateCompiledExpressions;
}
/*
6.2 Function ~isCEAlgebra~
This function returns whether the passed ~algID~ is that of
the ~CompiledExpressionsAlgebra~.
*/
bool
CEQueryProcessor::isCEAlgebra( int algID) {
int ceAlgebraID = am->GetAlgebraId("CompiledExpressionsAlgebra");
if ((am->IsAlgebraLoaded(ceAlgebraID)) && (ceAlgebraID == algID)) {
return true;
} else {
return false;
}
}
/*
6.3 Function ~getMainTypesAsString~
This function extracts the main type from the given type in the nested list ~args~.
This function is also copied from the ~QueryProcessor.cpp~-file. The reasons are the
same as indicated above for enum ~OpNodeType~ and struct ~OpNode~. Thus, here too,
a possible change of code in the ~QueryProcessor.cpp~-file must be added here.
*/
std::string
CEQueryProcessor::getMainTypesAsString(ListExpr args){
if(nl->AtomType(args)!=NoAtom){
return "invalid type list";
}
std::stringstream ss;
ss << "(";
bool first = true;
while(!nl->IsEmpty(args)){
if(!first) ss << ", ";
ListExpr arg = nl->First(args);
args = nl->Rest(args);
while(nl->AtomType(arg)==NoAtom && !nl->IsEmpty(arg)){
arg = nl->First(arg);
}
ss << nl->ToString(arg);
first = false;
}
ss << ")";
return ss.str();
}
/*
6.4 Function ~TestOverloadedOperators~
This function test all possible type mappings for overloaded operators.
In contrast to the original function in the ~QueryProcessor.cpp~-file, the function
no longer breaks after the first hit, but instead searches for an operator from
the ~Compiled Expressions Algebra~.
*/
ListExpr
CEQueryProcessor::TestOverloadedOperators(
const std::string& operatorSymbolStr,
ListExpr opList,
ListExpr typeList,
ListExpr typeArgList,
int& alId,
int& opId,
int& opFunId,
bool checkFunId,
bool traceMode,
ListExpr& resultAlgList,
ListExpr& resultFunIdList,
CEQuery* ptrCEQY) {
if (!ptrCEQY->getUseCEQP()) {
return ptrCEQY->getPtrQP()->TestOverloadedOperators(operatorSymbolStr,
opList,
typeList,
typeArgList,
alId,
opId,
opFunId,
checkFunId,
traceMode);
} else if (!CompiledExpressionsAlgebra::isActiv()) {
return ptrCEQY->getPtrQP()->TestOverloadedOperators(operatorSymbolStr,
opList,
typeList,
typeArgList,
alId,
opId,
opFunId,
checkFunId,
traceMode);
} else {
ListExpr resultTypeOrigOp = nl->TheEmptyList();
ListExpr resultTypeCEAlgOp = nl->TheEmptyList();
ListExpr resultType = nl->TheEmptyList();
ListExpr origAlgOpList = nl->TheEmptyList();
ListExpr ceaAlgOpList = nl->TheEmptyList();
bool foundOrigOp = false;
bool foundCEAOp = false;
int selFunIdxOrigOp = -1;
static const int width=70;
static const std::string sepLine = "\n" + std::string(width,'-') + "\n";
if ( traceMode ) {
cout << sepLine
<< "Type mapping for operator " << operatorSymbolStr << ": "
<< NList(opList).convertToString() << endl;
}
std::string typeErrorMsg =
"Type map error for operator " + operatorSymbolStr + "!"
+ sepLine
+ wordWrap("Input: ", width, NList(typeList).convertToString())
+ sepLine
+ wordWrap("Short: ", width, getMainTypesAsString(typeList))
+ sepLine + "Error Message(s):" + sepLine;
do { // Overloading: test operator candidates
resultType = nl->TheEmptyList();
alId = nl->IntValue( nl->First( nl->First( opList ) ) );
opId = nl->IntValue( nl->Second( nl->First( opList ) ) );
/*
apply the operator's type mapping:
(i) standard case: pass the list of types
(ii) special case: pass the list of pairs (type, argument)
This is for operators who need to see argument expressions within the type mapping,
for example, a filename passed as a string, to get some type information from the
file. This case applies if the operator has registered "UsesArgumentsInTypeMapping".
It is demonstrated with the filter operator in the relation algebra.
*/
if ( !am->getOperator( alId, opId )->UsesArgsInTypeMapping() ) {
resultType = am->TransformType( alId, opId, typeList );
} else {
resultType = am->TransformType( alId, opId, typeArgList );
}
std::string algName = am->GetAlgebraName(alId);
if(traceMode) {
std::stringstream traceMsg;
traceMsg << algName << ": " << operatorSymbolStr << " (algId="
<< alId << ", opId=" << opId << ") "<< std::ends;
if( nl->IsEqual( resultType, "typeerror" ) )
cout << traceMsg.str() << "rejected!" << endl;
else
cout << traceMsg.str() << "accepted!" << endl;
}
bool excluded = am->getOperator(alId,opId)->isExcluded();
if(excluded) {
resultType = nl->TypeError();
std::string msg = "";
ErrorReporter::GetErrorMessage(msg);
ErrorReporter::ReportError("operator has been excluded (no example)");
}
if ( !ErrorReporter::TypeMapError ) {
std::string msg = "";
ErrorReporter::GetErrorMessage(msg);
// remove errors produced by testing operators
if ( msg == "" )
msg = "<No error message specified>";
typeErrorMsg += wordWrap(algName + ": ",4 ,width, msg) + "\n";
}
opList = nl->Rest( opList );
// end of the original while-loop
if (nl->IsEmpty( opList ) ||
!nl->IsEqual( resultType, "typeerror" )) {
/*
check if the final result of testing is still a typeerror.
If so save the messages in the error reporter. Errors detected
afterwards will not be reported any more.
*/
int selFunIndex=-1;
if ( nl->IsEmpty( opList ) && nl->IsEqual( resultType, "typeerror" )
&& !foundOrigOp ) {
if(!ErrorReporter::TypeMapError){
ErrorReporter::ReportError(typeErrorMsg + sepLine);
}
ErrorReporter::TypeMapError = true;
} else {
/*
use the operator's selection function to get the index
(opFunId) of the evaluation function for this operator:
*/
if ( checkFunId ) {
selFunIndex = am->Select( alId, opId, typeList );
opFunId = selFunIndex * 65536 + opId;
/*
Check whether this is a type operator; in that case
opFunId will be negative. A type operator does only a type
mapping, nothing else; hence it is wrong here and we return
type error.
*/
if ( opFunId < 0 )
resultType = nl->SymbolAtom( "typeerror" );
}
if ( isCEAlgebra(alId)) {
if ( !foundCEAOp ) {
ceaAlgOpList = nl->TwoElemList(nl->IntAtom( alId ),
nl->IntAtom( opFunId ));
resultTypeCEAlgOp = resultType;
foundCEAOp = true;
}
} else {
if ( !foundOrigOp ) {
origAlgOpList = nl->TwoElemList(nl->IntAtom( alId ),
nl->IntAtom( opFunId ));
selFunIdxOrigOp = selFunIndex;
resultTypeOrigOp = resultType;
foundOrigOp = true;
}
}
}
}
} while ( !nl->IsEmpty(opList) && (!foundOrigOp || !foundCEAOp));
if (traceMode) {
cout << wordWrap( "IN: ",
width, NList(typeList).convertToString() )
<< endl
<< wordWrap( "OUT-OrigOP: ",
width, NList(resultTypeOrigOp).convertToString() )
<< endl
<< wordWrap( "OUT-CEAOP: ",
width, NList(resultTypeCEAlgOp).convertToString() )
<< endl
<< "SelectionFunction: index = " << selFunIdxOrigOp << endl
<< sepLine << endl;
}
if ((foundOrigOp && foundCEAOp) &&
nl->Equal(resultTypeOrigOp, resultTypeCEAlgOp)) {
resultAlgList = nl->TwoElemList(nl->First(origAlgOpList),
nl->First(ceaAlgOpList));
resultFunIdList = nl->TwoElemList(nl->Second(origAlgOpList),
nl->Second(ceaAlgOpList));
resultType = resultTypeOrigOp;
} else if (foundOrigOp && !foundCEAOp) {
resultAlgList = nl->TwoElemList(nl->First(origAlgOpList),
nl->TheEmptyList());
resultFunIdList = nl->TwoElemList(nl->Second(origAlgOpList),
nl->TheEmptyList());
resultType = resultTypeOrigOp;
} else {
resultAlgList = nl->TwoElemList(nl->IntAtom( alId ),
nl->TheEmptyList());
resultFunIdList = nl->TwoElemList(nl->IntAtom( opId ),
nl->TheEmptyList());
}
return resultType;
}
}
/*
6.5 Function ~generateApplyopList~
This function adapted ~generateApplyopList~-functionality included in
the ~Secondo QueryProcessor Annotate~-function.
In this case, the structure of the annotated list is changed to a form containing
further necessary information for the ~CECompiler~ of the ~Compiled Expressions Algebra~.
The change refers to the ~operator~-list and the ~applyop~-list.
In the ~operator~-list, the atom ~operator-ID~ and ~algebra-ID~ are replaced by a two element
list, whose first atom is the ~operator-ID~ or ~algebra-ID~ of the original operator and the
second atom is the ~operator-ID~ or ~algebra-ID~ of the operator from
the ~Compiled Expressions Algebra~. The replacement in the ~applyop~-list for the ~opFun-ID~
is done. So instead of the ~operator~-list
----
((<name> operator <opID> <algID>) typeerror)
----
this list is created
----
((<name> operator ((<opID origOp>) (<opID ceaOp>)) ((<algID origAlg>) (<algID ceaAlg>)) typeerror)
----
The ~applyop~-list is created instead
---- ((none applyop (ann(op) ann(arg1) ... ann(argn)))
<resulttype>
<opFunId>)
----
this list is created
---- ((none applyop (ann(op) ann(arg1) ... ann(argn)))
<resulttype>
((<opFunID orig>) (<opFunID cea>)))
----
*/
void
CEQueryProcessor::generateApplyopList(
ListExpr& applyopList,
ListExpr first,
ListExpr list,
ListExpr resultAlgList,
ListExpr resultFunIdList,
ListExpr resultType) {
if (CompiledExpressionsAlgebra::isActiv()) {
ListExpr tmpFunIdListOperator = nl->TwoElemList(
nl->First(resultFunIdList),
nl->Second(resultFunIdList));
ListExpr tmpFunIdListApplyop = nl->TwoElemList(
nl->First(resultFunIdList),
nl->Second(resultFunIdList));
ListExpr newList = nl->Cons(
nl->TwoElemList(
nl->FourElemList(
nl->First(first),
nl->Second(first),
resultAlgList,
tmpFunIdListOperator),
nl->Second(nl->First(list))),
nl->Rest(list));
applyopList = nl->ThreeElemList(
nl->ThreeElemList(
nl->SymbolAtom("none"),
nl->SymbolAtom("applyop"),
newList),
resultType,
tmpFunIdListApplyop);
}
}
/*
6.6 Function ~GenerateCompiledExpressions~
This function calls the ~CECompiler~ to create the shared library with
the compiled query.
*/
void
CEQueryProcessor::GenerateCompiledExpressions(
CEQuery* ptrCEQY,
ListExpr& list) {
if (ptrCEQY && ptrCEQY->getUseCEQP()) {
CECompiler::getInstance()->ceGenerateQuery(list, ptrCEQY);
}
}
/*
6.7 Function ~getQPDebugMode~
This function returns whether the debug mode is set.
*/
bool
CEQueryProcessor::getQPDebugMode() {
return ptrQP->getDebugMode();
}
/*
6.7 Function ~getQPTraceMode~
This function returns whether the trace mode is set.
*/
bool
CEQueryProcessor::getQPTraceMode() {
return ptrQP->getTraceMode();
}
/*
6.7 Function ~loadCompiledExpressions~
This function loaded the generated shared library.
*/
void
CEQueryProcessor::loadCompiledExpressions(std::string libName,
CEQuery* ptrCEQY)
/*throw (CEQRuntimeError)*/ {
bool loadOK = false;
if (ptrCEQY) {
if (ptrCEQY->getPtrCEQYLibrary()->Load(libName)) {
void* ptrFuncInit = ptrCEQY->getPtrCEQYLibrary()
->GetFunctionAddress("initCompiledExpressionsLib");
void* ptrFuncClose = ptrCEQY->getPtrCEQYLibrary()
->GetFunctionAddress("closeCompiledExpressionsLib");
if (ptrFuncInit && ptrFuncClose) {
ptrCEQY->setFuncCloseCompiledExpressionsLib(ptrFuncClose);
FuncInitCompiledExpressionsLib_t initCELib =
(FuncInitCompiledExpressionsLib_t) ptrFuncInit;
if (initCELib(ptrCEQY))
loadOK = true;
}
}
}
if (!loadOK) {
cout << "Error by loading CompiledExpression-Library." << endl;
throw CEQRuntimeError("Error by loading CompiledExpression-Library.");
}
}
/*
6.7 Function ~createLibFunctionAddressNList~
The function generates a list that contains the memory address of the functions
to be called by the operators in the generated shared library.
*/
bool
CEQueryProcessor::createLibFunctionAddressNList
(ListExpr& ptrListFunction,
ListExpr& returnType,
const std::string& functionName,
CEQuery* ptrCEQY) {
bool retValue = false;
if (ptrCEQY) {
if(ptrCEQY->getPtrCEQYLibrary()->IsLoaded()) {
void* ptr = ptrCEQY->getPtrCEQYLibrary()
->GetFunctionAddress(functionName);
if (ptr) {
NameIndex varnames;
VarEntryTable vartable;
bool defined = true;
ListExpr ptrList = listutils::getPtrList(ptr);
ListExpr ptrAnnList = nl->TwoElemList(
returnType,
nl->TwoElemList(
nl->SymbolAtom("ptr"),
ptrList));
ptrListFunction = ptrQP->Annotate(ptrAnnList,
varnames,
vartable,
defined,
nl->TheEmptyList(),
nl->TheEmptyList());
retValue = true;
}
}
}
return retValue;
}
/*
6.7 Function ~getQPValues~
This function returns the value with the index ~idx~ from the ~Secondo QueryProcessor~.
*/
Word
CEQueryProcessor::getQPValues(unsigned int idx) {
if (idx < ptrQP->getValues().size())
return ptrQP->getValues()[idx].value;
else
return SetWord(Address(0));
}
/*
6.7 Function ~qpResultStorage~
This function returns the result storage from the given supplier ~s~.
*/
Word
CEQueryProcessor::qpResultStorage(const Supplier s) {
return ptrQP->ResultStorage(s);
}
/*
6.7 Function ~IsPointerNode~
This function checks if the given supplier ~s~ a pointer node in the
operator tree.
*/
bool
CEQueryProcessor::IsPointerNode( const Supplier s ) const {
OpTree tree = static_cast<OpTree>( s );
return tree->nodetype == Pointer;
}
/*
6.8 Function ~GetTupleResultType~
A ~get~-function returned the nested list is assigned the return type for
the given node key.
*/
ListExpr
CEQueryProcessor::GetTupleResultType(std::string ceNodeKey,
CEQuery* ceQY) {
ListExpr tmpReturnTypeList = ceQY->getMapResultTypes(ceNodeKey);
if (nl->IsEmpty(tmpReturnTypeList))
return tmpReturnTypeList;
else
return SecondoSystem::GetCatalog()->NumericType(tmpReturnTypeList);
}
} // end of namespace CompiledExpressions
/*
7 External call functions
*/
#ifdef __cplusplus
extern "C"{
#endif
/*
7.1 Function ~FuncCEQYGetNewInstance~
This external call function generate a new ~CEQuery~-object and returned
a pointer of them.
*/
CompiledExpressions::CEQuery*
FuncCEQYGetNewInstance(bool useCEQP) {
return new CompiledExpressions::CEQuery(useCEQP);
}
/*
7.2 Function ~FuncCEQPGetNewInstance~
This external call function generate a new ~CEQueryProcessor~-object and
returned a pointer of them.
*/
CompiledExpressions::CEQueryProcessor*
FuncCEQPGetNewInstance(QueryProcessor* ptrQP) {
return new CEQueryProcessor(ptrQP);
}
#ifdef __cplusplus
}
#endif