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 update queries #1354

Merged
merged 17 commits into from
Jun 5, 2024
85 changes: 17 additions & 68 deletions src/parser/ParsedQuery.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "parser/PropertyPath.h"
#include "parser/SelectClause.h"
#include "parser/TripleComponent.h"
#include "parser/UpdateClause.h"
#include "parser/data/GroupKey.h"
#include "parser/data/LimitOffsetClause.h"
#include "parser/data/OrderKey.h"
Expand Down Expand Up @@ -49,75 +50,8 @@ class SparqlPrefix {
bool operator==(const SparqlPrefix&) const = default;
};

inline bool isVariable(const string& elem) { return elem.starts_with("?"); }
inline bool isVariable(const TripleComponent& elem) {
return elem.isVariable();
}

inline bool isVariable(const PropertyPath& elem) {
return elem._operation == PropertyPath::Operation::IRI &&
isVariable(elem._iri);
}

std::ostream& operator<<(std::ostream& out, const PropertyPath& p);

// Data container for parsed triples from the where clause.
// It is templated on the predicate type, see the instantiations below.
template <typename Predicate>
class SparqlTripleBase {
public:
using AdditionalScanColumns = std::vector<std::pair<ColumnIndex, Variable>>;
SparqlTripleBase(TripleComponent s, Predicate p, TripleComponent o,
AdditionalScanColumns additionalScanColumns = {})
: s_(std::move(s)),
p_(std::move(p)),
o_(std::move(o)),
additionalScanColumns_(std::move(additionalScanColumns)) {}

bool operator==(const SparqlTripleBase& other) const = default;
TripleComponent s_;
Predicate p_;
TripleComponent o_;
// The additional columns (e.g. patterns) that are to be attached when
// performing an index scan using this triple.
// TODO<joka921> On this level we should not store `ColumnIndex`, but the
// special predicate IRIs that are to be attached here.
std::vector<std::pair<ColumnIndex, Variable>> additionalScanColumns_;
};

// A triple where the predicate is a `TripleComponent`, so a fixed entity or a
// variable, but not a property path.
class SparqlTripleSimple : public SparqlTripleBase<TripleComponent> {
using Base = SparqlTripleBase<TripleComponent>;
using Base::Base;
};

// A triple where the predicate is a `PropertyPath` (which technically still
// might be a variable or fixed entity in the current implementation).
class SparqlTriple : public SparqlTripleBase<PropertyPath> {
public:
using Base = SparqlTripleBase<PropertyPath>;
using Base::Base;

// ___________________________________________________________________________
SparqlTriple(TripleComponent s, const std::string& p_iri, TripleComponent o)
: Base{std::move(s), PropertyPath::fromIri(p_iri), std::move(o)} {}

// ___________________________________________________________________________
[[nodiscard]] string asString() const;

// Convert to a simple triple. Fails with an exception if the predicate
// actually is a property path.
SparqlTripleSimple getSimple() const {
AD_CONTRACT_CHECK(p_.isIri());
TripleComponent p =
isVariable(p_._iri)
? TripleComponent{Variable{p_._iri}}
: TripleComponent(TripleComponent::Iri::fromIriref(p_._iri));
return {s_, p, o_, additionalScanColumns_};
}
};

// Forward declaration
namespace parsedQuery {
struct GraphPatternOperation;
Expand All @@ -132,6 +66,8 @@ class ParsedQuery {

using ConstructClause = parsedQuery::ConstructClause;

using UpdateClause = parsedQuery::UpdateClause;

ParsedQuery() = default;

GraphPattern _rootGraphPattern;
Expand All @@ -147,7 +83,8 @@ class ParsedQuery {

// explicit default initialisation because the constructor
// of SelectClause is private
std::variant<SelectClause, ConstructClause> _clause{SelectClause{}};
std::variant<SelectClause, ConstructClause, UpdateClause> _clause{
SelectClause{}};

[[nodiscard]] bool hasSelectClause() const {
return std::holds_alternative<SelectClause>(_clause);
Expand All @@ -157,6 +94,10 @@ class ParsedQuery {
return std::holds_alternative<ConstructClause>(_clause);
}

[[nodiscard]] bool hasUpdateClause() const {
return std::holds_alternative<UpdateClause>(_clause);
}

Qup42 marked this conversation as resolved.
Show resolved Hide resolved
[[nodiscard]] decltype(auto) selectClause() const {
return std::get<SelectClause>(_clause);
}
Expand All @@ -165,6 +106,10 @@ class ParsedQuery {
return std::get<ConstructClause>(_clause);
}

[[nodiscard]] decltype(auto) updateClause() const {
return std::get<UpdateClause>(_clause);
}

[[nodiscard]] decltype(auto) selectClause() {
return std::get<SelectClause>(_clause);
}
Expand All @@ -173,6 +118,10 @@ class ParsedQuery {
return std::get<ConstructClause>(_clause);
}

[[nodiscard]] decltype(auto) updateClause() {
return std::get<UpdateClause>(_clause);
}

// Add a variable, that was found in the query body.
void registerVariableVisibleInQueryBody(const Variable& variable);

Expand Down
80 changes: 80 additions & 0 deletions src/parser/SparqlTriple.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Copyright 2024, University of Freiburg,
// Chair of Algorithms and Data Structures.
// Authors: Björn Buchhold (buchhold@informatik.uni-freiburg.de)
// Johannes Kalmbach <johannes.kalmbach@gmail.com>

#pragma once

#include <vector>

#include "PropertyPath.h"
#include "TripleComponent.h"
#include "global/Id.h"
#include "parser/data/Variable.h"

inline bool isVariable(const string& elem) { return elem.starts_with("?"); }
inline bool isVariable(const TripleComponent& elem) {
return elem.isVariable();
}

inline bool isVariable(const PropertyPath& elem) {
return elem._operation == PropertyPath::Operation::IRI &&
isVariable(elem._iri);
}

// Data container for parsed triples from the where clause.
// It is templated on the predicate type, see the instantiations below.
template <typename Predicate>
class SparqlTripleBase {
public:
using AdditionalScanColumns = std::vector<std::pair<ColumnIndex, Variable>>;
SparqlTripleBase(TripleComponent s, Predicate p, TripleComponent o,
AdditionalScanColumns additionalScanColumns = {})
: s_(std::move(s)),
p_(std::move(p)),
o_(std::move(o)),
additionalScanColumns_(std::move(additionalScanColumns)) {}

bool operator==(const SparqlTripleBase& other) const = default;
TripleComponent s_;
Predicate p_;
TripleComponent o_;
// The additional columns (e.g. patterns) that are to be attached when
// performing an index scan using this triple.
// TODO<joka921> On this level we should not store `ColumnIndex`, but the
// special predicate IRIs that are to be attached here.
std::vector<std::pair<ColumnIndex, Variable>> additionalScanColumns_;
};

// A triple where the predicate is a `TripleComponent`, so a fixed entity or a
// variable, but not a property path.
class SparqlTripleSimple : public SparqlTripleBase<TripleComponent> {
using Base = SparqlTripleBase<TripleComponent>;
using Base::Base;
};

// A triple where the predicate is a `PropertyPath` (which technically still
// might be a variable or fixed entity in the current implementation).
class SparqlTriple : public SparqlTripleBase<PropertyPath> {
public:
using Base = SparqlTripleBase<PropertyPath>;
using Base::Base;

// ___________________________________________________________________________
SparqlTriple(TripleComponent s, const std::string& p_iri, TripleComponent o)
: Base{std::move(s), PropertyPath::fromIri(p_iri), std::move(o)} {}

// ___________________________________________________________________________
[[nodiscard]] string asString() const;

// Convert to a simple triple. Fails with an exception if the predicate
// actually is a property path.
SparqlTripleSimple getSimple() const {
AD_CONTRACT_CHECK(p_.isIri());
TripleComponent p =
isVariable(p_._iri)
? TripleComponent{Variable{p_._iri}}
: TripleComponent(TripleComponent::Iri::fromIriref(p_._iri));
return {s_, p, o_, additionalScanColumns_};
}
};
21 changes: 21 additions & 0 deletions src/parser/UpdateClause.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2024, University of Freiburg,
// Chair of Algorithms and Data Structures.
// Author: Julian Mundhahs (mundhahj@informatik.uni-freiburg.de)

#pragma once

#include "parser/SelectClause.h"
#include "parser/SparqlTriple.h"
#include "parser/data/Types.h"

namespace parsedQuery {
struct UpdateClause : ClauseBase {
std::vector<SparqlTripleSimple> toInsert_;
std::vector<SparqlTripleSimple> toDelete_;

UpdateClause() = default;
UpdateClause(std::vector<SparqlTripleSimple> toInsert,
std::vector<SparqlTripleSimple> toDelete)
: toInsert_{std::move(toInsert)}, toDelete_{std::move(toDelete)} {}

Check warning on line 19 in src/parser/UpdateClause.h

View check run for this annotation

Codecov / codecov/patch

src/parser/UpdateClause.h#L19

Added line #L19 was not covered by tests
};
} // namespace parsedQuery
Loading
Loading