You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by an...@apache.org on 2018/02/12 09:08:56 UTC

[2/5] jena git commit: promote(Promote mode)

http://git-wip-us.apache.org/repos/asf/jena/blob/5f99f5f3/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/solver/OpExecutorTDB1.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/solver/OpExecutorTDB1.java b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/solver/OpExecutorTDB1.java
deleted file mode 100644
index 828bcab..0000000
--- a/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/solver/OpExecutorTDB1.java
+++ /dev/null
@@ -1,428 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.jena.tdb2.solver;
-
-import java.util.function.Predicate;
-
-import org.apache.jena.atlas.lib.tuple.Tuple ;
-import org.apache.jena.atlas.logging.Log ;
-import org.apache.jena.graph.Graph ;
-import org.apache.jena.graph.Node ;
-import org.apache.jena.sparql.ARQInternalErrorException ;
-import org.apache.jena.sparql.algebra.Op ;
-import org.apache.jena.sparql.algebra.op.* ;
-import org.apache.jena.sparql.algebra.optimize.TransformFilterPlacement ;
-import org.apache.jena.sparql.core.BasicPattern ;
-import org.apache.jena.sparql.core.Quad ;
-import org.apache.jena.sparql.core.Substitute ;
-import org.apache.jena.sparql.core.Var ;
-import org.apache.jena.sparql.engine.ExecutionContext ;
-import org.apache.jena.sparql.engine.QueryIterator ;
-import org.apache.jena.sparql.engine.iterator.QueryIterPeek ;
-import org.apache.jena.sparql.engine.main.OpExecutor ;
-import org.apache.jena.sparql.engine.main.OpExecutorFactory ;
-import org.apache.jena.sparql.engine.main.QC ;
-import org.apache.jena.sparql.engine.main.iterator.QueryIterGraph ;
-import org.apache.jena.sparql.engine.optimizer.reorder.ReorderProc ;
-import org.apache.jena.sparql.engine.optimizer.reorder.ReorderTransformation ;
-import org.apache.jena.sparql.expr.ExprList ;
-import org.apache.jena.sparql.mgt.Explain ;
-import org.apache.jena.tdb2.store.DatasetGraphTDB;
-import org.apache.jena.tdb2.store.GraphTDB;
-import org.apache.jena.tdb2.store.NodeId;
-import org.slf4j.Logger ;
-import org.slf4j.LoggerFactory ;
-
-/** TDB executor for algebra expressions.  It is the standard ARQ executor
- *  except for basic graph patterns and filtered basic graph patterns (currently).  
- * 
- * See also: StageGeneratorDirectTDB, a non-reordering 
- */
-public class OpExecutorTDB1 extends OpExecutor
-{
-    private static final Logger log = LoggerFactory.getLogger(OpExecutorTDB1.class) ;
-    
-    public final static OpExecutorFactory OpExecFactoryTDB = new OpExecutorFactory()
-    {
-        @Override
-        public OpExecutor create(ExecutionContext execCxt)
-        { return new OpExecutorTDB1(execCxt) ; }
-    } ;
-    
-    private final boolean isForTDB ;
-    
-    // A new compile object is created for each op compilation.
-    // So the execCxt is changing as we go through the query-compile-execute process  
-    public OpExecutorTDB1(ExecutionContext execCxt)
-    {
-        super(execCxt) ;
-        // NB. The dataset may be a TDB one, or a general one.
-        // Any merged union graph magic (for a TDB dataset was handled
-        // in QueryEngineTDB).
-        
-        isForTDB = (execCxt.getActiveGraph() instanceof GraphTDB) ;
-    }
-
-    @Override
-    protected QueryIterator exec(Op op, QueryIterator input) {
-        if ( level < 0 )
-            // Print only at top level (and we're called before level++) 
-            Explain.explain("TDB", op, super.execCxt.getContext()) ;
-        return super.exec(op, input) ;
-    } 
-    
-    // Retrieving nodes isn't so bad because they will be needed anyway.
-    // And if their duplicates, likely to be cached.
-    // Need to work with SolverLib which wraps the NodeId bindgins with a converter. 
-    
-    @Override
-    protected QueryIterator execute(OpDistinct opDistinct, QueryIterator input)
-    {
-        return super.execute(opDistinct, input) ;
-    }
-    
-    @Override
-    protected QueryIterator execute(OpReduced opReduced, QueryIterator input)
-    {
-        return super.execute(opReduced, input) ;
-    }
-    
-    @Override
-    protected QueryIterator execute(OpFilter opFilter, QueryIterator input)
-    {
-        if ( ! isForTDB )
-            return super.execute(opFilter, input) ;
-        
-        // If the filter does not apply to the input??
-        // Where does ARQ catch this?
-        
-        // (filter (bgp ...))
-        if ( OpBGP.isBGP(opFilter.getSubOp()) )
-        {
-            // Still may be a TDB graph in a non-TDB dataset (e.g. a named model)
-            GraphTDB graph = (GraphTDB)execCxt.getActiveGraph() ;
-            OpBGP opBGP = (OpBGP)opFilter.getSubOp() ;
-            return executeBGP(graph, opBGP, input, opFilter.getExprs(), execCxt) ;
-        }
-        
-        // (filter (quadpattern ...))
-        if ( opFilter.getSubOp() instanceof OpQuadPattern )
-        {
-            OpQuadPattern quadPattern = (OpQuadPattern)opFilter.getSubOp() ;
-            DatasetGraphTDB ds = (DatasetGraphTDB)execCxt.getDataset() ;
-            return optimizeExecuteQuads(ds, input,
-                                        quadPattern.getGraphNode(), quadPattern.getBasicPattern(),
-                                        opFilter.getExprs(), execCxt) ;
-        }
-    
-        // (filter (anything else))
-        return super.execute(opFilter, input) ;
-        }
-
-    // ---- Triple patterns
-    
-    @Override
-    protected QueryIterator execute(OpBGP opBGP, QueryIterator input)
-    {
-        if ( ! isForTDB )
-            return super.execute(opBGP, input) ;
-        
-        GraphTDB graph = (GraphTDB)execCxt.getActiveGraph() ;
-        return executeBGP(graph, opBGP, input, null, execCxt) ;
-       
-    }
-
-    @Override
-    protected QueryIterator execute(OpQuadPattern quadPattern, QueryIterator input)
-    {
-        if ( ! isForTDB )
-            return super.execute(quadPattern, input) ;
-            
-    //        DatasetGraph dg = execCxt.getDataset() ;
-    //        if ( ! ( dg instanceof DatasetGraphTDB ) )
-    //            throw new InternalErrorException("Not a TDB backed dataset in quad pattern execution") ;
-        
-        DatasetGraphTDB ds = (DatasetGraphTDB)execCxt.getDataset() ;
-        BasicPattern bgp = quadPattern.getBasicPattern() ;
-        Node gn = quadPattern.getGraphNode() ;
-        return optimizeExecuteQuads(ds, input, gn, bgp, null, execCxt) ;
-    }
-
-    @Override
-    protected QueryIterator execute(OpGraph opGraph, QueryIterator input)
-    {
-        // Path evaluation or dataset sets which do not go straight to the DatasetGraphTDB  
-        return new QueryIterGraph(input, opGraph, execCxt) ;
-    }
-
-    /** Execute a BGP (and filters) on a TDB graph, which may be in default storage or it may be a named graph */ 
-    private static QueryIterator executeBGP(GraphTDB graph, OpBGP opBGP, QueryIterator input, ExprList exprs, 
-                                            ExecutionContext execCxt)
-    {
-        // Is it the real default graph (normal route or explicitly named)?
-        if ( ! isDefaultGraphStorage(graph.getGraphName()))
-        {
-            // Not default storage - it's a named graph in storage. 
-            DatasetGraphTDB ds = graph.getDSG() ;
-            return optimizeExecuteQuads(ds, input, graph.getGraphName(), opBGP.getPattern(), exprs, execCxt) ;
-        }
-        
-        // Execute a BGP on the real default graph
-        return optimizeExecuteTriples(graph, input, opBGP.getPattern(), exprs, execCxt) ;
-    }
-
-    /** Execute, with optimization, a basic graph pattern on the default graph storage */
-    private static QueryIterator optimizeExecuteTriples(GraphTDB graph, QueryIterator input,
-                                                        BasicPattern pattern, ExprList exprs,
-                                                        ExecutionContext execCxt)
-    {
-        if ( ! input.hasNext() )
-            return input ;
-    
-        // -- Input
-        // Must pass this iterator into the next stage.
-        if ( pattern.size() >= 2 )
-        {
-            // Must be 2 or triples to reorder. 
-            ReorderTransformation transform = graph.getDSG().getReorderTransform() ;
-            if ( transform != null )
-            {
-                QueryIterPeek peek = QueryIterPeek.create(input, execCxt) ;
-                input = peek ; // Must pass on
-                pattern = reorder(pattern, peek, transform) ;
-            }
-        }
-        // -- Filter placement
-            
-        Op op = null ;
-        if ( exprs != null )
-            op = TransformFilterPlacement.transform(exprs, pattern) ;
-        else
-            op = new OpBGP(pattern) ;
-        
-        return plainExecute(op, input, execCxt) ;
-    }
-
-    /** Execute, with optimization, a quad pattern */
-    private static QueryIterator optimizeExecuteQuads(DatasetGraphTDB ds, 
-                                                      QueryIterator input, 
-                                                      Node gn, BasicPattern bgp,
-                                                      ExprList exprs, ExecutionContext execCxt)
-    {
-        if ( ! input.hasNext() )
-            return input ;
-
-        // ---- Graph names with special meaning. 
-
-        gn = decideGraphNode(gn, execCxt) ;
-        if ( gn == null )
-            return optimizeExecuteTriples(ds.getDefaultGraphTDB(), input, bgp, exprs, execCxt) ;
-        
-        // ---- Execute quads+filters
-        if ( bgp.size() >= 2 )
-        {
-            ReorderTransformation transform = ds.getReorderTransform() ;
-    
-            if ( transform != null )
-            {
-                QueryIterPeek peek = QueryIterPeek.create(input, execCxt) ;
-                input = peek ; // Original input now invalid.
-                bgp = reorder(bgp, peek, transform) ;
-            }
-        }
-        // -- Filter placement
-        Op op = null ;
-        if ( exprs != null )
-            op = TransformFilterPlacement.transform(exprs, gn, bgp) ;
-        else
-            op = new OpQuadPattern(gn, bgp) ;
-
-        return plainExecute(op, input, execCxt) ;
-    }
-
-    /** Execute without modification of the op - does <b>not</b> apply special graph name translations */ 
-    private static QueryIterator plainExecute(Op op, QueryIterator input, ExecutionContext execCxt)
-    {
-        // -- Execute
-        // Switch to a non-reordering executor
-        // The Op may be a sequence due to TransformFilterPlacement
-        // so we need to do a full execution step, not go straight to the SolverLib.
-        
-        ExecutionContext ec2 = new ExecutionContext(execCxt) ;
-        ec2.setExecutor(plainFactory) ;
-
-        // Solve without going through this executor again.
-        // There would be issues of nested patterns but this is only a
-        // (filter (bgp...)) or (filter (quadpattern ...)) or sequences of these.
-        // so there are no nested patterns to reorder.
-        return QC.execute(op, input, ec2) ;
-    }
-
-    private static BasicPattern reorder(BasicPattern pattern, QueryIterPeek peek, ReorderTransformation transform)
-    {
-        if ( transform != null )
-        {
-            // This works by getting one result from the peek iterator,
-            // and creating the more gounded BGP. The tranform is used to
-            // determine the best order and the transformation is returned. This
-            // transform is applied to the unsubstituted pattern (which will be
-            // substituted as part of evaluation.
-            
-            if ( ! peek.hasNext() )
-                throw new ARQInternalErrorException("Peek iterator is already empty") ;
- 
-            BasicPattern pattern2 = Substitute.substitute(pattern, peek.peek() ) ;
-            // Calculate the reordering based on the substituted pattern.
-            ReorderProc proc = transform.reorderIndexes(pattern2) ;
-            // Then reorder original patten
-            pattern = proc.reorder(pattern) ;
-        }
-        return pattern ;
-    }
-    
-    /** Handle special graph node names.  
-     * Returns null for default graph in storage (use the triple table).
-     * Returns Node.ANY for the union graph
-     */
-    public static Node decideGraphNode(Node gn, ExecutionContext execCxt)
-    {
-     // ---- Graph names with special meaning. 
-    
-        // Graph names with special meaning:
-        //   Quad.defaultGraphIRI -- the IRI used in GRAPH <> to mean the default graph.
-        //   Quad.defaultGraphNodeGenerated -- the internal marker node used for the quad form of queries.
-        //   Quad.unionGraph -- the IRI used in GRAPH <> to mean the union of named graphs
-    
-        if ( isDefaultGraphStorage(gn) ) 
-        {
-            // Storage concrete, default graph. 
-            // Either outside GRAPH (no implicit union)
-            // or using the "name" of the default graph
-            return null ;
-        }
-
-        // Not default storage graph.
-        // ---- Union (RDF Merge) of named graphs
-
-        if ( Quad.isUnionGraph(gn) ) 
-            return Node.ANY ;
-        boolean doingUnion = false ;
-        
-        return gn ;
-    }
-
-    // Is this a query against the real default graph in the storage (in a 3-tuple table). 
-    private static boolean isDefaultGraphStorage(Node gn)
-    {
-        if ( gn == null )
-            return true ;
-        
-        // Is it the implicit name for default graph.
-        if ( Quad.isDefaultGraph(gn) )
-            // Not accessing the union of named graphs as the default graph
-            // and pattern is directed to the default graph.
-            return true ;
-    
-        return false ;
-    }
-    
-    @Override
-    protected QueryIterator execute(OpDatasetNames dsNames, QueryIterator input)
-    { 
-        DatasetGraphTDB ds = (DatasetGraphTDB)execCxt.getDataset() ;
-        Predicate<Tuple<NodeId>> filter = QC2.getFilter(execCxt.getContext()) ;
-        Node gn = dsNames.getGraphNode() ;
-        if ( Var.isVar(gn) )
-            return SolverLib.graphNames(ds, dsNames.getGraphNode(), input, filter, execCxt) ;
-        else
-            return SolverLib.testForGraphName(ds, dsNames.getGraphNode(), input, filter, execCxt) ;
-    }
-
-    // ---- OpExecute factories and plain executor.
-    
-    private static OpExecutorFactory plainFactory = new OpExecutorPlainFactoryTDB() ;
-    private static class OpExecutorPlainFactoryTDB implements OpExecutorFactory
-    {
-        @Override
-        public OpExecutor create(ExecutionContext execCxt)
-        {
-            return new OpExecutorPlainTDB(execCxt) ;
-        }
-    }
-
-    /** An op executor that simply executes a BGP or QuadPattern without any reordering */ 
-    private static class OpExecutorPlainTDB extends OpExecutor
-    {
-        Predicate<Tuple<NodeId>> filter = null ;
-        
-        public OpExecutorPlainTDB(ExecutionContext execCxt)
-        {
-            super(execCxt) ;
-            filter = QC2.getFilter(execCxt.getContext()) ;
-        }
-        
-        @Override
-        public QueryIterator execute(OpBGP opBGP, QueryIterator input)
-        {
-            Graph g = execCxt.getActiveGraph() ;
-            
-            if ( g instanceof GraphTDB )
-            {
-                BasicPattern bgp = opBGP.getPattern() ;
-                Explain.explain("Execute", bgp, execCxt.getContext()) ;
-                // Triple-backed (but may be named as explicit default graph).
-                //return SolverLib.execute((GraphTDB)g, bgp, input, filter, execCxt) ;
-                GraphTDB gtdb = (GraphTDB)g ;
-                Node gn = decideGraphNode(gtdb.getGraphName(), execCxt) ;
-                return SolverLib.execute(gtdb.getDSG(), gn, bgp, input, filter, execCxt) ;
-            }
-            Log.warn(this, "Non-GraphTDB passed to OpExecutorPlainTDB") ;
-            return super.execute(opBGP, input) ;
-        }
-        
-        @Override
-        public QueryIterator execute(OpQuadPattern opQuadPattern, QueryIterator input)
-        {
-            Node gn = opQuadPattern.getGraphNode() ;
-            gn = decideGraphNode(gn, execCxt) ;
-            
-            if ( execCxt.getDataset() instanceof DatasetGraphTDB )
-            {
-                DatasetGraphTDB ds = (DatasetGraphTDB)execCxt.getDataset() ;
-                Explain.explain("Execute", opQuadPattern.getPattern(), execCxt.getContext()) ;
-                BasicPattern bgp = opQuadPattern.getBasicPattern() ;
-                return SolverLib.execute(ds, gn, bgp, input, filter, execCxt) ;
-            }
-            // Maybe a TDB named graph inside a non-TDB dataset.
-            Graph g = execCxt.getActiveGraph() ;
-            if ( g instanceof GraphTDB )
-            {
-                // Triples graph from TDB (which is the default graph of the dataset),
-                // used a named graph in a composite dataset.
-                BasicPattern bgp = opQuadPattern.getBasicPattern() ;
-                Explain.explain("Execute", bgp, execCxt.getContext()) ;
-                // Don't pass in G -- gn may be different.
-                return SolverLib.execute(((GraphTDB)g).getDSG(), gn, bgp, input, filter, execCxt) ;
-            }
-            Log.warn(this, "Non-DatasetGraphTDB passed to OpExecutorPlainTDB") ;
-            return super.execute(opQuadPattern, input) ;
-        }
-
-    }
-}

