01: /*
02: * Copyright Aduna (http://www.aduna-software.com/) (c) 2007.
03: * Copyright James Leigh (c) 2006.
04: *
05: * Licensed under the Aduna BSD-style license.
06: */
07: package org.openrdf.query.algebra.evaluation.impl;
08:
09: import java.util.ArrayList;
10: import java.util.List;
11:
12: import org.openrdf.query.BindingSet;
13: import org.openrdf.query.Dataset;
14: import org.openrdf.query.algebra.And;
15: import org.openrdf.query.algebra.Filter;
16: import org.openrdf.query.algebra.TupleExpr;
17: import org.openrdf.query.algebra.ValueExpr;
18: import org.openrdf.query.algebra.evaluation.QueryOptimizer;
19: import org.openrdf.query.algebra.helpers.QueryModelNodeReplacer;
20: import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;
21:
22: /**
23: * Splits conjunctive constraints into seperate constraints.
24: *
25: * @author Arjohn Kampman
26: */
27: public class ConjunctiveConstraintSplitter implements QueryOptimizer {
28:
29: public void optimize(TupleExpr tupleExpr, Dataset dataset,
30: BindingSet bindings) {
31: tupleExpr.visit(new ConstraintVisitor(tupleExpr));
32: }
33:
34: protected class ConstraintVisitor extends
35: QueryModelVisitorBase<RuntimeException> {
36:
37: protected final QueryModelNodeReplacer replacer = new QueryModelNodeReplacer();
38:
39: protected final TupleExpr tupleExpr;
40:
41: public ConstraintVisitor(TupleExpr tupleExpr) {
42: this .tupleExpr = tupleExpr;
43: }
44:
45: @Override
46: public void meet(Filter filter) {
47: super .meet(filter);
48:
49: List<ValueExpr> conjunctiveConstraints = new ArrayList<ValueExpr>(
50: 16);
51: getConjunctiveConstraints(filter.getCondition(),
52: conjunctiveConstraints);
53:
54: TupleExpr filterArg = filter.getArg();
55:
56: for (int i = conjunctiveConstraints.size() - 1; i >= 1; i--) {
57: Filter newFilter = new Filter(filterArg,
58: conjunctiveConstraints.get(i));
59: filterArg = newFilter;
60: }
61:
62: filter.setCondition(conjunctiveConstraints.get(0));
63: filter.setArg(filterArg);
64: }
65:
66: protected void getConjunctiveConstraints(ValueExpr valueExpr,
67: List<ValueExpr> conjunctiveConstraints) {
68: if (valueExpr instanceof And) {
69: And and = (And) valueExpr;
70: getConjunctiveConstraints(and.getLeftArg(),
71: conjunctiveConstraints);
72: getConjunctiveConstraints(and.getRightArg(),
73: conjunctiveConstraints);
74: } else {
75: conjunctiveConstraints.add(valueExpr);
76: }
77: }
78: }
79: }
|