Skip to content

Add utilities in preparation for materialized view query rewriting#2692

Open
ullingerc wants to merge 12 commits intoad-freiburg:masterfrom
ullingerc:matview-rewrite-prep
Open

Add utilities in preparation for materialized view query rewriting#2692
ullingerc wants to merge 12 commits intoad-freiburg:masterfrom
ullingerc:matview-rewrite-prep

Conversation

@ullingerc
Copy link
Member

@ullingerc ullingerc commented Feb 2, 2026

This change adds various utilities for the query rewriting infrastructure that will allow implicit use of materialized views.

Preparation for #2649

@codecov
Copy link

codecov bot commented Feb 2, 2026

Codecov Report

❌ Patch coverage is 97.50000% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 91.60%. Comparing base (cca3768) to head (95d0256).

Files with missing lines Patch % Lines
src/parser/GraphPatternOperation.cpp 90.90% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##           master    #2692   +/-   ##
=======================================
  Coverage   91.60%   91.60%           
=======================================
  Files         483      485    +2     
  Lines       41360    41401   +41     
  Branches     5493     5501    +8     
=======================================
+ Hits        37886    37925   +39     
+ Misses       1897     1896    -1     
- Partials     1577     1580    +3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@sparql-conformance
Copy link

Overview

Number of Tests Passed ✅ Intended ✅ Failed ❌ Not tested
547 450 73 24 0

Conformance check passed ✅

No test result changes.

Details: https://qlever.dev/sparql-conformance-ui?cur=95d02561c18351fa69b8c497ed135491abb94301&prev=cca37689eb8be289bc51bcb675030d05dd10f671

@ullingerc ullingerc requested a review from joka921 February 3, 2026 13:34
@sonarqubecloud
Copy link

sonarqubecloud bot commented Feb 3, 2026

Copy link
Member

@joka921 joka921 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much and sorry for the long wait.
Please ping me for the next round, it should be faster then.

// Call a function for every variable contained in the triple.
void forEachVariable(auto function) const {
if (s_.isVariable()) {
function(s_.getVariable());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider using std::invoke (for the flex + member pointers of Variable:))

}

// Call a function for every variable contained in the triple.
void forEachVariable(auto function) const {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a requirement (invocable with a const Variable&).

Comment on lines +89 to +92
// Extract all variables present in a the first `BasicGraphPattern` contained in
// a vector of `GraphPatternOperation`s. It is used for skipping some graph
// patterns in `MaterializedViewQueryAnalysis.cpp`.
//
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment is a little ambigious:

  1. does this use the first basic pattern in the query, even if the pattern is not at the beginnning of the query (so first subquery, then BGP), or only "the first element if it is a parsed graph pattern". The comment says more the first, but as this is a function with strange uninituitive behavior, better be precise and verbose.

ad_utility::filterRangeOfVariantsByType<parsedQuery::BasicGraphPattern>(
graphPatterns);
if (!ql::ranges::empty(basicGraphPatterns)) {
(*basicGraphPatterns.begin()).collectAllContainedVariables(vars);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not bgp.begin()-> (the start is confusing to read )

Comment on lines +18 to +25
// interested in the bindings for variables from `variables_` as they do not
// affect the result for these `variables_`.
//
// For example: A basic graph pattern (a list of triples) is invariant to a
// `BIND` statement whose target variable is not contained in the basic graph
// pattern, because the `BIND` only adds its own column, but neither adds nor
// deletes result rows.
//
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this statement actually true:

 ?x <is-a> ?y .
 BIND (somethingCompletelyElse as ?z) # seems invariant.
 FILTER (?x > ?y)  upps...

Or will you in this case consider filter the whole thing out, because you see the filter and EVERYTHING has to be invariant? in that case please comment this, that this is only true for one step.

But otherwise: The comment is now great to understand

Comment on lines +63 to +65
template <typename ValueType>
using StringPairHashMap =
ad_utility::HashMap<ad_utility::detail::StringPair, ValueType,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this support types other than StringPair and StringViewPair?
in that case you can make that clear in comments, and/or requires clauses.

Comment on lines +17 to +19
CPP_template(typename T, typename R)(
requires ql::ranges::range<R>) auto filterRangeOfVariantsByType(const R&
range) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doesn't need to be constrained to const & , can be R&& , then you need a remove_cvref_t or decay for the range constraint, and (as I still haven't patched range-v3 for this) use return ad_utility::allView(AD_FWD(range)) | ....

expectFilteredRange<V, char>(vec, {'c', 'f'});
expectFilteredRange<V, bool>(vec, {true, false, true});
expectFilteredRange<V, double>(vec, {});
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add tests for my suggested improvements. In particular test that auto f = filterRange<blub>(temporaryVector) doesn't dangle (which it currently does!).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(+ checks for mutable references).

ASSERT_EQ(map.size(), 2u);

// Lookup using `std::string_view` pairs.
auto it = map.find(StringViewPair{"hello", "world"});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Am I seeing correctly as this could never allocate, as StringViewPair is not convertible to StringPair? If yes, then this could be a static assertion.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • something i forgot in the implementation:

For the same reason (if I am right), we cannot insert via the string_view_pair (because not even explicitly they are convertible, then this should be commented as part of the interface there.

// The `VALUES` doesn't bind to any of the `variables_`.
ql::ranges::none_of(variables, [this](const auto& var) {
return variables_.contains(var);
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically this module is currently untested (at least I cannot find the tests, otherwise please point me to them). I am not sure if this is a hard problem for me, but they should be easy to vibecode etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants