| /* |
| * 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.sdb.compiler; |
| |
| import org.apache.jena.sdb.SDB ; |
| import org.apache.jena.sdb.core.SDBRequest ; |
| import org.apache.jena.sdb.core.sqlnode.SqlNode ; |
| import org.apache.jena.sdb.shared.SDBInternalError ; |
| import org.apache.jena.sparql.core.Quad ; |
| |
| public class QuadBlockCompilerMain implements QuadBlockCompiler |
| { |
| SDBRequest request ; |
| SlotCompiler slotCompiler ; |
| static public PatternTable patternTable = null ; |
| |
| public QuadBlockCompilerMain(SDBRequest request, SlotCompiler slotCompiler) |
| { |
| //super(request, slotCompiler) ; |
| this.request = request ; |
| this.slotCompiler = slotCompiler ; |
| } |
| |
| @Override |
| public SlotCompiler getSlotCompiler() |
| { return slotCompiler ; } |
| |
| //@Override |
| @Override |
| final |
| public SqlNode compile(QuadBlock quads) |
| { |
| SqlNode sqlNode = slotCompiler.start(quads) ; |
| quads = new QuadBlock(quads) ; // Copy it because it's modified. |
| |
| // ---- Stage builder |
| SqlStageList sList = new SqlStageList() ; |
| // Potential concurrent modification - need to use an explicit index. |
| for ( int i = 0 ; i < quads.size() ; ) |
| { |
| Quad q = quads.get(i) ; |
| if ( patternTable != null && patternTable.trigger(q) ) |
| { |
| // Removes current quad |
| SqlStage stage = patternTable.process(i, quads) ; |
| if ( stage != null ) |
| { |
| if ( quads.get(i) == q ) |
| throw new SDBInternalError("Pattern table returned a stage but did not remove the first quad") ; |
| sList.add(stage) ; |
| continue ; |
| } |
| } |
| sList.add(new SqlStageBasicQuad(q)) ; |
| i++ ; |
| } |
| |
| // ---- and now turn the stages into SqlNodes |
| SqlNode sqlStages = sList.build(request, slotCompiler) ; |
| |
| // --- Join the initial node (constants). |
| sqlNode = SqlBuilder.innerJoin(request, sqlNode, sqlStages) ; |
| sqlNode = slotCompiler.finish(sqlNode, quads) ; |
| |
| // Insert DISTINCT if accessing the RDF merge of all named graphs |
| // An RDF Merge is the DISTINCT results of query over the union of all graphs. |
| // Or in TransformSDB |
| |
| boolean needDistinct = false ; |
| // Either it's the uniongraph ... |
| if ( quads.getGraphNode().equals(Quad.unionGraph) ) |
| needDistinct = true ; |
| // Or it's the union graph via redirected defaultGraph |
| else if ( Quad.isDefaultGraphGenerated(quads.getGraphNode()) && |
| request.getContext().isTrue(SDB.unionDefaultGraph)) |
| needDistinct = true ; |
| |
| if ( needDistinct ) |
| { |
| // DISTINCT -- over the named variables but not * (which includes the graph node). |
| String renameName = request.genId("A") ; |
| //sqlNode = SqlRename.view(renameName, sqlNode) ; |
| sqlNode = SqlBuilder.view(request, sqlNode) ; |
| sqlNode = SqlBuilder.distinct(request, sqlNode) ; |
| } |
| |
| return sqlNode ; |
| } |
| } |