http://git-wip-us.apache.org/repos/asf/jena/blob/5f99f5f3/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/solver/OpExecutorTDB2.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/solver/OpExecutorTDB2.java b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/solver/OpExecutorTDB2.java
new file mode 100644
index 0000000..aa0f5df
--- /dev/null
+++ b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/solver/OpExecutorTDB2.java
@@ -0,0 +1,428 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.tdb2.solver;
+
+import java.util.function.Predicate;
+
+import org.apache.jena.atlas.lib.tuple.Tuple ;
+import org.apache.jena.atlas.logging.Log ;
+import org.apache.jena.graph.Graph ;
+import org.apache.jena.graph.Node ;
+import org.apache.jena.sparql.ARQInternalErrorException ;
+import org.apache.jena.sparql.algebra.Op ;
+import org.apache.jena.sparql.algebra.op.* ;
+import org.apache.jena.sparql.algebra.optimize.TransformFilterPlacement ;
+import org.apache.jena.sparql.core.BasicPattern ;
+import org.apache.jena.sparql.core.Quad ;
+import org.apache.jena.sparql.core.Substitute ;
+import org.apache.jena.sparql.core.Var ;
+import org.apache.jena.sparql.engine.ExecutionContext ;
+import org.apache.jena.sparql.engine.QueryIterator ;
+import org.apache.jena.sparql.engine.iterator.QueryIterPeek ;
+import org.apache.jena.sparql.engine.main.OpExecutor ;
+import org.apache.jena.sparql.engine.main.OpExecutorFactory ;
+import org.apache.jena.sparql.engine.main.QC ;
+import org.apache.jena.sparql.engine.main.iterator.QueryIterGraph ;
+import org.apache.jena.sparql.engine.optimizer.reorder.ReorderProc ;
+import org.apache.jena.sparql.engine.optimizer.reorder.ReorderTransformation ;
+import org.apache.jena.sparql.expr.ExprList ;
+import org.apache.jena.sparql.mgt.Explain ;
+import org.apache.jena.tdb2.store.DatasetGraphTDB;
+import org.apache.jena.tdb2.store.GraphTDB;
+import org.apache.jena.tdb2.store.NodeId;
+import org.slf4j.Logger ;
+import org.slf4j.LoggerFactory ;
+
+/** TDB executor for algebra expressions.  It is the standard ARQ executor
+ *  except for basic graph patterns and filtered basic graph patterns (currently).  
+ * 
+ * See also: StageGeneratorDirectTDB, a non-reordering 
+ */
+public class OpExecutorTDB2 extends OpExecutor
+{
+    private static final Logger log = LoggerFactory.getLogger(OpExecutorTDB2.class) ;
+    
+    public final static OpExecutorFactory OpExecFactoryTDB = new OpExecutorFactory()
+    {
+        @Override
+        public OpExecutor create(ExecutionContext execCxt)
+        { return new OpExecutorTDB2(execCxt) ; }
+    } ;
+    
+    private final boolean isForTDB ;
+    
+    // A new compile object is created for each op compilation.
+    // So the execCxt is changing as we go through the query-compile-execute process  
+    public OpExecutorTDB2(ExecutionContext execCxt)
+    {
+        super(execCxt) ;
+        // NB. The dataset may be a TDB one, or a general one.
+        // Any merged union graph magic (for a TDB dataset was handled
+        // in QueryEngineTDB).
+        
+        isForTDB = (execCxt.getActiveGraph() instanceof GraphTDB) ;
+    }
+
+    @Override
+    protected QueryIterator exec(Op op, QueryIterator input) {
+        if ( level < 0 )
+            // Print only at top level (and we're called before level++) 
+            Explain.explain("TDB", op, super.execCxt.getContext()) ;
+        return super.exec(op, input) ;
+    } 
+    
+    // Retrieving nodes isn't so bad because they will be needed anyway.
+    // And if their duplicates, likely to be cached.
+    // Need to work with SolverLib which wraps the NodeId bindgins with a converter. 
+    
+    @Override
+    protected QueryIterator execute(OpDistinct opDistinct, QueryIterator input)
+    {
+        return super.execute(opDistinct, input) ;
+    }
+    
+    @Override
+    protected QueryIterator execute(OpReduced opReduced, QueryIterator input)
+    {
+        return super.execute(opReduced, input) ;
+    }
+    
+    @Override
+    protected QueryIterator execute(OpFilter opFilter, QueryIterator input)
+    {
+        if ( ! isForTDB )
+            return super.execute(opFilter, input) ;
+        
+        // If the filter does not apply to the input??
+        // Where does ARQ catch this?
+        
+        // (filter (bgp ...))
+        if ( OpBGP.isBGP(opFilter.getSubOp()) )
+        {
+            // Still may be a TDB graph in a non-TDB dataset (e.g. a named model)
+            GraphTDB graph = (GraphTDB)execCxt.getActiveGraph() ;
+            OpBGP opBGP = (OpBGP)opFilter.getSubOp() ;
+            return executeBGP(graph, opBGP, input, opFilter.getExprs(), execCxt) ;
+        }
+        
+        // (filter (quadpattern ...))
+        if ( opFilter.getSubOp() instanceof OpQuadPattern )
+        {
+            OpQuadPattern quadPattern = (OpQuadPattern)opFilter.getSubOp() ;
+            DatasetGraphTDB ds = (DatasetGraphTDB)execCxt.getDataset() ;
+            return optimizeExecuteQuads(ds, input,
+                                        quadPattern.getGraphNode(), quadPattern.getBasicPattern(),
+                                        opFilter.getExprs(), execCxt) ;
+        }
+    
+        // (filter (anything else))
+        return super.execute(opFilter, input) ;
+        }
+
+    // ---- Triple patterns
+    
+    @Override
+    protected QueryIterator execute(OpBGP opBGP, QueryIterator input)
+    {
+        if ( ! isForTDB )
+            return super.execute(opBGP, input) ;
+        
+        GraphTDB graph = (GraphTDB)execCxt.getActiveGraph() ;
+        return executeBGP(graph, opBGP, input, null, execCxt) ;
+       
+    }
+
+    @Override
+    protected QueryIterator execute(OpQuadPattern quadPattern, QueryIterator input)
+    {
+        if ( ! isForTDB )
+            return super.execute(quadPattern, input) ;
+            
+    //        DatasetGraph dg = execCxt.getDataset() ;
+    //        if ( ! ( dg instanceof DatasetGraphTDB ) )
+    //            throw new InternalErrorException("Not a TDB backed dataset in quad pattern execution") ;
+        
+        DatasetGraphTDB ds = (DatasetGraphTDB)execCxt.getDataset() ;
+        BasicPattern bgp = quadPattern.getBasicPattern() ;
+        Node gn = quadPattern.getGraphNode() ;
+        return optimizeExecuteQuads(ds, input, gn, bgp, null, execCxt) ;
+    }
+
+    @Override
+    protected QueryIterator execute(OpGraph opGraph, QueryIterator input)
+    {
+        // Path evaluation or dataset sets which do not go straight to the DatasetGraphTDB  
+        return new QueryIterGraph(input, opGraph, execCxt) ;
+    }
+
+    /** Execute a BGP (and filters) on a TDB graph, which may be in default storage or it may be a named graph */ 
+    private static QueryIterator executeBGP(GraphTDB graph, OpBGP opBGP, QueryIterator input, ExprList exprs, 
+                                            ExecutionContext execCxt)
+    {
+        // Is it the real default graph (normal route or explicitly named)?
+        if ( ! isDefaultGraphStorage(graph.getGraphName()))
+        {
+            // Not default storage - it's a named graph in storage. 
+            DatasetGraphTDB ds = graph.getDSG() ;
+            return optimizeExecuteQuads(ds, input, graph.getGraphName(), opBGP.getPattern(), exprs, execCxt) ;
+        }
+        
+        // Execute a BGP on the real default graph
+        return optimizeExecuteTriples(graph, input, opBGP.getPattern(), exprs, execCxt) ;
+    }
+
+    /** Execute, with optimization, a basic graph pattern on the default graph storage */
+    private static QueryIterator optimizeExecuteTriples(GraphTDB graph, QueryIterator input,
+                                                        BasicPattern pattern, ExprList exprs,
+                                                        ExecutionContext execCxt)
+    {
+        if ( ! input.hasNext() )
+            return input ;
+    
+        // -- Input
+        // Must pass this iterator into the next stage.
+        if ( pattern.size() >= 2 )
+        {
+            // Must be 2 or triples to reorder. 
+            ReorderTransformation transform = graph.getDSG().getReorderTransform() ;
+            if ( transform != null )
+            {
+                QueryIterPeek peek = QueryIterPeek.create(input, execCxt) ;
+                input = peek ; // Must pass on
+                pattern = reorder(pattern, peek, transform) ;
+            }
+        }
+        // -- Filter placement
+            
+        Op op = null ;
+        if ( exprs != null )
+            op = TransformFilterPlacement.transform(exprs, pattern) ;
+        else
+            op = new OpBGP(pattern) ;
+        
+        return plainExecute(op, input, execCxt) ;
+    }
+
+    /** Execute, with optimization, a quad pattern */
+    private static QueryIterator optimizeExecuteQuads(DatasetGraphTDB ds, 
+                                                      QueryIterator input, 
+                                                      Node gn, BasicPattern bgp,
+                                                      ExprList exprs, ExecutionContext execCxt)
+    {
+        if ( ! input.hasNext() )
+            return input ;
+
+        // ---- Graph names with special meaning. 
+
+        gn = decideGraphNode(gn, execCxt) ;
+        if ( gn == null )
+            return optimizeExecuteTriples(ds.getDefaultGraphTDB(), input, bgp, exprs, execCxt) ;
+        
+        // ---- Execute quads+filters
+        if ( bgp.size() >= 2 )
+        {
+            ReorderTransformation transform = ds.getReorderTransform() ;
+    
+            if ( transform != null )
+            {
+                QueryIterPeek peek = QueryIterPeek.create(input, execCxt) ;
+                input = peek ; // Original input now invalid.
+                bgp = reorder(bgp, peek, transform) ;
+            }
+        }
+        // -- Filter placement
+        Op op = null ;
+        if ( exprs != null )
+            op = TransformFilterPlacement.transform(exprs, gn, bgp) ;
+        else
+            op = new OpQuadPattern(gn, bgp) ;
+
+        return plainExecute(op, input, execCxt) ;
+    }
+
+    /** Execute without modification of the op - does <b>not</b> apply special graph name translations */ 
+    private static QueryIterator plainExecute(Op op, QueryIterator input, ExecutionContext execCxt)
+    {
+        // -- Execute
+        // Switch to a non-reordering executor
+        // The Op may be a sequence due to TransformFilterPlacement
+        // so we need to do a full execution step, not go straight to the SolverLib.
+        
+        ExecutionContext ec2 = new ExecutionContext(execCxt) ;
+        ec2.setExecutor(plainFactory) ;
+
+        // Solve without going through this executor again.
+        // There would be issues of nested patterns but this is only a
+        // (filter (bgp...)) or (filter (quadpattern ...)) or sequences of these.
+        // so there are no nested patterns to reorder.
+        return QC.execute(op, input, ec2) ;
+    }
+
+    private static BasicPattern reorder(BasicPattern pattern, QueryIterPeek peek, ReorderTransformation transform)
+    {
+        if ( transform != null )
+        {
+            // This works by getting one result from the peek iterator,
+            // and creating the more gounded BGP. The tranform is used to
+            // determine the best order and the transformation is returned. This
+            // transform is applied to the unsubstituted pattern (which will be
+            // substituted as part of evaluation.
+            
+            if ( ! peek.hasNext() )
+                throw new ARQInternalErrorException("Peek iterator is already empty") ;
+ 
+            BasicPattern pattern2 = Substitute.substitute(pattern, peek.peek() ) ;
+            // Calculate the reordering based on the substituted pattern.
+            ReorderProc proc = transform.reorderIndexes(pattern2) ;
+            // Then reorder original patten
+            pattern = proc.reorder(pattern) ;
+        }
+        return pattern ;
+    }
+    
+    /** Handle special graph node names.  
+     * Returns null for default graph in storage (use the triple table).
+     * Returns Node.ANY for the union graph
+     */
+    public static Node decideGraphNode(Node gn, ExecutionContext execCxt)
+    {
+     // ---- Graph names with special meaning. 
+    
+        // Graph names with special meaning:
+        //   Quad.defaultGraphIRI -- the IRI used in GRAPH <> to mean the default graph.
+        //   Quad.defaultGraphNodeGenerated -- the internal marker node used for the quad form of queries.
+        //   Quad.unionGraph -- the IRI used in GRAPH <> to mean the union of named graphs
+    
+        if ( isDefaultGraphStorage(gn) ) 
+        {
+            // Storage concrete, default graph. 
+            // Either outside GRAPH (no implicit union)
+            // or using the "name" of the default graph
+            return null ;
+        }
+
+        // Not default storage graph.
+        // ---- Union (RDF Merge) of named graphs
+
+        if ( Quad.isUnionGraph(gn) ) 
+            return Node.ANY ;
+        boolean doingUnion = false ;
+        
+        return gn ;
+    }
+
+    // Is this a query against the real default graph in the storage (in a 3-tuple table). 
+    private static boolean isDefaultGraphStorage(Node gn)
+    {
+        if ( gn == null )
+            return true ;
+        
+        // Is it the implicit name for default graph.
+        if ( Quad.isDefaultGraph(gn) )
+            // Not accessing the union of named graphs as the default graph
+            // and pattern is directed to the default graph.
+            return true ;
+    
+        return false ;
+    }
+    
+    @Override
+    protected QueryIterator execute(OpDatasetNames dsNames, QueryIterator input)
+    { 
+        DatasetGraphTDB ds = (DatasetGraphTDB)execCxt.getDataset() ;
+        Predicate<Tuple<NodeId>> filter = QC2.getFilter(execCxt.getContext()) ;
+        Node gn = dsNames.getGraphNode() ;
+        if ( Var.isVar(gn) )
+            return SolverLib.graphNames(ds, dsNames.getGraphNode(), input, filter, execCxt) ;
+        else
+            return SolverLib.testForGraphName(ds, dsNames.getGraphNode(), input, filter, execCxt) ;
+    }
+
+    // ---- OpExecute factories and plain executor.
+    
+    private static OpExecutorFactory plainFactory = new OpExecutorPlainFactoryTDB() ;
+    private static class OpExecutorPlainFactoryTDB implements OpExecutorFactory
+    {
+        @Override
+        public OpExecutor create(ExecutionContext execCxt)
+        {
+            return new OpExecutorPlainTDB(execCxt) ;
+        }
+    }
+
+    /** An op executor that simply executes a BGP or QuadPattern without any reordering */ 
+    private static class OpExecutorPlainTDB extends OpExecutor
+    {
+        Predicate<Tuple<NodeId>> filter = null ;
+        
+        public OpExecutorPlainTDB(ExecutionContext execCxt)
+        {
+            super(execCxt) ;
+            filter = QC2.getFilter(execCxt.getContext()) ;
+        }
+        
+        @Override
+        public QueryIterator execute(OpBGP opBGP, QueryIterator input)
+        {
+            Graph g = execCxt.getActiveGraph() ;
+            
+            if ( g instanceof GraphTDB )
+            {
+                BasicPattern bgp = opBGP.getPattern() ;
+                Explain.explain("Execute", bgp, execCxt.getContext()) ;
+                // Triple-backed (but may be named as explicit default graph).
+                //return SolverLib.execute((GraphTDB)g, bgp, input, filter, execCxt) ;
+                GraphTDB gtdb = (GraphTDB)g ;
+                Node gn = decideGraphNode(gtdb.getGraphName(), execCxt) ;
+                return SolverLib.execute(gtdb.getDSG(), gn, bgp, input, filter, execCxt) ;
+            }
+            Log.warn(this, "Non-GraphTDB passed to OpExecutorPlainTDB") ;
+            return super.execute(opBGP, input) ;
+        }
+        
+        @Override
+        public QueryIterator execute(OpQuadPattern opQuadPattern, QueryIterator input)
+        {
+            Node gn = opQuadPattern.getGraphNode() ;
+            gn = decideGraphNode(gn, execCxt) ;
+            
+            if ( execCxt.getDataset() instanceof DatasetGraphTDB )
+            {
+                DatasetGraphTDB ds = (DatasetGraphTDB)execCxt.getDataset() ;
+                Explain.explain("Execute", opQuadPattern.getPattern(), execCxt.getContext()) ;
+                BasicPattern bgp = opQuadPattern.getBasicPattern() ;
+                return SolverLib.execute(ds, gn, bgp, input, filter, execCxt) ;
+            }
+            // Maybe a TDB named graph inside a non-TDB dataset.
+            Graph g = execCxt.getActiveGraph() ;
+            if ( g instanceof GraphTDB )
+            {
+                // Triples graph from TDB (which is the default graph of the dataset),
+                // used a named graph in a composite dataset.
+                BasicPattern bgp = opQuadPattern.getBasicPattern() ;
+                Explain.explain("Execute", bgp, execCxt.getContext()) ;
+                // Don't pass in G -- gn may be different.
+                return SolverLib.execute(((GraphTDB)g).getDSG(), gn, bgp, input, filter, execCxt) ;
+            }
+            Log.warn(this, "Non-DatasetGraphTDB passed to OpExecutorPlainTDB") ;
+            return super.execute(opQuadPattern, input) ;
+        }
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/5f99f5f3/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/store/DatasetGraphSwitchable.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/store/DatasetGraphSwitchable.java b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/store/DatasetGraphSwitchable.java
index a9a2fc0..60b654a 100644
--- a/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/store/DatasetGraphSwitchable.java
+++ b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/store/DatasetGraphSwitchable.java
@@ -30,10 +30,11 @@ import org.apache.jena.graph.Node;
 import org.apache.jena.shared.PrefixMapping;
 import org.apache.jena.shared.impl.PrefixMappingImpl;
 import org.apache.jena.sparql.core.DatasetGraph ;
+import org.apache.jena.sparql.core.DatasetGraphWrapper;
 import org.apache.jena.sparql.core.DatasetPrefixStorage ;
 
 final
-public class DatasetGraphSwitchable extends DatasetGraphWrapperTxn /* Until ARQ catches up with promote */ 
+public class DatasetGraphSwitchable extends DatasetGraphWrapper 
 {
     // QueryEngineFactoryWrapper has a QueryEngineFactory that is always loaded that
     // executes on the unwrapped DSG (recursively). Unwrapping is via getBase, calling

http://git-wip-us.apache.org/repos/asf/jena/blob/5f99f5f3/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/store/DatasetGraphTDB.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/store/DatasetGraphTDB.java b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/store/DatasetGraphTDB.java
index 5acec81..42690b2 100644
--- a/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/store/DatasetGraphTDB.java
+++ b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/store/DatasetGraphTDB.java
@@ -174,10 +174,9 @@ public class DatasetGraphTDB extends DatasetGraphTriplesQuads
         Transaction txn = txnSystem.getThreadTransaction() ;
         if ( txn == null )
             throw new TransactionException("Not in a transaction") ;
-            
         if ( txn.isWriteTxn() )
             return ;
-        boolean b = txn.promote() ;
+        boolean b = promote() ;
         if ( !b )
             throw new TransactionException("Can't write") ;
     }
@@ -445,7 +444,7 @@ public class DatasetGraphTDB extends DatasetGraphTriplesQuads
     }
 
     @Override
-    public boolean promote(TxnType txnType) {
+    public boolean promote(Promote txnType) {
         if ( txnMonitor != null ) txnMonitor.startPromote();
         try { 
             return txnSystem.promote(txnType) ;

http://git-wip-us.apache.org/repos/asf/jena/blob/5f99f5f3/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/store/DatasetGraphWrapperTxn.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/store/DatasetGraphWrapperTxn.java b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/store/DatasetGraphWrapperTxn.java
deleted file mode 100644
index 8022165..0000000
--- a/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/store/DatasetGraphWrapperTxn.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.jena.tdb2.store;
-
-import org.apache.jena.sparql.core.DatasetGraphWrapper ;
-
-public class DatasetGraphWrapperTxn extends DatasetGraphWrapper implements DatasetGraphTxn {
-
-    public DatasetGraphWrapperTxn(DatasetGraphTxn dsg) {
-        super(dsg) ;
-    }
-
-    @Override
-    public boolean promote() {
-        return ((DatasetGraphTxn)get()).promote() ;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/jena/blob/5f99f5f3/jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/store/TestDatasetTDB.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/store/TestDatasetTDB.java b/jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/store/TestDatasetTDB.java
index 16149df..2c2258f 100644
--- a/jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/store/TestDatasetTDB.java
+++ b/jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/store/TestDatasetTDB.java
@@ -28,6 +28,7 @@ import org.apache.jena.riot.Lang ;
 import org.apache.jena.riot.RDFDataMgr ;
 import org.apache.jena.sparql.core.Quad ;
 import org.apache.jena.sparql.sse.SSE ;
+import org.apache.jena.system.JenaSystem;
 import org.apache.jena.tdb2.TDB2;
 import org.apache.jena.tdb2.junit.TL;
 import org.junit.After ;
@@ -37,6 +38,11 @@ import org.junit.Test ;
 /** Tests of datasets, prefixes, special URIs etc (see also {@link org.apache.jena.sparql.graph.GraphsTests} */
 public class TestDatasetTDB
 {
+    static {
+        JenaSystem.DEBUG_INIT = true ; 
+        JenaSystem.init();
+    }
+    
     private Dataset dataset ;
     
     @Before public void before() {
@@ -170,6 +176,7 @@ public class TestDatasetTDB
     
     @Test public void special3()
     {
+        JenaSystem.init();
         Dataset ds = dataset() ;
 
         load1(ds.getDefaultModel()) ;

http://git-wip-us.apache.org/repos/asf/jena/blob/5f99f5f3/jena-rdfconnection/src/main/java/org/apache/jena/rdfconnection/RDFConnectionLocal.java
----------------------------------------------------------------------
diff --git a/jena-rdfconnection/src/main/java/org/apache/jena/rdfconnection/RDFConnectionLocal.java b/jena-rdfconnection/src/main/java/org/apache/jena/rdfconnection/RDFConnectionLocal.java
index 5c6e42f..362a4be 100644
--- a/jena-rdfconnection/src/main/java/org/apache/jena/rdfconnection/RDFConnectionLocal.java
+++ b/jena-rdfconnection/src/main/java/org/apache/jena/rdfconnection/RDFConnectionLocal.java
@@ -295,8 +295,7 @@ public class RDFConnectionLocal implements RDFConnection {
     @Override public void begin()                       { dataset.begin(); }
     @Override public void begin(TxnType txnType)        { dataset.begin(txnType); }
     @Override public void begin(ReadWrite mode)         { dataset.begin(mode); }
-    @Override public boolean promote()                  { return dataset.promote(); }
-    @Override public boolean promote(TxnType txnType)   { return dataset.promote(txnType); }
+    @Override public boolean promote(Promote promote)   { return dataset.promote(promote); }
     @Override public void commit()                      { dataset.commit(); }
     @Override public void abort()                       { dataset.abort(); }
     @Override public boolean isInTransaction()          { return dataset.isInTransaction(); }

http://git-wip-us.apache.org/repos/asf/jena/blob/5f99f5f3/jena-rdfconnection/src/main/java/org/apache/jena/rdfconnection/RDFConnectionModular.java
----------------------------------------------------------------------
diff --git a/jena-rdfconnection/src/main/java/org/apache/jena/rdfconnection/RDFConnectionModular.java b/jena-rdfconnection/src/main/java/org/apache/jena/rdfconnection/RDFConnectionModular.java
index b6f215e..0cd85cc 100644
--- a/jena-rdfconnection/src/main/java/org/apache/jena/rdfconnection/RDFConnectionModular.java
+++ b/jena-rdfconnection/src/main/java/org/apache/jena/rdfconnection/RDFConnectionModular.java
@@ -37,8 +37,7 @@ public class RDFConnectionModular implements RDFConnection {
     @Override public void begin()                       { transactional.begin(); }
     @Override public void begin(TxnType txnType)        { transactional.begin(txnType); }
     @Override public void begin(ReadWrite mode)         { transactional.begin(mode); }
-    @Override public boolean promote()                  { return transactional.promote(); }
-    @Override public boolean promote(TxnType txnType)   { return transactional.promote(txnType); }
+    @Override public boolean promote(Promote promote)   { return transactional.promote(promote); }
     @Override public void commit()                      { transactional.commit(); }
     @Override public void abort()                       { transactional.abort(); }
     @Override public boolean isInTransaction()          { return transactional.isInTransaction(); }

http://git-wip-us.apache.org/repos/asf/jena/blob/5f99f5f3/jena-rdfconnection/src/main/java/org/apache/jena/rdfconnection/RDFConnectionRemote.java
----------------------------------------------------------------------
diff --git a/jena-rdfconnection/src/main/java/org/apache/jena/rdfconnection/RDFConnectionRemote.java b/jena-rdfconnection/src/main/java/org/apache/jena/rdfconnection/RDFConnectionRemote.java
index 4960484..371945e 100644
--- a/jena-rdfconnection/src/main/java/org/apache/jena/rdfconnection/RDFConnectionRemote.java
+++ b/jena-rdfconnection/src/main/java/org/apache/jena/rdfconnection/RDFConnectionRemote.java
@@ -421,8 +421,7 @@ public class RDFConnectionRemote implements RDFConnection {
     @Override public void begin()                       { txn.begin(); }
     @Override public void begin(TxnType txnType)        { txn.begin(txnType); }
     @Override public void begin(ReadWrite mode)         { txn.begin(mode); }
-    @Override public boolean promote()                  { return txn.promote(); }
-    @Override public boolean promote(TxnType txnType)   { return txn.promote(txnType); }
+    @Override public boolean promote(Promote promote)   { return txn.promote(promote); }
     @Override public void commit()                      { txn.commit(); }
     @Override public void abort()                       { txn.abort(); }
     @Override public boolean isInTransaction()          { return txn.isInTransaction(); }

http://git-wip-us.apache.org/repos/asf/jena/blob/5f99f5f3/jena-sdb/src/main/java/org/apache/jena/sdb/store/DatasetGraphSDB.java
----------------------------------------------------------------------
diff --git a/jena-sdb/src/main/java/org/apache/jena/sdb/store/DatasetGraphSDB.java b/jena-sdb/src/main/java/org/apache/jena/sdb/store/DatasetGraphSDB.java
index dda35e9..f85a159 100644
--- a/jena-sdb/src/main/java/org/apache/jena/sdb/store/DatasetGraphSDB.java
+++ b/jena-sdb/src/main/java/org/apache/jena/sdb/store/DatasetGraphSDB.java
@@ -117,8 +117,7 @@ public class DatasetGraphSDB extends DatasetGraphTriplesQuads
     @Override public void begin()                       { txn.begin(); }
     @Override public void begin(TxnType txnType)        { txn.begin(txnType); }
     @Override public void begin(ReadWrite mode)         { txn.begin(mode); }
-    @Override public boolean promote()                  { return txn.promote(); }
-    @Override public boolean promote(TxnType txnType)   { return txn.promote(txnType); }
+    @Override public boolean promote(Promote txnType)   { return txn.promote(txnType); }
     @Override public void commit()                      { txn.commit(); }
     @Override public void abort()                       { txn.abort(); }
     @Override public boolean isInTransaction()          { return txn.isInTransaction(); }

http://git-wip-us.apache.org/repos/asf/jena/blob/5f99f5f3/jena-tdb/src/main/java/org/apache/jena/tdb/store/DatasetGraphTDB.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/main/java/org/apache/jena/tdb/store/DatasetGraphTDB.java b/jena-tdb/src/main/java/org/apache/jena/tdb/store/DatasetGraphTDB.java
index 13f8c18..f960e99 100644
--- a/jena-tdb/src/main/java/org/apache/jena/tdb/store/DatasetGraphTDB.java
+++ b/jena-tdb/src/main/java/org/apache/jena/tdb/store/DatasetGraphTDB.java
@@ -260,8 +260,7 @@ public class DatasetGraphTDB extends DatasetGraphTriplesQuads
     @Override public void begin()                       { txn.begin(); }
     @Override public void begin(TxnType txnType)        { txn.begin(txnType); }
     @Override public void begin(ReadWrite mode)         { txn.begin(mode); }
-    @Override public boolean promote()                  { return txn.promote(); }
-    @Override public boolean promote(TxnType txnType)   { return txn.promote(txnType); }
+    @Override public boolean promote(Promote txnType)   { return txn.promote(txnType); }
     @Override public void commit()                      { txn.commit(); }
     @Override public void abort()                       { txn.abort(); }
     @Override public boolean isInTransaction()          { return txn.isInTransaction(); }

http://git-wip-us.apache.org/repos/asf/jena/blob/5f99f5f3/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/DatasetGraphTransaction.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/DatasetGraphTransaction.java b/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/DatasetGraphTransaction.java
index 5b77607..7eedb4e 100644
--- a/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/DatasetGraphTransaction.java
+++ b/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/DatasetGraphTransaction.java
@@ -93,19 +93,28 @@ import org.apache.jena.tdb.store.GraphTxnTDB ;
             DatasetGraphTxn dsgTxn = dsgtxn.get() ;
             if ( dsgTxn.getTransaction().isRead() ) {
                 TxnType txnType = dsgTxn.getTransaction().getTxnType();
+                Promote mode;
                 switch(txnType) {
                     case READ : 
                         throw new JenaTransactionException("Attempt to update in a read transaction"); 
                     case WRITE :
                         // Impossible. We're in read-mode.
                         throw new TDBException("Internal inconsistency: read-mode write transaction");
-                    case READ_COMMITTED_PROMOTE :
                     case READ_PROMOTE : 
+                        mode = Promote.ISOLATED;
+                        break;
+                    case READ_COMMITTED_PROMOTE :
+                        mode = Promote.READ_COMMITTED;
+                        break;
+                    default:
+                        throw new TDBException("Internal inconsistency: null transaction type");
                 }
                 // Promotion.
                 TransactionManager txnMgr = dsgTxn.getTransaction().getTxnMgr() ;
-                DatasetGraphTxn dsgTxn2 = txnMgr.promote(dsgTxn, txnType) ;
+                DatasetGraphTxn dsgTxn2 = txnMgr.promote(dsgTxn, txnType, mode) ;
                 if ( dsgTxn2 == null )
+                    // We were asked for a write operation and can't promote.
+                    // Returning false makes no sense.
                     throw new JenaTransactionException("Can't promote "+txnType+"- dataset has been written to");
                 dsgtxn.set(dsgTxn2);
             }
@@ -206,12 +215,12 @@ import org.apache.jena.tdb.store.GraphTxnTDB ;
     }
 
     @Override
-    protected boolean _promote() {
+    protected boolean _promote(Promote promoteMode) {
         // Promotion (TDB1) is a reset of the DatasetGraphTxn.
         checkNotClosed() ;
         DatasetGraphTxn dsgTxn = dsgtxn.get();
         Transaction transaction = dsgTxn.getTransaction();
-        DatasetGraphTxn dsgTxn2 = transaction.getTxnMgr().promote(dsgTxn, transaction.getTxnType());
+        DatasetGraphTxn dsgTxn2 = transaction.getTxnMgr().promote(dsgTxn, transaction.getTxnType(), promoteMode);
         if ( dsgTxn2 == null )
             return false;
         dsgtxn.set(dsgTxn2) ;

http://git-wip-us.apache.org/repos/asf/jena/blob/5f99f5f3/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/TransactionManager.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/TransactionManager.java b/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/TransactionManager.java
index e9c4797..448c99c 100644
--- a/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/TransactionManager.java
+++ b/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/TransactionManager.java
@@ -24,7 +24,10 @@ import static org.apache.jena.tdb.transaction.TransactionManager.TxnPoint.BEGIN
 import static org.apache.jena.tdb.transaction.TransactionManager.TxnPoint.CLOSE ;
 
 import java.io.File ;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
 import java.util.concurrent.BlockingQueue ;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.LinkedBlockingDeque ;
@@ -39,6 +42,7 @@ import org.apache.jena.atlas.logging.Log ;
 import org.apache.jena.query.ReadWrite ;
 import org.apache.jena.query.TxnType;
 import org.apache.jena.shared.Lock ;
+import org.apache.jena.sparql.core.Transactional.Promote;
 import org.apache.jena.tdb.store.DatasetGraphTDB ;
 import org.apache.jena.tdb.sys.SystemTDB ;
 import org.slf4j.Logger ;
@@ -375,24 +379,24 @@ public class TransactionManager
      * <p>
      * Return null for "no promote" due to intermediate commits.  
      */
-    /*package*/ DatasetGraphTxn promote(DatasetGraphTxn dsgtxn, TxnType txnType) throws TDBTransactionException {
+    /*package*/ DatasetGraphTxn promote(DatasetGraphTxn dsgtxn, TxnType originalTxnType, Promote promoteType) throws TDBTransactionException {
         Transaction txn = dsgtxn.getTransaction() ;
         if ( txn.getState() != TxnState.ACTIVE )
             throw new TDBTransactionException("promote: transaction is not active") ;
         if ( txn.getTxnMode() == ReadWrite.WRITE )
             return dsgtxn ;
-        if ( txn.getTxnType() == TxnType.READ ) {
-            txn.abort();
-            throw new TDBTransactionException("promote: transaction is a READ transaction") ;
-        }
+        if ( txn.getTxnType() == TxnType.READ )
+            return null;    // Did no promote.
+            //txn.abort();
+            //throw new TDBTransactionException("promote: transaction is a READ transaction") ;
         
         // Read commit - pick up whatever is current at the point setup.
         // Can also promote - may need to wait for active writers. 
         // Go through begin for the writers lock. 
-        if ( txnType == TxnType.READ_COMMITTED_PROMOTE ) {
+        if ( promoteType == Promote.READ_COMMITTED ) {
             acquireWriterLock(true);
             // No need to sync - we just queue as a writer.
-            return promoteExec$(dsgtxn, txnType);
+            return promoteExec$(dsgtxn, originalTxnType);
         }
         
         // First check, without the writer lock. Fast fail.
@@ -414,7 +418,7 @@ public class TransactionManager
         // can commit/abort.  Otherwise, we have deadlock.
         acquireWriterLock(true) ;
         // Do the synchronized stuff.
-        return promoteSync$(dsgtxn, txnType) ; 
+        return promoteSync$(dsgtxn, originalTxnType) ; 
     }
     
     synchronized

http://git-wip-us.apache.org/repos/asf/jena/blob/5f99f5f3/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 2ccd2f8..8b8df56 100644
--- a/pom.xml
+++ b/pom.xml
@@ -735,6 +735,7 @@
           <artifactId>maven-compiler-plugin</artifactId>
           <version>3.7.0</version>
           <configuration>
+            <showDeprecation>false</showDeprecation>
             <encoding>UTF-8</encoding>
             <debug>true</debug>
             <debuglevel>source,lines,vars</debuglevel>