Strabon

changeset 1169:d41bcd569028 temporals

generalized spatialJoinOptimizer into an abstract class to be extended by the spatial and temporal optimizers respectively. There is a bug when the spatial and temporal optimizer operate on the same time, I have to fix this
author Konstantina Bereta <Konstantina.Bereta@di.uoa.gr>
date Fri May 10 19:27:31 2013 +0300 (2013-05-10)
parents c003d2c1a053
children 2aaa9fc419cf
files evaluation/src/main/java/org/openrdf/query/algebra/evaluation/impl/SpatialJoinOptimizer.java evaluation/src/main/java/org/openrdf/query/algebra/evaluation/impl/TemporalJoinOptimizer.java generaldb/src/main/java/org/openrdf/sail/generaldb/optimizers/GeneralDBQueryOptimizer.java
line diff
     1.1 --- a/evaluation/src/main/java/org/openrdf/query/algebra/evaluation/impl/SpatialJoinOptimizer.java	Fri May 10 16:10:00 2013 +0300
     1.2 +++ b/evaluation/src/main/java/org/openrdf/query/algebra/evaluation/impl/SpatialJoinOptimizer.java	Fri May 10 19:27:31 2013 +0300
     1.3 @@ -46,8 +46,10 @@
     1.4   * A query optimizer that re-orders nested Joins.
     1.5   * 
     1.6   * @author Manos Karpathiotakis <mk@di.uoa.gr>
     1.7 + * 
     1.8 + * @author Konstantina Bereta <Konstantina.Bereta@di.uoa.gr>
     1.9   */
    1.10 -public class SpatialJoinOptimizer 
    1.11 +public class SpatialJoinOptimizer extends SpatioTemporalJoinOptimizer
    1.12  //implements QueryOptimizer //Removed it consciously 
    1.13  {
    1.14  
    1.15 @@ -63,682 +65,36 @@
    1.16  		tupleExpr.visit(new JoinVisitor(spatialJoins));
    1.17  	}
    1.18  
    1.19 -	protected class JoinVisitor extends QueryModelVisitorBase<RuntimeException> {
    1.20 -		
    1.21 -		
    1.22 -		
    1.23 -		public JoinVisitor(List<TupleExpr> spatialJoins) {
    1.24 -			super();
    1.25 -			this.spatialJoins = spatialJoins;
    1.26 +
    1.27 +	protected boolean isRelevantSTFunc(FunctionCall functionCall)  
    1.28 +	{
    1.29 +		Function function = FunctionRegistry.getInstance().get(functionCall.getURI());
    1.30 +		if(function instanceof SpatialConstructFunc)
    1.31 +		{
    1.32 +			//TODO may have to comment this part again
    1.33 +			//uncommented because I use this function in the case of metrics
    1.34 +			return true;
    1.35  		}
    1.36 -
    1.37 -		
    1.38 -		private List<TupleExpr> spatialJoins;
    1.39 -		//buffer with a var as a second argument
    1.40 -		private boolean problematicBuffer = false;
    1.41 -
    1.42 -		//indicates whether a metric expression contains a spatial function call	
    1.43 -		private boolean containsSpatial = false;
    1.44 -		private boolean optimizableMetricOrProperty = true;
    1.45 -
    1.46 -		private int thematicJoinsSize = 0;
    1.47 -
    1.48 -		//List<SpatialFilterInfo> allSFilters = new ArrayList<SpatialFilterInfo>();
    1.49 -		Map<TupleExpr, List<Var>> allSFilters = new HashMap<TupleExpr, List<Var>>();
    1.50 -
    1.51 -		@Override
    1.52 -		public void meet(Join node) {
    1.53 -
    1.54 -			//XXX NOTE: NOT OPTIMIZING CONTENTS OF OPTIONAL CLAUSE!!!
    1.55 -			//Reason1: Errors occurred in the condition of the LeftJoin containing the optional subgraph
    1.56 -
    1.57 -			//Not as successful as I hoped. Some OPTIONAL clauses may pass
    1.58 -			if(parentIsOptional(node))
    1.59 -			{
    1.60 -				return;
    1.61 -			}
    1.62 -			//			if(node.getParentNode() instanceof LeftJoin)
    1.63 -			//			{
    1.64 -			//				return;
    1.65 -			//			}
    1.66 -
    1.67 -			// Recursively get the join arguments
    1.68 -			List<TupleExpr> joinArgs = getJoinArgs(node, new ArrayList<TupleExpr>());
    1.69 -
    1.70 -			if(joinArgs == null)
    1.71 -			{
    1.72 -				//2nd mechanism to avoid OPTIONAL clauses from passing
    1.73 -				return;
    1.74 -			}
    1.75 -
    1.76 -
    1.77 -			Map<TupleExpr, List<Var>> varsMap = new /*Linked*/HashMap<TupleExpr, List<Var>>();
    1.78 -
    1.79 -			for (TupleExpr tupleExpr : joinArgs) {
    1.80 -				varsMap.put(tupleExpr, getStatementPatternVars(tupleExpr));
    1.81 -
    1.82 -			}
    1.83 -
    1.84 -			//Now I have all the info I need. Just need to structure it efficiently
    1.85 -			int allNodes = varsMap.size() + allSFilters.size();
    1.86 -			thematicJoinsSize = varsMap.size();
    1.87 -			//careful with positions on the diagonal! Do not utilize them!
    1.88 -			int joinsGraph[][] = new int[allNodes][allNodes];
    1.89 -
    1.90 -			//prints for debug
    1.91 -			//			Set<TupleExpr> allExprs = varsMap.keySet();
    1.92 -			//			System.out.println(allExprs.toString());
    1.93 -			//			
    1.94 -			//			Set<TupleExpr> allFilters = allSFilters.keySet();
    1.95 -			//			System.out.println(allFilters.toString());
    1.96 -
    1.97 -			//Thematic part first
    1.98 -			int i = 0;
    1.99 -
   1.100 -			for(List<Var> listHorizontal : varsMap.values())
   1.101 -			{
   1.102 -				int j = 0;
   1.103 -				int k = 0;
   1.104 -
   1.105 -				//Other thematics
   1.106 -				for(List<Var> listVertical : varsMap.values())
   1.107 -				{
   1.108 -					if(i==j)
   1.109 -					{
   1.110 -						j++;
   1.111 -						continue;
   1.112 -					}
   1.113 -
   1.114 -
   1.115 -					joinsGraph[i][j] = sameVar(listHorizontal, listVertical);
   1.116 -
   1.117 -					j++;
   1.118 -				}
   1.119 -
   1.120 -				//Spatials
   1.121 -				for(List<Var> listVertical : allSFilters.values())
   1.122 -				{
   1.123 -
   1.124 -					joinsGraph[i][k+varsMap.size()] = sameVar(listHorizontal, listVertical);
   1.125 -
   1.126 -					k++;
   1.127 -				}
   1.128 -
   1.129 -				i++;
   1.130 -			}
   1.131 -
   1.132 -			//Now for the spatial horizontal nodes
   1.133 -			i = varsMap.size();
   1.134 -			for(List<Var> listHorizontal : allSFilters.values())
   1.135 -			{
   1.136 -				int j = 0;
   1.137 -				int k = 0;
   1.138 -
   1.139 -				//Other thematics
   1.140 -				for(List<Var> listVertical : varsMap.values())
   1.141 -				{
   1.142 -
   1.143 -					joinsGraph[i][j] = sameVar(listHorizontal, listVertical);
   1.144 -
   1.145 -					j++;
   1.146 -				}
   1.147 -
   1.148 -				//Spatials
   1.149 -				for(List<Var> listVertical : allSFilters.values())
   1.150 -				{
   1.151 -					if(i==k+varsMap.size())
   1.152 -					{
   1.153 -						k++;
   1.154 -						continue;
   1.155 -					}
   1.156 -
   1.157 -					joinsGraph[i][k+varsMap.size()] =sameVar(listHorizontal, listVertical);
   1.158 -
   1.159 -					k++;
   1.160 -				}
   1.161 -
   1.162 -				i++;
   1.163 -			}
   1.164 -
   1.165 -			//Checking graph to be sure
   1.166 -			/*
   1.167 -			for(int a = 0; a < allNodes; a++)
   1.168 -			{
   1.169 -				for(int b = 0; b < allNodes; b++)
   1.170 -				{
   1.171 -					System.out.print(joinsGraph[a][b]+" ");
   1.172 -
   1.173 -				}
   1.174 -				System.out.println("");
   1.175 -			}
   1.176 -			*/
   1.177 -
   1.178 -			//Time to construct ordered sequence of joins + filters
   1.179 -			List<TupleExpr> orderedJoinArgs = new ArrayList<TupleExpr>(allNodes);
   1.180 -			//maybe I won't need all the positions -> some spatial joins may not be utilized
   1.181 -			List<Integer> tempList = new ArrayList<Integer>(allNodes);
   1.182 -			List<Integer> pathList = new ArrayList<Integer>();
   1.183 -			List<Integer> finalList = new ArrayList<Integer>();
   1.184 -			Set<Var> varsTillNow = new LinkedHashSet<Var>();
   1.185 -			for(int row = 0 ; row < allNodes ; row++)
   1.186 -			{
   1.187 -				tempList.add(row);
   1.188 -				createOrderedJoins(joinsGraph, row, row, 1, varsTillNow, tempList, pathList, finalList);
   1.189 -				pathList.clear();
   1.190 -				if(finalList.size() == allNodes)
   1.191 -				{
   1.192 -					break;
   1.193 -				}
   1.194 -
   1.195 -			}
   1.196 -
   1.197 -			/*
   1.198 -			System.out.println("*--REWRITTEN TREE--**");
   1.199 -			System.out.println(finalList.toString());
   1.200 -			*/
   1.201 -
   1.202 -			int varsMapSize = varsMap.size();
   1.203 -			for(Integer position : finalList)
   1.204 -			{
   1.205 -				if(position<varsMapSize)//thematic!
   1.206 -				{
   1.207 -					int count = 0;
   1.208 -					Iterator it = varsMap.entrySet().iterator();
   1.209 -
   1.210 -					while (it.hasNext())
   1.211 -					{
   1.212 -						{
   1.213 -							Map.Entry entry = (Map.Entry)it.next();
   1.214 -							if(count == position)
   1.215 -							{
   1.216 -								orderedJoinArgs.add((TupleExpr) entry.getKey());
   1.217 -
   1.218 -								it.remove();
   1.219 -								varsMapSize--;
   1.220 -
   1.221 -								for(int fix = 0 ; fix < finalList.size(); fix++)
   1.222 -								{
   1.223 -									if(finalList.get(fix) > position)
   1.224 -									{
   1.225 -										int reduced = finalList.get(fix) - 1;
   1.226 -										finalList.set(fix, reduced);
   1.227 -
   1.228 -									}
   1.229 -								}
   1.230 -								break;
   1.231 -							}
   1.232 -							count++;
   1.233 -						}
   1.234 -					}
   1.235 -				}
   1.236 -				else//spatial!
   1.237 -				{
   1.238 -					int count = 0;
   1.239 -					Iterator it = allSFilters.entrySet().iterator();
   1.240 -					while (it.hasNext())
   1.241 -					{
   1.242 -						{
   1.243 -							Map.Entry entry = (Map.Entry)it.next();
   1.244 -							if(count == position - varsMapSize)
   1.245 -							{
   1.246 -								//If I keep record of this entry, I can use the info later to avoid duplicate filters
   1.247 -								spatialJoins.add((TupleExpr) entry.getKey());
   1.248 -								//
   1.249 -								orderedJoinArgs.add((TupleExpr) entry.getKey());
   1.250 -								it.remove();
   1.251 -								for(int fix = 0 ; fix < finalList.size(); fix++)
   1.252 -								{
   1.253 -									if(finalList.get(fix) > position)
   1.254 -									{
   1.255 -										int reduced = finalList.get(fix) - 1;
   1.256 -										finalList.set(fix, reduced);
   1.257 -									}
   1.258 -								}
   1.259 -								break;
   1.260 -							}
   1.261 -							count++;
   1.262 -						}
   1.263 -					}
   1.264 -				}
   1.265 -
   1.266 -			}
   1.267 -			//Must take care of the remainders as well!
   1.268 -			Iterator it = varsMap.entrySet().iterator();
   1.269 -			while (it.hasNext())
   1.270 -			{
   1.271 -				Map.Entry entry = (Map.Entry)it.next();
   1.272 -				orderedJoinArgs.add((TupleExpr) entry.getKey());
   1.273 -				it.remove();
   1.274 -			}
   1.275 -
   1.276 -			TupleExpr replacement = orderedJoinArgs.get(0);
   1.277 -			for (int ii = 1; ii < orderedJoinArgs.size(); ii++) {
   1.278 -				replacement = new Join(replacement, orderedJoinArgs.get(ii));
   1.279 -			}
   1.280 -
   1.281 -			// Replace old join hierarchy
   1.282 -			node.replaceWith(replacement);
   1.283 -
   1.284 +		else if(function instanceof SpatialRelationshipFunc)
   1.285 +		{
   1.286 +			return true;
   1.287  		}
   1.288 -
   1.289 -
   1.290 -		public boolean parentIsOptional(QueryModelNode node)
   1.291 +		else if(function instanceof SpatialPropertyFunc) //1 argument
   1.292  		{
   1.293 -			if(node.getParentNode() == null)
   1.294 -			{
   1.295 -				return false;
   1.296 -			}
   1.297 -			else if(node.getParentNode() instanceof LeftJoin)
   1.298 -			{
   1.299 -				return true;
   1.300 -			}
   1.301 -			else
   1.302 -			{
   1.303 -				return parentIsOptional(node.getParentNode());
   1.304 -			}
   1.305 +			return true;
   1.306  		}
   1.307 -
   1.308 -		/**
   1.309 -		 * General Comment: If more than one function exists in the query and can be used to perform the join, no preference is shown 
   1.310 -		 * on which function will actually be used for this purpose. This could cause an issue if ST_Disjoint is the one finally used, 
   1.311 -		 * as the index won't be used for the evaluation in this case. Perhaps I should include some 'priority'
   1.312 -		 */
   1.313 -		@Override
   1.314 -		public void meet(Filter node) {
   1.315 -
   1.316 -			/**
   1.317 -			 * Filter node must not be in OPTIONAL clause!
   1.318 -			 * After all, unneeded check. If an optional exists, the 'Filter' tuple expression
   1.319 -			 * is removed and only the Function Calls remain
   1.320 -			 */
   1.321 -			if(!withinHaving(node))
   1.322 -			{
   1.323 -				//if(!(node.getParentNode() instanceof LeftJoin))
   1.324 -				//{
   1.325 -				//XXX Ignore OR in Filters for now! (perhaps permanently)
   1.326 -				if(!(node.getCondition() instanceof Or))
   1.327 -				{
   1.328 -					if(node.getCondition() instanceof FunctionCall)
   1.329 -					{
   1.330 -						//Only interested in spatial ones
   1.331 -						if(isRelevantSpatialFunc((FunctionCall) node.getCondition()))
   1.332 -						{
   1.333 -							//Have to retrieve all nested variables and other info
   1.334 -
   1.335 -							//1.Retrieve varNames
   1.336 -							List<Var> varList = getFunctionCallVars((FunctionCall) node.getCondition());
   1.337 -
   1.338 -							//Cannot optimize buffer constructs when their 2nd argument is a 
   1.339 -							//thematic var, because I can't manipulate the order of the 
   1.340 -							//numeric_values table
   1.341 -							if(!problematicBuffer)
   1.342 -							{
   1.343 -								//XXX I cannot process cases involving more than 2 arguments in the spatial join!
   1.344 -								// They transcend the theta join level!
   1.345 -								//							if(varList.size()<3)
   1.346 -
   1.347 -								//if the arguments are not 2, I am essentially doing a selection!
   1.348 -								//No reason to push into optimizer then
   1.349 -								if(varList.size()==2)
   1.350 -								{
   1.351 -									//Add all important info about this spatial relationship to the appropriate structure
   1.352 -									//allSFilters.add(new SpatialFilterInfo(varList, (FunctionCall) node.getCondition()));
   1.353 -									Filter toEnter = node.clone();
   1.354 -
   1.355 -									/**
   1.356 -									 * VERY CAREFUL HERE! 
   1.357 -									 * Reason I did this: If not, I would carry a copy of the whole expression for
   1.358 -									 * every extra filter of my query!
   1.359 -									 * -DUMMY-!!!
   1.360 -									 */
   1.361 -									StatementPattern t = new StatementPattern();
   1.362 -									t.setSubjectVar(new Var("-dummy-"));
   1.363 -									t.setPredicateVar(new Var("-dummy-"));
   1.364 -									t.setObjectVar(new Var("-dummy-"));
   1.365 -									t.setScope(Scope.DEFAULT_CONTEXTS);
   1.366 -									toEnter.setArg(t);
   1.367 -
   1.368 -									if(!allSFilters.containsKey(toEnter))
   1.369 -									{
   1.370 -										allSFilters.put(toEnter,varList);
   1.371 -									}
   1.372 -								}
   1.373 -								problematicBuffer = false;
   1.374 -							}
   1.375 -						}
   1.376 -					}
   1.377 -					//Metrics
   1.378 -					//I have a similar problematic case with the one occurring in Buffer! 
   1.379 -					//Cannot manipulate the join order when I am dealing with numerics!
   1.380 -					//Therefore, I cannot use a numeric field (a numeric var) to alter the join sequence
   1.381 -					else if(node.getCondition() instanceof Compare)
   1.382 -					{
   1.383 -						containsSpatial = false;
   1.384 -						List<Var> allVars = new ArrayList<Var>(getVarsInMetricOrProperty(node.getCondition()));
   1.385 -						if(containsSpatial&&optimizableMetricOrProperty)
   1.386 -						{
   1.387 -							//if the arguments are not 2, I am essentially doing a selection!
   1.388 -							//No reason to push into optimizer then
   1.389 -							if(allVars.size()==2)
   1.390 -								//if(allVars.size()<3)
   1.391 -							{
   1.392 -								//Add all important info about this spatial relationship to the appropriate structure
   1.393 -								//allSFilters.add(new SpatialFilterInfo(varList, (FunctionCall) node.getCondition()));
   1.394 -								Filter toEnter = node.clone();
   1.395 -
   1.396 -								StatementPattern t = new StatementPattern();
   1.397 -								t.setSubjectVar(new Var("-dummy-"));
   1.398 -								t.setPredicateVar(new Var("-dummy-"));
   1.399 -								t.setObjectVar(new Var("-dummy-"));
   1.400 -								t.setScope(Scope.DEFAULT_CONTEXTS);
   1.401 -								toEnter.setArg(t);
   1.402 -
   1.403 -								if(!allSFilters.containsKey(toEnter))
   1.404 -								{
   1.405 -									allSFilters.put(toEnter,allVars);
   1.406 -								}
   1.407 -							}
   1.408 -							containsSpatial = false;
   1.409 -						}
   1.410 -						optimizableMetricOrProperty = true;
   1.411 -					}
   1.412 -
   1.413 -				}
   1.414 -				//}
   1.415 -			}
   1.416 -
   1.417 -			//Last thing to do is ensuring the entire tree is traversed
   1.418 -			node.visitChildren(this);
   1.419 -
   1.420 +		else if(function instanceof SpatialMetricFunc) //Arguments # depends on the function selected
   1.421 +		{
   1.422 +			return true;
   1.423  		}
   1.424 -
   1.425 -
   1.426 -		/**
   1.427 -		 * Helper Functions
   1.428 -		 */
   1.429 -
   1.430 -		/**
   1.431 -		 * Used to find out whether the Filter expr we are currently visiting is located inside
   1.432 -		 * a HAVING clause.
   1.433 -		 * 
   1.434 -		 * From what I have seen so far, it seems that if this is the case, its arg (or one of the following FILTER args in 
   1.435 -		 * the case of disjunction/conjunction) will be an Extension expr followed by a GROUP expr
   1.436 -		 */
   1.437 -		private boolean withinHaving(Filter expr)
   1.438 -		{
   1.439 -			if(expr.getArg() instanceof Extension)
   1.440 -			{
   1.441 -				return true;
   1.442 -			}
   1.443 -			else if(expr.getArg() instanceof Filter)
   1.444 -			{
   1.445 -				return withinHaving((Filter) expr.getArg());
   1.446 -			}
   1.447 -			else
   1.448 -			{
   1.449 -				return false;
   1.450 -			}
   1.451 -		}
   1.452 -
   1.453 -		private <L extends List<TupleExpr>> L getJoinArgs(TupleExpr tupleExpr, L joinArgs) {
   1.454 -			if (tupleExpr instanceof Join) {
   1.455 -				Join join = (Join)tupleExpr;
   1.456 -				if(getJoinArgs(join.getLeftArg(), joinArgs) == null)
   1.457 -					return null;
   1.458 -				if(getJoinArgs(join.getRightArg(), joinArgs) == null)
   1.459 -					return null;
   1.460 -			}
   1.461 -			else if(tupleExpr instanceof LeftJoin) 
   1.462 -			{
   1.463 -				//Trying to avoid OPTIONAL clauses from passing
   1.464 -				return null;
   1.465 -			}
   1.466 -			else 
   1.467 -			{
   1.468 -				joinArgs.add(tupleExpr);
   1.469 -			}
   1.470 -
   1.471 -			return joinArgs;
   1.472 -		}
   1.473 -
   1.474 -		private List<Var> getStatementPatternVars(TupleExpr tupleExpr) {
   1.475 -			List<StatementPattern> stPatterns = StatementPatternCollector.process(tupleExpr);
   1.476 -			List<Var> varList = new ArrayList<Var>(stPatterns.size() * 4);
   1.477 -			for (StatementPattern sp : stPatterns) {
   1.478 -				sp.getVars(varList);
   1.479 -			}
   1.480 -			return varList;
   1.481 -		}
   1.482 -
   1.483 -		/**
   1.484 -		 * spatialContent: Used to declare that this expression does include some spatial 
   1.485 -		 * content and an attempt should be made to use it in the joins' optimization process
   1.486 -		 */
   1.487 -		private Set<Var> getVarsInMetricOrProperty(ValueExpr expr)
   1.488 -		{
   1.489 -			Set<Var> allVars = new LinkedHashSet<Var>();
   1.490 -
   1.491 -			if(expr instanceof Compare)
   1.492 -			{
   1.493 -				allVars.addAll(getVarsInMetricOrProperty(((Compare) expr).getLeftArg()));
   1.494 -				allVars.addAll(getVarsInMetricOrProperty(((Compare) expr).getRightArg()));
   1.495 -			}
   1.496 -			else if(expr instanceof MathExpr)
   1.497 -			{
   1.498 -				allVars.addAll(getVarsInMetricOrProperty(((MathExpr) expr).getLeftArg()));
   1.499 -				allVars.addAll(getVarsInMetricOrProperty(((MathExpr) expr).getRightArg()));
   1.500 -			}
   1.501 -			else if(expr instanceof FunctionCall )
   1.502 -			{
   1.503 -				if(isRelevantSpatialFunc((FunctionCall) expr))
   1.504 -				{
   1.505 -					/**
   1.506 -					 * There is a point in continuing the search recursively ONLY 
   1.507 -					 * if I reach this case. Otherwise, the function call
   1.508 -					 * may not refer to a spatial function
   1.509 -					 */
   1.510 -					this.containsSpatial = true;
   1.511 -					allVars.addAll(getFunctionCallVars((FunctionCall) expr));
   1.512 -
   1.513 -				}
   1.514 -			}
   1.515 -			else if(expr instanceof Var)
   1.516 -			{
   1.517 -				if(!(expr.getParentNode() instanceof FunctionCall))
   1.518 -				{
   1.519 -					//Cannot manipulate the join order when I am dealing with numerics!
   1.520 -					//Therefore, I cannot use a numeric field (a numeric var) to alter the join sequence
   1.521 -					this.optimizableMetricOrProperty = false;
   1.522 -				}
   1.523 -				if(!allVars.contains(expr))
   1.524 -				{
   1.525 -					allVars.add((Var) expr);
   1.526 -				}
   1.527 -			}
   1.528 -
   1.529 -			return allVars;
   1.530 -		}
   1.531 -
   1.532 -		private boolean isRelevantSpatialFunc(FunctionCall functionCall)
   1.533 -		{
   1.534 -			Function function = FunctionRegistry.getInstance().get(functionCall.getURI());
   1.535 -			if(function instanceof SpatialConstructFunc)
   1.536 -			{
   1.537 -				//TODO may have to comment this part again
   1.538 -				//uncommented because I use this function in the case of metrics
   1.539 -				return true;
   1.540 -			}
   1.541 -			else if(function instanceof SpatialRelationshipFunc)
   1.542 -			{
   1.543 -				return true;
   1.544 -			}
   1.545 -			else if(function instanceof SpatialPropertyFunc) //1 argument
   1.546 -			{
   1.547 -				return true;
   1.548 -			}
   1.549 -			else if(function instanceof SpatialMetricFunc) //Arguments # depends on the function selected
   1.550 -			{
   1.551 -				return true;
   1.552 -			}
   1.553 -			return false;
   1.554 -		}
   1.555 -
   1.556 -		private List<Var> getFunctionCallVars(FunctionCall functionCall) {
   1.557 -			List<Var> varList = new ArrayList<Var>();
   1.558 -			int argList = 0;
   1.559 -			for(ValueExpr expr : functionCall.getArgs())
   1.560 -			{
   1.561 -				argList++;
   1.562 -				if(expr instanceof Var)
   1.563 -				{
   1.564 -					//					if(!existingVars.contains(((Var) expr).getName()))
   1.565 -					//					{
   1.566 -					//						existingVars.add(((Var) expr).getName());
   1.567 -					//					}
   1.568 -
   1.569 -					if(!varList.contains(expr))
   1.570 -					{
   1.571 -						//Was using this code when I tried to incorporate the Buffer case buffer(?Spatial,?thematic)
   1.572 -						if(argList == 2 && functionCall.getURI().equals("http://strdf.di.uoa.gr/ontology#buffer"))
   1.573 -						{
   1.574 -							problematicBuffer = true;
   1.575 -						}
   1.576 -						varList.add((Var) expr);
   1.577 -					}
   1.578 -
   1.579 -				}
   1.580 -				else if(expr instanceof FunctionCall)
   1.581 -				{
   1.582 -					varList.addAll(getFunctionCallVars((FunctionCall) expr));
   1.583 -				}
   1.584 -				//TODO Should I add any additional cases? I don't think so
   1.585 -				else
   1.586 -				{
   1.587 -					continue;
   1.588 -				}
   1.589 -			}
   1.590 -			return varList;
   1.591 -		}
   1.592 -
   1.593 -		/**
   1.594 -		 * Both lists belong to either a thematic node (St.Pattern) or a spatial node (Filter)
   1.595 -		 * Comparing the vars with each other to discover links of the query graph
   1.596 -		 * @param list1 
   1.597 -		 * @param list2
   1.598 -		 * @return
   1.599 -		 */
   1.600 -		private int sameVar(List<Var> list1, List<Var> list2)
   1.601 -		{
   1.602 -			for(Var var : list1)
   1.603 -			{
   1.604 -				if(list2.contains(var))
   1.605 -				{
   1.606 -					return 1;
   1.607 -				}
   1.608 -			}
   1.609 -
   1.610 -			return 0;
   1.611 -		}
   1.612 -
   1.613 -
   1.614 -
   1.615 -
   1.616 -
   1.617 -		//Input: a single line of the table
   1.618 -		//NOTE: NO LOOPS! CAREFUL!!
   1.619 -		private boolean createOrderedJoins(int table[][], int lineToScan,int columnToSkip, 
   1.620 -				int pathLen, Set<Var> varsTillNow, List<Integer> tempList, List<Integer> pathList, List<Integer> finalList)
   1.621 -		{
   1.622 -			boolean success = false;
   1.623 -			int dims = table.length;
   1.624 -
   1.625 -			int j;
   1.626 -
   1.627 -			//dims: all arguments
   1.628 -			for(j = 0; j < dims; j++)
   1.629 -			{
   1.630 -				if(j == columnToSkip)
   1.631 -				{
   1.632 -					continue;
   1.633 -				}
   1.634 -
   1.635 -				//A connection exists!
   1.636 -				if(table[lineToScan][j]>0)
   1.637 -				{
   1.638 -					//Don't want my graph to have circles!!!
   1.639 -					if(!tempList.contains(j)&&!pathList.contains(j))
   1.640 -					{
   1.641 -						if(j >= thematicJoinsSize) //aka if(allSFilters.size() > 0)
   1.642 -						{
   1.643 -							List<Var> thisFilterVars = null;
   1.644 -							int count = 0;
   1.645 -							for(List<Var> vars : allSFilters.values())
   1.646 -							{
   1.647 -								if(count == j - thematicJoinsSize)
   1.648 -								{
   1.649 -									thisFilterVars = vars;
   1.650 -									break;
   1.651 -								}
   1.652 -								count++;
   1.653 -							}
   1.654 -							if(!varsTillNow.isEmpty())
   1.655 -							{
   1.656 -								if(varsTillNow.containsAll(thisFilterVars))
   1.657 -								{
   1.658 -									continue;
   1.659 -								}
   1.660 -							}
   1.661 -
   1.662 -							//varsTillNow.add(thisFilterVars.get(1));
   1.663 -							varsTillNow.addAll(thisFilterVars);
   1.664 -
   1.665 -						}
   1.666 -
   1.667 -						tempList.add((Integer)j);
   1.668 -						pathLen++;
   1.669 -						if(pathLen == dims)
   1.670 -						{
   1.671 -							//End of recursion
   1.672 -							pathList.addAll(tempList);
   1.673 -							tempList.clear();
   1.674 -							finalList.clear();
   1.675 -							finalList.addAll(pathList);
   1.676 -
   1.677 -							return true;
   1.678 -						}
   1.679 -
   1.680 -						//Recurse
   1.681 -						success = createOrderedJoins(table, j, lineToScan, pathLen, varsTillNow, tempList, pathList, finalList);
   1.682 -
   1.683 -						//Success = true => recursion ended with pathLen = maxLen
   1.684 -						if(success)
   1.685 -						{
   1.686 -							return true;
   1.687 -						}
   1.688 -						else
   1.689 -						{	
   1.690 -							//end of a path originating from this node was found -> find an additional path (if exists)
   1.691 -							continue;
   1.692 -						}
   1.693 -					}
   1.694 -				}
   1.695 -			}
   1.696 -			//To reach this place means the end of a path was found 
   1.697 -			pathList.addAll(tempList);
   1.698 -			tempList.clear();
   1.699 -			if(pathList.size() > finalList.size())
   1.700 -			{
   1.701 -				finalList.clear();
   1.702 -				finalList.addAll(pathList);
   1.703 -				if(finalList.size() == dims)
   1.704 -				{
   1.705 -					return true;
   1.706 -				}
   1.707 -			}
   1.708 -			return false;			
   1.709 -		}
   1.710 -
   1.711 +		return false;
   1.712  	}
   1.713  
   1.714  
   1.715 +	@Override
   1.716 +	public String getClassName() {
   1.717 +		// TODO Auto-generated method stub
   1.718 +		return this.getClass().getCanonicalName();
   1.719 +	}
   1.720 +
   1.721  }
     2.1 --- a/evaluation/src/main/java/org/openrdf/query/algebra/evaluation/impl/TemporalJoinOptimizer.java	Fri May 10 16:10:00 2013 +0300
     2.2 +++ b/evaluation/src/main/java/org/openrdf/query/algebra/evaluation/impl/TemporalJoinOptimizer.java	Fri May 10 19:27:31 2013 +0300
     2.3 @@ -3,7 +3,7 @@
     2.4   * License, v. 2.0. If a copy of the MPL was not distributed with this
     2.5   * file, You can obtain one at http://mozilla.org/MPL/2.0/.
     2.6   * 
     2.7 - * Copyright (C) 2010, 2011, 2012, Pyravlos Team
     2.8 + * Copyright (C) 2013 Pyravlos Team
     2.9   * 
    2.10   * http://www.strabon.di.uoa.gr/
    2.11   */
    2.12 @@ -42,9 +42,12 @@
    2.13  /**
    2.14   * A query optimizer that re-orders nested Joins.
    2.15   * 
    2.16 + * @author Konstantina Bereta <Konstantina.Bereta@di.uoa.gr>
    2.17 + * 
    2.18 + * based on the code of the SpatialJoinOptimizer by
    2.19   * @author Manos Karpathiotakis <mk@di.uoa.gr>
    2.20   */
    2.21 -public class TemporalJoinOptimizer 
    2.22 +public class TemporalJoinOptimizer extends SpatioTemporalJoinOptimizer
    2.23  //implements QueryOptimizer //Removed it consciously 
    2.24  {
    2.25  
    2.26 @@ -60,674 +63,29 @@
    2.27  		tupleExpr.visit(new JoinVisitor(temporalJoins));
    2.28  	}
    2.29  
    2.30 -	protected class JoinVisitor extends QueryModelVisitorBase<RuntimeException> {
    2.31 -		
    2.32 -		
    2.33 -		
    2.34 -		public JoinVisitor(List<TupleExpr> temporalJoins) {
    2.35 -			super();
    2.36 -			this.temporalJoins = temporalJoins;
    2.37 +
    2.38 +	
    2.39 +	protected boolean isRelevantSTFunc(FunctionCall functionCall)
    2.40 +	{
    2.41 +		Function function = FunctionRegistry.getInstance().get(functionCall.getURI());
    2.42 +		if(function instanceof org.openrdf.query.algebra.evaluation.function.temporal.stsparql.construct.TemporalConstructFunc )
    2.43 +		{
    2.44 +			//TODO may have to comment this part again
    2.45 +			//uncommented because I use this function in the case of metrics
    2.46 +			return true;
    2.47  		}
    2.48 -
    2.49 -		
    2.50 -		private List<TupleExpr> temporalJoins;
    2.51 -		//buffer with a var as a second argument
    2.52 -		private boolean problematicBuffer = false;
    2.53 -
    2.54 -		//indicates whether a metric expression contains a temporal function call	
    2.55 -		private boolean containsTemporal = false;
    2.56 -		private boolean optimizableMetricOrProperty = true;
    2.57 -
    2.58 -		private int thematicJoinsSize = 0;
    2.59 -
    2.60 -		
    2.61 -		Map<TupleExpr, List<Var>> temporalFilters = new HashMap<TupleExpr, List<Var>>();
    2.62 -
    2.63 -		@Override
    2.64 -		public void meet(Join node) {
    2.65 -
    2.66 -			//XXX NOTE: NOT OPTIMIZING CONTENTS OF OPTIONAL CLAUSE!!!
    2.67 -			//Reason1: Errors occurred in the condition of the LeftJoin containing the optional subgraph
    2.68 -
    2.69 -			//Not as successful as I hoped. Some OPTIONAL clauses may pass
    2.70 -			if(parentIsOptional(node))
    2.71 -			{
    2.72 -				return;
    2.73 -			}
    2.74 -			//			if(node.getParentNode() instanceof LeftJoin)
    2.75 -			//			{
    2.76 -			//				return;
    2.77 -			//			}
    2.78 -
    2.79 -			// Recursively get the join arguments
    2.80 -			List<TupleExpr> joinArgs = getJoinArgs(node, new ArrayList<TupleExpr>());
    2.81 -
    2.82 -			if(joinArgs == null)
    2.83 -			{
    2.84 -				//2nd mechanism to avoid OPTIONAL clauses from passing
    2.85 -				return;
    2.86 -			}
    2.87 -
    2.88 -
    2.89 -			Map<TupleExpr, List<Var>> varsMap = new /*Linked*/HashMap<TupleExpr, List<Var>>();
    2.90 -
    2.91 -			for (TupleExpr tupleExpr : joinArgs) {
    2.92 -				varsMap.put(tupleExpr, getStatementPatternVars(tupleExpr));
    2.93 -
    2.94 -			}
    2.95 -
    2.96 -			//Now I have all the info I need. Just need to structure it efficiently
    2.97 -			int allNodes = varsMap.size() + temporalFilters.size();
    2.98 -			thematicJoinsSize = varsMap.size();
    2.99 -			//careful with positions on the diagonal! Do not utilize them!
   2.100 -			int joinsGraph[][] = new int[allNodes][allNodes];
   2.101 -
   2.102 -			//prints for debug
   2.103 -			//			Set<TupleExpr> allExprs = varsMap.keySet();
   2.104 -			//			System.out.println(allExprs.toString());
   2.105 -			//			
   2.106 -			//			Set<TupleExpr> allFilters = temporalFilters.keySet();
   2.107 -			//			System.out.println(allFilters.toString());
   2.108 -
   2.109 -			//Thematic part first
   2.110 -			int i = 0;
   2.111 -
   2.112 -			for(List<Var> listHorizontal : varsMap.values())
   2.113 -			{
   2.114 -				int j = 0;
   2.115 -				int k = 0;
   2.116 -
   2.117 -				//Other thematics
   2.118 -				for(List<Var> listVertical : varsMap.values())
   2.119 -				{
   2.120 -					if(i==j)
   2.121 -					{
   2.122 -						j++;
   2.123 -						continue;
   2.124 -					}
   2.125 -
   2.126 -
   2.127 -					joinsGraph[i][j] = sameVar(listHorizontal, listVertical);
   2.128 -
   2.129 -					j++;
   2.130 -				}
   2.131 -
   2.132 -				//Temporals
   2.133 -				for(List<Var> listVertical : temporalFilters.values())
   2.134 -				{
   2.135 -
   2.136 -					joinsGraph[i][k+varsMap.size()] = sameVar(listHorizontal, listVertical);
   2.137 -
   2.138 -					k++;
   2.139 -				}
   2.140 -
   2.141 -				i++;
   2.142 -			}
   2.143 -
   2.144 -			//Now for the temporal horizontal nodes
   2.145 -			i = varsMap.size();
   2.146 -			for(List<Var> listHorizontal : temporalFilters.values())
   2.147 -			{
   2.148 -				int j = 0;
   2.149 -				int k = 0;
   2.150 -
   2.151 -				//Other thematics
   2.152 -				for(List<Var> listVertical : varsMap.values())
   2.153 -				{
   2.154 -
   2.155 -					joinsGraph[i][j] = sameVar(listHorizontal, listVertical);
   2.156 -
   2.157 -					j++;
   2.158 -				}
   2.159 -
   2.160 -				//Temporals
   2.161 -				for(List<Var> listVertical : temporalFilters.values())
   2.162 -				{
   2.163 -					if(i==k+varsMap.size())
   2.164 -					{
   2.165 -						k++;
   2.166 -						continue;
   2.167 -					}
   2.168 -
   2.169 -					joinsGraph[i][k+varsMap.size()] =sameVar(listHorizontal, listVertical);
   2.170 -
   2.171 -					k++;
   2.172 -				}
   2.173 -
   2.174 -				i++;
   2.175 -			}
   2.176 -
   2.177 -			//Checking graph to be sure
   2.178 -			/*
   2.179 -			for(int a = 0; a < allNodes; a++)
   2.180 -			{
   2.181 -				for(int b = 0; b < allNodes; b++)
   2.182 -				{
   2.183 -					System.out.print(joinsGraph[a][b]+" ");
   2.184 -
   2.185 -				}
   2.186 -				System.out.println("");
   2.187 -			}
   2.188 -			*/
   2.189 -
   2.190 -			//Time to construct ordered sequence of joins + filters
   2.191 -			List<TupleExpr> orderedJoinArgs = new ArrayList<TupleExpr>(allNodes);
   2.192 -			//maybe I won't need all the positions -> some temporal joins may not be utilized
   2.193 -			List<Integer> tempList = new ArrayList<Integer>(allNodes);
   2.194 -			List<Integer> pathList = new ArrayList<Integer>();
   2.195 -			List<Integer> finalList = new ArrayList<Integer>();
   2.196 -			Set<Var> varsTillNow = new LinkedHashSet<Var>();
   2.197 -			for(int row = 0 ; row < allNodes ; row++)
   2.198 -			{
   2.199 -				tempList.add(row);
   2.200 -				createOrderedJoins(joinsGraph, row, row, 1, varsTillNow, tempList, pathList, finalList);
   2.201 -				pathList.clear();
   2.202 -				if(finalList.size() == allNodes)
   2.203 -				{
   2.204 -					break;
   2.205 -				}
   2.206 -
   2.207 -			}
   2.208 -
   2.209 -			/*
   2.210 -			System.out.println("*--REWRITTEN TREE--**");
   2.211 -			System.out.println(finalList.toString());
   2.212 -			*/
   2.213 -
   2.214 -			int varsMapSize = varsMap.size();
   2.215 -			for(Integer position : finalList)
   2.216 -			{
   2.217 -				if(position<varsMapSize)//thematic!
   2.218 -				{
   2.219 -					int count = 0;
   2.220 -					Iterator it = varsMap.entrySet().iterator();
   2.221 -
   2.222 -					while (it.hasNext())
   2.223 -					{
   2.224 -						{
   2.225 -							Map.Entry entry = (Map.Entry)it.next();
   2.226 -							if(count == position)
   2.227 -							{
   2.228 -								orderedJoinArgs.add((TupleExpr) entry.getKey());
   2.229 -
   2.230 -								it.remove();
   2.231 -								varsMapSize--;
   2.232 -
   2.233 -								for(int fix = 0 ; fix < finalList.size(); fix++)
   2.234 -								{
   2.235 -									if(finalList.get(fix) > position)
   2.236 -									{
   2.237 -										int reduced = finalList.get(fix) - 1;
   2.238 -										finalList.set(fix, reduced);
   2.239 -
   2.240 -									}
   2.241 -								}
   2.242 -								break;
   2.243 -							}
   2.244 -							count++;
   2.245 -						}
   2.246 -					}
   2.247 -				}
   2.248 -				else//temporal!
   2.249 -				{
   2.250 -					int count = 0;
   2.251 -					Iterator it = temporalFilters.entrySet().iterator();
   2.252 -					while (it.hasNext())
   2.253 -					{
   2.254 -						{
   2.255 -							Map.Entry entry = (Map.Entry)it.next();
   2.256 -							if(count == position - varsMapSize)
   2.257 -							{
   2.258 -								//If I keep record of this entry, I can use the info later to avoid duplicate filters
   2.259 -								temporalJoins.add((TupleExpr) entry.getKey());
   2.260 -								//
   2.261 -								orderedJoinArgs.add((TupleExpr) entry.getKey());
   2.262 -								it.remove();
   2.263 -								for(int fix = 0 ; fix < finalList.size(); fix++)
   2.264 -								{
   2.265 -									if(finalList.get(fix) > position)
   2.266 -									{
   2.267 -										int reduced = finalList.get(fix) - 1;
   2.268 -										finalList.set(fix, reduced);
   2.269 -									}
   2.270 -								}
   2.271 -								break;
   2.272 -							}
   2.273 -							count++;
   2.274 -						}
   2.275 -					}
   2.276 -				}
   2.277 -
   2.278 -			}
   2.279 -			//Must take care of the remainders as well!
   2.280 -			Iterator it = varsMap.entrySet().iterator();
   2.281 -			while (it.hasNext())
   2.282 -			{
   2.283 -				Map.Entry entry = (Map.Entry)it.next();
   2.284 -				orderedJoinArgs.add((TupleExpr) entry.getKey());
   2.285 -				it.remove();
   2.286 -			}
   2.287 -
   2.288 -			TupleExpr replacement = orderedJoinArgs.get(0);
   2.289 -			for (int ii = 1; ii < orderedJoinArgs.size(); ii++) {
   2.290 -				replacement = new Join(replacement, orderedJoinArgs.get(ii));
   2.291 -			}
   2.292 -
   2.293 -			// Replace old join hierarchy
   2.294 -			node.replaceWith(replacement);
   2.295 -
   2.296 +		else if(function instanceof TemporalRelationFunc)
   2.297 +		{
   2.298 +			return true;
   2.299  		}
   2.300 -
   2.301 -
   2.302 -		public boolean parentIsOptional(QueryModelNode node)
   2.303 -		{
   2.304 -			if(node.getParentNode() == null)
   2.305 -			{
   2.306 -				return false;
   2.307 -			}
   2.308 -			else if(node.getParentNode() instanceof LeftJoin)
   2.309 -			{
   2.310 -				return true;
   2.311 -			}
   2.312 -			else
   2.313 -			{
   2.314 -				return parentIsOptional(node.getParentNode());
   2.315 -			}
   2.316 -		}
   2.317 -
   2.318 -		/**
   2.319 -		 * General Comment: If more than one function exists in the query and can be used to perform the join, no preference is shown 
   2.320 -		 * on which function will actually be used for this purpose. This could cause an issue if ST_Disjoint is the one finally used, 
   2.321 -		 * as the index won't be used for the evaluation in this case. Perhaps I should include some 'priority'
   2.322 -		 */
   2.323 -		@Override
   2.324 -		public void meet(Filter node) {
   2.325 -
   2.326 -			/**
   2.327 -			 * Filter node must not be in OPTIONAL clause!
   2.328 -			 * After all, unneeded check. If an optional exists, the 'Filter' tuple expression
   2.329 -			 * is removed and only the Function Calls remain
   2.330 -			 */
   2.331 -			if(!withinHaving(node))
   2.332 -			{
   2.333 -				//if(!(node.getParentNode() instanceof LeftJoin))
   2.334 -				//{
   2.335 -				//XXX Ignore OR in Filters for now! (perhaps permanently)
   2.336 -				if(!(node.getCondition() instanceof Or))
   2.337 -				{
   2.338 -					if(node.getCondition() instanceof FunctionCall)
   2.339 -					{
   2.340 -						//Only interested in temporal ones
   2.341 -						if(isRelevantTemporalFunc((FunctionCall) node.getCondition()))
   2.342 -						{
   2.343 -							//Have to retrieve all nested variables and other info
   2.344 -
   2.345 -							//1.Retrieve varNames
   2.346 -							List<Var> varList = getFunctionCallVars((FunctionCall) node.getCondition());
   2.347 -
   2.348 -							//Cannot optimize buffer constructs when their 2nd argument is a 
   2.349 -							//thematic var, because I can't manipulate the order of the 
   2.350 -							//numeric_values table
   2.351 -							if(!problematicBuffer)
   2.352 -							{
   2.353 -								//XXX I cannot process cases involving more than 2 arguments in the temporal join!
   2.354 -								// They transcend the theta join level!
   2.355 -								//							if(varList.size()<3)
   2.356 -
   2.357 -								//if the arguments are not 2, I am essentially doing a selection!
   2.358 -								//No reason to push into optimizer then
   2.359 -								if(varList.size()==2)
   2.360 -								{
   2.361 -									//Add all important info about this temporal relationship to the appropriate structure
   2.362 -									//temporalFilters.add(new TemporalFilterInfo(varList, (FunctionCall) node.getCondition()));
   2.363 -									Filter toEnter = node.clone();
   2.364 -
   2.365 -									/**
   2.366 -									 * VERY CAREFUL HERE! 
   2.367 -									 * Reason I did this: If not, I would carry a copy of the whole expression for
   2.368 -									 * every extra filter of my query!
   2.369 -									 * -DUMMY-!!!
   2.370 -									 */
   2.371 -									StatementPattern t = new StatementPattern();
   2.372 -									t.setSubjectVar(new Var("-dummy-temporal"));
   2.373 -									t.setPredicateVar(new Var("-dummy-temporal"));
   2.374 -									t.setObjectVar(new Var("-dummy-temporal"));
   2.375 -									t.setScope(Scope.DEFAULT_CONTEXTS);
   2.376 -									toEnter.setArg(t);
   2.377 -
   2.378 -									if(!temporalFilters.containsKey(toEnter))
   2.379 -									{
   2.380 -										temporalFilters.put(toEnter,varList);
   2.381 -									}
   2.382 -								}
   2.383 -								problematicBuffer = false;
   2.384 -							}
   2.385 -						}
   2.386 -					}
   2.387 -					//Metrics
   2.388 -					//I have a similar problematic case with the one occurring in Buffer! 
   2.389 -					//Cannot manipulate the join order when I am dealing with numerics!
   2.390 -					//Therefore, I cannot use a numeric field (a numeric var) to alter the join sequence
   2.391 -					else if(node.getCondition() instanceof Compare)
   2.392 -					{
   2.393 -						containsTemporal = false;
   2.394 -						List<Var> allVars = new ArrayList<Var>(getVarsInMetricOrProperty(node.getCondition()));
   2.395 -						if(containsTemporal&&optimizableMetricOrProperty)
   2.396 -						{
   2.397 -							//if the arguments are not 2, I am essentially doing a selection!
   2.398 -							//No reason to push into optimizer then
   2.399 -							if(allVars.size()==2)
   2.400 -								//if(allVars.size()<3)
   2.401 -							{
   2.402 -								//Add all important info about this temporal relationship to the appropriate structure
   2.403 -								//temporalFilters.add(new TemporalFilterInfo(varList, (FunctionCall) node.getCondition()));
   2.404 -								Filter toEnter = node.clone();
   2.405 -
   2.406 -								StatementPattern t = new StatementPattern();
   2.407 -								t.setSubjectVar(new Var("-dummy-"));
   2.408 -								t.setPredicateVar(new Var("-dummy-"));
   2.409 -								t.setObjectVar(new Var("-dummy-"));
   2.410 -								t.setScope(Scope.DEFAULT_CONTEXTS);
   2.411 -								toEnter.setArg(t);
   2.412 -
   2.413 -								if(!temporalFilters.containsKey(toEnter))
   2.414 -								{
   2.415 -									temporalFilters.put(toEnter,allVars);
   2.416 -								}
   2.417 -							}
   2.418 -							containsTemporal = false;
   2.419 -						}
   2.420 -						optimizableMetricOrProperty = true;
   2.421 -					}
   2.422 -
   2.423 -				}
   2.424 -				//}
   2.425 -			}
   2.426 -
   2.427 -			//Last thing to do is ensuring the entire tree is traversed
   2.428 -			node.visitChildren(this);
   2.429 -
   2.430 -		}
   2.431 -
   2.432 -
   2.433 -		/**
   2.434 -		 * Helper Functions
   2.435 -		 */
   2.436 -
   2.437 -		/**
   2.438 -		 * Used to find out whether the Filter expr we are currently visiting is located inside
   2.439 -		 * a HAVING clause.
   2.440 -		 * 
   2.441 -		 * From what I have seen so far, it seems that if this is the case, its arg (or one of the following FILTER args in 
   2.442 -		 * the case of disjunction/conjunction) will be an Extension expr followed by a GROUP expr
   2.443 -		 */
   2.444 -		private boolean withinHaving(Filter expr)
   2.445 -		{
   2.446 -			if(expr.getArg() instanceof Extension)
   2.447 -			{
   2.448 -				return true;
   2.449 -			}
   2.450 -			else if(expr.getArg() instanceof Filter)
   2.451 -			{
   2.452 -				return withinHaving((Filter) expr.getArg());
   2.453 -			}
   2.454 -			else
   2.455 -			{
   2.456 -				return false;
   2.457 -			}
   2.458 -		}
   2.459 -
   2.460 -		private <L extends List<TupleExpr>> L getJoinArgs(TupleExpr tupleExpr, L joinArgs) {
   2.461 -			if (tupleExpr instanceof Join) {
   2.462 -				Join join = (Join)tupleExpr;
   2.463 -				if(getJoinArgs(join.getLeftArg(), joinArgs) == null)
   2.464 -					return null;
   2.465 -				if(getJoinArgs(join.getRightArg(), joinArgs) == null)
   2.466 -					return null;
   2.467 -			}
   2.468 -			else if(tupleExpr instanceof LeftJoin) 
   2.469 -			{
   2.470 -				//Trying to avoid OPTIONAL clauses from passing
   2.471 -				return null;
   2.472 -			}
   2.473 -			else 
   2.474 -			{
   2.475 -				joinArgs.add(tupleExpr);
   2.476 -			}
   2.477 -
   2.478 -			return joinArgs;
   2.479 -		}
   2.480 -
   2.481 -		private List<Var> getStatementPatternVars(TupleExpr tupleExpr) {
   2.482 -			List<StatementPattern> stPatterns = StatementPatternCollector.process(tupleExpr);
   2.483 -			List<Var> varList = new ArrayList<Var>(stPatterns.size() * 4);
   2.484 -			for (StatementPattern sp : stPatterns) {
   2.485 -				sp.getVars(varList);
   2.486 -			}
   2.487 -			return varList;
   2.488 -		}
   2.489 -
   2.490 -		/**
   2.491 -		 * temporalContent: Used to declare that this expression does include some temporal 
   2.492 -		 * content and an attempt should be made to use it in the joins' optimization process
   2.493 -		 */
   2.494 -		private Set<Var> getVarsInMetricOrProperty(ValueExpr expr)
   2.495 -		{
   2.496 -			Set<Var> allVars = new LinkedHashSet<Var>();
   2.497 -
   2.498 -			if(expr instanceof Compare)
   2.499 -			{
   2.500 -				allVars.addAll(getVarsInMetricOrProperty(((Compare) expr).getLeftArg()));
   2.501 -				allVars.addAll(getVarsInMetricOrProperty(((Compare) expr).getRightArg()));
   2.502 -			}
   2.503 -			else if(expr instanceof MathExpr)
   2.504 -			{
   2.505 -				allVars.addAll(getVarsInMetricOrProperty(((MathExpr) expr).getLeftArg()));
   2.506 -				allVars.addAll(getVarsInMetricOrProperty(((MathExpr) expr).getRightArg()));
   2.507 -			}
   2.508 -			else if(expr instanceof FunctionCall )
   2.509 -			{
   2.510 -				if(isRelevantTemporalFunc((FunctionCall) expr))
   2.511 -				{
   2.512 -					/**
   2.513 -					 * There is a point in continuing the search recursively ONLY 
   2.514 -					 * if I reach this case. Otherwise, the function call
   2.515 -					 * may not refer to a temporal function
   2.516 -					 */
   2.517 -					this.containsTemporal = true;
   2.518 -					allVars.addAll(getFunctionCallVars((FunctionCall) expr));
   2.519 -
   2.520 -				}
   2.521 -			}
   2.522 -			else if(expr instanceof Var)
   2.523 -			{
   2.524 -				if(!(expr.getParentNode() instanceof FunctionCall))
   2.525 -				{
   2.526 -					//Cannot manipulate the join order when I am dealing with numerics!
   2.527 -					//Therefore, I cannot use a numeric field (a numeric var) to alter the join sequence
   2.528 -					this.optimizableMetricOrProperty = false;
   2.529 -				}
   2.530 -				if(!allVars.contains(expr))
   2.531 -				{
   2.532 -					allVars.add((Var) expr);
   2.533 -				}
   2.534 -			}
   2.535 -
   2.536 -			return allVars;
   2.537 -		}
   2.538 -
   2.539 -		private boolean isRelevantTemporalFunc(FunctionCall functionCall)
   2.540 -		{
   2.541 -			Function function = FunctionRegistry.getInstance().get(functionCall.getURI());
   2.542 -			if(function instanceof org.openrdf.query.algebra.evaluation.function.temporal.stsparql.construct.TemporalConstructFunc )
   2.543 -			{
   2.544 -				//TODO may have to comment this part again
   2.545 -				//uncommented because I use this function in the case of metrics
   2.546 -				return true;
   2.547 -			}
   2.548 -			else if(function instanceof TemporalRelationFunc)
   2.549 -			{
   2.550 -				return true;
   2.551 -			}
   2.552 -			return false;
   2.553 -		}
   2.554 -
   2.555 -		private List<Var> getFunctionCallVars(FunctionCall functionCall) {
   2.556 -			List<Var> varList = new ArrayList<Var>();
   2.557 -			int argList = 0;
   2.558 -			for(ValueExpr expr : functionCall.getArgs())
   2.559 -			{
   2.560 -				argList++;
   2.561 -				if(expr instanceof Var)
   2.562 -				{
   2.563 -					//					if(!existingVars.contains(((Var) expr).getName()))
   2.564 -					//					{
   2.565 -					//						existingVars.add(((Var) expr).getName());
   2.566 -					//					}
   2.567 -
   2.568 -					if(!varList.contains(expr))
   2.569 -					{
   2.570 -						//Was using this code when I tried to incorporate the Buffer case buffer(?Temporal,?thematic)
   2.571 -						if(argList == 2 && functionCall.getURI().equals("http://strdf.di.uoa.gr/ontology#buffer"))
   2.572 -						{
   2.573 -							problematicBuffer = true;
   2.574 -						}
   2.575 -						varList.add((Var) expr);
   2.576 -					}
   2.577 -
   2.578 -				}
   2.579 -				else if(expr instanceof FunctionCall)
   2.580 -				{
   2.581 -					varList.addAll(getFunctionCallVars((FunctionCall) expr));
   2.582 -				}
   2.583 -				//TODO Should I add any additional cases? I don't think so
   2.584 -				else
   2.585 -				{
   2.586 -					continue;
   2.587 -				}
   2.588 -			}
   2.589 -			return varList;
   2.590 -		}
   2.591 -
   2.592 -		/**
   2.593 -		 * Both lists belong to either a thematic node (St.Pattern) or a temporal node (Filter)
   2.594 -		 * Comparing the vars with each other to discover links of the query graph
   2.595 -		 * @param list1 
   2.596 -		 * @param list2
   2.597 -		 * @return
   2.598 -		 */
   2.599 -		private int sameVar(List<Var> list1, List<Var> list2)
   2.600 -		{
   2.601 -			for(Var var : list1)
   2.602 -			{
   2.603 -				if(list2.contains(var))
   2.604 -				{
   2.605 -					return 1;
   2.606 -				}
   2.607 -			}
   2.608 -
   2.609 -			return 0;
   2.610 -		}
   2.611 -
   2.612 -
   2.613 -
   2.614 -
   2.615 -
   2.616 -		//Input: a single line of the table
   2.617 -		//NOTE: NO LOOPS! CAREFUL!!
   2.618 -		private boolean createOrderedJoins(int table[][], int lineToScan,int columnToSkip, 
   2.619 -				int pathLen, Set<Var> varsTillNow, List<Integer> tempList, List<Integer> pathList, List<Integer> finalList)
   2.620 -		{
   2.621 -			boolean success = false;
   2.622 -			int dims = table.length;
   2.623 -
   2.624 -			int j;
   2.625 -
   2.626 -			//dims: all arguments
   2.627 -			for(j = 0; j < dims; j++)
   2.628 -			{
   2.629 -				if(j == columnToSkip)
   2.630 -				{
   2.631 -					continue;
   2.632 -				}
   2.633 -
   2.634 -				//A connection exists!
   2.635 -				if(table[lineToScan][j]>0)
   2.636 -				{
   2.637 -					//Don't want my graph to have circles!!!
   2.638 -					if(!tempList.contains(j)&&!pathList.contains(j))
   2.639 -					{
   2.640 -						if(j >= thematicJoinsSize) //aka if(temporalFilters.size() > 0)
   2.641 -						{
   2.642 -							List<Var> thisFilterVars = null;
   2.643 -							int count = 0;
   2.644 -							for(List<Var> vars : temporalFilters.values())
   2.645 -							{
   2.646 -								if(count == j - thematicJoinsSize)
   2.647 -								{
   2.648 -									thisFilterVars = vars;
   2.649 -									break;
   2.650 -								}
   2.651 -								count++;
   2.652 -							}
   2.653 -							if(!varsTillNow.isEmpty())
   2.654 -							{
   2.655 -								if(varsTillNow.containsAll(thisFilterVars))
   2.656 -								{
   2.657 -									continue;
   2.658 -								}
   2.659 -							}
   2.660 -
   2.661 -							//varsTillNow.add(thisFilterVars.get(1));
   2.662 -							varsTillNow.addAll(thisFilterVars);
   2.663 -
   2.664 -						}
   2.665 -
   2.666 -						tempList.add((Integer)j);
   2.667 -						pathLen++;
   2.668 -						if(pathLen == dims)
   2.669 -						{
   2.670 -							//End of recursion
   2.671 -							pathList.addAll(tempList);
   2.672 -							tempList.clear();
   2.673 -							finalList.clear();
   2.674 -							finalList.addAll(pathList);
   2.675 -
   2.676 -							return true;
   2.677 -						}
   2.678 -
   2.679 -						//Recurse
   2.680 -						success = createOrderedJoins(table, j, lineToScan, pathLen, varsTillNow, tempList, pathList, finalList);
   2.681 -
   2.682 -						//Success = true => recursion ended with pathLen = maxLen
   2.683 -						if(success)
   2.684 -						{
   2.685 -							return true;
   2.686 -						}
   2.687 -						else
   2.688 -						{	
   2.689 -							//end of a path originating from this node was found -> find an additional path (if exists)
   2.690 -							continue;
   2.691 -						}
   2.692 -					}
   2.693 -				}
   2.694 -			}
   2.695 -			//To reach this place means the end of a path was found 
   2.696 -			pathList.addAll(tempList);
   2.697 -			tempList.clear();
   2.698 -			if(pathList.size() > finalList.size())
   2.699 -			{
   2.700 -				finalList.clear();
   2.701 -				finalList.addAll(pathList);
   2.702 -				if(finalList.size() == dims)
   2.703 -				{
   2.704 -					return true;
   2.705 -				}
   2.706 -			}
   2.707 -			return false;			
   2.708 -		}
   2.709 -
   2.710 +		return false;
   2.711  	}
   2.712  
   2.713 +	@Override
   2.714 +	public String getClassName() {
   2.715 +		// TODO Auto-generated method stub
   2.716 +		return this.getClass().getCanonicalName();
   2.717 +	}
   2.718 +
   2.719  
   2.720  }
     3.1 --- a/generaldb/src/main/java/org/openrdf/sail/generaldb/optimizers/GeneralDBQueryOptimizer.java	Fri May 10 16:10:00 2013 +0300
     3.2 +++ b/generaldb/src/main/java/org/openrdf/sail/generaldb/optimizers/GeneralDBQueryOptimizer.java	Fri May 10 19:27:31 2013 +0300
     3.3 @@ -119,7 +119,7 @@
     3.4  		//XXX
     3.5  		new SpatialJoinOptimizer().optimize(expr, dataset, bindings,spatialJoins);
     3.6  		
     3.7 -		new TemporalJoinOptimizer().optimize(expr, dataset, bindings, temporalJoins);
     3.8 +		//new TemporalJoinOptimizer().optimize(expr, dataset, bindings, temporalJoins);
     3.9  	}
    3.10  
    3.11  	protected void rdbmsOptimizations(TupleExpr expr, Dataset dataset, BindingSet bindings) {