Strabon

changeset 43:07eaeca98f59

Fixed bug related with aggregate functions. Confidence calculation should now work
author Manos Karpathiotakis <mk@di.uoa.gr>
date Sat Mar 10 03:55:10 2012 +0200 (2012-03-10)
parents e21067f0e959
children 7bbf921b454d
files generaldb/src/main/java/org/openrdf/sail/generaldb/evaluation/GeneralDBEvaluation.java generaldb/src/main/java/org/openrdf/sail/generaldb/optimizers/GeneralDBSelectQueryOptimizer.java postgis/src/main/java/org/openrdf/sail/postgis/evaluation/PostGISQueryBuilder.java
line diff
     1.1 --- a/generaldb/src/main/java/org/openrdf/sail/generaldb/evaluation/GeneralDBEvaluation.java	Thu Mar 08 19:59:26 2012 +0200
     1.2 +++ b/generaldb/src/main/java/org/openrdf/sail/generaldb/evaluation/GeneralDBEvaluation.java	Sat Mar 10 03:55:10 2012 +0200
     1.3 @@ -144,6 +144,8 @@
     1.4  
     1.5  	protected HashMap<Integer,String> geoNames = new HashMap<Integer,String>();
     1.6  
     1.7 +	protected List<GeneralDBSqlExpr> thematicExpressions = new ArrayList<GeneralDBSqlExpr>(5);
     1.8 +
     1.9  	//used to retrieve the appropriate column in the Binding Iteration
    1.10  	protected HashMap<GeneralDBSpatialFuncInfo, Integer> constructIndexesAndNames = new HashMap<GeneralDBSpatialFuncInfo, Integer>();
    1.11  	//private HashMap<String, Integer> constructIndexesAndNames = new HashMap<String, Integer>();
    1.12 @@ -166,8 +168,8 @@
    1.13  	@Override
    1.14  	public CloseableIteration<BindingSet, QueryEvaluationException> evaluate(TupleExpr expr,
    1.15  			BindingSet bindings)
    1.16 -	throws QueryEvaluationException
    1.17 -	{
    1.18 +			throws QueryEvaluationException
    1.19 +			{
    1.20  		if (expr instanceof GeneralDBSelectQuery)
    1.21  			return evaluate((GeneralDBSelectQuery)expr, bindings);
    1.22  		else if (expr instanceof Group) {
    1.23 @@ -177,11 +179,11 @@
    1.24  			return evaluate((Order)expr, bindings);
    1.25  		}
    1.26  		return super.evaluate(expr, bindings);
    1.27 -	}
    1.28 +			}
    1.29  	@Override
    1.30  	public Value evaluate(ValueExpr expr, BindingSet bindings)
    1.31 -			throws ValueExprEvaluationException, QueryEvaluationException
    1.32 -			{
    1.33 +	throws ValueExprEvaluationException, QueryEvaluationException
    1.34 +	{
    1.35  		if (expr instanceof Var) {
    1.36  			return evaluate((Var)expr, bindings);
    1.37  		}
    1.38 @@ -189,7 +191,7 @@
    1.39  			return evaluate((FunctionCall)expr, bindings);
    1.40  		}
    1.41  		return super.evaluate(expr, bindings);
    1.42 -			}
    1.43 +	}
    1.44  
    1.45  	/**
    1.46  	 * Had to use it for the cases met in group by (Union as an aggregate)
    1.47 @@ -198,12 +200,12 @@
    1.48  	public Value evaluate(Var var, BindingSet bindings) throws ValueExprEvaluationException, QueryEvaluationException
    1.49  	{
    1.50  		boolean groupBy = false;
    1.51 -//		//Case met when ORDER BY involved (?)
    1.52 -//		if(var.getName().startsWith("-mbbVar-"))
    1.53 -//		{
    1.54 -//			var.setName(var.getName().replace("-mbbVar-",""));
    1.55 -//		}
    1.56 -		
    1.57 +		//		//Case met when ORDER BY involved (?)
    1.58 +		//		if(var.getName().startsWith("-mbbVar-"))
    1.59 +		//		{
    1.60 +		//			var.setName(var.getName().replace("-mbbVar-",""));
    1.61 +		//		}
    1.62 +
    1.63  		//Case met when evaluating a construct function inside an aggregate 
    1.64  		if(var.getName().endsWith("?spatial"))
    1.65  		{
    1.66 @@ -256,33 +258,33 @@
    1.67  				}
    1.68  			}
    1.69  		}
    1.70 -		
    1.71 +
    1.72  		Function function = FunctionRegistry.getInstance().get(fc.getURI());
    1.73  
    1.74 -//		if(fc.getParentNode() instanceof Filter)
    1.75 -//		{
    1.76 -//			//Traditional Behavior!
    1.77 -//			try {
    1.78 -//				if (function == null) {
    1.79 -//					throw new QueryEvaluationException("Unknown function '" + fc.getURI() + "'");
    1.80 -//				}
    1.81 -//
    1.82 -//				List<ValueExpr> args = fc.getArgs();
    1.83 -//
    1.84 -//				Value[] argValues = new Value[args.size()];
    1.85 -//
    1.86 -//				for (int i = 0; i < args.size(); i++) {
    1.87 -//
    1.88 -//					argValues[i] = evaluate(args.get(i), bindings);
    1.89 -//
    1.90 -//				}
    1.91 -//
    1.92 -//				return function.evaluate(tripleSource.getValueFactory(), argValues);} catch (ValueExprEvaluationException e) {
    1.93 -//					e.printStackTrace();
    1.94 -//				} catch (QueryEvaluationException e) {
    1.95 -//					e.printStackTrace();
    1.96 -//				}
    1.97 -//		}
    1.98 +		//		if(fc.getParentNode() instanceof Filter)
    1.99 +		//		{
   1.100 +		//			//Traditional Behavior!
   1.101 +		//			try {
   1.102 +		//				if (function == null) {
   1.103 +		//					throw new QueryEvaluationException("Unknown function '" + fc.getURI() + "'");
   1.104 +		//				}
   1.105 +		//
   1.106 +		//				List<ValueExpr> args = fc.getArgs();
   1.107 +		//
   1.108 +		//				Value[] argValues = new Value[args.size()];
   1.109 +		//
   1.110 +		//				for (int i = 0; i < args.size(); i++) {
   1.111 +		//
   1.112 +		//					argValues[i] = evaluate(args.get(i), bindings);
   1.113 +		//
   1.114 +		//				}
   1.115 +		//
   1.116 +		//				return function.evaluate(tripleSource.getValueFactory(), argValues);} catch (ValueExprEvaluationException e) {
   1.117 +		//					e.printStackTrace();
   1.118 +		//				} catch (QueryEvaluationException e) {
   1.119 +		//					e.printStackTrace();
   1.120 +		//				}
   1.121 +		//		}
   1.122  		ValueExpr left = fc.getArgs().get(0);
   1.123  
   1.124  
   1.125 @@ -298,9 +300,9 @@
   1.126  		}
   1.127  
   1.128  
   1.129 -//		if(!(function instanceof EnvelopeFunc) 
   1.130 -//				&& !(function instanceof ConvexHullFunc) 
   1.131 -//				&& !(function instanceof BoundaryFunc))
   1.132 +		//		if(!(function instanceof EnvelopeFunc) 
   1.133 +		//				&& !(function instanceof ConvexHullFunc) 
   1.134 +		//				&& !(function instanceof BoundaryFunc))
   1.135  		if ( fc.getArgs().size() == 2 )
   1.136  		{
   1.137  			ValueExpr right = fc.getArgs().get(1);
   1.138 @@ -312,7 +314,7 @@
   1.139  				e.printStackTrace();
   1.140  			}
   1.141  		}
   1.142 -		
   1.143 +
   1.144  		try {
   1.145  			if ( function instanceof SpatialConstructFunc ) 
   1.146  				return spatialConstructPicker(function, leftResult, rightResult);
   1.147 @@ -335,7 +337,7 @@
   1.148  				{	//SHOULD NEVER REACH THIS CASE!
   1.149  					return null;
   1.150  				}
   1.151 -				
   1.152 +
   1.153  				if(rightResult instanceof StrabonPolyhedron)
   1.154  				{
   1.155  					rightGeom = ((StrabonPolyhedron) rightResult).getGeometry();
   1.156 @@ -348,8 +350,8 @@
   1.157  				{	//SHOULD NEVER REACH THIS CASE!
   1.158  					return null;
   1.159  				}
   1.160 -				
   1.161 -				
   1.162 +
   1.163 +
   1.164  				if(function instanceof AboveFunc)
   1.165  				{
   1.166  					funcResult = leftGeom.getEnvelopeInternal().getMinY() > rightGeom.getEnvelopeInternal().getMaxY();
   1.167 @@ -403,7 +405,7 @@
   1.168  				{
   1.169  					funcResult = leftGeom.touches(rightGeom);
   1.170  				}
   1.171 -				
   1.172 +
   1.173  				return funcResult ? BooleanLiteralImpl.TRUE : BooleanLiteralImpl.FALSE;
   1.174  			}
   1.175  			else {
   1.176 @@ -479,29 +481,29 @@
   1.177  
   1.178  	@Override
   1.179  	public CloseableIteration<BindingSet, QueryEvaluationException> evaluate(Group node, BindingSet bindings)
   1.180 -			throws QueryEvaluationException
   1.181 -			{
   1.182 -//		Set<String> tmp1 = node.getAggregateBindingNames();
   1.183 -//		Set<String> tmp2 = node.getAssuredBindingNames();
   1.184 -//		Set<String> tmp3 = node.getBindingNames();
   1.185 -//		Set<String> tmp4 = node.getGroupBindingNames();
   1.186 -//		for(String tmp : tmp4)
   1.187 -//		{
   1.188 -//			//System.out.println(node.g);
   1.189 -//		}
   1.190 +	throws QueryEvaluationException
   1.191 +	{
   1.192 +		//		Set<String> tmp1 = node.getAggregateBindingNames();
   1.193 +		//		Set<String> tmp2 = node.getAssuredBindingNames();
   1.194 +		//		Set<String> tmp3 = node.getBindingNames();
   1.195 +		//		Set<String> tmp4 = node.getGroupBindingNames();
   1.196 +		//		for(String tmp : tmp4)
   1.197 +		//		{
   1.198 +		//			//System.out.println(node.g);
   1.199 +		//		}
   1.200  		return new StSPARQLGroupIterator(this, node, bindings);
   1.201 -			}
   1.202 +	}
   1.203  
   1.204  	@Override
   1.205  	public CloseableIteration<BindingSet, QueryEvaluationException> evaluate(Order node, BindingSet bindings)
   1.206 -			throws QueryEvaluationException
   1.207 -			{
   1.208 +	throws QueryEvaluationException
   1.209 +	{
   1.210  		StSPARQLValueComparator vcmp = new StSPARQLValueComparator();
   1.211  		StSPARQLOrderComparator cmp = new StSPARQLOrderComparator(this, node, vcmp);
   1.212  		boolean reduced = isReduced(node);
   1.213  		long limit = getLimit(node);
   1.214  		return new OrderIterator(evaluate(node.getArg(), bindings), cmp, limit, reduced);
   1.215 -			}
   1.216 +	}
   1.217  
   1.218  	//Duplicated from EvaluationStrategyImpl
   1.219  	private boolean isReduced(QueryModelNode node) {
   1.220 @@ -584,10 +586,10 @@
   1.221  	//	}
   1.222  
   1.223  	protected abstract CloseableIteration<BindingSet, QueryEvaluationException> evaluate(GeneralDBSelectQuery qb, BindingSet b)
   1.224 -			throws UnsupportedRdbmsOperatorException, RdbmsQueryEvaluationException;
   1.225 +	throws UnsupportedRdbmsOperatorException, RdbmsQueryEvaluationException;
   1.226  
   1.227  	protected String toQueryString(GeneralDBSelectQuery qb, QueryBindingSet bindings, List<Object> parameters)
   1.228 -		throws RdbmsException, UnsupportedRdbmsOperatorException
   1.229 +	throws RdbmsException, UnsupportedRdbmsOperatorException
   1.230  	{
   1.231  		GeneralDBQueryBuilder query = factory.createQueryBuilder();
   1.232  		if (qb.isDistinct()) {
   1.233 @@ -662,35 +664,41 @@
   1.234  			GeneralDBSqlExpr expr = (GeneralDBSqlExpr) pairs.getValue();
   1.235  			locateColumnVars(expr,qb.getVars());
   1.236  
   1.237 -			query.construct(expr); 
   1.238 -			GeneralDBSpatialFuncInfo info = null;
   1.239 -			switch(constructReturnType(expr))
   1.240 +			//Assuming thematic aggregates and spatial expressions won't be combined
   1.241 +			if(!this.thematicExpressions.contains(expr))
   1.242  			{
   1.243 -			case 1:
   1.244 -				//Integer
   1.245 -				info = new GeneralDBSpatialFuncInfo((String) pairs.getKey(), typeOfField.Integer);
   1.246 -				break;
   1.247 -			case 2: 
   1.248 -				//String
   1.249 -				info = new GeneralDBSpatialFuncInfo((String) pairs.getKey(), typeOfField.String);
   1.250 -				break;
   1.251 -			case 3: 
   1.252 -				//Boolean
   1.253 -				info = new GeneralDBSpatialFuncInfo((String) pairs.getKey(), typeOfField.Boolean);
   1.254 -				break;
   1.255 -			case 4: 
   1.256 -				//WKB
   1.257 -				info = new GeneralDBSpatialFuncInfo((String) pairs.getKey(), typeOfField.WKB);
   1.258 -				break;
   1.259 -			case 5: 
   1.260 -				//DOUBLE
   1.261 -				info = new GeneralDBSpatialFuncInfo((String) pairs.getKey(), typeOfField.Double);
   1.262 -				break;
   1.263 -			default: throw new UnsupportedRdbmsOperatorException("No such spatial expression exists!");
   1.264 +				query.construct(expr);
   1.265 +
   1.266 +
   1.267 +				GeneralDBSpatialFuncInfo info = null;
   1.268 +				switch(constructReturnType(expr))
   1.269 +				{
   1.270 +				case 1:
   1.271 +					//Integer
   1.272 +					info = new GeneralDBSpatialFuncInfo((String) pairs.getKey(), typeOfField.Integer);
   1.273 +					break;
   1.274 +				case 2: 
   1.275 +					//String
   1.276 +					info = new GeneralDBSpatialFuncInfo((String) pairs.getKey(), typeOfField.String);
   1.277 +					break;
   1.278 +				case 3: 
   1.279 +					//Boolean
   1.280 +					info = new GeneralDBSpatialFuncInfo((String) pairs.getKey(), typeOfField.Boolean);
   1.281 +					break;
   1.282 +				case 4: 
   1.283 +					//WKB
   1.284 +					info = new GeneralDBSpatialFuncInfo((String) pairs.getKey(), typeOfField.WKB);
   1.285 +					break;
   1.286 +				case 5: 
   1.287 +					//DOUBLE
   1.288 +					info = new GeneralDBSpatialFuncInfo((String) pairs.getKey(), typeOfField.Double);
   1.289 +					break;
   1.290 +				default: throw new UnsupportedRdbmsOperatorException("No such spatial expression exists!");
   1.291 +				}
   1.292 +
   1.293 +				//constructIndexesAndNames.put((String) pairs.getKey(),index++);
   1.294 +				constructIndexesAndNames.put(info,index++);
   1.295  			}
   1.296 -
   1.297 -			//constructIndexesAndNames.put((String) pairs.getKey(),index++);
   1.298 -			constructIndexesAndNames.put(info,index++);
   1.299  		}
   1.300  		//
   1.301  
   1.302 @@ -785,6 +793,7 @@
   1.303  		}
   1.304  		else if(expr instanceof GeneralDBNumericColumn)//ColumnVar at least
   1.305  		{
   1.306 +			boolean found = false;
   1.307  			String name = ((GeneralDBNumericColumn) expr).getVarName();
   1.308  
   1.309  			//String alias =  ((GeneralDBNumericColumn) expr).getAlias();
   1.310 @@ -797,8 +806,17 @@
   1.311  
   1.312  					GeneralDBSqlExpr exprCopy = new GeneralDBLabelColumn(reference,false);
   1.313  					expr.replaceWith(exprCopy);
   1.314 +					found = true;
   1.315  				}
   1.316  			}
   1.317 +
   1.318 +			if(!found)
   1.319 +			{
   1.320 +				//Will keep non-spatial math expressions to avoid iterating through them 
   1.321 +				//at QueryBuilder.construct. Otherwise, exception occurs. 
   1.322 +				//This case probably only concerns thematic aggregates
   1.323 +				this.thematicExpressions.add((GeneralDBSqlExpr)expr.getParentNode());
   1.324 +			}
   1.325  			//System.out.println("stopper");
   1.326  		}
   1.327  		else if(expr instanceof GeneralDBSqlMathExpr)//Case when I have calculations in select
     2.1 --- a/generaldb/src/main/java/org/openrdf/sail/generaldb/optimizers/GeneralDBSelectQueryOptimizer.java	Thu Mar 08 19:59:26 2012 +0200
     2.2 +++ b/generaldb/src/main/java/org/openrdf/sail/generaldb/optimizers/GeneralDBSelectQueryOptimizer.java	Sat Mar 10 03:55:10 2012 +0200
     2.3 @@ -35,6 +35,7 @@
     2.4  import org.openrdf.query.Dataset;
     2.5  import org.openrdf.query.algebra.And;
     2.6  import org.openrdf.query.algebra.Avg;
     2.7 +import org.openrdf.query.algebra.BinaryValueOperator;
     2.8  import org.openrdf.query.algebra.Compare;
     2.9  import org.openrdf.query.algebra.Distinct;
    2.10  import org.openrdf.query.algebra.Extension;
    2.11 @@ -54,6 +55,7 @@
    2.12  import org.openrdf.query.algebra.Slice;
    2.13  import org.openrdf.query.algebra.StatementPattern;
    2.14  import org.openrdf.query.algebra.TupleExpr;
    2.15 +import org.openrdf.query.algebra.UnaryValueOperator;
    2.16  import org.openrdf.query.algebra.Union;
    2.17  import org.openrdf.query.algebra.ValueExpr;
    2.18  import org.openrdf.query.algebra.Var;
    2.19 @@ -87,10 +89,14 @@
    2.20  import org.openrdf.sail.generaldb.algebra.GeneralDBSelectQuery;
    2.21  import org.openrdf.sail.generaldb.algebra.GeneralDBSqlEq;
    2.22  import org.openrdf.sail.generaldb.algebra.GeneralDBSqlOr;
    2.23 +import org.openrdf.sail.generaldb.algebra.GeneralDBSqlSpatialMetricBinary;
    2.24 +import org.openrdf.sail.generaldb.algebra.GeneralDBSqlSpatialMetricUnary;
    2.25  import org.openrdf.sail.generaldb.algebra.GeneralDBURIColumn;
    2.26  import org.openrdf.sail.generaldb.algebra.GeneralDBUnionItem;
    2.27 +import org.openrdf.sail.generaldb.algebra.base.BinaryGeneralDBOperator;
    2.28  import org.openrdf.sail.generaldb.algebra.base.GeneralDBQueryModelVisitorBase;
    2.29  import org.openrdf.sail.generaldb.algebra.base.GeneralDBSqlExpr;
    2.30 +import org.openrdf.sail.generaldb.algebra.base.UnaryGeneralDBOperator;
    2.31  import org.openrdf.sail.generaldb.algebra.factories.GeneralDBSqlExprFactory;
    2.32  import org.openrdf.sail.rdbms.exceptions.RdbmsException;
    2.33  import org.openrdf.sail.rdbms.exceptions.RdbmsRuntimeException;
    2.34 @@ -976,12 +982,20 @@
    2.35  				}
    2.36  
    2.37  			}
    2.38 +			//Issue: MathExpr is not exclusively met in spatial cases!
    2.39 +			//Need to distinguish thematic and spatial!!
    2.40 +
    2.41 +			//One way to do it: Check for label column in children of expression. If none exists: No way sth spatial is involved!
    2.42  			else if(expr instanceof MathExpr)
    2.43  			{
    2.44  				try {
    2.45 -					sqlExpr = sql.getNumericExprFactory().createNumericExpr(expr);
    2.46 -					reference.getSpatialConstructs().put(name, sqlExpr);
    2.47 -					iter.remove();
    2.48 +					if(!thematicExpression(expr))
    2.49 +					{
    2.50 +						sqlExpr = sql.getNumericExprFactory().createNumericExpr(expr);
    2.51 +
    2.52 +						reference.getSpatialConstructs().put(name, sqlExpr);
    2.53 +						iter.remove();
    2.54 +					}
    2.55  				} catch (UnsupportedRdbmsOperatorException e) {
    2.56  					e.printStackTrace();
    2.57  				}
    2.58 @@ -1017,6 +1031,33 @@
    2.59  		}
    2.60  	}
    2.61  
    2.62 +	//Checking that no spatial function exists in this metric expression
    2.63 +	private boolean thematicExpression(ValueExpr expr)
    2.64 +	{
    2.65 +		if(expr instanceof UnaryValueOperator)
    2.66 +		{
    2.67 +			return thematicExpression(((UnaryValueOperator) expr).getArg());
    2.68 +		}
    2.69 +		else if(expr instanceof BinaryValueOperator)
    2.70 +		{
    2.71 +			return thematicExpression(((BinaryValueOperator) expr).getLeftArg()) &&
    2.72 +				   thematicExpression(((BinaryValueOperator) expr).getRightArg());
    2.73 +		}
    2.74 +		else
    2.75 +		{
    2.76 +			if(expr instanceof FunctionCall)
    2.77 +			{
    2.78 +				Function function = FunctionRegistry.getInstance().get(((FunctionCall) expr).getURI());
    2.79 +				if(function instanceof SpatialMetricFunc)
    2.80 +				{
    2.81 +					return false;
    2.82 +				}
    2.83 +			}
    2.84 +			return true;
    2.85 +		}
    2.86 +
    2.87 +	}
    2.88 +
    2.89  	/**
    2.90  	 * XXX 23/11/11
    2.91  	 * Commented because I now aim to evaluate any function calls present in SELECT with JTS in the case they
    2.92 @@ -1173,7 +1214,7 @@
    2.93  	throws RuntimeException
    2.94  	{
    2.95  		int mbbCounter = 0;
    2.96 -//		super.meet(node);
    2.97 +		//		super.meet(node);
    2.98  		if (!(node.getArg() instanceof GeneralDBSelectQuery))
    2.99  			//In other words, I have encountered having/groupby
   2.100  		{
   2.101 @@ -1200,20 +1241,20 @@
   2.102  							{
   2.103  								Extension ext = new Extension();
   2.104  								ext.addElement(extElem);
   2.105 -//								((Projection)(node.getParentNode())).setArg(ext);
   2.106 -//								ext.setArg(node);
   2.107 +								//								((Projection)(node.getParentNode())).setArg(ext);
   2.108 +								//								ext.setArg(node);
   2.109  								Extension tmpExt = (Extension) node.getArg();
   2.110  								node.setArg(ext);
   2.111  								ext.setArg(tmpExt);
   2.112 -								
   2.113 +
   2.114  							}
   2.115 -//							else if(node.getParentNode() instanceof Projection)
   2.116 -//							{
   2.117 -//								Extension ext = new Extension();
   2.118 -//								ext.addElement(extElem);
   2.119 -//								((Projection)(node.getParentNode())).setArg(ext);
   2.120 -//								ext.setArg(node);
   2.121 -//							}
   2.122 +							//							else if(node.getParentNode() instanceof Projection)
   2.123 +							//							{
   2.124 +							//								Extension ext = new Extension();
   2.125 +							//								ext.addElement(extElem);
   2.126 +							//								((Projection)(node.getParentNode())).setArg(ext);
   2.127 +							//								ext.setArg(node);
   2.128 +							//							}
   2.129  							else if(node.getParentNode() instanceof Extension)
   2.130  							{
   2.131  								((Extension)node.getParentNode()).addElement(extElem);
   2.132 @@ -1235,19 +1276,19 @@
   2.133  					{
   2.134  						Extension ext = new Extension();
   2.135  						ext.addElement(extElem);
   2.136 -//						((Projection)(node.getParentNode())).setArg(ext);
   2.137 -//						ext.setArg(node);
   2.138 +						//						((Projection)(node.getParentNode())).setArg(ext);
   2.139 +						//						ext.setArg(node);
   2.140  						Extension tmpExt = (Extension) node.getArg();
   2.141  						node.setArg(ext);
   2.142  						ext.setArg(tmpExt);
   2.143  					}
   2.144 -//					else if(node.getParentNode() instanceof Projection)
   2.145 -//					{
   2.146 -//						Extension ext = new Extension();
   2.147 -//						ext.addElement(extElem);
   2.148 -//						((Projection)(node.getParentNode())).setArg(ext);
   2.149 -//						ext.setArg(node);
   2.150 -//					}
   2.151 +					//					else if(node.getParentNode() instanceof Projection)
   2.152 +					//					{
   2.153 +					//						Extension ext = new Extension();
   2.154 +					//						ext.addElement(extElem);
   2.155 +					//						((Projection)(node.getParentNode())).setArg(ext);
   2.156 +					//						ext.setArg(node);
   2.157 +					//					}
   2.158  					else if(node.getParentNode() instanceof Extension)
   2.159  					{
   2.160  						((Extension)node.getParentNode()).addElement(extElem);
     3.1 --- a/postgis/src/main/java/org/openrdf/sail/postgis/evaluation/PostGISQueryBuilder.java	Thu Mar 08 19:59:26 2012 +0200
     3.2 +++ b/postgis/src/main/java/org/openrdf/sail/postgis/evaluation/PostGISQueryBuilder.java	Sat Mar 10 03:55:10 2012 +0200
     3.3 @@ -284,9 +284,11 @@
     3.4  			}
     3.5  
     3.6  	//FIXME my addition from here on
     3.7 +	
     3.8 +	//Issue with this function: crashes when MathExpr is present in Select but does not
     3.9 +	//involve spatial variables! must escape this somehow
    3.10  	@Override
    3.11 -	public GeneralDBQueryBuilder construct(GeneralDBSqlExpr expr)
    3.12 -			throws UnsupportedRdbmsOperatorException
    3.13 +	public GeneralDBQueryBuilder construct(GeneralDBSqlExpr expr) throws UnsupportedRdbmsOperatorException
    3.14  			{
    3.15  		if(!(expr instanceof GeneralDBSqlSpatialMetricBinary) 
    3.16  				&&!(expr instanceof GeneralDBSqlSpatialMetricUnary)