use of org.eclipse.rdf4j.query.algebra.ValueExpr in project rdf4j by eclipse.
the class TupleExprBuilder method visit.
@Override
public Object visit(ASTServiceGraphPattern node, Object data) throws VisitorException {
GraphPattern parentGP = graphPattern;
ValueExpr serviceRef = (ValueExpr) node.jjtGetChild(0).jjtAccept(this, null);
graphPattern = new GraphPattern(parentGP);
node.jjtGetChild(1).jjtAccept(this, null);
TupleExpr serviceExpr = graphPattern.buildTupleExpr();
if (serviceExpr instanceof SingletonSet)
// do not add an empty service block
return null;
String serviceExpressionString = node.getPatternString();
parentGP.addRequiredTE(new Service(mapValueExprToVar(serviceRef), serviceExpr, serviceExpressionString, node.getPrefixDeclarations(), node.getBaseURI(), node.isSilent()));
graphPattern = parentGP;
return null;
}
use of org.eclipse.rdf4j.query.algebra.ValueExpr in project rdf4j by eclipse.
the class TupleExprBuilder method visit.
@Override
public ValueExpr visit(ASTNotIn node, Object data) throws VisitorException {
ValueExpr result = null;
ValueExpr leftArg = (ValueExpr) data;
int listItemCount = node.jjtGetNumChildren();
if (listItemCount == 0) {
result = new ValueConstant(BooleanLiteral.TRUE);
} else if (listItemCount == 1) {
ValueExpr arg = (ValueExpr) node.jjtGetChild(0).jjtAccept(this, null);
result = new Compare(leftArg, arg, CompareOp.NE);
} else {
// create a set of conjunctive comparisons to represent the NOT IN
// operator: X NOT IN (a, b, c) -> X != a && X != b && X != c.
And and = new And();
And currentAnd = and;
for (int i = 0; i < listItemCount - 1; i++) {
ValueExpr arg = (ValueExpr) node.jjtGetChild(i).jjtAccept(this, null);
currentAnd.setLeftArg(new Compare(leftArg, arg, CompareOp.NE));
if (i == listItemCount - 2) {
// second-to-last item
arg = (ValueExpr) node.jjtGetChild(i + 1).jjtAccept(this, null);
currentAnd.setRightArg(new Compare(leftArg, arg, CompareOp.NE));
} else {
And newAnd = new And();
currentAnd.setRightArg(newAnd);
currentAnd = newAnd;
}
}
result = and;
}
return result;
}
use of org.eclipse.rdf4j.query.algebra.ValueExpr 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.ValueExpr in project rdf4j by eclipse.
the class TupleExprBuilder method visit.
@Override
public IRIFunction visit(ASTIRIFunc node, Object data) throws VisitorException {
ValueExpr expr = (ValueExpr) node.jjtGetChild(0).jjtAccept(this, null);
IRIFunction fn = new IRIFunction(expr);
fn.setBaseURI(node.getBaseURI());
return fn;
}
use of org.eclipse.rdf4j.query.algebra.ValueExpr in project rdf4j by eclipse.
the class TupleExprBuilder method visit.
@Override
public ValueExpr visit(ASTInfix node, Object data) throws VisitorException {
ValueExpr leftArg = (ValueExpr) node.jjtGetChild(0).jjtAccept(this, data);
ValueExpr rightArg = (ValueExpr) node.jjtGetChild(1).jjtAccept(this, leftArg);
return rightArg;
}
Aggregations