KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > hp > hpl > jena > db > impl > DBQueryHandler


1 /*
2   (c) Copyright 2002, 2003, 2004, 2005 Hewlett-Packard Development Company, LP
3   [See end of file]
4   $Id: DBQueryHandler.java,v 1.16 2005/03/01 01:04:46 wkw Exp $
5 */

6
7 package com.hp.hpl.jena.db.impl;
8
9 /**
10     An extension of SimpleQueryHandler for database-graphs.
11     @author wkw et al
12 */

13
14 import com.hp.hpl.jena.graph.*;
15 import com.hp.hpl.jena.graph.query.*;
16 import com.hp.hpl.jena.db.*;
17 import com.hp.hpl.jena.shared.JenaException;
18
19 import java.util.*;
20
21 public class DBQueryHandler extends SimpleQueryHandler {
22     /** the Graph this handler is working for */
23     private GraphRDB graph;
24     boolean queryOnlyStmt; // if true, query only asserted stmt (ignore reification)
25
boolean queryOnlyReif; // if true, query only reified stmt (ignore asserted)
26
boolean queryFullReif; // if true, ignore partially reified statements
27
private boolean doFastpath; // if true, enable fastpath optimization
28
private boolean doImplicitJoin; // if true, optimize (pushdown) implicit joins
29
// e.g., "(ur1 pred1 ?v1) (uri1 pred2 ?v2)" is an implicit join on uri1
30

31     /** make an instance, remember the graph */
32     public DBQueryHandler ( GraphRDB graph ) {
33         super(graph);
34         this.graph = graph;
35         if ( graph.reificationBehavior() == GraphRDB.OPTIMIZE_ALL_REIFICATIONS_AND_HIDE_NOTHING ) {
36             queryFullReif = queryOnlyReif = queryOnlyStmt = false;
37         } else {
38             queryFullReif = queryOnlyReif = false;
39             queryOnlyStmt = true;
40         }
41         doFastpath = true;
42     }
43
44     public void setDoFastpath ( boolean val ) { doFastpath = val; }
45     public boolean getDoFastpath () { return doFastpath; }
46     public void setDoImplicitJoin ( boolean val ) { doImplicitJoin = val; }
47
48     public Stage patternStage(
49         Mapping varMap,
50         ExpressionSet constraints,
51         Triple[] ptn) {
52         final Stage[] stages = new Stage[ptn.length];
53         int stageCnt = 0;
54         final Integer JavaDoc numStages;
55         DBPattern[] source = new DBPattern[ptn.length];
56
57         // find the specialized graphs for the patterns
58
int i;
59         Triple pat;
60         List patternsToDo = new ArrayList();
61         for(i=0;i<ptn.length;i++) patternsToDo.add(new Integer JavaDoc(i));
62         DBPattern src;
63         int reifBehavior = graph.reificationBehavior();
64         
65         if ( ((patternsToDo.size() == 1) && !constraints.isComplex()) ||
66              (doFastpath == false) ) {
67             // fastpath fastpath; assumes it's faster to do a find for single pattern queries
68
for(i=0;i<patternsToDo.size();i++)
69                 stages[stageCnt++] =
70                     super.patternStage( varMap, constraints, new Triple[] { ptn[i] });
71         } else {
72             for (i = 0; i < ptn.length; i++) {
73                 pat = ptn[i];
74                 src = new DBPattern(pat, varMap);
75                 Iterator it = graph.getSpecializedGraphs();
76                 // find graphs that could match this pattern
77
while (it.hasNext()) {
78                     SpecializedGraph sg = (SpecializedGraph) it.next();
79                     char sub = sg.subsumes(pat,reifBehavior);
80                     if (sub == SpecializedGraph.noTriplesForPattern)
81                         continue;
82                     src.sourceAdd(sg, sub);
83                     if (sub == SpecializedGraph.allTriplesForPattern) {
84                         break;
85                     }
86                 }
87                 /* if (!src.hasSource())
88                     throw new RDFRDBException(
89                         "Pattern is not bound by any specialized graph: "
90                             + pat);
91                 */

92                 source[i] = src;
93             }
94
95             int minCost, minConnCost;
96             int cost;
97             DBPattern minSrc, unstaged = null;
98             boolean isConnected = false;
99             // find the minimum cost pattern ... but always choose a connected
100
// pattern over a disconnected pattern (to avoid cross-products).
101
// if no min cost pattern, take one at random.
102
while (patternsToDo.size() > 0) {
103                 minCost = minConnCost = DBPattern.costMax;
104                 isConnected = false;
105                 minSrc = null;
106                 int minIx = -1;
107                 for (i = 0; i < patternsToDo.size(); i++) {
108                     unstaged = source[((Integer JavaDoc)patternsToDo.get(i)).intValue()];
109                     cost = unstaged.cost(varMap);
110                     if (unstaged.isConnected) {
111                         if (cost < minConnCost) {
112                             minSrc = unstaged;
113                             minConnCost = cost;
114                             isConnected = true;
115                             minIx = i;
116                         }
117                     } else if ((cost < minCost) && !isConnected) {
118                         minCost = cost;
119                         minSrc = unstaged;
120                         minIx = i;
121                     }
122                 }
123                 if ( minSrc == null ) {
124                     src = unstaged; minIx = i-1;
125                 } else {
126                     src = minSrc;
127                 }
128                 src.isStaged = true;
129                 patternsToDo.remove(minIx);
130
131                 // now we have a pattern for the next stage.
132
List varList = new ArrayList(); // list of VarDesc
133
ExpressionSet evalCons = new ExpressionSet(); // constraints to eval
134
List qryPat = new ArrayList(); // list of DBPattern
135
qryPat.add(src);
136                 boolean doQuery = false;
137                 boolean didJoin = false;
138                 boolean foundJoin;
139                 // fastpath is only supported for patterns over one table.
140
if (src.isSingleSource()) {
141                     // see if other patterns can join with it.
142
src.addFreeVars(varList);
143                     do {
144                         foundJoin = false;
145                         for (i = 0; i < patternsToDo.size(); i++) {
146                             unstaged = source[((Integer JavaDoc)patternsToDo.get(i)).intValue()];
147                             if (unstaged.joinsWith(src,varList,queryOnlyStmt,queryOnlyReif,doImplicitJoin)) {
148                                 qryPat.add(unstaged);
149                                 patternsToDo.remove(i);
150                                 unstaged.addFreeVars(varList);
151                                 unstaged.isStaged = true;
152                                 foundJoin = didJoin = true;
153                             }
154                         }
155                     } while ( foundJoin && (patternsToDo.size() > 0));
156                     // push down query if (1) there is a join OR if
157
// (2) there is no join but there is a constraint to
158
// eval on a single pattern.
159
// see if any constraints can be pushed down
160
if ( didJoin )
161                         doQuery = true;
162                     else {
163                         for(i=0;i<varList.size();i++) {
164                             VarDesc vx = (VarDesc) varList.get(i);
165                             // see if any constraints on a result var.
166
// if so, push down constraint.
167
/*/ UNCOMMENT THE LINES BELOW TO ENABLE CONSTRAINT EVALUATION WITHIN THE DB. */
168                             if ( (vx.isArgVar == false) &&
169                                 findConstraints(constraints,evalCons,vx) )
170                                 doQuery = true;
171 /* UNCOMMENT THE LINES ABOVE TO ENABLE CONSTRAINT EVALUATION WITHIN THE DB. */
172                         }
173                     }
174                     if ( doQuery ) {
175                         // add result vars to reslist for query
176
for(i=0;i<varList.size();i++) {
177                             VarDesc vx = (VarDesc) varList.get(i);
178                             if ( vx.isArgVar == false )
179                                 vx.bindToVarMap(varMap);
180                         }
181                     }
182
183                 } else if ( !src.hasSource() )
184                     doQuery = true;
185                     // hack to handle the case when no graphs match the pattern
186
if ( doQuery ) {
187                         stages[stageCnt] =
188                             new DBQueryStage(graph,src.hasSource() ? src.singleSource() : null ,varList,qryPat, evalCons);
189                 } else {
190                     stages[stageCnt] =
191                             super.patternStage(varMap,constraints, new Triple[]{src.pattern});
192                 }
193                 stageCnt++;
194             }
195         }
196         numStages = new Integer JavaDoc(stageCnt);
197
198         return new Stage() {
199             public Stage connectFrom(Stage s) {
200                 for (int i = 0; i < numStages.intValue(); i += 1) {
201                     stages[i].connectFrom(s);
202                     s = stages[i];
203                 }
204                 return super.connectFrom(s);
205             }
206             public Pipe deliver(Pipe L) {
207                 return stages[numStages.intValue() - 1].deliver(L);
208             }
209         };
210     }
211     
212     // getters/setters for query handler options
213

214     public void setQueryOnlyAsserted ( boolean opt ) {
215         if ( (opt == true) && (queryOnlyReif==true) )
216             throw new JenaException("QueryOnlyAsserted and QueryOnlyReif cannot both be true");
217         queryOnlyStmt = opt;
218     }
219
220     public boolean getQueryOnlyAsserted() {
221         return queryOnlyStmt;
222     }
223
224     public void setQueryOnlyReified ( boolean opt ) {
225         if ( graph.reificationBehavior() != GraphRDB.OPTIMIZE_ALL_REIFICATIONS_AND_HIDE_NOTHING )
226             throw new JenaException("Reified statements cannot be queried for this model's reification style");
227         if ( (opt == true) && (queryOnlyReif==true) )
228             throw new JenaException("QueryOnlyAsserted and QueryOnlyReif cannot both be true");
229         queryOnlyReif = true;
230         throw new JenaException("QueryOnlyReified is not yet supported");
231     }
232
233     public boolean getQueryOnlyReified() {
234         return queryOnlyReif;
235     }
236
237     public void setQueryFullReified ( boolean opt ) {
238         if ( graph.reificationBehavior() != GraphRDB.OPTIMIZE_ALL_REIFICATIONS_AND_HIDE_NOTHING )
239             throw new JenaException("Reified statements cannot be queried for this model's reification style");
240         queryFullReif = true;
241     }
242
243     public boolean getQueryFullReified() {
244         return queryFullReif;
245     }
246
247
248     private boolean findConstraints ( ExpressionSet constraints, ExpressionSet evalCons, VarDesc vx ) {
249         boolean res = false;
250         Iterator it = constraints.iterator();
251         Expression e;
252         while (it.hasNext()) {
253             e = (Expression) it.next();
254             if (e.isApply() && e.argCount() == 2) {
255                 Expression l = e.getArg(0);
256                 if ( l.isVariable() && vx.var.getName().equals(l.getName()) ) {
257                     String JavaDoc f = e.getFun();
258                     if ( f.equals(ExpressionFunctionURIs.J_startsWith) ||
259                          f.equals(ExpressionFunctionURIs.J_startsWithInsensitive) ||
260                          f.equals(ExpressionFunctionURIs.J_contains) ||
261                          f.equals(ExpressionFunctionURIs.J_containsInsensitive) ||
262                          f.equals(ExpressionFunctionURIs.J_EndsWith) ||
263                          f.equals(ExpressionFunctionURIs.J_endsWithInsensitive) ) {
264                         evalCons.add(e);
265                         // for now, constraints must be reevaluated outside the
266
// db engine since the db engine may not fully evaluate
267
// the constraint.
268
// it.remove();
269
res = true;
270                     }
271                 }
272             }
273         }
274         return res;
275     }
276 }
277
278 /*
279     (c) Copyright 2002, 2002, 2003, 2004, 2005 Hewlett-Packard Development Company, LP
280     All rights reserved.
281
282     Redistribution and use in source and binary forms, with or without
283     modification, are permitted provided that the following conditions
284     are met:
285
286     1. Redistributions of source code must retain the above copyright
287        notice, this list of conditions and the following disclaimer.
288
289     2. Redistributions in binary form must reproduce the above copyright
290        notice, this list of conditions and the following disclaimer in the
291        documentation and/or other materials provided with the distribution.
292
293     3. The name of the author may not be used to endorse or promote products
294        derived from this software without specific prior written permission.
295
296     THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
297     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
298     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
299     IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
300     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
301     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
302     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
303     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
304     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
305     THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
306 */

307
Popular Tags