diff --git a/src/engine/Describe.cpp b/src/engine/Describe.cpp index 51902d2340..83c836e688 100644 --- a/src/engine/Describe.cpp +++ b/src/engine/Describe.cpp @@ -46,7 +46,10 @@ string Describe::getCacheKeyImpl() const { // Add the names of the default graphs (from the FROM clauses) to the cache // key, in a deterministic order. // - // TODO: What about the FROM NAMED clauses? + // NOTE: The default and named graphs are also part of the cache key of the + // `subtree_`. However, the named graphs only determine the result for + // `subtree_` (the resouces to be described), whereas the default graphs + // also determine which triples for these resources become part of the result. const auto& defaultGraphs = describe_.datasetClauses_.defaultGraphs_; if (defaultGraphs.has_value()) { std::vector graphIdVec; @@ -169,7 +172,9 @@ IdTable Describe::makeAndExecuteJoinWithFullIndex( // Compute the result of the `join` and select the columns `?subject`, // `?predicate`, `?object`. // - // TODO: How can the `result` have more columns than those? + // NOTE: Typically, the join result has already those exact columns, in which + // case the `selectColumns` operation is a no-op. Note sure when this is not + // the case, but better safe than sorry. auto result = join->getResult(); IdTable resultTable = result->idTable().clone(); ColumnIndex s = join->getVariableColumn(V{"?subject"}); diff --git a/src/parser/sparqlParser/SparqlQleverVisitor.cpp b/src/parser/sparqlParser/SparqlQleverVisitor.cpp index c6b09c5842..28054466db 100644 --- a/src/parser/sparqlParser/SparqlQleverVisitor.cpp +++ b/src/parser/sparqlParser/SparqlQleverVisitor.cpp @@ -284,9 +284,9 @@ ParsedQuery Visitor::visit(Parser::DescribeQueryContext* ctx) { auto describeClause = parsedQuery::Describe{}; auto describedResources = visitVector(ctx->varOrIri()); - std::vector describedVariables; // Convert the describe resources (variables or IRIs) from the format that the - // parser delivers to the one that the `Describe` struct expects. + // parser delivers to the one that the `parsedQuery::Describe` struct expects. + std::vector describedVariables; for (GraphTerm& resource : describedResources) { if (std::holds_alternative(resource)) { const auto& variable = std::get(resource); @@ -300,13 +300,13 @@ ParsedQuery Visitor::visit(Parser::DescribeQueryContext* ctx) { } } - // Parse the FROM and FROM NAMED clauses and store them in the - // `describeClause`. + // Parse the FROM and FROM NAMED clauses. auto datasetClauses = parsedQuery::DatasetClauses::fromClauses( visitVector(ctx->datasetClause())); describeClause.datasetClauses_ = datasetClauses; - // Parse the WHERE clause and handle the special case of `DESCRIBE *`. + // Parse the WHERE clause and construct a SELECT query from it. For `DESCRIBE + // *`, add each visible variable as a resource to describe. visitWhereClause(ctx->whereClause(), parsedQuery_); if (describedResources.empty()) { const auto& visibleVariables = @@ -319,10 +319,17 @@ ParsedQuery Visitor::visit(Parser::DescribeQueryContext* ctx) { selectClause.setSelected(std::move(describedVariables)); describeClause.whereClause_ = std::move(parsedQuery_); - // Set up the actual DESCRIBE query, which is implemented as a CONSTRUCT query - // of the form `CONSTRUCT { ?subject ?predicate ?object} { ... }`. Note that - // the solution modifiers (in particular ORDER BY) are part of this query, not - // of the WHERE clause. + // Set up the final `ParsedQuery` object for the DESCRIBE query. The clause is + // a CONSTRUCT query of the form `CONSTRUCT { ?subject ?predicate ?object} { + // ... }`, with the `parsedQuery::Describe` object from above as the root + // graph pattern. The solution modifiers (in particular ORDER BY) are part of + // the CONSTRUCT query. + // + // NOTE: The dataset clauses are stored once in `parsedQuery_.datasetClauses_` + // (which pertains to the CONSTRUCT query that computes the result of the + // DESCRIBE), and once in `parsedQuery_.describeClause_.datasetClauses_` + // (which pertains to the SELECT query that computes the resources to be + // described). parsedQuery_ = ParsedQuery{}; parsedQuery_.addSolutionModifiers(visit(ctx->solutionModifier())); parsedQuery_._rootGraphPattern._graphPatterns.emplace_back(