Hi Andy, I understand the differences of how they are implemented.
I think what I'm missing is a sort of overview of when those different approaches should be used, and also examples of when they produce semantically different queries. Martynas On Thu, Feb 6, 2025 at 5:59 PM Andy Seaborne <a...@apache.org> wrote: > > > > On 06/02/2025 03:24, Nicholas Car wrote: > > You could try running that with RDFlib and see what it does…. > > > > How is substitute() different to just string template substitution? Is it > > just a convenience function so substitution can be done on a Jena SPARQL > > object (perhaps algebra) rather than a string? > > > It does not work on a string - when working with Query objects (e.g. > service enhancer), manipulate is on Query objects. > It does does not have injection attacks. > > There some places where you can't replace a variable by a value > > BIND(123 AS ?X) > > for example. QueryTransforOps checks. > > Substitute.substitue is a collect of algebra to algebra changes - some > of which are used in execution. > > > > > Is that your goal for an RDFLib equivalent? > > See also ParameterizedSparqlString in Jena which is injection-safe. > That's closer to string replacement. > > Under the general concept of "substitute" there are different uses cases > on different objects. > > Andy > > > SPARQL string to/from SPARQL grammar object is handles in RDFLib fine so I > > guess as I think the code says, an RDFLib substitute() could work on either > > or both. > > > > Nick > > > > On Thu, Feb 6, 2025 at 10:05 am, Martynas Jusevičius > > <[marty...@atomgraph.com](mailto:On Thu, Feb 6, 2025 at 10:05 am, Martynas > > Jusevičius <<a href=)> wrote: > > > >> OK I simply fed Jena's source to ChatGPT and asked it to produce an > >> RDFLIb version :) > >> No idea if it's correct but I'll find out I guess. > >> > >> from rdflib import Variable, BNode, Literal > >> from rdflib.plugins.sparql.algebra import BGP, Filter, Join, LeftJoin, > >> Union, Graph, Extend, Minus, OrderBy, Project > >> > >> def substitute(algebra, binding): > >> if isinstance(algebra, BGP): > >> new_triples = [] > >> for s, p, o in algebra.triples: > >> s = binding.get(s, s) > >> p = binding.get(p, p) > >> o = binding.get(o, o) > >> new_triples.append((s, p, o)) > >> return BGP(new_triples) > >> elif isinstance(algebra, Filter): > >> new_p = substitute(algebra.p, binding) > >> new_expr = algebra.expr > >> for var, val in binding.items(): > >> new_expr = new_expr.substitute(var, val) > >> return Filter(new_expr, new_p) > >> elif isinstance(algebra, Join): > >> return Join(substitute(algebra.p1, binding), > >> substitute(algebra.p2, binding)) > >> elif isinstance(algebra, LeftJoin): > >> return LeftJoin(substitute(algebra.p1, binding), > >> substitute(algebra.p2, binding), algebra.expr) > >> elif isinstance(algebra, Union): > >> return Union(substitute(algebra.p1, binding), > >> substitute(algebra.p2, binding)) > >> elif isinstance(algebra, Graph): > >> return Graph(algebra.term, substitute(algebra.p, binding)) > >> elif isinstance(algebra, Extend): > >> new_p = substitute(algebra.p, binding) > >> new_expr = algebra.expr > >> for var, val in binding.items(): > >> new_expr = new_expr.substitute(var, val) > >> return Extend(new_p, new_expr, algebra.var) > >> elif isinstance(algebra, Minus): > >> return Minus(substitute(algebra.p1, binding), > >> substitute(algebra.p2, binding)) > >> elif isinstance(algebra, OrderBy): > >> return OrderBy(substitute(algebra.p, binding), algebra.expr) > >> elif isinstance(algebra, Project): > >> return Project(substitute(algebra.p, binding), algebra.PV) > >> else: > >> return algebra > >> > >> On Thu, Feb 6, 2025 at 12:54 AM Martynas Jusevičius > >> <marty...@atomgraph.com> wrote: > >>> > >>> Hi, > >>> > >>> I was looking to implement something like substitute() using RDFLib. > >>> > >>> I checked the note: > >>> https://afs.github.io/substitute.htm > >>> But I couldn't find a clear example. > >>> > >>> For example, how would this query string (the template) > >>> > >>> PREFIX dbo: <http://dbpedia.org/ontology/> > >>> CONSTRUCT > >>> WHERE { ?city dbo:populationTotal ?population } > >>> > >>> would look like after substituting (?city, > >>> <http://dbpedia.org/resource/Copenhagen>)? > >>> > >>> > >>> Martynas >