Strabon

changeset 294:dc26807e3b3f

Issue with double spatial predicates most likely resolved.
Will test with queries of NOA
author Manos Karpathiotakis <mk@di.uoa.gr>
date Tue Jun 19 17:16:20 2012 +0300 (2012-06-19)
parents 5e7b26452def
children ac3e112e7478
files evaluation/src/main/java/org/openrdf/query/algebra/evaluation/impl/SpatialJoinOptimizer.java generaldb/src/main/java/org/openrdf/sail/generaldb/optimizers/GeneralDBQueryOptimizer.java generaldb/src/main/java/org/openrdf/sail/generaldb/optimizers/GeneralDBSelectQueryOptimizer.java postgis/src/main/java/org/openrdf/sail/postgis/evaluation/PostGISEvaluation.java
line diff
     1.1 --- a/evaluation/src/main/java/org/openrdf/query/algebra/evaluation/impl/SpatialJoinOptimizer.java	Tue Jun 19 16:45:00 2012 +0300
     1.2 +++ b/evaluation/src/main/java/org/openrdf/query/algebra/evaluation/impl/SpatialJoinOptimizer.java	Tue Jun 19 17:16:20 2012 +0300
     1.3 @@ -52,7 +52,9 @@
     1.4   * @author James Leigh
     1.5   */
     1.6  
     1.7 -public class SpatialJoinOptimizer implements QueryOptimizer {
     1.8 +public class SpatialJoinOptimizer 
     1.9 +//implements QueryOptimizer //Removed it consciously 
    1.10 +{
    1.11  
    1.12  
    1.13  	//private Set<String> existingVars = new TreeSet<String>();
    1.14 @@ -62,12 +64,21 @@
    1.15  	 * 
    1.16  	 * @param tupleExpr
    1.17  	 */
    1.18 -	public void optimize(TupleExpr tupleExpr, Dataset dataset, BindingSet bindings) {
    1.19 -		tupleExpr.visit(new JoinVisitor());
    1.20 +	public void optimize(TupleExpr tupleExpr, Dataset dataset, BindingSet bindings, List<TupleExpr> spatialJoins) {
    1.21 +		tupleExpr.visit(new JoinVisitor(spatialJoins));
    1.22  	}
    1.23  
    1.24  	protected class JoinVisitor extends QueryModelVisitorBase<RuntimeException> {
    1.25 +		
    1.26 +		
    1.27 +		
    1.28 +		public JoinVisitor(List<TupleExpr> spatialJoins) {
    1.29 +			super();
    1.30 +			this.spatialJoins = spatialJoins;
    1.31 +		}
    1.32  
    1.33 +		
    1.34 +		private List<TupleExpr> spatialJoins;
    1.35  		//buffer with a var as a second argument
    1.36  		private boolean problematicBuffer = false;
    1.37  
    1.38 @@ -275,6 +286,9 @@
    1.39  							Map.Entry entry = (Map.Entry)it.next();
    1.40  							if(count == position - varsMapSize)
    1.41  							{
    1.42 +								//If I keep record of this entry, I can use the info later to avoid duplicate filters
    1.43 +								spatialJoins.add((TupleExpr) entry.getKey());
    1.44 +								//
    1.45  								orderedJoinArgs.add((TupleExpr) entry.getKey());
    1.46  								it.remove();
    1.47  								for(int fix = 0 ; fix < finalList.size(); fix++)
    1.48 @@ -329,7 +343,11 @@
    1.49  			}
    1.50  		}
    1.51  
    1.52 -
    1.53 +		/**
    1.54 +		 * General Comment: If more than one function exists in the query and can be used to perform the join, no preference is shown 
    1.55 +		 * on which function will actually be used for this purpose. This could cause an issue if ST_Disjoint is the one finally used, 
    1.56 +		 * as the index won't be used for the evaluation in this case. Perhaps I should include some 'priority'
    1.57 +		 */
    1.58  		@Override
    1.59  		public void meet(Filter node) {
    1.60  
     2.1 --- a/generaldb/src/main/java/org/openrdf/sail/generaldb/optimizers/GeneralDBQueryOptimizer.java	Tue Jun 19 16:45:00 2012 +0300
     2.2 +++ b/generaldb/src/main/java/org/openrdf/sail/generaldb/optimizers/GeneralDBQueryOptimizer.java	Tue Jun 19 17:16:20 2012 +0300
     2.3 @@ -5,6 +5,9 @@
     2.4   */
     2.5  package org.openrdf.sail.generaldb.optimizers;
     2.6  
     2.7 +import java.util.ArrayList;
     2.8 +import java.util.List;
     2.9 +
    2.10  import org.openrdf.query.BindingSet;
    2.11  import org.openrdf.query.Dataset;
    2.12  import org.openrdf.query.algebra.QueryRoot;
    2.13 @@ -42,7 +45,11 @@
    2.14  	private GeneralDBSelectQueryOptimizerFactory factory;
    2.15  
    2.16  	private HashTable hashTable;
    2.17 -
    2.18 +	
    2.19 +	//Addition to locate duplicate filters caused by the SpatialJoinOptimizer
    2.20 +	List<TupleExpr> spatialJoins = new ArrayList<TupleExpr>();
    2.21 +	//
    2.22 +	
    2.23  	public void setSelectQueryOptimizerFactory(GeneralDBSelectQueryOptimizerFactory factory) {
    2.24  		this.factory = factory;
    2.25  	}
    2.26 @@ -100,12 +107,13 @@
    2.27  		new SameTermFilterOptimizer().optimize(expr, dataset, bindings);
    2.28  
    2.29  		//XXX
    2.30 -		new SpatialJoinOptimizer().optimize(expr, dataset, bindings);
    2.31 +		new SpatialJoinOptimizer().optimize(expr, dataset, bindings,spatialJoins);
    2.32  	}
    2.33  
    2.34  	protected void rdbmsOptimizations(TupleExpr expr, Dataset dataset, BindingSet bindings) {
    2.35  		new GeneralDBValueIdLookupOptimizer(vf).optimize(expr, dataset, bindings);
    2.36 -		factory.createRdbmsFilterOptimizer().optimize(expr, dataset, bindings);
    2.37 +		factory.createRdbmsFilterOptimizer().optimize(expr, dataset, bindings,spatialJoins);
    2.38 +		this.spatialJoins.clear();
    2.39  		new GeneralDBVarColumnLookupOptimizer().optimize(expr, dataset, bindings);
    2.40  		GeneralDBValueJoinOptimizer valueJoins = new GeneralDBValueJoinOptimizer();
    2.41  		valueJoins.setBnodeTable(bnodes);
     3.1 --- a/generaldb/src/main/java/org/openrdf/sail/generaldb/optimizers/GeneralDBSelectQueryOptimizer.java	Tue Jun 19 16:45:00 2012 +0300
     3.2 +++ b/generaldb/src/main/java/org/openrdf/sail/generaldb/optimizers/GeneralDBSelectQueryOptimizer.java	Tue Jun 19 17:16:20 2012 +0300
     3.3 @@ -52,6 +52,7 @@
     3.4  import org.openrdf.query.algebra.Projection;
     3.5  import org.openrdf.query.algebra.ProjectionElem;
     3.6  import org.openrdf.query.algebra.ProjectionElemList;
     3.7 +import org.openrdf.query.algebra.QueryModelNode;
     3.8  import org.openrdf.query.algebra.Slice;
     3.9  import org.openrdf.query.algebra.StatementPattern;
    3.10  import org.openrdf.query.algebra.TupleExpr;
    3.11 @@ -113,16 +114,17 @@
    3.12   * @author James Leigh
    3.13   * 
    3.14   */
    3.15 -public class GeneralDBSelectQueryOptimizer extends GeneralDBQueryModelVisitorBase<RuntimeException> implements
    3.16 -QueryOptimizer
    3.17 +public class GeneralDBSelectQueryOptimizer extends GeneralDBQueryModelVisitorBase<RuntimeException> 
    3.18 +//implements QueryOptimizer //removed it consciously
    3.19  {
    3.20  
    3.21  	/**
    3.22  	 * XXX additions (manolee)
    3.23  	 */
    3.24 +	private List<TupleExpr> spatialJoins;
    3.25  
    3.26  	//assuming no more than 10 uniquely-named variables will be spatial in the average case 
    3.27 -	private ArrayList<String> geoNames = new ArrayList<String>(10);
    3.28 +	private List<String> geoNames = new ArrayList<String>(10);
    3.29  
    3.30  	//private Map<String, GeneralDBSqlExpr> constructsForSelect = new HashMap<String, GeneralDBSqlExpr>();
    3.31  
    3.32 @@ -183,29 +185,29 @@
    3.33  		this.ids = ids;
    3.34  	}
    3.35  
    3.36 -	public void optimize(TupleExpr tupleExpr, Dataset dataset, BindingSet bindings) {
    3.37 +	public void optimize(TupleExpr tupleExpr, Dataset dataset, BindingSet bindings, List<TupleExpr> spatialJoins) {
    3.38  		this.dataset = dataset;
    3.39  		this.bindings = bindings;
    3.40 +		this.spatialJoins = spatialJoins;
    3.41  		tupleExpr.visit(this);
    3.42 -		//System.out.println("placeholder");
    3.43  	}
    3.44  
    3.45  	@Override
    3.46  	public void meet(Distinct node)
    3.47 -	throws RuntimeException
    3.48 -	{
    3.49 +			throws RuntimeException
    3.50 +			{
    3.51  		super.meet(node);
    3.52  		if (node.getArg() instanceof GeneralDBSelectQuery) {
    3.53  			GeneralDBSelectQuery query = (GeneralDBSelectQuery)node.getArg();
    3.54  			query.setDistinct(true);
    3.55  			node.replaceWith(query);
    3.56  		}
    3.57 -	}
    3.58 +			}
    3.59  
    3.60  	@Override
    3.61  	public void meet(Union node)
    3.62 -	throws RuntimeException
    3.63 -	{
    3.64 +			throws RuntimeException
    3.65 +			{
    3.66  		super.meet(node);
    3.67  		TupleExpr l = node.getLeftArg();
    3.68  		TupleExpr r = node.getRightArg();
    3.69 @@ -225,7 +227,7 @@
    3.70  		mergeSelectClause(query, right);
    3.71  		addProjectionsFromUnion(query, union);
    3.72  		node.replaceWith(query);
    3.73 -	}
    3.74 +			}
    3.75  
    3.76  	/**
    3.77  	 * This happens when both sides of the union have the same variable name with
    3.78 @@ -248,8 +250,8 @@
    3.79  
    3.80  	@Override
    3.81  	public void meet(Join node)
    3.82 -	throws RuntimeException
    3.83 -	{
    3.84 +			throws RuntimeException
    3.85 +			{
    3.86  		super.meet(node);
    3.87  		TupleExpr l = node.getLeftArg();
    3.88  		TupleExpr r = node.getRightArg();
    3.89 @@ -270,12 +272,12 @@
    3.90  		 * This change was made before altering the spatial joins operation
    3.91  		 */
    3.92  		reference = left;
    3.93 -	}
    3.94 +			}
    3.95  
    3.96  	@Override
    3.97  	public void meet(LeftJoin node)
    3.98 -	throws RuntimeException
    3.99 -	{
   3.100 +			throws RuntimeException
   3.101 +			{
   3.102  		super.meet(node);
   3.103  		TupleExpr l = node.getLeftArg();
   3.104  		TupleExpr r = node.getRightArg();
   3.105 @@ -306,7 +308,7 @@
   3.106  		}
   3.107  		node.replaceWith(left);
   3.108  		reference = left;
   3.109 -	}
   3.110 +			}
   3.111  
   3.112  	@Override
   3.113  	public void meet(StatementPattern sp) {
   3.114 @@ -497,8 +499,8 @@
   3.115  
   3.116  	@Override
   3.117  	public void meet(Filter node)
   3.118 -	throws RuntimeException
   3.119 -	{
   3.120 +			throws RuntimeException
   3.121 +			{
   3.122  
   3.123  		/**
   3.124  		 * XXX 21/09/2011 addition for spatial joins
   3.125 @@ -752,40 +754,68 @@
   3.126  		/**
   3.127  		 * End of addition
   3.128  		 */
   3.129 -		else //DEFAULT BEHAVIOR
   3.130 +		else //DEFAULT BEHAVIOR (Enhanced with check for duplicates)
   3.131  		{
   3.132 +
   3.133 +			boolean dup = false;
   3.134 +			ValueExpr dupFunctionCall = node.getCondition();
   3.135 +			for(TupleExpr sfilter : this.spatialJoins)
   3.136 +			{
   3.137 +				ValueExpr tmpExpr = ((Filter)sfilter).getCondition();
   3.138 +				if(tmpExpr.equals(dupFunctionCall))
   3.139 +				{
   3.140 +					//					QueryModelNode parent = node.getParentNode();
   3.141 +					//					TupleExpr replacement = ((Filter)node).getArg();
   3.142 +					//					parent.replaceChildNode(node, replacement);
   3.143 +					//					//If I do reach this point, the former 'child' argument will be a traditional Join operator
   3.144 +					//					super.meet((Join)replacement);
   3.145 +					//					node.setCondition(null);
   3.146 +					//					return;
   3.147 +					dup = true;
   3.148 +					break;
   3.149 +				}
   3.150 +			}
   3.151 +
   3.152  			super.meet(node);
   3.153  			if (node.getArg() instanceof GeneralDBSelectQuery) {
   3.154  				GeneralDBSelectQuery query = (GeneralDBSelectQuery)node.getArg();
   3.155  
   3.156  				ValueExpr condition = null;
   3.157 -				for (ValueExpr expr : flatten(node.getCondition())) {
   3.158 -					try {
   3.159 -						//07/09/2011
   3.160 -						//Attempt to move spatial selections and joins to FROM clause
   3.161 -						//XXX removed because I followed a different approach. May come in handy later on. 09/09/11
   3.162 -						//					if(node.getCondition() instanceof FunctionCall)
   3.163 -						//					{
   3.164 -						//						GeneralDBSqlExpr sqlExpression = sql.createBooleanExpr(expr);
   3.165 -						//						query.addSpatialFilter(sqlExpression);
   3.166 -						//						//query.getFrom().addFilter(sql.createBooleanExpr(expr));
   3.167 -						//						query.addFilter(sqlExpression);
   3.168 -						//					}
   3.169 -						//					else //DEFAULT CASE
   3.170 -						//					{
   3.171 -						query.addFilter(sql.createBooleanExpr(expr));
   3.172 -						//					}
   3.173 +				if(!dup)
   3.174 +				{
   3.175 +					for (ValueExpr expr : flatten(node.getCondition())) {
   3.176 +						try {
   3.177 +							//07/09/2011
   3.178 +							//Attempt to move spatial selections and joins to FROM clause
   3.179 +							//XXX removed because I followed a different approach. May come in handy later on. 09/09/11
   3.180 +							//					if(node.getCondition() instanceof FunctionCall)
   3.181 +							//					{
   3.182 +							//						GeneralDBSqlExpr sqlExpression = sql.createBooleanExpr(expr);
   3.183 +							//						query.addSpatialFilter(sqlExpression);
   3.184 +							//						//query.getFrom().addFilter(sql.createBooleanExpr(expr));
   3.185 +							//						query.addFilter(sqlExpression);
   3.186 +							//					}
   3.187 +							//					else //DEFAULT CASE
   3.188 +							//					{
   3.189 +							query.addFilter(sql.createBooleanExpr(expr));
   3.190 +							//					}
   3.191  
   3.192 -					}
   3.193 -					catch (UnsupportedRdbmsOperatorException e) {
   3.194 -						if (condition == null) {
   3.195 -							condition = expr;
   3.196  						}
   3.197 -						else {
   3.198 -							condition = new And(condition, expr);
   3.199 +						catch (UnsupportedRdbmsOperatorException e) {
   3.200 +							if (condition == null) {
   3.201 +								condition = expr;
   3.202 +							}
   3.203 +							else {
   3.204 +								condition = new And(condition, expr);
   3.205 +							}
   3.206  						}
   3.207  					}
   3.208  				}
   3.209 +				else
   3.210 +				{
   3.211 +					condition = null;
   3.212 +				}
   3.213 +
   3.214  				if (condition == null) {
   3.215  					node.replaceWith(node.getArg());
   3.216  				}
   3.217 @@ -838,14 +868,14 @@
   3.218  
   3.219  
   3.220  		}
   3.221 -	}
   3.222 +			}
   3.223  
   3.224  
   3.225  
   3.226  	@Override
   3.227  	public void meet(Projection node)
   3.228 -	throws RuntimeException
   3.229 -	{
   3.230 +			throws RuntimeException
   3.231 +			{
   3.232  		super.meet(node);
   3.233  		if (node.getArg() instanceof GeneralDBSelectQuery) {
   3.234  			GeneralDBSelectQuery query = (GeneralDBSelectQuery)node.getArg();
   3.235 @@ -866,15 +896,15 @@
   3.236  			query.setSqlSelectVar(selection);
   3.237  			node.replaceWith(query);
   3.238  		}
   3.239 -	}
   3.240 +			}
   3.241  
   3.242  	/**
   3.243  	 * XXX used to retrieve the geoNames from the TRADITIONAL filter clauses - not the ones in Joins
   3.244  	 */
   3.245  	@Override
   3.246  	public void meet(FunctionCall node)
   3.247 -	throws RuntimeException
   3.248 -	{
   3.249 +			throws RuntimeException
   3.250 +			{
   3.251  		Function function = FunctionRegistry.getInstance().get(node.getURI());
   3.252  
   3.253  		super.meet(node);
   3.254 @@ -936,7 +966,7 @@
   3.255  			//			}
   3.256  		}
   3.257  
   3.258 -	}
   3.259 +			}
   3.260  
   3.261  	//
   3.262  	@Override
   3.263 @@ -1042,7 +1072,7 @@
   3.264  		else if(expr instanceof BinaryValueOperator)
   3.265  		{
   3.266  			return thematicExpression(((BinaryValueOperator) expr).getLeftArg()) &&
   3.267 -				   thematicExpression(((BinaryValueOperator) expr).getRightArg());
   3.268 +					thematicExpression(((BinaryValueOperator) expr).getRightArg());
   3.269  		}
   3.270  		else
   3.271  		{
   3.272 @@ -1195,8 +1225,8 @@
   3.273  
   3.274  	@Override
   3.275  	public void meet(Slice node)
   3.276 -	throws RuntimeException
   3.277 -	{
   3.278 +			throws RuntimeException
   3.279 +			{
   3.280  		super.meet(node);
   3.281  		if (node.getArg() instanceof GeneralDBSelectQuery) {
   3.282  			GeneralDBSelectQuery query = (GeneralDBSelectQuery)node.getArg();
   3.283 @@ -1208,12 +1238,12 @@
   3.284  			}
   3.285  			node.replaceWith(query);
   3.286  		}
   3.287 -	}
   3.288 +			}
   3.289  
   3.290  	@Override
   3.291  	public void meet(Order node)
   3.292 -	throws RuntimeException
   3.293 -	{
   3.294 +			throws RuntimeException
   3.295 +			{
   3.296  		int mbbCounter = 0;
   3.297  		//		super.meet(node);
   3.298  		if (!(node.getArg() instanceof GeneralDBSelectQuery))
   3.299 @@ -1344,7 +1374,7 @@
   3.300  		catch (UnsupportedRdbmsOperatorException e) {
   3.301  			// unsupported
   3.302  		}
   3.303 -	}
   3.304 +			}
   3.305  
   3.306  	/**
   3.307  	 * FIXME uncomment if you need sorted results based on the group by's contents!!!
     4.1 --- a/postgis/src/main/java/org/openrdf/sail/postgis/evaluation/PostGISEvaluation.java	Tue Jun 19 16:45:00 2012 +0300
     4.2 +++ b/postgis/src/main/java/org/openrdf/sail/postgis/evaluation/PostGISEvaluation.java	Tue Jun 19 17:16:20 2012 +0300
     4.3 @@ -73,7 +73,7 @@
     4.4  				result.setGeoNames(this.geoNames);
     4.5  				result.setConstructIndexesAndNames(this.constructIndexesAndNames);
     4.6  				//
     4.7 -		
     4.8 +//				System.out.println("In PostGIS Evaluation, query is: \n" + stmt);
     4.9  				if (logger.isDebugEnabled()) {
    4.10  					logger.debug("In PostGIS Evaluation, query is: \n{}", stmt);
    4.11  				}