Skip to content

Commit

Permalink
Implemented the changes requested in the review.
Browse files Browse the repository at this point in the history
  • Loading branch information
floriankramer committed Aug 31, 2018
1 parent a302e0d commit 7411d12
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 36 deletions.
81 changes: 46 additions & 35 deletions src/engine/QueryPlanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ QueryExecutionTree QueryPlanner::createExecutionTree(ParsedQuery& pq) const {
<< std::endl;

// Look for ql:has-predicate to determine if the pattern trick should be used.
// If the pattern trick is used the has predicate triple will be removed from
// the list of where clause triples.
// If the pattern trick is used the ql:has-predicate triple will be removed
// from the list of where clause triples.
SparqlTriple patternTrickTriple("", "", "");
bool usePatternTrick = checkUsePatternTrick(pq, patternTrickTriple);
bool usePatternTrick = checkUsePatternTrick(pq, &patternTrickTriple);

bool doGrouping = pq._groupByVariables.size() > 0 || usePatternTrick;
if (!doGrouping) {
Expand Down Expand Up @@ -408,18 +408,20 @@ QueryExecutionTree QueryPlanner::createExecutionTree(ParsedQuery& pq) const {
}

bool QueryPlanner::checkUsePatternTrick(
ParsedQuery& pq, SparqlTriple& patternTrickTriple) const {
ParsedQuery& pq, SparqlTriple* patternTrickTriple) const {
bool usePatternTrick = false;
// Check if the query has the right number of variables for aliases and group
// by.
if (pq._groupByVariables.size() == 1 && pq._aliases.size() == 1) {
const ParsedQuery::Alias& alias = pq._aliases.back();
// Create a lower case version of the aliases function string to allow
// for case insensitive keyword detection.
std::string aliasFunctionLower =
ad_utility::getLowercaseUtf8(alias._function);
// Check if the alias is a non distinct count alias
if (alias._isAggregate &&
alias._function.find("DISTINCT") == std::string::npos &&
alias._function.find("distinct") == std::string::npos &&
(ad_utility::startsWith(alias._function, "COUNT") ||
ad_utility::startsWith(alias._function, "count"))) {
aliasFunctionLower.find("distinct") == std::string::npos &&
ad_utility::startsWith(aliasFunctionLower, "count")) {
// look for a HAS_RELATION_PREDICATE triple
for (size_t i = 0; i < pq._rootGraphPattern._whereClauseTriples.size();
i++) {
Expand All @@ -440,10 +442,10 @@ bool QueryPlanner::checkUsePatternTrick(
break;
}
}
// Check for triples containing the has predicates triples object.
// Check for triples containing the ql:has-predicate triple's object.
for (size_t j = 0;
j < pq._rootGraphPattern._whereClauseTriples.size() &&
usePatternTrick;
usePatternTrick &&
j < pq._rootGraphPattern._whereClauseTriples.size();
j++) {
const SparqlTriple& other =
pq._rootGraphPattern._whereClauseTriples[j];
Expand All @@ -452,40 +454,49 @@ bool QueryPlanner::checkUsePatternTrick(
usePatternTrick = false;
}
}
// Check for filters on the has predicate triples subject or object
for (const SparqlFilter& filter : pq._rootGraphPattern._filters) {
if (filter._lhs == t._o || filter._lhs == t._s ||
filter._rhs == t._o || filter._rhs == t._s) {
usePatternTrick = false;
break;
// Don't run any more checks if we already determined that the pattern
// trick is not going to be used.
if (usePatternTrick) {
// Check for filters on the ql:has-predicate triple's subject or
// object
for (const SparqlFilter& filter : pq._rootGraphPattern._filters) {
if (filter._lhs == t._o || filter._lhs == t._s ||
filter._rhs == t._o || filter._rhs == t._s) {
usePatternTrick = false;
break;
}
}
}
// Check for optional parts containing the has predicate triples
// object
std::vector<const ParsedQuery::GraphPattern*> graphsToProcess;
graphsToProcess.insert(graphsToProcess.end(),
pq._rootGraphPattern._children.begin(),
pq._rootGraphPattern._children.end());
while (!graphsToProcess.empty()) {
const ParsedQuery::GraphPattern* pattern = graphsToProcess.back();
graphsToProcess.pop_back();
// Don't run any more checks if we already determined that the pattern
// trick is not going to be used.
if (usePatternTrick) {
// Check for optional parts containing the ql:has-predicate triple's
// object
std::vector<const ParsedQuery::GraphPattern*> graphsToProcess;
graphsToProcess.insert(graphsToProcess.end(),
pattern->_children.begin(),
pattern->_children.end());
for (const SparqlTriple& other : pattern->_whereClauseTriples) {
if (other._s == t._o || other._p == t._o || other._o == t._o) {
usePatternTrick = false;
pq._rootGraphPattern._children.begin(),
pq._rootGraphPattern._children.end());
while (!graphsToProcess.empty()) {
const ParsedQuery::GraphPattern* pattern = graphsToProcess.back();
graphsToProcess.pop_back();
graphsToProcess.insert(graphsToProcess.end(),
pattern->_children.begin(),
pattern->_children.end());
for (const SparqlTriple& other : pattern->_whereClauseTriples) {
if (other._s == t._o || other._p == t._o || other._o == t._o) {
usePatternTrick = false;
break;
}
}
if (!usePatternTrick) {
break;
}
}
if (!usePatternTrick) {
break;
}
}
if (usePatternTrick) {
LOG(DEBUG) << "Using the pattern trick to answer the query."
<< endl;
patternTrickTriple = t;
*patternTrickTriple = t;
// remove the triple from the graph
pq._rootGraphPattern._whereClauseTriples.erase(
pq._rootGraphPattern._whereClauseTriples.begin() + i);
Expand Down
14 changes: 13 additions & 1 deletion src/engine/QueryPlanner.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,18 @@ class QueryPlanner {
SubtreePlan getTextLeafPlan(const TripleGraph::Node& node) const;

SubtreePlan optionalJoin(const SubtreePlan& a, const SubtreePlan& b) const;

/**
* @brief Determines if the pattern trick (and in turn the
* CountAvailablePredicates operation) are applicable to the given
* parsed query. If a has predicate triple is found and
* CountAvailblePredicates can be used for it the triple is removed from the
* parsed query.
* @param pq The parsed query.
* @param patternTrickTriple An output parameter in which the triple that
* satisfies the requirements for the pattern trick is stored.
* @return True if the pattern trick should be used.
*/
bool checkUsePatternTrick(ParsedQuery& pq,
SparqlTriple& patternTrickTriple) const;
SparqlTriple* patternTrickTriple) const;
};

0 comments on commit 7411d12

Please sign in to comment.