Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parse WHERE clause using ANTLR #749

Merged
merged 33 commits into from
Aug 26, 2022
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
42f8bf2
First Step
Qup42 Aug 20, 2022
1411f83
Commit Code for Code Review
Qup42 Aug 22, 2022
618beed
Formatting
Qup42 Aug 22, 2022
fc5fec9
Commit from In Person Review
Qup42 Aug 23, 2022
92f7365
Update src/util/Algorithm.h
Qup42 Aug 23, 2022
763bfc6
Code Review
Qup42 Aug 23, 2022
48ad122
Merge branch 'master' into ANTLR/whereClause
Qup42 Aug 23, 2022
7ebf5c2
Fix Wrong Handling of Triples/GraphPatternOperation
Qup42 Aug 24, 2022
80973d9
Consistent Test naming
Qup42 Aug 24, 2022
1398562
Use visitAlternative for graphPatternNotTriples
Qup42 Aug 24, 2022
b6a0416
Build fixes
Qup42 Aug 24, 2022
11b8611
Remove obsolete helper functions
Qup42 Aug 24, 2022
1fe996d
Test Cleanup, and finish settings of ids
Qup42 Aug 24, 2022
be86fca
More tests
Qup42 Aug 24, 2022
80ffcc6
Parse whereClause in ANTLR
Qup42 Aug 24, 2022
1f7cd52
Fix another test that may fail when run in parallel
Qup42 Aug 25, 2022
2c7bc1c
Code Review
Qup42 Aug 25, 2022
1413bb0
Update test/SparqlAntlrParserTestHelpers.h
Qup42 Aug 25, 2022
70149a2
Merge remote-tracking branch 'fork/ANTLR/whereClause' into ANTLR/wher…
Qup42 Aug 25, 2022
3350b85
Code Review
Qup42 Aug 25, 2022
e852149
Code Review
Qup42 Aug 25, 2022
c1bb9c6
Code Review
Qup42 Aug 25, 2022
890852b
Cleanup Copyright Notice and Includes
Qup42 Aug 25, 2022
2a426ed
Implement and Test Subquery with following Values Clause
Qup42 Aug 26, 2022
5ca51f5
Apply suggestions from code review
Qup42 Aug 26, 2022
06f0c00
Fix compilation bug in ANTLR/whereClause
Aug 26, 2022
c92c912
Make clang-format happy + fix order of includes
Aug 26, 2022
cc86c88
Code Review
Qup42 Aug 26, 2022
8ef32be
Merge branch 'master' into ANTLR/whereClause
Qup42 Aug 26, 2022
22b066e
Sort imports
Qup42 Aug 26, 2022
c0d9254
Apply suggestions from code review
Qup42 Aug 26, 2022
0617793
Code review
Qup42 Aug 26, 2022
09cf3a4
Code review
Qup42 Aug 26, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 46 additions & 43 deletions src/parser/sparqlParser/SparqlQleverVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@
// Hannah Bast <[email protected]>
// 2022 Julian Mundhahs <[email protected]>

#include "SparqlQleverVisitor.h"
#include <parser/SparqlParser.h>
#include <parser/sparqlParser/SparqlQleverVisitor.h>
Qup42 marked this conversation as resolved.
Show resolved Hide resolved

#include <string>
#include <vector>
Qup42 marked this conversation as resolved.
Show resolved Hide resolved

#include "../SparqlParser.h"

using namespace ad_utility::sparql_types;
using ExpressionPtr = sparqlExpression::SparqlExpression::Ptr;
using SparqlExpressionPimpl = sparqlExpression::SparqlExpressionPimpl;
Expand Down Expand Up @@ -64,6 +63,14 @@ ExpressionPtr Visitor::processIriFunctionCall(
throw ParseException{"Function \"" + iri + "\" not supported"};
}

void Visitor::addVisibleVariable(const string& var) {
addVisibleVariable(Variable{var});
}
Qup42 marked this conversation as resolved.
Show resolved Hide resolved

