Search in sources :

Example 1 with Group

use of org.eclipse.rdf4j.query.algebra.Group in project rdf4j by eclipse.

the class TupleExprBuilder method visit.

@Override
public Group visit(ASTGroupClause node, Object data) throws VisitorException {
    TupleExpr tupleExpr = (TupleExpr) data;
    Group g = new Group(tupleExpr);
    int childCount = node.jjtGetNumChildren();
    List<String> groupBindingNames = new ArrayList<String>();
    for (int i = 0; i < childCount; i++) {
        String name = (String) node.jjtGetChild(i).jjtAccept(this, g);
        groupBindingNames.add(name);
    }
    g.setGroupBindingNames(groupBindingNames);
    return g;
}
Also used : Group(org.eclipse.rdf4j.query.algebra.Group) ArrayList(java.util.ArrayList) TupleExpr(org.eclipse.rdf4j.query.algebra.TupleExpr)

Example 2 with Group

use of org.eclipse.rdf4j.query.algebra.Group in project rdf4j by eclipse.

the class TupleExprBuilder method visit.

@Override
public TupleExpr visit(ASTDescribeQuery node, Object data) throws VisitorException {
    TupleExpr tupleExpr = null;
    if (node.getWhereClause() != null) {
        // Start with building the graph pattern
        graphPattern = new GraphPattern();
        node.getWhereClause().jjtAccept(this, null);
        tupleExpr = graphPattern.buildTupleExpr();
        // Apply grouping
        Group group = null;
        ASTGroupClause groupNode = node.getGroupClause();
        if (groupNode != null) {
            tupleExpr = (TupleExpr) groupNode.jjtAccept(this, tupleExpr);
            group = (Group) tupleExpr;
        }
        if (node.getHavingClause() != null) {
            if (group == null) {
                // create implicit group
                group = new Group(tupleExpr);
            }
            // Apply HAVING group filter condition
            tupleExpr = processHavingClause(node.getHavingClause(), tupleExpr, group);
        }
        if (node.getOrderClause() != null) {
            if (group == null) {
                // create implicit group
                group = new Group(tupleExpr);
            }
            // Apply result ordering
            tupleExpr = processOrderClause(node.getOrderClause(), tupleExpr, group);
        }
        // Process limit and offset clauses
        ASTLimit limitNode = node.getLimit();
        long limit = -1;
        if (limitNode != null) {
            limit = (Long) limitNode.jjtAccept(this, null);
        }
        ASTOffset offsetNode = node.getOffset();
        long offset = -1;
        if (offsetNode != null) {
            offset = (Long) offsetNode.jjtAccept(this, null);
        }
        if (offset >= 1 || limit >= 0) {
            tupleExpr = new Slice(tupleExpr, offset, limit);
        }
    }
    // Process describe clause last
    return (TupleExpr) node.getDescribe().jjtAccept(this, tupleExpr);
}
Also used : Group(org.eclipse.rdf4j.query.algebra.Group) Slice(org.eclipse.rdf4j.query.algebra.Slice) TupleExpr(org.eclipse.rdf4j.query.algebra.TupleExpr)

Example 3 with Group

use of org.eclipse.rdf4j.query.algebra.Group 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;
}
Also used : Extension(org.eclipse.rdf4j.query.algebra.Extension) Group(org.eclipse.rdf4j.query.algebra.Group) ValueExpr(org.eclipse.rdf4j.query.algebra.ValueExpr) Var(org.eclipse.rdf4j.query.algebra.Var) ExtensionElem(org.eclipse.rdf4j.query.algebra.ExtensionElem) TupleExpr(org.eclipse.rdf4j.query.algebra.TupleExpr)

Example 4 with Group

use of org.eclipse.rdf4j.query.algebra.Group in project rdf4j by eclipse.

the class TupleExprBuilder method visit.

