Skip to content

Added Support for default prefixes in SPARQL queries (#647)#787

Open
Aeternant wants to merge 1 commit into
mainfrom
feature/647-default-queries
Open

Added Support for default prefixes in SPARQL queries (#647)#787
Aeternant wants to merge 1 commit into
mainfrom
feature/647-default-queries

Conversation

@Aeternant
Copy link
Copy Markdown
Collaborator

Makes base and prefix IRIs available to Import/Export and closes #647

@Aeternant Aeternant requested a review from mmarx May 12, 2026 11:16
@github-project-automation github-project-automation Bot moved this to Todo in nemo May 12, 2026
Copy link
Copy Markdown
Member

@mmarx mmarx left a comment

Choose a reason for hiding this comment

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

This is mostly fine, only a few stylistic issues remain

Comment on lines +186 to +187
base: Option<Iri<String>>,
prefixes: HashMap<String, IriRef<String>>,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is fine for now, but we would want to consider moving these into a FormatContext (or something like that) struct if we ever add more parameters

(
key.clone(),
Iri::from_str(&value.to_string())
.unwrap_or_else(|_| base.clone().unwrap().resolve(value).unwrap()),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We generally avoid unwrap() in favour of expect() (this is somewhat less strict in tests, but in library code, we don't want to have any plain unwraps).

Here, I don't even think the unwrap on base is warranted – it might be None and that could still be valid if the relative prefix isn't actually used in the query. The validation should proceed like this:

  • if base is None, only collect the absolute prefixes (if the prefix is required in the query, the existing error handling will already catch it, if not, this is fine)
  • otherwise, collect all the prefixes, resolving relative prefixes with respect to the base (this will always succeed, so you can base.resolve(value).expect("relative IRI can always be resolved with the absolute base") here
let resolved_prefixes = if let Some(base) = base {
  prefixes.iter().map(|(key, value)| (key.clone(), Iri::from_str(value).unwrap_or_else(|_| base.resolve(value).expect("relative IRI can always be resolved with absolute base")).collect()
} else {
  prefixes.iter().filter_map(|(key, value)| (key.clone(), Iri::from_str(value)?).collect()
}

.collect();

if let Some(base) = base {
parser = parser.with_base_iri(base.to_string()).unwrap();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
parser = parser.with_base_iri(base.to_string()).unwrap();
parser = parser.with_base_iri(base.to_string()).expect("IRI is valid");

for (prefix_name, prefix_iri) in resolved_prefixes {
parser = parser
.with_prefix(prefix_name, prefix_iri.to_string())
.unwrap();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

(see above, also applies elsewhere in the PR)

Comment on lines +197 to +219
let mut parser = SparqlParser::new();

// SparqlParser only accepts absolute (resolved) iri's
let resolved_prefixes: Vec<(String, Iri<String>)> = prefixes
.iter()
.map(|(key, value)| {
(
key.clone(),
Iri::from_str(&value.to_string())
.unwrap_or_else(|_| base.clone().unwrap().resolve(value).unwrap()),
)
})
.collect();

if let Some(base) = base {
parser = parser.with_base_iri(base.to_string()).unwrap();
}

for (prefix_name, prefix_iri) in resolved_prefixes {
parser = parser
.with_prefix(prefix_name, prefix_iri.to_string())
.unwrap();
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It's maybe worthwhile to factor this into function that takes base and prefixes and returns a SparqlParser, since we're doing the same thing above


let valid_query = AnyDataValue::new_plain_string(String::from("
PREFIX wikibase: <http://wikiba.se/ontology#>
PREFIX wikibase: <http://wikiba.se/ontology#>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Not sure why we change the alignment here?

Comment on lines +537 to +546
let parameters = Parameters::<B>::validate(
predicate,
spec,
bindings,
filter_rules,
direction,
report,
base.clone(),
prefixes.clone(),
)?;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This should probably be factored into one or possible several (that'd make it easier to reuse them elsewhere) structs. We can discuss the details in person tomorrow.

let base = translation
.base
.clone()
.map(|x| Iri::from_str(&x.0).unwrap());
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is the base already validated at this point? If yes, we can expect here, otherwise, this might need to produce an error.

let prefixes = translation
.prefix_mapping
.iter()
.map(|(key, value)| (key.clone(), IriRef::from_str(&value.0).unwrap()))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same question as for the base above.

@github-project-automation github-project-automation Bot moved this from Todo to In Progress in nemo May 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

Feature: Support default prefixes in SPARQL queries

2 participants