private TupleExpr merge(List<Block> blocks, QueryMetadata md) { List<TupleExpr> tuples = new ArrayList<TupleExpr>(blocks.size()); boolean asLeftJoin = false; for (Block block : blocks) { if (block instanceof OptionalBlock) { if (!tuples.isEmpty()) { TupleExpr right = toTuple(block, md); LeftJoin lj = new LeftJoin(tuples.size() == 1 ? tuples.get(0) : join(tuples), right); tuples = new ArrayList<TupleExpr>(); tuples.add(lj); } else { asLeftJoin = true; tuples.add(toTuple(block, md)); } } else if (asLeftJoin) { LeftJoin lj = new LeftJoin(toTuple(block, md), tuples.get(0)); tuples = new ArrayList<TupleExpr>(); tuples.add(lj); asLeftJoin = false; } else { tuples.add(toTuple(block, md)); } } return join(tuples); }
private TupleExpr filter(TupleExpr tuple, Predicate expr, QueryMetadata md){ ValueExpr filter = toValue(expr, md); if (filter != null){ return new Filter(tuple, filter); }else{ return tuple; } }
tuple = toTuple(md.getWhere(), md); } else if (fromUIDs.size() == 1) { graphs.push(visit(fromUIDs.get(0), md)); tuple = toTuple(md.getWhere(), md); graphs.pop(); } else { QUID g = new QUID("__g"); graphs.push(visit(g, md)); BooleanBuilder b = new BooleanBuilder(); for (Constant<UID> co : fromUIDs){ b.or(g.eq(co)); tuple = filter(toTuple(md.getWhere(), md), b.getValue(), md); graphs.pop(); List<OrderElem> orderElements = new ArrayList<OrderElem>(); for (OrderSpecifier<?> os : md.getOrderBy()){ orderElements.add(new OrderElem(toValue(os.getTarget(), md), os.isAscending())); if (queryType == QueryLanguage.TUPLE){ for (Expression<?> expr : md.getProjection()){ ValueExpr val = toValue(expr, md); if (val instanceof Var){ projection.addElement(new ProjectionElem(((Var)val).getName())); PatternBlock pa = (PatternBlock)expr; ProjectionElemList p = new ProjectionElemList(); ValueExpr subject = toValue(pa.getSubject(), md); if (subject instanceof Var){
Operator<?> op = expr.getOperator(); if (op == Ops.AND){ return new And(toValue(expr.getArg(0), md), toValue(expr.getArg(1), md)); }else if (op == Ops.OR){ return new Or(toValue(expr.getArg(0), md), toValue(expr.getArg(1), md)); }else if (op == Ops.IN){ return new Not(toValue(expr.getArg(0), md)); }else if (COMPARE_OPS.containsKey(op)){ if (expr.getArg(1) instanceof SubQueryExpression<?>){ return new CompareAll(toValue(expr.getArg(0), md), toTuple(expr.getArg(1), md), COMPARE_OPS.get(op)); }else{ return new Compare(toValue(expr.getArg(0), md), toValue(expr.getArg(1), md), COMPARE_OPS.get(op)); return new MathExpr(toValue(expr.getArg(0), md), toValue(expr.getArg(1), md), MATH_OPS.get(op)); }else if (op == Ops.NEGATE){ return new MathExpr(toValue(expr.getArg(0), md), toValue(new ConstantImpl<LIT>(new LIT("-1", XSD.intType)), md), MathOp.MULTIPLY); }else if (op == Ops.MATCHES){ return new Regex(new Str(toValue(expr.getArg(0), md)), new Str(toValue(expr.getArg(1), md)), null); }else if (op == Ops.MATCHES_IC){ return new Regex(new Str(toValue(expr.getArg(0), md)), new Str(toValue(expr.getArg(1), md)), CASE_INSENSITIVE); }else if (op == Ops.STRING_IS_EMPTY){ return new Regex(new Str(toValue(expr.getArg(0), md)), "", false); }else if (op == Ops.IS_NULL){ return new Not(new Bound(toVar(expr.getArg(0), md))); }else if (op == Ops.IS_NOT_NULL){ return new Bound(toVar(expr.getArg(0), md)); }else if (op == Ops.EXISTS){ return new Exists(toTuple(expr.getArg(0), md));
@SuppressWarnings("unchecked") @Override public <D, Q> Q createQuery(QueryLanguage<D, Q> queryLanguage, D definition) { boolean queryInference = !inference.subClassOf(); if (queryLanguage.equals(QueryLanguage.SPARQL)){ return (Q)createSPARQLQuery((String) definition); }else if (queryLanguage.equals(QueryLanguage.TUPLE)){ SesameRDFVisitor visitor = new SesameRDFVisitor(dialect); TupleExpr tuple = visitor.visit((QueryMetadata)definition, queryLanguage); TupleQueryModel queryModel = new TupleQueryModel(tuple); TupleQuery query = DirectQuery.getQuery(connection, queryModel, queryInference); return (Q)new TupleQueryImpl(query, dialect); }else if (queryLanguage.equals(QueryLanguage.GRAPH)){ SesameRDFVisitor visitor = new SesameRDFVisitor(dialect); TupleExpr tuple = visitor.visit((QueryMetadata)definition, queryLanguage); GraphQueryModel queryModel = new GraphQueryModel(tuple); GraphQuery query = DirectQuery.getQuery(connection, queryModel, queryInference); return (Q)new GraphQueryImpl(query, dialect); }else if (queryLanguage.equals(QueryLanguage.BOOLEAN)){ SesameRDFVisitor visitor = new SesameRDFVisitor(dialect); TupleExpr tuple = visitor.visit((QueryMetadata)definition, queryLanguage); BooleanQueryModel queryModel = new BooleanQueryModel(tuple); BooleanQuery query = DirectQuery.getQuery(connection, queryModel, queryInference); return (Q)new BooleanQueryImpl(query, dialect); }else{ throw new UnsupportedQueryLanguageException(queryLanguage); } }
@Override public TupleExpr visit(GroupBlock expr, QueryMetadata md) { return visit((ContainerBlock)expr, md); }
@Override public Union visit(UnionBlock expr, QueryMetadata md) { List<TupleExpr> tuples = new ArrayList<TupleExpr>(expr.getBlocks().size()); for (Block block : expr.getBlocks()) { tuples.add(toTuple(block, md)); } Union rv = new Union(tuples.get(0), tuples.get(1)); for (int i = 2; i < tuples.size(); i++) { rv = new Union(rv, tuples.get(i)); } return rv; }
@Override public TupleExpr visit(PatternBlock expr, QueryMetadata md) { Var subject = toVar(expr.getSubject(), md); Var predicate = toVar(expr.getPredicate(), md); Var object = toVar(expr.getObject(), md); StatementPattern pattern; if (expr.getContext() != null){ pattern = new StatementPattern(subject, predicate, object, toVar(expr.getContext(), md)); }else if (!graphs.isEmpty()){ pattern = new StatementPattern(subject, predicate, object, graphs.peek()); }else{ pattern = new StatementPattern(subject, predicate, object); } // datatype inference (string typed literal can be replaced with untyped) via union if (object.getValue() != null && object.getValue() instanceof Literal && XMLSchema.STRING.equals(((Literal)object.getValue()).getDatatype())){ Var object2 = new Var(object.getName(), dialect.getLiteral(new LIT(object.getValue().stringValue(), RDF.text))); return new Union(pattern, new StatementPattern(subject, predicate, object2, pattern.getContextVar())); }else{ return pattern; } }
tuple = toTuple(md.getWhere(), md); } else if (fromUIDs.size() == 1) { graphs.push(visit(fromUIDs.get(0), md)); tuple = toTuple(md.getWhere(), md); graphs.pop(); } else { QUID g = new QUID("__g"); graphs.push(visit(g, md)); BooleanBuilder b = new BooleanBuilder(); for (Constant<UID> co : fromUIDs) { b.or(g.eq(co)); tuple = filter(toTuple(md.getWhere(), md), b.getValue(), md); graphs.pop(); List<OrderElem> orderElements = new ArrayList<OrderElem>(); for (OrderSpecifier<?> os : md.getOrderBy()) { orderElements.add(new OrderElem(toValue(os.getTarget(), md), os.isAscending())); if (queryType == QueryLanguage.TUPLE) { for (Expression<?> expr : md.getProjection()) { ValueExpr val = toValue(expr, md); if (val instanceof Var) { projection.addElement(new ProjectionElem(((Var) val).getName())); PatternBlock pa = (PatternBlock) expr; ProjectionElemList p = new ProjectionElemList(); ValueExpr subject = toValue(pa.getSubject(), md); if (subject instanceof Var) {
Operator<?> op = expr.getOperator(); if (op == Ops.AND) { return new And(toValue(expr.getArg(0), md), toValue(expr.getArg(1), md)); } else if (op == Ops.OR) { return new Or(toValue(expr.getArg(0), md), toValue(expr.getArg(1), md)); } else if (op == Ops.IN) { return new Not(toValue(expr.getArg(0), md)); } else if (COMPARE_OPS.containsKey(op)) { if (expr.getArg(1) instanceof SubQueryExpression<?>) { return new CompareAll(toValue(expr.getArg(0), md), toTuple(expr.getArg(1), md), COMPARE_OPS.get(op)); } else { return new Compare(toValue(expr.getArg(0), md), toValue(expr.getArg(1), md), COMPARE_OPS.get(op)); return new MathExpr(toValue(expr.getArg(0), md), toValue(expr.getArg(1), md), MATH_OPS.get(op)); } else if (op == Ops.NEGATE) { return new MathExpr(toValue(expr.getArg(0), md), toValue(new ConstantImpl<LIT>(new LIT("-1", XSD.intType)), md), MathOp.MULTIPLY); } else if (op == Ops.NEGATE) { return new MathExpr(toValue(expr.getArg(0), md), toValue(ConstantImpl.create(-1), md), MathOp.MULTIPLY); } else if (op == Ops.MATCHES) { return new Regex(new Str(toValue(expr.getArg(0), md)), new Str(toValue(expr.getArg(1), md)), null); } else if (op == Ops.MATCHES_IC) { return new Regex(new Str(toValue(expr.getArg(0), md)), new Str(toValue(expr.getArg(1), md)), CASE_INSENSITIVE); } else if (op == Ops.STRING_IS_EMPTY) { return new Regex(new Str(toValue(expr.getArg(0), md)), EMPTY_STRING, null); } else if (op == Ops.IS_NULL) { return new Not(new Bound(toVar(expr.getArg(0), md))); } else if (op == Ops.IS_NOT_NULL) { return new Bound(toVar(expr.getArg(0), md));
@SuppressWarnings("unchecked") @Override public <D, Q> Q createQuery(QueryLanguage<D, Q> queryLanguage, D definition) { boolean queryInference = !inference.subClassOf(); if (queryLanguage.equals(QueryLanguage.SPARQL)) { return (Q) createSPARQLQuery((String) definition); } else if (queryLanguage.equals(QueryLanguage.TUPLE)) { SesameRDFVisitor visitor = new SesameRDFVisitor(dialect); TupleExpr tuple = visitor.visit((QueryMetadata) definition, queryLanguage); TupleQueryModel queryModel = new TupleQueryModel(tuple); TupleQuery query = DirectQuery.getQuery(connection, queryModel, queryInference); return (Q) new TupleQueryImpl(query, dialect); } else if (queryLanguage.equals(QueryLanguage.GRAPH)) { SesameRDFVisitor visitor = new SesameRDFVisitor(dialect); TupleExpr tuple = visitor.visit((QueryMetadata) definition, queryLanguage); GraphQueryModel queryModel = new GraphQueryModel(tuple); GraphQuery query = DirectQuery.getQuery(connection, queryModel, queryInference); return (Q) new GraphQueryImpl(query, dialect); } else if (queryLanguage.equals(QueryLanguage.BOOLEAN)) { SesameRDFVisitor visitor = new SesameRDFVisitor(dialect); TupleExpr tuple = visitor.visit((QueryMetadata) definition, queryLanguage); BooleanQueryModel queryModel = new BooleanQueryModel(tuple); BooleanQuery query = DirectQuery.getQuery(connection, queryModel, queryInference); return (Q) new BooleanQueryImpl(query, dialect); } else { throw new UnsupportedQueryLanguageException(queryLanguage); } }
@Override public TupleExpr visit(GroupBlock expr, QueryMetadata md) { return visit((ContainerBlock) expr, md); }
@Override public Union visit(UnionBlock expr, QueryMetadata md) { List<TupleExpr> tuples = new ArrayList<TupleExpr>(expr.getBlocks().size()); for (Block block : expr.getBlocks()) { tuples.add(toTuple(block, md)); } return new Union(tuples); }
@Override public TupleExpr visit(PatternBlock expr, QueryMetadata md) { Var subject = toVar(expr.getSubject(), md); Var predicate = toVar(expr.getPredicate(), md); Var object = toVar(expr.getObject(), md); StatementPattern pattern; if (expr.getContext() != null) { pattern = new StatementPattern(subject, predicate, object, toVar(expr.getContext(), md)); } else if (!graphs.isEmpty()) { pattern = new StatementPattern(subject, predicate, object, graphs.peek()); } else { pattern = new StatementPattern(subject, predicate, object); } // datatype inference (string typed literal can be replaced with // untyped) via union if (object.getValue() != null && object.getValue() instanceof Literal && XMLSchema.STRING.equals(((Literal) object.getValue()).getDatatype())) { Var object2 = new Var(object.getName(), dialect.getLiteral(new LIT(object.getValue().stringValue(), RDF.text))); return new Union(pattern, new StatementPattern(subject, predicate, object2, pattern.getContextVar())); } else { return pattern; } }
tuple = toTuple(md.getWhere(), md); } else if (fromUIDs.size() == 1) { graphs.push(visit(fromUIDs.get(0), md)); tuple = toTuple(md.getWhere(), md); graphs.pop(); } else { QUID g = new QUID("__g"); graphs.push(visit(g, md)); BooleanBuilder b = new BooleanBuilder(); for (Constant<UID> co : fromUIDs) { b.or(g.eq(co)); tuple = filter(toTuple(md.getWhere(), md), b.getValue(), md); graphs.pop(); List<OrderElem> orderElements = new ArrayList<OrderElem>(); for (OrderSpecifier<?> os : md.getOrderBy()) { orderElements.add(new OrderElem(toValue(os.getTarget(), md), os.isAscending())); if (queryType == QueryLanguage.TUPLE) { for (Expression<?> expr : md.getProjection()) { ValueExpr val = toValue(expr, md); if (val instanceof Var) { projection.addElement(new ProjectionElem(((Var) val).getName())); PatternBlock pa = (PatternBlock) expr; ProjectionElemList p = new ProjectionElemList(); ValueExpr subject = toValue(pa.getSubject(), md); if (subject instanceof Var) {
Operator<?> op = expr.getOperator(); if (op == Ops.AND) { return new And(toValue(expr.getArg(0), md), toValue(expr.getArg(1), md)); } else if (op == Ops.OR) { return new Or(toValue(expr.getArg(0), md), toValue(expr.getArg(1), md)); } else if (op == Ops.IN) { return new Not(toValue(expr.getArg(0), md)); } else if (COMPARE_OPS.containsKey(op)) { if (expr.getArg(1) instanceof SubQueryExpression<?>) { return new CompareAll(toValue(expr.getArg(0), md), toTuple(expr.getArg(1), md), COMPARE_OPS.get(op)); } else { return new Compare(toValue(expr.getArg(0), md), toValue(expr.getArg(1), md), COMPARE_OPS.get(op)); return new MathExpr(toValue(expr.getArg(0), md), toValue(expr.getArg(1), md), MATH_OPS.get(op)); } else if (op == Ops.NEGATE) { return new MathExpr(toValue(expr.getArg(0), md), toValue(new ConstantImpl<LIT>(new LIT("-1", XSD.intType)), md), MathOp.MULTIPLY); } else if (op == Ops.MATCHES) { return new Regex(new Str(toValue(expr.getArg(0), md)), new Str(toValue(expr.getArg(1), md)), null); } else if (op == Ops.MATCHES_IC) { return new Regex(new Str(toValue(expr.getArg(0), md)), new Str(toValue(expr.getArg(1), md)), CASE_INSENSITIVE); } else if (op == Ops.STRING_IS_EMPTY) { return new Regex(new Str(toValue(expr.getArg(0), md)), "", false); } else if (op == Ops.IS_NULL) { return new Not(new Bound(toVar(expr.getArg(0), md))); } else if (op == Ops.IS_NOT_NULL) { return new Bound(toVar(expr.getArg(0), md)); } else if (op == Ops.EXISTS) { return new Exists(toTuple(expr.getArg(0), md));