-
Notifications
You must be signed in to change notification settings - Fork 52
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow
REGEX
for arbitrary expressions (not just a variable) (#1576)
So far, the `REGEX` function was only implemented for the (frequent) special case, where the first argument is either a variable (like `?x`) or `STR` of a variable (like `STR(?x)`). Now `REGEX` works for arbitrary expressions. Use the occasion to clean up the code a little bit and improve the documentation.
- Loading branch information
Showing
3 changed files
with
186 additions
and
104 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
// Copyright 2022, University of Freiburg, | ||
// Chair of Algorithms and Data Structures. | ||
// Author: Johannes Kalmbach <[email protected]> | ||
// Copyright 2022 - 2024, University of Freiburg | ||
// Chair of Algorithms and Data Structures | ||
// Author: Johannes Kalmbach <[email protected]> | ||
|
||
#pragma once | ||
|
||
|
@@ -11,22 +11,27 @@ | |
#include "re2/re2.h" | ||
|
||
namespace sparqlExpression { | ||
// Class implementing the REGEX function, which takes two mandatory arguments | ||
// (an expression and a regex) and one optional argument (a string of flags). | ||
class RegexExpression : public SparqlExpression { | ||
private: | ||
SparqlExpression::Ptr child_; | ||
// If this variant holds a string, we consider this string as the prefix of a | ||
// prefix regex. | ||
std::variant<std::string, RE2> regex_; | ||
// The reguar expression. It needs to be a `std::optional` because `RE2` | ||
// objects do not have a default constructor. | ||
std::optional<RE2> regex_; | ||
// If this `std::optional` holds a string, we have a simple prefix regex | ||
// (which translates to a range search) and this string holds the prefix. | ||
std::optional<std::string> prefixRegex_; | ||
// The regex as a string, used for the cache key. | ||
std::string regexAsString_; | ||
|
||
// True if the STR() function is to be applied on the child before evaluating | ||
// the regex. | ||
// True iff the expression is enclosed in `STR()`. | ||
bool childIsStrExpression_ = false; | ||
|
||
public: | ||
// `child` must be a `VariableExpression` and `regex` must be a | ||
// `LiteralExpression` that stores a string, else an exception will be thrown. | ||
// The `child` must be a `VariableExpression` and `regex` must be a | ||
// `LiteralExpression` that stores a string, otherwise an exception will be | ||
// thrown. | ||
RegexExpression(SparqlExpression::Ptr child, SparqlExpression::Ptr regex, | ||
std::optional<SparqlExpression::Ptr> optionalFlags); | ||
|
||
|
@@ -46,17 +51,21 @@ class RegexExpression : public SparqlExpression { | |
|
||
private: | ||
std::span<SparqlExpression::Ptr> childrenImpl() override; | ||
// Internal implementations that are called by `evaluate`. | ||
|
||
// Evaluate for the special case, where the expression is a variable and we | ||
// have a simple prefix regex (in which case the regex match translates to a | ||
// simple range check). | ||
ExpressionResult evaluatePrefixRegex( | ||
const Variable& variable, | ||
sparqlExpression::EvaluationContext* context) const; | ||
ExpressionResult evaluateNonPrefixRegex( | ||
const Variable& variable, | ||
sparqlExpression::EvaluationContext* context) const; | ||
|
||
/// Helper function to check if the `CancellationHandle` of the passed | ||
/// `EvaluationContext` has been cancelled and throw an exception if this is | ||
/// the case. | ||
// Evaluate for the general case. | ||
template <SingleExpressionResult T> | ||
ExpressionResult evaluateGeneralCase( | ||
T&& input, sparqlExpression::EvaluationContext* context) const; | ||
|
||
// Check if the `CancellationHandle` of `context` has been cancelled and throw | ||
// an exception if this is the case. | ||
static void checkCancellation( | ||
const sparqlExpression::EvaluationContext* context, | ||
ad_utility::source_location location = | ||
|
Oops, something went wrong.