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

Merge main into develop #4128

Merged
merged 2 commits into from
Aug 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.function.BiConsumer;
Expand Down Expand Up @@ -271,8 +270,8 @@ public void meet(Var node) throws QueryEvaluationException {
@Override
public void meet(ProjectionElem node) throws QueryEvaluationException {
super.meet(node);
node.setSourceName(varNames.computeIfAbsent(node.getSourceName(), k -> k));
node.setTargetName(varNames.computeIfAbsent(node.getTargetName(), k -> k));
node.setName(varNames.computeIfAbsent(node.getName(), k -> k));
node.setProjectionAlias(varNames.computeIfAbsent(node.getProjectionAlias().orElse(null), k -> k));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public void optimize(TupleExpr tupleExpr, Dataset dataset, BindingSet bindings)
varsBefore.removeAll(varsAfter);
for (ProjectionElemList projElems : visitor.projElemLists) {
for (ProjectionElem projElem : projElems.getElements()) {
String name = projElem.getSourceName();
String name = projElem.getName();
if (varsBefore.contains(name)) {
UnaryTupleOperator proj = (UnaryTupleOperator) projElems.getParentNode();
Extension ext = new Extension(proj.getArg());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,7 @@ public void meet(Var node) {
if (projection != null) {
boolean projected = false;
for (ProjectionElem e : projection.getProjectionElemList().getElements()) {
String source = e.getSourceName();
String target = e.getTargetName();
if (node.getName().equals(source) && node.getName().equals(target)) {
if (node.getName().equals(e.getName())) {
projected = true;
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,8 @@ public void meet(Var var) {

@Override
public void meet(ProjectionElem projElem) throws RuntimeException {
if (projElem.getSourceName().equals(oldVar.getName())) {
projElem.setSourceName(newVar.getName());
if (projElem.getName().equals(oldVar.getName())) {
projElem.setName(newVar.getName());
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,9 @@ public ProjectionIterator(Projection projection, CloseableIteration<BindingSet,

BiConsumer<MutableBindingSet, BindingSet> consumer = null;
for (ProjectionElem pe : projectionElemList.getElements()) {
String sourceName = pe.getSourceName();
String targetName = pe.getTargetName();
Function<BindingSet, Value> valueWithSourceName = context.getValue(sourceName);
BiConsumer<Value, MutableBindingSet> setTarget = context.setBinding(targetName);
String projectionName = pe.getProjectionAlias().orElse(pe.getName());
Function<BindingSet, Value> valueWithSourceName = context.getValue(pe.getName());
BiConsumer<Value, MutableBindingSet> setTarget = context.setBinding(projectionName);
BiConsumer<MutableBindingSet, BindingSet> next = (resultBindings, sourceBindings) -> {
Value targetValue = valueWithSourceName.apply(sourceBindings);
if (!includeAllParentBindings && targetValue == null) {
Expand Down Expand Up @@ -120,12 +119,12 @@ public static BindingSet project(ProjectionElemList projElemList, BindingSet sou
final QueryBindingSet resultBindings = makeNewQueryBindings(parentBindings, includeAllParentBindings);

for (ProjectionElem pe : projElemList.getElements()) {
Value targetValue = sourceBindings.getValue(pe.getSourceName());
Value targetValue = sourceBindings.getValue(pe.getName());
if (!includeAllParentBindings && targetValue == null) {
targetValue = parentBindings.getValue(pe.getSourceName());
targetValue = parentBindings.getValue(pe.getName());
}
if (targetValue != null) {
resultBindings.setBinding(pe.getTargetName(), targetValue);
resultBindings.setBinding(pe.getProjectionAlias().orElse(pe.getName()), targetValue);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public void optimize(TupleExpr tupleExpr, Dataset dataset, BindingSet bindings)
for (ProjectionElemList projElems : visitor.projElemLists) {
for (ProjectionElem projElem : projElems.getElements()) {

String name = projElem.getSourceName();
String name = projElem.getName();

if (varsBefore.contains(name)) {
UnaryTupleOperator proj = (UnaryTupleOperator) projElems.getParentNode();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,7 @@ public void meet(Var node) {
if (projection != null) {
boolean projected = false;
for (ProjectionElem e : projection.getProjectionElemList().getElements()) {
String source = e.getSourceName();
String target = e.getTargetName();
if (node.getName().equals(source) && node.getName().equals(target)) {
if (node.getName().equals(e.getName())) {
projected = true;
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,8 @@ public void meet(Var var) {

@Override
public void meet(ProjectionElem projElem) throws RuntimeException {
if (projElem.getSourceName().equals(oldVar.getName())) {
projElem.setSourceName(newVar.getName());
if (projElem.getName().equals(oldVar.getName())) {
projElem.setName(newVar.getName());
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public Set<String> getBindingNames() {
Set<String> bindingNames = new HashSet<>();

for (ProjectionElemList projElemList : projections) {
bindingNames.addAll(projElemList.getTargetNames());
bindingNames.addAll(projElemList.getProjectedNames());
}

return bindingNames;
Expand All @@ -89,10 +89,10 @@ public Set<String> getAssuredBindingNames() {
if (projections.size() >= 1) {
Set<String> assuredSourceNames = getArg().getAssuredBindingNames();

bindingNames.addAll(projections.get(0).getTargetNamesFor(assuredSourceNames));
bindingNames.addAll(projections.get(0).getProjectedNamesFor(assuredSourceNames));

for (int i = 1; i < projections.size(); i++) {
bindingNames.retainAll(projections.get(i).getTargetNamesFor(assuredSourceNames));
bindingNames.retainAll(projections.get(i).getProjectedNamesFor(assuredSourceNames));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,14 @@ public void setProjectionElemList(ProjectionElemList projElemList) {

@Override
public Set<String> getBindingNames() {
return projElemList.getTargetNames();
return projElemList.getProjectedNames();
}

@Override
public Set<String> getAssuredBindingNames() {
// Return all target binding names for which the source binding is assured
// by the argument
return projElemList.getTargetNamesFor(getArg().getAssuredBindingNames());
return projElemList.getProjectedNamesFor(getArg().getAssuredBindingNames());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,56 +10,135 @@
*******************************************************************************/
package org.eclipse.rdf4j.query.algebra;

import java.util.Objects;
import java.util.Optional;

/**
* Projection elements control which of the selected expressions (produced by the WHERE clause of a query) are returned
* in the solution, and the order in which they appear.
* <p>
* In SPARQL SELECT queries, projection elements are the variables determined by the algorithm for finding SELECT
* expressions (see <a href="https://www.w3.org/TR/sparql11-query/#sparqlSelectExpressions">SPARQL 1.1 Query Language
* Recommendation, section 18.2.4.4</a>). Each projection element will be a single variable name (any aliasing is
* handled by the use of {@link Extension}s).
* <p>
* In SPARQL CONSTRUCT queries, the projection elements are used to map the variables obtained from the SELECT
* expressions to the required statement patterns. In this case, each projection element will have an additional
* {@link #getProjectionAlias() target name} that maps each projection variable name to one of {@code subject},
* {@code predicate}, {@code object} or {@code context}.
*
* @author Jeen Broekstra
*/
public class ProjectionElem extends AbstractQueryModelNode {

/*-----------*
* Variables *
*-----------*/
private static final long serialVersionUID = -8129811335486478066L;

private String sourceName;
private String name;

private String targetName;
private String projectionAlias;

private boolean aggregateOperatorInExpression;

private ExtensionElem sourceExpression;

/*--------------*
* Constructors *
*--------------*/

/**
* Create a new empty {@link ProjectionElem}.
*/
public ProjectionElem() {
}

/**
* Create a new {@link ProjectionElem} with a variable name.
*
* @param name The name of the projection element (typically the name of the variable in the select expressions).
* May not be <code>null</code>.
*/
public ProjectionElem(String name) {
this(name, name);
this(name, null);
}

public ProjectionElem(String sourceName, String targetName) {
setSourceName(sourceName);
setTargetName(targetName);
/**
* Create a new {@link ProjectionElem} with a variable name and an additional mapped {@link #getProjectionAlias()
* target name}
*
* @param name The name of the projection element (typically the name of the variable in the select
* expressions). May not be <code>null</code>.
* @param targetName The name of the variable the projection element value should be mapped to, to produce the
* projection. Used in CONSTRUCT queries for mapping select expressions to statement patterns. May
* be <code>null</code>.
*/
public ProjectionElem(String name, String targetName) {
setName(name);
setProjectionAlias(targetName);
}

/*---------*
* Methods *
*---------*/
/**
* Get the name of the projection element (typically the name of the variable in the select expressions)
*
*/
public String getName() {
return name;
}

/**
* @deprecated since 4.1.1. Use {@link #getName()} instead.
*/
@Deprecated(since = "4.1.1", forRemoval = true)
public String getSourceName() {
return sourceName;
return getName();
}

/**
* @deprecated since 4.1.1. Use {@link #setName(String)} instead.
*/
@Deprecated(since = "4.1.1", forRemoval = true)
public void setSourceName(String sourceName) {
assert sourceName != null : "sourceName must not be null";
this.sourceName = sourceName;
setName(sourceName);
}

public String getTargetName() {
return targetName;
/**
* Set the name of the projection element (typically the name of the variable in the select expressions)
*
* @param name the projection variable name. May not be {@code null}.
*/
public void setName(String name) {
this.name = Objects.requireNonNull(name);
}

/**
* Get the alias the projection element value should be mapped to. Used in CONSTRUCT queries for mapping select
* expressions to statement patterns.
*
* @return an optionally empty projection alias.
*/
public Optional<String> getProjectionAlias() {
return Optional.ofNullable(projectionAlias);
}

/**
* Set the alias the projection element value should be mapped to. Used in CONSTRUCT queries for mapping select
* expressions to statement patterns.
*
* @param alias the projection alias.
*/
public void setProjectionAlias(String alias) {
this.projectionAlias = alias;
}

/**
* @deprecated since 4.1.1. Use {@link #setProjectionAlias(String)} instead.
*/
@Deprecated(since = "4.1.1", forRemoval = true)
public void setTargetName(String targetName) {
assert targetName != null : "targetName must not be null";
this.targetName = targetName;
setProjectionAlias(targetName);
}

/**
* @deprecated since 4.1.1. Use {@link #getProjectionAlias()} instead.
*/
@Deprecated(since = "4.1.1", forRemoval = true)
public String getTargetName() {
return getProjectionAlias().orElse(null);
}

@Override
Expand All @@ -78,11 +157,11 @@ public String getSignature() {
sb.append(super.getSignature());

sb.append(" \"");
sb.append(sourceName);
sb.append(name);
sb.append("\"");

if (!sourceName.equals(targetName)) {
sb.append(" AS \"").append(targetName).append("\"");
if (projectionAlias != null) {
sb.append(" AS \"").append(projectionAlias).append("\"");
}

return sb.toString();
Expand All @@ -92,15 +171,14 @@ public String getSignature() {
public boolean equals(Object other) {
if (other instanceof ProjectionElem) {
ProjectionElem o = (ProjectionElem) other;
return sourceName.equals(o.getSourceName()) && targetName.equals(o.getTargetName());
return name.equals(o.getName()) && Objects.equals(getProjectionAlias(), o.getProjectionAlias());
}
return false;
}

@Override
public int hashCode() {
// Note: don't xor source and target since they will often be equal
return targetName.hashCode();
return Objects.hash(name, projectionAlias);
}

@Override
Expand Down
Loading