use of org.eclipse.rdf4j.query.algebra.Extension in project rdf4j by eclipse.
the class TupleExprBuilder method visit.
@Override
public String visit(ASTGroupCondition node, Object data) throws VisitorException {
Group group = (Group) data;
TupleExpr arg = group.getArg();
Extension extension = null;
if (arg instanceof Extension) {
extension = (Extension) arg;
} else {
extension = new Extension();
}
String name = null;
ValueExpr ve = (ValueExpr) node.jjtGetChild(0).jjtAccept(this, data);
boolean aliased = false;
if (node.jjtGetNumChildren() > 1) {
aliased = true;
Var v = (Var) node.jjtGetChild(1).jjtAccept(this, data);
name = v.getName();
} else {
if (ve instanceof Var) {
name = ((Var) ve).getName();
} else {
aliased = true;
Var v = createAnonVar();
name = v.getName();
}
}
if (aliased) {
ExtensionElem elem = new ExtensionElem(ve, name);
extension.addElement(elem);
}
if (extension.getElements().size() > 0 && !(arg instanceof Extension)) {
extension.setArg(arg);
group.setArg(extension);
}
return name;
}
use of org.eclipse.rdf4j.query.algebra.Extension in project rdf4j by eclipse.
the class TupleExprBuilder method visit.
@Override
public TupleExpr visit(ASTSelect node, Object data) throws VisitorException {
TupleExpr result = (TupleExpr) data;
final Order orderClause = result instanceof Order ? (Order) result : null;
Extension extension = new Extension();
ProjectionElemList projElemList = new ProjectionElemList();
GroupFinder groupFinder = new GroupFinder();
result.visit(groupFinder);
Group group = groupFinder.getGroup();
boolean existingGroup = group != null;
List<String> aliasesInProjection = new ArrayList<String>();
for (ASTProjectionElem projElemNode : node.getProjectionElemList()) {
Node child = projElemNode.jjtGetChild(0);
String alias = projElemNode.getAlias();
if (alias != null) {
// aliased projection element
if (aliasesInProjection.contains(alias)) {
throw new VisitorException("duplicate use of alias '" + alias + "' in projection.");
}
// check if alias is not previously used.
if (result.getBindingNames().contains(alias)) {
throw new VisitorException("projection alias '" + alias + "' was previously used");
}
aliasesInProjection.add(alias);
ValueExpr valueExpr = (ValueExpr) child.jjtAccept(this, null);
String targetName = alias;
String sourceName = alias;
if (child instanceof ASTVar) {
sourceName = ((ASTVar) child).getName();
}
ProjectionElem elem = new ProjectionElem(sourceName, targetName);
projElemList.addElement(elem);
AggregateCollector collector = new AggregateCollector();
valueExpr.visit(collector);
if (collector.getOperators().size() > 0) {
elem.setAggregateOperatorInExpression(true);
for (AggregateOperator operator : collector.getOperators()) {
// Apply implicit grouping if necessary
if (group == null) {
group = new Group(result);
}
if (operator.equals(valueExpr)) {
group.addGroupElement(new GroupElem(alias, operator));
extension.setArg(group);
} else {
ValueExpr expr = (ValueExpr) operator.getParentNode();
Extension anonymousExtension = new Extension();
Var anonVar = createAnonVar();
expr.replaceChildNode(operator, anonVar);
anonymousExtension.addElement(new ExtensionElem(operator, anonVar.getName()));
anonymousExtension.setArg(result);
result = anonymousExtension;
group.addGroupElement(new GroupElem(anonVar.getName(), operator));
}
if (!existingGroup) {
result = group;
}
}
}
// add extension element reference to the projection element and
// to
// the extension
ExtensionElem extElem = new ExtensionElem(valueExpr, alias);
extension.addElement(extElem);
elem.setSourceExpression(extElem);
} else if (child instanceof ASTVar) {
Var projVar = (Var) child.jjtAccept(this, null);
ProjectionElem elem = new ProjectionElem(projVar.getName());
projElemList.addElement(elem);
VarCollector whereClauseVarCollector = new VarCollector();
result.visit(whereClauseVarCollector);
if (!whereClauseVarCollector.collectedVars.contains(projVar)) {
ExtensionElem extElem = new ExtensionElem(projVar, projVar.getName());
extension.addElement(extElem);
elem.setSourceExpression(extElem);
}
} else {
throw new IllegalStateException("required alias for non-Var projection elements not found");
}
}
if (!extension.getElements().isEmpty()) {
if (orderClause != null) {
// Extensions produced by SELECT expressions should be nested
// inside
// the ORDER BY clause, to make sure
// sorting can work on the newly introduced variable. See
// SES-892
// and SES-1809.
TupleExpr arg = orderClause.getArg();
extension.setArg(arg);
orderClause.setArg(extension);
result = orderClause;
} else {
extension.setArg(result);
result = extension;
}
}
result = new Projection(result, projElemList);
if (group != null) {
for (ProjectionElem elem : projElemList.getElements()) {
if (!elem.hasAggregateOperatorInExpression()) {
Set<String> groupNames = group.getBindingNames();
ExtensionElem extElem = elem.getSourceExpression();
if (extElem != null) {
ValueExpr expr = extElem.getExpr();
VarCollector collector = new VarCollector();
expr.visit(collector);
for (Var var : collector.getCollectedVars()) {
if (!groupNames.contains(var.getName())) {
throw new VisitorException("variable '" + var.getName() + "' in projection not present in GROUP BY.");
}
}
} else {
if (!groupNames.contains(elem.getTargetName())) {
throw new VisitorException("variable '" + elem.getTargetName() + "' in projection not present in GROUP BY.");
} else if (!groupNames.contains(elem.getSourceName())) {
throw new VisitorException("variable '" + elem.getSourceName() + "' in projection not present in GROUP BY.");
}
}
}
}
}
if (node.isSubSelect()) {
// set context var at the level of the projection. This allows us
// to distinguish named graphs selected in the
// outer query from named graphs selected as part of the sub-select.
((Projection) result).setProjectionContext(graphPattern.getContextVar());
}
if (node.isDistinct()) {
result = new Distinct(result);
} else if (node.isReduced()) {
result = new Reduced(result);
}
return result;
}
use of org.eclipse.rdf4j.query.algebra.Extension in project rdf4j by eclipse.
the class TupleExprBuilder method visit.
@Override
public TupleExpr visit(ASTConstruct node, Object data) throws VisitorException {
TupleExpr result = (TupleExpr) data;
// Collect construct triples
graphPattern = new GraphPattern();
super.visit(node, null);
TupleExpr constructExpr = graphPattern.buildTupleExpr();
// Retrieve all StatementPatterns from the construct expression
List<StatementPattern> statementPatterns = StatementPatternCollector.process(constructExpr);
if (constructExpr instanceof Filter) {
// sameTerm filters in construct (this can happen when there's a
// cyclic
// path defined, see SES-1685 and SES-2104)
// we remove the sameTerm filters by simply replacing all mapped
// variable occurrences
Set<SameTerm> sameTermConstraints = getSameTermConstraints((Filter) constructExpr);
statementPatterns = replaceSameTermVars(statementPatterns, sameTermConstraints);
}
Set<Var> constructVars = getConstructVars(statementPatterns);
VarCollector whereClauseVarCollector = new VarCollector();
result.visit(whereClauseVarCollector);
// Create BNodeGenerators for all anonymous variables
// NB: preserve order for a deterministic output
Map<Var, ExtensionElem> extElemMap = new LinkedHashMap<Var, ExtensionElem>();
for (Var var : constructVars) {
if (var.isAnonymous() && !extElemMap.containsKey(var)) {
ValueExpr valueExpr;
if (var.hasValue()) {
valueExpr = new ValueConstant(var.getValue());
} else {
valueExpr = new BNodeGenerator();
}
extElemMap.put(var, new ExtensionElem(valueExpr, var.getName()));
} else if (!whereClauseVarCollector.collectedVars.contains(var)) {
// non-anon var in construct clause not present in where clause
if (!extElemMap.containsKey(var)) {
// assign non-anonymous vars not present in where clause as
// extension elements. This is necessary to make external
// binding
// assingnment possible (see SES-996)
extElemMap.put(var, new ExtensionElem(var, var.getName()));
}
}
}
if (!extElemMap.isEmpty()) {
result = new Extension(result, extElemMap.values());
}
// Create a Projection for each StatementPattern in the constructor
List<ProjectionElemList> projList = new ArrayList<ProjectionElemList>();
for (StatementPattern sp : statementPatterns) {
ProjectionElemList projElemList = new ProjectionElemList();
projElemList.addElement(new ProjectionElem(sp.getSubjectVar().getName(), "subject"));
projElemList.addElement(new ProjectionElem(sp.getPredicateVar().getName(), "predicate"));
projElemList.addElement(new ProjectionElem(sp.getObjectVar().getName(), "object"));
if (sp.getContextVar() != null) {
projElemList.addElement(new ProjectionElem(sp.getContextVar().getName(), "context"));
}
projList.add(projElemList);
}
if (projList.size() == 1) {
result = new Projection(result, projList.get(0));
} else if (projList.size() > 1) {
result = new MultiProjection(result, projList);
} else {
// Empty constructor
result = new EmptySet();
}
return new Reduced(result);
}
use of org.eclipse.rdf4j.query.algebra.Extension in project rdf4j by eclipse.
the class SPARQLParserTest method testOrderByWithAliases1.
@Test
public void testOrderByWithAliases1() throws Exception {
String queryString = " SELECT ?x (SUM(?v1)/COUNT(?v1) as ?r) WHERE { ?x <urn:foo> ?v1 } GROUP BY ?x ORDER BY ?r";
ParsedQuery query = parser.parseQuery(queryString, null);
assertNotNull(query);
TupleExpr te = query.getTupleExpr();
assertTrue(te instanceof Projection);
te = ((Projection) te).getArg();
assertTrue(te instanceof Order);
te = ((Order) te).getArg();
assertTrue(te instanceof Extension);
}
use of org.eclipse.rdf4j.query.algebra.Extension in project rdf4j by eclipse.
the class AbstractQueryBuilder method multiProjection.
private UnaryTupleOperator multiProjection() {
MultiProjection aProjection = new MultiProjection();
Extension aExt = null;
for (StatementPattern aPattern : mProjectionPatterns) {
ProjectionElemList aList = new ProjectionElemList();
aList.addElement(new ProjectionElem(aPattern.getSubjectVar().getName(), "subject"));
aList.addElement(new ProjectionElem(aPattern.getPredicateVar().getName(), "predicate"));
aList.addElement(new ProjectionElem(aPattern.getObjectVar().getName(), "object"));
if (aPattern.getSubjectVar().hasValue()) {
if (aExt == null) {
aExt = new Extension();
}
aExt.addElements(new ExtensionElem(new ValueConstant(aPattern.getSubjectVar().getValue()), aPattern.getSubjectVar().getName()));
}
if (aPattern.getPredicateVar().hasValue()) {
if (aExt == null) {
aExt = new Extension();
}
aExt.addElements(new ExtensionElem(new ValueConstant(aPattern.getPredicateVar().getValue()), aPattern.getPredicateVar().getName()));
}
if (aPattern.getObjectVar().hasValue()) {
if (aExt == null) {
aExt = new Extension();
}
aExt.addElements(new ExtensionElem(new ValueConstant(aPattern.getObjectVar().getValue()), aPattern.getObjectVar().getName()));
}
aProjection.addProjection(aList);
}
if (aExt != null) {
aProjection.setArg(aExt);
}
return aProjection;
}
Aggregations