From: <tho...@us...> - 2011-03-01 01:05:41
|
Revision: 4261 http://bigdata.svn.sourceforge.net/bigdata/?rev=4261&view=rev Author: thompsonbry Date: 2011-03-01 01:05:33 +0000 (Tue, 01 Mar 2011) Log Message: ----------- Commit of partial support for rotating a key-range constraint onto an access path from/to key based on a path by MikeP. The logic in the SAIL which recognizes and lifts the key-range constraint onto the predicate is disabled in this commit. Look at ~817 of BigdataSailEvaluationStrategy3 to enable this behavior. Modified Paths: -------------- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/BOpBase.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/IPredicate.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/ap/Predicate.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/constraint/BooleanValueExpression.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/constraint/Constraint.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/join/PipelineJoin.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/striterator/AbstractKeyOrder.java branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/bop/rdf/aggregate/SUM.java branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/internal/IVUtility.java branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/internal/constraints/CompareBOp.java branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/internal/constraints/Constraint.java branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/internal/constraints/MathBOp.java branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/internal/constraints/ValueExpressionBOp.java branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/spo/SPOKeyOrder.java branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/spo/SPOPredicate.java branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/test/com/bigdata/bop/rdf/joinGraph/TestJoinGraphOnBSBMData.java branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/test/com/bigdata/rdf/internal/constraints/TestInlineConstraints.java branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/BigdataEvaluationStrategyImpl3.java branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/QueryHints.java branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/QueryOptimizerEnum.java branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/Rule2BOpUtility.java branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/bench/NanoSparqlClient.java branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/sop/SOp2BOpUtility.java branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/sop/SOpTree.java Added Paths: ----------- branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/internal/Range.java branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/internal/constraints/RangeBOp.java branches/QUADS_QUERY_BRANCH/bigdata-sails/src/test/com/bigdata/rdf/sail/TestRangeBOp.java Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/BOpBase.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/BOpBase.java 2011-02-28 16:26:37 UTC (rev 4260) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/BOpBase.java 2011-03-01 01:05:33 UTC (rev 4261) @@ -195,9 +195,12 @@ */ public BOpBase(final BOpBase op) { // deep copy the arguments. - args = deepCopy(op.args); +// args = deepCopy(op.args); // deep copy the annotations. - annotations = deepCopy(op.annotations); +// annotations = deepCopy(op.annotations); + // Note: only shallow copy is required to achieve immutable semantics! + args = Arrays.copyOf(op.args, op.args.length); + annotations = new LinkedHashMap<String, Object>(op.annotations); } // /** Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/IPredicate.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/IPredicate.java 2011-02-28 16:26:37 UTC (rev 4260) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/IPredicate.java 2011-03-01 01:05:33 UTC (rev 4261) @@ -678,6 +678,12 @@ * @return The newly annotated {@link IPredicate}. */ public IPredicate<E> setBOpId(int bopId); + + /** + * Return a copy of this predicate with a different {@link IVariableOrConstant} + * for the arg specified by the supplied index parameter. + */ + public IPredicate<E> setArg(int index, IVariableOrConstant arg); /** * Return <code>true</code> iff this operator is an access path which writes Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/ap/Predicate.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/ap/Predicate.java 2011-02-28 16:26:37 UTC (rev 4260) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/ap/Predicate.java 2011-03-01 01:05:33 UTC (rev 4261) @@ -419,6 +419,16 @@ } + public Predicate<E> setArg(final int index, final IVariableOrConstant arg) { + + final Predicate<E> tmp = this.clone(); + + tmp._set(index, arg); + + return tmp; + + } + /** * Add an {@link Annotations#INDEX_LOCAL_FILTER}. When there is a filter for * the named property, the filters are combined. Otherwise the filter is Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/constraint/BooleanValueExpression.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/constraint/BooleanValueExpression.java 2011-02-28 16:26:37 UTC (rev 4260) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/constraint/BooleanValueExpression.java 2011-03-01 01:05:33 UTC (rev 4261) @@ -27,16 +27,16 @@ import java.util.Map; import com.bigdata.bop.BOp; +import com.bigdata.bop.BOpBase; import com.bigdata.bop.IBindingSet; import com.bigdata.bop.IValueExpression; -import com.bigdata.bop.ImmutableBOp; /** * Base class for boolean value expression BOps. Value expressions perform some * evaluation on one or more value expressions as input and produce one * boolean as output. */ -public abstract class BooleanValueExpression extends ImmutableBOp +public abstract class BooleanValueExpression extends BOpBase implements IValueExpression<Boolean> { /** Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/constraint/Constraint.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/constraint/Constraint.java 2011-02-28 16:26:37 UTC (rev 4260) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/constraint/Constraint.java 2011-03-01 01:05:33 UTC (rev 4261) @@ -29,14 +29,14 @@ import org.apache.log4j.Logger; import com.bigdata.bop.BOp; +import com.bigdata.bop.BOpBase; import com.bigdata.bop.IBindingSet; import com.bigdata.bop.IConstraint; -import com.bigdata.bop.ImmutableBOp; /** * BOpConstraint that wraps a {@link BooleanValueExpression}. */ -public class Constraint extends ImmutableBOp implements IConstraint { +public class Constraint extends BOpBase implements IConstraint { /** * Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/join/PipelineJoin.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/join/PipelineJoin.java 2011-02-28 16:26:37 UTC (rev 4260) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/join/PipelineJoin.java 2011-03-01 01:05:33 UTC (rev 4261) @@ -1593,9 +1593,11 @@ this.accessPath = context.getAccessPath(relation, predicate); - if (log.isDebugEnabled()) - log.debug("joinOp=" + joinOp + ", #bindingSets=" + n - + ", accessPath=" + accessPath); + if (log.isDebugEnabled()) { + log.debug("joinOp=" + joinOp); + log.debug("#bindingSets=" + n); + log.debug("accessPath=" + accessPath); + } // convert to array for thread-safe traversal. this.bindingSets = bindingSets.toArray(new IBindingSet[n]); @@ -1644,7 +1646,11 @@ // range count of the as-bound access path (should be cached). final long rangeCount = accessPath .rangeCount(false/* exact */); - + + if (log.isDebugEnabled()) { + log.debug("range count: " + rangeCount); + } + stats.accessPathCount.increment(); stats.accessPathRangeCount.add(rangeCount); Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/striterator/AbstractKeyOrder.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/striterator/AbstractKeyOrder.java 2011-02-28 16:26:37 UTC (rev 4260) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/striterator/AbstractKeyOrder.java 2011-03-01 01:05:33 UTC (rev 4261) @@ -72,7 +72,7 @@ } - final public byte[] getFromKey(final IKeyBuilder keyBuilder, + public byte[] getFromKey(final IKeyBuilder keyBuilder, final IPredicate<E> predicate) { keyBuilder.reset(); @@ -99,17 +99,43 @@ } - return noneBound ? null : keyBuilder.getKey(); + final byte[] key = noneBound ? null : keyBuilder.getKey(); + return key; + } - final public byte[] getToKey(final IKeyBuilder keyBuilder, + public byte[] getToKey(final IKeyBuilder keyBuilder, final IPredicate<E> predicate) { - final byte[] from = getFromKey(keyBuilder, predicate); + keyBuilder.reset(); - return from == null ? null : SuccessorUtil.successor(from); + final int keyArity = getKeyArity(); // use the key's "arity". + boolean noneBound = true; + + for (int i = 0; i < keyArity; i++) { + + final IVariableOrConstant<?> term = predicate.get(getKeyOrder(i)); + + // Note: term MAY be null for the context position. + if (term == null || term.isVar()) + break; + + /* + * Note: If you need to override the default IKeyBuilder behavior do + * it in the invoked method. + */ + appendKeyComponent(keyBuilder, i, term.get()); + + noneBound = false; + + } + + final byte[] key = noneBound ? null : keyBuilder.getKey(); + + return key == null ? null : SuccessorUtil.successor(key); + } /** Modified: branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/bop/rdf/aggregate/SUM.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/bop/rdf/aggregate/SUM.java 2011-02-28 16:26:37 UTC (rev 4260) +++ branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/bop/rdf/aggregate/SUM.java 2011-03-01 01:05:33 UTC (rev 4261) @@ -25,8 +25,6 @@ import java.util.Map; -import org.openrdf.query.algebra.MathExpr.MathOp; - import com.bigdata.bop.BOp; import com.bigdata.bop.BOpBase; import com.bigdata.bop.IBindingSet; @@ -34,10 +32,10 @@ import com.bigdata.bop.IVariable; import com.bigdata.bop.aggregate.AggregateBase; import com.bigdata.bop.aggregate.IAggregate; -import com.bigdata.bop.aggregate.AggregateBase.FunctionCode; import com.bigdata.rdf.internal.IV; import com.bigdata.rdf.internal.IVUtility; import com.bigdata.rdf.internal.XSDLongIV; +import com.bigdata.rdf.internal.constraints.MathBOp.MathOp; import com.bigdata.rdf.model.BigdataLiteral; /** Modified: branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/internal/IVUtility.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/internal/IVUtility.java 2011-02-28 16:26:37 UTC (rev 4260) +++ branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/internal/IVUtility.java 2011-03-01 01:05:33 UTC (rev 4261) @@ -32,11 +32,10 @@ import java.util.ArrayList; import java.util.UUID; -import org.openrdf.query.algebra.MathExpr.MathOp; - import com.bigdata.btree.keys.IKeyBuilder; import com.bigdata.btree.keys.KeyBuilder; import com.bigdata.rawstore.Bytes; +import com.bigdata.rdf.internal.constraints.MathBOp.MathOp; import com.bigdata.rdf.model.BigdataBNode; import com.bigdata.rdf.model.BigdataLiteral; @@ -235,6 +234,10 @@ return new XSDDecimalIV(left.multiply(right)); case DIVIDE: return new XSDDecimalIV(left.divide(right)); + case MIN: + return new XSDDecimalIV(left.compareTo(right) < 0 ? left : right); + case MAX: + return new XSDDecimalIV(left.compareTo(right) > 0 ? left : right); default: throw new UnsupportedOperationException(); } @@ -253,6 +256,10 @@ return new XSDIntegerIV(left.multiply(right)); case DIVIDE: return new XSDIntegerIV(left.divide(right)); + case MIN: + return new XSDIntegerIV(left.compareTo(right) < 0 ? left : right); + case MAX: + return new XSDIntegerIV(left.compareTo(right) > 0 ? left : right); default: throw new UnsupportedOperationException(); } @@ -271,6 +278,10 @@ return new XSDFloatIV(left*right); case DIVIDE: return new XSDFloatIV(left/right); + case MIN: + return new XSDFloatIV(Math.min(left,right)); + case MAX: + return new XSDFloatIV(Math.max(left,right)); default: throw new UnsupportedOperationException(); } @@ -289,6 +300,10 @@ return new XSDDoubleIV(left*right); case DIVIDE: return new XSDDoubleIV(left/right); + case MIN: + return new XSDDoubleIV(Math.min(left,right)); + case MAX: + return new XSDDoubleIV(Math.max(left,right)); default: throw new UnsupportedOperationException(); } @@ -307,6 +322,10 @@ return new XSDIntIV(left*right); case DIVIDE: return new XSDIntIV(left/right); + case MIN: + return new XSDIntIV(Math.min(left,right)); + case MAX: + return new XSDIntIV(Math.max(left,right)); default: throw new UnsupportedOperationException(); } @@ -325,6 +344,10 @@ return new XSDLongIV(left*right); case DIVIDE: return new XSDLongIV(left/right); + case MIN: + return new XSDLongIV(Math.min(left,right)); + case MAX: + return new XSDLongIV(Math.max(left,right)); default: throw new UnsupportedOperationException(); } Added: branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/internal/Range.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/internal/Range.java (rev 0) +++ branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/internal/Range.java 2011-03-01 01:05:33 UTC (rev 4261) @@ -0,0 +1,73 @@ +/** + +Copyright (C) SYSTAP, LLC 2011. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package com.bigdata.rdf.internal; + +import java.io.Serializable; + +/** + * Represents a numerical range of IVs - a lower bound and an upper bound. + * Useful for constraining predicates to a particular range of values for the + * object. + */ +public class Range implements Serializable { + + /** + * + */ + private static final long serialVersionUID = -706615195901299026L; + + private final IV from, to; + + /** + * Construct a numerical range using two IVs. The range includes the from + * and to value (>= from && <= to). Non-inclusive from and to must be + * accomplished using a filter. The from must be less than or equal to the + * to. + */ + public Range(final IV from, final IV to) { + + if (!from.isNumeric()) + throw new IllegalArgumentException("not numeric: " + from); + if (!to.isNumeric()) + throw new IllegalArgumentException("not numeric: " + to); + + final int compare = IVUtility.numericalCompare(from, to); + if (compare > 0) + throw new IllegalArgumentException("invalid range: " + from+">"+to); + + this.from = from; + this.to = to; + + } + + public IV from() { + return from; + } + + public IV to() { + return to; + } + +} Modified: branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/internal/constraints/CompareBOp.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/internal/constraints/CompareBOp.java 2011-02-28 16:26:37 UTC (rev 4260) +++ branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/internal/constraints/CompareBOp.java 2011-03-01 01:05:33 UTC (rev 4261) @@ -93,6 +93,10 @@ public CompareBOp(final CompareBOp op) { super(op); } + + public CompareOp op() { + return (CompareOp) getRequiredProperty(Annotations.OP); + } public boolean accept(final IBindingSet s) { @@ -103,7 +107,7 @@ if (left == null || right == null) throw new SparqlTypeErrorException(); - final CompareOp op = (CompareOp) getProperty(Annotations.OP); + final CompareOp op = op(); if (left.isTermId() && right.isTermId()) { if (op == CompareOp.EQ || op == CompareOp.NE) { Modified: branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/internal/constraints/Constraint.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/internal/constraints/Constraint.java 2011-02-28 16:26:37 UTC (rev 4260) +++ branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/internal/constraints/Constraint.java 2011-03-01 01:05:33 UTC (rev 4261) @@ -86,6 +86,10 @@ return (EBVBOp) super.get(i); } + public IValueExpression<IV> getValueExpression() { + return get(0).get(0); + } + public boolean accept(final IBindingSet bs) { try { Modified: branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/internal/constraints/MathBOp.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/internal/constraints/MathBOp.java 2011-02-28 16:26:37 UTC (rev 4260) +++ branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/internal/constraints/MathBOp.java 2011-03-01 01:05:33 UTC (rev 4261) @@ -62,6 +62,25 @@ } + public enum MathOp { + PLUS, + MINUS, + MULTIPLY, + DIVIDE, + MIN, + MAX; + + public static MathOp valueOf(org.openrdf.query.algebra.MathExpr.MathOp op) { + switch(op) { + case PLUS: return MathOp.PLUS; + case MINUS: return MathOp.MINUS; + case MULTIPLY: return MathOp.MULTIPLY; + case DIVIDE: return MathOp.DIVIDE; + } + throw new IllegalArgumentException(); + } + } + /** * * @param left @@ -189,5 +208,5 @@ return h; } - + } Added: branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/internal/constraints/RangeBOp.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/internal/constraints/RangeBOp.java (rev 0) +++ branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/internal/constraints/RangeBOp.java 2011-03-01 01:05:33 UTC (rev 4261) @@ -0,0 +1,245 @@ +/** + +Copyright (C) SYSTAP, LLC 2006-2011. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +package com.bigdata.rdf.internal.constraints; + +import java.util.Map; + +import org.apache.log4j.Logger; + +import com.bigdata.bop.BOp; +import com.bigdata.bop.BOpBase; +import com.bigdata.bop.Constant; +import com.bigdata.bop.IBindingSet; +import com.bigdata.bop.IConstant; +import com.bigdata.bop.IValueExpression; +import com.bigdata.bop.IVariable; +import com.bigdata.bop.IVariableOrConstant; +import com.bigdata.bop.ImmutableBOp; +import com.bigdata.bop.NV; +import com.bigdata.rdf.error.SparqlTypeErrorException; +import com.bigdata.rdf.internal.IV; +import com.bigdata.rdf.internal.Range; + +final public class RangeBOp extends BOpBase + implements IVariable<Range> { + + /** + * + */ + private static final long serialVersionUID = 3368581489737593349L; + +// private static final Logger log = Logger.getLogger(RangeBOp.class); + + + public interface Annotations extends ImmutableBOp.Annotations { + + String VAR = RangeBOp.class.getName() + ".var"; + + String FROM = RangeBOp.class.getName() + ".from"; + + String TO = RangeBOp.class.getName() + ".to"; + + } + + @SuppressWarnings("rawtypes") + public RangeBOp(final IVariable<IV> var, + final IValueExpression<IV> from, + final IValueExpression<IV> to) { + + this(NOARGS, + NV.asMap(new NV(Annotations.VAR, var), + new NV(Annotations.FROM, from), + new NV(Annotations.TO, to))); + + } + + /** + * Required shallow copy constructor. + */ + public RangeBOp(final BOp[] args, Map<String,Object> anns) { + + super(args,anns); + + if (getProperty(Annotations.VAR) == null + || getProperty(Annotations.FROM) == null + || getProperty(Annotations.TO) == null) { + + throw new IllegalArgumentException(); + + } + + } + + /** + * Required deep copy constructor. + */ + public RangeBOp(final RangeBOp op) { + + super(op); + + } + + public IVariable<IV> var() { + return (IVariable<IV>) getRequiredProperty(Annotations.VAR); + } + + public IValueExpression<IV> from() { + return (IValueExpression<IV>) getRequiredProperty(Annotations.FROM); + } + + public IValueExpression<IV> to() { + return (IValueExpression<IV>) getRequiredProperty(Annotations.TO); + } + + final public Range get(final IBindingSet bs) { + +// log.debug("getting the asBound value"); + + final IV from = from().get(bs); + final IV to = to().get(bs); + +// log.debug("from: " + from); +// log.debug("to: " + to); + + // sort of like Var.get(), which returns null when the variable + // is not yet bound + if (from == null || to == null) + return null; + + try { + // let Range ctor() do the type checks and valid range checks + return new Range(from, to); + } catch (IllegalArgumentException ex) { + // log the reason the range is invalid +// if (log.isInfoEnabled()) +// log.info("dropping solution: " + ex.getMessage()); + // drop the solution + throw new SparqlTypeErrorException(); + } + + } + + final public RangeBOp asBound(final IBindingSet bs) { + + final RangeBOp asBound = (RangeBOp) this.clone(); + +// log.debug("getting the asBound value"); + + final IV from = from().get(bs); + final IV to = to().get(bs); + +// log.debug("from: " + from); +// log.debug("to: " + to); + + // sort of like Var.get(), which returns null when the variable + // is not yet bound + if (from == null || to == null) + return asBound; + + asBound._setProperty(Annotations.FROM, new Constant(from)); + asBound._setProperty(Annotations.TO, new Constant(to)); + + return asBound; + + } + + final public boolean isFullyBound() { + + return from() instanceof IConstant && to() instanceof IConstant; + + } + + @Override + public boolean isVar() { + return true; + } + + @Override + public boolean isConstant() { + return false; + } + + @Override + public Range get() { +// log.debug("somebody tried to get me"); + + return null; + } + + @Override + public String getName() { + return var().getName(); + } + + @Override + public boolean isWildcard() { + return false; + } + + + final public boolean equals(final IVariableOrConstant op) { + + if (op == null) + return false; + + if (this == op) + return true; + + if (op instanceof IVariable<?>) { + + return var().getName().equals(((IVariable<?>) op).getName()); + + } + + return false; + + } + + final private boolean _equals(final RangeBOp op) { + + return var().equals(op.var()) + && from().equals(op.from()) + && to().equals(op.to()); + + } + + /** + * Caches the hash code. + */ + private int hash = 0; + public int hashCode() { +// +// int h = hash; +// if (h == 0) { +// h = 31 * h + var().hashCode(); +// h = 31 * h + from().hashCode(); +// h = 31 * h + to().hashCode(); +// hash = h; +// } +// return h; +// + return var().hashCode(); + } + +} Modified: branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/internal/constraints/ValueExpressionBOp.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/internal/constraints/ValueExpressionBOp.java 2011-02-28 16:26:37 UTC (rev 4260) +++ branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/internal/constraints/ValueExpressionBOp.java 2011-03-01 01:05:33 UTC (rev 4261) @@ -27,8 +27,8 @@ import java.util.Map; import com.bigdata.bop.BOp; +import com.bigdata.bop.BOpBase; import com.bigdata.bop.IValueExpression; -import com.bigdata.bop.ImmutableBOp; import com.bigdata.rdf.internal.IV; /** @@ -36,7 +36,7 @@ * evaluation on one or more value expressions as input and produce one * value expression as output (boolean, numeric value, etc.) */ -public abstract class ValueExpressionBOp extends ImmutableBOp +public abstract class ValueExpressionBOp extends BOpBase implements IValueExpression<IV> { /** Modified: branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/spo/SPOKeyOrder.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/spo/SPOKeyOrder.java 2011-02-28 16:26:37 UTC (rev 4260) +++ branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/spo/SPOKeyOrder.java 2011-03-01 01:05:33 UTC (rev 4261) @@ -35,14 +35,19 @@ import java.util.Iterator; import java.util.NoSuchElementException; +import org.apache.log4j.Logger; + +import com.bigdata.bop.IConstant; import com.bigdata.bop.IPredicate; import com.bigdata.bop.IVariableOrConstant; import com.bigdata.btree.keys.IKeyBuilder; +import com.bigdata.btree.keys.SuccessorUtil; import com.bigdata.rdf.internal.IV; import com.bigdata.rdf.internal.IVUtility; +import com.bigdata.rdf.internal.Range; +import com.bigdata.rdf.internal.constraints.RangeBOp; import com.bigdata.rdf.model.StatementEnum; import com.bigdata.striterator.AbstractKeyOrder; -import com.bigdata.striterator.IKeyOrder; /** * Represents the key order used by an index for a triple relation. @@ -65,6 +70,8 @@ */ private static final long serialVersionUID = 87501920529732159L; + private static Logger log = Logger.getLogger(SPOKeyOrder.class); + /* * Note: these constants make it possible to use switch(index()) constructs. */ @@ -466,11 +473,92 @@ // // } - @Override + public byte[] getFromKey(final IKeyBuilder keyBuilder, + final IPredicate<ISPO> predicate) { + + keyBuilder.reset(); + + final int keyArity = getKeyArity(); // use the key's "arity". + + boolean noneBound = true; + + final RangeBOp range = (RangeBOp) + predicate.getProperty(SPOPredicate.Annotations.RANGE); + + for (int i = 0; i < keyArity; i++) { + + final int index = getKeyOrder(i); + + final IVariableOrConstant<?> term = predicate.get(index); + + if (term == null || term.isVar()) { + if (index == 2 && range != null && range.isFullyBound()) { + final IConstant<IV> c = (IConstant<IV>) range.from(); + appendKeyComponent(keyBuilder, i, c.get()); + noneBound = false; + } else { + break; + } + } else { + appendKeyComponent(keyBuilder, i, term.get()); + noneBound = false; + } + + } + + final byte[] key = noneBound ? null : keyBuilder.getKey(); + + return key; + + } + + public byte[] getToKey(final IKeyBuilder keyBuilder, + final IPredicate<ISPO> predicate) { + + keyBuilder.reset(); + + final int keyArity = getKeyArity(); // use the key's "arity". + + boolean noneBound = true; + + final RangeBOp range = (RangeBOp) + predicate.getProperty(SPOPredicate.Annotations.RANGE); + + for (int i = 0; i < keyArity; i++) { + + final int index = getKeyOrder(i); + + final IVariableOrConstant<?> term = predicate.get(index); + + // Note: term MAY be null for the context position. + if (term == null || term.isVar()) { + if (index == 2 && range != null && range.isFullyBound()) { + final IConstant<IV> c = (IConstant<IV>) range.to(); + appendKeyComponent(keyBuilder, i, c.get()); + noneBound = false; + } else { + break; + } + } else { + appendKeyComponent(keyBuilder, i, term.get()); + noneBound = false; + } + + } + + final byte[] key = noneBound ? null : keyBuilder.getKey(); + + return key == null ? null : SuccessorUtil.successor(key); + + } + + protected void appendKeyComponent(final IKeyBuilder keyBuilder, final int index, final Object keyComponent) { ((IV) keyComponent).encode(keyBuilder); + +// log.debug("appending key component: " + keyComponent); } @@ -672,32 +760,34 @@ static public SPOKeyOrder getKeyOrder(final IPredicate<ISPO> predicate, final int keyArity) { - final Object s = predicate.get(0).isVar() ? null : predicate - .get(0).get(); + final RangeBOp range = (RangeBOp) + predicate.getProperty(SPOPredicate.Annotations.RANGE); + + final boolean rangeIsBound = range != null && range.isFullyBound(); + + final boolean s = !predicate.get(0).isVar(); - final Object p = predicate.get(1).isVar() ? null : predicate - .get(1).get(); + final boolean p = !predicate.get(1).isVar(); - final Object o = predicate.get(2).isVar() ? null : predicate - .get(2).get(); + final boolean o = !predicate.get(2).isVar() || rangeIsBound; if (keyArity == 3) { // Note: Context is ignored! - if (s != null && p != null && o != null) { + if (s && p && o) { return SPO; - } else if (s != null && p != null) { + } else if (s && p) { return SPO; - } else if (s != null && o != null) { + } else if (s && o) { return OSP; - } else if (p != null && o != null) { + } else if (p && o) { return POS; - } else if (s != null) { + } else if (s) { return SPO; - } else if (p != null) { + } else if (p) { return POS; - } else if (o != null) { + } else if (o) { return OSP; } else { return SPO; @@ -708,39 +798,31 @@ @SuppressWarnings("unchecked") final IVariableOrConstant<IV> t = predicate.get(3); - final IV c = t == null ? null : (t.isVar() ? null : t.get()); + final boolean c = t != null && !t.isVar(); - /* - * if ((s == null && p == null && o == null && c == null) || (s != - * null && p == null && o == null && c == null) || (s != null && p - * != null && o == null && c == null) || (s != null && p != null && - * o != null && c == null) || (s != null && p != null && o != null - * && c != null)) { return SPOKeyOrder.SPOC; } - */ - - if ((s == null && p != null && o == null && c == null) - || (s == null && p != null && o != null && c == null) - || (s == null && p != null && o != null && c != null)) { + if ((!s && p && !o && !c) + || (!s && p && o && !c) + || (!s && p && o && c)) { return POCS; } - if ((s == null && p == null && o != null && c == null) - || (s == null && p == null && o != null && c != null) - || (s != null && p == null && o != null && c != null)) { + if ((!s && !p && o && !c) + || (!s && !p && o && c) + || (s && !p && o && c)) { return OCSP; } - if ((s == null && p == null && o == null && c != null) - || (s != null && p == null && o == null && c != null) - || (s != null && p != null && o == null && c != null)) { + if ((!s && !p && !o && c) + || (s && !p && !o && c) + || (s && p && !o && c)) { return CSPO; } - if ((s == null && p != null && o == null && c != null)) { + if ((!s && p && !o && c)) { return PCSO; } - if ((s != null && p == null && o != null && c == null)) { + if ((s && !p && o && !c)) { return SOPC; } Modified: branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/spo/SPOPredicate.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/spo/SPOPredicate.java 2011-02-28 16:26:37 UTC (rev 4260) +++ branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/spo/SPOPredicate.java 2011-03-01 01:05:33 UTC (rev 4261) @@ -26,12 +26,15 @@ import java.util.Map; import com.bigdata.bop.BOp; +import com.bigdata.bop.Constant; import com.bigdata.bop.IBindingSet; import com.bigdata.bop.IConstant; import com.bigdata.bop.IVariableOrConstant; import com.bigdata.bop.NV; import com.bigdata.bop.ap.Predicate; import com.bigdata.rdf.internal.IV; +import com.bigdata.rdf.internal.Range; +import com.bigdata.rdf.internal.constraints.RangeBOp; import com.bigdata.relation.rule.IAccessPathExpander; /** @@ -49,10 +52,17 @@ public class SPOPredicate extends Predicate<ISPO> { /** - * - */ - private static final long serialVersionUID = 1L; + * + */ + private static final long serialVersionUID = 3517916629931687107L; + public interface Annotations extends Predicate.Annotations { + + String RANGE = SPOPredicate.class.getName() + ".range"; + + } + + /** * Variable argument version of the shallow copy constructor. */ @@ -275,9 +285,9 @@ } @SuppressWarnings("unchecked") - final public IVariableOrConstant<IV> o() { + final public IVariableOrConstant o() { - return (IVariableOrConstant<IV>) get(2/* o */); + return (IVariableOrConstant) get(2/* o */); } @@ -287,6 +297,12 @@ return (IVariableOrConstant<IV>) get(3/* c */); } + + final public RangeBOp range() { + + return (RangeBOp) getProperty(Annotations.RANGE); + + } /** * Strengthened return type. @@ -296,8 +312,23 @@ @Override public SPOPredicate asBound(final IBindingSet bindingSet) { - return (SPOPredicate) super.asBound(bindingSet); + if (bindingSet == null) + throw new IllegalArgumentException(); + final SPOPredicate tmp = (SPOPredicate) super.asBound(bindingSet); + + final RangeBOp rangeBOp = range(); + + // we don't have a range bop for ?o + if (rangeBOp == null) + return tmp; + + final RangeBOp asBound = rangeBOp.asBound(bindingSet); + + tmp._setProperty(Annotations.RANGE, asBound); + + return tmp; + } } Modified: branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/test/com/bigdata/bop/rdf/joinGraph/TestJoinGraphOnBSBMData.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/test/com/bigdata/bop/rdf/joinGraph/TestJoinGraphOnBSBMData.java 2011-02-28 16:26:37 UTC (rev 4260) +++ branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/test/com/bigdata/bop/rdf/joinGraph/TestJoinGraphOnBSBMData.java 2011-03-01 01:05:33 UTC (rev 4261) @@ -5,7 +5,6 @@ import java.util.UUID; import org.openrdf.query.algebra.Compare.CompareOp; -import org.openrdf.query.algebra.MathExpr.MathOp; import org.openrdf.rio.RDFFormat; import com.bigdata.bop.BOp; @@ -18,7 +17,6 @@ import com.bigdata.bop.NV; import com.bigdata.bop.Var; import com.bigdata.bop.IPredicate.Annotations; -import com.bigdata.bop.engine.QueryEngine; import com.bigdata.bop.engine.QueryLog; import com.bigdata.bop.joinGraph.rto.JoinGraph; import com.bigdata.journal.ITx; @@ -30,6 +28,7 @@ import com.bigdata.rdf.internal.constraints.MathBOp; import com.bigdata.rdf.internal.constraints.NotBOp; import com.bigdata.rdf.internal.constraints.SameTermBOp; +import com.bigdata.rdf.internal.constraints.MathBOp.MathOp; import com.bigdata.rdf.model.BigdataLiteral; import com.bigdata.rdf.model.BigdataURI; import com.bigdata.rdf.model.BigdataValue; Modified: branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/test/com/bigdata/rdf/internal/constraints/TestInlineConstraints.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/test/com/bigdata/rdf/internal/constraints/TestInlineConstraints.java 2011-02-28 16:26:37 UTC (rev 4260) +++ branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/test/com/bigdata/rdf/internal/constraints/TestInlineConstraints.java 2011-03-01 01:05:33 UTC (rev 4261) @@ -39,7 +39,6 @@ import org.openrdf.model.vocabulary.RDF; import org.openrdf.query.QueryEvaluationException; import org.openrdf.query.algebra.Compare.CompareOp; -import org.openrdf.query.algebra.MathExpr.MathOp; import com.bigdata.bop.BOp; import com.bigdata.bop.BOpUtility; @@ -48,46 +47,36 @@ import com.bigdata.bop.IConstant; import com.bigdata.bop.IConstraint; import com.bigdata.bop.IPredicate; +import com.bigdata.bop.IPredicate.Annotations; import com.bigdata.bop.IValueExpression; import com.bigdata.bop.IVariable; import com.bigdata.bop.IVariableOrConstant; import com.bigdata.bop.NV; import com.bigdata.bop.PipelineOp; import com.bigdata.bop.Var; -import com.bigdata.bop.IPredicate.Annotations; import com.bigdata.bop.bindingSet.HashBindingSet; import com.bigdata.bop.engine.IRunningQuery; import com.bigdata.bop.engine.QueryEngine; import com.bigdata.bop.fed.QueryEngineFactory; -import com.bigdata.bop.joinGraph.IEvaluationPlan; -import com.bigdata.bop.joinGraph.IEvaluationPlanFactory; -import com.bigdata.bop.joinGraph.fast.DefaultEvaluationPlanFactory2; import com.bigdata.btree.IRangeQuery; import com.bigdata.rdf.error.SparqlTypeErrorException; import com.bigdata.rdf.internal.IV; import com.bigdata.rdf.internal.IVUtility; import com.bigdata.rdf.internal.XSDBooleanIV; +import com.bigdata.rdf.internal.constraints.MathBOp.MathOp; import com.bigdata.rdf.model.BigdataLiteral; import com.bigdata.rdf.model.BigdataURI; import com.bigdata.rdf.model.BigdataValue; import com.bigdata.rdf.model.BigdataValueFactory; import com.bigdata.rdf.rio.StatementBuffer; -import com.bigdata.rdf.rules.RuleContextEnum; import com.bigdata.rdf.sail.BigdataSail; import com.bigdata.rdf.sail.Rule2BOpUtility; -import com.bigdata.rdf.sail.sop.SOp2BOpUtility; -import com.bigdata.rdf.sail.sop.UnsupportedOperatorException; import com.bigdata.rdf.spo.SPOPredicate; import com.bigdata.rdf.store.AbstractTripleStore; import com.bigdata.rdf.store.ProxyTestCase; -import com.bigdata.relation.accesspath.ElementFilter; import com.bigdata.relation.accesspath.IAsynchronousIterator; import com.bigdata.relation.rule.IRule; import com.bigdata.relation.rule.Rule; -import com.bigdata.relation.rule.eval.ActionEnum; -import com.bigdata.relation.rule.eval.IJoinNexus; -import com.bigdata.relation.rule.eval.IJoinNexusFactory; -import com.bigdata.relation.rule.eval.ISolution; import com.bigdata.striterator.ChunkedWrappedIterator; import com.bigdata.striterator.Dechunkerator; import com.bigdata.striterator.IChunkedOrderedIterator; Modified: branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/BigdataEvaluationStrategyImpl3.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/BigdataEvaluationStrategyImpl3.java 2011-02-28 16:26:37 UTC (rev 4260) +++ branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/BigdataEvaluationStrategyImpl3.java 2011-03-01 01:05:33 UTC (rev 4261) @@ -28,6 +28,7 @@ import org.openrdf.query.algebra.And; import org.openrdf.query.algebra.Bound; import org.openrdf.query.algebra.Compare; +import org.openrdf.query.algebra.Compare.CompareOp; import org.openrdf.query.algebra.Filter; import org.openrdf.query.algebra.Group; import org.openrdf.query.algebra.IsBNode; @@ -37,7 +38,6 @@ import org.openrdf.query.algebra.Join; import org.openrdf.query.algebra.LeftJoin; import org.openrdf.query.algebra.MathExpr; -import org.openrdf.query.algebra.MathExpr.MathOp; import org.openrdf.query.algebra.MultiProjection; import org.openrdf.query.algebra.Not; import org.openrdf.query.algebra.Or; @@ -51,7 +51,6 @@ import org.openrdf.query.algebra.SameTerm; import org.openrdf.query.algebra.StatementPattern; import org.openrdf.query.algebra.StatementPattern.Scope; -import org.openrdf.query.algebra.Str; import org.openrdf.query.algebra.TupleExpr; import org.openrdf.query.algebra.UnaryTupleOperator; import org.openrdf.query.algebra.Union; @@ -85,6 +84,10 @@ import com.bigdata.rdf.internal.DummyIV; import com.bigdata.rdf.internal.IV; import com.bigdata.rdf.internal.XSDBooleanIV; +import com.bigdata.rdf.internal.XSDDecimalIV; +import com.bigdata.rdf.internal.XSDDoubleIV; +import com.bigdata.rdf.internal.XSDIntIV; +import com.bigdata.rdf.internal.XSDIntegerIV; import com.bigdata.rdf.internal.constraints.AndBOp; import com.bigdata.rdf.internal.constraints.CompareBOp; import com.bigdata.rdf.internal.constraints.Constraint; @@ -94,8 +97,10 @@ import com.bigdata.rdf.internal.constraints.IsLiteralBOp; import com.bigdata.rdf.internal.constraints.IsURIBOp; import com.bigdata.rdf.internal.constraints.MathBOp; +import com.bigdata.rdf.internal.constraints.MathBOp.MathOp; import com.bigdata.rdf.internal.constraints.NotBOp; import com.bigdata.rdf.internal.constraints.OrBOp; +import com.bigdata.rdf.internal.constraints.RangeBOp; import com.bigdata.rdf.internal.constraints.SameTermBOp; import com.bigdata.rdf.lexicon.LexiconRelation; import com.bigdata.rdf.model.BigdataValue; @@ -809,6 +814,17 @@ */ attachNamedGraphsFilterToSearches(sopTree); + if (false) { + /* + * Look for numerical filters that can be rotated inside predicates + */ + final Iterator<SOpGroup> groups = sopTree.groups(); + while (groups.hasNext()) { + final SOpGroup g = groups.next(); + attachRangeBOps(g); + } + } + /* * Gather variables required by Sesame outside of the query * evaluation (projection and global sesame filters). @@ -939,7 +955,7 @@ final IChunkedOrderedIterator<IBindingSet> it2 = new ChunkedWrappedIterator<IBindingSet>( new Dechunkerator<IBindingSet>(it1)); - + // Materialize IVs as RDF Values. final CloseableIteration<BindingSet, QueryEvaluationException> result = // Monitor IRunningQuery and cancel if Sesame iterator is closed. @@ -954,315 +970,6 @@ } -// /** -// * This is the method that will attempt to take a top-level join or left -// * join and turn it into a native bigdata rule. The Sesame operators Join -// * and LeftJoin share only the common base class BinaryTupleOperator, but -// * other BinaryTupleOperators are not supported by this method. Other -// * specific types of BinaryTupleOperators will cause this method to throw -// * an exception. -// * <p> -// * This method will also turn a single top-level StatementPattern into a -// * rule with one predicate in it. -// * <p> -// * Note: As a pre-condition, the {@link Value}s in the query expression -// * MUST have been rewritten as {@link BigdataValue}s and their term -// * identifiers MUST have been resolved. Any term identifier that remains -// * {@link IRawTripleStore#NULL} is an indication that there is no entry for -// * that {@link Value} in the database. Since the JOINs are required (vs -// * OPTIONALs), that means that there is no solution for the JOINs and an -// * {@link EmptyIteration} is returned rather than evaluating the query. -// * -// * @param join -// * @return native bigdata rule -// * @throws UnsupportedOperatorException -// * this exception will be thrown if the Sesame join contains any -// * SPARQL language constructs that cannot be converted into -// * the bigdata native rule model -// * @throws QueryEvaluationException -// */ -// private IRule createNativeQueryOld(final TupleExpr join) -// throws UnsupportedOperatorException, -// QueryEvaluationException { -// -// if (!(join instanceof StatementPattern || -// join instanceof Join || join instanceof LeftJoin || -// join instanceof Filter)) { -// throw new AssertionError( -// "only StatementPattern, Join, and LeftJoin supported"); -// } -// -// // flattened collection of statement patterns nested within this join, -// // along with whether or not each one is optional -// final Map<StatementPattern, Boolean> stmtPatterns = -// new LinkedHashMap<StatementPattern, Boolean>(); -// // flattened collection of filters nested within this join -// final Collection<Filter> filters = new LinkedList<Filter>(); -// -// // will throw EncounteredUnknownTupleExprException if the join -// // contains something we don't handle yet -//// collectStatementPatterns(join, stmtPatterns, filters); -// -// if (false) { -// for (Map.Entry<StatementPattern, Boolean> entry : -// stmtPatterns.entrySet()) { -// log.debug(entry.getKey() + ", optional=" + entry.getValue()); -// } -// for (Filter filter : filters) { -// log.debug(filter.getCondition()); -// } -// } -// -// // generate tails -// Collection<IPredicate> tails = new LinkedList<IPredicate>(); -// // keep a list of free text searches for later to solve a named graphs -// // problem -// final Map<IPredicate, StatementPattern> searches = -// new HashMap<IPredicate, StatementPattern>(); -// for (Map.Entry<StatementPattern, Boolean> entry : stmtPatterns -// .entrySet()) { -// StatementPattern sp = entry.getKey(); -// boolean optional = entry.getValue(); -// IPredicate tail = toPredicate(sp, optional); -// // encountered a value not in the database lexicon -// if (tail == null) { -// if (log.isDebugEnabled()) { -// log.debug("could not generate tail for: " + sp); -// } -// if (optional) { -// // for optionals, just skip the tail -// continue; -// } else { -// // for non-optionals, skip the entire rule -// return null; -// } -// } -// if (tail.getAccessPathExpander() instanceof FreeTextSearchExpander) { -// searches.put(tail, sp); -// } -// tails.add(tail); -// } -// -// /* -// * When in quads mode, we need to go through the free text searches and -// * make sure that they are properly filtered for the dataset where -// * needed. Joins will take care of this, so we only need to add a filter -// * when a search variable does not appear in any other tails that are -// * non-optional. -// * -// * @todo Bryan seems to think this can be fixed with a DISTINCT JOIN -// * mechanism in the rule evaluation. -// */ -// if (database.isQuads() && dataset != null) { -// for (IPredicate search : searches.keySet()) { -// final Set<URI> graphs; -// StatementPattern sp = searches.get(search); -// switch (sp.getScope()) { -// case DEFAULT_CONTEXTS: { -// /* -// * Query against the RDF merge of zero or more source -// * graphs. -// */ -// graphs = dataset.getDefaultGraphs(); -// break; -// } -// case NAMED_CONTEXTS: { -// /* -// * Query against zero or more named graphs. -// */ -// graphs = dataset.getNamedGraphs(); -// break; -// } -// default: -// throw new AssertionError(); -// } -// if (graphs == null) { -// continue; -// } -// // why would we use a constant with a free text search??? -// if (search.get(0).isConstant()) { -// throw new AssertionError(); -// } -// // get ahold of the search variable -// com.bigdata.bop.Var searchVar = -// (com.bigdata.bop.Var) search.get(0); -// if (log.isDebugEnabled()) { -// log.debug(searchVar); -// } -// // start by assuming it needs filtering, guilty until proven -// // innocent -// boolean needsFilter = true; -// // check the other tails one by one -// for (IPredicate<ISPO> tail : tails) { -// IAccessPathExpander<ISPO> expander = -// tail.getAccessPathExpander(); -// // only concerned with non-optional tails that are not -// // themselves magic searches -// if (expander instanceof FreeTextSearchExpander -// || tail.isOptional()) { -// continue; -// } -// // see if the search variable appears in this tail -// boolean appears = false; -// for (int i = 0; i < tail.arity(); i++) { -// IVariableOrConstant term = tail.get(i); -// if (log.isDebugEnabled()) { -// log.debug(term); -// } -// if (term.equals(searchVar)) { -// appears = true; -// break; -// } -// } -// // if it appears, we don't need a filter -// if (appears) { -// needsFilter = false; -// break; -// } -// } -// // if it needs a filter, add it to the expander -// if (needsFilter) { -// if (log.isDebugEnabled()) { -// log.debug("needs filter: " + searchVar); -// } -// FreeTextSearchExpander expander = (FreeTextSearchExpander) -// search.getAccessPathExpander(); -// expander.addNamedGraphsFilter(graphs); -// } -// } -// } -// -// // generate constraints -// final Collection<IConstraint> constraints = -// new LinkedList<IConstraint>(); -// final Iterator<Filter> filterIt = filters.iterator(); -// while (filterIt.hasNext()) { -// final Filter filter = filterIt.next(); -// final IConstraint constraint = toConstraint(filter.getCondition()); -// if (constraint != null) { -// // remove if we are able to generate a native constraint for it -// if (log.isDebugEnabled()) { -// log.debug("able to generate a constraint: " + constraint); -// } -// filterIt.remove(); -// constraints.add(constraint); -// } -// } -// -// /* -// * FIXME Native slice, DISTINCT, etc. are all commented out for now. -// * Except for ORDER_BY, support exists for all of these features in the -// * native rules, but we need to separate the rewrite of the tupleExpr -// * and its evaluation in order to properly handle this stuff. -// */ -// IQueryOptions queryOptions = QueryOptions.NONE; -// // if (slice) { -// // if (!distinct && !union) { -// // final ISlice slice = new Slice(offset, limit); -// // queryOptions = new QueryOptions(false/* distinct */, -// // true/* stable */, null/* orderBy */, slice); -// // } -// // } else { -// // if (distinct && !union) { -// // queryOptions = QueryOptions.DISTINCT; -// // } -// // } -// -//// if (log.isDebugEnabled()) { -//// for (IPredicate<ISPO> tail : tails) { -//// IAccessPathExpander<ISPO> expander = tail.getAccessPathExpander(); -//// if (expander != null) { -//// IAccessPath<ISPO> accessPath = database.getSPORelation() -//// .getAccessPath(tail); -//// accessPath = expander.getAccessPath(accessPath); -//// IChunkedOrderedIterator<ISPO> it = accessPath.iterator(); -//// while (it.hasNext()) { -//// log.debug(it.next().toString(database)); -//// } -//// } -//// } -//// } -// -// /* -// * Collect a set of variables required beyond just the join (i.e. -// * aggregation, projection, filters, etc.) -// */ -// Set<String> required = new HashSet<String>(); -// -// try { -// -// QueryModelNode p = join; -// while (true) { -// p = p.getParentNode(); -// if (log.isDebugEnabled()) { -// log.debug(p.getClass()); -// } -// if (p instanceof UnaryTupleOperator) { -// required.addAll(collectVariables((UnaryTupleOperator) p)); -// } -// if (p instanceof QueryRoot) { -// break; -// } -// } -// -// if (filters.size() > 0) { -// for (Filter filter : filters) { -// required.addAll(collectVariables((UnaryTupleOperator) filter)); -// } -// } -// -// } catch (Exception ex) { -// throw new QueryEvaluationException(ex); -// } -// -// IVariable[] requiredVars = new IVariable[required.size()]; -// int i = 0; -// for (String v : required) { -// requiredVars[i++] = com.bigdata.bop.Var.var(v); -// } -// -// if (log.isDebugEnabled()) { -// log.debug("required binding names: " + Arrays.toString(requiredVars)); -// } -// -//// if (starJoins) { // database.isQuads() == false) { -//// if (log.isDebugEnabled()) { -//// log.debug("generating star joins"); -//// } -//// tails = generateStarJoins(tails); -//// } -// -// // generate native rule -// IRule rule = new Rule("nativeJoin", -// // @todo should serialize the query string here for the logs. -// null, // head -// tails.toArray(new IPredicate[tails.size()]), queryOptions, -// // constraints on the rule. -// constraints.size() > 0 ? constraints -// .toArray(new IConstraint[constraints.size()]) : null, -// null/* constants */, null/* taskFactory */, requiredVars); -// -// if (BigdataStatics.debug) { -// System.err.println(join.toString()); -// System.err.println(rule.toString()); -// } -// -// // we have filters that we could not translate natively -// if (filters.size() > 0) { -// if (log.isDebugEnabled()) { -// log.debug("could not translate " + filters.size() -// + " filters into native constraints:"); -// for (Filter filter : filters) { -// log.debug("\n" + filter.getCondition()); -// } -// } -// // use the basic filter iterator for remaining filters -//// rule = new ProxyRuleWithSesameFilters(rule, filters); -// } -// -// return rule; -// -// } private void attachNamedGraphsFilterToSearches(final SOpTree sopTree) { @@ -1370,7 +1077,125 @@ } } + + protected void attachRangeBOps(final SOpGroup g) { + final Map<IVariable,Collection<IValueExpression>> lowerBounds = + new LinkedHashMap<IVariable,Collection<IValueExpression>>(); + final Map<IVariable,Collection<IValueExpression>> upperBounds = + new LinkedHashMap<IVariable,Collection<IValueExpression>>(); + + for (SOp sop : g) { + final BOp bop = sop.getBOp(); + if (!(bop instanceof Constraint)) { + continue; + } + final Constraint c = (Constraint) bop; + if (!(c.getValueExpression() instanceof Com... [truncated message content] |