@Override
public TupleExpr visit(ASTSelectQuery node, Object data) throws VisitorException {
    GraphPattern parentGP = graphPattern;
    // Start with building the graph pattern
    graphPattern = new GraphPattern(parentGP);
    node.getWhereClause().jjtAccept(this, null);
    TupleExpr tupleExpr = graphPattern.buildTupleExpr();
    // Apply grouping
    Group group = null;
    ASTGroupClause groupNode = node.getGroupClause();
    if (groupNode != null) {
        tupleExpr = (TupleExpr) groupNode.jjtAccept(this, tupleExpr);
        group = (Group) tupleExpr;
    }
    final ASTHavingClause havingClause = node.getHavingClause();
    if (havingClause != null) {
        if (group == null) {
            // create implicit group
            group = new Group(tupleExpr);
        }
        // Apply HAVING group filter condition
        tupleExpr = processHavingClause(havingClause, tupleExpr, group);
    }
    // process bindings clause
    final ASTBindingsClause bindingsClause = node.getBindingsClause();
    if (bindingsClause != null) {
        tupleExpr = new Join((BindingSetAssignment) bindingsClause.jjtAccept(this, null), tupleExpr);
    }
    final ASTOrderClause orderClause = node.getOrderClause();
    if (orderClause != null) {
        if (group == null) {
            // create implicit group
            group = new Group(tupleExpr);
        }
        // Apply result ordering
        tupleExpr = processOrderClause(node.getOrderClause(), tupleExpr, group);
    }
    // Apply projection
    tupleExpr = (TupleExpr) node.getSelect().jjtAccept(this, tupleExpr);
    // Process limit and offset clauses
    ASTLimit limitNode = node.getLimit();
    long limit = -1L;
    if (limitNode != null) {
        limit = (Long) limitNode.jjtAccept(this, null);
    }
    ASTOffset offsetNode = node.getOffset();
    long offset = -1L;
    if (offsetNode != null) {
        offset = (Long) offsetNode.jjtAccept(this, null);
    }
    if (offset >= 1L || limit >= 0L) {
        tupleExpr = new Slice(tupleExpr, offset, limit);
    }
    if (parentGP != null) {
        parentGP.addRequiredTE(tupleExpr);
        graphPattern = parentGP;
    }
    return tupleExpr;
}
Also used : Group(org.eclipse.rdf4j.query.algebra.Group) BindingSetAssignment(org.eclipse.rdf4j.query.algebra.BindingSetAssignment) Join(org.eclipse.rdf4j.query.algebra.Join) TupleExpr(org.eclipse.rdf4j.query.algebra.TupleExpr) Slice(org.eclipse.rdf4j.query.algebra.Slice)

Example 5 with Group

use of org.eclipse.rdf4j.query.algebra.Group 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;
}
Also used : ProjectionElemList(org.eclipse.rdf4j.query.algebra.ProjectionElemList) Group(org.eclipse.rdf4j.query.algebra.Group) Var(org.eclipse.rdf4j.query.algebra.Var) QueryModelNode(org.eclipse.rdf4j.query.algebra.QueryModelNode) IsBNode(org.eclipse.rdf4j.query.algebra.IsBNode) ArrayList(java.util.ArrayList) GroupElem(org.eclipse.rdf4j.query.algebra.GroupElem) ExtensionElem(org.eclipse.rdf4j.query.algebra.ExtensionElem) Projection(org.eclipse.rdf4j.query.algebra.Projection) MultiProjection(org.eclipse.rdf4j.query.algebra.MultiProjection) Reduced(org.eclipse.rdf4j.query.algebra.Reduced) Distinct(org.eclipse.rdf4j.query.algebra.Distinct) AggregateOperator(org.eclipse.rdf4j.query.algebra.AggregateOperator) Order(org.eclipse.rdf4j.query.algebra.Order) ValueExpr(org.eclipse.rdf4j.query.algebra.ValueExpr) TupleExpr(org.eclipse.rdf4j.query.algebra.TupleExpr) Extension(org.eclipse.rdf4j.query.algebra.Extension) ProjectionElem(org.eclipse.rdf4j.query.algebra.ProjectionElem)

Aggregations

Group (org.eclipse.rdf4j.query.algebra.Group)8 TupleExpr (org.eclipse.rdf4j.query.algebra.TupleExpr)7 Slice (org.eclipse.rdf4j.query.algebra.Slice)4 BindingSetAssignment (org.eclipse.rdf4j.query.algebra.BindingSetAssignment)3 Extension (org.eclipse.rdf4j.query.algebra.Extension)3 ExtensionElem (org.eclipse.rdf4j.query.algebra.ExtensionElem)3 Join (org.eclipse.rdf4j.query.algebra.Join)3 ValueExpr (org.eclipse.rdf4j.query.algebra.ValueExpr)3 Var (org.eclipse.rdf4j.query.algebra.Var)3 ArrayList (java.util.ArrayList)2 AggregateOperator (org.eclipse.rdf4j.query.algebra.AggregateOperator)2 GroupElem (org.eclipse.rdf4j.query.algebra.GroupElem)2 MalformedQueryException (org.eclipse.rdf4j.query.MalformedQueryException)1 Distinct (org.eclipse.rdf4j.query.algebra.Distinct)1 Filter (org.eclipse.rdf4j.query.algebra.Filter)1 IsBNode (org.eclipse.rdf4j.query.algebra.IsBNode)1 MultiProjection (org.eclipse.rdf4j.query.algebra.MultiProjection)1 Order (org.eclipse.rdf4j.query.algebra.Order)1 Projection (org.eclipse.rdf4j.query.algebra.Projection)1 ProjectionElem (org.eclipse.rdf4j.query.algebra.ProjectionElem)1