void Visitor::addVisibleVariable(const Variable& var) {
visibleVariables_.back().emplace_back(var);
Qup42 marked this conversation as resolved.
Show resolved Hide resolved
}

// ___________________________________________________________________________
namespace {
string stripAndLowercaseKeywordLiteral(std::string_view lit) {
Expand Down Expand Up @@ -182,7 +189,7 @@ Variable Visitor::visitTypesafe(Parser::VarContext* ctx) {

// ____________________________________________________________________________________
GraphPatternOperation Visitor::visitTypesafe(Parser::BindContext* ctx) {
visibleVariables_.back().emplace_back(ctx->var()->getText());
addVisibleVariable(ctx->var()->getText());
return GraphPatternOperation{
Bind{{visitTypesafe(ctx->expression())}, ctx->var()->getText()}};
}
Expand All @@ -191,9 +198,9 @@ GraphPatternOperation Visitor::visitTypesafe(Parser::BindContext* ctx) {
GraphPatternOperation Visitor::visitTypesafe(Parser::InlineDataContext* ctx) {
Values values = visitTypesafe(ctx->dataBlock());
for (const auto& variable : values._inlineValues._variables) {
visibleVariables_.back().emplace_back(variable);
addVisibleVariable(variable);
}
return GraphPatternOperation{values};
return GraphPatternOperation{std::move(values)};
}

// ____________________________________________________________________________________
Expand Down Expand Up @@ -230,9 +237,8 @@ GraphPattern Visitor::visitTypesafe(Parser::GroupGraphPatternContext* ctx) {
}
}

// TODO: Package this type into a struct.
std::pair<vector<GraphPatternOperation>, vector<SparqlFilter>>
Visitor::visitTypesafe(Parser::GroupGraphPatternSubContext* ctx) {
Visitor::OperationsAndFilters Visitor::visitTypesafe(
Parser::GroupGraphPatternSubContext* ctx) {
vector<GraphPatternOperation> ops;
vector<SparqlFilter> filters;

Expand All @@ -244,46 +250,39 @@ Visitor::visitTypesafe(Parser::GroupGraphPatternSubContext* ctx) {
};

if (ctx->triplesBlock()) {
ops.emplace_back(GraphPatternOperation::BasicGraphPattern{
visitTypesafe(ctx->triplesBlock())});
ops.emplace_back(visitTypesafe(ctx->triplesBlock()));
}
auto others = visitVector<
std::pair<variant<GraphPatternOperation, SparqlFilter>,
std::optional<GraphPatternOperation::BasicGraphPattern>>>(
ctx->graphPatternNotTriplesAndMaybeTriples());
for (auto [variant, triples] : others) {
std::visit(ad_utility::OverloadCallOperator{filter, op}, variant);
if (triples.has_value()) {
if (holds_alternative<SparqlFilter>(variant) && !ops.empty() &&
holds_alternative<GraphPatternOperation::BasicGraphPattern>(
ops.back().variant_)) {
ad_utility::appendVector(
get<GraphPatternOperation::BasicGraphPattern>(ops.back().variant_)
._whereClauseTriples,
std::move(triples.value()._whereClauseTriples));

} else {
ops.emplace_back(triples.value());
}
for (auto [graphPattern, triples] : others) {
std::visit(ad_utility::OverloadCallOperator{filter, op}, graphPattern);
if (!triples.has_value()) {
continue;
}
if (ops.empty() ||
!holds_alternative<GraphPatternOperation::BasicGraphPattern>(
ops.back().variant_)) {
Qup42 marked this conversation as resolved.
Show resolved Hide resolved
ops.emplace_back(GraphPatternOperation::BasicGraphPattern{});
}
ad_utility::appendVector(
get<GraphPatternOperation::BasicGraphPattern>(ops.back().variant_)
Qup42 marked this conversation as resolved.
Show resolved Hide resolved
._whereClauseTriples,
std::move(triples.value()._whereClauseTriples));
Qup42 marked this conversation as resolved.
Show resolved Hide resolved
}
return {ops, filters};
return {std::move(ops), std::move(filters)};
}

// TODO: Package this type into a struct.
std::pair<variant<GraphPatternOperation, SparqlFilter>,
std::optional<GraphPatternOperation::BasicGraphPattern>>
Visitor::visitTypesafe(
Visitor::OperationOrFilterAndMaybeTriples Visitor::visitTypesafe(
Parser::GraphPatternNotTriplesAndMaybeTriplesContext* ctx) {
auto triples = ctx->triplesBlock()
? std::optional{GraphPatternOperation::BasicGraphPattern{
visitTypesafe(ctx->triplesBlock())}}
: std::nullopt;
return {visitTypesafe(ctx->graphPatternNotTriples()), std::move(triples)};
return {visitTypesafe(ctx->graphPatternNotTriples()),
visitOptional(ctx->triplesBlock())};
}

// ____________________________________________________________________________________
vector<SparqlTriple> Visitor::visitTypesafe(Parser::TriplesBlockContext* ctx) {
GraphPatternOperation::BasicGraphPattern Visitor::visitTypesafe(
Qup42 marked this conversation as resolved.
Show resolved Hide resolved
Parser::TriplesBlockContext* ctx) {
auto iri = [](const Iri& iri) -> TripleComponent { return iri.toSparql(); };
auto blankNode = [](const BlankNode& blankNode) -> TripleComponent {
return blankNode.toSparql();
Expand Down Expand Up @@ -325,7 +324,7 @@ vector<SparqlTriple> Visitor::visitTypesafe(Parser::TriplesBlockContext* ctx) {

auto registerIfVariable = [this](auto& variant) {
if (holds_alternative<Variable>(variant)) {
visibleVariables_.back().emplace_back(std::get<Variable>(variant));
addVisibleVariable(std::get<Variable>(variant));
Qup42 marked this conversation as resolved.
Show resolved Hide resolved
}
};

Expand All @@ -344,13 +343,14 @@ vector<SparqlTriple> Visitor::visitTypesafe(Parser::TriplesBlockContext* ctx) {
auto triples = ad_utility::transform(
visitTypesafe(ctx->triplesSameSubjectPath()), convertAndRegisterTriple);
if (ctx->triplesBlock()) {
ad_utility::appendVector(triples, visitTypesafe(ctx->triplesBlock()));
ad_utility::appendVector(
triples, visitTypesafe(ctx->triplesBlock())._whereClauseTriples);
Qup42 marked this conversation as resolved.
Show resolved Hide resolved
}
return triples;
return {triples};
Qup42 marked this conversation as resolved.
Show resolved Hide resolved
}

// ____________________________________________________________________________________
std::variant<GraphPatternOperation, SparqlFilter> Visitor::visitTypesafe(
Visitor::OperationOrFilter Visitor::visitTypesafe(
Parser::GraphPatternNotTriplesContext* ctx) {
if (ctx->graphGraphPattern() || ctx->serviceGraphPattern()) {
reportError(ctx,
Expand All @@ -367,7 +367,8 @@ GraphPatternOperation Visitor::visitTypesafe(
Parser::OptionalGraphPatternContext* ctx) {
Qup42 marked this conversation as resolved.
Show resolved Hide resolved
auto pattern = visitTypesafe(ctx->groupGraphPattern());
pattern._optional = true;
return GraphPatternOperation{GraphPatternOperation::Optional{pattern}};
return GraphPatternOperation{
GraphPatternOperation::Optional{std::move(pattern)}};
}

// ____________________________________________________________________________________
Expand Down Expand Up @@ -566,7 +567,9 @@ GraphPatternOperation::Subquery Visitor::visitTypesafe(
numInternalVariables_ = query.getNumInternalVariables();
if (ctx->valuesClause() && !ctx->valuesClause()->getText().empty()) {
// TODO: implement
reportError(ctx->valuesClause(), "ValuesClause is not yet implemented.");
reportError(
ctx->valuesClause(),
"VALUES clause directly after a Subquery is not yet implemented.");
Qup42 marked this conversation as resolved.
Show resolved Hide resolved
}
// auto values = visitTypesafe(ctx->valuesClause());
// if (values.has_value()) {
Expand All @@ -578,7 +581,7 @@ GraphPatternOperation::Subquery Visitor::visitTypesafe(
}
// Variables that are selected in this query are visible in the parent query.
for (const auto& variable : query.selectClause().getSelectedVariables()) {
visibleVariables_.back().emplace_back(variable);
addVisibleVariable(variable);
}
query._numGraphPatterns = numGraphPatterns_++;
return {std::move(query)};
Expand Down
66 changes: 37 additions & 29 deletions src/parser/sparqlParser/SparqlQleverVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,26 @@

#pragma once

#include "../../engine/sparqlExpressions/AggregateExpression.h"
#include "../../engine/sparqlExpressions/GroupConcatExpression.h"
#include "../../engine/sparqlExpressions/LiteralExpression.h"
#include "../../engine/sparqlExpressions/NaryExpression.h"
#include "../../engine/sparqlExpressions/SparqlExpressionPimpl.h"
// #include "../../engine/sparqlExpressions/RelationalExpression.h"
#include "../../engine/sparqlExpressions/SampleExpression.h"
#include "../../util/HashMap.h"
#include "../../util/OverloadCallOperator.h"
#include "../../util/StringUtils.h"
#include "../../util/antlr/ANTLRErrorHandling.h"
#include "../Alias.h"
#include "../ParsedQuery.h"
#include "../RdfEscaping.h"
#include "../data/BlankNode.h"
#include "../data/Iri.h"
#include "../data/SolutionModifiers.h"
#include "../data/Types.h"
#include "../data/VarOrTerm.h"
#include "antlr4-runtime.h"
#include "generated/SparqlAutomaticVisitor.h"
#include <antlr4-runtime.h>
#include <engine/sparqlExpressions/AggregateExpression.h>
#include <engine/sparqlExpressions/GroupConcatExpression.h>
#include <engine/sparqlExpressions/LiteralExpression.h>
#include <engine/sparqlExpressions/NaryExpression.h>
#include <engine/sparqlExpressions/SampleExpression.h>
#include <engine/sparqlExpressions/SparqlExpressionPimpl.h>
#include <parser/Alias.h>
#include <parser/ParsedQuery.h>
#include <parser/RdfEscaping.h>
#include <parser/data/BlankNode.h>
#include <parser/data/Iri.h>
#include <parser/data/SolutionModifiers.h>
#include <parser/data/Types.h>
#include <parser/data/VarOrTerm.h>
#include <parser/sparqlParser/generated/SparqlAutomaticVisitor.h>
#include <util/HashMap.h>
#include <util/OverloadCallOperator.h>
#include <util/StringUtils.h>
#include <util/antlr/ANTLRErrorHandling.h>
Qup42 marked this conversation as resolved.
Show resolved Hide resolved

template <typename T>
class Reversed {
Expand Down Expand Up @@ -54,6 +53,12 @@ class SparqlQleverVisitor : public SparqlAutomaticVisitor {
using ObjectList = ad_utility::sparql_types::ObjectList;
using PropertyList = ad_utility::sparql_types::PropertyList;
using Any = antlrcpp::Any;
using OperationsAndFilters =
std::pair<vector<GraphPatternOperation>, vector<SparqlFilter>>;
using OperationOrFilterAndMaybeTriples =
std::pair<variant<GraphPatternOperation, SparqlFilter>,
std::optional<GraphPatternOperation::BasicGraphPattern>>;
using OperationOrFilter = std::variant<GraphPatternOperation, SparqlFilter>;
size_t _blankNodeCounter = 0;
int64_t numInternalVariables_ = 0;
int64_t numGraphPatterns_ = 0;
Expand Down Expand Up @@ -101,6 +106,11 @@ class SparqlQleverVisitor : public SparqlAutomaticVisitor {
ExpressionPtr processIriFunctionCall(const std::string& iri,
std::vector<ExpressionPtr> argList);

// TODO: Remove addVisibleVariable(const string&) when all Types use the
// strong type Variable.
Qup42 marked this conversation as resolved.
Show resolved Hide resolved
void addVisibleVariable(const string& var);
void addVisibleVariable(const Variable& var);

public:
// ___________________________________________________________________________
Any visitQuery(Parser::QueryContext* ctx) override {
Expand Down Expand Up @@ -297,23 +307,22 @@ class SparqlQleverVisitor : public SparqlAutomaticVisitor {
return visitTypesafe(ctx);
}

std::pair<vector<GraphPatternOperation>, vector<SparqlFilter>> visitTypesafe(
Parser::GroupGraphPatternSubContext* ctx);
OperationsAndFilters visitTypesafe(Parser::GroupGraphPatternSubContext* ctx);

Any visitGraphPatternNotTriplesAndMaybeTriples(
Parser::GraphPatternNotTriplesAndMaybeTriplesContext* ctx) override {
return visitTypesafe(ctx);
}

std::pair<variant<GraphPatternOperation, SparqlFilter>,
std::optional<GraphPatternOperation::BasicGraphPattern>>
visitTypesafe(Parser::GraphPatternNotTriplesAndMaybeTriplesContext* ctx);
OperationOrFilterAndMaybeTriples visitTypesafe(
Parser::GraphPatternNotTriplesAndMaybeTriplesContext* ctx);

Any visitTriplesBlock(Parser::TriplesBlockContext* ctx) override {
return visitTypesafe(ctx);
}

vector<SparqlTriple> visitTypesafe(Parser::TriplesBlockContext* ctx);
GraphPatternOperation::BasicGraphPattern visitTypesafe(
Parser::TriplesBlockContext* ctx);

Any visitGraphPatternNotTriples(
Parser::GraphPatternNotTriplesContext* ctx) override {
Expand All @@ -322,8 +331,7 @@ class SparqlQleverVisitor : public SparqlAutomaticVisitor {

// Filter clauses are no independent graph patterns themselves, but their
// scope is always the complete graph pattern enclosing them.
std::variant<GraphPatternOperation, SparqlFilter> visitTypesafe(
Parser::GraphPatternNotTriplesContext* ctx);
OperationOrFilter visitTypesafe(Parser::GraphPatternNotTriplesContext* ctx);

Any visitOptionalGraphPattern(
Parser::OptionalGraphPatternContext* ctx) override {
Expand Down
1 change: 1 addition & 0 deletions src/parser/sparqlParser/generated/SparqlAutomatic.g4
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ groupGraphPatternSub
: triplesBlock? graphPatternNotTriplesAndMaybeTriples*
;

Qup42 marked this conversation as resolved.
Show resolved Hide resolved
/* Helper rules to make parsing of groupGraphPatternSub easier. */
graphPatternNotTriplesAndMaybeTriples
: graphPatternNotTriples '.'? triplesBlock?
;
Expand Down
18 changes: 14 additions & 4 deletions src/util/Algorithm.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
#ifndef QLEVER_ALGORITHM_H
#define QLEVER_ALGORITHM_H

#include <util/TypeTraits.h>

#include <utility>
Qup42 marked this conversation as resolved.
Show resolved Hide resolved

// TODO: Test the algorithms.
namespace ad_utility {

/**
Expand Down Expand Up @@ -39,10 +44,15 @@ bool contains_if(const Container& container, const Predicate& predicate) {
* @param destination Vector& to which to append
* @param source Vector&& to append
*/
template <typename T>
void appendVector(std::vector<T>& destination, std::vector<T>&& source) {
destination.insert(destination.end(), std::make_move_iterator(source.begin()),
std::make_move_iterator(source.end()));
template <typename T, ad_utility::SimilarTo<std::vector<T>> U>
void appendVector(std::vector<T>& destination, U&& source) {
if constexpr (std::is_rvalue_reference_v<U&&>) {
destination.insert(destination.end(),
std::make_move_iterator(source.begin()),
std::make_move_iterator(source.end()));
} else {
destination.insert(destination.end(), source.begin(), source.end());
}
}

/**
Expand Down
Loading