Skip to content

Commit

Permalink
Merge pull request #192 from floriankramer/fix_patterns_single_entity
Browse files Browse the repository at this point in the history
Implemented the missing support for counting the predicates of a sing…
  • Loading branch information
niklas88 committed Feb 17, 2019
2 parents 765c9e2 + d67a6f6 commit 7520920
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 9 deletions.
13 changes: 13 additions & 0 deletions e2e/scientists_queries.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -549,4 +549,17 @@ queries:
- selected: ["?p", "?count"]
- contains_row: ["<Film_appeared_in>", 56]
- contains_row: ["<Patent>", 2]
- query : count-available-predicates-on-single-entity
type: no-text
sparql: |
SELECT ?p (COUNT(?p) as ?count) WHERE {
<Albert_Einstein> ql:has-predicate ?p .
}
GROUP BY ?p
checks:
- num_rows: 35
- num_cols: 2
- selected: ["?p", "?count"]
- contains_row: ["<Hall_of_fame_induction>", 1]
- contains_row: ["<Weight>", 1]

32 changes: 28 additions & 4 deletions src/engine/CountAvailablePredicates.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ CountAvailablePredicates::CountAvailablePredicates(QueryExecutionContext* qec)
: Operation(qec),
_subtree(nullptr),
_subjectColumnIndex(0),
_subjectEntityName(),
_predicateVarName("predicate"),
_countVarName("count") {}

Expand All @@ -19,6 +20,16 @@ CountAvailablePredicates::CountAvailablePredicates(
: Operation(qec),
_subtree(subtree),
_subjectColumnIndex(subjectColumnIndex),
_subjectEntityName(),
_predicateVarName("predicate"),
_countVarName("count") {}

CountAvailablePredicates::CountAvailablePredicates(QueryExecutionContext* qec,
std::string entityName)
: Operation(qec),
_subtree(nullptr),
_subjectColumnIndex(0),
_subjectEntityName(entityName),
_predicateVarName("predicate"),
_countVarName("count") {}

Expand All @@ -28,11 +39,13 @@ string CountAvailablePredicates::asString(size_t indent) const {
for (size_t i = 0; i < indent; ++i) {
os << " ";
}
if (_subtree != nullptr) {
if (_subjectEntityName) {
os << "COUNT_AVAILABLE_PREDICATES for " << _subjectEntityName.value();
} else if (_subtree == nullptr) {
os << "COUNT_AVAILABLE_PREDICATES for all entities.";
} else {
os << "COUNT_AVAILABLE_PREDICATES (col " << _subjectColumnIndex << ")\n"
<< _subtree->asString(indent);
} else {
os << "COUNT_AVAILABLE_PREDICATES for all entities.";
}
return os.str();
}
Expand Down Expand Up @@ -124,7 +137,18 @@ void CountAvailablePredicates::computeResult(ResultTable* result) {
const CompactStringVector<size_t, Id>& patterns =
_executionContext->getIndex().getPatterns();

if (_subtree == nullptr) {
if (_subjectEntityName) {
runtimeInfo.setDescriptor("CountAvailablePredicates for a single entity.");
size_t entityId;
// If the entity exists return the all predicates for that entitity,
// otherwise return an empty result.
if (getIndex().getVocab().getId(_subjectEntityName.value(), &entityId)) {
std::vector<array<Id, 1>> input = {{entityId}};
CountAvailablePredicates::computePatternTrick<array<Id, 1>>(
&input, static_cast<vector<array<Id, 2>>*>(result->_fixedSizeData),
hasPattern, hasPredicate, patterns, 0, &runtimeInfo);
}
} else if (_subtree == nullptr) {
runtimeInfo.setDescriptor("CountAvailablePredicates for all entities");
// Compute the predicates for all entities
CountAvailablePredicates::computePatternTrickAllEntities(
Expand Down
8 changes: 8 additions & 0 deletions src/engine/CountAvailablePredicates.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ class CountAvailablePredicates : public Operation {
std::shared_ptr<QueryExecutionTree> subtree,
size_t subjectColumnIndex);

/**
* @brief Creates a new CountAvailblePredicates operation that returns
* predicates and their counts for the entity given by the entityName.
*/
CountAvailablePredicates(QueryExecutionContext* qec, std::string entityName);

virtual string asString(size_t indent = 0) const override;

virtual size_t getResultWidth() const override;
Expand Down Expand Up @@ -100,6 +106,8 @@ class CountAvailablePredicates : public Operation {
private:
std::shared_ptr<QueryExecutionTree> _subtree;
size_t _subjectColumnIndex;
// This can be used to aquire the predicates for a single entity
std::optional<std::string> _subjectEntityName;
std::string _predicateVarName;
std::string _countVarName;

Expand Down
28 changes: 23 additions & 5 deletions src/engine/QueryPlanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -455,12 +455,15 @@ vector<QueryPlanner::SubtreePlan> QueryPlanner::getDistinctRow(
vector<QueryPlanner::SubtreePlan> QueryPlanner::getPatternTrickRow(
const ParsedQuery& pq, const vector<vector<SubtreePlan>>& dpTab,
const SparqlTriple& patternTrickTriple) const {
const vector<SubtreePlan>& previous = dpTab[dpTab.size() - 1];
const vector<SubtreePlan>* previous = nullptr;
if (!dpTab.empty()) {
previous = &dpTab.back();
}
vector<SubtreePlan> added;
if (previous.size() > 0) {
added.reserve(previous.size());
for (size_t i = 0; i < previous.size(); ++i) {
const SubtreePlan& parent = previous[i];
if (previous != nullptr && !previous->empty()) {
added.reserve(previous->size());
for (size_t i = 0; i < previous->size(); ++i) {
const SubtreePlan& parent = (*previous)[i];
// Determine the column containing the subjects for which we are
// interested in their predicates.
auto it =
Expand Down Expand Up @@ -506,6 +509,21 @@ vector<QueryPlanner::SubtreePlan> QueryPlanner::getPatternTrickRow(
countPred);
added.push_back(patternTrickPlan);
}
} else if (patternTrickTriple._s[0] != '?') {
// The subject of the pattern trick is not a variable
SubtreePlan patternTrickPlan(_qec);
std::shared_ptr<Operation> countPred(
new CountAvailablePredicates(_qec, patternTrickTriple._s));

static_cast<CountAvailablePredicates*>(countPred.get())
->setVarNames(patternTrickTriple._o, pq._aliases[0]._outVarName);
QueryExecutionTree& tree = *patternTrickPlan._qet.get();
tree.setVariableColumns(
static_cast<CountAvailablePredicates*>(countPred.get())
->getVariableColumns());
tree.setOperation(QueryExecutionTree::COUNT_AVAILABLE_PREDICATES,
countPred);
added.push_back(patternTrickPlan);
} else {
// Use the pattern trick without a subtree
SubtreePlan patternTrickPlan(_qec);
Expand Down

0 comments on commit 7520920

Please sign in to comment.