Strabon

changeset 193:065c75ef3026 experiments

Johny Cache
author Manos Karpathiotakis <mk@di.uoa.gr>
date Thu May 24 13:58:55 2012 +0300 (2012-05-24)
parents 6ae3bb2cc015
children 0e2280ccf198
files generaldb/pom.xml generaldb/src/main/java/org/openrdf/sail/generaldb/iteration/GeneralDBBindingIteration.java generaldb/src/main/java/org/openrdf/sail/generaldb/schema/TripleTable.java generaldb/src/main/java/org/openrdf/sail/generaldb/schema/ValueTable.java monetdb/pom.xml pom.xml postgis/pom.xml rdbms/pom.xml rdbms/src/main/java/org/openrdf/sail/rdbms/RdbmsConnection.java rdbms/src/main/java/org/openrdf/sail/rdbms/RdbmsConnectionFactory.java rdbms/src/main/java/org/openrdf/sail/rdbms/RdbmsProvider.java rdbms/src/main/java/org/openrdf/sail/rdbms/RdbmsStore.java rdbms/src/main/java/org/openrdf/sail/rdbms/RdbmsTripleRepository.java rdbms/src/main/java/org/openrdf/sail/rdbms/RdbmsValueFactory.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/BNodeColumn.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/ColumnVar.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/DatatypeColumn.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/DateTimeColumn.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/DoubleValue.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/FalseValue.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/HashColumn.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/IdColumn.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/JoinItem.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/LabelColumn.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/LanguageColumn.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/LongLabelColumn.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/LongURIColumn.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/NumberValue.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/NumericColumn.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/RefIdColumn.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/SelectProjection.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/SelectQuery.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/SqlAbs.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/SqlAnd.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/SqlCase.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/SqlCast.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/SqlCompare.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/SqlConcat.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/SqlEq.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/SqlIsNull.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/SqlLike.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/SqlLowerCase.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/SqlMathExpr.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/SqlNot.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/SqlNull.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/SqlOr.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/SqlRegex.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/SqlShift.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/StringValue.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/TrueValue.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/URIColumn.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/UnionItem.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/base/BinarySqlOperator.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/base/BooleanValue.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/base/FromItem.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/base/RdbmsQueryModelNodeBase.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/base/RdbmsQueryModelVisitorBase.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/base/SqlConstant.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/base/SqlExpr.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/base/SqlExprSupport.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/base/UnarySqlOperator.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/base/ValueColumnBase.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/factories/BNodeExprFactory.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/factories/BooleanExprFactory.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/factories/DatatypeExprFactory.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/factories/HashExprFactory.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/factories/LabelExprFactory.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/factories/LanguageExprFactory.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/factories/NumericExprFactory.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/factories/SqlExprFactory.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/factories/TimeExprFactory.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/factories/URIExprFactory.java rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/factories/ZonedExprFactory.java rdbms/src/main/java/org/openrdf/sail/rdbms/config/RdbmsStoreConfig.java rdbms/src/main/java/org/openrdf/sail/rdbms/config/RdbmsStoreFactory.java rdbms/src/main/java/org/openrdf/sail/rdbms/config/RdbmsStoreSchema.java rdbms/src/main/java/org/openrdf/sail/rdbms/evaluation/QueryBuilder.java rdbms/src/main/java/org/openrdf/sail/rdbms/evaluation/QueryBuilderFactory.java rdbms/src/main/java/org/openrdf/sail/rdbms/evaluation/RdbmsEvaluation.java rdbms/src/main/java/org/openrdf/sail/rdbms/evaluation/RdbmsEvaluationFactory.java rdbms/src/main/java/org/openrdf/sail/rdbms/evaluation/RdbmsTripleSource.java rdbms/src/main/java/org/openrdf/sail/rdbms/evaluation/SqlBracketBuilder.java rdbms/src/main/java/org/openrdf/sail/rdbms/evaluation/SqlCaseBuilder.java rdbms/src/main/java/org/openrdf/sail/rdbms/evaluation/SqlCastBuilder.java rdbms/src/main/java/org/openrdf/sail/rdbms/evaluation/SqlExprBuilder.java rdbms/src/main/java/org/openrdf/sail/rdbms/evaluation/SqlJoinBuilder.java rdbms/src/main/java/org/openrdf/sail/rdbms/evaluation/SqlQueryBuilder.java rdbms/src/main/java/org/openrdf/sail/rdbms/evaluation/SqlRegexBuilder.java rdbms/src/main/java/org/openrdf/sail/rdbms/exceptions/RdbmsException.java rdbms/src/main/java/org/openrdf/sail/rdbms/exceptions/RdbmsQueryEvaluationException.java rdbms/src/main/java/org/openrdf/sail/rdbms/exceptions/RdbmsRuntimeException.java rdbms/src/main/java/org/openrdf/sail/rdbms/exceptions/UnsupportedRdbmsOperatorException.java rdbms/src/main/java/org/openrdf/sail/rdbms/iteration/EmptyRdbmsResourceIteration.java rdbms/src/main/java/org/openrdf/sail/rdbms/iteration/EmptyRdbmsStatementIteration.java rdbms/src/main/java/org/openrdf/sail/rdbms/iteration/NamespaceIteration.java rdbms/src/main/java/org/openrdf/sail/rdbms/iteration/RdbmsBindingIteration.java rdbms/src/main/java/org/openrdf/sail/rdbms/iteration/RdbmsResourceIteration.java rdbms/src/main/java/org/openrdf/sail/rdbms/iteration/RdbmsStatementIteration.java rdbms/src/main/java/org/openrdf/sail/rdbms/iteration/base/RdbmIterationBase.java rdbms/src/main/java/org/openrdf/sail/rdbms/managers/BNodeManager.java rdbms/src/main/java/org/openrdf/sail/rdbms/managers/HashManager.java rdbms/src/main/java/org/openrdf/sail/rdbms/managers/LiteralManager.java rdbms/src/main/java/org/openrdf/sail/rdbms/managers/NamespaceManager.java rdbms/src/main/java/org/openrdf/sail/rdbms/managers/PredicateManager.java rdbms/src/main/java/org/openrdf/sail/rdbms/managers/TransTableManager.java rdbms/src/main/java/org/openrdf/sail/rdbms/managers/TripleManager.java rdbms/src/main/java/org/openrdf/sail/rdbms/managers/TripleTableManager.java rdbms/src/main/java/org/openrdf/sail/rdbms/managers/UriManager.java rdbms/src/main/java/org/openrdf/sail/rdbms/managers/base/ManagerBase.java rdbms/src/main/java/org/openrdf/sail/rdbms/managers/base/ValueManagerBase.java rdbms/src/main/java/org/openrdf/sail/rdbms/managers/helpers/BatchBlockingQueue.java rdbms/src/main/java/org/openrdf/sail/rdbms/model/RdbmsBNode.java rdbms/src/main/java/org/openrdf/sail/rdbms/model/RdbmsLiteral.java rdbms/src/main/java/org/openrdf/sail/rdbms/model/RdbmsResource.java rdbms/src/main/java/org/openrdf/sail/rdbms/model/RdbmsStatement.java rdbms/src/main/java/org/openrdf/sail/rdbms/model/RdbmsURI.java rdbms/src/main/java/org/openrdf/sail/rdbms/model/RdbmsValue.java rdbms/src/main/java/org/openrdf/sail/rdbms/mysql/MySqlConnectionFactory.java rdbms/src/main/java/org/openrdf/sail/rdbms/mysql/MySqlProvider.java rdbms/src/main/java/org/openrdf/sail/rdbms/mysql/MySqlStore.java rdbms/src/main/java/org/openrdf/sail/rdbms/mysql/MySqlTable.java rdbms/src/main/java/org/openrdf/sail/rdbms/mysql/MySqlValueTable.java rdbms/src/main/java/org/openrdf/sail/rdbms/optimizers/RdbmsQueryOptimizer.java rdbms/src/main/java/org/openrdf/sail/rdbms/optimizers/SelectQueryOptimizer.java rdbms/src/main/java/org/openrdf/sail/rdbms/optimizers/SelectQueryOptimizerFactory.java rdbms/src/main/java/org/openrdf/sail/rdbms/optimizers/SqlConstantOptimizer.java rdbms/src/main/java/org/openrdf/sail/rdbms/optimizers/ValueIdLookupOptimizer.java rdbms/src/main/java/org/openrdf/sail/rdbms/optimizers/ValueJoinOptimizer.java rdbms/src/main/java/org/openrdf/sail/rdbms/optimizers/VarColumnLookupOptimizer.java rdbms/src/main/java/org/openrdf/sail/rdbms/postgresql/PgQueryBuilderFactory.java rdbms/src/main/java/org/openrdf/sail/rdbms/postgresql/PgSqlConnectionFactory.java rdbms/src/main/java/org/openrdf/sail/rdbms/postgresql/PgSqlProvider.java rdbms/src/main/java/org/openrdf/sail/rdbms/postgresql/PgSqlQueryBuilder.java rdbms/src/main/java/org/openrdf/sail/rdbms/postgresql/PgSqlQueryOptimizer.java rdbms/src/main/java/org/openrdf/sail/rdbms/postgresql/PgSqlRegexFlagsInliner.java rdbms/src/main/java/org/openrdf/sail/rdbms/postgresql/PgSqlStore.java rdbms/src/main/java/org/openrdf/sail/rdbms/postgresql/PgSqlTable.java rdbms/src/main/java/org/openrdf/sail/rdbms/postgresql/PgSqlTableFactory.java rdbms/src/main/java/org/openrdf/sail/rdbms/postgresql/PgSqlValueTable.java rdbms/src/main/java/org/openrdf/sail/rdbms/postgresql/PgSqlValueTableFactory.java rdbms/src/main/java/org/openrdf/sail/rdbms/schema/BNodeTable.java rdbms/src/main/java/org/openrdf/sail/rdbms/schema/Batch.java rdbms/src/main/java/org/openrdf/sail/rdbms/schema/HashBatch.java rdbms/src/main/java/org/openrdf/sail/rdbms/schema/HashTable.java rdbms/src/main/java/org/openrdf/sail/rdbms/schema/IdSequence.java rdbms/src/main/java/org/openrdf/sail/rdbms/schema/IntegerIdSequence.java rdbms/src/main/java/org/openrdf/sail/rdbms/schema/LiteralTable.java rdbms/src/main/java/org/openrdf/sail/rdbms/schema/LongIdSequence.java rdbms/src/main/java/org/openrdf/sail/rdbms/schema/NamespacesTable.java rdbms/src/main/java/org/openrdf/sail/rdbms/schema/RdbmsTable.java rdbms/src/main/java/org/openrdf/sail/rdbms/schema/TableFactory.java rdbms/src/main/java/org/openrdf/sail/rdbms/schema/TransactionTable.java rdbms/src/main/java/org/openrdf/sail/rdbms/schema/TripleBatch.java rdbms/src/main/java/org/openrdf/sail/rdbms/schema/TripleTable.java rdbms/src/main/java/org/openrdf/sail/rdbms/schema/URITable.java rdbms/src/main/java/org/openrdf/sail/rdbms/schema/ValueBatch.java rdbms/src/main/java/org/openrdf/sail/rdbms/schema/ValueTable.java rdbms/src/main/java/org/openrdf/sail/rdbms/schema/ValueTableFactory.java rdbms/src/main/java/org/openrdf/sail/rdbms/schema/ValueType.java rdbms/src/main/java/org/openrdf/sail/rdbms/schema/ValueTypes.java rdbms/src/main/java/org/openrdf/sail/rdbms/util/DatabaseLockManager.java rdbms/src/main/java/org/openrdf/sail/rdbms/util/LRUMap.java rdbms/src/main/java/org/openrdf/sail/rdbms/util/Tracer.java runtime/pom.xml runtime/src/main/java/eu/earthobservatory/runtime/generaldb/Strabon.java runtime/src/main/java/eu/earthobservatory/runtime/monetdb/Strabon.java runtime/src/main/java/eu/earthobservatory/runtime/postgis/QueryOp_ExtraArg.java runtime/src/main/java/eu/earthobservatory/runtime/postgis/StoreOp_ExtraArg.java runtime/src/main/java/eu/earthobservatory/runtime/postgis/Strabon.java
line diff
     1.1 --- a/generaldb/pom.xml	Wed May 23 21:42:05 2012 +0300
     1.2 +++ b/generaldb/pom.xml	Thu May 24 13:58:55 2012 +0300
     1.3 @@ -24,7 +24,7 @@
     1.4  		</dependency>
     1.5  		<dependency>
     1.6  			<groupId>org.openrdf.sesame</groupId>
     1.7 -			<artifactId>sesame-sail-rdbms</artifactId>
     1.8 +			<artifactId>sesame-sail-rdbms-caches</artifactId>
     1.9  		</dependency>
    1.10  		<dependency>
    1.11  			<groupId>org.openrdf.sesame</groupId>
     2.1 --- a/generaldb/src/main/java/org/openrdf/sail/generaldb/iteration/GeneralDBBindingIteration.java	Wed May 23 21:42:05 2012 +0300
     2.2 +++ b/generaldb/src/main/java/org/openrdf/sail/generaldb/iteration/GeneralDBBindingIteration.java	Thu May 24 13:58:55 2012 +0300
     2.3 @@ -111,25 +111,25 @@
     2.4  	throws SQLException
     2.5  	{
     2.6  		
     2.7 -		/// debug
     2.8 -		for(int i=1; i<12;i++) {
     2.9 -			Object o = rs.getObject(i);
    2.10 -			if (o instanceof byte[] ) {
    2.11 -				byte[] label = rs.getBytes(i);
    2.12 -				int srid = rs.getInt(i + 1);
    2.13 -				GeneralDBPolyhedron g = vf.getRdbmsPolyhedron(114, StrabonPolyhedron.ogcGeometry, label, srid);
    2.14 -				System.out.println(i+": "+g.getPolyhedronStringRep());
    2.15 -			} else if (o instanceof Blob ) {
    2.16 -				Blob labelBlob = rs.getBlob(i); 
    2.17 -				byte[] label = labelBlob.getBytes((long)1, (int)labelBlob.length());
    2.18 -				int srid = rs.getInt(i + 1);
    2.19 -				GeneralDBPolyhedron g = vf.getRdbmsPolyhedron(114, StrabonPolyhedron.ogcGeometry, label, srid);
    2.20 -				System.out.println(i+": "+g.getPolyhedronStringRep());
    2.21 -			}  
    2.22 -			else 
    2.23 -				System.out.println(i+": "+rs.getObject(i));
    2.24 -		}
    2.25 -		///
    2.26 +//		/// debug
    2.27 +//		for(int i=1; i<12;i++) {
    2.28 +//			Object o = rs.getObject(i);
    2.29 +//			if (o instanceof byte[] ) {
    2.30 +//				byte[] label = rs.getBytes(i);
    2.31 +//				int srid = rs.getInt(i + 1);
    2.32 +//				GeneralDBPolyhedron g = vf.getRdbmsPolyhedron(114, StrabonPolyhedron.ogcGeometry, label, srid);
    2.33 +//				System.out.println(i+": "+g.getPolyhedronStringRep());
    2.34 +//			} else if (o instanceof Blob ) {
    2.35 +//				Blob labelBlob = rs.getBlob(i); 
    2.36 +//				byte[] label = labelBlob.getBytes((long)1, (int)labelBlob.length());
    2.37 +//				int srid = rs.getInt(i + 1);
    2.38 +//				GeneralDBPolyhedron g = vf.getRdbmsPolyhedron(114, StrabonPolyhedron.ogcGeometry, label, srid);
    2.39 +//				System.out.println(i+": "+g.getPolyhedronStringRep());
    2.40 +//			}  
    2.41 +//			else 
    2.42 +//				System.out.println(i+": "+rs.getObject(i));
    2.43 +//		}
    2.44 +//		///
    2.45  
    2.46  		QueryBindingSet result = new QueryBindingSet(bindings);
    2.47  		for (GeneralDBColumnVar var : projections) {
     3.1 --- a/generaldb/src/main/java/org/openrdf/sail/generaldb/schema/TripleTable.java	Wed May 23 21:42:05 2012 +0300
     3.2 +++ b/generaldb/src/main/java/org/openrdf/sail/generaldb/schema/TripleTable.java	Thu May 24 13:58:55 2012 +0300
     3.3 @@ -5,10 +5,18 @@
     3.4   */
     3.5  package org.openrdf.sail.generaldb.schema;
     3.6  
     3.7 +import java.io.DataInputStream;
     3.8 +import java.io.DataOutputStream;
     3.9 +import java.io.File;
    3.10 +import java.io.FileInputStream;
    3.11 +import java.io.FileNotFoundException;
    3.12 +import java.io.FileOutputStream;
    3.13 +import java.io.IOException;
    3.14  import java.sql.SQLException;
    3.15  import java.util.List;
    3.16  import java.util.Map;
    3.17  
    3.18 +import org.openrdf.query.algebra.evaluation.function.spatial.StrabonPolyhedron;
    3.19  import org.openrdf.sail.rdbms.schema.RdbmsTable;
    3.20  import org.openrdf.sail.rdbms.schema.ValueTypes;
    3.21  import org.openrdf.sail.rdbms.schema.ValueType;
    3.22 @@ -53,6 +61,12 @@
    3.23  
    3.24  	private IdSequence ids;
    3.25  
    3.26 +	/**
    3.27 +	 * My additions in order to avoid the expensive initialization queries
    3.28 +	 */
    3.29 +	private int[] subjAggregates;
    3.30 +	private int[] objAggregates;
    3.31 +
    3.32  	public TripleTable(RdbmsTable table) {
    3.33  		this.table = table;
    3.34  	}
    3.35 @@ -74,8 +88,8 @@
    3.36  	}
    3.37  
    3.38  	public synchronized void initTable()
    3.39 -		throws SQLException
    3.40 -	{
    3.41 +			throws SQLException
    3.42 +			{
    3.43  		if (initialize)
    3.44  			return;
    3.45  		table.createTransactionalTable(buildTableColumns());
    3.46 @@ -95,62 +109,241 @@
    3.47  			createIndex();
    3.48  		}
    3.49  		initialize = true;
    3.50 -	}
    3.51 +			}
    3.52  
    3.53 +	/**
    3.54 +	 *  TODO Steps:
    3.55 +	 *  
    3.56 +	 *  During 1st run, use the original code of reload enhanced only with the two additional int tables. Also 
    3.57 +	 *  use the altered form of close()
    3.58 +	 *  
    3.59 +	 *  2nd run: replace reload() code and keep original close()
    3.60 +	 */
    3.61 +
    3.62 +	//Original
    3.63 +	//	public void reload()
    3.64 +	//	throws SQLException
    3.65 +	//	{
    3.66 +	//		table.count();
    3.67 +	//		if (table.size() > 0) {
    3.68 +	//			//XXX uncomment during 1st run!! --> Original code
    3.69 +	//			ValueType[] values = ValueType.values();
    3.70 +	//			String[] OBJ_CONTAINS = new String[values.length];
    3.71 +	//			String[] SUBJ_CONTAINS = new String[values.length];
    3.72 +	//			StringBuilder sb = new StringBuilder();
    3.73 +	//			for (int i = 0, n = values.length; i < n; i++) {
    3.74 +	//				sb.delete(0, sb.length());
    3.75 +	//				ValueType code = values[i];
    3.76 +	//				sb.append("MAX(CASE WHEN obj BETWEEN ").append(ids.minId(code));
    3.77 +	//				sb.append(" AND ").append(ids.maxId(code));
    3.78 +	//				sb.append(" THEN 1 ELSE 0 END)");
    3.79 +	//				OBJ_CONTAINS[i] = sb.toString();
    3.80 +	//				sb.delete(0, sb.length());
    3.81 +	//				sb.append("MAX(CASE WHEN subj BETWEEN ").append(ids.minId(code));
    3.82 +	//				sb.append(" AND ").append(ids.maxId(code));
    3.83 +	//				sb.append(" THEN 1 ELSE 0 END)");
    3.84 +	//				SUBJ_CONTAINS[i] = sb.toString();
    3.85 +	//			}
    3.86 +	//			int[] aggregate = table.aggregate(OBJ_CONTAINS);
    3.87 +	//			//XXX mine
    3.88 +	//			objAggregates = aggregate;
    3.89 +	//			//
    3.90 +	//			for (int i = 0; i < aggregate.length; i++) {
    3.91 +	//				if (aggregate[i] == 1) {
    3.92 +	//					objTypes.add(values[i]);
    3.93 +	//				}
    3.94 +	//			}
    3.95 +	//			aggregate = table.aggregate(SUBJ_CONTAINS);
    3.96 +	//			//XXX mine
    3.97 +	//			subjAggregates = aggregate;
    3.98 +	//			//
    3.99 +	//			for (int i = 0; i < aggregate.length; i++) {
   3.100 +	//				if (aggregate[i] == 1) {
   3.101 +	//					subjTypes.add(values[i]);
   3.102 +	//				}
   3.103 +	//			}
   3.104 +	//		}
   3.105 +	//		initialize = true;
   3.106 +	//	}
   3.107 +
   3.108 +
   3.109 +	//2nd version of reload
   3.110  	public void reload()
   3.111 -		throws SQLException
   3.112 -	{
   3.113 -		table.count();
   3.114 -		if (table.size() > 0) {
   3.115 -			ValueType[] values = ValueType.values();
   3.116 -			String[] OBJ_CONTAINS = new String[values.length];
   3.117 -			String[] SUBJ_CONTAINS = new String[values.length];
   3.118 -			StringBuilder sb = new StringBuilder();
   3.119 -			for (int i = 0, n = values.length; i < n; i++) {
   3.120 -				sb.delete(0, sb.length());
   3.121 -				ValueType code = values[i];
   3.122 -				sb.append("MAX(CASE WHEN obj BETWEEN ").append(ids.minId(code));
   3.123 -				sb.append(" AND ").append(ids.maxId(code));
   3.124 -				sb.append(" THEN 1 ELSE 0 END)");
   3.125 -				OBJ_CONTAINS[i] = sb.toString();
   3.126 -				sb.delete(0, sb.length());
   3.127 -				sb.append("MAX(CASE WHEN subj BETWEEN ").append(ids.minId(code));
   3.128 -				sb.append(" AND ").append(ids.maxId(code));
   3.129 -				sb.append(" THEN 1 ELSE 0 END)");
   3.130 -				SUBJ_CONTAINS[i] = sb.toString();
   3.131 -			}
   3.132 -			int[] aggregate = table.aggregate(OBJ_CONTAINS);
   3.133 -			for (int i = 0; i < aggregate.length; i++) {
   3.134 -				if (aggregate[i] == 1) {
   3.135 -					objTypes.add(values[i]);
   3.136 +			throws SQLException
   3.137 +			{
   3.138 +		//File existing = new File(StrabonPolyhedron.CACHEPATH+"initialized.bin");
   3.139 +		File file = new File(StrabonPolyhedron.CACHEPATH+"tableProperties/"+this.getName());
   3.140 +		//if(!existing.exists())
   3.141 +		if(!file.exists())
   3.142 +		{			
   3.143 +			long start = System.nanoTime();
   3.144 +			table.count();
   3.145 +			if (table.size() > 0) {
   3.146 +
   3.147 +				ValueType[] values = ValueType.values();
   3.148 +				String[] OBJ_CONTAINS = new String[values.length];
   3.149 +				String[] SUBJ_CONTAINS = new String[values.length];
   3.150 +				StringBuilder sb = new StringBuilder();
   3.151 +				for (int i = 0, n = values.length; i < n; i++) {
   3.152 +					sb.delete(0, sb.length());
   3.153 +					ValueType code = values[i];
   3.154 +					sb.append("MAX(CASE WHEN obj BETWEEN ").append(ids.minId(code));
   3.155 +					sb.append(" AND ").append(ids.maxId(code));
   3.156 +					sb.append(" THEN 1 ELSE 0 END)");
   3.157 +					OBJ_CONTAINS[i] = sb.toString();
   3.158 +					sb.delete(0, sb.length());
   3.159 +					sb.append("MAX(CASE WHEN subj BETWEEN ").append(ids.minId(code));
   3.160 +					sb.append(" AND ").append(ids.maxId(code));
   3.161 +					sb.append(" THEN 1 ELSE 0 END)");
   3.162 +					SUBJ_CONTAINS[i] = sb.toString();
   3.163 +				}
   3.164 +				int[] aggregate = table.aggregate(OBJ_CONTAINS);
   3.165 +
   3.166 +				objAggregates = aggregate;
   3.167 +
   3.168 +				for (int i = 0; i < aggregate.length; i++) {
   3.169 +					if (aggregate[i] == 1) {
   3.170 +						objTypes.add(values[i]);
   3.171 +					}
   3.172 +				}
   3.173 +				aggregate = table.aggregate(SUBJ_CONTAINS);
   3.174 +
   3.175 +				subjAggregates = aggregate;
   3.176 +
   3.177 +				for (int i = 0; i < aggregate.length; i++) {
   3.178 +					if (aggregate[i] == 1) {
   3.179 +						subjTypes.add(values[i]);
   3.180 +					}
   3.181  				}
   3.182  			}
   3.183 -			aggregate = table.aggregate(SUBJ_CONTAINS);
   3.184 -			for (int i = 0; i < aggregate.length; i++) {
   3.185 -				if (aggregate[i] == 1) {
   3.186 -					subjTypes.add(values[i]);
   3.187 +			initialize = true;
   3.188 +			//System.out.println("["+this.getName()+"] Cache TRIPLETABLE file not found. Initialization took "+(System.nanoTime()-start)+" nanoseconds.");
   3.189 +		}
   3.190 +		else
   3.191 +		{
   3.192 +			long start = System.nanoTime();
   3.193 +			//System.out.println("Everything is cached");
   3.194 +			table.count();
   3.195 +			if (table.size() > 0) {
   3.196 +
   3.197 +
   3.198 +				try {
   3.199 +					ValueType[] values = ValueType.values();
   3.200 +					//KKFileInputStream fstream = new FileInputStream(new File(StrabonPolyhedron.TABLE_SUBJ_OBJ_TYPES));
   3.201 +					FileInputStream fstream = new FileInputStream(file);
   3.202 +					DataInputStream dis = new DataInputStream(fstream);
   3.203 +					//KKboolean foundName = false;
   3.204 +					//KKwhile(!foundName)
   3.205 +					//KK{
   3.206 +					//KKString potentialName = dis.readUTF();
   3.207 +					//KKif(table.getName().equals(potentialName))//found table name
   3.208 +					//KK{
   3.209 +					//KK	foundName = true;
   3.210 +					int[] aggregate = new int[16];
   3.211 +					for(int i=0;i<16;i++)
   3.212 +					{
   3.213 +						aggregate[i] = dis.readInt();
   3.214 +						if (aggregate[i] == 1) {
   3.215 +							subjTypes.add(values[i]);
   3.216 +
   3.217 +						}
   3.218 +					}
   3.219 +
   3.220 +					for(int i=0;i<16;i++)
   3.221 +					{
   3.222 +						aggregate[i] = dis.readInt();
   3.223 +						if (aggregate[i] == 1) {
   3.224 +							objTypes.add(values[i]);
   3.225 +
   3.226 +						}
   3.227 +					}
   3.228 +
   3.229 +					dis.close();
   3.230 +					//KK}
   3.231 +				//KKelse //skip line
   3.232 +					//KK{
   3.233 +					//KKwhile(dis.readChar()!='\n')
   3.234 +					//KK{
   3.235 +					//KK//just loop till you find next line
   3.236 +					//KK}
   3.237 +					//KK}}
   3.238 +					//KK}
   3.239 +				} catch (FileNotFoundException e) {
   3.240 +
   3.241 +					e.printStackTrace();
   3.242 +				} catch (IOException e) {
   3.243 +
   3.244 +					e.printStackTrace();
   3.245  				}
   3.246 +
   3.247 +			}
   3.248 +			initialize = true;
   3.249 +			//System.out.println("["+this.getName()+"] Cache TRIPLETABLE file found. Initialization took "+(System.nanoTime()-start)+" nanoseconds.");
   3.250 +		}
   3.251  			}
   3.252  
   3.253 +	public void close()
   3.254 +			throws SQLException
   3.255 +			{
   3.256 +		//XXX uncomment during 1st run in order to fill properties file
   3.257 +		//KKFile output = new File(StrabonPolyhedron.TABLE_SUBJ_OBJ_TYPES);
   3.258 +		File output = new File(StrabonPolyhedron.CACHEPATH+"tableProperties/"+this.getName());
   3.259 +		//File existing = new File(StrabonPolyhedron.CACHEPATH+"initialized.bin");
   3.260 +		if(!output.exists()&&subjAggregates!=null)
   3.261 +		{
   3.262 +			System.out.println("["+this.getName()+"] Cache TRIPLETABLE file not found. Storing cache details...");
   3.263 +			FileOutputStream fstream = null;
   3.264 +			DataOutputStream dos = null;
   3.265 +			try {
   3.266 +				//KKfstream = new FileOutputStream(output,true);
   3.267 +				fstream = new FileOutputStream(output,false);
   3.268 +
   3.269 +				dos = new DataOutputStream(fstream);
   3.270 +
   3.271 +				//KKdos.writeUTF(table.getName());
   3.272 +				//dos.writeChar(';');
   3.273 +				for(int ii=0;ii<subjAggregates.length;ii++)
   3.274 +				{
   3.275 +					dos.writeInt(subjAggregates[ii]);
   3.276 +				}
   3.277 +
   3.278 +				//dos.writeChar(';');
   3.279 +				for(int ii=0;ii<objAggregates.length;ii++)
   3.280 +				{
   3.281 +					dos.writeInt(objAggregates[ii]);
   3.282 +				}
   3.283 +
   3.284 +				//KKdos.writeChar('\n');
   3.285 +				dos.close();
   3.286 +
   3.287 +			} catch (IOException e) {
   3.288 +
   3.289 +				e.printStackTrace();
   3.290 +			}
   3.291  		}
   3.292 -		initialize = true;
   3.293 -	}
   3.294  
   3.295 -	public void close()
   3.296 -		throws SQLException
   3.297 -	{
   3.298 +
   3.299 +
   3.300  		table.close();
   3.301 -	}
   3.302 +			}
   3.303 +
   3.304 +
   3.305 +	//	//Original close
   3.306 +	//	public void close()
   3.307 +	//		throws SQLException
   3.308 +	//	{
   3.309 +	//		table.close();
   3.310 +	//	}
   3.311  
   3.312  	public boolean isIndexed()
   3.313 -		throws SQLException
   3.314 -	{
   3.315 +			throws SQLException
   3.316 +			{
   3.317  		return table.getIndexes().size() > 1;
   3.318 -	}
   3.319 +			}
   3.320  
   3.321  	public void createIndex()
   3.322 -		throws SQLException
   3.323 -	{
   3.324 +			throws SQLException
   3.325 +			{
   3.326  		if (isPredColumnPresent()) {
   3.327  			table.index(PRED_INDEX);
   3.328  			total_st++;
   3.329 @@ -161,42 +354,42 @@
   3.330  		total_st++;
   3.331  		table.index(EXPL_INDEX);
   3.332  		total_st++;
   3.333 -	}
   3.334 +			}
   3.335  
   3.336  	public void dropIndex()
   3.337 -		throws SQLException
   3.338 -	{
   3.339 +			throws SQLException
   3.340 +			{
   3.341  		for (Map.Entry<String, List<String>> e : table.getIndexes().entrySet()) {
   3.342  			if (!e.getValue().contains("OBJ") && !e.getValue().contains("obj")) {
   3.343  				table.dropIndex(e.getKey());
   3.344  			}
   3.345  		}
   3.346 -	}
   3.347 +			}
   3.348  
   3.349  	public boolean isReady() {
   3.350  		return initialize;
   3.351  	}
   3.352  
   3.353  	public void blockUntilReady()
   3.354 -		throws SQLException
   3.355 -	{
   3.356 +			throws SQLException
   3.357 +			{
   3.358  		if (initialize)
   3.359  			return;
   3.360  		initTable();
   3.361 -	}
   3.362 +			}
   3.363  
   3.364  	public String getName()
   3.365 -		throws SQLException
   3.366 -	{
   3.367 +			throws SQLException
   3.368 +			{
   3.369  		return table.getName();
   3.370 -	}
   3.371 +			}
   3.372  
   3.373  	public String getNameWhenReady()
   3.374 -		throws SQLException
   3.375 -	{
   3.376 +			throws SQLException
   3.377 +			{
   3.378  		blockUntilReady();
   3.379  		return table.getName();
   3.380 -	}
   3.381 +			}
   3.382  
   3.383  	public ValueTypes getObjTypes() {
   3.384  		return objTypes;
   3.385 @@ -215,8 +408,8 @@
   3.386  	}
   3.387  
   3.388  	public void modified(int addedCount, int removedCount)
   3.389 -		throws SQLException
   3.390 -	{
   3.391 +			throws SQLException
   3.392 +			{
   3.393  		blockUntilReady();
   3.394  		table.modified(addedCount, removedCount);
   3.395  		table.optimize();
   3.396 @@ -224,14 +417,14 @@
   3.397  			objTypes.reset();
   3.398  			subjTypes.reset();
   3.399  		}
   3.400 -	}
   3.401 +			}
   3.402  
   3.403  	public boolean isEmpty()
   3.404 -		throws SQLException
   3.405 -	{
   3.406 +			throws SQLException
   3.407 +			{
   3.408  		blockUntilReady();
   3.409  		return table.size() == 0;
   3.410 -	}
   3.411 +			}
   3.412  
   3.413  	@Override
   3.414  	public String toString() {
   3.415 @@ -239,11 +432,11 @@
   3.416  	}
   3.417  
   3.418  	public void drop()
   3.419 -		throws SQLException
   3.420 -	{
   3.421 +			throws SQLException
   3.422 +			{
   3.423  		blockUntilReady();
   3.424  		table.drop();
   3.425 -	}
   3.426 +			}
   3.427  
   3.428  	protected CharSequence buildTableColumns() {
   3.429  		StringBuilder sb = new StringBuilder();
     4.1 --- a/generaldb/src/main/java/org/openrdf/sail/generaldb/schema/ValueTable.java	Wed May 23 21:42:05 2012 +0300
     4.2 +++ b/generaldb/src/main/java/org/openrdf/sail/generaldb/schema/ValueTable.java	Thu May 24 13:58:55 2012 +0300
     4.3 @@ -5,6 +5,14 @@
     4.4   */
     4.5  package org.openrdf.sail.generaldb.schema;
     4.6  
     4.7 +import java.io.DataInputStream;
     4.8 +import java.io.DataOutputStream;
     4.9 +import java.io.EOFException;
    4.10 +import java.io.File;
    4.11 +import java.io.FileInputStream;
    4.12 +import java.io.FileNotFoundException;
    4.13 +import java.io.FileOutputStream;
    4.14 +import java.io.IOException;
    4.15  import java.sql.PreparedStatement;
    4.16  import java.sql.ResultSet;
    4.17  import java.sql.SQLException;
    4.18 @@ -13,6 +21,7 @@
    4.19  import java.util.List;
    4.20  import java.util.concurrent.BlockingQueue;
    4.21  
    4.22 +import org.openrdf.query.algebra.evaluation.function.spatial.StrabonPolyhedron;
    4.23  import org.openrdf.sail.generaldb.GeneralDBSqlTable;
    4.24  import org.openrdf.sail.rdbms.schema.RdbmsTable;
    4.25  
    4.26 @@ -58,6 +67,11 @@
    4.27  
    4.28  	private PreparedStatement insertSelect;
    4.29  
    4.30 +	//XXX addition in order to avoid costly select - hack
    4.31 +	private List<Long> maxIds = new ArrayList<Long>();
    4.32 +	private boolean isHashTable = false;
    4.33 +	////
    4.34 +
    4.35  	public void setQueue(BlockingQueue<Batch> queue) {
    4.36  		this.queue = queue;
    4.37  	}
    4.38 @@ -123,12 +137,12 @@
    4.39  	}
    4.40  
    4.41  	public void initialize()
    4.42 -		throws SQLException
    4.43 -	{
    4.44 +			throws SQLException
    4.45 +			{
    4.46  		StringBuilder sb = new StringBuilder();
    4.47  		/****************/
    4.48 -//		sb.append("INSERT INTO ").append(getInsertTable().getName());
    4.49 -//		sb.append(" (id, value) VALUES (?, ?)");
    4.50 +		//		sb.append("INSERT INTO ").append(getInsertTable().getName());
    4.51 +		//		sb.append(" (id, value) VALUES (?, ?)");
    4.52  		sb.append("INSERT INTO ").append(getInsertTable().getName());
    4.53  		GeneralDBSqlTable table = (GeneralDBSqlTable)getInsertTable();
    4.54  		sb.append(table.buildInsertValue(sql(sqlType, length)));
    4.55 @@ -160,11 +174,46 @@
    4.56  		if (temporary != null && !temporary.isCreated()) {
    4.57  			createTemporaryTable(temporary);
    4.58  		}
    4.59 -	}
    4.60 +			}
    4.61  
    4.62  	public void close()
    4.63 -		throws SQLException
    4.64 -	{
    4.65 +			throws SQLException
    4.66 +			{
    4.67 +		//XXX uncomment during 1st run in order to fill properties file
    4.68 +		//File will only have one line
    4.69 +
    4.70 +		File output = new File(StrabonPolyhedron.TABLE_SHIFTING);
    4.71 +		File existing = new File(StrabonPolyhedron.CACHEPATH+"initialized.bin");
    4.72 +		if((!existing.exists()) || (!output.exists()))
    4.73 +		{			
    4.74 +			if(isHashTable)
    4.75 +			{
    4.76 +				System.out.println("["+this.getName()+"] Cache VALUETABLE file not found. Storing cache details...");
    4.77 +
    4.78 +				FileOutputStream fstream = null;
    4.79 +				DataOutputStream dos = null;
    4.80 +				try {
    4.81 +					fstream = new FileOutputStream(output,true);
    4.82 +
    4.83 +					dos = new DataOutputStream(fstream);
    4.84 +
    4.85 +					//dos.writeUTF(table.getName());
    4.86 +
    4.87 +					for(Long tmp : maxIds)
    4.88 +					{
    4.89 +						dos.writeLong(tmp);
    4.90 +					}
    4.91 +
    4.92 +					//dos.writeChar('\n');
    4.93 +					dos.close();
    4.94 +				} catch (IOException e) {
    4.95 +
    4.96 +					e.printStackTrace();
    4.97 +				}
    4.98 +			}
    4.99 +		}
   4.100 +		//end of addition
   4.101 +
   4.102  		if (insertSelect != null) {
   4.103  			insertSelect.close();
   4.104  		}
   4.105 @@ -172,11 +221,11 @@
   4.106  			temporary.close();
   4.107  		}
   4.108  		table.close();
   4.109 -	}
   4.110 +			}
   4.111  
   4.112  	public synchronized void insert(Number id, String value)
   4.113 -		throws SQLException, InterruptedException
   4.114 -	{
   4.115 +			throws SQLException, InterruptedException
   4.116 +			{
   4.117  		ValueBatch batch = getValueBatch();
   4.118  		if (isExpired(batch)) {
   4.119  			batch = newValueBatch();
   4.120 @@ -186,11 +235,11 @@
   4.121  		batch.setString(2, value);
   4.122  		batch.addBatch();
   4.123  		queue(batch);
   4.124 -	}
   4.125 +			}
   4.126  
   4.127  	public synchronized void insert(Number id, Number value)
   4.128 -		throws SQLException, InterruptedException
   4.129 -	{
   4.130 +			throws SQLException, InterruptedException
   4.131 +			{
   4.132  		ValueBatch batch = getValueBatch();
   4.133  		if (isExpired(batch)) {
   4.134  			batch = newValueBatch();
   4.135 @@ -200,7 +249,7 @@
   4.136  		batch.setObject(2, value);
   4.137  		batch.addBatch();
   4.138  		queue(batch);
   4.139 -	}
   4.140 +			}
   4.141  
   4.142  	public ValueBatch getValueBatch() {
   4.143  		return this.batch;
   4.144 @@ -217,8 +266,8 @@
   4.145  	}
   4.146  
   4.147  	public void initBatch(ValueBatch batch)
   4.148 -		throws SQLException
   4.149 -	{
   4.150 +			throws SQLException
   4.151 +			{
   4.152  		batch.setTable(table);
   4.153  		batch.setBatchStatement(prepareInsert(INSERT));
   4.154  		batch.setMaxBatchSize(getBatchSize());
   4.155 @@ -229,11 +278,11 @@
   4.156  			}
   4.157  			batch.setInsertStatement(insertSelect);
   4.158  		}
   4.159 -	}
   4.160 +			}
   4.161  
   4.162  	public void queue(ValueBatch batch)
   4.163 -		throws SQLException, InterruptedException
   4.164 -	{
   4.165 +			throws SQLException, InterruptedException
   4.166 +			{
   4.167  		this.batch = batch;
   4.168  		if (queue == null) {
   4.169  			batch.flush();
   4.170 @@ -241,17 +290,17 @@
   4.171  		else {
   4.172  			queue.put(batch);
   4.173  		}
   4.174 -	}
   4.175 +			}
   4.176  
   4.177  	public void optimize()
   4.178 -		throws SQLException
   4.179 -	{
   4.180 +			throws SQLException
   4.181 +			{
   4.182  		table.optimize();
   4.183 -	}
   4.184 +			}
   4.185  
   4.186  	public boolean expunge(String condition)
   4.187 -		throws SQLException
   4.188 -	{
   4.189 +			throws SQLException
   4.190 +			{
   4.191  		synchronized (table) {
   4.192  			int count = table.executeUpdate(EXPUNGE + condition);
   4.193  			if (count < 1)
   4.194 @@ -259,73 +308,117 @@
   4.195  			table.modified(0, count);
   4.196  			return true;
   4.197  		}
   4.198 -	}
   4.199 +			}
   4.200  
   4.201  	public List<Long> maxIds(int shift, int mod)
   4.202 -		throws SQLException
   4.203 -	{
   4.204 -		String column = "id";
   4.205 -		StringBuilder expr = new StringBuilder();
   4.206 -		expr.append("MOD((").append(column);
   4.207 -		expr.append(" >> ").append(shift);
   4.208 -		expr.append(") + ").append(mod).append(", ");
   4.209 -		expr.append(mod);
   4.210 -		expr.append(")");
   4.211 -		StringBuilder sb = new StringBuilder();
   4.212 -		sb.append("SELECT ");
   4.213 -		sb.append("MAX(");
   4.214 -		sb.append(column);
   4.215 -		sb.append("), ").append(expr).append(" AS grp");
   4.216 -		sb.append("\nFROM ").append(getName());
   4.217 -		sb.append("\nGROUP BY grp");
   4.218 -		String query = sb.toString();
   4.219 -		PreparedStatement st = table.prepareStatement(query);
   4.220 -		try {
   4.221 -			ResultSet rs = st.executeQuery();
   4.222 +			throws SQLException
   4.223 +			{
   4.224 +
   4.225 +		File existing = new File(StrabonPolyhedron.CACHEPATH+"initialized.bin");
   4.226 +		if(!existing.exists())
   4.227 +		{
   4.228 +			String column = "id";
   4.229 +			StringBuilder expr = new StringBuilder();
   4.230 +			expr.append("MOD((").append(column);
   4.231 +			expr.append(" >> ").append(shift);
   4.232 +			expr.append(") + ").append(mod).append(", ");
   4.233 +			expr.append(mod);
   4.234 +			expr.append(")");
   4.235 +			StringBuilder sb = new StringBuilder();
   4.236 +			sb.append("SELECT ");
   4.237 +			sb.append("MAX(");
   4.238 +			sb.append(column);
   4.239 +			sb.append("), ").append(expr).append(" AS grp");
   4.240 +			sb.append("\nFROM ").append(getName());
   4.241 +			sb.append("\nGROUP BY grp");
   4.242 +			String query = sb.toString();
   4.243 +			PreparedStatement st = table.prepareStatement(query);
   4.244  			try {
   4.245 -				List<Long> result = new ArrayList<Long>();
   4.246 -				while (rs.next()) {
   4.247 -					result.add(rs.getLong(1));
   4.248 +				ResultSet rs = st.executeQuery();
   4.249 +				try {
   4.250 +					List<Long> result = new ArrayList<Long>();
   4.251 +					while (rs.next()) {
   4.252 +						result.add(rs.getLong(1));
   4.253 +					}
   4.254 +
   4.255 +					//XXX addition --> will use in close()
   4.256 +					maxIds.addAll(result);
   4.257 +					isHashTable = true;
   4.258 +
   4.259 +					return result;
   4.260  				}
   4.261 -				return result;
   4.262 +
   4.263 +				finally {
   4.264 +					rs.close();
   4.265 +				}
   4.266  			}
   4.267  			finally {
   4.268 -				rs.close();
   4.269 +				st.close();
   4.270  			}
   4.271  		}
   4.272 -		finally {
   4.273 -			st.close();
   4.274 +		else
   4.275 +		{
   4.276 +			long start = System.nanoTime();
   4.277 +			try 
   4.278 +			{
   4.279 +				FileInputStream fstream = new FileInputStream(new File(StrabonPolyhedron.TABLE_SHIFTING));
   4.280 +				DataInputStream dis = new DataInputStream(fstream);
   4.281 +
   4.282 +
   4.283 +				while(true)
   4.284 +				{
   4.285 +					try
   4.286 +					{
   4.287 +						long read = dis.readLong();
   4.288 +						maxIds.add(read);
   4.289 +					}
   4.290 +					catch(EOFException e)
   4.291 +					{
   4.292 +						break;
   4.293 +					}
   4.294 +				}
   4.295 +
   4.296 +
   4.297 +			} catch (FileNotFoundException e) {
   4.298 +
   4.299 +				e.printStackTrace();
   4.300 +			} catch (IOException e) {
   4.301 +
   4.302 +				e.printStackTrace();
   4.303 +			}
   4.304 +			//System.out.println("["+this.getName()+"] Cache VALUETABLE file found. Initialization took "+(System.nanoTime()-start)+" nanoseconds.");
   4.305 +			return maxIds;
   4.306  		}
   4.307 -	}
   4.308 +			}
   4.309  
   4.310  	public String sql(int type, int length) {
   4.311  		switch (type) {
   4.312 -			case Types.VARCHAR:
   4.313 -				if (length > 0)
   4.314 -					return "VARCHAR(" + length + ")";
   4.315 -				return "TEXT";
   4.316 -			case Types.LONGVARCHAR:
   4.317 -				if (length > 0)
   4.318 -					return "LONGVARCHAR(" + length + ")";
   4.319 -				return "TEXT";
   4.320 -			case Types.BIGINT:
   4.321 -				return "BIGINT";
   4.322 -			case Types.INTEGER:
   4.323 -				return "INTEGER";
   4.324 -			case Types.SMALLINT:
   4.325 -				return "SMALLINT";
   4.326 -			case Types.FLOAT:
   4.327 -				return "FLOAT";
   4.328 -			case Types.DOUBLE:
   4.329 -				return "DOUBLE";
   4.330 -			case Types.DECIMAL:
   4.331 -				return "DECIMAL";
   4.332 -			case Types.BOOLEAN:
   4.333 -				return "BOOLEAN";
   4.334 -			case Types.TIMESTAMP:
   4.335 -				return "TIMESTAMP";
   4.336 -			default:
   4.337 -				throw new AssertionError("Unsupported SQL Type: " + type);
   4.338 +		case Types.VARCHAR:
   4.339 +			if (length > 0)
   4.340 +				return "VARCHAR(" + length + ")";
   4.341 +			return "TEXT";
   4.342 +		case Types.LONGVARCHAR:
   4.343 +			if (length > 0)
   4.344 +				return "LONGVARCHAR(" + length + ")";
   4.345 +			return "TEXT";
   4.346 +		case Types.BIGINT:
   4.347 +			return "BIGINT";
   4.348 +		case Types.INTEGER:
   4.349 +			return "INTEGER";
   4.350 +		case Types.SMALLINT:
   4.351 +			return "SMALLINT";
   4.352 +		case Types.FLOAT:
   4.353 +			return "FLOAT";
   4.354 +		case Types.DOUBLE:
   4.355 +			return "DOUBLE";
   4.356 +		case Types.DECIMAL:
   4.357 +			return "DECIMAL";
   4.358 +		case Types.BOOLEAN:
   4.359 +			return "BOOLEAN";
   4.360 +		case Types.TIMESTAMP:
   4.361 +			return "TIMESTAMP";
   4.362 +		default:
   4.363 +			throw new AssertionError("Unsupported SQL Type: " + type);
   4.364  		}
   4.365  	}
   4.366  
   4.367 @@ -343,34 +436,34 @@
   4.368  	}
   4.369  
   4.370  	protected PreparedStatement prepareInsert(String sql)
   4.371 -		throws SQLException
   4.372 -	{
   4.373 +			throws SQLException
   4.374 +			{
   4.375  		return table.prepareStatement(sql);
   4.376 -	}
   4.377 +			}
   4.378  
   4.379  	protected PreparedStatement prepareInsertSelect(String sql)
   4.380 -		throws SQLException
   4.381 -	{
   4.382 +			throws SQLException
   4.383 +			{
   4.384  		return table.prepareStatement(sql);
   4.385 -	}
   4.386 +			}
   4.387  
   4.388  	protected void createTable(RdbmsTable table)
   4.389 -		throws SQLException
   4.390 -	{
   4.391 +			throws SQLException
   4.392 +			{
   4.393  		StringBuilder sb = new StringBuilder();
   4.394  		sb.append("  id ").append(sql(idType, -1)).append(" NOT NULL,\n");
   4.395  		sb.append("  value ").append(sql(sqlType, length));
   4.396  		sb.append(" NOT NULL\n");
   4.397  		table.createTable(sb);
   4.398 -	}
   4.399 +			}
   4.400  
   4.401  	protected void createTemporaryTable(RdbmsTable table)
   4.402 -		throws SQLException
   4.403 -	{
   4.404 +			throws SQLException
   4.405 +			{
   4.406  		StringBuilder sb = new StringBuilder();
   4.407  		sb.append("  id ").append(sql(idType, -1)).append(" NOT NULL,\n");
   4.408  		sb.append("  value ").append(sql(sqlType, length));
   4.409  		sb.append(" NOT NULL\n");
   4.410  		table.createTemporaryTable(sb);
   4.411 -	}
   4.412 +			}
   4.413  }
     5.1 --- a/monetdb/pom.xml	Wed May 23 21:42:05 2012 +0300
     5.2 +++ b/monetdb/pom.xml	Thu May 24 13:58:55 2012 +0300
     5.3 @@ -28,7 +28,7 @@
     5.4  		</dependency>
     5.5  		<dependency>
     5.6  			<groupId>org.openrdf.sesame</groupId>
     5.7 -			<artifactId>sesame-sail-rdbms</artifactId>
     5.8 +			<artifactId>sesame-sail-rdbms-caches</artifactId>
     5.9  		</dependency>
    5.10  		<dependency>
    5.11  			<groupId>org.openrdf.sesame</groupId>
     6.1 --- a/pom.xml	Wed May 23 21:42:05 2012 +0300
     6.2 +++ b/pom.xml	Thu May 24 13:58:55 2012 +0300
     6.3 @@ -26,6 +26,7 @@
     6.4  		<module>generaldb</module>
     6.5  		<module>resultio</module>
     6.6  		<module>endpoint</module>
     6.7 +		<module>rdbms</module>
     6.8  	</modules>
     6.9  
    6.10  	<properties>
    6.11 @@ -45,6 +46,13 @@
    6.12  	<dependencyManagement>
    6.13  		<dependencies>
    6.14  			<!-- Strabon dependencies -->
    6.15 +			
    6.16 +			<dependency>
    6.17 +				<groupId>org.openrdf.sesame</groupId>
    6.18 +				<artifactId>sesame-sail-rdbms-caches</artifactId>
    6.19 +				<version>${eu.earthobservatory.version}</version>
    6.20 +			</dependency>
    6.21 +			
    6.22  			<dependency>
    6.23  				<groupId>org.openrdf.sesame</groupId>
    6.24  				<artifactId>sesame-queryalgebra-evaluation-spatial</artifactId>
    6.25 @@ -150,12 +158,6 @@
    6.26  
    6.27  			<dependency>
    6.28  				<groupId>org.openrdf.sesame</groupId>
    6.29 -				<artifactId>sesame-sail-rdbms</artifactId>
    6.30 -				<version>${sesame.version}</version>
    6.31 -			</dependency>
    6.32 -
    6.33 -			<dependency>
    6.34 -				<groupId>org.openrdf.sesame</groupId>
    6.35  				<artifactId>sesame-repository-sparql</artifactId>
    6.36  				<version>${sesame.version}</version>
    6.37  			</dependency>
     7.1 --- a/postgis/pom.xml	Wed May 23 21:42:05 2012 +0300
     7.2 +++ b/postgis/pom.xml	Thu May 24 13:58:55 2012 +0300
     7.3 @@ -28,7 +28,7 @@
     7.4  		</dependency>
     7.5  		<dependency>
     7.6  			<groupId>org.openrdf.sesame</groupId>
     7.7 -			<artifactId>sesame-sail-rdbms</artifactId>
     7.8 +			<artifactId>sesame-sail-rdbms-caches</artifactId>
     7.9  		</dependency>
    7.10  		<dependency>
    7.11  			<groupId>org.openrdf.sesame</groupId>
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/rdbms/pom.xml	Thu May 24 13:58:55 2012 +0300
     8.3 @@ -0,0 +1,66 @@
     8.4 +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     8.5 +  <modelVersion>4.0.0</modelVersion>
     8.6 +  <parent>
     8.7 +    <artifactId>strabon</artifactId>
     8.8 +    <groupId>eu.earthobservatory</groupId>
     8.9 +    <version>3.1.10-SNAPSHOT</version>
    8.10 +    <relativePath>..</relativePath>
    8.11 +  </parent>
    8.12 +  <groupId>org.openrdf.sesame</groupId>
    8.13 +  <artifactId>sesame-sail-rdbms-caches</artifactId>
    8.14 +  <name>Open RDF Sesame: RDBMS Sail Extension</name>
    8.15 +  <description>RDBMS Sail Extension accommodating our needs for caches</description>
    8.16 +  <packaging>jar</packaging>
    8.17 +  
    8.18 +  <dependencies>
    8.19 +		<dependency>
    8.20 +			<groupId>org.openrdf.sesame</groupId>
    8.21 +			<artifactId>sesame-sail-api</artifactId>
    8.22 +		</dependency>
    8.23 +
    8.24 +		<dependency>
    8.25 +			<groupId>org.openrdf.sesame</groupId>
    8.26 +			<artifactId>sesame-queryalgebra-evaluation</artifactId>
    8.27 +		</dependency>
    8.28 +		<dependency>
    8.29 +			<groupId>org.openrdf.sesame</groupId>
    8.30 +			<artifactId>sesame-queryalgebra-model</artifactId>
    8.31 +		</dependency>
    8.32 +		<dependency>
    8.33 +			<groupId>org.openrdf.sesame</groupId>
    8.34 +			<artifactId>sesame-query</artifactId>
    8.35 +		</dependency>
    8.36 +
    8.37 +		<dependency>
    8.38 +			<groupId>org.openrdf.sesame</groupId>
    8.39 +			<artifactId>sesame-model</artifactId>
    8.40 +		</dependency>
    8.41 +
    8.42 +		<dependency>
    8.43 +			<groupId>org.slf4j</groupId>
    8.44 +			<artifactId>slf4j-api</artifactId>
    8.45 +		</dependency>
    8.46 +
    8.47 +		<dependency>
    8.48 +			<groupId>commons-dbcp</groupId>
    8.49 +			<artifactId>commons-dbcp</artifactId>
    8.50 +		</dependency>
    8.51 +
    8.52 +		<dependency>
    8.53 +			<groupId>junit</groupId>
    8.54 +			<artifactId>junit</artifactId>
    8.55 +		</dependency>
    8.56 +
    8.57 +		<dependency>
    8.58 +			<groupId>postgresql</groupId>
    8.59 +			<artifactId>postgresql</artifactId>
    8.60 +			<scope>provided</scope>
    8.61 +		</dependency>
    8.62 +
    8.63 +		<dependency>
    8.64 +			<groupId>org.openrdf.sesame</groupId>
    8.65 +			<artifactId>sesame-queryalgebra-evaluation-spatial</artifactId>
    8.66 +		</dependency>
    8.67 +	</dependencies>
    8.68 +</project>
    8.69 +
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/RdbmsConnection.java	Thu May 24 13:58:55 2012 +0300
     9.3 @@ -0,0 +1,309 @@
     9.4 +/*
     9.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
     9.6 + *
     9.7 + * Licensed under the Aduna BSD-style license.
     9.8 + */
     9.9 +package org.openrdf.sail.rdbms;
    9.10 +
    9.11 +import java.sql.SQLException;
    9.12 +import java.util.Collection;
    9.13 +
    9.14 +import info.aduna.concurrent.locks.ExclusiveLockManager;
    9.15 +import info.aduna.concurrent.locks.Lock;
    9.16 +import info.aduna.iteration.CloseableIteration;
    9.17 +
    9.18 +import org.openrdf.model.Namespace;
    9.19 +import org.openrdf.model.Resource;
    9.20 +import org.openrdf.model.Statement;
    9.21 +import org.openrdf.model.URI;
    9.22 +import org.openrdf.model.Value;
    9.23 +import org.openrdf.query.BindingSet;
    9.24 +import org.openrdf.query.Dataset;
    9.25 +import org.openrdf.query.QueryEvaluationException;
    9.26 +import org.openrdf.query.algebra.TupleExpr;
    9.27 +import org.openrdf.query.algebra.evaluation.EvaluationStrategy;
    9.28 +import org.openrdf.query.impl.EmptyBindingSet;
    9.29 +import org.openrdf.sail.SailConnection;
    9.30 +import org.openrdf.sail.SailException;
    9.31 +import org.openrdf.sail.helpers.DefaultSailChangedEvent;
    9.32 +import org.openrdf.sail.helpers.SailConnectionBase;
    9.33 +import org.openrdf.sail.rdbms.evaluation.RdbmsEvaluationFactory;
    9.34 +import org.openrdf.sail.rdbms.exceptions.RdbmsException;
    9.35 +import org.openrdf.sail.rdbms.iteration.NamespaceIteration;
    9.36 +import org.openrdf.sail.rdbms.iteration.RdbmsResourceIteration;
    9.37 +import org.openrdf.sail.rdbms.managers.NamespaceManager;
    9.38 +import org.openrdf.sail.rdbms.model.RdbmsResource;
    9.39 +import org.openrdf.sail.rdbms.model.RdbmsURI;
    9.40 +import org.openrdf.sail.rdbms.model.RdbmsValue;
    9.41 +import org.openrdf.sail.rdbms.optimizers.RdbmsQueryOptimizer;
    9.42 +
    9.43 +/**
    9.44 + * Coordinates the triple store, namespace manager, optimizer, and evaluation
    9.45 + * strategy into the {@link SailConnection} interface.
    9.46 + * 
    9.47 + * @author James Leigh
    9.48 + * 
    9.49 + */
    9.50 +public class RdbmsConnection extends SailConnectionBase {
    9.51 +
    9.52 +	private RdbmsStore sail;
    9.53 +
    9.54 +	private RdbmsValueFactory vf;
    9.55 +
    9.56 +	private RdbmsTripleRepository triples;
    9.57 +
    9.58 +	private NamespaceManager namespaces;
    9.59 +
    9.60 +	private RdbmsQueryOptimizer optimizer;
    9.61 +
    9.62 +	private RdbmsEvaluationFactory factory;
    9.63 +
    9.64 +	private ExclusiveLockManager lockManager;
    9.65 +
    9.66 +	private Lock lock;
    9.67 +
    9.68 +	public RdbmsConnection(RdbmsStore sail, RdbmsTripleRepository triples) {
    9.69 +		super(sail);
    9.70 +		this.sail = sail;
    9.71 +		this.vf = sail.getValueFactory();
    9.72 +		this.triples = triples;
    9.73 +	}
    9.74 +
    9.75 +	public void setNamespaces(NamespaceManager namespaces) {
    9.76 +		this.namespaces = namespaces;
    9.77 +	}
    9.78 +
    9.79 +	public void setRdbmsQueryOptimizer(RdbmsQueryOptimizer optimizer) {
    9.80 +		this.optimizer = optimizer;
    9.81 +	}
    9.82 +
    9.83 +	public void setRdbmsEvaluationFactory(RdbmsEvaluationFactory factory) {
    9.84 +		this.factory = factory;
    9.85 +	}
    9.86 +
    9.87 +	public void setLockManager(ExclusiveLockManager lock) {
    9.88 +		this.lockManager = lock;
    9.89 +	}
    9.90 +
    9.91 +	@Override
    9.92 +	protected void addStatementInternal(Resource subj, URI pred, Value obj, Resource... contexts)
    9.93 +		throws SailException
    9.94 +	{
    9.95 +		try {
    9.96 +			if (contexts.length == 0) {
    9.97 +				triples.add(vf.createStatement(subj, pred, obj));
    9.98 +			}
    9.99 +			else {
   9.100 +				for (Resource ctx : contexts) {
   9.101 +					triples.add(vf.createStatement(subj, pred, obj, ctx));
   9.102 +				}
   9.103 +			}
   9.104 +		}
   9.105 +		catch (SQLException e) {
   9.106 +			throw new RdbmsException(e);
   9.107 +		}
   9.108 +		catch (InterruptedException e) {
   9.109 +			throw new RdbmsException(e);
   9.110 +		}
   9.111 +	}
   9.112 +
   9.113 +	@Override
   9.114 +	protected void clearInternal(Resource... contexts)
   9.115 +		throws SailException
   9.116 +	{
   9.117 +		removeStatementsInternal(null, null, null, contexts);
   9.118 +	}
   9.119 +
   9.120 +	@Override
   9.121 +	protected void closeInternal()
   9.122 +		throws SailException
   9.123 +	{
   9.124 +		try {
   9.125 +			triples.close();
   9.126 +		}
   9.127 +		catch (SQLException e) {
   9.128 +			throw new RdbmsException(e);
   9.129 +		}
   9.130 +		finally {
   9.131 +			unlock();
   9.132 +		}
   9.133 +	}
   9.134 +
   9.135 +	@Override
   9.136 +	protected void commitInternal()
   9.137 +		throws SailException
   9.138 +	{
   9.139 +		try {
   9.140 +			triples.commit();
   9.141 +			unlock();
   9.142 +		}
   9.143 +		catch (SQLException e) {
   9.144 +			throw new RdbmsException(e);
   9.145 +		}
   9.146 +		catch (InterruptedException e) {
   9.147 +			throw new RdbmsException(e);
   9.148 +		}
   9.149 +
   9.150 +		// create a fresh event object.
   9.151 +		triples.setSailChangedEvent(new DefaultSailChangedEvent(sail));
   9.152 +	}
   9.153 +
   9.154 +	@Override
   9.155 +	protected RdbmsResourceIteration getContextIDsInternal()
   9.156 +		throws SailException
   9.157 +	{
   9.158 +		try {
   9.159 +			return triples.findContexts();
   9.160 +		}
   9.161 +		catch (SQLException e) {
   9.162 +			throw new RdbmsException(e);
   9.163 +		}
   9.164 +	}
   9.165 +
   9.166 +	@Override
   9.167 +	protected CloseableIteration<? extends Statement, SailException> getStatementsInternal(Resource subj,
   9.168 +			URI pred, Value obj, boolean includeInferred, Resource... contexts)
   9.169 +		throws SailException
   9.170 +	{
   9.171 +		RdbmsResource s = vf.asRdbmsResource(subj);
   9.172 +		RdbmsURI p = vf.asRdbmsURI(pred);
   9.173 +		RdbmsValue o = vf.asRdbmsValue(obj);
   9.174 +		RdbmsResource[] c = vf.asRdbmsResource(contexts);
   9.175 +		return triples.find(s, p, o, c);
   9.176 +	}
   9.177 +
   9.178 +	@Override
   9.179 +	protected void removeStatementsInternal(Resource subj, URI pred, Value obj, Resource... contexts)
   9.180 +		throws SailException
   9.181 +	{
   9.182 +		RdbmsResource s = vf.asRdbmsResource(subj);
   9.183 +		RdbmsURI p = vf.asRdbmsURI(pred);
   9.184 +		RdbmsValue o = vf.asRdbmsValue(obj);
   9.185 +		RdbmsResource[] c = vf.asRdbmsResource(contexts);
   9.186 +		triples.remove(s, p, o, c);
   9.187 +	}
   9.188 +
   9.189 +	@Override
   9.190 +	protected void rollbackInternal()
   9.191 +		throws SailException
   9.192 +	{
   9.193 +		try {
   9.194 +			triples.rollback();
   9.195 +		}
   9.196 +		catch (SQLException e) {
   9.197 +			throw new RdbmsException(e);
   9.198 +		}
   9.199 +		finally {
   9.200 +			unlock();
   9.201 +		}
   9.202 +	}
   9.203 +
   9.204 +	@Override
   9.205 +	protected CloseableIteration<BindingSet, QueryEvaluationException> evaluateInternal(TupleExpr expr,
   9.206 +			Dataset dataset, BindingSet bindings, boolean includeInferred)
   9.207 +		throws SailException
   9.208 +	{
   9.209 +		triples.flush();
   9.210 +		try {
   9.211 +			TupleExpr tupleExpr;
   9.212 +			EvaluationStrategy strategy;
   9.213 +			strategy = factory.createRdbmsEvaluation(dataset);
   9.214 +			tupleExpr = optimizer.optimize(expr, dataset, bindings, strategy);
   9.215 +			return strategy.evaluate(tupleExpr, EmptyBindingSet.getInstance());
   9.216 +		}
   9.217 +		catch (QueryEvaluationException e) {
   9.218 +			throw new SailException(e);
   9.219 +		}
   9.220 +	}
   9.221 +
   9.222 +	@Override
   9.223 +	protected void clearNamespacesInternal()
   9.224 +		throws SailException
   9.225 +	{
   9.226 +		namespaces.clearPrefixes();
   9.227 +	}
   9.228 +
   9.229 +	@Override
   9.230 +	protected String getNamespaceInternal(String prefix)
   9.231 +		throws SailException
   9.232 +	{
   9.233 +		Namespace ns = namespaces.findByPrefix(prefix);
   9.234 +		if (ns == null)
   9.235 +			return null;
   9.236 +		return ns.getName();
   9.237 +	}
   9.238 +
   9.239 +	@Override
   9.240 +	protected CloseableIteration<? extends Namespace, SailException> getNamespacesInternal()
   9.241 +		throws SailException
   9.242 +	{
   9.243 +		Collection<? extends Namespace> ns = namespaces.getNamespacesWithPrefix();
   9.244 +		return new NamespaceIteration(ns.iterator());
   9.245 +	}
   9.246 +
   9.247 +	@Override
   9.248 +	protected void removeNamespaceInternal(String prefix)
   9.249 +		throws SailException
   9.250 +	{
   9.251 +		namespaces.removePrefix(prefix);
   9.252 +	}
   9.253 +
   9.254 +	@Override
   9.255 +	protected void setNamespaceInternal(String prefix, String name)
   9.256 +		throws SailException
   9.257 +	{
   9.258 +		namespaces.setPrefix(prefix, name);
   9.259 +	}
   9.260 +
   9.261 +	@Override
   9.262 +	protected long sizeInternal(Resource... contexts)
   9.263 +		throws SailException
   9.264 +	{
   9.265 +		try {
   9.266 +			return triples.size(vf.asRdbmsResource(contexts));
   9.267 +		}
   9.268 +		catch (SQLException e) {
   9.269 +			throw new RdbmsException(e);
   9.270 +		}
   9.271 +	}
   9.272 +
   9.273 +	@Override
   9.274 +	protected void startTransactionInternal()
   9.275 +		throws SailException
   9.276 +	{
   9.277 +		try {
   9.278 +			lock();
   9.279 +			triples.begin();
   9.280 +		}
   9.281 +		catch (SQLException e) {
   9.282 +			unlock();
   9.283 +			throw new RdbmsException(e);
   9.284 +		}
   9.285 +		catch (InterruptedException e) {
   9.286 +			unlock();
   9.287 +			throw new RdbmsException(e);
   9.288 +		}
   9.289 +	}
   9.290 +
   9.291 +	@Override
   9.292 +	protected void finalize()
   9.293 +		throws Throwable
   9.294 +	{
   9.295 +		unlock();
   9.296 +		super.finalize();
   9.297 +	}
   9.298 +
   9.299 +	private void lock() throws InterruptedException {
   9.300 +		if (lockManager != null) {
   9.301 +			lock = lockManager.getExclusiveLock();
   9.302 +		}
   9.303 +	}
   9.304 +
   9.305 +	private void unlock() {
   9.306 +		if (lockManager != null && lock != null) {
   9.307 +			lock.release();
   9.308 +			lock = null;
   9.309 +		}
   9.310 +	}
   9.311 +
   9.312 +}
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/RdbmsConnectionFactory.java	Thu May 24 13:58:55 2012 +0300
    10.3 @@ -0,0 +1,437 @@
    10.4 +/*
    10.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    10.6 + *
    10.7 + * Licensed under the Aduna BSD-style license.
    10.8 + */
    10.9 +package org.openrdf.sail.rdbms;
   10.10 +
   10.11 +import static java.sql.Connection.TRANSACTION_READ_COMMITTED;
   10.12 +
   10.13 +import java.sql.Connection;
   10.14 +import java.sql.SQLException;
   10.15 +
   10.16 +import javax.sql.DataSource;
   10.17 +
   10.18 +import info.aduna.concurrent.locks.ExclusiveLockManager;
   10.19 +import info.aduna.concurrent.locks.Lock;
   10.20 +
   10.21 +import org.openrdf.model.impl.ValueFactoryImpl;
   10.22 +import org.openrdf.sail.SailConnection;
   10.23 +import org.openrdf.sail.SailException;
   10.24 +import org.openrdf.sail.helpers.DefaultSailChangedEvent;
   10.25 +import org.openrdf.sail.rdbms.evaluation.QueryBuilderFactory;
   10.26 +import org.openrdf.sail.rdbms.evaluation.RdbmsEvaluationFactory;
   10.27 +import org.openrdf.sail.rdbms.exceptions.RdbmsException;
   10.28 +import org.openrdf.sail.rdbms.managers.BNodeManager;
   10.29 +import org.openrdf.sail.rdbms.managers.HashManager;
   10.30 +import org.openrdf.sail.rdbms.managers.LiteralManager;
   10.31 +import org.openrdf.sail.rdbms.managers.NamespaceManager;
   10.32 +import org.openrdf.sail.rdbms.managers.PredicateManager;
   10.33 +import org.openrdf.sail.rdbms.managers.TransTableManager;
   10.34 +import org.openrdf.sail.rdbms.managers.TripleManager;
   10.35 +import org.openrdf.sail.rdbms.managers.TripleTableManager;
   10.36 +import org.openrdf.sail.rdbms.managers.UriManager;
   10.37 +import org.openrdf.sail.rdbms.optimizers.RdbmsQueryOptimizer;
   10.38 +import org.openrdf.sail.rdbms.optimizers.SelectQueryOptimizerFactory;
   10.39 +import org.openrdf.sail.rdbms.schema.BNodeTable;
   10.40 +import org.openrdf.sail.rdbms.schema.HashTable;
   10.41 +import org.openrdf.sail.rdbms.schema.IdSequence;
   10.42 +import org.openrdf.sail.rdbms.schema.IntegerIdSequence;
   10.43 +import org.openrdf.sail.rdbms.schema.LiteralTable;
   10.44 +import org.openrdf.sail.rdbms.schema.LongIdSequence;
   10.45 +import org.openrdf.sail.rdbms.schema.NamespacesTable;
   10.46 +import org.openrdf.sail.rdbms.schema.TableFactory;
   10.47 +import org.openrdf.sail.rdbms.schema.URITable;
   10.48 +import org.openrdf.sail.rdbms.schema.ValueTableFactory;
   10.49 +import org.openrdf.sail.rdbms.util.DatabaseLockManager;
   10.50 +import org.openrdf.sail.rdbms.util.Tracer;
   10.51 +
   10.52 +/**
   10.53 + * Responsible to initialise and wire all components together that will be
   10.54 + * needed to satisfy any sail connection request.
   10.55 + * 
   10.56 + * @author James Leigh
   10.57 + */
   10.58 +public class RdbmsConnectionFactory {
   10.59 +
   10.60 +	private RdbmsStore sail;
   10.61 +
   10.62 +	private DataSource ds;
   10.63 +
   10.64 +	private String user;
   10.65 +
   10.66 +	private String password;
   10.67 +
   10.68 +	private Connection resourceInserts;
   10.69 +
   10.70 +	private Connection literalInserts;
   10.71 +
   10.72 +	private Connection hashLookups;
   10.73 +
   10.74 +	private Connection nsAndTableIndexes;
   10.75 +
   10.76 +	private NamespaceManager namespaces;
   10.77 +
   10.78 +	private TripleTableManager tripleTableManager;
   10.79 +
   10.80 +	private HashManager hashManager;
   10.81 +
   10.82 +	private RdbmsValueFactory vf;
   10.83 +
   10.84 +	private UriManager uriManager;
   10.85 +
   10.86 +	private BNodeManager bnodeManager;
   10.87 +
   10.88 +	private LiteralManager literalManager;
   10.89 +
   10.90 +	private PredicateManager predicateManager;
   10.91 +
   10.92 +	private int maxTripleTables;
   10.93 +
   10.94 +	private boolean triplesIndexed = true;
   10.95 +
   10.96 +	private boolean sequenced;
   10.97 +
   10.98 +	private HashTable hashTable;
   10.99 +
  10.100 +	private URITable uriTable;
  10.101 +
  10.102 +	private BNodeTable bnodeTable;
  10.103 +
  10.104 +	private LiteralTable literalTable;
  10.105 +
  10.106 +	private IdSequence ids;
  10.107 +
  10.108 +	private final ExclusiveLockManager lock = new ExclusiveLockManager();
  10.109 +
  10.110 +	private Lock databaseLock;
  10.111 +
  10.112 +	public void setSail(RdbmsStore sail) {
  10.113 +		this.sail = sail;
  10.114 +	}
  10.115 +
  10.116 +	public DataSource getDataSource() {
  10.117 +		return ds;
  10.118 +	}
  10.119 +
  10.120 +	public void setDataSource(DataSource ds) {
  10.121 +		if (Tracer.isTraceEnabled()) {
  10.122 +			this.ds = Tracer.traceDataSource(ds);
  10.123 +		}
  10.124 +		else {
  10.125 +			this.ds = ds;
  10.126 +		}
  10.127 +	}
  10.128 +
  10.129 +	public void setDataSource(DataSource ds, String user, String password) {
  10.130 +		setDataSource(ds);
  10.131 +		this.user = user;
  10.132 +		this.password = password;
  10.133 +	}
  10.134 +
  10.135 +	public int getMaxNumberOfTripleTables() {
  10.136 +		return maxTripleTables;
  10.137 +	}
  10.138 +
  10.139 +	public void setMaxNumberOfTripleTables(int max) {
  10.140 +		maxTripleTables = max;
  10.141 +	}
  10.142 +
  10.143 +	public boolean isSequenced() {
  10.144 +		return sequenced || hashManager != null;
  10.145 +	}
  10.146 +
  10.147 +	public void setSequenced(boolean useSequence) {
  10.148 +		this.sequenced = useSequence;
  10.149 +	}
  10.150 +
  10.151 +	public boolean isTriplesIndexed() {
  10.152 +		return triplesIndexed;
  10.153 +	}
  10.154 +
  10.155 +	public void setTriplesIndexed(boolean triplesIndexed)
  10.156 +		throws SailException
  10.157 +	{
  10.158 +		this.triplesIndexed = triplesIndexed;
  10.159 +		if (tripleTableManager != null) {
  10.160 +			try {
  10.161 +				if (triplesIndexed) {
  10.162 +					tripleTableManager.createTripleIndexes();
  10.163 +				}
  10.164 +				else {
  10.165 +					tripleTableManager.dropTripleIndexes();
  10.166 +				}
  10.167 +			}
  10.168 +			catch (SQLException e) {
  10.169 +				throw new RdbmsException(e);
  10.170 +			}
  10.171 +		}
  10.172 +	}
  10.173 +
  10.174 +	public RdbmsValueFactory getValueFactory() {
  10.175 +		return vf;
  10.176 +	}
  10.177 +
  10.178 +	public void init()
  10.179 +		throws SailException
  10.180 +	{
  10.181 +		databaseLock = createDatabaseLock();
  10.182 +		try {
  10.183 +			nsAndTableIndexes = getConnection();
  10.184 +			resourceInserts = getConnection();
  10.185 +			literalInserts = getConnection();
  10.186 +			nsAndTableIndexes.setAutoCommit(true);
  10.187 +			resourceInserts.setAutoCommit(true);
  10.188 +			literalInserts.setAutoCommit(true);
  10.189 +			bnodeManager = new BNodeManager();
  10.190 +			uriManager = new UriManager();
  10.191 +			literalManager = new LiteralManager();
  10.192 +			ValueTableFactory tables = createValueTableFactory();
  10.193 +			tables.setSequenced(sequenced);
  10.194 +			if (sequenced) {
  10.195 +				ids = new IntegerIdSequence();
  10.196 +				tables.setIdSequence(ids);
  10.197 +				hashLookups = getConnection();
  10.198 +				hashLookups.setAutoCommit(true);
  10.199 +				hashManager = new HashManager();
  10.200 +				hashTable = tables.createHashTable(hashLookups, hashManager.getQueue());
  10.201 +				ids.setHashTable(hashTable);
  10.202 +				ids.init();
  10.203 +				hashManager.setHashTable(hashTable);
  10.204 +				hashManager.setBNodeManager(bnodeManager);
  10.205 +				hashManager.setLiteralManager(literalManager);
  10.206 +				hashManager.setUriManager(uriManager);
  10.207 +				hashManager.setIdSequence(ids);
  10.208 +				hashManager.init();
  10.209 +			}
  10.210 +			else {
  10.211 +				ids = new LongIdSequence();
  10.212 +				ids.init();
  10.213 +				tables.setIdSequence(ids);
  10.214 +			}
  10.215 +			namespaces = new NamespaceManager();
  10.216 +			namespaces.setConnection(resourceInserts);
  10.217 +			NamespacesTable nsTable = tables.createNamespacesTable(nsAndTableIndexes);
  10.218 +			nsTable.initialize();
  10.219 +			namespaces.setNamespacesTable(nsTable);
  10.220 +			namespaces.initialize();
  10.221 +			bnodeManager.setHashManager(hashManager);
  10.222 +			bnodeManager.setIdSequence(ids);
  10.223 +			uriManager.setHashManager(hashManager);
  10.224 +			uriManager.setIdSequence(ids);
  10.225 +			bnodeTable = tables.createBNodeTable(resourceInserts, bnodeManager.getQueue());
  10.226 +			uriTable = tables.createURITable(resourceInserts, uriManager.getQueue());
  10.227 +			literalManager.setHashManager(hashManager);
  10.228 +			literalManager.setIdSequence(ids);
  10.229 +			literalTable = tables.createLiteralTable(literalInserts, literalManager.getQueue());
  10.230 +			literalTable.setIdSequence(ids);
  10.231 +			vf = new RdbmsValueFactory();
  10.232 +			vf.setDelegate(ValueFactoryImpl.getInstance());
  10.233 +			vf.setIdSequence(ids);
  10.234 +			uriManager.setUriTable(uriTable);
  10.235 +			uriManager.init();
  10.236 +			predicateManager = new PredicateManager();
  10.237 +			predicateManager.setUriManager(uriManager);
  10.238 +			tripleTableManager = new TripleTableManager(tables);
  10.239 +			tripleTableManager.setConnection(nsAndTableIndexes);
  10.240 +			tripleTableManager.setIdSequence(ids);
  10.241 +			tripleTableManager.setBNodeManager(bnodeManager);
  10.242 +			tripleTableManager.setUriManager(uriManager);
  10.243 +			tripleTableManager.setLiteralManager(literalManager);
  10.244 +			tripleTableManager.setHashManager(hashManager);
  10.245 +			tripleTableManager.setPredicateManager(predicateManager);
  10.246 +			tripleTableManager.setMaxNumberOfTripleTables(maxTripleTables);
  10.247 +			tripleTableManager.setIndexingTriples(triplesIndexed);
  10.248 +			tripleTableManager.initialize();
  10.249 +			if (triplesIndexed) {
  10.250 +				tripleTableManager.createTripleIndexes();
  10.251 +			}
  10.252 +			else {
  10.253 +				tripleTableManager.dropTripleIndexes();
  10.254 +			}
  10.255 +			bnodeManager.setTable(bnodeTable);
  10.256 +			bnodeManager.init();
  10.257 +			vf.setBNodeManager(bnodeManager);
  10.258 +			vf.setURIManager(uriManager);
  10.259 +			literalManager.setTable(literalTable);
  10.260 +			literalManager.init();
  10.261 +			vf.setLiteralManager(literalManager);
  10.262 +			vf.setPredicateManager(predicateManager);
  10.263 +		}
  10.264 +		catch (SQLException e) {
  10.265 +			throw new RdbmsException(e);
  10.266 +		}
  10.267 +	}
  10.268 +
  10.269 +	public boolean isWritable()
  10.270 +		throws SailException
  10.271 +	{
  10.272 +		try {
  10.273 +			return !nsAndTableIndexes.isReadOnly();
  10.274 +		}
  10.275 +		catch (SQLException e) {
  10.276 +			throw new RdbmsException(e);
  10.277 +		}
  10.278 +	}
  10.279 +
  10.280 +	public SailConnection createConnection()
  10.281 +		throws SailException
  10.282 +	{
  10.283 +		try {
  10.284 +			Connection db = getConnection();
  10.285 +			db.setAutoCommit(true);
  10.286 +			if (db.getTransactionIsolation() != TRANSACTION_READ_COMMITTED) {
  10.287 +				db.setTransactionIsolation(TRANSACTION_READ_COMMITTED);
  10.288 +			}
  10.289 +			TripleManager tripleManager = new TripleManager();
  10.290 +			RdbmsTripleRepository s = new RdbmsTripleRepository();
  10.291 +			s.setTripleManager(tripleManager);
  10.292 +			s.setValueFactory(vf);
  10.293 +			s.setConnection(db);
  10.294 +			s.setBNodeTable(bnodeTable);
  10.295 +			s.setURITable(uriTable);
  10.296 +			s.setLiteralTable(literalTable);
  10.297 +			s.setIdSequence(ids);
  10.298 +			DefaultSailChangedEvent sailChangedEvent = new DefaultSailChangedEvent(sail);
  10.299 +			s.setSailChangedEvent(sailChangedEvent);
  10.300 +			TableFactory tables = createTableFactory();
  10.301 +			TransTableManager trans = createTransTableManager();
  10.302 +			trans.setIdSequence(ids);
  10.303 +			tripleManager.setTransTableManager(trans);
  10.304 +			trans.setBatchQueue(tripleManager.getQueue());
  10.305 +			trans.setSailChangedEvent(sailChangedEvent);
  10.306 +			trans.setConnection(db);
  10.307 +			trans.setTemporaryTableFactory(tables);
  10.308 +			trans.setStatementsTable(tripleTableManager);
  10.309 +			trans.setFromDummyTable(getFromDummyTable());
  10.310 +			trans.initialize();
  10.311 +			s.setTransaction(trans);
  10.312 +			QueryBuilderFactory bfactory = createQueryBuilderFactory();
  10.313 +			bfactory.setValueFactory(vf);
  10.314 +			bfactory.setUsingHashTable(hashManager != null);
  10.315 +			s.setQueryBuilderFactory(bfactory);
  10.316 +			RdbmsConnection conn = new RdbmsConnection(sail, s);
  10.317 +			conn.setNamespaces(namespaces);
  10.318 +			RdbmsEvaluationFactory efactory = new RdbmsEvaluationFactory();
  10.319 +			efactory.setQueryBuilderFactory(bfactory);
  10.320 +			efactory.setRdbmsTripleRepository(s);
  10.321 +			efactory.setIdSequence(ids);
  10.322 +			conn.setRdbmsEvaluationFactory(efactory);
  10.323 +			RdbmsQueryOptimizer optimizer = createOptimizer();
  10.324 +			SelectQueryOptimizerFactory selectOptimizerFactory = createSelectQueryOptimizerFactory();
  10.325 +			selectOptimizerFactory.setTransTableManager(trans);
  10.326 +			selectOptimizerFactory.setValueFactory(vf);
  10.327 +			selectOptimizerFactory.setIdSequence(ids);
  10.328 +			optimizer.setSelectQueryOptimizerFactory(selectOptimizerFactory);
  10.329 +			optimizer.setValueFactory(vf);
  10.330 +			optimizer.setBnodeTable(bnodeTable);
  10.331 +			optimizer.setUriTable(uriTable);
  10.332 +			optimizer.setLiteralTable(literalTable);
  10.333 +			optimizer.setHashTable(hashTable);
  10.334 +			conn.setRdbmsQueryOptimizer(optimizer);
  10.335 +			conn.setLockManager(lock);
  10.336 +			return conn;
  10.337 +		}
  10.338 +		catch (SQLException e) {
  10.339 +			throw new RdbmsException(e);
  10.340 +		}
  10.341 +	}
  10.342 +
  10.343 +	public void shutDown()
  10.344 +		throws SailException
  10.345 +	{
  10.346 +		try {
  10.347 +			if (tripleTableManager != null) {
  10.348 +				tripleTableManager.close();
  10.349 +			}
  10.350 +			if (uriManager != null) {
  10.351 +				uriManager.close();
  10.352 +			}
  10.353 +			if (bnodeManager != null) {
  10.354 +				bnodeManager.close();
  10.355 +			}
  10.356 +			if (literalManager != null) {
  10.357 +				literalManager.close();
  10.358 +			}
  10.359 +			if (hashManager != null) {
  10.360 +				hashManager.close();
  10.361 +			}
  10.362 +			if (resourceInserts != null) {
  10.363 +				resourceInserts.close();
  10.364 +				resourceInserts = null;
  10.365 +			}
  10.366 +			if (literalInserts != null) {
  10.367 +				literalInserts.close();
  10.368 +				literalInserts = null;
  10.369 +			}
  10.370 +			if (hashLookups != null) {
  10.371 +				hashLookups.close();
  10.372 +				hashLookups = null;
  10.373 +			}
  10.374 +			if (nsAndTableIndexes != null) {
  10.375 +				nsAndTableIndexes.close();
  10.376 +				nsAndTableIndexes = null;
  10.377 +			}
  10.378 +		}
  10.379 +		catch (SQLException e) {
  10.380 +			throw new RdbmsException(e);
  10.381 +		}
  10.382 +		finally {
  10.383 +			if (databaseLock != null) {
  10.384 +				databaseLock.release();
  10.385 +			}
  10.386 +		}
  10.387 +	}
  10.388 +
  10.389 +	protected Lock createDatabaseLock()
  10.390 +		throws SailException
  10.391 +	{
  10.392 +		DatabaseLockManager manager;
  10.393 +		manager = new DatabaseLockManager(ds, user, password);
  10.394 +		if (manager.isDebugEnabled())
  10.395 +			return manager.tryLock();
  10.396 +		return manager.lockOrFail();
  10.397 +	}
  10.398 +
  10.399 +	protected QueryBuilderFactory createQueryBuilderFactory() {
  10.400 +		return new QueryBuilderFactory();
  10.401 +	}
  10.402 +
  10.403 +	protected ValueTableFactory createValueTableFactory() {
  10.404 +		return new ValueTableFactory(createTableFactory());
  10.405 +	}
  10.406 +
  10.407 +	protected TableFactory createTableFactory() {
  10.408 +		return new TableFactory();
  10.409 +	}
  10.410 +
  10.411 +	protected TransTableManager createTransTableManager() {
  10.412 +		return new TransTableManager();
  10.413 +	}
  10.414 +
  10.415 +	protected RdbmsQueryOptimizer createOptimizer() {
  10.416 +		return new RdbmsQueryOptimizer();
  10.417 +	}
  10.418 +
  10.419 +	protected SelectQueryOptimizerFactory createSelectQueryOptimizerFactory() {
  10.420 +		return new SelectQueryOptimizerFactory();
  10.421 +	}
  10.422 +
  10.423 +	/**
  10.424 +	 * FROM DUAL
  10.425 +	 * 
  10.426 +	 * @return from clause or empty string
  10.427 +	 */
  10.428 +	protected String getFromDummyTable() {
  10.429 +		return "";
  10.430 +	}
  10.431 +
  10.432 +	protected Connection getConnection()
  10.433 +		throws SQLException
  10.434 +	{
  10.435 +		if (user == null)
  10.436 +			return ds.getConnection();
  10.437 +		return ds.getConnection(user, password);
  10.438 +	}
  10.439 +
  10.440 +}
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/RdbmsProvider.java	Thu May 24 13:58:55 2012 +0300
    11.3 @@ -0,0 +1,20 @@
    11.4 +/*
    11.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    11.6 + *
    11.7 + * Licensed under the Aduna BSD-style license.
    11.8 + */
    11.9 +package org.openrdf.sail.rdbms;
   11.10 +
   11.11 +/**
   11.12 + * Each supported relation store should implement this service provider
   11.13 + * interface to initiate a connection factory tailored to the given product name
   11.14 + * and version. If a provider does not support the given database name and
   11.15 + * version it should not return a connection factory, but rather a null value.
   11.16 + * 
   11.17 + * @author James Leigh
   11.18 + * 
   11.19 + */
   11.20 +public interface RdbmsProvider {
   11.21 +
   11.22 +	RdbmsConnectionFactory createRdbmsConnectionFactory(String dbName, String dbVersion);
   11.23 +}
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/RdbmsStore.java	Thu May 24 13:58:55 2012 +0300
    12.3 @@ -0,0 +1,258 @@
    12.4 +/*
    12.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    12.6 + *
    12.7 + * Licensed under the Aduna BSD-style license.
    12.8 + */
    12.9 +package org.openrdf.sail.rdbms;
   12.10 +
   12.11 +import java.sql.Connection;
   12.12 +import java.sql.DatabaseMetaData;
   12.13 +import java.sql.SQLException;
   12.14 +import java.util.Iterator;
   12.15 +
   12.16 +import javax.imageio.spi.ServiceRegistry;
   12.17 +import javax.naming.InitialContext;
   12.18 +import javax.naming.NamingException;
   12.19 +import javax.sql.DataSource;
   12.20 +
   12.21 +import org.apache.commons.dbcp.BasicDataSource;
   12.22 +
   12.23 +import org.openrdf.sail.SailConnection;
   12.24 +import org.openrdf.sail.SailException;
   12.25 +import org.openrdf.sail.helpers.SailBase;
   12.26 +import org.openrdf.sail.rdbms.exceptions.RdbmsException;
   12.27 +
   12.28 +/**
   12.29 + * The RDBMS SAIL for relational database storage in Sesame. This class acts
   12.30 + * both as a base class for database specific stores as well as a generic store
   12.31 + * that can infer the type of database through the JDBC connection.
   12.32 + * 
   12.33 + * @author James Leigh
   12.34 + */
   12.35 +public class RdbmsStore extends SailBase {
   12.36 +
   12.37 +	private RdbmsConnectionFactory factory;
   12.38 +
   12.39 +	private String jdbcDriver;
   12.40 +
   12.41 +	private String url;
   12.42 +
   12.43 +	private String user;
   12.44 +
   12.45 +	private String password;
   12.46 +
   12.47 +	private int maxTripleTables;
   12.48 +
   12.49 +	private boolean triplesIndexed = true;
   12.50 +
   12.51 +	private boolean sequenced = true;
   12.52 +
   12.53 +	private BasicDataSource ds;
   12.54 +
   12.55 +	public RdbmsStore() {
   12.56 +		super();
   12.57 +	}
   12.58 +
   12.59 +	/**
   12.60 +	 * Creates a new RDBMS RDF Store using the provided database connection.
   12.61 +	 * 
   12.62 +	 * @param url
   12.63 +	 *        JDNI url of a DataSource
   12.64 +	 */
   12.65 +	public RdbmsStore(String url) {
   12.66 +		this.url = url;
   12.67 +	}
   12.68 +
   12.69 +	/**
   12.70 +	 * Creates a new RDBMS RDF Store using the provided database connection.
   12.71 +	 * 
   12.72 +	 * @param url
   12.73 +	 *        JDNI url of a DataSource
   12.74 +	 * @param user
   12.75 +	 * @param password
   12.76 +	 */
   12.77 +	public RdbmsStore(String url, String user, String password) {
   12.78 +		this.url = url;
   12.79 +		this.user = user;
   12.80 +		this.password = password;
   12.81 +	}
   12.82 +
   12.83 +	/**
   12.84 +	 * Creates a new RDBMS RDF Store using the provided database connection.
   12.85 +	 * 
   12.86 +	 * @param jdbcDriver
   12.87 +	 * @param jdbcUrl
   12.88 +	 */
   12.89 +	public RdbmsStore(String jdbcDriver, String jdbcUrl) {
   12.90 +		this.jdbcDriver = jdbcDriver;
   12.91 +		this.url = jdbcUrl;
   12.92 +	}
   12.93 +
   12.94 +	/**
   12.95 +	 * Creates a new RDBMS RDF Store using the provided database connection.
   12.96 +	 * 
   12.97 +	 * @param jdbcDriver
   12.98 +	 * @param jdbcUrl
   12.99 +	 * @param user
  12.100 +	 * @param password
  12.101 +	 */
  12.102 +	public RdbmsStore(String jdbcDriver, String jdbcUrl, String user, String password) {
  12.103 +		this.jdbcDriver = jdbcDriver;
  12.104 +		this.url = jdbcUrl;
  12.105 +		this.user = user;
  12.106 +		this.password = password;
  12.107 +	}
  12.108 +
  12.109 +	public int getMaxNumberOfTripleTables() {
  12.110 +		return maxTripleTables;
  12.111 +	}
  12.112 +
  12.113 +	public void setMaxNumberOfTripleTables(int max) {
  12.114 +		maxTripleTables = max;
  12.115 +	}
  12.116 +
  12.117 +	public boolean isIndexed() {
  12.118 +		return triplesIndexed;
  12.119 +	}
  12.120 +
  12.121 +	public void setIndexed(boolean indexed)
  12.122 +		throws SailException
  12.123 +	{
  12.124 +		triplesIndexed = indexed;
  12.125 +		if (factory != null) {
  12.126 +			factory.setTriplesIndexed(triplesIndexed);
  12.127 +		}
  12.128 +	}
  12.129 +
  12.130 +	public boolean isSequenced() {
  12.131 +		return sequenced;
  12.132 +	}
  12.133 +
  12.134 +	public void setSequenced(boolean useSequence) {
  12.135 +		this.sequenced = useSequence;
  12.136 +	}
  12.137 +
  12.138 +	@Override
  12.139 +	protected void initializeInternal()
  12.140 +		throws SailException
  12.141 +	{
  12.142 +		if (factory == null) {
  12.143 +			try {
  12.144 +				factory = createFactory(jdbcDriver, url, user, password);
  12.145 +			}
  12.146 +			catch (SailException e) {
  12.147 +				throw e;
  12.148 +			}
  12.149 +			catch (Exception e) {
  12.150 +				throw new RdbmsException(e);
  12.151 +			}
  12.152 +		}
  12.153 +		factory.setMaxNumberOfTripleTables(maxTripleTables);
  12.154 +		factory.setTriplesIndexed(triplesIndexed);
  12.155 +		factory.setSequenced(sequenced);
  12.156 +		factory.init();
  12.157 +	}
  12.158 +
  12.159 +	public boolean isWritable()
  12.160 +		throws SailException
  12.161 +	{
  12.162 +		return factory.isWritable();
  12.163 +	}
  12.164 +
  12.165 +	public RdbmsValueFactory getValueFactory() {
  12.166 +		return factory.getValueFactory();
  12.167 +	}
  12.168 +
  12.169 +	@Override
  12.170 +	protected SailConnection getConnectionInternal()
  12.171 +		throws SailException
  12.172 +	{
  12.173 +		return factory.createConnection();
  12.174 +	}
  12.175 +
  12.176 +	@Override
  12.177 +	protected void shutDownInternal()
  12.178 +		throws SailException
  12.179 +	{
  12.180 +		factory.shutDown();
  12.181 +		try {
  12.182 +			if (ds != null) {
  12.183 +				ds.close();
  12.184 +			}
  12.185 +		}
  12.186 +		catch (SQLException e) {
  12.187 +			throw new RdbmsException(e);
  12.188 +		}
  12.189 +	}
  12.190 +
  12.191 +	protected void setConnectionFactory(RdbmsConnectionFactory factory) {
  12.192 +		this.factory = factory;
  12.193 +	}
  12.194 +
  12.195 +	protected void setBasicDataSource(BasicDataSource ds) {
  12.196 +		this.ds = ds;
  12.197 +	}
  12.198 +
  12.199 +	private RdbmsConnectionFactory createFactory(String jdbcDriver, String url, String user, String password)
  12.200 +		throws Exception
  12.201 +	{
  12.202 +		if (jdbcDriver != null) {
  12.203 +			Class.forName(jdbcDriver);
  12.204 +		}
  12.205 +		DataSource ds = lookupDataSource(url, user, password);
  12.206 +		Connection con;
  12.207 +		if (user == null || url.startsWith("jdbc:")) {
  12.208 +			con = ds.getConnection();
  12.209 +		}
  12.210 +		else {
  12.211 +			con = ds.getConnection(user, password);
  12.212 +		}
  12.213 +		try {
  12.214 +			DatabaseMetaData metaData = con.getMetaData();
  12.215 +			RdbmsConnectionFactory factory = newFactory(metaData);
  12.216 +			factory.setSail(this);
  12.217 +			if (user == null || url.startsWith("jdbc:")) {
  12.218 +				factory.setDataSource(ds);
  12.219 +			}
  12.220 +			else {
  12.221 +				factory.setDataSource(ds, user, password);
  12.222 +			}
  12.223 +			return factory;
  12.224 +		}
  12.225 +		finally {
  12.226 +			con.close();
  12.227 +		}
  12.228 +	}
  12.229 +
  12.230 +	private DataSource lookupDataSource(String url, String user, String password)
  12.231 +		throws NamingException
  12.232 +	{
  12.233 +		if (url.startsWith("jdbc:")) {
  12.234 +			BasicDataSource ds = new BasicDataSource();
  12.235 +			ds.setUrl(url);
  12.236 +			ds.setUsername(user);
  12.237 +			ds.setPassword(password);
  12.238 +			setBasicDataSource(ds);
  12.239 +			return ds;
  12.240 +		}
  12.241 +		return (DataSource)new InitialContext().lookup(url);
  12.242 +	}
  12.243 +
  12.244 +	private RdbmsConnectionFactory newFactory(DatabaseMetaData metaData)
  12.245 +		throws SQLException
  12.246 +	{
  12.247 +		String dbn = metaData.getDatabaseProductName();
  12.248 +		String dbv = metaData.getDatabaseProductVersion();
  12.249 +		RdbmsConnectionFactory factory;
  12.250 +		Iterator<RdbmsProvider> providers;
  12.251 +		providers = ServiceRegistry.lookupProviders(RdbmsProvider.class);
  12.252 +		while (providers.hasNext()) {
  12.253 +			RdbmsProvider provider = providers.next();
  12.254 +			factory = provider.createRdbmsConnectionFactory(dbn, dbv);
  12.255 +			if (factory != null)
  12.256 +				return factory;
  12.257 +		}
  12.258 +		return new RdbmsConnectionFactory();
  12.259 +	}
  12.260 +
  12.261 +}
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/RdbmsTripleRepository.java	Thu May 24 13:58:55 2012 +0300
    13.3 @@ -0,0 +1,563 @@
    13.4 +/*
    13.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    13.6 + *
    13.7 + * Licensed under the Aduna BSD-style license.
    13.8 + */
    13.9 +package org.openrdf.sail.rdbms;
   13.10 +
   13.11 +import java.sql.Connection;
   13.12 +import java.sql.PreparedStatement;
   13.13 +import java.sql.ResultSet;
   13.14 +import java.sql.SQLException;
   13.15 +import java.util.ArrayList;
   13.16 +import java.util.Collection;
   13.17 +import java.util.Collections;
   13.18 +import java.util.LinkedList;
   13.19 +import java.util.List;
   13.20 +
   13.21 +import info.aduna.concurrent.locks.Lock;
   13.22 +
   13.23 +import org.openrdf.model.Resource;
   13.24 +import org.openrdf.model.URI;
   13.25 +import org.openrdf.model.Value;
   13.26 +import org.openrdf.sail.SailException;
   13.27 +import org.openrdf.sail.helpers.DefaultSailChangedEvent;
   13.28 +import org.openrdf.sail.rdbms.evaluation.QueryBuilderFactory;
   13.29 +import org.openrdf.sail.rdbms.evaluation.SqlBracketBuilder;
   13.30 +import org.openrdf.sail.rdbms.evaluation.SqlJoinBuilder;
   13.31 +import org.openrdf.sail.rdbms.evaluation.SqlQueryBuilder;
   13.32 +import org.openrdf.sail.rdbms.exceptions.RdbmsException;
   13.33 +import org.openrdf.sail.rdbms.iteration.EmptyRdbmsResourceIteration;
   13.34 +import org.openrdf.sail.rdbms.iteration.EmptyRdbmsStatementIteration;
   13.35 +import org.openrdf.sail.rdbms.iteration.RdbmsResourceIteration;
   13.36 +import org.openrdf.sail.rdbms.iteration.RdbmsStatementIteration;
   13.37 +import org.openrdf.sail.rdbms.managers.TransTableManager;
   13.38 +import org.openrdf.sail.rdbms.managers.TripleManager;
   13.39 +import org.openrdf.sail.rdbms.model.RdbmsResource;
   13.40 +import org.openrdf.sail.rdbms.model.RdbmsStatement;
   13.41 +import org.openrdf.sail.rdbms.model.RdbmsURI;
   13.42 +import org.openrdf.sail.rdbms.model.RdbmsValue;
   13.43 +import org.openrdf.sail.rdbms.schema.BNodeTable;
   13.44 +import org.openrdf.sail.rdbms.schema.IdSequence;
   13.45 +import org.openrdf.sail.rdbms.schema.LiteralTable;
   13.46 +import org.openrdf.sail.rdbms.schema.URITable;
   13.47 +import org.openrdf.sail.rdbms.schema.ValueTable;
   13.48 +
   13.49 +/**
   13.50 + * Facade to {@link TransTableManager}, {@link URITable}, {@link BNodeTable} and
   13.51 + * {@link LiteralTable} for adding, removing, and retrieving statements from the
   13.52 + * database.
   13.53 + * 
   13.54 + * @author James Leigh
   13.55 + */
   13.56 +public class RdbmsTripleRepository {
   13.57 +
   13.58 +	public static int STMT_BUFFER = 32;
   13.59 +
   13.60 +	private Connection conn;
   13.61 +
   13.62 +	private RdbmsValueFactory vf;
   13.63 +
   13.64 +	private TransTableManager statements;
   13.65 +
   13.66 +	private QueryBuilderFactory factory;
   13.67 +
   13.68 +	private BNodeTable bnodes;
   13.69 +
   13.70 +	private URITable uris;
   13.71 +
   13.72 +	private LiteralTable literals;
   13.73 +
   13.74 +	private Lock readLock;
   13.75 +
   13.76 +	private DefaultSailChangedEvent sailChangedEvent;
   13.77 +
   13.78 +	private TripleManager manager;
   13.79 +
   13.80 +	private LinkedList<RdbmsStatement> queue = new LinkedList<RdbmsStatement>();
   13.81 +
   13.82 +	private IdSequence ids;
   13.83 +
   13.84 +	public Connection getConnection() {
   13.85 +		return conn;
   13.86 +	}
   13.87 +
   13.88 +	public void setConnection(Connection conn) {
   13.89 +		this.conn = conn;
   13.90 +	}
   13.91 +
   13.92 +	public void setIdSequence(IdSequence ids) {
   13.93 +		this.ids = ids;
   13.94 +	}
   13.95 +
   13.96 +	public RdbmsValueFactory getValueFactory() {
   13.97 +		return vf;
   13.98 +	}
   13.99 +
  13.100 +	public void setValueFactory(RdbmsValueFactory vf) {
  13.101 +		this.vf = vf;
  13.102 +	}
  13.103 +
  13.104 +	public DefaultSailChangedEvent getSailChangedEvent() {
  13.105 +		return sailChangedEvent;
  13.106 +	}
  13.107 +
  13.108 +	public void setSailChangedEvent(DefaultSailChangedEvent sailChangedEvent) {
  13.109 +		this.sailChangedEvent = sailChangedEvent;
  13.110 +	}
  13.111 +
  13.112 +	public void setQueryBuilderFactory(QueryBuilderFactory factory) {
  13.113 +		this.factory = factory;
  13.114 +	}
  13.115 +
  13.116 +	public void setBNodeTable(BNodeTable bnodes) {
  13.117 +		this.bnodes = bnodes;
  13.118 +	}
  13.119 +
  13.120 +	public void setURITable(URITable uris) {
  13.121 +		this.uris = uris;
  13.122 +	}
  13.123 +
  13.124 +	public void setLiteralTable(LiteralTable literals) {
  13.125 +		this.literals = literals;
  13.126 +	}
  13.127 +
  13.128 +	public void setTransaction(TransTableManager temporary) {
  13.129 +		this.statements = temporary;
  13.130 +	}
  13.131 +
  13.132 +	public void setTripleManager(TripleManager tripleManager) {
  13.133 +		this.manager = tripleManager;
  13.134 +	}
  13.135 +
  13.136 +	public void flush()
  13.137 +		throws RdbmsException
  13.138 +	{
  13.139 +		try {
  13.140 +			synchronized (queue) {
  13.141 +				while (!queue.isEmpty()) {
  13.142 +					insert(queue.removeFirst());
  13.143 +				}
  13.144 +			}
  13.145 +			vf.flush();
  13.146 +			manager.flush();
  13.147 +		}
  13.148 +		catch (SQLException e) {
  13.149 +			throw new RdbmsException(e);
  13.150 +		}
  13.151 +		catch (InterruptedException e) {
  13.152 +			throw new RdbmsException(e);
  13.153 +		}
  13.154 +	}
  13.155 +
  13.156 +	public synchronized void begin()
  13.157 +		throws SQLException
  13.158 +	{
  13.159 +		conn.setAutoCommit(false);
  13.160 +	}
  13.161 +
  13.162 +	public synchronized void close()
  13.163 +		throws SQLException
  13.164 +	{
  13.165 +		manager.close();
  13.166 +		if (!conn.getAutoCommit()) {
  13.167 +			conn.rollback();
  13.168 +		}
  13.169 +		conn.setAutoCommit(true);
  13.170 +		conn.close();
  13.171 +		releaseLock();
  13.172 +	}
  13.173 +
  13.174 +	public synchronized void commit()
  13.175 +		throws SQLException, RdbmsException, InterruptedException
  13.176 +	{
  13.177 +		synchronized (queue) {
  13.178 +			while (!queue.isEmpty()) {
  13.179 +				insert(queue.removeFirst());
  13.180 +			}
  13.181 +		}
  13.182 +		manager.flush();
  13.183 +		conn.commit();
  13.184 +		conn.setAutoCommit(true);
  13.185 +		releaseLock();
  13.186 +		Lock writeLock = vf.tryIdWriteLock();
  13.187 +		try {
  13.188 +			vf.flush();
  13.189 +			statements.committed(writeLock != null);
  13.190 +		}
  13.191 +		finally {
  13.192 +			if (writeLock != null) {
  13.193 +				writeLock.release();
  13.194 +			}
  13.195 +		}
  13.196 +	}
  13.197 +
  13.198 +	public void rollback()
  13.199 +		throws SQLException, SailException
  13.200 +	{
  13.201 +		synchronized (queue) {
  13.202 +			queue.clear();
  13.203 +		}
  13.204 +		manager.clear();
  13.205 +		if (!conn.getAutoCommit()) {
  13.206 +			conn.rollback();
  13.207 +			conn.setAutoCommit(true);
  13.208 +		}
  13.209 +		releaseLock();
  13.210 +	}
  13.211 +
  13.212 +	@Override
  13.213 +	protected void finalize()
  13.214 +		throws Throwable
  13.215 +	{
  13.216 +		releaseLock();
  13.217 +		super.finalize();
  13.218 +	}
  13.219 +
  13.220 +	public void add(RdbmsStatement st)
  13.221 +		throws SailException, SQLException, InterruptedException
  13.222 +	{
  13.223 +		acquireLock();
  13.224 +		synchronized (queue) {
  13.225 +			queue.add(st);
  13.226 +			if (queue.size() > getMaxQueueSize()) {
  13.227 +				insert(queue.removeFirst());
  13.228 +			}
  13.229 +		}
  13.230 +	}
  13.231 +
  13.232 +	public RdbmsStatementIteration find(Resource subj, URI pred, Value obj, Resource... ctxs)
  13.233 +		throws RdbmsException
  13.234 +	{
  13.235 +		try {
  13.236 +			RdbmsResource s = vf.asRdbmsResource(subj);
  13.237 +			RdbmsURI p = vf.asRdbmsURI(pred);
  13.238 +			RdbmsValue o = vf.asRdbmsValue(obj);
  13.239 +			RdbmsResource[] c = vf.asRdbmsResource(ctxs);
  13.240 +			flush();
  13.241 +			SqlQueryBuilder query = buildSelectQuery(s, p, o, c);
  13.242 +			if (query == null)
  13.243 +				return new EmptyRdbmsStatementIteration();
  13.244 +			List<?> parameters = query.findParameters(new ArrayList<Object>());
  13.245 +			PreparedStatement stmt = conn.prepareStatement(query.toString());
  13.246 +			try {
  13.247 +				for (int i = 0, n = parameters.size(); i < n; i++) {
  13.248 +					stmt.setObject(i + 1, parameters.get(i));
  13.249 +				}
  13.250 +				return new RdbmsStatementIteration(vf, stmt, ids);
  13.251 +			}
  13.252 +			catch (SQLException e) {
  13.253 +				stmt.close();
  13.254 +				throw e;
  13.255 +			}
  13.256 +		}
  13.257 +		catch (SQLException e) {
  13.258 +			throw new RdbmsException(e);
  13.259 +		}
  13.260 +
  13.261 +	}
  13.262 +
  13.263 +	public RdbmsResourceIteration findContexts()
  13.264 +		throws SQLException, RdbmsException
  13.265 +	{
  13.266 +		flush();
  13.267 +		String qry = buildContextQuery();
  13.268 +		if (qry == null)
  13.269 +			return new EmptyRdbmsResourceIteration();
  13.270 +		PreparedStatement stmt = conn.prepareStatement(qry);
  13.271 +		try {
  13.272 +			return new RdbmsResourceIteration(vf, stmt);
  13.273 +		}
  13.274 +		catch (SQLException e) {
  13.275 +			stmt.close();
  13.276 +			throw e;
  13.277 +		}
  13.278 +	}
  13.279 +
  13.280 +	public boolean isClosed()
  13.281 +		throws SQLException
  13.282 +	{
  13.283 +		return conn.isClosed();
  13.284 +	}
  13.285 +
  13.286 +	public int remove(Resource subj, URI pred, Value obj, Resource... ctxs)
  13.287 +		throws RdbmsException
  13.288 +	{
  13.289 +		RdbmsResource s = vf.asRdbmsResource(subj);
  13.290 +		RdbmsURI p = vf.asRdbmsURI(pred);
  13.291 +		RdbmsValue o = vf.asRdbmsValue(obj);
  13.292 +		RdbmsResource[] c = vf.asRdbmsResource(ctxs);
  13.293 +		flush();
  13.294 +		try {
  13.295 +			Collection<Number> predicates;
  13.296 +			if (p == null) {
  13.297 +				predicates = statements.getPredicateIds();
  13.298 +			}
  13.299 +			else {
  13.300 +				predicates = Collections.singleton(vf.getInternalId(p));
  13.301 +			}
  13.302 +			int total = 0;
  13.303 +			for (Number id : predicates) {
  13.304 +				String tableName = statements.findTableName(id);
  13.305 +				if (!statements.isPredColumnPresent(id)) {
  13.306 +					p = null;
  13.307 +				}
  13.308 +				String query = buildDeleteQuery(tableName, s, p, o, c);
  13.309 +				PreparedStatement stmt = conn.prepareStatement(query);
  13.310 +				try {
  13.311 +					setSelectQuery(stmt, s, p, o, c);
  13.312 +					int count = stmt.executeUpdate();
  13.313 +					statements.removed(id, count);
  13.314 +					total += count;
  13.315 +				}
  13.316 +				finally {
  13.317 +					stmt.close();
  13.318 +				}
  13.319 +			}
  13.320 +			if (total > 0) {
  13.321 +				sailChangedEvent.setStatementsRemoved(true);
  13.322 +			}
  13.323 +			return total;
  13.324 +		}
  13.325 +		catch (SQLException e) {
  13.326 +			throw new RdbmsException(e);
  13.327 +		}
  13.328 +	}
  13.329 +
  13.330 +	public long size(RdbmsResource... ctxs)
  13.331 +		throws SQLException, SailException
  13.332 +	{
  13.333 +		flush();
  13.334 +		String qry = buildCountQuery(ctxs);
  13.335 +		if (qry == null)
  13.336 +			return 0;
  13.337 +		PreparedStatement stmt = conn.prepareStatement(qry);
  13.338 +		try {
  13.339 +			setCountQuery(stmt, ctxs);
  13.340 +			ResultSet rs = stmt.executeQuery();
  13.341 +			try {
  13.342 +				if (rs.next())
  13.343 +					return rs.getLong(1);
  13.344 +				throw new RdbmsException("Could not determine size");
  13.345 +			}
  13.346 +			finally {
  13.347 +				rs.close();
  13.348 +			}
  13.349 +		}
  13.350 +		finally {
  13.351 +			stmt.close();
  13.352 +		}
  13.353 +	}
  13.354 +
  13.355 +	protected int getMaxQueueSize() {
  13.356 +		return STMT_BUFFER;
  13.357 +	}
  13.358 +
  13.359 +	private synchronized void acquireLock()
  13.360 +		throws InterruptedException
  13.361 +	{
  13.362 +		if (readLock == null) {
  13.363 +			readLock = vf.getIdReadLock();
  13.364 +		}
  13.365 +	}
  13.366 +
  13.367 +	private synchronized void releaseLock() {
  13.368 +		if (readLock != null) {
  13.369 +			readLock.release();
  13.370 +			readLock = null;
  13.371 +		}
  13.372 +	}
  13.373 +
  13.374 +	private String buildContextQuery()
  13.375 +		throws SQLException
  13.376 +	{
  13.377 +		if (statements.isEmpty())
  13.378 +			return null;
  13.379 +		String tableName = statements.getCombinedTableName();
  13.380 +		SqlQueryBuilder query = factory.createSqlQueryBuilder();
  13.381 +		query.select().column("t", "ctx");
  13.382 +		query.select().append("CASE WHEN MIN(u.value) IS NOT NULL THEN MIN(u.value) ELSE MIN(b.value) END");
  13.383 +		SqlJoinBuilder join = query.from(tableName, "t");
  13.384 +		join.leftjoin(bnodes.getName(), "b").on("id", "t.ctx");
  13.385 +		join.leftjoin(uris.getShortTableName(), "u").on("id", "t.ctx");
  13.386 +		SqlBracketBuilder open = query.filter().and().open();
  13.387 +		open.column("u", "value").isNotNull();
  13.388 +		open.or();
  13.389 +		open.column("b", "value").isNotNull();
  13.390 +		open.close();
  13.391 +		query.groupBy("t.ctx");
  13.392 +		return query.toString();
  13.393 +	}
  13.394 +
  13.395 +	private String buildCountQuery(RdbmsResource... ctxs)
  13.396 +		throws SQLException
  13.397 +	{
  13.398 +		String tableName = statements.getCombinedTableName();
  13.399 +		StringBuilder sb = new StringBuilder();
  13.400 +		sb.append("SELECT COUNT(*) FROM ");
  13.401 +		sb.append(tableName).append(" t");
  13.402 +		if (ctxs != null && ctxs.length > 0) {
  13.403 +			sb.append("\nWHERE ");
  13.404 +			for (int i = 0; i < ctxs.length; i++) {
  13.405 +				sb.append("t.ctx = ?");
  13.406 +				if (i < ctxs.length - 1) {
  13.407 +					sb.append(" OR ");
  13.408 +				}
  13.409 +			}
  13.410 +		}
  13.411 +		return sb.toString();
  13.412 +	}
  13.413 +
  13.414 +	private String buildDeleteQuery(String tableName, RdbmsResource subj, RdbmsURI pred, RdbmsValue obj,
  13.415 +			RdbmsResource... ctxs)
  13.416 +		throws RdbmsException, SQLException
  13.417 +	{
  13.418 +		StringBuilder sb = new StringBuilder();
  13.419 +		sb.append("DELETE FROM ").append(tableName);
  13.420 +		return buildWhere(sb, subj, pred, obj, ctxs);
  13.421 +	}
  13.422 +
  13.423 +	private SqlQueryBuilder buildSelectQuery(RdbmsResource subj, RdbmsURI pred, RdbmsValue obj,
  13.424 +			RdbmsResource... ctxs)
  13.425 +		throws RdbmsException, SQLException
  13.426 +	{
  13.427 +		String tableName = statements.getTableName(vf.getInternalId(pred));
  13.428 +		SqlQueryBuilder query = factory.createSqlQueryBuilder();
  13.429 +		query.select().column("t", "ctx");
  13.430 +		query.select().append(
  13.431 +				"CASE WHEN cu.value IS NOT NULL THEN cu.value WHEN clu.value IS NOT NULL THEN clu.value ELSE cb.value END");
  13.432 +		query.select().column("t", "subj");
  13.433 +		query.select().append(
  13.434 +				"CASE WHEN su.value IS NOT NULL THEN su.value WHEN slu.value IS NOT NULL THEN slu.value ELSE sb.value END");
  13.435 +		query.select().column("pu", "id");
  13.436 +		query.select().column("pu", "value");
  13.437 +		query.select().column("t", "obj");
  13.438 +		query.select().append(
  13.439 +				"CASE WHEN ou.value IS NOT NULL THEN ou.value" + " WHEN olu.value IS NOT NULL THEN olu.value"
  13.440 +						+ " WHEN ob.value IS NOT NULL THEN ob.value"
  13.441 +						+ " WHEN ol.value IS NOT NULL THEN ol.value ELSE oll.value END");
  13.442 +		query.select().column("od", "value");
  13.443 +		query.select().column("og", "value");
  13.444 +		SqlJoinBuilder join;
  13.445 +		if (pred != null) {
  13.446 +			join = query.from(uris.getShortTableName(), "pu");
  13.447 +			// TODO what about long predicate URIs?
  13.448 +			join = join.join(tableName, "t");
  13.449 +		}
  13.450 +		else {
  13.451 +			join = query.from(tableName, "t");
  13.452 +		}
  13.453 +		if (pred == null) {
  13.454 +			join.join(uris.getShortTableName(), "pu").on("id", "t.pred");
  13.455 +		}
  13.456 +		join.leftjoin(uris.getShortTableName(), "cu").on("id", "t.ctx");
  13.457 +		join.leftjoin(uris.getLongTableName(), "clu").on("id", "t.ctx");
  13.458 +		join.leftjoin(bnodes.getName(), "cb").on("id", "t.ctx");
  13.459 +		join.leftjoin(uris.getShortTableName(), "su").on("id", "t.subj");
  13.460 +		join.leftjoin(uris.getLongTableName(), "slu").on("id", "t.subj");
  13.461 +		join.leftjoin(bnodes.getName(), "sb").on("id", "t.subj");
  13.462 +		join.leftjoin(uris.getShortTableName(), "ou").on("id", "t.obj");
  13.463 +		join.leftjoin(uris.getLongTableName(), "olu").on("id", "t.obj");
  13.464 +		join.leftjoin(bnodes.getName(), "ob").on("id", "t.obj");
  13.465 +		join.leftjoin(literals.getLabelTable().getName(), "ol").on("id", "t.obj");
  13.466 +		join.leftjoin(literals.getLongLabelTable().getName(), "oll").on("id", "t.obj");
  13.467 +		join.leftjoin(literals.getLanguageTable().getName(), "og").on("id", "t.obj");
  13.468 +		join.leftjoin(literals.getDatatypeTable().getName(), "od").on("id", "t.obj");
  13.469 +		if (ctxs != null && ctxs.length > 0) {
  13.470 +			Number[] ids = new Number[ctxs.length];
  13.471 +			for (int i = 0; i < ids.length; i++) {
  13.472 +				ids[i] = vf.getInternalId(ctxs[i]);
  13.473 +			}
  13.474 +			query.filter().and().columnIn("t", "ctx", ids);
  13.475 +		}
  13.476 +		if (subj != null) {
  13.477 +			Number id = vf.getInternalId(subj);
  13.478 +			query.filter().and().columnEquals("t", "subj", id);
  13.479 +		}
  13.480 +		if (pred != null) {
  13.481 +			Number id = vf.getInternalId(pred);
  13.482 +			query.filter().and().columnEquals("pu", "id", id);
  13.483 +			if (statements.isPredColumnPresent(id)) {
  13.484 +				query.filter().and().columnEquals("t", "pred", id);
  13.485 +			}
  13.486 +		}
  13.487 +		if (obj != null) {
  13.488 +			Number id = vf.getInternalId(obj);
  13.489 +			query.filter().and().columnEquals("t", "obj", id);
  13.490 +		}
  13.491 +		return query;
  13.492 +	}
  13.493 +
  13.494 +	private String buildWhere(StringBuilder sb, RdbmsResource subj, RdbmsURI pred, RdbmsValue obj,
  13.495 +			RdbmsResource... ctxs)
  13.496 +	{
  13.497 +		sb.append("\nWHERE 1=1");
  13.498 +		if (ctxs != null && ctxs.length > 0) {
  13.499 +			sb.append(" AND (");
  13.500 +			for (int i = 0; i < ctxs.length; i++) {
  13.501 +				sb.append("ctx = ?");
  13.502 +				if (i < ctxs.length - 1) {
  13.503 +					sb.append(" OR ");
  13.504 +				}
  13.505 +			}
  13.506 +			sb.append(")");
  13.507 +		}
  13.508 +		if (subj != null) {
  13.509 +			sb.append(" AND subj = ?");
  13.510 +		}
  13.511 +		if (pred != null) {
  13.512 +			sb.append(" AND pred = ?");
  13.513 +		}
  13.514 +		if (obj != null) {
  13.515 +			sb.append(" AND obj = ?");
  13.516 +		}
  13.517 +		return sb.toString();
  13.518 +	}
  13.519 +
  13.520 +	private void insert(RdbmsStatement st)
  13.521 +		throws RdbmsException, SQLException, InterruptedException
  13.522 +	{
  13.523 +		Number ctx = vf.getInternalId(st.getContext());
  13.524 +		Number subj = vf.getInternalId(st.getSubject());
  13.525 +		Number pred = vf.getPredicateId(st.getPredicate());
  13.526 +		Number obj = vf.getInternalId(st.getObject());
  13.527 +		manager.insert(ctx, subj, pred, obj);
  13.528 +	}
  13.529 +
  13.530 +	private void setCountQuery(PreparedStatement stmt, RdbmsResource... ctxs)
  13.531 +		throws SQLException, RdbmsException
  13.532 +	{
  13.533 +		if (ctxs != null && ctxs.length > 0) {
  13.534 +			for (int i = 0; i < ctxs.length; i++) {
  13.535 +				stmt.setObject(i + 1, vf.getInternalId(ctxs[i]));
  13.536 +			}
  13.537 +		}
  13.538 +	}
  13.539 +
  13.540 +	private void setSelectQuery(PreparedStatement stmt, RdbmsResource subj, RdbmsURI pred, RdbmsValue obj,
  13.541 +			RdbmsResource... ctxs)
  13.542 +		throws SQLException, RdbmsException
  13.543 +	{
  13.544 +		int p = 0;
  13.545 +		if (ctxs != null && ctxs.length > 0) {
  13.546 +			for (int i = 0; i < ctxs.length; i++) {
  13.547 +				if (ctxs[i] == null) {
  13.548 +					stmt.setLong(++p, ValueTable.NIL_ID);
  13.549 +				}
  13.550 +				else {
  13.551 +					stmt.setObject(++p, vf.getInternalId(ctxs[i]));
  13.552 +				}
  13.553 +			}
  13.554 +		}
  13.555 +		if (subj != null) {
  13.556 +			stmt.setObject(++p, vf.getInternalId(subj));
  13.557 +		}
  13.558 +		if (pred != null) {
  13.559 +			stmt.setObject(++p, vf.getInternalId(pred));
  13.560 +		}
  13.561 +		if (obj != null) {
  13.562 +			stmt.setObject(++p, vf.getInternalId(obj));
  13.563 +		}
  13.564 +	}
  13.565 +
  13.566 +}
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/RdbmsValueFactory.java	Thu May 24 13:58:55 2012 +0300
    14.3 @@ -0,0 +1,308 @@
    14.4 +/*
    14.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    14.6 + *
    14.7 + * Licensed under the Aduna BSD-style license.
    14.8 + */
    14.9 +package org.openrdf.sail.rdbms;
   14.10 +
   14.11 +import java.sql.SQLException;
   14.12 +
   14.13 +import info.aduna.concurrent.locks.Lock;
   14.14 +import info.aduna.concurrent.locks.WritePrefReadWriteLockManager;
   14.15 +
   14.16 +import org.openrdf.model.BNode;
   14.17 +import org.openrdf.model.Literal;
   14.18 +import org.openrdf.model.Resource;
   14.19 +import org.openrdf.model.Statement;
   14.20 +import org.openrdf.model.URI;
   14.21 +import org.openrdf.model.Value;
   14.22 +import org.openrdf.model.ValueFactory;
   14.23 +import org.openrdf.model.impl.ValueFactoryBase;
   14.24 +import org.openrdf.sail.rdbms.exceptions.RdbmsException;
   14.25 +import org.openrdf.sail.rdbms.exceptions.RdbmsRuntimeException;
   14.26 +import org.openrdf.sail.rdbms.managers.BNodeManager;
   14.27 +import org.openrdf.sail.rdbms.managers.LiteralManager;
   14.28 +import org.openrdf.sail.rdbms.managers.PredicateManager;
   14.29 +import org.openrdf.sail.rdbms.managers.UriManager;
   14.30 +import org.openrdf.sail.rdbms.model.RdbmsBNode;
   14.31 +import org.openrdf.sail.rdbms.model.RdbmsLiteral;
   14.32 +import org.openrdf.sail.rdbms.model.RdbmsResource;
   14.33 +import org.openrdf.sail.rdbms.model.RdbmsStatement;
   14.34 +import org.openrdf.sail.rdbms.model.RdbmsURI;
   14.35 +import org.openrdf.sail.rdbms.model.RdbmsValue;
   14.36 +import org.openrdf.sail.rdbms.schema.IdSequence;
   14.37 +import org.openrdf.sail.rdbms.schema.LiteralTable;
   14.38 +import org.openrdf.sail.rdbms.schema.ValueTable;
   14.39 +
   14.40 +/**
   14.41 + * Provides basic value creation both for traditional values as well as values
   14.42 + * with an internal id. {@link RdbmsValue}s behaviour similar to the default
   14.43 + * {@link Value} implementation with the addition that they also include an
   14.44 + * internal id and a version associated with that id. The internal ids should
   14.45 + * not be accessed directly, but rather either through this class or the
   14.46 + * corresponding manager class.
   14.47 + * 
   14.48 + * @author James Leigh
   14.49 + * 
   14.50 + */
   14.51 +public class RdbmsValueFactory extends ValueFactoryBase {
   14.52 +
   14.53 +	@Deprecated
   14.54 +	public static final String NIL_LABEL = "nil";
   14.55 +
   14.56 +	private ValueFactory vf;
   14.57 +
   14.58 +	private BNodeManager bnodes;
   14.59 +
   14.60 +	private UriManager uris;
   14.61 +
   14.62 +	private LiteralManager literals;
   14.63 +
   14.64 +	private PredicateManager predicates;
   14.65 +
   14.66 +	private WritePrefReadWriteLockManager lock = new WritePrefReadWriteLockManager();
   14.67 +
   14.68 +	private IdSequence ids;
   14.69 +
   14.70 +	public void setIdSequence(IdSequence ids) {
   14.71 +		this.ids = ids;
   14.72 +	}
   14.73 +
   14.74 +	public void setBNodeManager(BNodeManager bnodes) {
   14.75 +		this.bnodes = bnodes;
   14.76 +	}
   14.77 +
   14.78 +	public void setURIManager(UriManager uris) {
   14.79 +		this.uris = uris;
   14.80 +	}
   14.81 +
   14.82 +	public void setLiteralManager(LiteralManager literals) {
   14.83 +		this.literals = literals;
   14.84 +	}
   14.85 +
   14.86 +	public void setPredicateManager(PredicateManager predicates) {
   14.87 +		this.predicates = predicates;
   14.88 +	}
   14.89 +
   14.90 +	public void setDelegate(ValueFactory vf) {
   14.91 +		this.vf = vf;
   14.92 +	}
   14.93 +
   14.94 +	public void flush()
   14.95 +		throws RdbmsException
   14.96 +	{
   14.97 +		try {
   14.98 +			bnodes.flush();
   14.99 +			uris.flush();
  14.100 +			literals.flush();
  14.101 +		}
  14.102 +		catch (SQLException e) {
  14.103 +			throw new RdbmsException(e);
  14.104 +		}
  14.105 +		catch (InterruptedException e) {
  14.106 +			throw new RdbmsException(e);
  14.107 +		}
  14.108 +	}
  14.109 +
  14.110 +	public RdbmsBNode createBNode(String nodeID) {
  14.111 +		RdbmsBNode resource = bnodes.findInCache(nodeID);
  14.112 +		if (resource == null) {
  14.113 +			try {
  14.114 +				BNode impl = vf.createBNode(nodeID);
  14.115 +				resource = new RdbmsBNode(impl);
  14.116 +				bnodes.cache(resource);
  14.117 +			}
  14.118 +			catch (InterruptedException e) {
  14.119 +				throw new RdbmsRuntimeException(e);
  14.120 +			}
  14.121 +		}
  14.122 +		return resource;
  14.123 +	}
  14.124 +
  14.125 +	public RdbmsLiteral createLiteral(String label) {
  14.126 +		return asRdbmsLiteral(vf.createLiteral(label));
  14.127 +	}
  14.128 +
  14.129 +	public RdbmsLiteral createLiteral(String label, String language) {
  14.130 +		if (LiteralTable.ONLY_INSERT_LABEL)
  14.131 +			return createLiteral(label);
  14.132 +		return asRdbmsLiteral(vf.createLiteral(label, language));
  14.133 +	}
  14.134 +
  14.135 +	public RdbmsLiteral createLiteral(String label, URI datatype) {
  14.136 +		if (LiteralTable.ONLY_INSERT_LABEL)
  14.137 +			return createLiteral(label);
  14.138 +		return asRdbmsLiteral(vf.createLiteral(label, datatype));
  14.139 +	}
  14.140 +
  14.141 +	public RdbmsStatement createStatement(Resource subject, URI predicate, Value object) {
  14.142 +		return createStatement(subject, predicate, object, null);
  14.143 +	}
  14.144 +
  14.145 +	public RdbmsStatement createStatement(Resource subject, URI predicate, Value object, Resource context) {
  14.146 +		RdbmsResource subj = asRdbmsResource(subject);
  14.147 +		RdbmsURI pred = asRdbmsURI(predicate);
  14.148 +		RdbmsValue obj = asRdbmsValue(object);
  14.149 +		RdbmsResource ctx = asRdbmsResource(context);
  14.150 +		return new RdbmsStatement(subj, pred, obj, ctx);
  14.151 +	}
  14.152 +
  14.153 +	public RdbmsURI createURI(String uri) {
  14.154 +		RdbmsURI resource = uris.findInCache(uri);
  14.155 +		if (resource == null) {
  14.156 +			try {
  14.157 +				URI impl = vf.createURI(uri);
  14.158 +				resource = new RdbmsURI(impl);
  14.159 +				uris.cache(resource);
  14.160 +			}
  14.161 +			catch (InterruptedException e) {
  14.162 +				throw new RdbmsRuntimeException(e);
  14.163 +			}
  14.164 +		}
  14.165 +		return resource;
  14.166 +	}
  14.167 +
  14.168 +	public RdbmsURI createURI(String namespace, String localName) {
  14.169 +		return createURI(namespace + localName);
  14.170 +	}
  14.171 +
  14.172 +	public RdbmsResource getRdbmsResource(Number num, String stringValue) {
  14.173 +		assert stringValue != null : "Null stringValue for ID: " + num;
  14.174 +		Number id = ids.idOf(num);
  14.175 +		if (ids.isURI(id))
  14.176 +			return new RdbmsURI(id, uris.getIdVersion(), vf.createURI(stringValue));
  14.177 +		return new RdbmsBNode(id, bnodes.getIdVersion(), vf.createBNode(stringValue));
  14.178 +	}
  14.179 +
  14.180 +	public RdbmsLiteral getRdbmsLiteral(Number num, String label, String language, String datatype) {
  14.181 +		Number id = ids.idOf(num);
  14.182 +		if (datatype == null && language == null)
  14.183 +			return new RdbmsLiteral(id, literals.getIdVersion(), vf.createLiteral(label));
  14.184 +		if (datatype == null)
  14.185 +			return new RdbmsLiteral(id, literals.getIdVersion(), vf.createLiteral(label, language));
  14.186 +		return new RdbmsLiteral(id, literals.getIdVersion(), vf.createLiteral(label, vf.createURI(datatype)));
  14.187 +	}
  14.188 +
  14.189 +	public RdbmsResource asRdbmsResource(Resource node) {
  14.190 +		if (node == null)
  14.191 +			return null;
  14.192 +		if (node instanceof URI)
  14.193 +			return asRdbmsURI((URI)node);
  14.194 +		if (node instanceof RdbmsBNode) {
  14.195 +			try {
  14.196 +				bnodes.cache((RdbmsBNode)node);
  14.197 +				return (RdbmsBNode)node;
  14.198 +			}
  14.199 +			catch (InterruptedException e) {
  14.200 +				throw new RdbmsRuntimeException(e);
  14.201 +			}
  14.202 +		}
  14.203 +		return createBNode(((BNode)node).getID());
  14.204 +	}
  14.205 +
  14.206 +	public RdbmsURI asRdbmsURI(URI uri) {
  14.207 +		if (uri == null)
  14.208 +			return null;
  14.209 +		if (uri instanceof RdbmsURI) {
  14.210 +			try {
  14.211 +				uris.cache((RdbmsURI)uri);
  14.212 +				return (RdbmsURI)uri;
  14.213 +			}
  14.214 +			catch (InterruptedException e) {
  14.215 +				throw new RdbmsRuntimeException(e);
  14.216 +			}
  14.217 +		}
  14.218 +		return createURI(uri.stringValue());
  14.219 +	}
  14.220 +
  14.221 +	public RdbmsValue asRdbmsValue(Value value) {
  14.222 +		if (value == null)
  14.223 +			return null;
  14.224 +		if (value instanceof Literal)
  14.225 +			return asRdbmsLiteral((Literal)value);
  14.226 +		return asRdbmsResource((Resource)value);
  14.227 +	}
  14.228 +
  14.229 +	public RdbmsLiteral asRdbmsLiteral(Literal literal) {
  14.230 +		try {
  14.231 +			if (literal instanceof RdbmsLiteral) {
  14.232 +				literals.cache((RdbmsLiteral)literal);
  14.233 +				return (RdbmsLiteral)literal;
  14.234 +			}
  14.235 +			RdbmsLiteral lit = literals.findInCache(literal);
  14.236 +			if (lit == null) {
  14.237 +				lit = new RdbmsLiteral(literal);
  14.238 +				literals.cache(lit);
  14.239 +			}
  14.240 +			return lit;
  14.241 +		}
  14.242 +		catch (InterruptedException e) {
  14.243 +			throw new RdbmsRuntimeException(e);
  14.244 +		}
  14.245 +	}
  14.246 +
  14.247 +	public RdbmsResource[] asRdbmsResource(Resource... contexts) {
  14.248 +		RdbmsResource[] ctxs = new RdbmsResource[contexts.length];
  14.249 +		for (int i = 0; i < ctxs.length; i++) {
  14.250 +			ctxs[i] = asRdbmsResource(contexts[i]);
  14.251 +		}
  14.252 +		return ctxs;
  14.253 +	}
  14.254 +
  14.255 +	public RdbmsStatement asRdbmsStatement(Statement stmt) {
  14.256 +		if (stmt instanceof RdbmsStatement)
  14.257 +			return (RdbmsStatement)stmt;
  14.258 +		Resource s = stmt.getSubject();
  14.259 +		URI p = stmt.getPredicate();
  14.260 +		Value o = stmt.getObject();
  14.261 +		Resource c = stmt.getContext();
  14.262 +		return createStatement(s, p, o, c);
  14.263 +	}
  14.264 +
  14.265 +	public Number getInternalId(Value r)
  14.266 +		throws RdbmsException
  14.267 +	{
  14.268 +		try {
  14.269 +			if (r == null)
  14.270 +				return ValueTable.NIL_ID;
  14.271 +			RdbmsValue value = asRdbmsValue(r);
  14.272 +			if (value instanceof RdbmsURI)
  14.273 +				return uris.getInternalId((RdbmsURI)value);
  14.274 +			if (value instanceof RdbmsBNode)
  14.275 +				return bnodes.getInternalId((RdbmsBNode)value);
  14.276 +			return literals.getInternalId((RdbmsLiteral)value);
  14.277 +		}
  14.278 +		catch (SQLException e) {
  14.279 +			throw new RdbmsException(e);
  14.280 +		}
  14.281 +		catch (InterruptedException e) {
  14.282 +			throw new RdbmsRuntimeException(e);
  14.283 +		}
  14.284 +	}
  14.285 +
  14.286 +	public Number getPredicateId(RdbmsURI predicate)
  14.287 +		throws RdbmsException
  14.288 +	{
  14.289 +		try {
  14.290 +			return predicates.getIdOfPredicate(predicate);
  14.291 +		}
  14.292 +		catch (SQLException e) {
  14.293 +			throw new RdbmsException(e);
  14.294 +		}
  14.295 +		catch (InterruptedException e) {
  14.296 +			throw new RdbmsRuntimeException(e);
  14.297 +		}
  14.298 +	}
  14.299 +
  14.300 +	public Lock getIdReadLock() throws InterruptedException {
  14.301 +		return lock.getReadLock();
  14.302 +	}
  14.303 +
  14.304 +	public Lock tryIdWriteLock() {
  14.305 +		return lock.tryWriteLock();
  14.306 +	}
  14.307 +
  14.308 +	public Lock getIdWriteLock() throws InterruptedException {
  14.309 +		return lock.getWriteLock();
  14.310 +	}
  14.311 +}
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/BNodeColumn.java	Thu May 24 13:58:55 2012 +0300
    15.3 @@ -0,0 +1,34 @@
    15.4 +/*
    15.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    15.6 + *
    15.7 + * Licensed under the Aduna BSD-style license.
    15.8 + */
    15.9 +package org.openrdf.sail.rdbms.algebra;
   15.10 +
   15.11 +import org.openrdf.query.algebra.Var;
   15.12 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   15.13 +import org.openrdf.sail.rdbms.algebra.base.ValueColumnBase;
   15.14 +
   15.15 +/**
   15.16 + * Represents the BNode value of a variable.
   15.17 + * 
   15.18 + * @author James Leigh
   15.19 + * 
   15.20 + */
   15.21 +public class BNodeColumn extends ValueColumnBase {
   15.22 +
   15.23 +	public BNodeColumn(ColumnVar var) {
   15.24 +		super(var);
   15.25 +	}
   15.26 +
   15.27 +	public BNodeColumn(Var var) {
   15.28 +		super(var);
   15.29 +	}
   15.30 +
   15.31 +	@Override
   15.32 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
   15.33 +		throws X
   15.34 +	{
   15.35 +		visitor.meet(this);
   15.36 +	}
   15.37 +}
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/ColumnVar.java	Thu May 24 13:58:55 2012 +0300
    16.3 @@ -0,0 +1,236 @@
    16.4 +/*
    16.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    16.6 + *
    16.7 + * Licensed under the Aduna BSD-style license.
    16.8 + */
    16.9 +package org.openrdf.sail.rdbms.algebra;
   16.10 +
   16.11 +import org.openrdf.model.Resource;
   16.12 +import org.openrdf.model.URI;
   16.13 +import org.openrdf.model.Value;
   16.14 +import org.openrdf.query.algebra.Var;
   16.15 +import org.openrdf.sail.rdbms.model.RdbmsResource;
   16.16 +import org.openrdf.sail.rdbms.model.RdbmsURI;
   16.17 +import org.openrdf.sail.rdbms.schema.ValueTypes;
   16.18 +
   16.19 +/**
   16.20 + * Represents a variable in an SQL expression.
   16.21 + * 
   16.22 + * @author James Leigh
   16.23 + * 
   16.24 + */
   16.25 +public class ColumnVar implements Cloneable {
   16.26 +
   16.27 +	private int index;
   16.28 +
   16.29 +	private boolean anonymous;
   16.30 +
   16.31 +	private boolean hidden;
   16.32 +
   16.33 +	private boolean implied;
   16.34 +
   16.35 +	private String name;
   16.36 +
   16.37 +	private Value value;
   16.38 +
   16.39 +	private String alias;
   16.40 +
   16.41 +	private String column;
   16.42 +
   16.43 +	private boolean nullable;
   16.44 +
   16.45 +	private ValueTypes types;
   16.46 +
   16.47 +	private ColumnVar() {
   16.48 +	}
   16.49 +
   16.50 +	public static ColumnVar createSubj(String alias, Var v, Resource resource) {
   16.51 +		ColumnVar var = new ColumnVar();
   16.52 +		var.alias = alias;
   16.53 +		var.column = "subj";
   16.54 +		var.name = v.getName();
   16.55 +		var.anonymous = v.isAnonymous();
   16.56 +		var.value = resource;
   16.57 +		var.types = ValueTypes.RESOURCE;
   16.58 +		if (resource instanceof RdbmsURI) {
   16.59 +			var.types = ValueTypes.URI;
   16.60 +		}
   16.61 +		return var;
   16.62 +	}
   16.63 +
   16.64 +	public static ColumnVar createPred(String alias, Var v, URI uri, boolean implied) {
   16.65 +		ColumnVar var = createSubj(alias, v, uri);
   16.66 +		var.column = "pred";
   16.67 +		var.implied = uri != null && implied;
   16.68 +		var.types = ValueTypes.URI;
   16.69 +		return var;
   16.70 +	}
   16.71 +
   16.72 +	public static ColumnVar createObj(String alias, Var v, Value value) {
   16.73 +		ColumnVar var = new ColumnVar();
   16.74 +		var.alias = alias;
   16.75 +		var.column = "obj";
   16.76 +		var.name = v.getName();
   16.77 +		var.anonymous = v.isAnonymous();
   16.78 +		var.value = value;
   16.79 +		var.types = ValueTypes.UNKNOWN;
   16.80 +		if (value instanceof RdbmsURI) {
   16.81 +			var.types = ValueTypes.URI;
   16.82 +		}
   16.83 +		else if (value instanceof RdbmsResource) {
   16.84 +			var.types = ValueTypes.RESOURCE;
   16.85 +		}
   16.86 +		return var;
   16.87 +	}
   16.88 +
   16.89 +	public static ColumnVar createCtx(String alias, Var v, Resource resource) {
   16.90 +		ColumnVar var = new ColumnVar();
   16.91 +		var.alias = alias;
   16.92 +		var.column = "ctx";
   16.93 +		if (v == null) {
   16.94 +			var.name = "__ctx" + Integer.toHexString(System.identityHashCode(var));
   16.95 +			var.anonymous = true;
   16.96 +			var.hidden = true;
   16.97 +		}
   16.98 +		else {
   16.99 +			var.name = v.getName();
  16.100 +			var.anonymous = v.isAnonymous();
  16.101 +		}
  16.102 +		var.value = resource;
  16.103 +		var.types = ValueTypes.RESOURCE;
  16.104 +		if (resource instanceof RdbmsURI) {
  16.105 +			var.types = ValueTypes.URI;
  16.106 +		}
  16.107 +		return var;
  16.108 +	}
  16.109 +
  16.110 +	public ValueTypes getTypes() {
  16.111 +		return types;
  16.112 +	}
  16.113 +
  16.114 +	public void setTypes(ValueTypes types) {
  16.115 +		this.types = types;
  16.116 +	}
  16.117 +
  16.118 +	public boolean isAnonymous() {
  16.119 +		return anonymous;
  16.120 +	}
  16.121 +
  16.122 +	public boolean isHidden() {
  16.123 +		return hidden;
  16.124 +	}
  16.125 +
  16.126 +	public boolean isHiddenOrConstant() {
  16.127 +		return hidden || value != null;
  16.128 +	}
  16.129 +
  16.130 +	public boolean isImplied() {
  16.131 +		return implied;
  16.132 +	}
  16.133 +
  16.134 +	public boolean isResource() {
  16.135 +		return !types.isLiterals();
  16.136 +	}
  16.137 +
  16.138 +	public boolean isURI() {
  16.139 +		return !types.isLiterals() && !types.isBNodes();
  16.140 +	}
  16.141 +
  16.142 +	public boolean isNullable() {
  16.143 +		return nullable;
  16.144 +	}
  16.145 +
  16.146 +	public int getIndex() {
  16.147 +		return index;
  16.148 +	}
  16.149 +
  16.150 +	public void setIndex(int index) {
  16.151 +		this.index = index;
  16.152 +	}
  16.153 +
  16.154 +	public String getName() {
  16.155 +		return name;
  16.156 +	}
  16.157 +
  16.158 +	public Value getValue() {
  16.159 +		return value;
  16.160 +	}
  16.161 +
  16.162 +	public void setValue(Value value) {
  16.163 +		this.value = value;
  16.164 +		if (value == null) {
  16.165 +			implied = false;
  16.166 +		}
  16.167 +	}
  16.168 +
  16.169 +	public String getColumn() {
  16.170 +		return column;
  16.171 +	}
  16.172 +
  16.173 +	public boolean isPredicate() {
  16.174 +		return "pred".equals(column);
  16.175 +	}
  16.176 +
  16.177 +	public String getAlias() {
  16.178 +		return alias;
  16.179 +	}
  16.180 +
  16.181 +	public ColumnVar as(String name) {
  16.182 +		try {
  16.183 +			ColumnVar clone = (ColumnVar)super.clone();
  16.184 +			clone.name = name;
  16.185 +			return clone;
  16.186 +		}
  16.187 +		catch (CloneNotSupportedException e) {
  16.188 +			throw new AssertionError(e);
  16.189 +		}
  16.190 +	}
  16.191 +
  16.192 +	public ColumnVar as(String alias, String column) {
  16.193 +		try {
  16.194 +			ColumnVar clone = (ColumnVar)super.clone();
  16.195 +			clone.alias = alias;
  16.196 +			clone.column = column;
  16.197 +			clone.nullable = true;
  16.198 +			return clone;
  16.199 +		}
  16.200 +		catch (CloneNotSupportedException e) {
  16.201 +			throw new AssertionError(e);
  16.202 +		}
  16.203 +	}
  16.204 +
  16.205 +	@Override
  16.206 +	public boolean equals(Object other) {
  16.207 +		if (other instanceof ColumnVar) {
  16.208 +			return name.equals(((ColumnVar)other).name);
  16.209 +		}
  16.210 +
  16.211 +		return false;
  16.212 +	}
  16.213 +
  16.214 +	@Override
  16.215 +	public int hashCode() {
  16.216 +		return name.hashCode();
  16.217 +	}
  16.218 +
  16.219 +	@Override
  16.220 +	public String toString() {
  16.221 +		StringBuilder sb = new StringBuilder(128);
  16.222 +
  16.223 +		sb.append(alias).append(".").append(column);
  16.224 +
  16.225 +		sb.append(" (name=").append(name);
  16.226 +
  16.227 +		if (value != null) {
  16.228 +			sb.append(", value=").append(value.toString());
  16.229 +		}
  16.230 +
  16.231 +		sb.append(")");
  16.232 +		if (index > 0) {
  16.233 +			sb.append("#").append(index);
  16.234 +		}
  16.235 +
  16.236 +		return sb.toString();
  16.237 +	}
  16.238 +
  16.239 +}
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/DatatypeColumn.java	Thu May 24 13:58:55 2012 +0300
    17.3 @@ -0,0 +1,35 @@
    17.4 +/*
    17.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    17.6 + *
    17.7 + * Licensed under the Aduna BSD-style license.
    17.8 + */
    17.9 +package org.openrdf.sail.rdbms.algebra;
   17.10 +
   17.11 +import org.openrdf.query.algebra.Var;
   17.12 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   17.13 +import org.openrdf.sail.rdbms.algebra.base.ValueColumnBase;
   17.14 +
   17.15 +/**
   17.16 + * Represents a variable's datatype value in an SQL expression.
   17.17 + * 
   17.18 + * @author James Leigh
   17.19 + * 
   17.20 + */
   17.21 +public class DatatypeColumn extends ValueColumnBase {
   17.22 +
   17.23 +	public DatatypeColumn(Var var) {
   17.24 +		super(var);
   17.25 +	}
   17.26 +
   17.27 +	public DatatypeColumn(ColumnVar var) {
   17.28 +		super(var);
   17.29 +	}
   17.30 +
   17.31 +	@Override
   17.32 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
   17.33 +		throws X
   17.34 +	{
   17.35 +		visitor.meet(this);
   17.36 +	}
   17.37 +
   17.38 +}
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/DateTimeColumn.java	Thu May 24 13:58:55 2012 +0300
    18.3 @@ -0,0 +1,31 @@
    18.4 +/*
    18.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    18.6 + *
    18.7 + * Licensed under the Aduna BSD-style license.
    18.8 + */
    18.9 +package org.openrdf.sail.rdbms.algebra;
   18.10 +
   18.11 +import org.openrdf.query.algebra.Var;
   18.12 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   18.13 +import org.openrdf.sail.rdbms.algebra.base.ValueColumnBase;
   18.14 +
   18.15 +/**
   18.16 + * Represents a variable's time value in an SQL expression.
   18.17 + * 
   18.18 + * @author James Leigh
   18.19 + * 
   18.20 + */
   18.21 +public class DateTimeColumn extends ValueColumnBase {
   18.22 +
   18.23 +	public DateTimeColumn(Var var) {
   18.24 +		super(var);
   18.25 +	}
   18.26 +
   18.27 +	@Override
   18.28 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
   18.29 +		throws X
   18.30 +	{
   18.31 +		visitor.meet(this);
   18.32 +	}
   18.33 +
   18.34 +}
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/DoubleValue.java	Thu May 24 13:58:55 2012 +0300
    19.3 @@ -0,0 +1,29 @@
    19.4 +/*
    19.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    19.6 + *
    19.7 + * Licensed under the Aduna BSD-style license.
    19.8 + */
    19.9 +package org.openrdf.sail.rdbms.algebra;
   19.10 +
   19.11 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   19.12 +import org.openrdf.sail.rdbms.algebra.base.SqlConstant;
   19.13 +
   19.14 +/**
   19.15 + * A static number in an SQL expression.
   19.16 + * 
   19.17 + * @author James Leigh
   19.18 + * 
   19.19 + */
   19.20 +public class DoubleValue extends SqlConstant<Double> {
   19.21 +
   19.22 +	public DoubleValue(Double value) {
   19.23 +		super(value);
   19.24 +	}
   19.25 +
   19.26 +	@Override
   19.27 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
   19.28 +		throws X
   19.29 +	{
   19.30 +		visitor.meet(this);
   19.31 +	}
   19.32 +}
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/FalseValue.java	Thu May 24 13:58:55 2012 +0300
    20.3 @@ -0,0 +1,29 @@
    20.4 +/*
    20.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    20.6 + *
    20.7 + * Licensed under the Aduna BSD-style license.
    20.8 + */
    20.9 +package org.openrdf.sail.rdbms.algebra;
   20.10 +
   20.11 +import org.openrdf.sail.rdbms.algebra.base.BooleanValue;
   20.12 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   20.13 +
   20.14 +/**
   20.15 + * Represents the value false in an SQL expression.
   20.16 + * 
   20.17 + * @author James Leigh
   20.18 + * 
   20.19 + */
   20.20 +public class FalseValue extends BooleanValue {
   20.21 +
   20.22 +	public FalseValue() {
   20.23 +		super(false);
   20.24 +	}
   20.25 +
   20.26 +	@Override
   20.27 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
   20.28 +		throws X
   20.29 +	{
   20.30 +		visitor.meet(this);
   20.31 +	}
   20.32 +}
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/HashColumn.java	Thu May 24 13:58:55 2012 +0300
    21.3 @@ -0,0 +1,34 @@
    21.4 +/*
    21.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    21.6 + *
    21.7 + * Licensed under the Aduna BSD-style license.
    21.8 + */
    21.9 +package org.openrdf.sail.rdbms.algebra;
   21.10 +
   21.11 +import org.openrdf.query.algebra.Var;
   21.12 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   21.13 +import org.openrdf.sail.rdbms.algebra.base.ValueColumnBase;
   21.14 +
   21.15 +/**
   21.16 + * Represents the Hash value of a variable.
   21.17 + * 
   21.18 + * @author James Leigh
   21.19 + * 
   21.20 + */
   21.21 +public class HashColumn extends ValueColumnBase {
   21.22 +
   21.23 +	public HashColumn(ColumnVar var) {
   21.24 +		super(var);
   21.25 +	}
   21.26 +
   21.27 +	public HashColumn(Var var) {
   21.28 +		super(var);
   21.29 +	}
   21.30 +
   21.31 +	@Override
   21.32 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
   21.33 +		throws X
   21.34 +	{
   21.35 +		visitor.meet(this);
   21.36 +	}
   21.37 +}
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/IdColumn.java	Thu May 24 13:58:55 2012 +0300
    22.3 @@ -0,0 +1,99 @@
    22.4 +/*
    22.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    22.6 + *
    22.7 + * Licensed under the Aduna BSD-style license.
    22.8 + */
    22.9 +package org.openrdf.sail.rdbms.algebra;
   22.10 +
   22.11 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelNodeBase;
   22.12 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   22.13 +import org.openrdf.sail.rdbms.algebra.base.SqlExpr;
   22.14 +
   22.15 +/**
   22.16 + * A particular column in an SQL expression.
   22.17 + * 
   22.18 + * @author James Leigh
   22.19 + * 
   22.20 + */
   22.21 +public class IdColumn extends RdbmsQueryModelNodeBase implements SqlExpr {
   22.22 +
   22.23 +	private String alias;
   22.24 +
   22.25 +	private String column;
   22.26 +
   22.27 +	public IdColumn(String alias) {
   22.28 +		super();
   22.29 +		this.alias = alias;
   22.30 +		this.column = "id";
   22.31 +	}
   22.32 +
   22.33 +	public IdColumn(ColumnVar var) {
   22.34 +		super();
   22.35 +		this.alias = var.getAlias();
   22.36 +		this.column = var.getColumn();
   22.37 +	}
   22.38 +
   22.39 +	public IdColumn(String alias, String column) {
   22.40 +		super();
   22.41 +		this.alias = alias;
   22.42 +		this.column = column;
   22.43 +	}
   22.44 +
   22.45 +	public String getAlias() {
   22.46 +		return alias;
   22.47 +	}
   22.48 +
   22.49 +	public String getColumn() {
   22.50 +		return column;
   22.51 +	}
   22.52 +
   22.53 +	@Override
   22.54 +	public String getSignature() {
   22.55 +		return super.getSignature() + " " + alias + "." + column;
   22.56 +	}
   22.57 +
   22.58 +	@Override
   22.59 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
   22.60 +		throws X
   22.61 +	{
   22.62 +		visitor.meet(this);
   22.63 +	}
   22.64 +
   22.65 +	@Override
   22.66 +	public IdColumn clone() {
   22.67 +		return (IdColumn)super.clone();
   22.68 +	}
   22.69 +
   22.70 +	@Override
   22.71 +	public int hashCode() {
   22.72 +		final int prime = 31;
   22.73 +		int result = 1;
   22.74 +		result = prime * result + ((alias == null) ? 0 : alias.hashCode());
   22.75 +		result = prime * result + ((column == null) ? 0 : column.hashCode());
   22.76 +		return result;
   22.77 +	}
   22.78 +
   22.79 +	@Override
   22.80 +	public boolean equals(Object obj) {
   22.81 +		if (this == obj)
   22.82 +			return true;
   22.83 +		if (obj == null)
   22.84 +			return false;
   22.85 +		if (getClass() != obj.getClass())
   22.86 +			return false;
   22.87 +		final IdColumn other = (IdColumn)obj;
   22.88 +		if (alias == null) {
   22.89 +			if (other.alias != null)
   22.90 +				return false;
   22.91 +		}
   22.92 +		else if (!alias.equals(other.alias))
   22.93 +			return false;
   22.94 +		if (column == null) {
   22.95 +			if (other.column != null)
   22.96 +				return false;
   22.97 +		}
   22.98 +		else if (!column.equals(other.column))
   22.99 +			return false;
  22.100 +		return true;
  22.101 +	}
  22.102 +}
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/JoinItem.java	Thu May 24 13:58:55 2012 +0300
    23.3 @@ -0,0 +1,93 @@
    23.4 +/*
    23.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    23.6 + *
    23.7 + * Licensed under the Aduna BSD-style license.
    23.8 + */
    23.9 +package org.openrdf.sail.rdbms.algebra;
   23.10 +
   23.11 +import java.util.ArrayList;
   23.12 +import java.util.List;
   23.13 +
   23.14 +import org.openrdf.sail.rdbms.algebra.base.FromItem;
   23.15 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   23.16 +
   23.17 +/**
   23.18 + * An SQL join.
   23.19 + * 
   23.20 + * @author James Leigh
   23.21 + * 
   23.22 + */
   23.23 +public class JoinItem extends FromItem {
   23.24 +
   23.25 +	private String tableName;
   23.26 +
   23.27 +	private Number predId;
   23.28 +
   23.29 +	private List<ColumnVar> vars = new ArrayList<ColumnVar>();
   23.30 +
   23.31 +	public JoinItem(String alias, String tableName, Number predId) {
   23.32 +		super(alias);
   23.33 +		this.tableName = tableName;
   23.34 +		this.predId = predId;
   23.35 +	}
   23.36 +
   23.37 +	public JoinItem(String alias, String tableName) {
   23.38 +		super(alias);
   23.39 +		this.tableName = tableName;
   23.40 +		this.predId = 0;
   23.41 +	}
   23.42 +
   23.43 +	public String getTableName() {
   23.44 +		return tableName;
   23.45 +	}
   23.46 +
   23.47 +	public Number getPredId() {
   23.48 +		return predId;
   23.49 +	}
   23.50 +
   23.51 +	public void addVar(ColumnVar var) {
   23.52 +		this.vars.add(var);
   23.53 +	}
   23.54 +
   23.55 +	@Override
   23.56 +	public ColumnVar getVarForChildren(String name) {
   23.57 +		for (ColumnVar var : vars) {
   23.58 +			if (var.getName().equals(name))
   23.59 +				return var;
   23.60 +		}
   23.61 +		return super.getVarForChildren(name);
   23.62 +	}
   23.63 +
   23.64 +	@Override
   23.65 +	public List<ColumnVar> appendVars(List<ColumnVar> vars) {
   23.66 +		vars.addAll(this.vars);
   23.67 +		return super.appendVars(vars);
   23.68 +	}
   23.69 +
   23.70 +	@Override
   23.71 +	public String getSignature() {
   23.72 +		StringBuilder sb = new StringBuilder();
   23.73 +		if (isLeft()) {
   23.74 +			sb.append("LEFT ");
   23.75 +		}
   23.76 +		sb.append(super.getSignature());
   23.77 +		sb.append(" ").append(tableName);
   23.78 +		sb.append(" ").append(getAlias());
   23.79 +		return sb.toString();
   23.80 +	}
   23.81 +
   23.82 +	@Override
   23.83 +	public JoinItem clone() {
   23.84 +		JoinItem clone = (JoinItem)super.clone();
   23.85 +		clone.vars = new ArrayList<ColumnVar>(vars);
   23.86 +		return clone;
   23.87 +	}
   23.88 +
   23.89 +	@Override
   23.90 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
   23.91 +		throws X
   23.92 +	{
   23.93 +		visitor.meet(this);
   23.94 +	}
   23.95 +
   23.96 +}
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/LabelColumn.java	Thu May 24 13:58:55 2012 +0300
    24.3 @@ -0,0 +1,35 @@
    24.4 +/*
    24.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    24.6 + *
    24.7 + * Licensed under the Aduna BSD-style license.
    24.8 + */
    24.9 +package org.openrdf.sail.rdbms.algebra;
   24.10 +
   24.11 +import org.openrdf.query.algebra.Var;
   24.12 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   24.13 +import org.openrdf.sail.rdbms.algebra.base.ValueColumnBase;
   24.14 +
   24.15 +/**
   24.16 + * Represents a variable's label value in an SQL expression.
   24.17 + * 
   24.18 + * @author James Leigh
   24.19 + * 
   24.20 + */
   24.21 +public class LabelColumn extends ValueColumnBase {
   24.22 +
   24.23 +	public LabelColumn(Var var) {
   24.24 +		super(var);
   24.25 +	}
   24.26 +
   24.27 +	public LabelColumn(ColumnVar var) {
   24.28 +		super(var);
   24.29 +	}
   24.30 +
   24.31 +	@Override
   24.32 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
   24.33 +		throws X
   24.34 +	{
   24.35 +		visitor.meet(this);
   24.36 +	}
   24.37 +
   24.38 +}
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/LanguageColumn.java	Thu May 24 13:58:55 2012 +0300
    25.3 @@ -0,0 +1,35 @@
    25.4 +/*
    25.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    25.6 + *
    25.7 + * Licensed under the Aduna BSD-style license.
    25.8 + */
    25.9 +package org.openrdf.sail.rdbms.algebra;
   25.10 +
   25.11 +import org.openrdf.query.algebra.Var;
   25.12 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   25.13 +import org.openrdf.sail.rdbms.algebra.base.ValueColumnBase;
   25.14 +
   25.15 +/**
   25.16 + * Represents a variables language value in an SQL expression.
   25.17 + * 
   25.18 + * @author James Leigh
   25.19 + * 
   25.20 + */
   25.21 +public class LanguageColumn extends ValueColumnBase {
   25.22 +
   25.23 +	public LanguageColumn(Var var) {
   25.24 +		super(var);
   25.25 +	}
   25.26 +
   25.27 +	public LanguageColumn(ColumnVar var) {
   25.28 +		super(var);
   25.29 +	}
   25.30 +
   25.31 +	@Override
   25.32 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
   25.33 +		throws X
   25.34 +	{
   25.35 +		visitor.meet(this);
   25.36 +	}
   25.37 +
   25.38 +}
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/LongLabelColumn.java	Thu May 24 13:58:55 2012 +0300
    26.3 @@ -0,0 +1,35 @@
    26.4 +/*
    26.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    26.6 + *
    26.7 + * Licensed under the Aduna BSD-style license.
    26.8 + */
    26.9 +package org.openrdf.sail.rdbms.algebra;
   26.10 +
   26.11 +import org.openrdf.query.algebra.Var;
   26.12 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   26.13 +import org.openrdf.sail.rdbms.algebra.base.ValueColumnBase;
   26.14 +
   26.15 +/**
   26.16 + * Represents a variable's long label value in an SQL expression.
   26.17 + * 
   26.18 + * @author James Leigh
   26.19 + * 
   26.20 + */
   26.21 +public class LongLabelColumn extends ValueColumnBase {
   26.22 +
   26.23 +	public LongLabelColumn(Var var) {
   26.24 +		super(var);
   26.25 +	}
   26.26 +
   26.27 +	public LongLabelColumn(ColumnVar var) {
   26.28 +		super(var);
   26.29 +	}
   26.30 +
   26.31 +	@Override
   26.32 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
   26.33 +		throws X
   26.34 +	{
   26.35 +		visitor.meet(this);
   26.36 +	}
   26.37 +
   26.38 +}
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/LongURIColumn.java	Thu May 24 13:58:55 2012 +0300
    27.3 @@ -0,0 +1,35 @@
    27.4 +/*
    27.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    27.6 + *
    27.7 + * Licensed under the Aduna BSD-style license.
    27.8 + */
    27.9 +package org.openrdf.sail.rdbms.algebra;
   27.10 +
   27.11 +import org.openrdf.query.algebra.Var;
   27.12 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   27.13 +import org.openrdf.sail.rdbms.algebra.base.ValueColumnBase;
   27.14 +
   27.15 +/**
   27.16 + * Represents a variable's Long URI value in an SQL expression.
   27.17 + * 
   27.18 + * @author James Leigh
   27.19 + * 
   27.20 + */
   27.21 +public class LongURIColumn extends ValueColumnBase {
   27.22 +
   27.23 +	public LongURIColumn(Var var) {
   27.24 +		super(var);
   27.25 +	}
   27.26 +
   27.27 +	public LongURIColumn(ColumnVar var) {
   27.28 +		super(var);
   27.29 +	}
   27.30 +
   27.31 +	@Override
   27.32 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
   27.33 +		throws X
   27.34 +	{
   27.35 +		visitor.meet(this);
   27.36 +	}
   27.37 +
   27.38 +}
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/NumberValue.java	Thu May 24 13:58:55 2012 +0300
    28.3 @@ -0,0 +1,29 @@
    28.4 +/*
    28.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    28.6 + *
    28.7 + * Licensed under the Aduna BSD-style license.
    28.8 + */
    28.9 +package org.openrdf.sail.rdbms.algebra;
   28.10 +
   28.11 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   28.12 +import org.openrdf.sail.rdbms.algebra.base.SqlConstant;
   28.13 +
   28.14 +/**
   28.15 + * A static long value in an SQL expression.
   28.16 + * 
   28.17 + * @author James Leigh
   28.18 + * 
   28.19 + */
   28.20 +public class NumberValue extends SqlConstant<Number> {
   28.21 +
   28.22 +	public NumberValue(Number value) {
   28.23 +		super(value);
   28.24 +	}
   28.25 +
   28.26 +	@Override
   28.27 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
   28.28 +		throws X
   28.29 +	{
   28.30 +		visitor.meet(this);
   28.31 +	}
   28.32 +}
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/NumericColumn.java	Thu May 24 13:58:55 2012 +0300
    29.3 @@ -0,0 +1,31 @@
    29.4 +/*
    29.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    29.6 + *
    29.7 + * Licensed under the Aduna BSD-style license.
    29.8 + */
    29.9 +package org.openrdf.sail.rdbms.algebra;
   29.10 +
   29.11 +import org.openrdf.query.algebra.Var;
   29.12 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   29.13 +import org.openrdf.sail.rdbms.algebra.base.ValueColumnBase;
   29.14 +
   29.15 +/**
   29.16 + * Represents a variable's numeric value in an SQL expression.
   29.17 + * 
   29.18 + * @author James Leigh
   29.19 + * 
   29.20 + */
   29.21 +public class NumericColumn extends ValueColumnBase {
   29.22 +
   29.23 +	public NumericColumn(Var var) {
   29.24 +		super(var);
   29.25 +	}
   29.26 +
   29.27 +	@Override
   29.28 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
   29.29 +		throws X
   29.30 +	{
   29.31 +		visitor.meet(this);
   29.32 +	}
   29.33 +
   29.34 +}
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/RefIdColumn.java	Thu May 24 13:58:55 2012 +0300
    30.3 @@ -0,0 +1,39 @@
    30.4 +/*
    30.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    30.6 + *
    30.7 + * Licensed under the Aduna BSD-style license.
    30.8 + */
    30.9 +package org.openrdf.sail.rdbms.algebra;
   30.10 +
   30.11 +import org.openrdf.query.algebra.Var;
   30.12 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   30.13 +import org.openrdf.sail.rdbms.algebra.base.ValueColumnBase;
   30.14 +
   30.15 +/**
   30.16 + * Represents a variable's internal id value in an SQL expression.
   30.17 + * 
   30.18 + * @author James Leigh
   30.19 + * 
   30.20 + */
   30.21 +public class RefIdColumn extends ValueColumnBase {
   30.22 +
   30.23 +	public RefIdColumn(ColumnVar var) {
   30.24 +		super(var);
   30.25 +	}
   30.26 +
   30.27 +	public RefIdColumn(Var var) {
   30.28 +		super(var);
   30.29 +	}
   30.30 +
   30.31 +	@Override
   30.32 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
   30.33 +		throws X
   30.34 +	{
   30.35 +		visitor.meet(this);
   30.36 +	}
   30.37 +
   30.38 +	@Override
   30.39 +	public RefIdColumn clone() {
   30.40 +		return (RefIdColumn)super.clone();
   30.41 +	}
   30.42 +}
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/SelectProjection.java	Thu May 24 13:58:55 2012 +0300
    31.3 @@ -0,0 +1,176 @@
    31.4 +/*
    31.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    31.6 + *
    31.7 + * Licensed under the Aduna BSD-style license.
    31.8 + */
    31.9 +package org.openrdf.sail.rdbms.algebra;
   31.10 +
   31.11 +import org.openrdf.query.algebra.QueryModelNode;
   31.12 +import org.openrdf.query.algebra.QueryModelVisitor;
   31.13 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelNodeBase;
   31.14 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   31.15 +import org.openrdf.sail.rdbms.algebra.base.SqlExpr;
   31.16 +
   31.17 +/**
   31.18 + * A collection of SQL expressions that form an RDF value binding.
   31.19 + * 
   31.20 + * @author James Leigh
   31.21 + * 
   31.22 + */
   31.23 +public class SelectProjection extends RdbmsQueryModelNodeBase {
   31.24 +
   31.25 +	private ColumnVar var;
   31.26 +
   31.27 +	private RefIdColumn id;
   31.28 +
   31.29 +	private SqlExpr stringValue;
   31.30 +
   31.31 +	private SqlExpr datatype;
   31.32 +
   31.33 +	private SqlExpr language;
   31.34 +
   31.35 +	public ColumnVar getVar() {
   31.36 +		return var;
   31.37 +	}
   31.38 +
   31.39 +	public void setVar(ColumnVar var) {
   31.40 +		this.var = var;
   31.41 +	}
   31.42 +
   31.43 +	public RefIdColumn getId() {
   31.44 +		return id;
   31.45 +	}
   31.46 +
   31.47 +	public void setId(RefIdColumn id) {
   31.48 +		this.id = id;
   31.49 +		id.setParentNode(this);
   31.50 +	}
   31.51 +
   31.52 +	public SqlExpr getStringValue() {
   31.53 +		return stringValue;
   31.54 +	}
   31.55 +
   31.56 +	public void setStringValue(SqlExpr stringValue) {
   31.57 +		this.stringValue = stringValue;
   31.58 +		stringValue.setParentNode(this);
   31.59 +	}
   31.60 +
   31.61 +	public SqlExpr getDatatype() {
   31.62 +		return datatype;
   31.63 +	}
   31.64 +
   31.65 +	public void setDatatype(SqlExpr datatype) {
   31.66 +		this.datatype = datatype;
   31.67 +		datatype.setParentNode(this);
   31.68 +	}
   31.69 +
   31.70 +	public SqlExpr getLanguage() {
   31.71 +		return language;
   31.72 +	}
   31.73 +
   31.74 +	public void setLanguage(SqlExpr language) {
   31.75 +		this.language = language;
   31.76 +		language.setParentNode(this);
   31.77 +	}
   31.78 +
   31.79 +	@Override
   31.80 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
   31.81 +		throws X
   31.82 +	{
   31.83 +		visitor.meet(this);
   31.84 +	}
   31.85 +
   31.86 +	@Override
   31.87 +	public <X extends Exception> void visitChildren(QueryModelVisitor<X> visitor)
   31.88 +		throws X
   31.89 +	{
   31.90 +		id.visit(visitor);
   31.91 +		stringValue.visit(visitor);
   31.92 +		datatype.visit(visitor);
   31.93 +		language.visit(visitor);
   31.94 +	}
   31.95 +
   31.96 +	@Override
   31.97 +	public void replaceChildNode(QueryModelNode current, QueryModelNode replacement) {
   31.98 +		if (id == current) {
   31.99 +			setId((RefIdColumn)replacement);
  31.100 +		}
  31.101 +		else if (stringValue == current) {
  31.102 +			setStringValue((SqlExpr)replacement);
  31.103 +		}
  31.104 +		else if (datatype == current) {
  31.105 +			setDatatype((SqlExpr)replacement);
  31.106 +		}
  31.107 +		else if (language == current) {
  31.108 +			setLanguage((SqlExpr)replacement);
  31.109 +		}
  31.110 +		else {
  31.111 +			super.replaceChildNode(current, replacement);
  31.112 +		}
  31.113 +	}
  31.114 +
  31.115 +	@Override
  31.116 +	public SelectProjection clone() {
  31.117 +		SelectProjection clone = (SelectProjection)super.clone();
  31.118 +		clone.setId(getId().clone());
  31.119 +		clone.setStringValue(getStringValue().clone());
  31.120 +		clone.setDatatype(getDatatype().clone());
  31.121 +		clone.setLanguage(getLanguage().clone());
  31.122 +		return clone;
  31.123 +	}
  31.124 +
  31.125 +	@Override
  31.126 +	public int hashCode() {
  31.127 +		final int prime = 31;
  31.128 +		int result = 1;
  31.129 +		result = prime * result + ((datatype == null) ? 0 : datatype.hashCode());
  31.130 +		result = prime * result + ((id == null) ? 0 : id.hashCode());
  31.131 +		result = prime * result + ((language == null) ? 0 : language.hashCode());
  31.132 +		result = prime * result + ((stringValue == null) ? 0 : stringValue.hashCode());
  31.133 +		result = prime * result + ((var == null) ? 0 : var.hashCode());
  31.134 +		return result;
  31.135 +	}
  31.136 +
  31.137 +	@Override
  31.138 +	public boolean equals(Object obj) {
  31.139 +		if (this == obj)
  31.140 +			return true;
  31.141 +		if (obj == null)
  31.142 +			return false;
  31.143 +		if (getClass() != obj.getClass())
  31.144 +			return false;
  31.145 +		final SelectProjection other = (SelectProjection)obj;
  31.146 +		if (datatype == null) {
  31.147 +			if (other.datatype != null)
  31.148 +				return false;
  31.149 +		}
  31.150 +		else if (!datatype.equals(other.datatype))
  31.151 +			return false;
  31.152 +		if (id == null) {
  31.153 +			if (other.id != null)
  31.154 +				return false;
  31.155 +		}
  31.156 +		else if (!id.equals(other.id))
  31.157 +			return false;
  31.158 +		if (language == null) {
  31.159 +			if (other.language != null)
  31.160 +				return false;
  31.161 +		}
  31.162 +		else if (!language.equals(other.language))
  31.163 +			return false;
  31.164 +		if (stringValue == null) {
  31.165 +			if (other.stringValue != null)
  31.166 +				return false;
  31.167 +		}
  31.168 +		else if (!stringValue.equals(other.stringValue))
  31.169 +			return false;
  31.170 +		if (var == null) {
  31.171 +			if (other.var != null)
  31.172 +				return false;
  31.173 +		}
  31.174 +		else if (!var.equals(other.var))
  31.175 +			return false;
  31.176 +		return true;
  31.177 +	}
  31.178 +
  31.179 +}
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/SelectQuery.java	Thu May 24 13:58:55 2012 +0300
    32.3 @@ -0,0 +1,300 @@
    32.4 +/*
    32.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    32.6 + *
    32.7 + * Licensed under the Aduna BSD-style license.
    32.8 + */
    32.9 +package org.openrdf.sail.rdbms.algebra;
   32.10 +
   32.11 +import java.util.ArrayList;
   32.12 +import java.util.Collection;
   32.13 +import java.util.Collections;
   32.14 +import java.util.HashMap;
   32.15 +import java.util.HashSet;
   32.16 +import java.util.List;
   32.17 +import java.util.Map;
   32.18 +import java.util.Set;
   32.19 +
   32.20 +import org.openrdf.query.algebra.QueryModelNode;
   32.21 +import org.openrdf.query.algebra.QueryModelVisitor;
   32.22 +import org.openrdf.query.algebra.TupleExpr;
   32.23 +import org.openrdf.sail.rdbms.algebra.base.FromItem;
   32.24 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelNodeBase;
   32.25 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   32.26 +import org.openrdf.sail.rdbms.algebra.base.SqlConstant;
   32.27 +import org.openrdf.sail.rdbms.algebra.base.SqlExpr;
   32.28 +
   32.29 +/**
   32.30 + * An SQL query.
   32.31 + * 
   32.32 + * @author James Leigh
   32.33 + * 
   32.34 + */
   32.35 +public class SelectQuery extends RdbmsQueryModelNodeBase implements TupleExpr {
   32.36 +
   32.37 +	public static class OrderElem {
   32.38 +
   32.39 +		public final SqlExpr sqlExpr;
   32.40 +
   32.41 +		public final boolean isAscending;
   32.42 +
   32.43 +		protected OrderElem(SqlExpr sqlExpr, boolean isAscending) {
   32.44 +			this.sqlExpr = sqlExpr;
   32.45 +			this.isAscending = isAscending;
   32.46 +		}
   32.47 +	}
   32.48 +
   32.49 +	private Map<String, SelectProjection> projections = new HashMap<String, SelectProjection>();
   32.50 +
   32.51 +	private Map<String, String> bindingVars;
   32.52 +
   32.53 +	private boolean distinct;
   32.54 +
   32.55 +	private FromItem from;
   32.56 +
   32.57 +	private List<OrderElem> order = new ArrayList<OrderElem>();
   32.58 +
   32.59 +	private Long offset;
   32.60 +
   32.61 +	private Long limit;
   32.62 +
   32.63 +	public boolean isDistinct() {
   32.64 +		return distinct;
   32.65 +	}
   32.66 +
   32.67 +	public void setDistinct(boolean b) {
   32.68 +		distinct = b;
   32.69 +	}
   32.70 +
   32.71 +	public boolean isComplex() {
   32.72 +		if (offset != null || limit != null)
   32.73 +			return true;
   32.74 +		return isDistinct() || !order.isEmpty();
   32.75 +	}
   32.76 +
   32.77 +	public FromItem getFrom() {
   32.78 +		return from;
   32.79 +	}
   32.80 +
   32.81 +	public void setFrom(FromItem from) {
   32.82 +		this.from = from;
   32.83 +		from.setParentNode(this);
   32.84 +	}
   32.85 +
   32.86 +	public List<OrderElem> getOrderElems() {
   32.87 +		return order;
   32.88 +	}
   32.89 +
   32.90 +	public void addOrder(SqlExpr order, boolean isAscending) {
   32.91 +		if (order instanceof SqlNull)
   32.92 +			return;
   32.93 +		if (order instanceof SqlConstant<?>)
   32.94 +			return;
   32.95 +		this.order.add(new OrderElem(order, isAscending));
   32.96 +		order.setParentNode(this);
   32.97 +	}
   32.98 +
   32.99 +	public Long getOffset() {
  32.100 +		return offset;
  32.101 +	}
  32.102 +
  32.103 +	public void setOffset(Long offset) {
  32.104 +		this.offset = offset;
  32.105 +	}
  32.106 +
  32.107 +	public Long getLimit() {
  32.108 +		return limit;
  32.109 +	}
  32.110 +
  32.111 +	public void setLimit(Long limit) {
  32.112 +		this.limit = limit;
  32.113 +	}
  32.114 +
  32.115 +	public Collection<String> getBindingNames(ColumnVar var) {
  32.116 +		if (bindingVars == null)
  32.117 +			return Collections.singleton(var.getName());
  32.118 +		List<String> list = new ArrayList<String>(bindingVars.size());
  32.119 +		for (String name : bindingVars.keySet()) {
  32.120 +			if (var.getName().equals(bindingVars.get(name))) {
  32.121 +				list.add(name);
  32.122 +			}
  32.123 +		}
  32.124 +		return list;
  32.125 +	}
  32.126 +
  32.127 +	public Set<String> getBindingNames() {
  32.128 +		if (bindingVars == null) {
  32.129 +			Set<String> names = new HashSet<String>();
  32.130 +			for (ColumnVar var : getVars()) {
  32.131 +				names.add(var.getName());
  32.132 +			}
  32.133 +			return names;
  32.134 +		}
  32.135 +		return new HashSet<String>(bindingVars.keySet());
  32.136 +	}
  32.137 +	
  32.138 +	public Set<String> getAssuredBindingNames() {
  32.139 +		// FIXME: implement this properly
  32.140 +		return Collections.emptySet();
  32.141 +	}
  32.142 +
  32.143 +	public void setBindingVars(Map<String, String> bindingVars) {
  32.144 +		this.bindingVars = bindingVars;
  32.145 +	}
  32.146 +
  32.147 +	public Collection<SelectProjection> getSqlSelectVar() {
  32.148 +		return projections.values();
  32.149 +	}
  32.150 +
  32.151 +	public void setSqlSelectVar(Collection<SelectProjection> projections) {
  32.152 +		this.projections.clear();
  32.153 +		for (SelectProjection p : projections) {
  32.154 +			addSqlSelectVar(p);
  32.155 +		}
  32.156 +	}
  32.157 +
  32.158 +	public SelectProjection getSelectProjection(String name) {
  32.159 +		return projections.get(name);
  32.160 +	}
  32.161 +
  32.162 +	@Override
  32.163 +	public void replaceChildNode(QueryModelNode current, QueryModelNode replacement) {
  32.164 +		for (String name : projections.keySet()) {
  32.165 +			if (projections.get(name) == current) {
  32.166 +				projections.put(name, (SelectProjection)replacement);
  32.167 +				replacement.setParentNode(this);
  32.168 +				return;
  32.169 +			}
  32.170 +		}
  32.171 +		if (from == current) {
  32.172 +			from = (FromItem)replacement;
  32.173 +			replacement.setParentNode(this);
  32.174 +			return;
  32.175 +		}
  32.176 +		for (int i = 0, n = order.size(); i < n; i++) {
  32.177 +			if (order.get(i).sqlExpr == current) {
  32.178 +				if (replacement instanceof SqlNull || order instanceof SqlConstant<?>) {
  32.179 +					order.remove(i);
  32.180 +					return;
  32.181 +				}
  32.182 +				boolean asc = order.get(i).isAscending;
  32.183 +				order.set(i, new OrderElem((SqlExpr)replacement, asc));
  32.184 +				replacement.setParentNode(this);
  32.185 +				return;
  32.186 +			}
  32.187 +		}
  32.188 +		super.replaceChildNode(current, replacement);
  32.189 +	}
  32.190 +
  32.191 +	@Override
  32.192 +	public <X extends Exception> void visitChildren(QueryModelVisitor<X> visitor)
  32.193 +		throws X
  32.194 +	{
  32.195 +		super.visitChildren(visitor);
  32.196 +		from.visit(visitor);
  32.197 +		ArrayList<SelectProjection> list = new ArrayList<SelectProjection>(projections.values());
  32.198 +		for (SelectProjection expr : list) {
  32.199 +			expr.visit(visitor);
  32.200 +		}
  32.201 +		for (OrderElem by : new ArrayList<OrderElem>(order)) {
  32.202 +			by.sqlExpr.visit(visitor);
  32.203 +		}
  32.204 +	}
  32.205 +
  32.206 +	@Override
  32.207 +	public SelectQuery clone() {
  32.208 +		SelectQuery clone = (SelectQuery)super.clone();
  32.209 +		clone.distinct = distinct;
  32.210 +		clone.projections = new HashMap<String, SelectProjection>();
  32.211 +		for (SelectProjection expr : projections.values()) {
  32.212 +			clone.addSqlSelectVar(expr.clone());
  32.213 +		}
  32.214 +		clone.from = from.clone();
  32.215 +		clone.order = new ArrayList<OrderElem>(order);
  32.216 +		return clone;
  32.217 +	}
  32.218 +
  32.219 +	@Override
  32.220 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
  32.221 +		throws X
  32.222 +	{
  32.223 +		visitor.meet(this);
  32.224 +	}
  32.225 +
  32.226 +	public boolean hasSqlSelectVar(SelectProjection node) {
  32.227 +		return projections.containsKey(node.getVar().getName());
  32.228 +	}
  32.229 +
  32.230 +	public boolean hasSqlSelectVarName(String name) {
  32.231 +		return projections.containsKey(name);
  32.232 +	}
  32.233 +
  32.234 +	public void addSqlSelectVar(SelectProjection node) {
  32.235 +		projections.put(node.getVar().getName(), node);
  32.236 +		node.setParentNode(this);
  32.237 +	}
  32.238 +
  32.239 +	public Collection<ColumnVar> getProjections() {
  32.240 +		List<ColumnVar> vars = new ArrayList<ColumnVar>();
  32.241 +		for (SelectProjection proj : projections.values()) {
  32.242 +			ColumnVar var = proj.getVar();
  32.243 +			if (bindingVars == null) {
  32.244 +				vars.add(var);
  32.245 +			} else {
  32.246 +				for (String name : bindingVars.keySet()) {
  32.247 +					if (var.getName().equals(bindingVars.get(name))) {
  32.248 +						vars.add(var.as(name));
  32.249 +					}
  32.250 +				}
  32.251 +			}
  32.252 +		}
  32.253 +		return vars;
  32.254 +	}
  32.255 +
  32.256 +	public Collection<ColumnVar> getVars() {
  32.257 +		List<ColumnVar> vars = new ArrayList<ColumnVar>();
  32.258 +		from.appendVars(vars);
  32.259 +		return vars;
  32.260 +	}
  32.261 +
  32.262 +	public ColumnVar getVar(String varName) {
  32.263 +		return from.getVar(varName);
  32.264 +	}
  32.265 +
  32.266 +	public void addFilter(SqlExpr sql) {
  32.267 +		from.addFilter(sql);
  32.268 +	}
  32.269 +
  32.270 +	public void addJoin(SelectQuery right) {
  32.271 +		from.addJoin(right.getFrom());
  32.272 +	}
  32.273 +
  32.274 +	public void addLeftJoin(SelectQuery right) {
  32.275 +		FromItem join = right.getFrom();
  32.276 +		join.setLeft(true);
  32.277 +		from.addJoin(join);
  32.278 +	}
  32.279 +
  32.280 +	public FromItem getFromItem(String alias) {
  32.281 +		return from.getFromItemNotInUnion(alias);
  32.282 +	}
  32.283 +
  32.284 +	public List<SqlExpr> getFilters() {
  32.285 +		return from.getFilters();
  32.286 +	}
  32.287 +
  32.288 +	public void removeFilter(SqlExpr sqlExpr) {
  32.289 +		from.removeFilter(sqlExpr);
  32.290 +	}
  32.291 +
  32.292 +	public Map<String, ColumnVar> getVarMap() {
  32.293 +		Collection<ColumnVar> vars = getVars();
  32.294 +		Map<String, ColumnVar> map = new HashMap<String, ColumnVar>(vars.size());
  32.295 +		for (ColumnVar var : vars) {
  32.296 +			if (!map.containsKey(var.getName())) {
  32.297 +				map.put(var.getName(), var);
  32.298 +			}
  32.299 +		}
  32.300 +		return map;
  32.301 +	}
  32.302 +
  32.303 +}
    33.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/SqlAbs.java	Thu May 24 13:58:55 2012 +0300
    33.3 @@ -0,0 +1,30 @@
    33.4 +/*
    33.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    33.6 + *
    33.7 + * Licensed under the Aduna BSD-style license.
    33.8 + */
    33.9 +package org.openrdf.sail.rdbms.algebra;
   33.10 +
   33.11 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   33.12 +import org.openrdf.sail.rdbms.algebra.base.SqlExpr;
   33.13 +import org.openrdf.sail.rdbms.algebra.base.UnarySqlOperator;
   33.14 +
   33.15 +/**
   33.16 + * The SQL ABS expression.
   33.17 + * 
   33.18 + * @author James Leigh
   33.19 + * 
   33.20 + */
   33.21 +public class SqlAbs extends UnarySqlOperator {
   33.22 +
   33.23 +	public SqlAbs(SqlExpr arg) {
   33.24 +		super(arg);
   33.25 +	}
   33.26 +
   33.27 +	@Override
   33.28 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
   33.29 +		throws X
   33.30 +	{
   33.31 +		visitor.meet(this);
   33.32 +	}
   33.33 +}
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/SqlAnd.java	Thu May 24 13:58:55 2012 +0300
    34.3 @@ -0,0 +1,30 @@
    34.4 +/*
    34.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    34.6 + *
    34.7 + * Licensed under the Aduna BSD-style license.
    34.8 + */
    34.9 +package org.openrdf.sail.rdbms.algebra;
   34.10 +
   34.11 +import org.openrdf.sail.rdbms.algebra.base.BinarySqlOperator;
   34.12 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   34.13 +import org.openrdf.sail.rdbms.algebra.base.SqlExpr;
   34.14 +
   34.15 +/**
   34.16 + * The SQL AND expression.
   34.17 + * 
   34.18 + * @author James Leigh
   34.19 + * 
   34.20 + */
   34.21 +public class SqlAnd extends BinarySqlOperator {
   34.22 +
   34.23 +	public SqlAnd(SqlExpr leftArg, SqlExpr rightArg) {
   34.24 +		super(leftArg, rightArg);
   34.25 +	}
   34.26 +
   34.27 +	@Override
   34.28 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
   34.29 +		throws X
   34.30 +	{
   34.31 +		visitor.meet(this);
   34.32 +	}
   34.33 +}
    35.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/SqlCase.java	Thu May 24 13:58:55 2012 +0300
    35.3 @@ -0,0 +1,177 @@
    35.4 +/*
    35.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    35.6 + *
    35.7 + * Licensed under the Aduna BSD-style license.
    35.8 + */
    35.9 +package org.openrdf.sail.rdbms.algebra;
   35.10 +
   35.11 +import java.util.ArrayList;
   35.12 +import java.util.List;
   35.13 +
   35.14 +import org.openrdf.query.algebra.QueryModelNode;
   35.15 +import org.openrdf.query.algebra.QueryModelVisitor;
   35.16 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelNodeBase;
   35.17 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   35.18 +import org.openrdf.sail.rdbms.algebra.base.SqlExpr;
   35.19 +
   35.20 +/**
   35.21 + * The SQL CASE WHEN THEN END expression.
   35.22 + * 
   35.23 + * @author James Leigh
   35.24 + * 
   35.25 + */
   35.26 +public class SqlCase extends RdbmsQueryModelNodeBase implements SqlExpr {
   35.27 +
   35.28 +	private List<Entry> entries = new ArrayList<Entry>();
   35.29 +
   35.30 +	public class Entry {
   35.31 +
   35.32 +		private SqlExpr condition;
   35.33 +
   35.34 +		private SqlExpr result;
   35.35 +
   35.36 +		public Entry(SqlExpr condition, SqlExpr result) {
   35.37 +			super();
   35.38 +			this.condition = condition;
   35.39 +			this.result = result;
   35.40 +		}
   35.41 +
   35.42 +		public SqlExpr getCondition() {
   35.43 +			return condition;
   35.44 +		}
   35.45 +
   35.46 +		public void setCondition(SqlExpr condition) {
   35.47 +			this.condition = condition;
   35.48 +			condition.setParentNode(SqlCase.this);
   35.49 +		}
   35.50 +
   35.51 +		public SqlExpr getResult() {
   35.52 +			return result;
   35.53 +		}
   35.54 +
   35.55 +		public void setResult(SqlExpr result) {
   35.56 +			this.result = result;
   35.57 +			result.setParentNode(SqlCase.this);
   35.58 +		}
   35.59 +
   35.60 +		@Override
   35.61 +		public int hashCode() {
   35.62 +			final int prime = 31;
   35.63 +			int result = 1;
   35.64 +			result = prime * result + ((condition == null) ? 0 : condition.hashCode());
   35.65 +			result = prime * result + ((this.result == null) ? 0 : this.result.hashCode());
   35.66 +			return result;
   35.67 +		}
   35.68 +
   35.69 +		@Override
   35.70 +		public boolean equals(Object obj) {
   35.71 +			if (this == obj)
   35.72 +				return true;
   35.73 +			if (obj == null)
   35.74 +				return false;
   35.75 +			if (getClass() != obj.getClass())
   35.76 +				return false;
   35.77 +			final Entry other = (Entry)obj;
   35.78 +			if (condition == null) {
   35.79 +				if (other.condition != null)
   35.80 +					return false;
   35.81 +			}
   35.82 +			else if (!condition.equals(other.condition))
   35.83 +				return false;
   35.84 +			if (result == null) {
   35.85 +				if (other.result != null)
   35.86 +					return false;
   35.87 +			}
   35.88 +			else if (!result.equals(other.result))
   35.89 +				return false;
   35.90 +			return true;
   35.91 +		}
   35.92 +	}
   35.93 +
   35.94 +	public void when(SqlExpr condition, SqlExpr expr) {
   35.95 +		entries.add(new Entry(condition, expr));
   35.96 +		condition.setParentNode(this);
   35.97 +		expr.setParentNode(this);
   35.98 +	}
   35.99 +
  35.100 +	public List<Entry> getEntries() {
  35.101 +		return new ArrayList<Entry>(entries);
  35.102 +	}
  35.103 +
  35.104 +	@Override
  35.105 +	public <X extends Exception> void visitChildren(QueryModelVisitor<X> visitor)
  35.106 +		throws X
  35.107 +	{
  35.108 +		for (Entry e : entries) {
  35.109 +			e.getCondition().visit(visitor);
  35.110 +			e.getResult().visit(visitor);
  35.111 +		}
  35.112 +	}
  35.113 +
  35.114 +	@Override
  35.115 +	public void replaceChildNode(QueryModelNode current, QueryModelNode replacement) {
  35.116 +		for (Entry e : entries) {
  35.117 +			if (e.getCondition() == current) {
  35.118 +				e.setCondition((SqlExpr)replacement);
  35.119 +			}
  35.120 +			else if (e.getResult() == current) {
  35.121 +				e.setResult((SqlExpr)replacement);
  35.122 +			}
  35.123 +		}
  35.124 +	}
  35.125 +
  35.126 +	@Override
  35.127 +	public SqlCase clone() {
  35.128 +		SqlCase clone = (SqlCase)super.clone();
  35.129 +		clone.entries = new ArrayList<Entry>();
  35.130 +		for (Entry e : entries) {
  35.131 +			clone.when(e.getCondition().clone(), e.getResult().clone());
  35.132 +		}
  35.133 +		return clone;
  35.134 +	}
  35.135 +
  35.136 +	@Override
  35.137 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
  35.138 +		throws X
  35.139 +	{
  35.140 +		visitor.meet(this);
  35.141 +	}
  35.142 +
  35.143 +	public void removeEntry(Entry e) {
  35.144 +		entries.remove(e);
  35.145 +	}
  35.146 +
  35.147 +	public void truncateEntries(Entry e) {
  35.148 +		int idx = entries.indexOf(e) + 1;
  35.149 +		if (idx < entries.size()) {
  35.150 +			entries = entries.subList(0, idx);
  35.151 +		}
  35.152 +	}
  35.153 +
  35.154 +	@Override
  35.155 +	public int hashCode() {
  35.156 +		final int prime = 31;
  35.157 +		int result = 1;
  35.158 +		result = prime * result + ((entries == null) ? 0 : entries.hashCode());
  35.159 +		return result;
  35.160 +	}
  35.161 +
  35.162 +	@Override
  35.163 +	public boolean equals(Object obj) {
  35.164 +		if (this == obj)
  35.165 +			return true;
  35.166 +		if (obj == null)
  35.167 +			return false;
  35.168 +		if (getClass() != obj.getClass())
  35.169 +			return false;
  35.170 +		final SqlCase other = (SqlCase)obj;
  35.171 +		if (entries == null) {
  35.172 +			if (other.entries != null)
  35.173 +				return false;
  35.174 +		}
  35.175 +		else if (!entries.equals(other.entries))
  35.176 +			return false;
  35.177 +		return true;
  35.178 +	}
  35.179 +
  35.180 +}
    36.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/SqlCast.java	Thu May 24 13:58:55 2012 +0300
    36.3 @@ -0,0 +1,43 @@
    36.4 +/*
    36.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    36.6 + *
    36.7 + * Licensed under the Aduna BSD-style license.
    36.8 + */
    36.9 +package org.openrdf.sail.rdbms.algebra;
   36.10 +
   36.11 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   36.12 +import org.openrdf.sail.rdbms.algebra.base.SqlExpr;
   36.13 +import org.openrdf.sail.rdbms.algebra.base.UnarySqlOperator;
   36.14 +
   36.15 +/**
   36.16 + * The SQL IS CAST expression.
   36.17 + * 
   36.18 + * @author James Leigh
   36.19 + * 
   36.20 + */
   36.21 +public class SqlCast extends UnarySqlOperator {
   36.22 +
   36.23 +	private int type;
   36.24 +
   36.25 +	public SqlCast(SqlExpr arg, int type) {
   36.26 +		super(arg);
   36.27 +		this.type = type;
   36.28 +	}
   36.29 +
   36.30 +	@Override
   36.31 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
   36.32 +		throws X
   36.33 +	{
   36.34 +		visitor.meet(this);
   36.35 +	}
   36.36 +
   36.37 +	public int getType() {
   36.38 +		return type;
   36.39 +	}
   36.40 +
   36.41 +	@Override
   36.42 +	public String getSignature() {
   36.43 +		return super.getSignature() + " AS " + type;
   36.44 +	}
   36.45 +
   36.46 +}
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/SqlCompare.java	Thu May 24 13:58:55 2012 +0300
    37.3 @@ -0,0 +1,91 @@
    37.4 +/*
    37.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    37.6 + *
    37.7 + * Licensed under the Aduna BSD-style license.
    37.8 + */
    37.9 +package org.openrdf.sail.rdbms.algebra;
   37.10 +
   37.11 +import org.openrdf.query.algebra.Compare.CompareOp;
   37.12 +import org.openrdf.sail.rdbms.algebra.base.BinarySqlOperator;
   37.13 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   37.14 +import org.openrdf.sail.rdbms.algebra.base.SqlExpr;
   37.15 +
   37.16 +/**
   37.17 + * The SQL compare expressions (>, <, >=, <=).
   37.18 + * 
   37.19 + * @author James Leigh
   37.20 + * 
   37.21 + */
   37.22 +public class SqlCompare extends BinarySqlOperator {
   37.23 +
   37.24 +	public enum Operator {
   37.25 +		GT,
   37.26 +		LT,
   37.27 +		GE,
   37.28 +		LE
   37.29 +	}
   37.30 +
   37.31 +	private Operator op;
   37.32 +
   37.33 +	public SqlCompare(SqlExpr leftArg, CompareOp op, SqlExpr rightArg) {
   37.34 +		super(leftArg, rightArg);
   37.35 +		switch (op) {
   37.36 +			case GT:
   37.37 +				this.op = Operator.GT;
   37.38 +				break;
   37.39 +			case LT:
   37.40 +				this.op = Operator.LT;
   37.41 +				break;
   37.42 +			case GE:
   37.43 +				this.op = Operator.GE;
   37.44 +				break;
   37.45 +			case LE:
   37.46 +				this.op = Operator.LE;
   37.47 +				break;
   37.48 +			default:
   37.49 +				throw new AssertionError(op);
   37.50 +		}
   37.51 +	}
   37.52 +
   37.53 +	public Operator getOperator() {
   37.54 +		return op;
   37.55 +	}
   37.56 +
   37.57 +	@Override
   37.58 +	public String getSignature() {
   37.59 +		return super.getSignature() + " (" + op + ")";
   37.60 +	}
   37.61 +
   37.62 +	@Override
   37.63 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
   37.64 +		throws X
   37.65 +	{
   37.66 +		visitor.meet(this);
   37.67 +	}
   37.68 +
   37.69 +	@Override
   37.70 +	public int hashCode() {
   37.71 +		final int prime = 31;
   37.72 +		int result = super.hashCode();
   37.73 +		result = prime * result + ((op == null) ? 0 : op.hashCode());
   37.74 +		return result;
   37.75 +	}
   37.76 +
   37.77 +	@Override
   37.78 +	public boolean equals(Object obj) {
   37.79 +		if (this == obj)
   37.80 +			return true;
   37.81 +		if (!super.equals(obj))
   37.82 +			return false;
   37.83 +		if (getClass() != obj.getClass())
   37.84 +			return false;
   37.85 +		final SqlCompare other = (SqlCompare)obj;
   37.86 +		if (op == null) {
   37.87 +			if (other.op != null)
   37.88 +				return false;
   37.89 +		}
   37.90 +		else if (!op.equals(other.op))
   37.91 +			return false;
   37.92 +		return true;
   37.93 +	}
   37.94 +}
    38.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/SqlConcat.java	Thu May 24 13:58:55 2012 +0300
    38.3 @@ -0,0 +1,30 @@
    38.4 +/*
    38.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    38.6 + *
    38.7 + * Licensed under the Aduna BSD-style license.
    38.8 + */
    38.9 +package org.openrdf.sail.rdbms.algebra;
   38.10 +
   38.11 +import org.openrdf.sail.rdbms.algebra.base.BinarySqlOperator;
   38.12 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   38.13 +import org.openrdf.sail.rdbms.algebra.base.SqlExpr;
   38.14 +
   38.15 +/**
   38.16 + * The SQL concatenate expression (||).
   38.17 + * 
   38.18 + * @author James Leigh
   38.19 + * 
   38.20 + */
   38.21 +public class SqlConcat extends BinarySqlOperator {
   38.22 +
   38.23 +	public SqlConcat(SqlExpr leftArg, SqlExpr rightArg) {
   38.24 +		super(leftArg, rightArg);
   38.25 +	}
   38.26 +
   38.27 +	@Override
   38.28 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
   38.29 +		throws X
   38.30 +	{
   38.31 +		visitor.meet(this);
   38.32 +	}
   38.33 +}
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/SqlEq.java	Thu May 24 13:58:55 2012 +0300
    39.3 @@ -0,0 +1,30 @@
    39.4 +/*
    39.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    39.6 + *
    39.7 + * Licensed under the Aduna BSD-style license.
    39.8 + */
    39.9 +package org.openrdf.sail.rdbms.algebra;
   39.10 +
   39.11 +import org.openrdf.sail.rdbms.algebra.base.BinarySqlOperator;
   39.12 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   39.13 +import org.openrdf.sail.rdbms.algebra.base.SqlExpr;
   39.14 +
   39.15 +/**
   39.16 + * The SQL equals expression (=).
   39.17 + * 
   39.18 + * @author James Leigh
   39.19 + * 
   39.20 + */
   39.21 +public class SqlEq extends BinarySqlOperator {
   39.22 +
   39.23 +	public SqlEq(SqlExpr leftArg, SqlExpr rightArg) {
   39.24 +		super(leftArg, rightArg);
   39.25 +	}
   39.26 +
   39.27 +	@Override
   39.28 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
   39.29 +		throws X
   39.30 +	{
   39.31 +		visitor.meet(this);
   39.32 +	}
   39.33 +}
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/SqlIsNull.java	Thu May 24 13:58:55 2012 +0300
    40.3 @@ -0,0 +1,31 @@
    40.4 +/*
    40.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    40.6 + *
    40.7 + * Licensed under the Aduna BSD-style license.
    40.8 + */
    40.9 +package org.openrdf.sail.rdbms.algebra;
   40.10 +
   40.11 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   40.12 +import org.openrdf.sail.rdbms.algebra.base.SqlExpr;
   40.13 +import org.openrdf.sail.rdbms.algebra.base.UnarySqlOperator;
   40.14 +
   40.15 +/**
   40.16 + * The SQL IS NULL expression.
   40.17 + * 
   40.18 + * @author James Leigh
   40.19 + * 
   40.20 + */
   40.21 +public class SqlIsNull extends UnarySqlOperator {
   40.22 +
   40.23 +	public SqlIsNull(SqlExpr arg) {
   40.24 +		super(arg);
   40.25 +	}
   40.26 +
   40.27 +	@Override
   40.28 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
   40.29 +		throws X
   40.30 +	{
   40.31 +		visitor.meet(this);
   40.32 +	}
   40.33 +
   40.34 +}
    41.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/SqlLike.java	Thu May 24 13:58:55 2012 +0300
    41.3 @@ -0,0 +1,31 @@
    41.4 +/*
    41.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    41.6 + *
    41.7 + * Licensed under the Aduna BSD-style license.
    41.8 + */
    41.9 +package org.openrdf.sail.rdbms.algebra;
   41.10 +
   41.11 +import org.openrdf.sail.rdbms.algebra.base.BinarySqlOperator;
   41.12 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   41.13 +import org.openrdf.sail.rdbms.algebra.base.SqlExpr;
   41.14 +
   41.15 +/**
   41.16 + * The SQL LIKE operator.
   41.17 + * 
   41.18 + * @author James Leigh
   41.19 + * 
   41.20 + */
   41.21 +public class SqlLike extends BinarySqlOperator {
   41.22 +
   41.23 +	public SqlLike(SqlExpr left, SqlExpr right) {
   41.24 +		super(left, right);
   41.25 +	}
   41.26 +
   41.27 +	@Override
   41.28 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
   41.29 +		throws X
   41.30 +	{
   41.31 +		visitor.meet(this);
   41.32 +	}
   41.33 +
   41.34 +}
   41.35 \ No newline at end of file
    42.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/SqlLowerCase.java	Thu May 24 13:58:55 2012 +0300
    42.3 @@ -0,0 +1,31 @@
    42.4 +/*
    42.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    42.6 + *
    42.7 + * Licensed under the Aduna BSD-style license.
    42.8 + */
    42.9 +package org.openrdf.sail.rdbms.algebra;
   42.10 +
   42.11 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   42.12 +import org.openrdf.sail.rdbms.algebra.base.SqlExpr;
   42.13 +import org.openrdf.sail.rdbms.algebra.base.UnarySqlOperator;
   42.14 +
   42.15 +/**
   42.16 + * The SQL LOWER function.
   42.17 + * 
   42.18 + * @author James Leigh
   42.19 + * 
   42.20 + */
   42.21 +public class SqlLowerCase extends UnarySqlOperator {
   42.22 +
   42.23 +	public SqlLowerCase(SqlExpr arg) {
   42.24 +		super(arg);
   42.25 +	}
   42.26 +
   42.27 +	@Override
   42.28 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
   42.29 +		throws X
   42.30 +	{
   42.31 +		visitor.meet(this);
   42.32 +	}
   42.33 +
   42.34 +}
   42.35 \ No newline at end of file
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/SqlMathExpr.java	Thu May 24 13:58:55 2012 +0300
    43.3 @@ -0,0 +1,38 @@
    43.4 +/*
    43.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    43.6 + *
    43.7 + * Licensed under the Aduna BSD-style license.
    43.8 + */
    43.9 +package org.openrdf.sail.rdbms.algebra;
   43.10 +
   43.11 +import org.openrdf.query.algebra.MathExpr.MathOp;
   43.12 +import org.openrdf.sail.rdbms.algebra.base.BinarySqlOperator;
   43.13 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   43.14 +import org.openrdf.sail.rdbms.algebra.base.SqlExpr;
   43.15 +
   43.16 +/**
   43.17 + * The SQL subtraction (-) expression.
   43.18 + * 
   43.19 + * @author James Leigh
   43.20 + * 
   43.21 + */
   43.22 +public class SqlMathExpr extends BinarySqlOperator {
   43.23 +
   43.24 +	private MathOp op;
   43.25 +
   43.26 +	public SqlMathExpr(SqlExpr leftArg, MathOp op, SqlExpr rightArg) {
   43.27 +		super(leftArg, rightArg);
   43.28 +		this.op = op;
   43.29 +	}
   43.30 +
   43.31 +	public MathOp getOperator() {
   43.32 +		return op;
   43.33 +	}
   43.34 +
   43.35 +	@Override
   43.36 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
   43.37 +		throws X
   43.38 +	{
   43.39 +		visitor.meet(this);
   43.40 +	}
   43.41 +}
    44.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    44.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/SqlNot.java	Thu May 24 13:58:55 2012 +0300
    44.3 @@ -0,0 +1,31 @@
    44.4 +/*
    44.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    44.6 + *
    44.7 + * Licensed under the Aduna BSD-style license.
    44.8 + */
    44.9 +package org.openrdf.sail.rdbms.algebra;
   44.10 +
   44.11 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   44.12 +import org.openrdf.sail.rdbms.algebra.base.SqlExpr;
   44.13 +import org.openrdf.sail.rdbms.algebra.base.UnarySqlOperator;
   44.14 +
   44.15 +/**
   44.16 + * The SQL NOT expression.
   44.17 + * 
   44.18 + * @author James Leigh
   44.19 + * 
   44.20 + */
   44.21 +public class SqlNot extends UnarySqlOperator {
   44.22 +
   44.23 +	public SqlNot(SqlExpr arg) {
   44.24 +		super(arg);
   44.25 +	}
   44.26 +
   44.27 +	@Override
   44.28 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
   44.29 +		throws X
   44.30 +	{
   44.31 +		visitor.meet(this);
   44.32 +	}
   44.33 +
   44.34 +}
    45.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/SqlNull.java	Thu May 24 13:58:55 2012 +0300
    45.3 @@ -0,0 +1,29 @@
    45.4 +/*
    45.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    45.6 + *
    45.7 + * Licensed under the Aduna BSD-style license.
    45.8 + */
    45.9 +package org.openrdf.sail.rdbms.algebra;
   45.10 +
   45.11 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   45.12 +import org.openrdf.sail.rdbms.algebra.base.SqlConstant;
   45.13 +
   45.14 +/**
   45.15 + * The SQL NULL expression.
   45.16 + * 
   45.17 + * @author James Leigh
   45.18 + * 
   45.19 + */
   45.20 +public class SqlNull extends SqlConstant<Object> {
   45.21 +
   45.22 +	public SqlNull() {
   45.23 +		super(null);
   45.24 +	}
   45.25 +
   45.26 +	@Override
   45.27 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
   45.28 +		throws X
   45.29 +	{
   45.30 +		visitor.meet(this);
   45.31 +	}
   45.32 +}
    46.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/SqlOr.java	Thu May 24 13:58:55 2012 +0300
    46.3 @@ -0,0 +1,30 @@
    46.4 +/*
    46.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    46.6 + *
    46.7 + * Licensed under the Aduna BSD-style license.
    46.8 + */
    46.9 +package org.openrdf.sail.rdbms.algebra;
   46.10 +
   46.11 +import org.openrdf.sail.rdbms.algebra.base.BinarySqlOperator;
   46.12 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   46.13 +import org.openrdf.sail.rdbms.algebra.base.SqlExpr;
   46.14 +
   46.15 +/**
   46.16 + * The SQL OR expression.
   46.17 + * 
   46.18 + * @author James Leigh
   46.19 + * 
   46.20 + */
   46.21 +public class SqlOr extends BinarySqlOperator {
   46.22 +
   46.23 +	public SqlOr(SqlExpr leftArg, SqlExpr rightArg) {
   46.24 +		super(leftArg, rightArg);
   46.25 +	}
   46.26 +
   46.27 +	@Override
   46.28 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
   46.29 +		throws X
   46.30 +	{
   46.31 +		visitor.meet(this);
   46.32 +	}
   46.33 +}
    47.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/SqlRegex.java	Thu May 24 13:58:55 2012 +0300
    47.3 @@ -0,0 +1,122 @@
    47.4 +/*
    47.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    47.6 + *
    47.7 + * Licensed under the Aduna BSD-style license.
    47.8 + */
    47.9 +package org.openrdf.sail.rdbms.algebra;
   47.10 +
   47.11 +import org.openrdf.query.algebra.QueryModelVisitor;
   47.12 +import org.openrdf.sail.rdbms.algebra.base.BinarySqlOperator;
   47.13 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   47.14 +import org.openrdf.sail.rdbms.algebra.base.SqlExpr;
   47.15 +
   47.16 +/**
   47.17 + * The regular SQL expression - notation varies between databases.
   47.18 + * 
   47.19 + * @author James Leigh
   47.20 + * 
   47.21 + */
   47.22 +public class SqlRegex extends BinarySqlOperator {
   47.23 +
   47.24 +	/*-----------*
   47.25 +	 * Variables *
   47.26 +	 *-----------*/
   47.27 +
   47.28 +	private SqlExpr flagsArg;
   47.29 +
   47.30 +	/*--------------*
   47.31 +	 * Constructors *
   47.32 +	 *--------------*/
   47.33 +
   47.34 +	public SqlRegex() {
   47.35 +	}
   47.36 +
   47.37 +	public SqlRegex(SqlExpr expr, SqlExpr pattern) {
   47.38 +		super(expr, pattern);
   47.39 +	}
   47.40 +
   47.41 +	public SqlRegex(SqlExpr expr, SqlExpr pattern, SqlExpr flags) {
   47.42 +		super(expr, pattern);
   47.43 +		setFlagsArg(flags);
   47.44 +	}
   47.45 +
   47.46 +	/*---------*
   47.47 +	 * Methods *
   47.48 +	 *---------*/
   47.49 +
   47.50 +	public SqlExpr getArg() {
   47.51 +		return super.getLeftArg();
   47.52 +	}
   47.53 +
   47.54 +	public void setArg(SqlExpr leftArg) {
   47.55 +		super.setLeftArg(leftArg);
   47.56 +	}
   47.57 +
   47.58 +	public SqlExpr getPatternArg() {
   47.59 +		return super.getRightArg();
   47.60 +	}
   47.61 +
   47.62 +	public void setPatternArg(SqlExpr rightArg) {
   47.63 +		super.setRightArg(rightArg);
   47.64 +	}
   47.65 +
   47.66 +	public void setFlagsArg(SqlExpr flags) {
   47.67 +		this.flagsArg = flags;
   47.68 +	}
   47.69 +
   47.70 +	public SqlExpr getFlagsArg() {
   47.71 +		return flagsArg;
   47.72 +	}
   47.73 +
   47.74 +	@Override
   47.75 +	public <X extends Exception> void visitChildren(QueryModelVisitor<X> visitor)
   47.76 +		throws X
   47.77 +	{
   47.78 +		super.visitChildren(visitor);
   47.79 +		if (flagsArg != null) {
   47.80 +			flagsArg.visit(visitor);
   47.81 +		}
   47.82 +	}
   47.83 +
   47.84 +	@Override
   47.85 +	public SqlRegex clone() {
   47.86 +		SqlRegex clone = (SqlRegex)super.clone();
   47.87 +		if (flagsArg != null) {
   47.88 +			clone.setFlagsArg(flagsArg.clone());
   47.89 +		}
   47.90 +		return clone;
   47.91 +	}
   47.92 +
   47.93 +	@Override
   47.94 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
   47.95 +		throws X
   47.96 +	{
   47.97 +		visitor.meet(this);
   47.98 +	}
   47.99 +
  47.100 +	@Override
  47.101 +	public int hashCode() {
  47.102 +		final int prime = 31;
  47.103 +		int result = super.hashCode();
  47.104 +		result = prime * result + ((flagsArg == null) ? 0 : flagsArg.hashCode());
  47.105 +		return result;
  47.106 +	}
  47.107 +
  47.108 +	@Override
  47.109 +	public boolean equals(Object obj) {
  47.110 +		if (this == obj)
  47.111 +			return true;
  47.112 +		if (!super.equals(obj))
  47.113 +			return false;
  47.114 +		if (getClass() != obj.getClass())
  47.115 +			return false;
  47.116 +		final SqlRegex other = (SqlRegex)obj;
  47.117 +		if (flagsArg == null) {
  47.118 +			if (other.flagsArg != null)
  47.119 +				return false;
  47.120 +		}
  47.121 +		else if (!flagsArg.equals(other.flagsArg))
  47.122 +			return false;
  47.123 +		return true;
  47.124 +	}
  47.125 +}
    48.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/SqlShift.java	Thu May 24 13:58:55 2012 +0300
    48.3 @@ -0,0 +1,45 @@
    48.4 +/*
    48.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    48.6 + *
    48.7 + * Licensed under the Aduna BSD-style license.
    48.8 + */
    48.9 +package org.openrdf.sail.rdbms.algebra;
   48.10 +
   48.11 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   48.12 +import org.openrdf.sail.rdbms.algebra.base.SqlExpr;
   48.13 +import org.openrdf.sail.rdbms.algebra.base.UnarySqlOperator;
   48.14 +
   48.15 +/**
   48.16 + * The SQL binary shift right (>>) expression.
   48.17 + * 
   48.18 + * @author James Leigh
   48.19 + * 
   48.20 + */
   48.21 +public class SqlShift extends UnarySqlOperator {
   48.22 +
   48.23 +	private int shift;
   48.24 +
   48.25 +	private int range;
   48.26 +
   48.27 +	public SqlShift(SqlExpr arg, int shift, int range) {
   48.28 +		super(arg);
   48.29 +		this.shift = shift;
   48.30 +		this.range = range;
   48.31 +	}
   48.32 +
   48.33 +	public int getRightShift() {
   48.34 +		return shift;
   48.35 +	}
   48.36 +
   48.37 +	public int getRange() {
   48.38 +		return range;
   48.39 +	}
   48.40 +
   48.41 +	@Override
   48.42 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
   48.43 +		throws X
   48.44 +	{
   48.45 +		visitor.meet(this);
   48.46 +	}
   48.47 +
   48.48 +}
    49.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    49.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/StringValue.java	Thu May 24 13:58:55 2012 +0300
    49.3 @@ -0,0 +1,30 @@
    49.4 +/*
    49.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    49.6 + *
    49.7 + * Licensed under the Aduna BSD-style license.
    49.8 + */
    49.9 +package org.openrdf.sail.rdbms.algebra;
   49.10 +
   49.11 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   49.12 +import org.openrdf.sail.rdbms.algebra.base.SqlConstant;
   49.13 +
   49.14 +/**
   49.15 + * An SQL VARCHAR expression.
   49.16 + * 
   49.17 + * @author James Leigh
   49.18 + * 
   49.19 + */
   49.20 +public class StringValue extends SqlConstant<String> {
   49.21 +
   49.22 +	public StringValue(String value) {
   49.23 +		super(value);
   49.24 +		assert value != null;
   49.25 +	}
   49.26 +
   49.27 +	@Override
   49.28 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
   49.29 +		throws X
   49.30 +	{
   49.31 +		visitor.meet(this);
   49.32 +	}
   49.33 +}
    50.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    50.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/TrueValue.java	Thu May 24 13:58:55 2012 +0300
    50.3 @@ -0,0 +1,29 @@
    50.4 +/*
    50.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    50.6 + *
    50.7 + * Licensed under the Aduna BSD-style license.
    50.8 + */
    50.9 +package org.openrdf.sail.rdbms.algebra;
   50.10 +
   50.11 +import org.openrdf.sail.rdbms.algebra.base.BooleanValue;
   50.12 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   50.13 +
   50.14 +/**
   50.15 + * The boolean SQL expression of true.
   50.16 + * 
   50.17 + * @author James Leigh
   50.18 + * 
   50.19 + */
   50.20 +public class TrueValue extends BooleanValue {
   50.21 +
   50.22 +	public TrueValue() {
   50.23 +		super(true);
   50.24 +	}
   50.25 +
   50.26 +	@Override
   50.27 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
   50.28 +		throws X
   50.29 +	{
   50.30 +		visitor.meet(this);
   50.31 +	}
   50.32 +}
    51.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    51.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/URIColumn.java	Thu May 24 13:58:55 2012 +0300
    51.3 @@ -0,0 +1,35 @@
    51.4 +/*
    51.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    51.6 + *
    51.7 + * Licensed under the Aduna BSD-style license.
    51.8 + */
    51.9 +package org.openrdf.sail.rdbms.algebra;
   51.10 +
   51.11 +import org.openrdf.query.algebra.Var;
   51.12 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   51.13 +import org.openrdf.sail.rdbms.algebra.base.ValueColumnBase;
   51.14 +
   51.15 +/**
   51.16 + * Represents a variable's URI value in an SQL expression.
   51.17 + * 
   51.18 + * @author James Leigh
   51.19 + * 
   51.20 + */
   51.21 +public class URIColumn extends ValueColumnBase {
   51.22 +
   51.23 +	public URIColumn(Var var) {
   51.24 +		super(var);
   51.25 +	}
   51.26 +
   51.27 +	public URIColumn(ColumnVar var) {
   51.28 +		super(var);
   51.29 +	}
   51.30 +
   51.31 +	@Override
   51.32 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
   51.33 +		throws X
   51.34 +	{
   51.35 +		visitor.meet(this);
   51.36 +	}
   51.37 +
   51.38 +}
    52.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    52.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/UnionItem.java	Thu May 24 13:58:55 2012 +0300
    52.3 @@ -0,0 +1,159 @@
    52.4 +/*
    52.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    52.6 + *
    52.7 + * Licensed under the Aduna BSD-style license.
    52.8 + */
    52.9 +package org.openrdf.sail.rdbms.algebra;
   52.10 +
   52.11 +import java.util.ArrayList;
   52.12 +import java.util.HashMap;
   52.13 +import java.util.List;
   52.14 +import java.util.Map;
   52.15 +
   52.16 +import org.openrdf.query.algebra.QueryModelNode;
   52.17 +import org.openrdf.query.algebra.QueryModelVisitor;
   52.18 +import org.openrdf.sail.rdbms.algebra.base.FromItem;
   52.19 +import org.openrdf.sail.rdbms.algebra.base.RdbmsQueryModelVisitorBase;
   52.20 +import org.openrdf.sail.rdbms.schema.ValueTypes;
   52.21 +
   52.22 +/**
   52.23 + * An SQL UNION expression between two {@link FromItem}s.
   52.24 + * 
   52.25 + * @author James Leigh
   52.26 + * 
   52.27 + */
   52.28 +public class UnionItem extends FromItem {
   52.29 +
   52.30 +	private List<FromItem> union = new ArrayList<FromItem>();
   52.31 +
   52.32 +	public UnionItem(String alias) {
   52.33 +		super(alias);
   52.34 +	}
   52.35 +
   52.36 +	@Override
   52.37 +	public FromItem getFromItem(String alias) {
   52.38 +		for (FromItem from : union) {
   52.39 +			FromItem item = from.getFromItem(alias);
   52.40 +			if (item != null)
   52.41 +				return item;
   52.42 +		}
   52.43 +		return super.getFromItem(alias);
   52.44 +	}
   52.45 +
   52.46 +	public List<String> getSelectVarNames() {
   52.47 +		List<ColumnVar> vars = new ArrayList<ColumnVar>();
   52.48 +		for (FromItem from : union) {
   52.49 +			from.appendVars(vars);
   52.50 +		}
   52.51 +		List<String> selectVars = new ArrayList<String>();
   52.52 +		for (ColumnVar var : vars) {
   52.53 +			if (var.isHidden())
   52.54 +				continue;
   52.55 +			if (!selectVars.contains(var.getName())) {
   52.56 +				selectVars.add(var.getName());
   52.57 +			}
   52.58 +		}
   52.59 +		return selectVars;
   52.60 +	}
   52.61 +
   52.62 +	public List<ColumnVar> getSelectColumns() {
   52.63 +		List<ColumnVar> vars = new ArrayList<ColumnVar>();
   52.64 +		for (FromItem from : union) {
   52.65 +			from.appendVars(vars);
   52.66 +		}
   52.67 +		List<ColumnVar> columns = new ArrayList<ColumnVar>();
   52.68 +		Map<String, ColumnVar> selectVars = new HashMap<String, ColumnVar>();
   52.69 +		for (ColumnVar var : vars) {
   52.70 +			if (var.isHidden())
   52.71 +				continue;
   52.72 +			if (selectVars.containsKey(var.getName())) {
   52.73 +				ColumnVar existing = selectVars.get(var.getName());
   52.74 +				existing.setValue(null);
   52.75 +				ValueTypes types = existing.getTypes();
   52.76 +				types = types.clone().merge(var.getTypes());
   52.77 +				existing.setTypes(types);
   52.78 +			}
   52.79 +			else {
   52.80 +				String name = var.getAlias() + var.getColumn();
   52.81 +				ColumnVar as = var.as(getAlias(), name);
   52.82 +				columns.add(as);
   52.83 +				selectVars.put(var.getName(), as);
   52.84 +			}
   52.85 +		}
   52.86 +		return columns;
   52.87 +	}
   52.88 +
   52.89 +	@Override
   52.90 +	public List<ColumnVar> appendVars(List<ColumnVar> columns) {
   52.91 +		columns.addAll(getSelectColumns());
   52.92 +		return super.appendVars(columns);
   52.93 +	}
   52.94 +
   52.95 +	@Override
   52.96 +	public ColumnVar getVar(String name) {
   52.97 +		for (ColumnVar var : appendVars(new ArrayList<ColumnVar>())) {
   52.98 +			if (var.getName().equals(name)) {
   52.99 +				return var;
  52.100 +			}
  52.101 +		}
  52.102 +		return null;
  52.103 +	}
  52.104 +
  52.105 +	@Override
  52.106 +	public ColumnVar getVarForChildren(String name) {
  52.107 +		for (FromItem join : union) {
  52.108 +			ColumnVar var = join.getVar(name);
  52.109 +			if (var != null)
  52.110 +				return var;
  52.111 +		}
  52.112 +		return super.getVarForChildren(name);
  52.113 +	}
  52.114 +
  52.115 +	public void addUnion(FromItem from) {
  52.116 +		union.add(from);
  52.117 +		from.setParentNode(this);
  52.118 +	}
  52.119 +
  52.120 +	public List<FromItem> getUnion() {
  52.121 +		return union;
  52.122 +	}
  52.123 +
  52.124 +	@Override
  52.125 +	public UnionItem clone() {
  52.126 +		UnionItem clone = (UnionItem)super.clone();
  52.127 +		clone.union = new ArrayList<FromItem>();
  52.128 +		for (FromItem from : union) {
  52.129 +			clone.addUnion(from.clone());
  52.130 +		}
  52.131 +		return clone;
  52.132 +	}
  52.133 +
  52.134 +	@Override
  52.135 +	public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
  52.136 +		throws X
  52.137 +	{
  52.138 +		visitor.meet(this);
  52.139 +	}
  52.140 +
  52.141 +	@Override
  52.142 +	public void replaceChildNode(QueryModelNode current, QueryModelNode replacement) {
  52.143 +		for (int i = 0, n = union.size(); i < n; i++) {
  52.144 +			if (current == union.get(i)) {
  52.145 +				union.set(i, (FromItem)replacement);
  52.146 +				return;
  52.147 +			}
  52.148 +		}
  52.149 +		super.replaceChildNode(current, replacement);
  52.150 +	}
  52.151 +
  52.152 +	@Override
  52.153 +	public <X extends Exception> void visitChildren(QueryModelVisitor<X> visitor)
  52.154 +		throws X
  52.155 +	{
  52.156 +		super.visitChildren(visitor);
  52.157 +		for (FromItem join : new ArrayList<FromItem>(union)) {
  52.158 +			join.visit(visitor);
  52.159 +		}
  52.160 +	}
  52.161 +
  52.162 +}
    53.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    53.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/base/BinarySqlOperator.java	Thu May 24 13:58:55 2012 +0300
    53.3 @@ -0,0 +1,132 @@
    53.4 +/*
    53.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    53.6 + *
    53.7 + * Licensed under the Aduna BSD-style license.
    53.8 + */
    53.9 +package org.openrdf.sail.rdbms.algebra.base;
   53.10 +
   53.11 +import org.openrdf.query.algebra.QueryModelNode;
   53.12 +import org.openrdf.query.algebra.QueryModelVisitor;
   53.13 +import org.openrdf.query.algebra.helpers.QueryModelTreePrinter;
   53.14 +import org.openrdf.sail.rdbms.optimizers.SqlConstantOptimizer;
   53.15 +
   53.16 +/**
   53.17 + * An abstract binary sql operator with two arguments.
   53.18 + * 
   53.19 + * @author James Leigh
   53.20 + * 
   53.21 + */
   53.22 +public abstract class BinarySqlOperator extends RdbmsQueryModelNodeBase implements SqlExpr {
   53.23 +
   53.24 +	private SqlExpr leftArg;
   53.25 +
   53.26 +	private SqlExpr rightArg;
   53.27 +
   53.28 +	public BinarySqlOperator() {
   53.29 +		super();
   53.30 +	}
   53.31 +
   53.32 +	public BinarySqlOperator(SqlExpr leftArg, SqlExpr rightArg) {
   53.33 +		super();
   53.34 +		setLeftArg(leftArg);
   53.35 +		setRightArg(rightArg);
   53.36 +	}
   53.37 +
   53.38 +	public SqlExpr getLeftArg() {
   53.39 +		return leftArg;
   53.40 +	}
   53.41 +
   53.42 +	public void setLeftArg(SqlExpr leftArg) {
   53.43 +		this.leftArg = leftArg;
   53.44 +		leftArg.setParentNode(this);
   53.45 +	}
   53.46 +
   53.47 +	public SqlExpr getRightArg() {
   53.48 +		return rightArg;
   53.49 +	}
   53.50 +
   53.51 +	public void setRightArg(SqlExpr rightArg) {
   53.52 +		this.rightArg = rightArg;
   53.53 +		rightArg.setParentNode(this);
   53.54 +	}
   53.55 +
   53.56 +	@Override
   53.57 +	public <X extends Exception> void visitChildren(QueryModelVisitor<X> visitor)
   53.58 +		throws X
   53.59 +	{
   53.60 +		leftArg.visit(visitor);
   53.61 +		rightArg.visit(visitor);
   53.62 +	}
   53.63 +
   53.64 +	@Override
   53.65 +	public void replaceChildNode(QueryModelNode current, QueryModelNode replacement) {
   53.66 +		if (leftArg == current) {
   53.67 +			setLeftArg((SqlExpr)replacement);
   53.68 +		}
   53.69 +		else if (rightArg == current) {
   53.70 +			setRightArg((SqlExpr)replacement);
   53.71 +		}
   53.72 +		else {
   53.73 +			super.replaceChildNode(current, replacement);
   53.74 +		}
   53.75 +	}
   53.76 +
   53.77 +	@Override
   53.78 +	public BinarySqlOperator clone() {
   53.79 +		BinarySqlOperator clone = (BinarySqlOperator)super.clone();
   53.80 +		clone.setLeftArg(leftArg.clone());
   53.81 +		clone.setRightArg(rightArg.clone());
   53.82 +		return clone;
   53.83 +	}
   53.84 +
   53.85 +	@Override
   53.86 +	public int hashCode() {
   53.87 +		final int prime = 31;
   53.88 +		int result = 1;
   53.89 +		result = prime * result + ((leftArg == null) ? 0 : leftArg.hashCode());
   53.90 +		result = prime * result + ((rightArg == null) ? 0 : rightArg.hashCode());
   53.91 +		return result;
   53.92 +	}
   53.93 +
   53.94 +	@Override
   53.95 +	public boolean equals(Object obj) {
   53.96 +		if (this == obj)
   53.97 +			return true;
   53.98 +		if (obj == null)
   53.99 +			return false;
  53.100 +		if (getClass() != obj.getClass())
  53.101 +			return false;
  53.102 +		final BinarySqlOperator other = (BinarySqlOperator)obj;
  53.103 +		if (leftArg == null) {
  53.104 +			if (other.leftArg != null)
  53.105 +				return false;
  53.106 +		}
  53.107 +		else if (!leftArg.equals(other.leftArg))
  53.108 +			return false;
  53.109 +		if (rightArg == null) {
  53.110 +			if (other.rightArg != null)
  53.111 +				return false;
  53.112 +		}
  53.113 +		else if (!rightArg.equals(other.rightArg))
  53.114 +			return false;
  53.115 +		return true;
  53.116 +	}
  53.117 +
  53.118 +	@Override
  53.119 +	public String toString() {
  53.120 +		QueryModelTreePrinter treePrinter = new QueryModelTreePrinter();
  53.121 +		BinarySqlOperator clone = this.clone();
  53.122 +		UnarySqlOperator parent = new UnarySqlOperator(clone) {
  53.123 +
  53.124 +			@Override
  53.125 +			public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
  53.126 +				throws X
  53.127 +			{
  53.128 +				visitor.meetOther(this);
  53.129 +			}
  53.130 +		};
  53.131 +		new SqlConstantOptimizer().optimize(clone);
  53.132 +		parent.getArg().visit(treePrinter);
  53.133 +		return treePrinter.getTreeString();
  53.134 +	}
  53.135 +}
    54.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    54.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/base/BooleanValue.java	Thu May 24 13:58:55 2012 +0300
    54.3 @@ -0,0 +1,19 @@
    54.4 +/*
    54.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    54.6 + *
    54.7 + * Licensed under the Aduna BSD-style license.
    54.8 + */
    54.9 +package org.openrdf.sail.rdbms.algebra.base;
   54.10 +
   54.11 +/**
   54.12 + * A boolean value of true or false.
   54.13 + * 
   54.14 + * @author James Leigh
   54.15 + * 
   54.16 + */
   54.17 +public abstract class BooleanValue extends SqlConstant<Boolean> {
   54.18 +
   54.19 +	public BooleanValue(boolean value) {
   54.20 +		super(value);
   54.21 +	}
   54.22 +}
    55.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    55.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/base/FromItem.java	Thu May 24 13:58:55 2012 +0300
    55.3 @@ -0,0 +1,189 @@
    55.4 +/*
    55.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    55.6 + *
    55.7 + * Licensed under the Aduna BSD-style license.
    55.8 + */
    55.9 +package org.openrdf.sail.rdbms.algebra.base;
   55.10 +
   55.11 +import java.util.ArrayList;
   55.12 +import java.util.List;
   55.13 +
   55.14 +import org.openrdf.query.algebra.QueryModelNode;
   55.15 +import org.openrdf.query.algebra.QueryModelVisitor;
   55.16 +import org.openrdf.sail.rdbms.algebra.ColumnVar;
   55.17 +
   55.18 +/**
   55.19 + * An item in the SQL from clause.
   55.20 + * 
   55.21 + * @author James Leigh
   55.22 + * 
   55.23 + */
   55.24 +public abstract class FromItem extends RdbmsQueryModelNodeBase {
   55.25 +
   55.26 +	private String alias;
   55.27 +
   55.28 +	private boolean left;
   55.29 +
   55.30 +	private List<FromItem> joins = new ArrayList<FromItem>();
   55.31 +
   55.32 +	private List<SqlExpr> filters = new ArrayList<SqlExpr>();
   55.33 +
   55.34 +	public FromItem(String alias) {
   55.35 +		super();
   55.36 +		this.alias = alias;
   55.37 +	}
   55.38 +
   55.39 +	public String getAlias() {
   55.40 +		return alias;
   55.41 +	}
   55.42 +
   55.43 +	public boolean isLeft() {
   55.44 +		return left;
   55.45 +	}
   55.46 +
   55.47 +	public void setLeft(boolean left) {
   55.48 +		this.left = left;
   55.49 +	}
   55.50 +
   55.51 +	public List<SqlExpr> getFilters() {
   55.52 +		return filters;
   55.53 +	}
   55.54 +
   55.55 +	public void addFilter(SqlExpr filter) {
   55.56 +		this.filters.add(filter);
   55.57 +		filter.setParentNode(this);
   55.58 +	}
   55.59 +
   55.60 +	public List<FromItem> getJoins() {
   55.61 +		return joins;
   55.62 +	}
   55.63 +
   55.64 +	public ColumnVar getVarForChildren(String name) {
   55.65 +		for (FromItem join : joins) {
   55.66 +			ColumnVar var = join.getVar(name);
   55.67 +			if (var != null)
   55.68 +				return var;
   55.69 +		}
   55.70 +		return null;
   55.71 +	}
   55.72 +
   55.73 +	public ColumnVar getVar(String name) {
   55.74 +		return getVarForChildren(name);
   55.75 +	}
   55.76 +
   55.77 +	public void addJoin(FromItem join) {
   55.78 +		joins.add(join);
   55.79 +		joinAdded(join);
   55.80 +	}
   55.81 +
   55.82 +	public void addJoinBefore(FromItem valueJoin, FromItem join) {
   55.83 +		for (int i = 0, n = joins.size(); i < n; i++) {
   55.84 +			if (joins.get(i) == join) {
   55.85 +				joins.add(i, valueJoin);
   55.86 +				joinAdded(valueJoin);
   55.87 +				return;
   55.88 +			}
   55.89 +		}
   55.90 +		addJoin(valueJoin);
   55.91 +	}
   55.92 +
   55.93 +	protected void joinAdded(FromItem valueJoin) {
   55.94 +		valueJoin.setParentNode(this);
   55.95 +	}
   55.96 +
   55.97 +	public FromItem getFromItem(String alias) {
   55.98 +		if (this.alias.equals(alias))
   55.99 +			return this;
  55.100 +		for (FromItem join : joins) {
  55.101 +			FromItem result = join.getFromItem(alias);
  55.102 +			if (result != null)
  55.103 +				return result;
  55.104 +		}
  55.105 +		return null;
  55.106 +	}
  55.107 +
  55.108 +	public FromItem getFromItemNotInUnion(String alias) {
  55.109 +		if (this.alias.equals(alias))
  55.110 +			return this;
  55.111 +		for (FromItem join : joins) {
  55.112 +			FromItem result = join.getFromItemNotInUnion(alias);
  55.113 +			if (result != null)
  55.114 +				return result;
  55.115 +		}
  55.116 +		return null;
  55.117 +	}
  55.118 +
  55.119 +	public void removeFilter(SqlExpr sqlExpr) {
  55.120 +		for (int i = filters.size() - 1; i >= 0; i--) {
  55.121 +			if (filters.get(i) == sqlExpr) {
  55.122 +				filters.remove(i);
  55.123 +				break;
  55.124 +			}
  55.125 +		}
  55.126 +	}
  55.127 +
  55.128 +	public List<ColumnVar> appendVars(List<ColumnVar> vars) {
  55.129 +		for (FromItem join : joins) {
  55.130 +			join.appendVars(vars);
  55.131 +		}
  55.132 +		return vars;
  55.133 +	}
  55.134 +
  55.135 +	@Override
  55.136 +	public String getSignature() {
  55.137 +		StringBuilder sb = new StringBuilder();
  55.138 +		if (left) {
  55.139 +			sb.append("LEFT ");
  55.140 +		}
  55.141 +		sb.append(super.getSignature());
  55.142 +		sb.append(" ").append(alias);
  55.143 +		return sb.toString();
  55.144 +	}
  55.145 +
  55.146 +	@Override
  55.147 +	public FromItem clone() {
  55.148 +		FromItem clone = (FromItem)super.clone();
  55.149 +		clone.joins = new ArrayList<FromItem>();
  55.150 +		for (FromItem join : joins) {
  55.151 +			clone.addJoin(join.clone());
  55.152 +		}
  55.153 +		clone.filters = new ArrayList<SqlExpr>();
  55.154 +		for (SqlExpr expr : filters) {
  55.155 +			clone.addFilter(expr.clone());
  55.156 +		}
  55.157 +		return clone;
  55.158 +	}
  55.159 +
  55.160 +	@Override
  55.161 +	public <X extends Exception> void visitChildren(QueryModelVisitor<X> visitor)
  55.162 +		throws X
  55.163 +	{
  55.164 +		super.visitChildren(visitor);
  55.165 +		for (FromItem join : new ArrayList<FromItem>(joins)) {
  55.166 +			join.visit(visitor);
  55.167 +		}
  55.168 +		for (SqlExpr expr : new ArrayList<SqlExpr>(filters)) {
  55.169 +			expr.visit(visitor);
  55.170 +		}
  55.171 +	}
  55.172 +
  55.173 +	@Override
  55.174 +	public void replaceChildNode(QueryModelNode current, QueryModelNode replacement) {
  55.175 +		for (int i = 0, n = joins.size(); i < n; i++) {
  55.176 +			if (current == joins.get(i)) {
  55.177 +				joins.set(i, (FromItem)replacement);
  55.178 +				joinAdded((FromItem)replacement);
  55.179 +				return;
  55.180 +			}
  55.181 +		}
  55.182 +		for (int i = 0, n = filters.size(); i < n; i++) {
  55.183 +			if (current == filters.get(i)) {
  55.184 +				filters.set(i, (SqlExpr)replacement);
  55.185 +				replacement.setParentNode(this);
  55.186 +				return;
  55.187 +			}
  55.188 +		}
  55.189 +		super.replaceChildNode(current, replacement);
  55.190 +	}
  55.191 +
  55.192 +}
    56.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    56.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/base/RdbmsQueryModelNodeBase.java	Thu May 24 13:58:55 2012 +0300
    56.3 @@ -0,0 +1,32 @@
    56.4 +/*
    56.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    56.6 + *
    56.7 + * Licensed under the Aduna BSD-style license.
    56.8 + */
    56.9 +package org.openrdf.sail.rdbms.algebra.base;
   56.10 +
   56.11 +import org.openrdf.query.algebra.QueryModelNodeBase;
   56.12 +import org.openrdf.query.algebra.QueryModelVisitor;
   56.13 +
   56.14 +/**
   56.15 + * An extension to {@link QueryModelNodeBase} for SQL query algebra.
   56.16 + * 
   56.17 + * @author James Leigh
   56.18 + * 
   56.19 + */
   56.20 +public abstract class RdbmsQueryModelNodeBase extends QueryModelNodeBase {
   56.21 +
   56.22 +	public <X extends Exception> void visit(QueryModelVisitor<X> visitor)
   56.23 +		throws X
   56.24 +	{
   56.25 +		if (visitor instanceof RdbmsQueryModelVisitorBase) {
   56.26 +			visit((RdbmsQueryModelVisitorBase<X>)visitor);
   56.27 +		}
   56.28 +		else {
   56.29 +			visitor.meetOther(this);
   56.30 +		}
   56.31 +	}
   56.32 +
   56.33 +	public abstract <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
   56.34 +		throws X;
   56.35 +}
    57.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    57.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/base/RdbmsQueryModelVisitorBase.java	Thu May 24 13:58:55 2012 +0300
    57.3 @@ -0,0 +1,313 @@
    57.4 +/*
    57.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    57.6 + *
    57.7 + * Licensed under the Aduna BSD-style license.
    57.8 + */
    57.9 +package org.openrdf.sail.rdbms.algebra.base;
   57.10 +
   57.11 +import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;
   57.12 +import org.openrdf.sail.rdbms.algebra.BNodeColumn;
   57.13 +import org.openrdf.sail.rdbms.algebra.DatatypeColumn;
   57.14 +import org.openrdf.sail.rdbms.algebra.DateTimeColumn;
   57.15 +import org.openrdf.sail.rdbms.algebra.DoubleValue;
   57.16 +import org.openrdf.sail.rdbms.algebra.FalseValue;
   57.17 +import org.openrdf.sail.rdbms.algebra.HashColumn;
   57.18 +import org.openrdf.sail.rdbms.algebra.IdColumn;
   57.19 +import org.openrdf.sail.rdbms.algebra.JoinItem;
   57.20 +import org.openrdf.sail.rdbms.algebra.LabelColumn;
   57.21 +import org.openrdf.sail.rdbms.algebra.LanguageColumn;
   57.22 +import org.openrdf.sail.rdbms.algebra.LongLabelColumn;
   57.23 +import org.openrdf.sail.rdbms.algebra.LongURIColumn;
   57.24 +import org.openrdf.sail.rdbms.algebra.NumberValue;
   57.25 +import org.openrdf.sail.rdbms.algebra.NumericColumn;
   57.26 +import org.openrdf.sail.rdbms.algebra.RefIdColumn;
   57.27 +import org.openrdf.sail.rdbms.algebra.SelectProjection;
   57.28 +import org.openrdf.sail.rdbms.algebra.SelectQuery;
   57.29 +import org.openrdf.sail.rdbms.algebra.SqlAbs;
   57.30 +import org.openrdf.sail.rdbms.algebra.SqlAnd;
   57.31 +import org.openrdf.sail.rdbms.algebra.SqlCase;
   57.32 +import org.openrdf.sail.rdbms.algebra.SqlCast;
   57.33 +import org.openrdf.sail.rdbms.algebra.SqlCompare;
   57.34 +import org.openrdf.sail.rdbms.algebra.SqlConcat;
   57.35 +import org.openrdf.sail.rdbms.algebra.SqlEq;
   57.36 +import org.openrdf.sail.rdbms.algebra.SqlIsNull;
   57.37 +import org.openrdf.sail.rdbms.algebra.SqlLike;
   57.38 +import org.openrdf.sail.rdbms.algebra.SqlLowerCase;
   57.39 +import org.openrdf.sail.rdbms.algebra.SqlMathExpr;
   57.40 +import org.openrdf.sail.rdbms.algebra.SqlNot;
   57.41 +import org.openrdf.sail.rdbms.algebra.SqlNull;
   57.42 +import org.openrdf.sail.rdbms.algebra.SqlOr;
   57.43 +import org.openrdf.sail.rdbms.algebra.SqlRegex;
   57.44 +import org.openrdf.sail.rdbms.algebra.SqlShift;
   57.45 +import org.openrdf.sail.rdbms.algebra.StringValue;
   57.46 +import org.openrdf.sail.rdbms.algebra.TrueValue;
   57.47 +import org.openrdf.sail.rdbms.algebra.URIColumn;
   57.48 +import org.openrdf.sail.rdbms.algebra.UnionItem;
   57.49 +
   57.50 +/**
   57.51 + * Base class for RDBMS visitor classes. This class is extended with additional
   57.52 + * meet methods.
   57.53 + * 
   57.54 + * @author James Leigh
   57.55 + * 
   57.56 + */
   57.57 +public class RdbmsQueryModelVisitorBase<X extends Exception> extends QueryModelVisitorBase<X> {
   57.58 +
   57.59 +	public void meet(BNodeColumn node)
   57.60 +		throws X
   57.61 +	{
   57.62 +		meetValueColumnBase(node);
   57.63 +	}
   57.64 +
   57.65 +	public void meet(DatatypeColumn node)
   57.66 +		throws X
   57.67 +	{
   57.68 +		meetValueColumnBase(node);
   57.69 +	}
   57.70 +
   57.71 +	public void meet(DateTimeColumn node)
   57.72 +		throws X
   57.73 +	{
   57.74 +		meetValueColumnBase(node);
   57.75 +	}
   57.76 +
   57.77 +	public void meet(DoubleValue node)
   57.78 +		throws X
   57.79 +	{
   57.80 +		meetSqlConstant(node);
   57.81 +	}
   57.82 +
   57.83 +	public void meet(FalseValue node)
   57.84 +		throws X
   57.85 +	{
   57.86 +		meetSqlConstant(node);
   57.87 +	}
   57.88 +
   57.89 +	public void meet(HashColumn node)
   57.90 +		throws X
   57.91 +	{
   57.92 +		meetValueColumnBase(node);
   57.93 +	}
   57.94 +
   57.95 +	public void meet(IdColumn node)
   57.96 +		throws X
   57.97 +	{
   57.98 +		meetSqlExpr(node);
   57.99 +	}
  57.100 +
  57.101 +	public void meet(JoinItem node)
  57.102 +		throws X
  57.103 +	{
  57.104 +		meetFromItem(node);
  57.105 +	}
  57.106 +
  57.107 +	public void meet(LabelColumn node)
  57.108 +		throws X
  57.109 +	{
  57.110 +		meetValueColumnBase(node);
  57.111 +	}
  57.112 +
  57.113 +	public void meet(LanguageColumn node)
  57.114 +		throws X
  57.115 +	{
  57.116 +		meetValueColumnBase(node);
  57.117 +	}
  57.118 +
  57.119 +	public void meet(LongLabelColumn node)
  57.120 +		throws X
  57.121 +	{
  57.122 +		meetValueColumnBase(node);
  57.123 +	}
  57.124 +
  57.125 +	public void meet(LongURIColumn node)
  57.126 +		throws X
  57.127 +	{
  57.128 +		meetValueColumnBase(node);
  57.129 +	}
  57.130 +
  57.131 +	public void meet(NumberValue node)
  57.132 +		throws X
  57.133 +	{
  57.134 +		meetSqlConstant(node);
  57.135 +	}
  57.136 +
  57.137 +	public void meet(NumericColumn node)
  57.138 +		throws X
  57.139 +	{
  57.140 +		meetValueColumnBase(node);
  57.141 +	}
  57.142 +
  57.143 +	public void meet(RefIdColumn node)
  57.144 +		throws X
  57.145 +	{
  57.146 +		meetValueColumnBase(node);
  57.147 +	}
  57.148 +
  57.149 +	public void meet(SelectProjection node)
  57.150 +		throws X
  57.151 +	{
  57.152 +		meetNode(node);
  57.153 +	}
  57.154 +
  57.155 +	public void meet(SelectQuery node)
  57.156 +		throws X
  57.157 +	{
  57.158 +		meetNode(node);
  57.159 +	}
  57.160 +
  57.161 +	public void meet(SqlAbs node)
  57.162 +		throws X
  57.163 +	{
  57.164 +		meetUnarySqlOperator(node);
  57.165 +	}
  57.166 +
  57.167 +	public void meet(SqlAnd node)
  57.168 +		throws X
  57.169 +	{
  57.170 +		meetBinarySqlOperator(node);
  57.171 +	}
  57.172 +
  57.173 +	public void meet(SqlCase node)
  57.174 +		throws X
  57.175 +	{
  57.176 +		meetNode(node);
  57.177 +	}
  57.178 +
  57.179 +	public void meet(SqlCast node)
  57.180 +		throws X
  57.181 +	{
  57.182 +		meetUnarySqlOperator(node);
  57.183 +	}
  57.184 +
  57.185 +	public void meet(SqlCompare node)
  57.186 +		throws X
  57.187 +	{
  57.188 +		meetBinarySqlOperator(node);
  57.189 +	}
  57.190 +
  57.191 +	public void meet(SqlConcat node)
  57.192 +		throws X
  57.193 +	{
  57.194 +		meetBinarySqlOperator(node);
  57.195 +	}
  57.196 +
  57.197 +	public void meet(SqlEq node)
  57.198 +		throws X
  57.199 +	{
  57.200 +		meetBinarySqlOperator(node);
  57.201 +	}
  57.202 +
  57.203 +	public void meet(SqlIsNull node)
  57.204 +		throws X
  57.205 +	{
  57.206 +		meetUnarySqlOperator(node);
  57.207 +	}
  57.208 +
  57.209 +	public void meet(SqlLike node)
  57.210 +		throws X
  57.211 +	{
  57.212 +		meetBinarySqlOperator(node);
  57.213 +	}
  57.214 +
  57.215 +	public void meet(SqlLowerCase node)
  57.216 +		throws X
  57.217 +	{
  57.218 +		meetUnarySqlOperator(node);
  57.219 +	}
  57.220 +
  57.221 +	public void meet(SqlMathExpr node)
  57.222 +		throws X
  57.223 +	{
  57.224 +		meetBinarySqlOperator(node);
  57.225 +	}
  57.226 +
  57.227 +	public void meet(SqlNot node)
  57.228 +		throws X
  57.229 +	{
  57.230 +		meetUnarySqlOperator(node);
  57.231 +	}
  57.232 +
  57.233 +	public void meet(SqlNull node)
  57.234 +		throws X
  57.235 +	{
  57.236 +		meetSqlConstant(node);
  57.237 +	}
  57.238 +
  57.239 +	public void meet(SqlOr node)
  57.240 +		throws X
  57.241 +	{
  57.242 +		meetBinarySqlOperator(node);
  57.243 +	}
  57.244 +
  57.245 +	public void meet(SqlRegex node)
  57.246 +		throws X
  57.247 +	{
  57.248 +		meetBinarySqlOperator(node);
  57.249 +	}
  57.250 +
  57.251 +	public void meet(SqlShift node)
  57.252 +		throws X
  57.253 +	{
  57.254 +		meetUnarySqlOperator(node);
  57.255 +	}
  57.256 +
  57.257 +	public void meet(StringValue node)
  57.258 +		throws X
  57.259 +	{
  57.260 +		meetSqlConstant(node);
  57.261 +	}
  57.262 +
  57.263 +	public void meet(TrueValue node)
  57.264 +		throws X
  57.265 +	{
  57.266 +		meetSqlConstant(node);
  57.267 +	}
  57.268 +
  57.269 +	public void meet(UnionItem node)
  57.270 +		throws X
  57.271 +	{
  57.272 +		meetFromItem(node);
  57.273 +	}
  57.274 +
  57.275 +	public void meet(URIColumn node)
  57.276 +		throws X
  57.277 +	{
  57.278 +		meetValueColumnBase(node);
  57.279 +	}
  57.280 +
  57.281 +	protected void meetBinarySqlOperator(BinarySqlOperator node)
  57.282 +		throws X
  57.283 +	{
  57.284 +		meetNode(node);
  57.285 +	}
  57.286 +
  57.287 +	protected void meetFromItem(FromItem node)
  57.288 +		throws X
  57.289 +	{
  57.290 +		meetNode(node);
  57.291 +	}
  57.292 +
  57.293 +	protected void meetSqlConstant(SqlConstant<?> node)
  57.294 +		throws X
  57.295 +	{
  57.296 +		meetNode(node);
  57.297 +	}
  57.298 +
  57.299 +	protected void meetSqlExpr(SqlExpr node)
  57.300 +		throws X
  57.301 +	{
  57.302 +		meetNode(node);
  57.303 +	}
  57.304 +
  57.305 +	protected void meetUnarySqlOperator(UnarySqlOperator node)
  57.306 +		throws X
  57.307 +	{
  57.308 +		meetNode(node);
  57.309 +	}
  57.310 +
  57.311 +	protected void meetValueColumnBase(ValueColumnBase node)
  57.312 +		throws X
  57.313 +	{
  57.314 +		meetSqlExpr(node);
  57.315 +	}
  57.316 +}
    58.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    58.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/base/SqlConstant.java	Thu May 24 13:58:55 2012 +0300
    58.3 @@ -0,0 +1,72 @@
    58.4 +/*
    58.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    58.6 + *
    58.7 + * Licensed under the Aduna BSD-style license.
    58.8 + */
    58.9 +package org.openrdf.sail.rdbms.algebra.base;
   58.10 +
   58.11 +/**
   58.12 + * A constant SQL value, like a varchar or number.
   58.13 + * 
   58.14 + * @author James Leigh
   58.15 + * 
   58.16 + */
   58.17 +public abstract class SqlConstant<T> extends RdbmsQueryModelNodeBase implements SqlExpr {
   58.18 +
   58.19 +	private T value;
   58.20 +
   58.21 +	public SqlConstant() {
   58.22 +		super();
   58.23 +	}
   58.24 +
   58.25 +	public SqlConstant(T value) {
   58.26 +		super();
   58.27 +		this.value = value;
   58.28 +	}
   58.29 +
   58.30 +	public T getValue() {
   58.31 +		return value;
   58.32 +	}
   58.33 +
   58.34 +	public void setValue(T value) {
   58.35 +		this.value = value;
   58.36 +	}
   58.37 +
   58.38 +	@Override
   58.39 +	public String getSignature() {
   58.40 +		return super.getSignature() + " " + value;
   58.41 +	}
   58.42 +
   58.43 +	@Override
   58.44 +	public SqlConstant<T> clone() {
   58.45 +		SqlConstant<T> clone = (SqlConstant<T>)super.clone();
   58.46 +		clone.setValue(value);
   58.47 +		return clone;
   58.48 +	}
   58.49 +
   58.50 +	@Override
   58.51 +	public int hashCode() {
   58.52 +		final int prime = 31;
   58.53 +		int result = 1;
   58.54 +		result = prime * result + ((value == null) ? 0 : value.hashCode());
   58.55 +		return result;
   58.56 +	}
   58.57 +
   58.58 +	@Override
   58.59 +	public boolean equals(Object obj) {
   58.60 +		if (this == obj)
   58.61 +			return true;
   58.62 +		if (obj == null)
   58.63 +			return false;
   58.64 +		if (getClass() != obj.getClass())
   58.65 +			return false;
   58.66 +		final SqlConstant other = (SqlConstant)obj;
   58.67 +		if (value == null) {
   58.68 +			if (other.value != null)
   58.69 +				return false;
   58.70 +		}
   58.71 +		else if (!value.equals(other.value))
   58.72 +			return false;
   58.73 +		return true;
   58.74 +	}
   58.75 +}
    59.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    59.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/base/SqlExpr.java	Thu May 24 13:58:55 2012 +0300
    59.3 @@ -0,0 +1,19 @@
    59.4 +/*
    59.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    59.6 + *
    59.7 + * Licensed under the Aduna BSD-style license.
    59.8 + */
    59.9 +package org.openrdf.sail.rdbms.algebra.base;
   59.10 +
   59.11 +import org.openrdf.query.algebra.QueryModelNode;
   59.12 +
   59.13 +/**
   59.14 + * An SQL expression.
   59.15 + * 
   59.16 + * @author James Leigh
   59.17 + * 
   59.18 + */
   59.19 +public interface SqlExpr extends QueryModelNode {
   59.20 +
   59.21 +	public abstract SqlExpr clone();
   59.22 +}
    60.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    60.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/base/SqlExprSupport.java	Thu May 24 13:58:55 2012 +0300
    60.3 @@ -0,0 +1,212 @@
    60.4 +/*
    60.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    60.6 + *
    60.7 + * Licensed under the Aduna BSD-style license.
    60.8 + */
    60.9 +package org.openrdf.sail.rdbms.algebra.base;
   60.10 +
   60.11 +import java.sql.Types;
   60.12 +
   60.13 +import org.openrdf.model.URI;
   60.14 +import org.openrdf.model.vocabulary.XMLSchema;
   60.15 +import org.openrdf.query.algebra.MathExpr;
   60.16 +import org.openrdf.query.algebra.Compare.CompareOp;
   60.17 +import org.openrdf.sail.rdbms.algebra.DoubleValue;
   60.18 +import org.openrdf.sail.rdbms.algebra.FalseValue;
   60.19 +import org.openrdf.sail.rdbms.algebra.SqlAbs;
   60.20 +import org.openrdf.sail.rdbms.algebra.SqlAnd;
   60.21 +import org.openrdf.sail.rdbms.algebra.SqlCase;
   60.22 +import org.openrdf.sail.rdbms.algebra.SqlCast;
   60.23 +import org.openrdf.sail.rdbms.algebra.SqlCompare;
   60.24 +import org.openrdf.sail.rdbms.algebra.SqlConcat;
   60.25 +import org.openrdf.sail.rdbms.algebra.SqlEq;
   60.26 +import org.openrdf.sail.rdbms.algebra.SqlIsNull;
   60.27 +import org.openrdf.sail.rdbms.algebra.SqlLike;
   60.28 +import org.openrdf.sail.rdbms.algebra.SqlLowerCase;
   60.29 +import org.openrdf.sail.rdbms.algebra.SqlMathExpr;
   60.30 +import org.openrdf.sail.rdbms.algebra.SqlNot;
   60.31 +import org.openrdf.sail.rdbms.algebra.SqlNull;
   60.32 +import org.openrdf.sail.rdbms.algebra.SqlOr;
   60.33 +import org.openrdf.sail.rdbms.algebra.SqlRegex;
   60.34 +import org.openrdf.sail.rdbms.algebra.StringValue;
   60.35 +import org.openrdf.sail.rdbms.exceptions.UnsupportedRdbmsOperatorException;
   60.36 +
   60.37 +/**
   60.38 + * Support method to create SQL expressions.
   60.39 + * 
   60.40 + * @author James Leigh
   60.41 + * 
   60.42 + */
   60.43 +public class SqlExprSupport {
   60.44 +
   60.45 +	public static SqlExpr abs(SqlExpr arg) {
   60.46 +		return new SqlAbs(arg);
   60.47 +	}
   60.48 +
   60.49 +	public static SqlExpr and(SqlExpr left, SqlExpr right) {
   60.50 +		return new SqlAnd(left, right);
   60.51 +	}
   60.52 +
   60.53 +	public static SqlExpr cmp(SqlExpr left, CompareOp op, SqlExpr right) {
   60.54 +		return new SqlCompare(left, op, right);
   60.55 +	}
   60.56 +
   60.57 +	public static SqlExpr coalesce(SqlExpr... exprs) {
   60.58 +		SqlCase sqlCase = new SqlCase();
   60.59 +		for (SqlExpr expr : exprs) {
   60.60 +			sqlCase.when(isNotNull(expr.clone()), expr);
   60.61 +		}
   60.62 +		return sqlCase;
   60.63 +	}
   60.64 +
   60.65 +	public static SqlExpr concat(SqlExpr left, SqlExpr right) {
   60.66 +		return new SqlConcat(left, right);
   60.67 +	}
   60.68 +
   60.69 +	public static SqlExpr eq(SqlExpr left, SqlExpr right) {
   60.70 +		return new SqlEq(left, right);
   60.71 +	}
   60.72 +
   60.73 +	public static SqlExpr eqComparingNull(SqlExpr left, SqlExpr right) {
   60.74 +		SqlExpr leftIsNull = isNull(left.clone());
   60.75 +		SqlExpr rightIsNull = isNull(right.clone());
   60.76 +		SqlExpr bothNull = and(leftIsNull, rightIsNull);
   60.77 +		SqlExpr bothNotNull = and(not(leftIsNull), not(rightIsNull));
   60.78 +		return or(bothNull, and(bothNotNull, eq(left, right)));
   60.79 +	}
   60.80 +
   60.81 +	public static SqlExpr eqIfNotNull(SqlExpr left, SqlExpr right) {
   60.82 +		SqlExpr leftIsNotNull = isNotNull(left.clone());
   60.83 +		SqlExpr rightIsNotNull = isNotNull(right.clone());
   60.84 +		SqlExpr bothNotNull = and(leftIsNotNull, rightIsNotNull);
   60.85 +		return and(bothNotNull, eq(left, right));
   60.86 +	}
   60.87 +
   60.88 +	public static SqlExpr eqOrBothNull(SqlExpr left, SqlExpr right) {
   60.89 +		SqlExpr leftIsNull = isNull(left.clone());
   60.90 +		SqlExpr rightIsNull = isNull(right.clone());
   60.91 +		SqlExpr bothNull = and(leftIsNull, rightIsNull);
   60.92 +		return or(bothNull, eq(left, right));
   60.93 +	}
   60.94 +
   60.95 +	public static SqlExpr eqOrSimpleType(SqlExpr left, SqlExpr right) {
   60.96 +		SqlExpr bothSimple = and(simple(left), simple(right));
   60.97 +		return or(eq(left.clone(), right.clone()), bothSimple);
   60.98 +	}
   60.99 +
  60.100 +	public static SqlExpr ge(SqlExpr left, SqlExpr right) {
  60.101 +		return new SqlCompare(left, CompareOp.GE, right);
  60.102 +	}
  60.103 +
  60.104 +	public static SqlExpr gt(SqlExpr left, SqlExpr right) {
  60.105 +		return new SqlCompare(left, CompareOp.GT, right);
  60.106 +	}
  60.107 +
  60.108 +	public static SqlExpr in(SqlExpr compare, SqlExpr... values) {
  60.109 +		SqlExpr expr = null;
  60.110 +		for (SqlExpr value : values) {
  60.111 +			if (expr == null) {
  60.112 +				expr = new SqlEq(compare, value);
  60.113 +			}
  60.114 +			else {
  60.115 +				expr = or(expr, new SqlEq(compare.clone(), value));
  60.116 +			}
  60.117 +		}
  60.118 +		if (expr == null)
  60.119 +			return new FalseValue();
  60.120 +		return expr;
  60.121 +	}
  60.122 +
  60.123 +	public static SqlExpr isNotNull(SqlExpr arg) {
  60.124 +		return not(isNull(arg));
  60.125 +	}
  60.126 +
  60.127 +	public static SqlExpr isNull(SqlExpr arg) {
  60.128 +		return new SqlIsNull(arg);
  60.129 +	}
  60.130 +
  60.131 +	public static SqlExpr le(SqlExpr left, SqlExpr right) {
  60.132 +		return new SqlCompare(left, CompareOp.LE, right);
  60.133 +	}
  60.134 +
  60.135 +	public static SqlExpr like(SqlExpr left, SqlExpr right) {
  60.136 +		return new SqlLike(left, right);
  60.137 +	}
  60.138 +
  60.139 +	public static SqlExpr lowercase(SqlExpr arg) {
  60.140 +		return new SqlLowerCase(arg);
  60.141 +	}
  60.142 +
  60.143 +	public static SqlExpr lt(SqlExpr left, SqlExpr right) {
  60.144 +		return new SqlCompare(left, CompareOp.LT, right);
  60.145 +	}
  60.146 +
  60.147 +	public static SqlExpr neq(SqlExpr left, SqlExpr right) {
  60.148 +		return new SqlNot(new SqlEq(left, right));
  60.149 +	}
  60.150 +
  60.151 +	public static SqlExpr neqComparingNull(SqlExpr left, SqlExpr right) {
  60.152 +		SqlExpr leftIsNull = isNull(left.clone());
  60.153 +		SqlExpr rightIsNull = isNull(right.clone());
  60.154 +		SqlExpr onlyLeftIsNull = and(not(leftIsNull), rightIsNull.clone());
  60.155 +		SqlExpr onlyRightIsNull = and(leftIsNull.clone(), not(rightIsNull));
  60.156 +		SqlExpr compareNull = or(onlyRightIsNull, onlyLeftIsNull);
  60.157 +		return or(not(eq(left, right)), compareNull);
  60.158 +	}
  60.159 +
  60.160 +	public static SqlExpr not(SqlExpr arg) {
  60.161 +		return new SqlNot(arg);
  60.162 +	}
  60.163 +
  60.164 +	public static SqlExpr num(double value) {
  60.165 +		return new DoubleValue(value);
  60.166 +	}
  60.167 +
  60.168 +	public static SqlExpr or(SqlExpr left, SqlExpr right) {
  60.169 +		return new SqlOr(left, right);
  60.170 +	}
  60.171 +
  60.172 +	public static SqlExpr regex(SqlExpr value, SqlExpr pattern) {
  60.173 +		return new SqlRegex(value, pattern);
  60.174 +	}
  60.175 +
  60.176 +	public static SqlExpr regex(SqlExpr value, SqlExpr pattern, SqlExpr flags) {
  60.177 +		return new SqlRegex(value, pattern, flags);
  60.178 +	}
  60.179 +
  60.180 +	public static SqlExpr simple(SqlExpr arg) {
  60.181 +		SqlExpr isString = eq(arg.clone(), str(XMLSchema.STRING));
  60.182 +		return or(isNull(arg.clone()), isString);
  60.183 +	}
  60.184 +
  60.185 +	public static SqlExpr sqlNull() {
  60.186 +		return new SqlNull();
  60.187 +	}
  60.188 +
  60.189 +	public static SqlExpr str(String str) {
  60.190 +		if (str == null)
  60.191 +			return sqlNull();
  60.192 +		return new StringValue(str);
  60.193 +	}
  60.194 +
  60.195 +	public static SqlExpr str(URI uri) {
  60.196 +		return new StringValue(uri.stringValue());
  60.197 +	}
  60.198 +
  60.199 +	public static SqlExpr sub(SqlExpr left, SqlExpr right) {
  60.200 +		return new SqlMathExpr(left, MathExpr.MathOp.MINUS, right);
  60.201 +	}
  60.202 +
  60.203 +	public static SqlExpr text(SqlExpr arg) {
  60.204 +		return new SqlCast(arg, Types.VARCHAR);
  60.205 +	}
  60.206 +
  60.207 +	public static UnsupportedRdbmsOperatorException unsupported(Object arg) {
  60.208 +		return new UnsupportedRdbmsOperatorException(arg.toString());
  60.209 +	}
  60.210 +
  60.211 +	private SqlExprSupport() {
  60.212 +		// no constructor
  60.213 +	}
  60.214 +
  60.215 +}
    61.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    61.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/base/UnarySqlOperator.java	Thu May 24 13:58:55 2012 +0300
    61.3 @@ -0,0 +1,109 @@
    61.4 +/*
    61.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    61.6 + *
    61.7 + * Licensed under the Aduna BSD-style license.
    61.8 + */
    61.9 +package org.openrdf.sail.rdbms.algebra.base;
   61.10 +
   61.11 +import org.openrdf.query.algebra.QueryModelNode;
   61.12 +import org.openrdf.query.algebra.QueryModelVisitor;
   61.13 +import org.openrdf.query.algebra.helpers.QueryModelTreePrinter;
   61.14 +import org.openrdf.sail.rdbms.optimizers.SqlConstantOptimizer;
   61.15 +
   61.16 +/**
   61.17 + * An SQL operator with one argument.
   61.18 + * 
   61.19 + * @author James Leigh
   61.20 + * 
   61.21 + */
   61.22 +public abstract class UnarySqlOperator extends RdbmsQueryModelNodeBase implements SqlExpr {
   61.23 +
   61.24 +	private SqlExpr arg;
   61.25 +
   61.26 +	public UnarySqlOperator() {
   61.27 +		super();
   61.28 +	}
   61.29 +
   61.30 +	public UnarySqlOperator(SqlExpr arg) {
   61.31 +		super();
   61.32 +		setArg(arg);
   61.33 +	}
   61.34 +
   61.35 +	public SqlExpr getArg() {
   61.36 +		return arg;
   61.37 +	}
   61.38 +
   61.39 +	public void setArg(SqlExpr arg) {
   61.40 +		this.arg = arg;
   61.41 +		arg.setParentNode(this);
   61.42 +	}
   61.43 +
   61.44 +	@Override
   61.45 +	public <X extends Exception> void visitChildren(QueryModelVisitor<X> visitor)
   61.46 +		throws X
   61.47 +	{
   61.48 +		arg.visit(visitor);
   61.49 +	}
   61.50 +
   61.51 +	@Override
   61.52 +	public void replaceChildNode(QueryModelNode current, QueryModelNode replacement) {
   61.53 +		if (arg == current) {
   61.54 +			setArg((SqlExpr)replacement);
   61.55 +		}
   61.56 +		else {
   61.57 +			super.replaceChildNode(current, replacement);
   61.58 +		}
   61.59 +	}
   61.60 +
   61.61 +	@Override
   61.62 +	public UnarySqlOperator clone() {
   61.63 +		UnarySqlOperator clone = (UnarySqlOperator)super.clone();
   61.64 +		clone.setArg(arg.clone());
   61.65 +		return clone;
   61.66 +	}
   61.67 +
   61.68 +	@Override
   61.69 +	public int hashCode() {
   61.70 +		final int prime = 31;
   61.71 +		int result = 1;
   61.72 +		result = prime * result + ((arg == null) ? 0 : arg.hashCode());
   61.73 +		return result;
   61.74 +	}
   61.75 +
   61.76 +	@Override
   61.77 +	public boolean equals(Object obj) {
   61.78 +		if (this == obj)
   61.79 +			return true;
   61.80 +		if (obj == null)
   61.81 +			return false;
   61.82 +		if (getClass() != obj.getClass())
   61.83 +			return false;
   61.84 +		final UnarySqlOperator other = (UnarySqlOperator)obj;
   61.85 +		if (arg == null) {
   61.86 +			if (other.arg != null)
   61.87 +				return false;
   61.88 +		}
   61.89 +		else if (!arg.equals(other.arg))
   61.90 +			return false;
   61.91 +		return true;
   61.92 +	}
   61.93 +
   61.94 +	@Override
   61.95 +	public String toString() {
   61.96 +		QueryModelTreePrinter treePrinter = new QueryModelTreePrinter();
   61.97 +		UnarySqlOperator clone = this.clone();
   61.98 +		UnarySqlOperator parent = new UnarySqlOperator(clone) {
   61.99 +
  61.100 +			@Override
  61.101 +			public <X extends Exception> void visit(RdbmsQueryModelVisitorBase<X> visitor)
  61.102 +				throws X
  61.103 +			{
  61.104 +				visitor.meetOther(this);
  61.105 +			}
  61.106 +		};
  61.107 +		new SqlConstantOptimizer().optimize(clone);
  61.108 +		parent.getArg().visit(treePrinter);
  61.109 +		return treePrinter.getTreeString();
  61.110 +	}
  61.111 +
  61.112 +}
    62.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    62.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/base/ValueColumnBase.java	Thu May 24 13:58:55 2012 +0300
    62.3 @@ -0,0 +1,91 @@
    62.4 +/*
    62.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    62.6 + *
    62.7 + * Licensed under the Aduna BSD-style license.
    62.8 + */
    62.9 +package org.openrdf.sail.rdbms.algebra.base;
   62.10 +
   62.11 +import org.openrdf.query.algebra.Var;
   62.12 +import org.openrdf.sail.rdbms.algebra.ColumnVar;
   62.13 +
   62.14 +/**
   62.15 + * A column in an SQL expression.
   62.16 + * 
   62.17 + * @author James Leigh
   62.18 + * 
   62.19 + */
   62.20 +public abstract class ValueColumnBase extends RdbmsQueryModelNodeBase implements SqlExpr {
   62.21 +
   62.22 +	private String name;
   62.23 +
   62.24 +	private ColumnVar var;
   62.25 +
   62.26 +	public ValueColumnBase(Var var) {
   62.27 +		this.name = var.getName();
   62.28 +	}
   62.29 +
   62.30 +	public ValueColumnBase(ColumnVar var) {
   62.31 +		this.name = var.getName();
   62.32 +		setRdbmsVar(var);
   62.33 +	}
   62.34 +
   62.35 +	public String getVarName() {
   62.36 +		return name;
   62.37 +	}
   62.38 +
   62.39 +	public ColumnVar getRdbmsVar() {
   62.40 +		return var;
   62.41 +	}
   62.42 +
   62.43 +	public void setRdbmsVar(ColumnVar var) {
   62.44 +		assert var != null;
   62.45 +		this.var = var;
   62.46 +	}
   62.47 +
   62.48 +	public String getAlias() {
   62.49 +		return var.getAlias();
   62.50 +	}
   62.51 +
   62.52 +	public String getColumn() {
   62.53 +		return var.getColumn();
   62.54 +	}
   62.55 +
   62.56 +	@Override
   62.57 +	public String getSignature() {
   62.58 +		if (var != null)
   62.59 +			return super.getSignature() + " " + var;
   62.60 +		return super.getSignature() + " " + name;
   62.61 +	}
   62.62 +
   62.63 +	@Override
   62.64 +	public ValueColumnBase clone() {
   62.65 +		return (ValueColumnBase)super.clone();
   62.66 +	}
   62.67 +
   62.68 +	@Override
   62.69 +	public int hashCode() {
   62.70 +		final int prime = 31;
   62.71 +		int result = 1;
   62.72 +		result = prime * result + ((name == null) ? 0 : name.hashCode());
   62.73 +		return result;
   62.74 +	}
   62.75 +
   62.76 +	@Override
   62.77 +	public boolean equals(Object obj) {
   62.78 +		if (this == obj)
   62.79 +			return true;
   62.80 +		if (obj == null)
   62.81 +			return false;
   62.82 +		if (getClass() != obj.getClass())
   62.83 +			return false;
   62.84 +		final ValueColumnBase other = (ValueColumnBase)obj;
   62.85 +		if (name == null) {
   62.86 +			if (other.name != null)
   62.87 +				return false;
   62.88 +		}
   62.89 +		else if (!name.equals(other.name))
   62.90 +			return false;
   62.91 +		return true;
   62.92 +	}
   62.93 +
   62.94 +}
    63.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    63.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/factories/BNodeExprFactory.java	Thu May 24 13:58:55 2012 +0300
    63.3 @@ -0,0 +1,103 @@
    63.4 +/*
    63.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    63.6 + *
    63.7 + * Licensed under the Aduna BSD-style license.
    63.8 + */
    63.9 +package org.openrdf.sail.rdbms.algebra.factories;
   63.10 +
   63.11 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.sqlNull;
   63.12 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.str;
   63.13 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.unsupported;
   63.14 +
   63.15 +import org.openrdf.model.BNode;
   63.16 +import org.openrdf.model.Value;
   63.17 +import org.openrdf.query.algebra.Datatype;
   63.18 +import org.openrdf.query.algebra.Lang;
   63.19 +import org.openrdf.query.algebra.MathExpr;
   63.20 +import org.openrdf.query.algebra.QueryModelNode;
   63.21 +import org.openrdf.query.algebra.Str;
   63.22 +import org.openrdf.query.algebra.ValueConstant;
   63.23 +import org.openrdf.query.algebra.ValueExpr;
   63.24 +import org.openrdf.query.algebra.Var;
   63.25 +import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;
   63.26 +import org.openrdf.sail.rdbms.algebra.BNodeColumn;
   63.27 +import org.openrdf.sail.rdbms.algebra.SqlNull;
   63.28 +import org.openrdf.sail.rdbms.algebra.StringValue;
   63.29 +import org.openrdf.sail.rdbms.algebra.base.SqlExpr;
   63.30 +import org.openrdf.sail.rdbms.exceptions.UnsupportedRdbmsOperatorException;
   63.31 +
   63.32 +/**
   63.33 + * BNode expression factory - creates a {@link BNodeColumn} or a
   63.34 + * {@link StringValue} of the BNode ID.
   63.35 + * 
   63.36 + * @author James Leigh
   63.37 + * 
   63.38 + */
   63.39 +public class BNodeExprFactory extends QueryModelVisitorBase<UnsupportedRdbmsOperatorException> {
   63.40 +
   63.41 +	protected SqlExpr result;
   63.42 +
   63.43 +	public SqlExpr createBNodeExpr(ValueExpr expr)
   63.44 +		throws UnsupportedRdbmsOperatorException
   63.45 +	{
   63.46 +		result = null;
   63.47 +		if (expr == null)
   63.48 +			return new SqlNull();
   63.49 +		expr.visit(this);
   63.50 +		if (result == null)
   63.51 +			return new SqlNull();
   63.52 +		return result;
   63.53 +	}
   63.54 +
   63.55 +	@Override
   63.56 +	public void meet(Datatype node) {
   63.57 +		result = sqlNull();
   63.58 +	}
   63.59 +
   63.60 +	@Override
   63.61 +	public void meet(Lang node)
   63.62 +		throws UnsupportedRdbmsOperatorException
   63.63 +	{
   63.64 +		result = sqlNull();
   63.65 +	}
   63.66 +
   63.67 +	@Override
   63.68 +	public void meet(MathExpr node)
   63.69 +		throws UnsupportedRdbmsOperatorException
   63.70 +	{
   63.71 +		result = sqlNull();
   63.72 +	}
   63.73 +
   63.74 +	@Override
   63.75 +	public void meet(Str node) {
   63.76 +		result = sqlNull();
   63.77 +	}
   63.78 +
   63.79 +	@Override
   63.80 +	public void meet(ValueConstant vc) {
   63.81 +		result = valueOf(vc.getValue());
   63.82 +	}
   63.83 +
   63.84 +	@Override
   63.85 +	public void meet(Var var) {
   63.86 +		if (var.getValue() == null) {
   63.87 +			result = new BNodeColumn(var);
   63.88 +		}
   63.89 +		else {
   63.90 +			result = valueOf(var.getValue());
   63.91 +		}
   63.92 +	}
   63.93 +
   63.94 +	@Override
   63.95 +	protected void meetNode(QueryModelNode arg)
   63.96 +		throws UnsupportedRdbmsOperatorException
   63.97 +	{
   63.98 +		throw unsupported(arg);
   63.99 +	}
  63.100 +
  63.101 +	private SqlExpr valueOf(Value value) {
  63.102 +		if (value instanceof BNode)
  63.103 +			return str(((BNode)value).stringValue());
  63.104 +		return sqlNull();
  63.105 +	}
  63.106 +}
    64.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    64.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/factories/BooleanExprFactory.java	Thu May 24 13:58:55 2012 +0300
    64.3 @@ -0,0 +1,393 @@
    64.4 +/*
    64.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    64.6 + *
    64.7 + * Licensed under the Aduna BSD-style license.
    64.8 + */
    64.9 +package org.openrdf.sail.rdbms.algebra.factories;
   64.10 +
   64.11 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.abs;
   64.12 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.and;
   64.13 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.cmp;
   64.14 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.concat;
   64.15 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.eq;
   64.16 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.eqComparingNull;
   64.17 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.eqIfNotNull;
   64.18 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.gt;
   64.19 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.isNotNull;
   64.20 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.isNull;
   64.21 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.like;
   64.22 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.lowercase;
   64.23 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.neq;
   64.24 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.not;
   64.25 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.num;
   64.26 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.or;
   64.27 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.regex;
   64.28 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.simple;
   64.29 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.sqlNull;
   64.30 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.str;
   64.31 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.sub;
   64.32 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.unsupported;
   64.33 +
   64.34 +import org.openrdf.model.Literal;
   64.35 +import org.openrdf.model.Value;
   64.36 +import org.openrdf.model.vocabulary.XMLSchema;
   64.37 +import org.openrdf.query.algebra.And;
   64.38 +import org.openrdf.query.algebra.Bound;
   64.39 +import org.openrdf.query.algebra.Compare;
   64.40 +import org.openrdf.query.algebra.IsBNode;
   64.41 +import org.openrdf.query.algebra.IsLiteral;
   64.42 +import org.openrdf.query.algebra.IsResource;
   64.43 +import org.openrdf.query.algebra.IsURI;
   64.44 +import org.openrdf.query.algebra.LangMatches;
   64.45 +import org.openrdf.query.algebra.Not;
   64.46 +import org.openrdf.query.algebra.Or;
   64.47 +import org.openrdf.query.algebra.QueryModelNode;
   64.48 +import org.openrdf.query.algebra.Regex;
   64.49 +import org.openrdf.query.algebra.SameTerm;
   64.50 +import org.openrdf.query.algebra.ValueConstant;
   64.51 +import org.openrdf.query.algebra.ValueExpr;
   64.52 +import org.openrdf.query.algebra.Var;
   64.53 +import org.openrdf.query.algebra.Compare.CompareOp;
   64.54 +import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;
   64.55 +import org.openrdf.sail.rdbms.algebra.FalseValue;
   64.56 +import org.openrdf.sail.rdbms.algebra.RefIdColumn;
   64.57 +import org.openrdf.sail.rdbms.algebra.SqlCase;
   64.58 +import org.openrdf.sail.rdbms.algebra.SqlNull;
   64.59 +import org.openrdf.sail.rdbms.algebra.TrueValue;
   64.60 +import org.openrdf.sail.rdbms.algebra.base.SqlExpr;
   64.61 +import org.openrdf.sail.rdbms.exceptions.UnsupportedRdbmsOperatorException;
   64.62 +
   64.63 +/**
   64.64 + * Boolean SQL expression factory. This factory can convert a number of core
   64.65 + * algebra nodes into an SQL expression.
   64.66 + * 
   64.67 + * @author James Leigh
   64.68 + * 
   64.69 + */
   64.70 +public class BooleanExprFactory extends QueryModelVisitorBase<UnsupportedRdbmsOperatorException> {
   64.71 +
   64.72 +	private static final double HR14 = 14 * 60 * 60 * 1000;
   64.73 +
   64.74 +	protected SqlExpr result;
   64.75 +
   64.76 +	private SqlExprFactory sql;
   64.77 +
   64.78 +	public SqlExpr createBooleanExpr(ValueExpr expr)
   64.79 +		throws UnsupportedRdbmsOperatorException
   64.80 +	{
   64.81 +		result = null;
   64.82 +		if (expr == null)
   64.83 +			return new SqlNull();
   64.84 +		expr.visit(this);
   64.85 +		if (result == null)
   64.86 +			return new SqlNull();
   64.87 +		return result;
   64.88 +	}
   64.89 +
   64.90 +	@Override
   64.91 +	public void meet(And node)
   64.92 +		throws UnsupportedRdbmsOperatorException
   64.93 +	{
   64.94 +		result = and(bool(node.getLeftArg()), bool(node.getRightArg()));
   64.95 +	}
   64.96 +
   64.97 +	@Override
   64.98 +	public void meet(Bound node)
   64.99 +		throws UnsupportedRdbmsOperatorException
  64.100 +	{
  64.101 +		result = not(isNull(new RefIdColumn(node.getArg())));
  64.102 +	}
  64.103 +
  64.104 +	@Override
  64.105 +	public void meet(Compare compare)
  64.106 +		throws UnsupportedRdbmsOperatorException
  64.107 +	{
  64.108 +		ValueExpr left = compare.getLeftArg();
  64.109 +		ValueExpr right = compare.getRightArg();
  64.110 +		CompareOp op = compare.getOperator();
  64.111 +		switch (op) {
  64.112 +			case EQ:
  64.113 +				if (isTerm(left) && isTerm(right)) {
  64.114 +					result = termsEqual(left, right);
  64.115 +				}
  64.116 +				else {
  64.117 +					result = equal(left, right);
  64.118 +				}
  64.119 +				break;
  64.120 +			case NE:
  64.121 +				if (isTerm(left) && isTerm(right)) {
  64.122 +					result = not(termsEqual(left, right));
  64.123 +				}
  64.124 +				else {
  64.125 +					result = not(equal(left, right));
  64.126 +				}
  64.127 +				break;
  64.128 +			case GE:
  64.129 +			case GT:
  64.130 +			case LE:
  64.131 +			case LT:
  64.132 +				SqlExpr simple = and(simple(type(left)), simple(type(right)));
  64.133 +				SqlExpr labels = and(cmp(label(left), op, label(right)), simple);
  64.134 +				SqlExpr time = cmp(time(left), op, time(right));
  64.135 +				SqlExpr within = cmp(time(left), op, sub(time(right), num(HR14)));
  64.136 +				SqlExpr comp = or(eq(zoned(left), zoned(right)), within);
  64.137 +				SqlExpr dateTime = and(eq(type(left), type(right)), and(comp, time));
  64.138 +				result = or(cmp(numeric(left), op, numeric(right)), or(dateTime, labels));
  64.139 +				break;
  64.140 +		}
  64.141 +	}
  64.142 +
  64.143 +	@Override
  64.144 +	public void meet(IsBNode node)
  64.145 +		throws UnsupportedRdbmsOperatorException
  64.146 +	{
  64.147 +		result = isNotNull(sql.createBNodeExpr(node.getArg()));
  64.148 +	}
  64.149 +
  64.150 +	@Override
  64.151 +	public void meet(IsLiteral node)
  64.152 +		throws UnsupportedRdbmsOperatorException
  64.153 +	{
  64.154 +		result = isNotNull(sql.createLabelExpr(node.getArg()));
  64.155 +	}
  64.156 +
  64.157 +	@Override
  64.158 +	public void meet(IsResource node)
  64.159 +		throws UnsupportedRdbmsOperatorException
  64.160 +	{
  64.161 +		SqlExpr isBNode = isNotNull(sql.createBNodeExpr(node.getArg()));
  64.162 +		result = or(isBNode, isNotNull(sql.createUriExpr(node.getArg())));
  64.163 +	}
  64.164 +
  64.165 +	@Override
  64.166 +	public void meet(IsURI node)
  64.167 +		throws UnsupportedRdbmsOperatorException
  64.168 +	{
  64.169 +		result = isNotNull(sql.createUriExpr(node.getArg()));
  64.170 +	}
  64.171 +
  64.172 +	@Override
  64.173 +	public void meet(LangMatches node)
  64.174 +		throws UnsupportedRdbmsOperatorException
  64.175 +	{
  64.176 +		ValueExpr left = node.getLeftArg();
  64.177 +		ValueExpr right = node.getRightArg();
  64.178 +		SqlCase sqlCase = new SqlCase();
  64.179 +		sqlCase.when(eq(label(right), str("*")), neq(label(left), str("")));
  64.180 +		SqlExpr pattern = concat(lowercase(label(right)), str("%"));
  64.181 +		sqlCase.when(new TrueValue(), like(label(left), pattern));
  64.182 +		result = sqlCase;
  64.183 +	}
  64.184 +
  64.185 +	@Override
  64.186 +	public void meet(Not node)
  64.187 +		throws UnsupportedRdbmsOperatorException
  64.188 +	{
  64.189 +		result = not(bool(node.getArg()));
  64.190 +	}
  64.191 +
  64.192 +	@Override
  64.193 +	public void meet(Or node)
  64.194 +		throws UnsupportedRdbmsOperatorException
  64.195 +	{
  64.196 +		result = or(bool(node.getLeftArg()), bool(node.getRightArg()));
  64.197 +	}
  64.198 +
  64.199 +	@Override
  64.200 +	public void meet(Regex node)
  64.201 +		throws UnsupportedRdbmsOperatorException
  64.202 +	{
  64.203 +		result = regex(label(node.getArg()), label(node.getPatternArg()), label(node.getFlagsArg()));
  64.204 +	}
  64.205 +
  64.206 +	@Override
  64.207 +	public void meet(SameTerm node)
  64.208 +		throws UnsupportedRdbmsOperatorException
  64.209 +	{
  64.210 +		ValueExpr left = node.getLeftArg();
  64.211 +		ValueExpr right = node.getRightArg();
  64.212 +		boolean leftIsVar = left instanceof Var;
  64.213 +		boolean rightIsVar = right instanceof Var;
  64.214 +		boolean leftIsConst = left instanceof ValueConstant;
  64.215 +		boolean rightIsConst = right instanceof ValueConstant;
  64.216 +		if (leftIsVar && rightIsVar) {
  64.217 +			result = eq(new RefIdColumn((Var)left), new RefIdColumn((Var)right));
  64.218 +		}
  64.219 +		else if ((leftIsVar || leftIsConst) && (rightIsVar || rightIsConst)) {
  64.220 +			result = eq(hash(left), hash(right));
  64.221 +		}
  64.222 +		else {
  64.223 +			SqlExpr bnodes = eqComparingNull(bNode(left), bNode(right));
  64.224 +			SqlExpr uris = eqComparingNull(uri(left), uri(right));
  64.225 +			SqlExpr langs = eqComparingNull(lang(left), lang(right));
  64.226 +			SqlExpr datatype = eqComparingNull(type(left), type(right));
  64.227 +			SqlExpr labels = eqComparingNull(label(left), label(right));
  64.228 +
  64.229 +			SqlExpr literals = and(langs, and(datatype, labels));
  64.230 +			result = and(bnodes, and(uris, literals));
  64.231 +		}
  64.232 +	}
  64.233 +
  64.234 +	@Override
  64.235 +	public void meet(ValueConstant vc)
  64.236 +		throws UnsupportedRdbmsOperatorException
  64.237 +	{
  64.238 +		result = valueOf(vc.getValue());
  64.239 +	}
  64.240 +
  64.241 +	@Override
  64.242 +	public void meet(Var var)
  64.243 +		throws UnsupportedRdbmsOperatorException
  64.244 +	{
  64.245 +		if (var.getValue() == null) {
  64.246 +			result = effectiveBooleanValue(var);
  64.247 +		}
  64.248 +		else {
  64.249 +			result = valueOf(var.getValue());
  64.250 +		}
  64.251 +	}
  64.252 +
  64.253 +	public void setSqlExprFactory(SqlExprFactory sql) {
  64.254 +		this.sql = sql;
  64.255 +	}
  64.256 +
  64.257 +	protected SqlExpr bNode(ValueExpr arg)
  64.258 +		throws UnsupportedRdbmsOperatorException
  64.259 +	{
  64.260 +		return sql.createBNodeExpr(arg);
  64.261 +	}
  64.262 +
  64.263 +	protected SqlExpr bool(ValueExpr arg)
  64.264 +		throws UnsupportedRdbmsOperatorException
  64.265 +	{
  64.266 +		return sql.createBooleanExpr(arg);
  64.267 +	}
  64.268 +
  64.269 +	protected SqlExpr label(ValueExpr arg)
  64.270 +		throws UnsupportedRdbmsOperatorException
  64.271 +	{
  64.272 +		return sql.createLabelExpr(arg);
  64.273 +	}
  64.274 +
  64.275 +	protected SqlExpr lang(ValueExpr arg)
  64.276 +		throws UnsupportedRdbmsOperatorException
  64.277 +	{
  64.278 +		return sql.createLanguageExpr(arg);
  64.279 +	}
  64.280 +
  64.281 +	protected SqlExpr hash(ValueExpr arg)
  64.282 +		throws UnsupportedRdbmsOperatorException
  64.283 +	{
  64.284 +		return sql.createHashExpr(arg);
  64.285 +	}
  64.286 +
  64.287 +	@Override
  64.288 +	protected void meetNode(QueryModelNode arg)
  64.289 +		throws UnsupportedRdbmsOperatorException
  64.290 +	{
  64.291 +		if (arg instanceof ValueExpr) {
  64.292 +			result = effectiveBooleanValue((ValueExpr)arg);
  64.293 +		}
  64.294 +		else {
  64.295 +			throw unsupported(arg);
  64.296 +		}
  64.297 +	}
  64.298 +
  64.299 +	protected SqlExpr numeric(ValueExpr arg)
  64.300 +		throws UnsupportedRdbmsOperatorException
  64.301 +	{
  64.302 +		return sql.createNumericExpr(arg);
  64.303 +	}
  64.304 +
  64.305 +	protected SqlExpr time(ValueExpr arg)
  64.306 +		throws UnsupportedRdbmsOperatorException
  64.307 +	{
  64.308 +		return sql.createTimeExpr(arg);
  64.309 +	}
  64.310 +
  64.311 +	protected SqlExpr type(ValueExpr arg)
  64.312 +		throws UnsupportedRdbmsOperatorException
  64.313 +	{
  64.314 +		return sql.createDatatypeExpr(arg);
  64.315 +	}
  64.316 +
  64.317 +	protected SqlExpr uri(ValueExpr arg)
  64.318 +		throws UnsupportedRdbmsOperatorException
  64.319 +	{
  64.320 +		return sql.createUriExpr(arg);
  64.321 +	}
  64.322 +
  64.323 +	protected SqlExpr zoned(ValueExpr arg)
  64.324 +		throws UnsupportedRdbmsOperatorException
  64.325 +	{
  64.326 +		return sql.createZonedExpr(arg);
  64.327 +	}
  64.328 +
  64.329 +	private SqlExpr effectiveBooleanValue(ValueExpr v)
  64.330 +		throws UnsupportedRdbmsOperatorException
  64.331 +	{
  64.332 +		String bool = XMLSchema.BOOLEAN.stringValue();
  64.333 +		SqlCase sqlCase = new SqlCase();
  64.334 +		sqlCase.when(eq(type(v), str(bool)), eq(label(v), str("true")));
  64.335 +		sqlCase.when(simple(type(v)), not(eq(label(v), str(""))));
  64.336 +		sqlCase.when(isNotNull(numeric(v)), not(eq(numeric(v), num(0))));
  64.337 +		return sqlCase;
  64.338 +	}
  64.339 +
  64.340 +	private SqlExpr equal(ValueExpr left, ValueExpr right)
  64.341 +		throws UnsupportedRdbmsOperatorException
  64.342 +	{
  64.343 +		SqlExpr bnodes = eq(bNode(left), bNode(right));
  64.344 +		SqlExpr uris = eq(uri(left), uri(right));
  64.345 +		SqlCase scase = new SqlCase();
  64.346 +		scase.when(or(isNotNull(bNode(left)), isNotNull(bNode(right))), bnodes);
  64.347 +		scase.when(or(isNotNull(uri(left)), isNotNull(uri(right))), uris);
  64.348 +		return literalEqual(left, right, scase);
  64.349 +	}
  64.350 +
  64.351 +	private boolean isTerm(ValueExpr node) {
  64.352 +		return node instanceof Var || node instanceof ValueConstant;
  64.353 +	}
  64.354 +
  64.355 +	private SqlExpr literalEqual(ValueExpr left, ValueExpr right, SqlCase scase)
  64.356 +		throws UnsupportedRdbmsOperatorException
  64.357 +	{
  64.358 +		// TODO What about xsd:booleans?
  64.359 +		SqlExpr labels = eq(label(left), label(right));
  64.360 +		SqlExpr langs = and(eqIfNotNull(lang(left), lang(right)), labels.clone());
  64.361 +		SqlExpr numeric = eq(numeric(left), numeric(right));
  64.362 +		SqlExpr time = eq(time(left), time(right));
  64.363 +
  64.364 +		SqlExpr bothCalendar = and(isNotNull(time(left)), isNotNull(time(right)));
  64.365 +		SqlExpr over14 = gt(abs(sub(time(left), time(right))), num(HR14 / 2));
  64.366 +		SqlExpr comparable = and(bothCalendar, or(eq(zoned(left), zoned(right)), over14));
  64.367 +
  64.368 +		scase.when(or(isNotNull(lang(left)), isNotNull(lang(right))), langs);
  64.369 +		scase.when(and(simple(type(left)), simple(type(right))), labels.clone());
  64.370 +		scase.when(and(isNotNull(numeric(left)), isNotNull(numeric(right))), numeric);
  64.371 +		scase.when(comparable, time);
  64.372 +		scase.when(and(eq(type(left), type(right)), labels.clone()), new TrueValue());
  64.373 +		return scase;
  64.374 +	}
  64.375 +
  64.376 +	private SqlExpr termsEqual(ValueExpr left, ValueExpr right)
  64.377 +		throws UnsupportedRdbmsOperatorException
  64.378 +	{
  64.379 +		SqlExpr bnodes = eqIfNotNull(bNode(left), bNode(right));
  64.380 +		SqlExpr uris = eqIfNotNull(uri(left), uri(right));
  64.381 +		SqlCase scase = new SqlCase();
  64.382 +		scase.when(or(isNotNull(bNode(left)), isNotNull(bNode(right))), bnodes);
  64.383 +		scase.when(or(isNotNull(uri(left)), isNotNull(uri(right))), uris);
  64.384 +		return literalEqual(left, right, scase);
  64.385 +	}
  64.386 +
  64.387 +	private SqlExpr valueOf(Value value) {
  64.388 +		if (value instanceof Literal) {
  64.389 +			if (((Literal)value).booleanValue()) {
  64.390 +				return new TrueValue();
  64.391 +			}
  64.392 +			return new FalseValue();
  64.393 +		}
  64.394 +		return sqlNull();
  64.395 +	}
  64.396 +}
    65.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    65.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/factories/DatatypeExprFactory.java	Thu May 24 13:58:55 2012 +0300
    65.3 @@ -0,0 +1,129 @@
    65.4 +/*
    65.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    65.6 + *
    65.7 + * Licensed under the Aduna BSD-style license.
    65.8 + */
    65.9 +package org.openrdf.sail.rdbms.algebra.factories;
   65.10 +
   65.11 +import static org.openrdf.model.vocabulary.XMLSchema.DECIMAL;
   65.12 +import static org.openrdf.model.vocabulary.XMLSchema.DOUBLE;
   65.13 +import static org.openrdf.model.vocabulary.XMLSchema.FLOAT;
   65.14 +import static org.openrdf.model.vocabulary.XMLSchema.INTEGER;
   65.15 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.in;
   65.16 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.sqlNull;
   65.17 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.str;
   65.18 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.unsupported;
   65.19 +
   65.20 +import org.openrdf.model.Literal;
   65.21 +import org.openrdf.model.URI;
   65.22 +import org.openrdf.model.Value;
   65.23 +import org.openrdf.query.algebra.Datatype;
   65.24 +import org.openrdf.query.algebra.Lang;
   65.25 +import org.openrdf.query.algebra.MathExpr;
   65.26 +import org.openrdf.query.algebra.QueryModelNode;
   65.27 +import org.openrdf.query.algebra.Str;
   65.28 +import org.openrdf.query.algebra.ValueConstant;
   65.29 +import org.openrdf.query.algebra.ValueExpr;
   65.30 +import org.openrdf.query.algebra.Var;
   65.31 +import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;
   65.32 +import org.openrdf.sail.rdbms.algebra.DatatypeColumn;
   65.33 +import org.openrdf.sail.rdbms.algebra.SqlCase;
   65.34 +import org.openrdf.sail.rdbms.algebra.SqlNull;
   65.35 +import org.openrdf.sail.rdbms.algebra.TrueValue;
   65.36 +import org.openrdf.sail.rdbms.algebra.base.SqlExpr;
   65.37 +import org.openrdf.sail.rdbms.exceptions.UnsupportedRdbmsOperatorException;
   65.38 +
   65.39 +/**
   65.40 + * Creates a datatype SQL expression.
   65.41 + * 
   65.42 + * @author James Leigh
   65.43 + * 
   65.44 + */
   65.45 +public class DatatypeExprFactory extends QueryModelVisitorBase<UnsupportedRdbmsOperatorException> {
   65.46 +
   65.47 +	protected SqlExpr result;
   65.48 +
   65.49 +	public SqlExpr createDatatypeExpr(ValueExpr expr)
   65.50 +		throws UnsupportedRdbmsOperatorException
   65.51 +	{
   65.52 +		result = null;
   65.53 +		if (expr == null)
   65.54 +			return new SqlNull();
   65.55 +		expr.visit(this);
   65.56 +		if (result == null)
   65.57 +			return new SqlNull();
   65.58 +		return result;
   65.59 +	}
   65.60 +
   65.61 +	@Override
   65.62 +	public void meet(Datatype node) {
   65.63 +		result = sqlNull();
   65.64 +	}
   65.65 +
   65.66 +	@Override
   65.67 +	public void meet(Lang node)
   65.68 +		throws UnsupportedRdbmsOperatorException
   65.69 +	{
   65.70 +		result = sqlNull();
   65.71 +	}
   65.72 +
   65.73 +	@Override
   65.74 +	public void meet(MathExpr node)
   65.75 +		throws UnsupportedRdbmsOperatorException
   65.76 +	{
   65.77 +		boolean divide = node.getOperator().equals(MathExpr.MathOp.DIVIDE);
   65.78 +		ValueExpr left = node.getLeftArg();
   65.79 +		ValueExpr right = node.getRightArg();
   65.80 +		SqlCase sqlCase = new SqlCase();
   65.81 +		sqlCase.when(in(str(DOUBLE), type(left), type(right)), str(DOUBLE));
   65.82 +		sqlCase.when(in(str(FLOAT), type(left), type(right)), str(FLOAT));
   65.83 +		sqlCase.when(in(str(DECIMAL), type(left), type(right)), str(DECIMAL));
   65.84 +		sqlCase.when(new TrueValue(), divide ? str(DECIMAL) : str(INTEGER));
   65.85 +		result = sqlCase;
   65.86 +	}
   65.87 +
   65.88 +	@Override
   65.89 +	public void meet(Str node)
   65.90 +		throws UnsupportedRdbmsOperatorException
   65.91 +	{
   65.92 +		result = sqlNull();
   65.93 +	}
   65.94 +
   65.95 +	@Override
   65.96 +	public void meet(ValueConstant vc) {
   65.97 +		result = valueOf(vc.getValue());
   65.98 +	}
   65.99 +
  65.100 +	@Override
  65.101 +	public void meet(Var var) {
  65.102 +		if (var.getValue() == null) {
  65.103 +			result = new DatatypeColumn(var);
  65.104 +		}
  65.105 +		else {
  65.106 +			result = valueOf(var.getValue());
  65.107 +		}
  65.108 +	}
  65.109 +
  65.110 +	@Override
  65.111 +	protected void meetNode(QueryModelNode arg)
  65.112 +		throws UnsupportedRdbmsOperatorException
  65.113 +	{
  65.114 +		throw unsupported(arg);
  65.115 +	}
  65.116 +
  65.117 +	private SqlExpr valueOf(Value value) {
  65.118 +		if (value instanceof Literal) {
  65.119 +			URI datatype = ((Literal)value).getDatatype();
  65.120 +			if (datatype != null)
  65.121 +				return str(datatype.stringValue());
  65.122 +		}
  65.123 +		return sqlNull();
  65.124 +	}
  65.125 +
  65.126 +	private SqlExpr type(ValueExpr expr)
  65.127 +		throws UnsupportedRdbmsOperatorException
  65.128 +	{
  65.129 +		return createDatatypeExpr(expr);
  65.130 +	}
  65.131 +
  65.132 +}
  65.133 \ No newline at end of file
    66.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    66.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/factories/HashExprFactory.java	Thu May 24 13:58:55 2012 +0300
    66.3 @@ -0,0 +1,83 @@
    66.4 +/*
    66.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    66.6 + *
    66.7 + * Licensed under the Aduna BSD-style license.
    66.8 + */
    66.9 +package org.openrdf.sail.rdbms.algebra.factories;
   66.10 +
   66.11 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.unsupported;
   66.12 +
   66.13 +import org.openrdf.model.Value;
   66.14 +import org.openrdf.query.algebra.QueryModelNode;
   66.15 +import org.openrdf.query.algebra.ValueConstant;
   66.16 +import org.openrdf.query.algebra.ValueExpr;
   66.17 +import org.openrdf.query.algebra.Var;
   66.18 +import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;
   66.19 +import org.openrdf.sail.rdbms.RdbmsValueFactory;
   66.20 +import org.openrdf.sail.rdbms.algebra.NumberValue;
   66.21 +import org.openrdf.sail.rdbms.algebra.RefIdColumn;
   66.22 +import org.openrdf.sail.rdbms.algebra.SqlNull;
   66.23 +import org.openrdf.sail.rdbms.algebra.base.SqlExpr;
   66.24 +import org.openrdf.sail.rdbms.exceptions.RdbmsException;
   66.25 +import org.openrdf.sail.rdbms.exceptions.RdbmsRuntimeException;
   66.26 +import org.openrdf.sail.rdbms.exceptions.UnsupportedRdbmsOperatorException;
   66.27 +
   66.28 +/**
   66.29 + * 
   66.30 + * @author James Leigh
   66.31 + */
   66.32 +public class HashExprFactory extends QueryModelVisitorBase<UnsupportedRdbmsOperatorException> {
   66.33 +
   66.34 +	protected SqlExpr result;
   66.35 +
   66.36 +	private RdbmsValueFactory vf;
   66.37 +
   66.38 +	public HashExprFactory(RdbmsValueFactory vf) {
   66.39 +		super();
   66.40 +		this.vf = vf;
   66.41 +	}
   66.42 +
   66.43 +	public SqlExpr createHashExpr(ValueExpr expr)
   66.44 +		throws UnsupportedRdbmsOperatorException
   66.45 +	{
   66.46 +		result = null;
   66.47 +		if (expr == null)
   66.48 +			return new SqlNull();
   66.49 +		expr.visit(this);
   66.50 +		if (result == null)
   66.51 +			return new SqlNull();
   66.52 +		return result;
   66.53 +	}
   66.54 +
   66.55 +	@Override
   66.56 +	public void meet(ValueConstant vc) {
   66.57 +		result = valueOf(vc.getValue());
   66.58 +	}
   66.59 +
   66.60 +	@Override
   66.61 +	public void meet(Var var) {
   66.62 +		if (var.getValue() == null) {
   66.63 +			result = new RefIdColumn(var);
   66.64 +		}
   66.65 +		else {
   66.66 +			result = valueOf(var.getValue());
   66.67 +		}
   66.68 +	}
   66.69 +
   66.70 +	@Override
   66.71 +	protected void meetNode(QueryModelNode arg)
   66.72 +		throws UnsupportedRdbmsOperatorException
   66.73 +	{
   66.74 +		throw unsupported(arg);
   66.75 +	}
   66.76 +
   66.77 +	public SqlExpr valueOf(Value value) {
   66.78 +		try {
   66.79 +			return new NumberValue(vf.getInternalId(value));
   66.80 +		}
   66.81 +		catch (RdbmsException e) {
   66.82 +			throw new RdbmsRuntimeException(e);
   66.83 +		}
   66.84 +	}
   66.85 +
   66.86 +}
    67.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    67.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/factories/LabelExprFactory.java	Thu May 24 13:58:55 2012 +0300
    67.3 @@ -0,0 +1,140 @@
    67.4 +/*
    67.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    67.6 + *
    67.7 + * Licensed under the Aduna BSD-style license.
    67.8 + */
    67.9 +package org.openrdf.sail.rdbms.algebra.factories;
   67.10 +
   67.11 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.coalesce;
   67.12 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.isNotNull;
   67.13 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.sqlNull;
   67.14 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.str;
   67.15 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.text;
   67.16 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.unsupported;
   67.17 +
   67.18 +import org.openrdf.model.Literal;
   67.19 +import org.openrdf.model.Value;
   67.20 +import org.openrdf.query.algebra.Datatype;
   67.21 +import org.openrdf.query.algebra.Lang;
   67.22 +import org.openrdf.query.algebra.MathExpr;
   67.23 +import org.openrdf.query.algebra.QueryModelNode;
   67.24 +import org.openrdf.query.algebra.Str;
   67.25 +import org.openrdf.query.algebra.ValueConstant;
   67.26 +import org.openrdf.query.algebra.ValueExpr;
   67.27 +import org.openrdf.query.algebra.Var;
   67.28 +import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;
   67.29 +import org.openrdf.sail.rdbms.algebra.LabelColumn;
   67.30 +import org.openrdf.sail.rdbms.algebra.LongLabelColumn;
   67.31 +import org.openrdf.sail.rdbms.algebra.SqlCase;
   67.32 +import org.openrdf.sail.rdbms.algebra.SqlNull;
   67.33 +import org.openrdf.sail.rdbms.algebra.base.SqlExpr;
   67.34 +import org.openrdf.sail.rdbms.exceptions.UnsupportedRdbmsOperatorException;
   67.35 +
   67.36 +/**
   67.37 + * Creates a SQl expression of a literal label.
   67.38 + * 
   67.39 + * @author James Leigh
   67.40 + * 
   67.41 + */
   67.42 +public class LabelExprFactory extends QueryModelVisitorBase<UnsupportedRdbmsOperatorException> {
   67.43 +
   67.44 +	protected SqlExpr result;
   67.45 +
   67.46 +	private SqlExprFactory sql;
   67.47 +
   67.48 +	public void setSqlExprFactory(SqlExprFactory sql) {
   67.49 +		this.sql = sql;
   67.50 +	}
   67.51 +
   67.52 +	public SqlExpr createLabelExpr(ValueExpr expr)
   67.53 +		throws UnsupportedRdbmsOperatorException
   67.54 +	{
   67.55 +		result = null;
   67.56 +		if (expr == null)
   67.57 +			return new SqlNull();
   67.58 +		expr.visit(this);
   67.59 +		if (result == null)
   67.60 +			return new SqlNull();
   67.61 +		return result;
   67.62 +	}
   67.63 +
   67.64 +	@Override
   67.65 +	public void meet(Datatype node)
   67.66 +		throws UnsupportedRdbmsOperatorException
   67.67 +	{
   67.68 +		result = sqlNull();
   67.69 +	}
   67.70 +
   67.71 +	@Override
   67.72 +	public void meet(Lang node)
   67.73 +		throws UnsupportedRdbmsOperatorException
   67.74 +	{
   67.75 +		SqlCase sqlCase = new SqlCase();
   67.76 +		sqlCase.when(isNotNull(lang(node.getArg())), lang(node.getArg()));
   67.77 +		sqlCase.when(isNotNull(createLabelExpr(node.getArg())), str(""));
   67.78 +		result = sqlCase;
   67.79 +	}
   67.80 +
   67.81 +	@Override
   67.82 +	public void meet(MathExpr node)
   67.83 +		throws UnsupportedRdbmsOperatorException
   67.84 +	{
   67.85 +		result = text(num(node));
   67.86 +	}
   67.87 +
   67.88 +	@Override
   67.89 +	public void meet(Str str)
   67.90 +		throws UnsupportedRdbmsOperatorException
   67.91 +	{
   67.92 +		ValueExpr arg = str.getArg();
   67.93 +		result = coalesce(uri(arg), createLabelExpr(arg));
   67.94 +	}
   67.95 +
   67.96 +	@Override
   67.97 +	public void meet(ValueConstant vc) {
   67.98 +		result = valueOf(vc.getValue());
   67.99 +	}
  67.100 +
  67.101 +	@Override
  67.102 +	public void meet(Var var) {
  67.103 +		if (var.getValue() == null) {
  67.104 +			result = coalesce(new LabelColumn(var), new LongLabelColumn(var));
  67.105 +		}
  67.106 +		else {
  67.107 +			result = valueOf(var.getValue());
  67.108 +		}
  67.109 +	}
  67.110 +
  67.111 +	@Override
  67.112 +	protected void meetNode(QueryModelNode arg)
  67.113 +		throws UnsupportedRdbmsOperatorException
  67.114 +	{
  67.115 +		throw unsupported(arg);
  67.116 +	}
  67.117 +
  67.118 +	private SqlExpr lang(ValueExpr arg)
  67.119 +		throws UnsupportedRdbmsOperatorException
  67.120 +	{
  67.121 +		return sql.createLanguageExpr(arg);
  67.122 +	}
  67.123 +
  67.124 +	private SqlExpr uri(ValueExpr arg)
  67.125 +		throws UnsupportedRdbmsOperatorException
  67.126 +	{
  67.127 +		return sql.createUriExpr(arg);
  67.128 +	}
  67.129 +
  67.130 +	private SqlExpr num(ValueExpr arg)
  67.131 +		throws UnsupportedRdbmsOperatorException
  67.132 +	{
  67.133 +		return sql.createNumericExpr(arg);
  67.134 +	}
  67.135 +
  67.136 +	private SqlExpr valueOf(Value value) {
  67.137 +		if (value instanceof Literal) {
  67.138 +			return str(((Literal)value).getLabel());
  67.139 +		}
  67.140 +		return sqlNull();
  67.141 +	}
  67.142 +
  67.143 +}
  67.144 \ No newline at end of file
    68.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    68.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/factories/LanguageExprFactory.java	Thu May 24 13:58:55 2012 +0300
    68.3 @@ -0,0 +1,108 @@
    68.4 +/*
    68.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    68.6 + *
    68.7 + * Licensed under the Aduna BSD-style license.
    68.8 + */
    68.9 +package org.openrdf.sail.rdbms.algebra.factories;
   68.10 +
   68.11 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.sqlNull;
   68.12 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.str;
   68.13 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.unsupported;
   68.14 +
   68.15 +import org.openrdf.model.Literal;
   68.16 +import org.openrdf.model.Value;
   68.17 +import org.openrdf.query.algebra.Datatype;
   68.18 +import org.openrdf.query.algebra.Lang;
   68.19 +import org.openrdf.query.algebra.MathExpr;
   68.20 +import org.openrdf.query.algebra.QueryModelNode;
   68.21 +import org.openrdf.query.algebra.Str;
   68.22 +import org.openrdf.query.algebra.ValueConstant;
   68.23 +import org.openrdf.query.algebra.ValueExpr;
   68.24 +import org.openrdf.query.algebra.Var;
   68.25 +import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;
   68.26 +import org.openrdf.sail.rdbms.algebra.LanguageColumn;
   68.27 +import org.openrdf.sail.rdbms.algebra.SqlNull;
   68.28 +import org.openrdf.sail.rdbms.algebra.base.SqlExpr;
   68.29 +import org.openrdf.sail.rdbms.exceptions.UnsupportedRdbmsOperatorException;
   68.30 +
   68.31 +/**
   68.32 + * Creates an SQL expression of a literal's language.
   68.33 + * 
   68.34 + * @author James Leigh
   68.35 + * 
   68.36 + */
   68.37 +public class LanguageExprFactory extends QueryModelVisitorBase<UnsupportedRdbmsOperatorException> {
   68.38 +
   68.39 +	protected SqlExpr result;
   68.40 +
   68.41 +	public SqlExpr createLanguageExpr(ValueExpr expr)
   68.42 +		throws UnsupportedRdbmsOperatorException
   68.43 +	{
   68.44 +		result = null;
   68.45 +		if (expr == null)
   68.46 +			return new SqlNull();
   68.47 +		expr.visit(this);
   68.48 +		if (result == null)
   68.49 +			return new SqlNull();
   68.50 +		return result;
   68.51 +	}
   68.52 +
   68.53 +	@Override
   68.54 +	public void meet(Datatype node)
   68.55 +		throws UnsupportedRdbmsOperatorException
   68.56 +	{
   68.57 +		result = sqlNull();
   68.58 +	}
   68.59 +
   68.60 +	@Override
   68.61 +	public void meet(Lang node)
   68.62 +		throws UnsupportedRdbmsOperatorException
   68.63 +	{
   68.64 +		result = sqlNull();
   68.65 +	}
   68.66 +
   68.67 +	@Override
   68.68 +	public void meet(MathExpr node)
   68.69 +		throws UnsupportedRdbmsOperatorException
   68.70 +	{
   68.71 +		result = sqlNull();
   68.72 +	}
   68.73 +
   68.74 +	@Override
   68.75 +	public void meet(Str node)
   68.76 +		throws UnsupportedRdbmsOperatorException
   68.77 +	{
   68.78 +		result = sqlNull();
   68.79 +	}
   68.80 +
   68.81 +	@Override
   68.82 +	public void meet(ValueConstant vc) {
   68.83 +		result = valueOf(vc.getValue());
   68.84 +	}
   68.85 +
   68.86 +	@Override
   68.87 +	public void meet(Var var) {
   68.88 +		if (var.getValue() == null) {
   68.89 +			result = new LanguageColumn(var);
   68.90 +		}
   68.91 +		else {
   68.92 +			result = valueOf(var.getValue());
   68.93 +		}
   68.94 +	}
   68.95 +
   68.96 +	@Override
   68.97 +	protected void meetNode(QueryModelNode arg)
   68.98 +		throws UnsupportedRdbmsOperatorException
   68.99 +	{
  68.100 +		throw unsupported(arg);
  68.101 +	}
  68.102 +
  68.103 +	private SqlExpr valueOf(Value value) {
  68.104 +		if (value instanceof Literal) {
  68.105 +			Literal lit = (Literal)value;
  68.106 +			return str(lit.getLanguage());
  68.107 +		}
  68.108 +		return sqlNull();
  68.109 +	}
  68.110 +
  68.111 +}
  68.112 \ No newline at end of file
    69.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    69.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/factories/NumericExprFactory.java	Thu May 24 13:58:55 2012 +0300
    69.3 @@ -0,0 +1,119 @@
    69.4 +/*
    69.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    69.6 + *
    69.7 + * Licensed under the Aduna BSD-style license.
    69.8 + */
    69.9 +package org.openrdf.sail.rdbms.algebra.factories;
   69.10 +
   69.11 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.sqlNull;
   69.12 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.unsupported;
   69.13 +
   69.14 +import org.openrdf.model.Literal;
   69.15 +import org.openrdf.model.URI;
   69.16 +import org.openrdf.model.Value;
   69.17 +import org.openrdf.model.datatypes.XMLDatatypeUtil;
   69.18 +import org.openrdf.query.algebra.Datatype;
   69.19 +import org.openrdf.query.algebra.Lang;
   69.20 +import org.openrdf.query.algebra.MathExpr;
   69.21 +import org.openrdf.query.algebra.QueryModelNode;
   69.22 +import org.openrdf.query.algebra.Str;
   69.23 +import org.openrdf.query.algebra.ValueConstant;
   69.24 +import org.openrdf.query.algebra.ValueExpr;
   69.25 +import org.openrdf.query.algebra.Var;
   69.26 +import org.openrdf.query.algebra.MathExpr.MathOp;
   69.27 +import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;
   69.28 +import org.openrdf.sail.rdbms.algebra.DoubleValue;
   69.29 +import org.openrdf.sail.rdbms.algebra.NumericColumn;
   69.30 +import org.openrdf.sail.rdbms.algebra.SqlMathExpr;
   69.31 +import org.openrdf.sail.rdbms.algebra.SqlNull;
   69.32 +import org.openrdf.sail.rdbms.algebra.base.SqlExpr;
   69.33 +import org.openrdf.sail.rdbms.exceptions.UnsupportedRdbmsOperatorException;
   69.34 +
   69.35 +/**
   69.36 + * Creates an SQL expression of a literal's numeric value.
   69.37 + * 
   69.38 + * @author James Leigh
   69.39 + * 
   69.40 + */
   69.41 +public class NumericExprFactory extends QueryModelVisitorBase<UnsupportedRdbmsOperatorException> {
   69.42 +
   69.43 +	protected SqlExpr result;
   69.44 +
   69.45 +	public SqlExpr createNumericExpr(ValueExpr expr)
   69.46 +		throws UnsupportedRdbmsOperatorException
   69.47 +	{
   69.48 +		result = null;
   69.49 +		if (expr == null)
   69.50 +			return new SqlNull();
   69.51 +		expr.visit(this);
   69.52 +		if (result == null)
   69.53 +			return new SqlNull();
   69.54 +		return result;
   69.55 +	}
   69.56 +
   69.57 +	@Override
   69.58 +	public void meet(Datatype node) {
   69.59 +		result = sqlNull();
   69.60 +	}
   69.61 +
   69.62 +	@Override
   69.63 +	public void meet(Lang node)
   69.64 +		throws UnsupportedRdbmsOperatorException
   69.65 +	{
   69.66 +		result = sqlNull();
   69.67 +	}
   69.68 +
   69.69 +	@Override
   69.70 +	public void meet(MathExpr node)
   69.71 +		throws UnsupportedRdbmsOperatorException
   69.72 +	{
   69.73 +		SqlExpr left = createNumericExpr(node.getLeftArg());
   69.74 +		SqlExpr right = createNumericExpr(node.getRightArg());
   69.75 +		MathOp op = node.getOperator();
   69.76 +		result = new SqlMathExpr(left, op, right);
   69.77 +	}
   69.78 +
   69.79 +	@Override
   69.80 +	public void meet(Str node) {
   69.81 +		result = sqlNull();
   69.82 +	}
   69.83 +
   69.84 +	@Override
   69.85 +	public void meet(ValueConstant vc) {
   69.86 +		result = valueOf(vc.getValue());
   69.87 +	}
   69.88 +
   69.89 +	@Override
   69.90 +	public void meet(Var var) {
   69.91 +		if (var.getValue() == null) {
   69.92 +			result = new NumericColumn(var);
   69.93 +		}
   69.94 +		else {
   69.95 +			result = valueOf(var.getValue());
   69.96 +		}
   69.97 +	}
   69.98 +
   69.99 +	@Override
  69.100 +	protected void meetNode(QueryModelNode arg)
  69.101 +		throws UnsupportedRdbmsOperatorException
  69.102 +	{
  69.103 +		throw unsupported(arg);
  69.104 +	}
  69.105 +
  69.106 +	private SqlExpr valueOf(Value value) {
  69.107 +		if (value instanceof Literal) {
  69.108 +			Literal lit = (Literal)value;
  69.109 +			URI dt = lit.getDatatype();
  69.110 +			if (dt != null && XMLDatatypeUtil.isNumericDatatype(dt)) {
  69.111 +				try {
  69.112 +					return new DoubleValue(lit.doubleValue());
  69.113 +				}
  69.114 +				catch (NumberFormatException e) {
  69.115 +					return null;
  69.116 +				}
  69.117 +			}
  69.118 +		}
  69.119 +		return null;
  69.120 +	}
  69.121 +
  69.122 +}
  69.123 \ No newline at end of file
    70.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    70.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/factories/SqlExprFactory.java	Thu May 24 13:58:55 2012 +0300
    70.3 @@ -0,0 +1,140 @@
    70.4 +/*
    70.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    70.6 + *
    70.7 + * Licensed under the Aduna BSD-style license.
    70.8 + */
    70.9 +package org.openrdf.sail.rdbms.algebra.factories;
   70.10 +
   70.11 +import org.openrdf.query.algebra.ValueExpr;
   70.12 +import org.openrdf.sail.rdbms.algebra.base.SqlExpr;
   70.13 +import org.openrdf.sail.rdbms.exceptions.UnsupportedRdbmsOperatorException;
   70.14 +
   70.15 +/**
   70.16 + * Boolean SQL expression factory. This factory can convert a number of core
   70.17 + * algebra nodes into an SQL expression.
   70.18 + * 
   70.19 + * @author James Leigh
   70.20 + * 
   70.21 + */
   70.22 +public class SqlExprFactory {
   70.23 +
   70.24 +	private BNodeExprFactory bnode;
   70.25 +
   70.26 +	private BooleanExprFactory bool;
   70.27 +
   70.28 +	private DatatypeExprFactory datatype;
   70.29 +
   70.30 +	private LabelExprFactory label;
   70.31 +
   70.32 +	private LanguageExprFactory language;
   70.33 +
   70.34 +	private NumericExprFactory numeric;
   70.35 +
   70.36 +	private TimeExprFactory time;
   70.37 +
   70.38 +	private URIExprFactory uri;
   70.39 +
   70.40 +	private ZonedExprFactory zoned;
   70.41 +
   70.42 +	private HashExprFactory hash;
   70.43 +
   70.44 +	public void setBNodeExprFactory(BNodeExprFactory bnode) {
   70.45 +		this.bnode = bnode;
   70.46 +	}
   70.47 +
   70.48 +	public void setBooleanExprFactory(BooleanExprFactory bool) {
   70.49 +		this.bool = bool;
   70.50 +	}
   70.51 +
   70.52 +	public void setDatatypeExprFactory(DatatypeExprFactory datatype) {
   70.53 +		this.datatype = datatype;
   70.54 +	}
   70.55 +
   70.56 +	public void setLabelExprFactory(LabelExprFactory label) {
   70.57 +		this.label = label;
   70.58 +	}
   70.59 +
   70.60 +	public void setLanguageExprFactory(LanguageExprFactory language) {
   70.61 +		this.language = language;
   70.62 +	}
   70.63 +
   70.64 +	public void setNumericExprFactory(NumericExprFactory numeric) {
   70.65 +		this.numeric = numeric;
   70.66 +	}
   70.67 +
   70.68 +	public void setTimeExprFactory(TimeExprFactory time) {
   70.69 +		this.time = time;
   70.70 +	}
   70.71 +
   70.72 +	public void setURIExprFactory(URIExprFactory uri) {
   70.73 +		this.uri = uri;
   70.74 +	}
   70.75 +
   70.76 +	public void setZonedExprFactory(ZonedExprFactory zoned) {
   70.77 +		this.zoned = zoned;
   70.78 +	}
   70.79 +
   70.80 +	public void setHashExprFactory(HashExprFactory hash) {
   70.81 +		this.hash = hash;
   70.82 +	}
   70.83 +
   70.84 +	public SqlExpr createBNodeExpr(ValueExpr arg)
   70.85 +		throws UnsupportedRdbmsOperatorException
   70.86 +	{
   70.87 +		return bnode.createBNodeExpr(arg);
   70.88 +	}
   70.89 +
   70.90 +	public SqlExpr createBooleanExpr(ValueExpr arg)
   70.91 +		throws UnsupportedRdbmsOperatorException
   70.92 +	{
   70.93 +		return bool.createBooleanExpr(arg);
   70.94 +	}
   70.95 +
   70.96 +	public SqlExpr createLabelExpr(ValueExpr arg)
   70.97 +		throws UnsupportedRdbmsOperatorException
   70.98 +	{
   70.99 +		return label.createLabelExpr(arg);
  70.100 +	}
  70.101 +
  70.102 +	public SqlExpr createLanguageExpr(ValueExpr arg)
  70.103 +		throws UnsupportedRdbmsOperatorException
  70.104 +	{
  70.105 +		return language.createLanguageExpr(arg);
  70.106 +	}
  70.107 +
  70.108 +	public SqlExpr createNumericExpr(ValueExpr arg)
  70.109 +		throws UnsupportedRdbmsOperatorException
  70.110 +	{
  70.111 +		return numeric.createNumericExpr(arg);
  70.112 +	}
  70.113 +
  70.114 +	public SqlExpr createTimeExpr(ValueExpr arg)
  70.115 +		throws UnsupportedRdbmsOperatorException
  70.116 +	{
  70.117 +		return time.createTimeExpr(arg);
  70.118 +	}
  70.119 +
  70.120 +	public SqlExpr createZonedExpr(ValueExpr arg)
  70.121 +		throws UnsupportedRdbmsOperatorException
  70.122 +	{
  70.123 +		return zoned.createZonedExpr(arg);
  70.124 +	}
  70.125 +
  70.126 +	public SqlExpr createDatatypeExpr(ValueExpr arg)
  70.127 +		throws UnsupportedRdbmsOperatorException
  70.128 +	{
  70.129 +		return datatype.createDatatypeExpr(arg);
  70.130 +	}
  70.131 +
  70.132 +	public SqlExpr createUriExpr(ValueExpr arg)
  70.133 +		throws UnsupportedRdbmsOperatorException
  70.134 +	{
  70.135 +		return uri.createUriExpr(arg);
  70.136 +	}
  70.137 +
  70.138 +	public SqlExpr createHashExpr(ValueExpr arg)
  70.139 +		throws UnsupportedRdbmsOperatorException
  70.140 +	{
  70.141 +		return hash.createHashExpr(arg);
  70.142 +	}
  70.143 +}
    71.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    71.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/factories/TimeExprFactory.java	Thu May 24 13:58:55 2012 +0300
    71.3 @@ -0,0 +1,114 @@
    71.4 +/*
    71.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    71.6 + *
    71.7 + * Licensed under the Aduna BSD-style license.
    71.8 + */
    71.9 +package org.openrdf.sail.rdbms.algebra.factories;
   71.10 +
   71.11 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.sqlNull;
   71.12 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.unsupported;
   71.13 +import static org.openrdf.sail.rdbms.managers.LiteralManager.getCalendarValue;
   71.14 +
   71.15 +import org.openrdf.model.Literal;
   71.16 +import org.openrdf.model.URI;
   71.17 +import org.openrdf.model.Value;
   71.18 +import org.openrdf.model.datatypes.XMLDatatypeUtil;
   71.19 +import org.openrdf.query.algebra.Datatype;
   71.20 +import org.openrdf.query.algebra.Lang;
   71.21 +import org.openrdf.query.algebra.MathExpr;
   71.22 +import org.openrdf.query.algebra.QueryModelNode;
   71.23 +import org.openrdf.query.algebra.Str;
   71.24 +import org.openrdf.query.algebra.ValueConstant;
   71.25 +import org.openrdf.query.algebra.ValueExpr;
   71.26 +import org.openrdf.query.algebra.Var;
   71.27 +import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;
   71.28 +import org.openrdf.sail.rdbms.algebra.DateTimeColumn;
   71.29 +import org.openrdf.sail.rdbms.algebra.NumberValue;
   71.30 +import org.openrdf.sail.rdbms.algebra.SqlNull;
   71.31 +import org.openrdf.sail.rdbms.algebra.base.SqlExpr;
   71.32 +import org.openrdf.sail.rdbms.exceptions.UnsupportedRdbmsOperatorException;
   71.33 +
   71.34 +/**
   71.35 + * Creates an SQL expression for a literal's time value.
   71.36 + * 
   71.37 + * @author James Leigh
   71.38 + * 
   71.39 + */
   71.40 +public class TimeExprFactory extends QueryModelVisitorBase<UnsupportedRdbmsOperatorException> {
   71.41 +
   71.42 +	protected SqlExpr result;
   71.43 +
   71.44 +	public SqlExpr createTimeExpr(ValueExpr expr)
   71.45 +		throws UnsupportedRdbmsOperatorException
   71.46 +	{
   71.47 +		result = null;
   71.48 +		if (expr == null)
   71.49 +			return new SqlNull();
   71.50 +		expr.visit(this);
   71.51 +		if (result == null)
   71.52 +			return new SqlNull();
   71.53 +		return result;
   71.54 +	}
   71.55 +
   71.56 +	@Override
   71.57 +	public void meet(Datatype node) {
   71.58 +		result = sqlNull();
   71.59 +	}
   71.60 +
   71.61 +	@Override
   71.62 +	public void meet(Lang node)
   71.63 +		throws UnsupportedRdbmsOperatorException
   71.64 +	{
   71.65 +		result = sqlNull();
   71.66 +	}
   71.67 +
   71.68 +	@Override
   71.69 +	public void meet(MathExpr node)
   71.70 +		throws UnsupportedRdbmsOperatorException
   71.71 +	{
   71.72 +		result = sqlNull();
   71.73 +	}
   71.74 +
   71.75 +	@Override
   71.76 +	public void meet(Str node) {
   71.77 +		result = sqlNull();
   71.78 +	}
   71.79 +
   71.80 +	@Override
   71.81 +	public void meet(ValueConstant vc) {
   71.82 +		result = valueOf(vc.getValue());
   71.83 +	}
   71.84 +
   71.85 +	@Override
   71.86 +	public void meet(Var node) {
   71.87 +		if (node.getValue() == null) {
   71.88 +			result = new DateTimeColumn(node);
   71.89 +		}
   71.90 +		else {
   71.91 +			result = valueOf(node.getValue());
   71.92 +		}
   71.93 +	}
   71.94 +
   71.95 +	@Override
   71.96 +	protected void meetNode(QueryModelNode arg)
   71.97 +		throws UnsupportedRdbmsOperatorException
   71.98 +	{
   71.99 +		throw unsupported(arg);
  71.100 +	}
  71.101 +
  71.102 +	private SqlExpr valueOf(Value value) {
  71.103 +		if (value instanceof Literal) {
  71.104 +			Literal lit = (Literal)value;
  71.105 +			URI dt = lit.getDatatype();
  71.106 +			if (dt != null && XMLDatatypeUtil.isCalendarDatatype(dt)) {
  71.107 +				try {
  71.108 +					return new NumberValue(getCalendarValue(lit.calendarValue()));
  71.109 +				}
  71.110 +				catch (IllegalArgumentException e) {
  71.111 +					return null;
  71.112 +				}
  71.113 +			}
  71.114 +		}
  71.115 +		return null;
  71.116 +	}
  71.117 +}
    72.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    72.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/factories/URIExprFactory.java	Thu May 24 13:58:55 2012 +0300
    72.3 @@ -0,0 +1,140 @@
    72.4 +/*
    72.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    72.6 + *
    72.7 + * Licensed under the Aduna BSD-style license.
    72.8 + */
    72.9 +package org.openrdf.sail.rdbms.algebra.factories;
   72.10 +
   72.11 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.and;
   72.12 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.coalesce;
   72.13 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.isNotNull;
   72.14 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.isNull;
   72.15 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.sqlNull;
   72.16 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.str;
   72.17 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.unsupported;
   72.18 +
   72.19 +import org.openrdf.model.URI;
   72.20 +import org.openrdf.model.Value;
   72.21 +import org.openrdf.model.vocabulary.XMLSchema;
   72.22 +import org.openrdf.query.algebra.Datatype;
   72.23 +import org.openrdf.query.algebra.Lang;
   72.24 +import org.openrdf.query.algebra.MathExpr;
   72.25 +import org.openrdf.query.algebra.QueryModelNode;
   72.26 +import org.openrdf.query.algebra.Str;
   72.27 +import org.openrdf.query.algebra.ValueConstant;
   72.28 +import org.openrdf.query.algebra.ValueExpr;
   72.29 +import org.openrdf.query.algebra.Var;
   72.30 +import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;
   72.31 +import org.openrdf.sail.rdbms.algebra.LongURIColumn;
   72.32 +import org.openrdf.sail.rdbms.algebra.SqlCase;
   72.33 +import org.openrdf.sail.rdbms.algebra.SqlNull;
   72.34 +import org.openrdf.sail.rdbms.algebra.URIColumn;
   72.35 +import org.openrdf.sail.rdbms.algebra.base.SqlExpr;
   72.36 +import org.openrdf.sail.rdbms.exceptions.UnsupportedRdbmsOperatorException;
   72.37 +
   72.38 +/**
   72.39 + * Creates an SQL expression for a URI's string value.
   72.40 + * 
   72.41 + * @author James Leigh
   72.42 + * 
   72.43 + */
   72.44 +public class URIExprFactory extends QueryModelVisitorBase<UnsupportedRdbmsOperatorException> {
   72.45 +
   72.46 +	protected SqlExpr result;
   72.47 +
   72.48 +	private SqlExprFactory sql;
   72.49 +
   72.50 +	public void setSqlExprFactory(SqlExprFactory sql) {
   72.51 +		this.sql = sql;
   72.52 +	}
   72.53 +
   72.54 +	public SqlExpr createUriExpr(ValueExpr expr)
   72.55 +		throws UnsupportedRdbmsOperatorException
   72.56 +	{
   72.57 +		result = null;
   72.58 +		if (expr == null)
   72.59 +			return new SqlNull();
   72.60 +		expr.visit(this);
   72.61 +		if (result == null)
   72.62 +			return new SqlNull();
   72.63 +		return result;
   72.64 +	}
   72.65 +
   72.66 +	@Override
   72.67 +	public void meet(Datatype node)
   72.68 +		throws UnsupportedRdbmsOperatorException
   72.69 +	{
   72.70 +		SqlCase sqlCase = new SqlCase();
   72.71 +		sqlCase.when(isNotNull(type(node.getArg())), type(node.getArg()));
   72.72 +		sqlCase.when(and(isNull(lang(node.getArg())), isNotNull(label(node.getArg()))),
   72.73 +				str(XMLSchema.STRING.stringValue()));
   72.74 +		result = sqlCase;
   72.75 +	}
   72.76 +
   72.77 +	@Override
   72.78 +	public void meet(Lang node)
   72.79 +		throws UnsupportedRdbmsOperatorException
   72.80 +	{
   72.81 +		result = sqlNull();
   72.82 +	}
   72.83 +
   72.84 +	@Override
   72.85 +	public void meet(MathExpr node)
   72.86 +		throws UnsupportedRdbmsOperatorException
   72.87 +	{
   72.88 +		result = sqlNull();
   72.89 +	}
   72.90 +
   72.91 +	@Override
   72.92 +	public void meet(Str node) {
   72.93 +		result = sqlNull();
   72.94 +	}
   72.95 +
   72.96 +	@Override
   72.97 +	public void meet(ValueConstant vc) {
   72.98 +		result = valueOf(vc.getValue());
   72.99 +	}
  72.100 +
  72.101 +	@Override
  72.102 +	public void meet(Var var) {
  72.103 +		if (var.getValue() == null) {
  72.104 +			result = coalesce(new URIColumn(var), new LongURIColumn(var));
  72.105 +		}
  72.106 +		else {
  72.107 +			result = valueOf(var.getValue());
  72.108 +		}
  72.109 +	}
  72.110 +
  72.111 +	@Override
  72.112 +	protected void meetNode(QueryModelNode arg)
  72.113 +		throws UnsupportedRdbmsOperatorException
  72.114 +	{
  72.115 +		throw unsupported(arg);
  72.116 +	}
  72.117 +
  72.118 +	private SqlExpr label(ValueExpr arg)
  72.119 +		throws UnsupportedRdbmsOperatorException
  72.120 +	{
  72.121 +		return sql.createLabelExpr(arg);
  72.122 +	}
  72.123 +
  72.124 +	private SqlExpr lang(ValueExpr arg)
  72.125 +		throws UnsupportedRdbmsOperatorException
  72.126 +	{
  72.127 +		return sql.createLanguageExpr(arg);
  72.128 +	}
  72.129 +
  72.130 +	private SqlExpr type(ValueExpr arg)
  72.131 +		throws UnsupportedRdbmsOperatorException
  72.132 +	{
  72.133 +		return sql.createDatatypeExpr(arg);
  72.134 +	}
  72.135 +
  72.136 +	private SqlExpr valueOf(Value value) {
  72.137 +		if (value instanceof URI) {
  72.138 +			return str(((URI)value).stringValue());
  72.139 +		}
  72.140 +		return sqlNull();
  72.141 +	}
  72.142 +
  72.143 +}
    73.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    73.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/algebra/factories/ZonedExprFactory.java	Thu May 24 13:58:55 2012 +0300
    73.3 @@ -0,0 +1,111 @@
    73.4 +/*
    73.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    73.6 + *
    73.7 + * Licensed under the Aduna BSD-style license.
    73.8 + */
    73.9 +package org.openrdf.sail.rdbms.algebra.factories;
   73.10 +
   73.11 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.num;
   73.12 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.sqlNull;
   73.13 +import static org.openrdf.sail.rdbms.algebra.base.SqlExprSupport.unsupported;
   73.14 +
   73.15 +import org.openrdf.model.Literal;
   73.16 +import org.openrdf.model.Value;
   73.17 +import org.openrdf.query.algebra.Datatype;
   73.18 +import org.openrdf.query.algebra.Lang;
   73.19 +import org.openrdf.query.algebra.MathExpr;
   73.20 +import org.openrdf.query.algebra.QueryModelNode;
   73.21 +import org.openrdf.query.algebra.Str;
   73.22 +import org.openrdf.query.algebra.ValueConstant;
   73.23 +import org.openrdf.query.algebra.ValueExpr;
   73.24 +import org.openrdf.query.algebra.Var;
   73.25 +import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;
   73.26 +import org.openrdf.sail.rdbms.algebra.RefIdColumn;
   73.27 +import org.openrdf.sail.rdbms.algebra.SqlNull;
   73.28 +import org.openrdf.sail.rdbms.algebra.SqlShift;
   73.29 +import org.openrdf.sail.rdbms.algebra.base.SqlExpr;
   73.30 +import org.openrdf.sail.rdbms.exceptions.UnsupportedRdbmsOperatorException;
   73.31 +import org.openrdf.sail.rdbms.schema.IdSequence;
   73.32 +
   73.33 +/**
   73.34 + * Creates a binary SQL expression for a dateTime zoned value.
   73.35 + * 
   73.36 + * @author James Leigh
   73.37 + * 
   73.38 + */
   73.39 +public class ZonedExprFactory extends QueryModelVisitorBase<UnsupportedRdbmsOperatorException> {
   73.40 +
   73.41 +	protected SqlExpr result;
   73.42 +
   73.43 +	private IdSequence ids;
   73.44 +
   73.45 +	public ZonedExprFactory(IdSequence ids) {
   73.46 +		super();
   73.47 +		this.ids = ids;
   73.48 +	}
   73.49 +
   73.50 +	public SqlExpr createZonedExpr(ValueExpr expr)
   73.51 +		throws UnsupportedRdbmsOperatorException
   73.52 +	{
   73.53 +		result = null;
   73.54 +		if (expr == null)
   73.55 +			return new SqlNull();
   73.56 +		expr.visit(this);
   73.57 +		if (result == null)
   73.58 +			return new SqlNull();
   73.59 +		return result;
   73.60 +	}
   73.61 +
   73.62 +	@Override
   73.63 +	public void meet(Datatype node) {
   73.64 +		result = sqlNull();
   73.65 +	}
   73.66 +
   73.67 +	@Override
   73.68 +	public void meet(Lang node)
   73.69 +		throws UnsupportedRdbmsOperatorException
   73.70 +	{
   73.71 +		result = sqlNull();
   73.72 +	}
   73.73 +
   73.74 +	@Override
   73.75 +	public void meet(MathExpr node)
   73.76 +		throws UnsupportedRdbmsOperatorException
   73.77 +	{
   73.78 +		result = sqlNull();
   73.79 +	}
   73.80 +
   73.81 +	@Override
   73.82 +	public void meet(Str node) {
   73.83 +		result = sqlNull();
   73.84 +	}
   73.85 +
   73.86 +	@Override
   73.87 +	public void meet(ValueConstant vc) {
   73.88 +		result = valueOf(vc.getValue());
   73.89 +	}
   73.90 +
   73.91 +	@Override
   73.92 +	public void meet(Var node) {
   73.93 +		if (node.getValue() == null) {
   73.94 +			result = new SqlShift(new RefIdColumn(node), ids.getShift(), ids.getMod());
   73.95 +		}
   73.96 +		else {
   73.97 +			result = valueOf(node.getValue());
   73.98 +		}
   73.99 +	}
  73.100 +
  73.101 +	@Override
  73.102 +	protected void meetNode(QueryModelNode arg)
  73.103 +		throws UnsupportedRdbmsOperatorException
  73.104 +	{
  73.105 +		throw unsupported(arg);
  73.106 +	}
  73.107 +
  73.108 +	private SqlExpr valueOf(Value value) {
  73.109 +		if (value instanceof Literal) {
  73.110 +			return num(ids.code((Literal)value));
  73.111 +		}
  73.112 +		return null;
  73.113 +	}
  73.114 +}
    74.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    74.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/config/RdbmsStoreConfig.java	Thu May 24 13:58:55 2012 +0300
    74.3 @@ -0,0 +1,172 @@
    74.4 +/*
    74.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    74.6 + *
    74.7 + * Licensed under the Aduna BSD-style license.
    74.8 + */
    74.9 +package org.openrdf.sail.rdbms.config;
   74.10 +
   74.11 +import static org.openrdf.model.util.GraphUtil.getOptionalObjectLiteral;
   74.12 +import static org.openrdf.sail.rdbms.config.RdbmsStoreSchema.JDBC_DRIVER;
   74.13 +import static org.openrdf.sail.rdbms.config.RdbmsStoreSchema.MAX_TRIPLE_TABLES;
   74.14 +import static org.openrdf.sail.rdbms.config.RdbmsStoreSchema.PASSWORD;
   74.15 +import static org.openrdf.sail.rdbms.config.RdbmsStoreSchema.URL;
   74.16 +import static org.openrdf.sail.rdbms.config.RdbmsStoreSchema.USER;
   74.17 +
   74.18 +import org.openrdf.model.Graph;
   74.19 +import org.openrdf.model.Literal;
   74.20 +import org.openrdf.model.Resource;
   74.21 +import org.openrdf.model.ValueFactory;
   74.22 +import org.openrdf.model.util.GraphUtilException;
   74.23 +import org.openrdf.sail.config.SailConfigException;
   74.24 +import org.openrdf.sail.config.SailImplConfigBase;
   74.25 +
   74.26 +/**
   74.27 + * Holds the JDBC Driver, URL, user and password, as well as the database
   74.28 + * layout.
   74.29 + * 
   74.30 + * @author James Leigh
   74.31 + */
   74.32 +public class RdbmsStoreConfig extends SailImplConfigBase {
   74.33 +
   74.34 +	/*-----------*
   74.35 +	 * Variables *
   74.36 +	 *-----------*/
   74.37 +
   74.38 +	private String jdbcDriver;
   74.39 +
   74.40 +	private String url;
   74.41 +
   74.42 +	private String user;
   74.43 +
   74.44 +	private String password;
   74.45 +
   74.46 +	private int maxTripleTables = 256;
   74.47 +
   74.48 +	/*--------------*
   74.49 +	 * Constructors *
   74.50 +	 *--------------*/
   74.51 +
   74.52 +	public RdbmsStoreConfig() {
   74.53 +		super(RdbmsStoreFactory.SAIL_TYPE);
   74.54 +	}
   74.55 +
   74.56 +	/*---------*
   74.57 +	 * Methods *
   74.58 +	 *---------*/
   74.59 +
   74.60 +	public String getJdbcDriver() {
   74.61 +		return jdbcDriver;
   74.62 +	}
   74.63 +
   74.64 +	public void setJdbcDriver(String jdbcDriver) {
   74.65 +		this.jdbcDriver = jdbcDriver;
   74.66 +	}
   74.67 +
   74.68 +	public String getUrl() {
   74.69 +		return url;
   74.70 +	}
   74.71 +
   74.72 +	public void setUrl(String url) {
   74.73 +		this.url = url;
   74.74 +	}
   74.75 +
   74.76 +	public String getUser() {
   74.77 +		return user;
   74.78 +	}
   74.79 +
   74.80 +	public void setUser(String user) {
   74.81 +		this.user = user;
   74.82 +	}
   74.83 +
   74.84 +	public String getPassword() {
   74.85 +		return password;
   74.86 +	}
   74.87 +
   74.88 +	public void setPassword(String password) {
   74.89 +		this.password = password;
   74.90 +	}
   74.91 +
   74.92 +	public int getMaxTripleTables() {
   74.93 +		return maxTripleTables;
   74.94 +	}
   74.95 +
   74.96 +	public void setMaxTripleTables(int maxTripleTables) {
   74.97 +		this.maxTripleTables = maxTripleTables;
   74.98 +	}
   74.99 +
  74.100 +	@Override
  74.101 +	public void validate()
  74.102 +		throws SailConfigException
  74.103 +	{
  74.104 +		super.validate();
  74.105 +
  74.106 +		if (url == null) {
  74.107 +			throw new SailConfigException("No URL specified for RdbmsStore");
  74.108 +		}
  74.109 +	}
  74.110 +
  74.111 +	@Override
  74.112 +	public Resource export(Graph graph) {
  74.113 +		Resource implNode = super.export(graph);
  74.114 +
  74.115 +		ValueFactory vf = graph.getValueFactory();
  74.116 +
  74.117 +		if (jdbcDriver != null) {
  74.118 +			graph.add(implNode, JDBC_DRIVER, vf.createLiteral(jdbcDriver));
  74.119 +		}
  74.120 +		if (url != null) {
  74.121 +			graph.add(implNode, URL, vf.createLiteral(url));
  74.122 +		}
  74.123 +		if (user != null) {
  74.124 +			graph.add(implNode, USER, vf.createLiteral(user));
  74.125 +		}
  74.126 +		if (password != null) {
  74.127 +			graph.add(implNode, PASSWORD, vf.createLiteral(password));
  74.128 +		}
  74.129 +		graph.add(implNode, MAX_TRIPLE_TABLES, vf.createLiteral(maxTripleTables));
  74.130 +
  74.131 +		return implNode;
  74.132 +	}
  74.133 +
  74.134 +	@Override
  74.135 +	public void parse(Graph graph, Resource implNode)
  74.136 +		throws SailConfigException
  74.137 +	{
  74.138 +		super.parse(graph, implNode);
  74.139 +
  74.140 +		try {
  74.141 +			Literal jdbcDriverLit = getOptionalObjectLiteral(graph, implNode, JDBC_DRIVER);
  74.142 +			if (jdbcDriverLit != null) {
  74.143 +				setJdbcDriver(jdbcDriverLit.getLabel());
  74.144 +			}
  74.145 +
  74.146 +			Literal urlLit = getOptionalObjectLiteral(graph, implNode, URL);
  74.147 +			if (urlLit != null) {
  74.148 +				setUrl(urlLit.getLabel());
  74.149 +			}
  74.150 +
  74.151 +			Literal userLit = getOptionalObjectLiteral(graph, implNode, USER);
  74.152 +			if (userLit != null) {
  74.153 +				setUser(userLit.getLabel());
  74.154 +			}
  74.155 +
  74.156 +			Literal passwordLit = getOptionalObjectLiteral(graph, implNode, PASSWORD);
  74.157 +			if (passwordLit != null) {
  74.158 +				setPassword(passwordLit.getLabel());
  74.159 +			}
  74.160 +
  74.161 +			Literal maxTripleTablesLit = getOptionalObjectLiteral(graph, implNode, MAX_TRIPLE_TABLES);
  74.162 +			if (maxTripleTablesLit != null) {
  74.163 +				try {
  74.164 +					setMaxTripleTables(maxTripleTablesLit.intValue());
  74.165 +				}
  74.166 +				catch (NumberFormatException e) {
  74.167 +					throw new SailConfigException("Invalid value for maxTripleTables: " + maxTripleTablesLit);
  74.168 +				}
  74.169 +			}
  74.170 +		}
  74.171 +		catch (GraphUtilException e) {
  74.172 +			throw new SailConfigException(e.getMessage(), e);
  74.173 +		}
  74.174 +	}
  74.175 +}
    75.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    75.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/config/RdbmsStoreFactory.java	Thu May 24 13:58:55 2012 +0300
    75.3 @@ -0,0 +1,64 @@
    75.4 +/*
    75.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    75.6 + *
    75.7 + * Licensed under the Aduna BSD-style license.
    75.8 + */
    75.9 +package org.openrdf.sail.rdbms.config;
   75.10 +
   75.11 +import org.openrdf.sail.config.SailConfigException;
   75.12 +import org.openrdf.sail.config.SailFactory;
   75.13 +import org.openrdf.sail.config.SailImplConfig;
   75.14 +import org.openrdf.sail.rdbms.RdbmsStore;
   75.15 +
   75.16 +/**
   75.17 + * A {@link SailFactory} that creates {@link RdbmsStore}s based on RDF
   75.18 + * configuration data.
   75.19 + * 
   75.20 + * @author James Leigh
   75.21 + */
   75.22 +public class RdbmsStoreFactory implements SailFactory {
   75.23 +
   75.24 +	/**
   75.25 +	 * The type of repositories that are created by this factory.
   75.26 +	 * 
   75.27 +	 * @see SailFactory#getSailType()
   75.28 +	 */
   75.29 +	public static final String SAIL_TYPE = "openrdf:RdbmsStore";
   75.30 +
   75.31 +	/**
   75.32 +	 * Returns the Sail's type: <tt>openrdf:RdbmsStore</tt>.
   75.33 +	 */
   75.34 +	public String getSailType() {
   75.35 +		return SAIL_TYPE;
   75.36 +	}
   75.37 +
   75.38 +	public RdbmsStoreConfig getConfig() {
   75.39 +		return new RdbmsStoreConfig();
   75.40 +	}
   75.41 +
   75.42 +	public RdbmsStore getSail(SailImplConfig config)
   75.43 +		throws SailConfigException
   75.44 +	{
   75.45 +		if (!SAIL_TYPE.equals(config.getType())) {
   75.46 +			throw new SailConfigException("Invalid Sail type: " + config.getType());
   75.47 +		}
   75.48 +
   75.49 +		if (config instanceof RdbmsStoreConfig) {
   75.50 +			RdbmsStoreConfig rdbmsConfig = (RdbmsStoreConfig)config;
   75.51 +
   75.52 +			String jdbcDriver = rdbmsConfig.getJdbcDriver();
   75.53 +			String url = rdbmsConfig.getUrl();
   75.54 +			String user = rdbmsConfig.getUser();
   75.55 +			String password = rdbmsConfig.getPassword();
   75.56 +
   75.57 +			RdbmsStore store = new RdbmsStore(jdbcDriver, url, user, password);
   75.58 +
   75.59 +			store.setMaxNumberOfTripleTables(rdbmsConfig.getMaxTripleTables());
   75.60 +
   75.61 +			return store;
   75.62 +		}
   75.63 +
   75.64 +		throw new IllegalArgumentException("Supplied config objects should be an RdbmsStoreConfig, is: "
   75.65 +				+ config.getClass());
   75.66 +	}
   75.67 +}
    76.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    76.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/config/RdbmsStoreSchema.java	Thu May 24 13:58:55 2012 +0300
    76.3 @@ -0,0 +1,40 @@
    76.4 +/*
    76.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    76.6 + *
    76.7 + * Licensed under the Aduna BSD-style license.
    76.8 + */
    76.9 +package org.openrdf.sail.rdbms.config;
   76.10 +
   76.11 +import org.openrdf.model.URI;
   76.12 +import org.openrdf.model.ValueFactory;
   76.13 +import org.openrdf.model.impl.ValueFactoryImpl;
   76.14 +
   76.15 +/**
   76.16 + * Vocabulary for the RDBMS configuration.
   76.17 + * 
   76.18 + * @author James Leigh
   76.19 + * 
   76.20 + */
   76.21 +public class RdbmsStoreSchema {
   76.22 +
   76.23 +	public static final String NAMESPACE = "http://www.openrdf.org/config/sail/rdbms#";
   76.24 +
   76.25 +	public final static URI JDBC_DRIVER;
   76.26 +
   76.27 +	public final static URI URL;
   76.28 +
   76.29 +	public final static URI USER;
   76.30 +
   76.31 +	public final static URI PASSWORD;
   76.32 +
   76.33 +	public final static URI MAX_TRIPLE_TABLES;
   76.34 +
   76.35 +	static {
   76.36 +		ValueFactory factory = ValueFactoryImpl.getInstance();
   76.37 +		JDBC_DRIVER = factory.createURI(NAMESPACE, "jdbcDriver");
   76.38 +		URL = factory.createURI(NAMESPACE, "url");
   76.39 +		USER = factory.createURI(NAMESPACE, "user");
   76.40 +		PASSWORD = factory.createURI(NAMESPACE, "password");
   76.41 +		MAX_TRIPLE_TABLES = factory.createURI(NAMESPACE, "maxTripleTables");
   76.42 +	}
   76.43 +}
    77.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    77.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/evaluation/QueryBuilder.java	Thu May 24 13:58:55 2012 +0300
    77.3 @@ -0,0 +1,686 @@
    77.4 +/*
    77.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    77.6 + *
    77.7 + * Licensed under the Aduna BSD-style license.
    77.8 + */
    77.9 +package org.openrdf.sail.rdbms.evaluation;
   77.10 +
   77.11 +import java.util.ArrayList;
   77.12 +import java.util.List;
   77.13 +
   77.14 +import org.openrdf.model.Value;
   77.15 +import org.openrdf.sail.rdbms.RdbmsValueFactory;
   77.16 +import org.openrdf.sail.rdbms.algebra.BNodeColumn;
   77.17 +import org.openrdf.sail.rdbms.algebra.ColumnVar;
   77.18 +import org.openrdf.sail.rdbms.algebra.DatatypeColumn;
   77.19 +import org.openrdf.sail.rdbms.algebra.DateTimeColumn;
   77.20 +import org.openrdf.sail.rdbms.algebra.DoubleValue;
   77.21 +import org.openrdf.sail.rdbms.algebra.FalseValue;
   77.22 +import org.openrdf.sail.rdbms.algebra.HashColumn;
   77.23 +import org.openrdf.sail.rdbms.algebra.IdColumn;
   77.24 +import org.openrdf.sail.rdbms.algebra.JoinItem;
   77.25 +import org.openrdf.sail.rdbms.algebra.LabelColumn;
   77.26 +import org.openrdf.sail.rdbms.algebra.LanguageColumn;
   77.27 +import org.openrdf.sail.rdbms.algebra.LongLabelColumn;
   77.28 +import org.openrdf.sail.rdbms.algebra.LongURIColumn;
   77.29 +import org.openrdf.sail.rdbms.algebra.NumberValue;
   77.30 +import org.openrdf.sail.rdbms.algebra.NumericColumn;
   77.31 +import org.openrdf.sail.rdbms.algebra.RefIdColumn;
   77.32 +import org.openrdf.sail.rdbms.algebra.SqlAbs;
   77.33 +import org.openrdf.sail.rdbms.algebra.SqlAnd;
   77.34 +import org.openrdf.sail.rdbms.algebra.SqlCase;
   77.35 +import org.openrdf.sail.rdbms.algebra.SqlCast;
   77.36 +import org.openrdf.sail.rdbms.algebra.SqlCompare;
   77.37 +import org.openrdf.sail.rdbms.algebra.SqlConcat;
   77.38 +import org.openrdf.sail.rdbms.algebra.SqlEq;
   77.39 +import org.openrdf.sail.rdbms.algebra.SqlIsNull;
   77.40 +import org.openrdf.sail.rdbms.algebra.SqlLike;
   77.41 +import org.openrdf.sail.rdbms.algebra.SqlLowerCase;
   77.42 +import org.openrdf.sail.rdbms.algebra.SqlMathExpr;
   77.43 +import org.openrdf.sail.rdbms.algebra.SqlNot;
   77.44 +import org.openrdf.sail.rdbms.algebra.SqlNull;
   77.45 +import org.openrdf.sail.rdbms.algebra.SqlOr;
   77.46 +import org.openrdf.sail.rdbms.algebra.SqlRegex;
   77.47 +import org.openrdf.sail.rdbms.algebra.SqlShift;
   77.48 +import org.openrdf.sail.rdbms.algebra.StringValue;
   77.49 +import org.openrdf.sail.rdbms.algebra.TrueValue;
   77.50 +import org.openrdf.sail.rdbms.algebra.URIColumn;
   77.51 +import org.openrdf.sail.rdbms.algebra.UnionItem;
   77.52 +import org.openrdf.sail.rdbms.algebra.base.BinarySqlOperator;
   77.53 +import org.openrdf.sail.rdbms.algebra.base.FromItem;
   77.54 +import org.openrdf.sail.rdbms.algebra.base.SqlConstant;
   77.55 +import org.openrdf.sail.rdbms.algebra.base.SqlExpr;
   77.56 +import org.openrdf.sail.rdbms.algebra.base.UnarySqlOperator;
   77.57 +import org.openrdf.sail.rdbms.algebra.base.ValueColumnBase;
   77.58 +import org.openrdf.sail.rdbms.exceptions.RdbmsException;
   77.59 +import org.openrdf.sail.rdbms.exceptions.UnsupportedRdbmsOperatorException;
   77.60 +
   77.61 +/**
   77.62 + * Constructs an SQL query from {@link SqlExpr}s and {@link FromItem}s.
   77.63 + * 
   77.64 + * @author James Leigh
   77.65 + * 
   77.66 + */
   77.67 +public class QueryBuilder {
   77.68 +
   77.69 +	private SqlQueryBuilder query;
   77.70 +
   77.71 +	private RdbmsValueFactory vf;
   77.72 +
   77.73 +	private boolean usingHashTable;
   77.74 +
   77.75 +	public QueryBuilder(SqlQueryBuilder builder) {
   77.76 +		super();
   77.77 +		this.query = builder;
   77.78 +	}
   77.79 +
   77.80 +	public void setValueFactory(RdbmsValueFactory vf) {
   77.81 +		this.vf = vf;
   77.82 +	}
   77.83 +
   77.84 +	public void setUsingHashTable(boolean usingHashTable) {
   77.85 +		this.usingHashTable = usingHashTable;
   77.86 +	}
   77.87 +
   77.88 +	public void distinct() {
   77.89 +		query.distinct();
   77.90 +	}
   77.91 +
   77.92 +	public QueryBuilder filter(ColumnVar var, Value val)
   77.93 +		throws RdbmsException
   77.94 +	{
   77.95 +		String alias = var.getAlias();
   77.96 +		String column = var.getColumn();
   77.97 +		query.filter().and().columnEquals(alias, column, vf.getInternalId(val));
   77.98 +		return this;
   77.99 +	}
  77.100 +
  77.101 +	public void from(FromItem from)
  77.102 +		throws RdbmsException, UnsupportedRdbmsOperatorException
  77.103 +	{
  77.104 +		from(query, from);
  77.105 +	}
  77.106 +
  77.107 +	public List<?> getParameters() {
  77.108 +		return query.findParameters(new ArrayList<Object>());
  77.109 +	}
  77.110 +
  77.111 +	public void limit(Long limit) {
  77.112 +		query.limit(limit);
  77.113 +	}
  77.114 +
  77.115 +	public void offset(Long offset) {
  77.116 +		query.offset(offset);
  77.117 +	}
  77.118 +
  77.119 +	public void orderBy(SqlExpr expr, boolean isAscending)
  77.120 +		throws UnsupportedRdbmsOperatorException
  77.121 +	{
  77.122 +		SqlExprBuilder orderBy = query.orderBy();
  77.123 +		dispatch(expr, orderBy);
  77.124 +		if (!isAscending) {
  77.125 +			orderBy.append(" DESC");
  77.126 +		}
  77.127 +	}
  77.128 +
  77.129 +	public QueryBuilder select(SqlExpr expr)
  77.130 +		throws UnsupportedRdbmsOperatorException
  77.131 +	{
  77.132 +		dispatch(expr, query.select());
  77.133 +		return this;
  77.134 +	}
  77.135 +
  77.136 +	@Override
  77.137 +	public String toString() {
  77.138 +		return query.toString();
  77.139 +	}
  77.140 +
  77.141 +	private void append(BNodeColumn var, SqlExprBuilder filter) {
  77.142 +		String alias = getBNodeAlias(var.getRdbmsVar());
  77.143 +		filter.column(alias, "value");
  77.144 +	}
  77.145 +
  77.146 +	private void append(DatatypeColumn var, SqlExprBuilder filter) {
  77.147 +		if (var.getRdbmsVar().isResource()) {
  77.148 +			filter.appendNull();
  77.149 +		}
  77.150 +		else {
  77.151 +			String alias = getDatatypeAlias(var.getRdbmsVar());
  77.152 +			filter.column(alias, "value");
  77.153 +		}
  77.154 +	}
  77.155 +
  77.156 +	private void append(DateTimeColumn var, SqlExprBuilder filter) {
  77.157 +		if (var.getRdbmsVar().isResource()) {
  77.158 +			filter.appendNull();
  77.159 +		}
  77.160 +		else {
  77.161 +			String alias = getDateTimeAlias(var.getRdbmsVar());
  77.162 +			filter.column(alias, "value");
  77.163 +		}
  77.164 +	}
  77.165 +
  77.166 +	private void append(DoubleValue expr, SqlExprBuilder filter) {
  77.167 +		filter.appendNumeric(expr.getValue());
  77.168 +	}
  77.169 +
  77.170 +	private void append(FalseValue expr, SqlExprBuilder filter) {
  77.171 +		filter.appendBoolean(false);
  77.172 +	}
  77.173 +
  77.174 +	private void append(HashColumn var, SqlExprBuilder filter) {
  77.175 +		if (usingHashTable) {
  77.176 +			String alias = getHashAlias(var.getRdbmsVar());
  77.177 +			filter.column(alias, "value");
  77.178 +		}
  77.179 +		else {
  77.180 +			filter.column(var.getAlias(), var.getColumn());
  77.181 +		}
  77.182 +	}
  77.183 +
  77.184 +	private void append(IdColumn expr, SqlExprBuilder filter) {
  77.185 +		filter.column(expr.getAlias(), expr.getColumn());
  77.186 +	}
  77.187 +
  77.188 +	private void append(LabelColumn var, SqlExprBuilder filter) {
  77.189 +		if (var.getRdbmsVar().isResource()) {
  77.190 +			filter.appendNull();
  77.191 +		}
  77.192 +		else {
  77.193 +			String alias = getLabelAlias(var.getRdbmsVar());
  77.194 +			filter.column(alias, "value");
  77.195 +		}
  77.196 +	}
  77.197 +
  77.198 +	private void append(LongLabelColumn var, SqlExprBuilder filter) {
  77.199 +		if (var.getRdbmsVar().isResource()) {
  77.200 +			filter.appendNull();
  77.201 +		}
  77.202 +		else {
  77.203 +			String alias = getLongLabelAlias(var.getRdbmsVar());
  77.204 +			filter.column(alias, "value");
  77.205 +		}
  77.206 +	}
  77.207 +
  77.208 +	private void append(LanguageColumn var, SqlExprBuilder filter) {
  77.209 +		if (var.getRdbmsVar().isResource()) {
  77.210 +			filter.appendNull();
  77.211 +		}
  77.212 +		else {
  77.213 +			String alias = getLanguageAlias(var.getRdbmsVar());
  77.214 +			filter.column(alias, "value");
  77.215 +		}
  77.216 +	}
  77.217 +
  77.218 +	private void append(LongURIColumn uri, SqlExprBuilder filter) {
  77.219 +		ColumnVar var = uri.getRdbmsVar();
  77.220 +		String alias = getLongURIAlias(var);
  77.221 +		filter.column(alias, "value");
  77.222 +	}
  77.223 +
  77.224 +	private void append(NumberValue expr, SqlExprBuilder filter) {
  77.225 +		filter.number(expr.getValue());
  77.226 +	}
  77.227 +
  77.228 +	private void append(NumericColumn var, SqlExprBuilder filter) {
  77.229 +		if (var.getRdbmsVar().isResource()) {
  77.230 +			filter.appendNull();
  77.231 +		}
  77.232 +		else {
  77.233 +			String alias = getNumericAlias(var.getRdbmsVar());
  77.234 +			filter.column(alias, "value");
  77.235 +		}
  77.236 +	}
  77.237 +
  77.238 +	private void append(RefIdColumn expr, SqlExprBuilder filter) {
  77.239 +		filter.column(expr.getAlias(), expr.getColumn());
  77.240 +	}
  77.241 +
  77.242 +	private void append(SqlAbs expr, SqlExprBuilder filter)
  77.243 +		throws UnsupportedRdbmsOperatorException
  77.244 +	{
  77.245 +		SqlBracketBuilder abs = filter.abs();
  77.246 +		dispatch(expr.getArg(), abs);
  77.247 +		abs.close();
  77.248 +	}
  77.249 +
  77.250 +	private void append(SqlAnd expr, SqlExprBuilder filter)
  77.251 +		throws UnsupportedRdbmsOperatorException
  77.252 +	{
  77.253 +		dispatch(expr.getLeftArg(), filter);
  77.254 +		filter.and();
  77.255 +		dispatch(expr.getRightArg(), filter);
  77.256 +	}
  77.257 +
  77.258 +	private void append(SqlCase expr, SqlExprBuilder filter)
  77.259 +		throws UnsupportedRdbmsOperatorException
  77.260 +	{
  77.261 +		SqlCaseBuilder caseExpr = filter.caseBegin();
  77.262 +		for (SqlCase.Entry e : expr.getEntries()) {
  77.263 +			caseExpr.when();
  77.264 +			dispatch(e.getCondition(), filter);
  77.265 +			caseExpr.then();
  77.266 +			dispatch(e.getResult(), filter);
  77.267 +		}
  77.268 +		caseExpr.end();
  77.269 +	}
  77.270 +
  77.271 +	private void append(SqlCast expr, SqlExprBuilder filter)
  77.272 +		throws UnsupportedRdbmsOperatorException
  77.273 +	{
  77.274 +		SqlCastBuilder cast = filter.cast(expr.getType());
  77.275 +		dispatch(expr.getArg(), cast);
  77.276 +		cast.close();
  77.277 +	}
  77.278 +
  77.279 +	private void append(SqlCompare expr, SqlExprBuilder filter)
  77.280 +		throws UnsupportedRdbmsOperatorException
  77.281 +	{
  77.282 +		dispatch(expr.getLeftArg(), filter);
  77.283 +		filter.appendOperator(expr.getOperator());
  77.284 +		dispatch(expr.getRightArg(), filter);
  77.285 +	}
  77.286 +
  77.287 +	private void append(SqlConcat expr, SqlExprBuilder filter)
  77.288 +		throws UnsupportedRdbmsOperatorException
  77.289 +	{
  77.290 +		SqlBracketBuilder open = filter.open();
  77.291 +		dispatch(expr.getLeftArg(), open);
  77.292 +		open.concat();
  77.293 +		dispatch(expr.getRightArg(), open);
  77.294 +		open.close();
  77.295 +	}
  77.296 +
  77.297 +	private void append(SqlEq expr, SqlExprBuilder filter)
  77.298 +		throws UnsupportedRdbmsOperatorException
  77.299 +	{
  77.300 +		dispatch(expr.getLeftArg(), filter);
  77.301 +		filter.eq();
  77.302 +		dispatch(expr.getRightArg(), filter);
  77.303 +	}
  77.304 +
  77.305 +	private void append(SqlIsNull expr, SqlExprBuilder filter)
  77.306 +		throws UnsupportedRdbmsOperatorException
  77.307 +	{
  77.308 +		dispatch(expr.getArg(), filter);
  77.309 +		filter.isNull();
  77.310 +	}
  77.311 +
  77.312 +	private void append(SqlLike expr, SqlExprBuilder filter)
  77.313 +		throws UnsupportedRdbmsOperatorException
  77.314 +	{
  77.315 +		dispatch(expr.getLeftArg(), filter);
  77.316 +		filter.like();
  77.317 +		dispatch(expr.getRightArg(), filter);
  77.318 +	}
  77.319 +
  77.320 +	private void append(SqlLowerCase expr, SqlExprBuilder filter)
  77.321 +		throws UnsupportedRdbmsOperatorException
  77.322 +	{
  77.323 +		SqlBracketBuilder lower = filter.lowerCase();
  77.324 +		dispatch(expr.getArg(), lower);
  77.325 +		lower.close();
  77.326 +	}
  77.327 +
  77.328 +	private void append(SqlMathExpr expr, SqlExprBuilder filter)
  77.329 +		throws UnsupportedRdbmsOperatorException
  77.330 +	{
  77.331 +		dispatch(expr.getLeftArg(), filter);
  77.332 +		filter.math(expr.getOperator());
  77.333 +		dispatch(expr.getRightArg(), filter);
  77.334 +	}
  77.335 +
  77.336 +	private void append(SqlNot expr, SqlExprBuilder filter)
  77.337 +		throws UnsupportedRdbmsOperatorException
  77.338 +	{
  77.339 +		if (expr.getArg() instanceof SqlIsNull) {
  77.340 +			SqlIsNull arg = (SqlIsNull)expr.getArg();
  77.341 +			dispatch(arg.getArg(), filter);
  77.342 +			filter.isNotNull();
  77.343 +		}
  77.344 +		else {
  77.345 +			SqlBracketBuilder open = filter.not();
  77.346 +			dispatch(expr.getArg(), open);
  77.347 +			open.close();
  77.348 +		}
  77.349 +	}
  77.350 +
  77.351 +	private void append(SqlNull expr, SqlExprBuilder filter) {
  77.352 +		filter.appendNull();
  77.353 +	}
  77.354 +
  77.355 +	private void append(SqlOr expr, SqlExprBuilder filter)
  77.356 +		throws UnsupportedRdbmsOperatorException
  77.357 +	{
  77.358 +		SqlBracketBuilder open = filter.open();
  77.359 +		dispatch(expr.getLeftArg(), open);
  77.360 +		open.or();
  77.361 +		dispatch(expr.getRightArg(), open);
  77.362 +		open.close();
  77.363 +	}
  77.364 +
  77.365 +	private void append(SqlRegex expr, SqlExprBuilder filter)
  77.366 +		throws UnsupportedRdbmsOperatorException
  77.367 +	{
  77.368 +		SqlRegexBuilder regex = filter.regex();
  77.369 +		dispatch(expr.getArg(), regex.value());
  77.370 +		dispatch(expr.getPatternArg(), regex.pattern());
  77.371 +		SqlExpr flags = expr.getFlagsArg();
  77.372 +		if (flags != null) {
  77.373 +			dispatch(flags, regex.flags());
  77.374 +		}
  77.375 +		regex.close();
  77.376 +	}
  77.377 +
  77.378 +	private void append(SqlShift expr, SqlExprBuilder filter)
  77.379 +		throws UnsupportedRdbmsOperatorException
  77.380 +	{
  77.381 +		SqlBracketBuilder mod = filter.mod(expr.getRange());
  77.382 +		SqlBracketBuilder open = mod.open();
  77.383 +		dispatch(expr.getArg(), open);
  77.384 +		open.rightShift(expr.getRightShift());
  77.385 +		open.close();
  77.386 +		mod.plus(expr.getRange());
  77.387 +		mod.close();
  77.388 +	}
  77.389 +
  77.390 +	private void append(StringValue expr, SqlExprBuilder filter) {
  77.391 +		filter.varchar(expr.getValue());
  77.392 +	}
  77.393 +
  77.394 +	private void append(TrueValue expr, SqlExprBuilder filter) {
  77.395 +		filter.appendBoolean(true);
  77.396 +	}
  77.397 +
  77.398 +	private void append(URIColumn uri, SqlExprBuilder filter) {
  77.399 +		ColumnVar var = uri.getRdbmsVar();
  77.400 +		String alias = getURIAlias(var);
  77.401 +		filter.column(alias, "value");
  77.402 +	}
  77.403 +
  77.404 +	private void dispatch(SqlExpr expr, SqlExprBuilder filter)
  77.405 +		throws UnsupportedRdbmsOperatorException
  77.406 +	{
  77.407 +		if (expr instanceof ValueColumnBase) {
  77.408 +			dispatchValueColumnBase((ValueColumnBase)expr, filter);
  77.409 +		}
  77.410 +		else if (expr instanceof IdColumn) {
  77.411 +			append((IdColumn)expr, filter);
  77.412 +		}
  77.413 +		else if (expr instanceof SqlConstant<?>) {
  77.414 +			dispatchSqlConstant((SqlConstant<?>)expr, filter);
  77.415 +		}
  77.416 +		else if (expr instanceof UnarySqlOperator) {
  77.417 +			dispatchUnarySqlOperator((UnarySqlOperator)expr, filter);
  77.418 +		}
  77.419 +		else if (expr instanceof BinarySqlOperator) {
  77.420 +			dispatchBinarySqlOperator((BinarySqlOperator)expr, filter);
  77.421 +		}
  77.422 +		else {
  77.423 +			dispatchOther(expr, filter);
  77.424 +		}
  77.425 +	}
  77.426 +
  77.427 +	private void dispatchBinarySqlOperator(BinarySqlOperator expr, SqlExprBuilder filter)
  77.428 +		throws UnsupportedRdbmsOperatorException
  77.429 +	{
  77.430 +		if (expr instanceof SqlAnd) {
  77.431 +			append((SqlAnd)expr, filter);
  77.432 +		}
  77.433 +		else if (expr instanceof SqlEq) {
  77.434 +			append((SqlEq)expr, filter);
  77.435 +		}
  77.436 +		else if (expr instanceof SqlOr) {
  77.437 +			append((SqlOr)expr, filter);
  77.438 +		}
  77.439 +		else if (expr instanceof SqlCompare) {
  77.440 +			append((SqlCompare)expr, filter);
  77.441 +		}
  77.442 +		else if (expr instanceof SqlRegex) {
  77.443 +			append((SqlRegex)expr, filter);
  77.444 +		}
  77.445 +		else if (expr instanceof SqlConcat) {
  77.446 +			append((SqlConcat)expr, filter);
  77.447 +		}
  77.448 +		else if (expr instanceof SqlMathExpr) {
  77.449 +			append((SqlMathExpr)expr, filter);
  77.450 +		}
  77.451 +		else if (expr instanceof SqlLike) {
  77.452 +			append((SqlLike)expr, filter);
  77.453 +		}
  77.454 +		else {
  77.455 +			throw unsupported(expr);
  77.456 +		}
  77.457 +	}
  77.458 +
  77.459 +	private void dispatchOther(SqlExpr expr, SqlExprBuilder filter)
  77.460 +		throws UnsupportedRdbmsOperatorException
  77.461 +	{
  77.462 +		if (expr instanceof SqlCase) {
  77.463 +			append((SqlCase)expr, filter);
  77.464 +		}
  77.465 +		else {
  77.466 +			throw unsupported(expr);
  77.467 +		}
  77.468 +	}
  77.469 +
  77.470 +	private void dispatchSqlConstant(SqlConstant<?> expr, SqlExprBuilder filter)
  77.471 +		throws UnsupportedRdbmsOperatorException
  77.472 +	{
  77.473 +		if (expr instanceof DoubleValue) {
  77.474 +			append((DoubleValue)expr, filter);
  77.475 +		}
  77.476 +		else if (expr instanceof FalseValue) {
  77.477 +			append((FalseValue)expr, filter);
  77.478 +		}
  77.479 +		else if (expr instanceof TrueValue) {
  77.480 +			append((TrueValue)expr, filter);
  77.481 +		}
  77.482 +		else if (expr instanceof NumberValue) {
  77.483 +			append((NumberValue)expr, filter);
  77.484 +		}
  77.485 +		else if (expr instanceof SqlNull) {
  77.486 +			append((SqlNull)expr, filter);
  77.487 +		}
  77.488 +		else if (expr instanceof StringValue) {
  77.489 +			append((StringValue)expr, filter);
  77.490 +		}
  77.491 +		else {
  77.492 +			throw unsupported(expr);
  77.493 +		}
  77.494 +	}
  77.495 +
  77.496 +	private void dispatchUnarySqlOperator(UnarySqlOperator expr, SqlExprBuilder filter)
  77.497 +		throws UnsupportedRdbmsOperatorException
  77.498 +	{
  77.499 +		if (expr instanceof SqlAbs) {
  77.500 +			append((SqlAbs)expr, filter);
  77.501 +		}
  77.502 +		else if (expr instanceof SqlIsNull) {
  77.503 +			append((SqlIsNull)expr, filter);
  77.504 +		}
  77.505 +		else if (expr instanceof SqlNot) {
  77.506 +			append((SqlNot)expr, filter);
  77.507 +		}
  77.508 +		else if (expr instanceof SqlShift) {
  77.509 +			append((SqlShift)expr, filter);
  77.510 +		}
  77.511 +		else if (expr instanceof SqlLowerCase) {
  77.512 +			append((SqlLowerCase)expr, filter);
  77.513 +		}
  77.514 +		else if (expr instanceof SqlCast) {
  77.515 +			append((SqlCast)expr, filter);
  77.516 +		}
  77.517 +		else {
  77.518 +			throw unsupported(expr);
  77.519 +		}
  77.520 +	}
  77.521 +
  77.522 +	private void dispatchValueColumnBase(ValueColumnBase expr, SqlExprBuilder filter)
  77.523 +		throws UnsupportedRdbmsOperatorException
  77.524 +	{
  77.525 +		if (expr instanceof BNodeColumn) {
  77.526 +			append((BNodeColumn)expr, filter);
  77.527 +		}
  77.528 +		else if (expr instanceof DatatypeColumn) {
  77.529 +			append((DatatypeColumn)expr, filter);
  77.530 +		}
  77.531 +		else if (expr instanceof HashColumn) {
  77.532 +			append((HashColumn)expr, filter);
  77.533 +		}
  77.534 +		else if (expr instanceof DateTimeColumn) {
  77.535 +			append((DateTimeColumn)expr, filter);
  77.536 +		}
  77.537 +		else if (expr instanceof LabelColumn) {
  77.538 +			append((LabelColumn)expr, filter);
  77.539 +		}
  77.540 +		else if (expr instanceof LongLabelColumn) {
  77.541 +			append((LongLabelColumn)expr, filter);
  77.542 +		}
  77.543 +		else if (expr instanceof LongURIColumn) {
  77.544 +			append((LongURIColumn)expr, filter);
  77.545 +		}
  77.546 +		else if (expr instanceof LanguageColumn) {
  77.547 +			append((LanguageColumn)expr, filter);
  77.548 +		}
  77.549 +		else if (expr instanceof NumericColumn) {
  77.550 +			append((NumericColumn)expr, filter);
  77.551 +		}
  77.552 +		else if (expr instanceof URIColumn) {
  77.553 +			append((URIColumn)expr, filter);
  77.554 +		}
  77.555 +		else if (expr instanceof RefIdColumn) {
  77.556 +			append((RefIdColumn)expr, filter);
  77.557 +		}
  77.558 +		else {
  77.559 +			throw unsupported(expr);
  77.560 +		}
  77.561 +	}
  77.562 +
  77.563 +	private void from(SqlQueryBuilder subquery, FromItem item)
  77.564 +		throws RdbmsException, UnsupportedRdbmsOperatorException
  77.565 +	{
  77.566 +		assert !item.isLeft() : item;
  77.567 +		String alias = item.getAlias();
  77.568 +		if (item instanceof JoinItem) {
  77.569 +			String tableName = ((JoinItem)item).getTableName();
  77.570 +			subJoinAndFilter(subquery.from(tableName, alias), item);
  77.571 +		}
  77.572 +		else {
  77.573 +			subJoinAndFilter(subquery.from(alias), item);
  77.574 +		}
  77.575 +	}
  77.576 +
  77.577 +	private String getBNodeAlias(ColumnVar var) {
  77.578 +		return "b" + getDBName(var);
  77.579 +	}
  77.580 +
  77.581 +	private String getDatatypeAlias(ColumnVar var) {
  77.582 +		return "d" + getDBName(var);
  77.583 +	}
  77.584 +
  77.585 +	private String getDateTimeAlias(ColumnVar var) {
  77.586 +		return "t" + getDBName(var);
  77.587 +	}
  77.588 +
  77.589 +	private String getDBName(ColumnVar var) {
  77.590 +		String name = var.getName();
  77.591 +		if (name.indexOf('-') >= 0)
  77.592 +			return name.replace('-', '_');
  77.593 +		return "_" + name; // might be a keyword otherwise
  77.594 +	}
  77.595 +
  77.596 +	private String getHashAlias(ColumnVar var) {
  77.597 +		return "h" + getDBName(var);
  77.598 +	}
  77.599 +
  77.600 +	private String getLabelAlias(ColumnVar var) {
  77.601 +		return "l" + getDBName(var);
  77.602 +	}
  77.603 +
  77.604 +	private String getLongLabelAlias(ColumnVar var) {
  77.605 +		return "ll" + getDBName(var);
  77.606 +	}
  77.607 +
  77.608 +	private String getLongURIAlias(ColumnVar var) {
  77.609 +		return "lu" + getDBName(var);
  77.610 +	}
  77.611 +
  77.612 +	private String getLanguageAlias(ColumnVar var) {
  77.613 +		return "g" + getDBName(var);
  77.614 +	}
  77.615 +
  77.616 +	private String getNumericAlias(ColumnVar var) {
  77.617 +		return "n" + getDBName(var);
  77.618 +	}
  77.619 +
  77.620 +	private String getURIAlias(ColumnVar var) {
  77.621 +		return "u" + getDBName(var);
  77.622 +	}
  77.623 +
  77.624 +	private void join(SqlJoinBuilder query, FromItem join)
  77.625 +		throws RdbmsException, UnsupportedRdbmsOperatorException
  77.626 +	{
  77.627 +		String alias = join.getAlias();
  77.628 +		if (join instanceof JoinItem) {
  77.629 +			String tableName = ((JoinItem)join).getTableName();
  77.630 +			if (join.isLeft()) {
  77.631 +				subJoinAndFilter(query.leftjoin(tableName, alias), join);
  77.632 +			}
  77.633 +			else {
  77.634 +				subJoinAndFilter(query.join(tableName, alias), join);
  77.635 +			}
  77.636 +		}
  77.637 +		else {
  77.638 +			if (join.isLeft()) {
  77.639 +				subJoinAndFilter(query.leftjoin(alias), join);
  77.640 +			}
  77.641 +			else {
  77.642 +				subJoinAndFilter(query.join(alias), join);
  77.643 +			}
  77.644 +		}
  77.645 +	}
  77.646 +
  77.647 +	private SqlJoinBuilder subJoinAndFilter(SqlJoinBuilder query, FromItem from)
  77.648 +		throws RdbmsException, UnsupportedRdbmsOperatorException
  77.649 +	{
  77.650 +		if (from instanceof UnionItem) {
  77.651 +			UnionItem union = (UnionItem)from;
  77.652 +			List<String> names = union.getSelectVarNames();
  77.653 +			List<ColumnVar> vars = union.appendVars(new ArrayList<ColumnVar>());
  77.654 +			SqlQueryBuilder subquery = query.subquery();
  77.655 +			for (FromItem item : union.getUnion()) {
  77.656 +				for (int i = 0, n = names.size(); i < n; i++) {
  77.657 +					ColumnVar var = item.getVar(names.get(i));
  77.658 +					SqlExprBuilder select = subquery.select();
  77.659 +					if (var == null) {
  77.660 +						select.appendNull();
  77.661 +					}
  77.662 +					else if (var.isImplied()) {
  77.663 +						select.appendNumeric(vf.getInternalId(var.getValue()));
  77.664 +					}
  77.665 +					else {
  77.666 +						select.column(var.getAlias(), var.getColumn());
  77.667 +					}
  77.668 +					select.as(vars.get(i).getColumn());
  77.669 +				}
  77.670 +				from(subquery, item);
  77.671 +				subquery = subquery.union();
  77.672 +			}
  77.673 +		}
  77.674 +		for (FromItem join : from.getJoins()) {
  77.675 +			join(query, join);
  77.676 +		}
  77.677 +		for (SqlExpr expr : from.getFilters()) {
  77.678 +			dispatch(expr, query.on().and());
  77.679 +		}
  77.680 +		return query;
  77.681 +	}
  77.682 +
  77.683 +	private UnsupportedRdbmsOperatorException unsupported(Object object)
  77.684 +		throws UnsupportedRdbmsOperatorException
  77.685 +	{
  77.686 +		return new UnsupportedRdbmsOperatorException(object.toString());
  77.687 +	}
  77.688 +
  77.689 +}
    78.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    78.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/evaluation/QueryBuilderFactory.java	Thu May 24 13:58:55 2012 +0300
    78.3 @@ -0,0 +1,60 @@
    78.4 +/*
    78.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    78.6 + *
    78.7 + * Licensed under the Aduna BSD-style license.
    78.8 + */
    78.9 +package org.openrdf.sail.rdbms.evaluation;
   78.10 +
   78.11 +import org.openrdf.sail.rdbms.RdbmsValueFactory;
   78.12 +
   78.13 +/**
   78.14 + * Creates the SQL query building components.
   78.15 + * 
   78.16 + * @author James Leigh
   78.17 + * 
   78.18 + */
   78.19 +public class QueryBuilderFactory {
   78.20 +
   78.21 +	private RdbmsValueFactory vf;
   78.22 +
   78.23 +	private boolean usingHashTable;
   78.24 +
   78.25 +	public void setValueFactory(RdbmsValueFactory vf) {
   78.26 +		this.vf = vf;
   78.27 +	}
   78.28 +
   78.29 +	public void setUsingHashTable(boolean b) {
   78.30 +		this.usingHashTable = b;
   78.31 +	}
   78.32 +
   78.33 +	public QueryBuilder createQueryBuilder() {
   78.34 +		QueryBuilder query = new QueryBuilder(createSqlQueryBuilder());
   78.35 +		query.setValueFactory(vf);
   78.36 +		query.setUsingHashTable(usingHashTable);
   78.37 +		return query;
   78.38 +	}
   78.39 +
   78.40 +	public SqlQueryBuilder createSqlQueryBuilder() {
   78.41 +		return new SqlQueryBuilder(this);
   78.42 +	}
   78.43 +
   78.44 +	public SqlExprBuilder createSqlExprBuilder() {
   78.45 +		return new SqlExprBuilder(this);
   78.46 +	}
   78.47 +
   78.48 +	public SqlRegexBuilder createSqlRegexBuilder(SqlExprBuilder where) {
   78.49 +		return new SqlRegexBuilder(where, this);
   78.50 +	}
   78.51 +
   78.52 +	public SqlBracketBuilder createSqlBracketBuilder(SqlExprBuilder where) {
   78.53 +		return new SqlBracketBuilder(where, this);
   78.54 +	}
   78.55 +
   78.56 +	public SqlJoinBuilder createSqlJoinBuilder(String table, String alias) {
   78.57 +		return new SqlJoinBuilder(table, alias, this);
   78.58 +	}
   78.59 +
   78.60 +	public SqlCastBuilder createSqlCastBuilder(SqlExprBuilder where, int type) {
   78.61 +		return new SqlCastBuilder(where, this, type);
   78.62 +	}
   78.63 +}
    79.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    79.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/evaluation/RdbmsEvaluation.java	Thu May 24 13:58:55 2012 +0300
    79.3 @@ -0,0 +1,166 @@
    79.4 +/*
    79.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    79.6 + *
    79.7 + * Licensed under the Aduna BSD-style license.
    79.8 + */
    79.9 +package org.openrdf.sail.rdbms.evaluation;
   79.10 +
   79.11 +import java.sql.Connection;
   79.12 +import java.sql.PreparedStatement;
   79.13 +import java.sql.SQLException;
   79.14 +import java.util.ArrayList;
   79.15 +import java.util.Collection;
   79.16 +import java.util.List;
   79.17 +
   79.18 +import org.slf4j.Logger;
   79.19 +import org.slf4j.LoggerFactory;
   79.20 +
   79.21 +import info.aduna.iteration.CloseableIteration;
   79.22 +
   79.23 +import org.openrdf.query.BindingSet;
   79.24 +import org.openrdf.query.Dataset;
   79.25 +import org.openrdf.query.QueryEvaluationException;
   79.26 +import org.openrdf.query.algebra.TupleExpr;
   79.27 +import org.openrdf.query.algebra.evaluation.QueryBindingSet;
   79.28 +import org.openrdf.query.algebra.evaluation.impl.EvaluationStrategyImpl;
   79.29 +import org.openrdf.sail.rdbms.RdbmsTripleRepository;
   79.30 +import org.openrdf.sail.rdbms.RdbmsValueFactory;
   79.31 +import org.openrdf.sail.rdbms.algebra.ColumnVar;
   79.32 +import org.openrdf.sail.rdbms.algebra.SelectProjection;
   79.33 +import org.openrdf.sail.rdbms.algebra.SelectQuery;
   79.34 +import org.openrdf.sail.rdbms.algebra.SelectQuery.OrderElem;
   79.35 +import org.openrdf.sail.rdbms.exceptions.RdbmsException;
   79.36 +import org.openrdf.sail.rdbms.exceptions.RdbmsQueryEvaluationException;
   79.37 +import org.openrdf.sail.rdbms.exceptions.UnsupportedRdbmsOperatorException;
   79.38 +import org.openrdf.sail.rdbms.iteration.RdbmsBindingIteration;
   79.39 +import org.openrdf.sail.rdbms.schema.IdSequence;
   79.40 +
   79.41 +/**
   79.42 + * Extends the default strategy by accepting {@link SelectQuery} and evaluating
   79.43 + * them on a database.
   79.44 + * 
   79.45 + * @author James Leigh
   79.46 + * 
   79.47 + */
   79.48 +public class RdbmsEvaluation extends EvaluationStrategyImpl {
   79.49 +
   79.50 +	private Logger logger = LoggerFactory.getLogger(RdbmsEvaluation.class);
   79.51 +
   79.52 +	private QueryBuilderFactory factory;
   79.53 +
   79.54 +	private RdbmsValueFactory vf;
   79.55 +
   79.56 +	private RdbmsTripleRepository triples;
   79.57 +
   79.58 +	private IdSequence ids;
   79.59 +
   79.60 +	public RdbmsEvaluation(QueryBuilderFactory factory, RdbmsTripleRepository triples, Dataset dataset,
   79.61 +			IdSequence ids)
   79.62 +	{
   79.63 +		super(new RdbmsTripleSource(triples), dataset);
   79.64 +		this.factory = factory;
   79.65 +		this.triples = triples;
   79.66 +		this.vf = triples.getValueFactory();
   79.67 +		this.ids = ids;
   79.68 +	}
   79.69 +
   79.70 +	@Override
   79.71 +	public CloseableIteration<BindingSet, QueryEvaluationException> evaluate(TupleExpr expr,
   79.72 +			BindingSet bindings)
   79.73 +		throws QueryEvaluationException
   79.74 +	{
   79.75 +		if (expr instanceof SelectQuery)
   79.76 +			return evaluate((SelectQuery)expr, bindings);
   79.77 +		return super.evaluate(expr, bindings);
   79.78 +	}
   79.79 +
   79.80 +	private CloseableIteration<BindingSet, QueryEvaluationException> evaluate(SelectQuery qb, BindingSet b)
   79.81 +		throws UnsupportedRdbmsOperatorException, RdbmsQueryEvaluationException
   79.82 +	{
   79.83 +		List<Object> parameters = new ArrayList<Object>();
   79.84 +		try {
   79.85 +			QueryBindingSet bindings = new QueryBindingSet(b);
   79.86 +			String query = toQueryString(qb, bindings, parameters);
   79.87 +			try {
   79.88 +				Connection conn = triples.getConnection();
   79.89 +				PreparedStatement stmt = conn.prepareStatement(query);
   79.90 +				int p = 0;
   79.91 +				for (Object o : parameters) {
   79.92 +					stmt.setObject(++p, o);
   79.93 +				}
   79.94 +				Collection<ColumnVar> proj = qb.getProjections();
   79.95 +				RdbmsBindingIteration result = new RdbmsBindingIteration(stmt);
   79.96 +				result.setProjections(proj);
   79.97 +				result.setBindings(bindings);
   79.98 +				result.setValueFactory(vf);
   79.99 +				result.setIdSequence(ids);
  79.100 +				return result;
  79.101 +			}
  79.102 +			catch (SQLException e) {
  79.103 +				throw new RdbmsQueryEvaluationException(e.toString() + "\n" + query, e);
  79.104 +			}
  79.105 +		}
  79.106 +		catch (RdbmsException e) {
  79.107 +			throw new RdbmsQueryEvaluationException(e);
  79.108 +		}
  79.109 +	}
  79.110 +
  79.111 +	private String toQueryString(SelectQuery qb, QueryBindingSet bindings, List<Object> parameters)
  79.112 +		throws RdbmsException, UnsupportedRdbmsOperatorException
  79.113 +	{
  79.114 +		QueryBuilder query = factory.createQueryBuilder();
  79.115 +		if (qb.isDistinct()) {
  79.116 +			query.distinct();
  79.117 +		}
  79.118 +		query.from(qb.getFrom());
  79.119 +		for (ColumnVar var : qb.getVars()) {
  79.120 +			for (String name : qb.getBindingNames(var)) {
  79.121 +				if (var.getValue() == null && bindings.hasBinding(name)) {
  79.122 +					query.filter(var, bindings.getValue(name));
  79.123 +				}
  79.124 +				else if (var.getValue() != null && !bindings.hasBinding(name)
  79.125 +						&& qb.getBindingNames().contains(name))
  79.126 +				{
  79.127 +					bindings.addBinding(name, var.getValue());
  79.128 +				}
  79.129 +			}
  79.130 +		}
  79.131 +		int index = 0;
  79.132 +		for (SelectProjection proj : qb.getSqlSelectVar()) {
  79.133 +			ColumnVar var = proj.getVar();
  79.134 +			if (!var.isHiddenOrConstant()) {
  79.135 +				for (String name : qb.getBindingNames(var)) {
  79.136 +					if (!bindings.hasBinding(name)) {
  79.137 +						var.setIndex(index);
  79.138 +						query.select(proj.getId());
  79.139 +						query.select(proj.getStringValue());
  79.140 +						index += 2;
  79.141 +						if (var.getTypes().isLiterals()) {
  79.142 +							query.select(proj.getLanguage());
  79.143 +							query.select(proj.getDatatype());
  79.144 +							index += 2;
  79.145 +						}
  79.146 +					}
  79.147 +				}
  79.148 +			}
  79.149 +		}
  79.150 +		for (OrderElem by : qb.getOrderElems()) {
  79.151 +			query.orderBy(by.sqlExpr, by.isAscending);
  79.152 +			if (qb.isDistinct()) {
  79.153 +				query.select(by.sqlExpr);
  79.154 +			}
  79.155 +		}
  79.156 +		if (qb.getLimit() != null) {
  79.157 +			query.limit(qb.getLimit());
  79.158 +		}
  79.159 +		if (qb.getOffset() != null) {
  79.160 +			query.offset(qb.getOffset());
  79.161 +		}
  79.162 +		parameters.addAll(query.getParameters());
  79.163 +		if (logger.isDebugEnabled()) {
  79.164 +			logger.debug(query.toString());
  79.165 +			logger.debug(parameters.toString());
  79.166 +		}
  79.167 +		return query.toString();
  79.168 +	}
  79.169 +}
    80.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    80.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/evaluation/RdbmsEvaluationFactory.java	Thu May 24 13:58:55 2012 +0300
    80.3 @@ -0,0 +1,41 @@
    80.4 +/*
    80.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    80.6 + *
    80.7 + * Licensed under the Aduna BSD-style license.
    80.8 + */
    80.9 +package org.openrdf.sail.rdbms.evaluation;
   80.10 +
   80.11 +import org.openrdf.query.Dataset;
   80.12 +import org.openrdf.sail.rdbms.RdbmsTripleRepository;
   80.13 +import org.openrdf.sail.rdbms.schema.IdSequence;
   80.14 +
   80.15 +/**
   80.16 + * Creates an {@link RdbmsEvaluation}.
   80.17 + * 
   80.18 + * @author James Leigh
   80.19 + * 
   80.20 + */
   80.21 +public class RdbmsEvaluationFactory {
   80.22 +
   80.23 +	private QueryBuilderFactory factory;
   80.24 +
   80.25 +	private RdbmsTripleRepository triples;
   80.26 +
   80.27 +	private IdSequence ids;
   80.28 +
   80.29 +	public void setQueryBuilderFactory(QueryBuilderFactory factory) {
   80.30 +		this.factory = factory;
   80.31 +	}
   80.32 +
   80.33 +	public void setRdbmsTripleRepository(RdbmsTripleRepository triples) {
   80.34 +		this.triples = triples;
   80.35 +	}
   80.36 +
   80.37 +	public void setIdSequence(IdSequence ids) {
   80.38 +		this.ids = ids;
   80.39 +	}
   80.40 +
   80.41 +	public RdbmsEvaluation createRdbmsEvaluation(Dataset dataset) {
   80.42 +		return new RdbmsEvaluation(factory, triples, dataset, ids);
   80.43 +	}
   80.44 +}
    81.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    81.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/evaluation/RdbmsTripleSource.java	Thu May 24 13:58:55 2012 +0300
    81.3 @@ -0,0 +1,57 @@
    81.4 +/*
    81.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    81.6 + *
    81.7 + * Licensed under the Aduna BSD-style license.
    81.8 + */
    81.9 +package org.openrdf.sail.rdbms.evaluation;
   81.10 +
   81.11 +import info.aduna.iteration.CloseableIteration;
   81.12 +
   81.13 +import org.openrdf.model.Resource;
   81.14 +import org.openrdf.model.URI;
   81.15 +import org.openrdf.model.Value;
   81.16 +import org.openrdf.query.QueryEvaluationException;
   81.17 +import org.openrdf.query.algebra.evaluation.TripleSource;
   81.18 +import org.openrdf.sail.SailException;
   81.19 +import org.openrdf.sail.rdbms.RdbmsTripleRepository;
   81.20 +import org.openrdf.sail.rdbms.RdbmsValueFactory;
   81.21 +import org.openrdf.sail.rdbms.model.RdbmsResource;
   81.22 +import org.openrdf.sail.rdbms.model.RdbmsURI;
   81.23 +import org.openrdf.sail.rdbms.model.RdbmsValue;
   81.24 +
   81.25 +/**
   81.26 + * Proxies request to a {@link RdbmsTripleRepository}.
   81.27 + * 
   81.28 + * @author James Leigh
   81.29 + * 
   81.30 + */
   81.31 +public class RdbmsTripleSource implements TripleSource {
   81.32 +
   81.33 +	private RdbmsTripleRepository triples;
   81.34 +
   81.35 +	public RdbmsTripleSource(RdbmsTripleRepository triples) {
   81.36 +		super();
   81.37 +		this.triples = triples;
   81.38 +	}
   81.39 +
   81.40 +	public RdbmsValueFactory getValueFactory() {
   81.41 +		return triples.getValueFactory();
   81.42 +	}
   81.43 +
   81.44 +	public CloseableIteration getStatements(Resource subj, URI pred, Value obj, Resource... contexts)
   81.45 +		throws QueryEvaluationException
   81.46 +	{
   81.47 +		try {
   81.48 +			RdbmsValueFactory vf = triples.getValueFactory();
   81.49 +			RdbmsResource s = vf.asRdbmsResource(subj);
   81.50 +			RdbmsURI p = vf.asRdbmsURI(pred);
   81.51 +			RdbmsValue o = vf.asRdbmsValue(obj);
   81.52 +			RdbmsResource[] c = vf.asRdbmsResource(contexts);
   81.53 +			return triples.find(s, p, o, c);
   81.54 +		}
   81.55 +		catch (SailException e) {
   81.56 +			throw new QueryEvaluationException(e);
   81.57 +		}
   81.58 +	}
   81.59 +
   81.60 +}
    82.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    82.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/evaluation/SqlBracketBuilder.java	Thu May 24 13:58:55 2012 +0300
    82.3 @@ -0,0 +1,40 @@
    82.4 +/*
    82.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    82.6 + *
    82.7 + * Licensed under the Aduna BSD-style license.
    82.8 + */
    82.9 +package org.openrdf.sail.rdbms.evaluation;
   82.10 +
   82.11 +/**
   82.12 + * Prints round brackets in an SQL query.
   82.13 + * 
   82.14 + * @author James Leigh
   82.15 + * 
   82.16 + */
   82.17 +public class SqlBracketBuilder extends SqlExprBuilder {
   82.18 +
   82.19 +	private SqlExprBuilder where;
   82.20 +
   82.21 +	private String closing = ")";
   82.22 +
   82.23 +	public SqlBracketBuilder(SqlExprBuilder where, QueryBuilderFactory factory) {
   82.24 +		super(factory);
   82.25 +		this.where = where;
   82.26 +		append("(");
   82.27 +	}
   82.28 +
   82.29 +	public String getClosing() {
   82.30 +		return closing;
   82.31 +	}
   82.32 +
   82.33 +	public void setClosing(String closing) {
   82.34 +		this.closing = closing;
   82.35 +	}
   82.36 +
   82.37 +	public SqlExprBuilder close() {
   82.38 +		append(closing);
   82.39 +		where.append(toSql());
   82.40 +		where.addParameters(getParameters());
   82.41 +		return where;
   82.42 +	}
   82.43 +}
    83.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    83.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/evaluation/SqlCaseBuilder.java	Thu May 24 13:58:55 2012 +0300
    83.3 @@ -0,0 +1,38 @@
    83.4 +/*
    83.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    83.6 + *
    83.7 + * Licensed under the Aduna BSD-style license.
    83.8 + */
    83.9 +package org.openrdf.sail.rdbms.evaluation;
   83.10 +
   83.11 +/**
   83.12 + * Facilitates the creation of a CASE expression in SQL.
   83.13 + * 
   83.14 + * @author James Leigh
   83.15 + * 
   83.16 + */
   83.17 +public class SqlCaseBuilder {
   83.18 +
   83.19 +	private SqlExprBuilder where;
   83.20 +
   83.21 +	public SqlCaseBuilder(SqlExprBuilder where) {
   83.22 +		super();
   83.23 +		this.where = where;
   83.24 +		where.append("CASE ");
   83.25 +	}
   83.26 +
   83.27 +	public SqlExprBuilder when() {
   83.28 +		where.append(" WHEN ");
   83.29 +		return where;
   83.30 +	}
   83.31 +
   83.32 +	public SqlExprBuilder then() {
   83.33 +		where.append(" THEN ");
   83.34 +		return where;
   83.35 +	}
   83.36 +
   83.37 +	public SqlExprBuilder end() {
   83.38 +		where.append(" END");
   83.39 +		return where;
   83.40 +	}
   83.41 +}
    84.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    84.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/evaluation/SqlCastBuilder.java	Thu May 24 13:58:55 2012 +0300
    84.3 @@ -0,0 +1,46 @@
    84.4 +/*
    84.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    84.6 + *
    84.7 + * Licensed under the Aduna BSD-style license.
    84.8 + */
    84.9 +package org.openrdf.sail.rdbms.evaluation;
   84.10 +
   84.11 +import java.sql.Types;
   84.12 +
   84.13 +/**
   84.14 + * Prints round brackets in an SQL query.
   84.15 + * 
   84.16 + * @author James Leigh
   84.17 + * 
   84.18 + */
   84.19 +public class SqlCastBuilder extends SqlExprBuilder {
   84.20 +
   84.21 +	private SqlExprBuilder where;
   84.22 +
   84.23 +	private int jdbcType;
   84.24 +
   84.25 +	public SqlCastBuilder(SqlExprBuilder where, QueryBuilderFactory factory, int jdbcType) {
   84.26 +		super(factory);
   84.27 +		this.where = where;
   84.28 +		this.jdbcType = jdbcType;
   84.29 +		append(" CAST(");
   84.30 +	}
   84.31 +
   84.32 +	public SqlExprBuilder close() {
   84.33 +		append(" AS ");
   84.34 +		append(getSqlType(jdbcType));
   84.35 +		append(")");
   84.36 +		where.append(toSql());
   84.37 +		where.addParameters(getParameters());
   84.38 +		return where;
   84.39 +	}
   84.40 +
   84.41 +	protected CharSequence getSqlType(int type) {
   84.42 +		switch (type) {
   84.43 +			case Types.VARCHAR:
   84.44 +				return "VARCHAR";
   84.45 +			default:
   84.46 +				throw new AssertionError(type);
   84.47 +		}
   84.48 +	}
   84.49 +}
    85.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    85.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/evaluation/SqlExprBuilder.java	Thu May 24 13:58:55 2012 +0300
    85.3 @@ -0,0 +1,270 @@
    85.4 +/*
    85.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    85.6 + *
    85.7 + * Licensed under the Aduna BSD-style license.
    85.8 + */
    85.9 +package org.openrdf.sail.rdbms.evaluation;
   85.10 +
   85.11 +import java.util.ArrayList;
   85.12 +import java.util.List;
   85.13 +
   85.14 +import org.openrdf.query.algebra.MathExpr;
   85.15 +import org.openrdf.sail.rdbms.algebra.SqlCompare;
   85.16 +
   85.17 +/**
   85.18 + * Assemblies an SQL expression.
   85.19 + * 
   85.20 + * @author James Leigh
   85.21 + * 
   85.22 + */
   85.23 +public class SqlExprBuilder {
   85.24 +
   85.25 +	protected class Mark {
   85.26 +
   85.27 +		int length;
   85.28 +
   85.29 +		int size;
   85.30 +
   85.31 +		Mark(int length, int size) {
   85.32 +			this.length = length;
   85.33 +			this.size = size;
   85.34 +		}
   85.35 +	}
   85.36 +
   85.37 +	private static final String NULL = " NULL ";
   85.38 +
   85.39 +	private QueryBuilderFactory factory;
   85.40 +
   85.41 +	private List<Object> parameters = new ArrayList<Object>();
   85.42 +
   85.43 +	private StringBuilder where = new StringBuilder();
   85.44 +
   85.45 +	public SqlExprBuilder(QueryBuilderFactory factory) {
   85.46 +		super();
   85.47 +		this.factory = factory;
   85.48 +	}
   85.49 +
   85.50 +	public SqlBracketBuilder abs() {
   85.51 +		where.append(" ABS");
   85.52 +		return open();
   85.53 +	}
   85.54 +
   85.55 +	public SqlExprBuilder and() {
   85.56 +		if (!isEmpty()) {
   85.57 +			where.append("\n AND ");
   85.58 +		}
   85.59 +		return this;
   85.60 +	}
   85.61 +
   85.62 +	public SqlExprBuilder append(CharSequence sql) {
   85.63 +		where.append(sql);
   85.64 +		return this;
   85.65 +	}
   85.66 +
   85.67 +	public void appendBoolean(boolean booleanValue) {
   85.68 +		if (booleanValue) {
   85.69 +			where.append(" 1=1 ");
   85.70 +		}
   85.71 +		else {
   85.72 +			where.append(" 0=1 ");
   85.73 +		}
   85.74 +	}
   85.75 +
   85.76 +	public SqlExprBuilder appendNull() {
   85.77 +		where.append(getSqlNull());
   85.78 +		return this;
   85.79 +	}
   85.80 +
   85.81 +	public SqlExprBuilder appendNumeric(Number doubleValue) {
   85.82 +		where.append(" ? ");
   85.83 +		parameters.add(doubleValue);
   85.84 +		return this;
   85.85 +	}
   85.86 +
   85.87 +	public void appendOperator(SqlCompare.Operator op) {
   85.88 +		switch (op) {
   85.89 +			case GE:
   85.90 +				where.append(" >= ");
   85.91 +				break;
   85.92 +			case GT:
   85.93 +				where.append(" > ");
   85.94 +				break;
   85.95 +			case LE:
   85.96 +				where.append(" <= ");
   85.97 +				break;
   85.98 +			case LT:
   85.99 +				where.append(" < ");
  85.100 +				break;
  85.101 +		}
  85.102 +	}
  85.103 +
  85.104 +	public void as(String column) {
  85.105 +		where.append(" AS ").append(column);
  85.106 +	}
  85.107 +
  85.108 +	public SqlExprBuilder number(Number time) {
  85.109 +		where.append(" ? ");
  85.110 +		parameters.add(time);
  85.111 +		return this;
  85.112 +	}
  85.113 +
  85.114 +	public SqlCaseBuilder caseBegin() {
  85.115 +		return new SqlCaseBuilder(this);
  85.116 +	}
  85.117 +
  85.118 +	public SqlCastBuilder cast(int jdbcType) {
  85.119 +		return factory.createSqlCastBuilder(this, jdbcType);
  85.120 +	}
  85.121 +
  85.122 +	public SqlExprBuilder column(String alias, String column) {
  85.123 +		where.append(alias).append(".").append(column);
  85.124 +		return this;
  85.125 +	}
  85.126 +
  85.127 +	public SqlExprBuilder columnEquals(String alias, String column, Number id) {
  85.128 +		return column(alias, column).eq().number(id);
  85.129 +	}
  85.130 +
  85.131 +	public SqlExprBuilder columnEquals(String alias, String column, String label) {
  85.132 +		return column(alias, column).eq().varchar(label);
  85.133 +	}
  85.134 +
  85.135 +	public SqlExprBuilder columnIn(String alias, String column, Number[] ids) {
  85.136 +		if (ids.length == 1) {
  85.137 +			return columnEquals(alias, column, ids[0]);
  85.138 +		}
  85.139 +		SqlBracketBuilder open = open();
  85.140 +		for (int i = 0; i < ids.length; i++) {
  85.141 +			if (i > 0) {
  85.142 +				open.or();
  85.143 +			}
  85.144 +			open.column(alias, column);
  85.145 +			open.eq();
  85.146 +			open.number(ids[i]);
  85.147 +		}
  85.148 +		open.close();
  85.149 +		return this;
  85.150 +	}
  85.151 +
  85.152 +	public SqlExprBuilder columnsEqual(String al1, String col1, String al2, String col2) {
  85.153 +		return column(al1, col1).eq().column(al2, col2);
  85.154 +	}
  85.155 +
  85.156 +	public void concat() {
  85.157 +		append(" || ");
  85.158 +	}
  85.159 +
  85.160 +	public SqlExprBuilder eq() {
  85.161 +		where.append(" = ");
  85.162 +		return this;
  85.163 +	}
  85.164 +
  85.165 +	public List<Object> getParameters() {
  85.166 +		return parameters;
  85.167 +	}
  85.168 +
  85.169 +	public boolean isEmpty() {
  85.170 +		return where.length() == 0;
  85.171 +	}
  85.172 +
  85.173 +	public SqlExprBuilder isNotNull() {
  85.174 +		where.append(" IS NOT NULL ");
  85.175 +		return this;
  85.176 +	}
  85.177 +
  85.178 +	public SqlExprBuilder isNull() {
  85.179 +		where.append(" IS NULL ");
  85.180 +		return this;
  85.181 +	}
  85.182 +
  85.183 +	public void like() {
  85.184 +		where.append(" LIKE ");
  85.185 +	}
  85.186 +
  85.187 +	public SqlBracketBuilder lowerCase() {
  85.188 +		where.append(" lower");
  85.189 +		return open();
  85.190 +	}
  85.191 +
  85.192 +	public void math(MathExpr.MathOp op) {
  85.193 +		append(" ").append(op.getSymbol()).append(" ");
  85.194 +	}
  85.195 +
  85.196 +	public SqlBracketBuilder mod(int value) {
  85.197 +		where.append(" MOD");
  85.198 +		SqlBracketBuilder open = open();
  85.199 +		open.setClosing("," + value + open.getClosing());
  85.200 +		return open;
  85.201 +	}
  85.202 +
  85.203 +	public SqlBracketBuilder not() {
  85.204 +		where.append(" NOT");
  85.205 +		return open();
  85.206 +	}
  85.207 +
  85.208 +	public SqlExprBuilder notEqual() {
  85.209 +		where.append(" <> ");
  85.210 +		return this;
  85.211 +	}
  85.212 +
  85.213 +	public SqlBracketBuilder open() {
  85.214 +		return factory.createSqlBracketBuilder(this);
  85.215 +	}
  85.216 +
  85.217 +	public SqlExprBuilder or() {
  85.218 +		append(" OR ");
  85.219 +		return this;
  85.220 +	}
  85.221 +
  85.222 +	public void plus(int range) {
  85.223 +		where.append(" + " + range);
  85.224 +	}
  85.225 +
  85.226 +	public SqlRegexBuilder regex() {
  85.227 +		return factory.createSqlRegexBuilder(this);
  85.228 +	}
  85.229 +
  85.230 +	public void rightShift(int rightShift) {
  85.231 +		where.append(" >> " + rightShift);
  85.232 +	}
  85.233 +
  85.234 +	public CharSequence toSql() {
  85.235 +		return where;
  85.236 +	}
  85.237 +
  85.238 +	@Override
  85.239 +	public String toString() {
  85.240 +		return where.toString();
  85.241 +	}
  85.242 +
  85.243 +	public SqlExprBuilder varchar(String stringValue) {
  85.244 +		if (stringValue == null) {
  85.245 +			appendNull();
  85.246 +		}
  85.247 +		else {
  85.248 +			where.append(" ? ");
  85.249 +			parameters.add(stringValue);
  85.250 +		}
  85.251 +		return this;
  85.252 +	}
  85.253 +
  85.254 +	protected void addParameters(List<Object> params) {
  85.255 +		parameters.addAll(params);
  85.256 +	}
  85.257 +
  85.258 +	protected String getSqlNull() {
  85.259 +		return NULL;
  85.260 +	}
  85.261 +
  85.262 +	protected Mark mark() {
  85.263 +		return new Mark(where.length(), parameters.size());
  85.264 +	}
  85.265 +
  85.266 +	protected void reset(Mark mark) {
  85.267 +		where.delete(mark.length, where.length());
  85.268 +		for (int i = parameters.size() - 1; i >= mark.size; i--) {
  85.269 +			parameters.remove(i);
  85.270 +		}
  85.271 +	}
  85.272 +
  85.273 +}
    86.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    86.2 +++ b/rdbms/src/main/java/org/openrdf/sail/rdbms/evaluation/SqlJoinBuilder.java	Thu May 24 13:58:55 2012 +0300
    86.3 @@ -0,0 +1,206 @@
    86.4 +/*
    86.5 + * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
    86.6 + *
    86.7 + * Licensed under the Aduna BSD-style license.
    86.8 + */
    86.9 +package org.openrdf.sail.rdbms.evaluation;
   86.10 +
   86.11 +import java.util.ArrayList;
   86.12 +import java.util.List;
   86.13 +
   86.14 +/**
   86.15 + * Facilitates the building of a JOIN or FROM clause in SQL.
   86.16 + * 
   86.17 + * @author James Leigh
   86.18 + * 
   86.19 + */
   86.20 +public class SqlJoinBuilder {
   86.21 +
   86.22 +	private boolean left;
   86.23 +
   86.24 +	private SqlQueryBuilder subquery;
   86.25 +
   86.26 +	private String table;
   86.27 +
   86.28 +	private String alias;
   86.29 +
   86.30 +	private QueryBuilderFactory factory;
   86.31 +
   86.32 +	private List<SqlJoinBuilder> joins = new ArrayList<SqlJoinBuilder>();
   86.33 +
   86.34 +	private SqlExprBuilder on;
   86.35 +
   86.36 +	private List<SqlJoinBuilder> leftJoins = new ArrayList<SqlJoinBuilder>();
   86.37 +
   86.38 +	public SqlJoinBuilder(String table, String alias, QueryBuilderFactory factory) {
   86.39 +		super();
   86.40 +		this.table = table;
   86.41 +		this.alias = alias;
   86.42 +		this.factory = factory;
   86.43 +		on = factory.createSqlExprBuilder();
   86.44 +	}
   86.45 +
   86.46 +	public boolean isLeft() {
   86.47 +		return left;
   86.48 +	}
   86.49 +
   86.50 +	public void setLeft(boolean left) {
   86.51 +		this.left = left;
   86.52 +	}
   86.53 +
   86.54 +	public String getTable() {
   86.55 +		if (subquery == null)
   86.56 +			return table;
   86.57 +		return "( " + subquery.toString() + " )";
   86.58 +	}
   86.59 +
   86.60 +	public String getAlias() {
   86.61 +		return alias;
   86.62 +	}
   86.63 +
   86.64 +	public List<SqlJoinBuilder> getLeftJoins() {
   86.65 +		return leftJoins;
   86.66 +	}
   86.67 +
   86.68 +	public SqlJoinBuilder on(String column, String expression) {
   86.69 +		on.and().column(alias, column).eq().append(expression);
   86.70 +		return this;
   86.71 +	}
   86.72 +
   86.73 +	public SqlJoinBuilder findJoin(String alias) {
   86.74 +		if (alias.equals(this.alias))
   86.75 +			return this;
   86.76 +		SqlJoinBuilder result;
   86.77 +		for (SqlJoinBuilder join : joins) {
   86.78 +			result = join.findJoin(alias);
   86.79 +			if (result != null)
   86.80 +				return result;
   86.81 +		}
   86.82 +		for (SqlJoinBuilder join : leftJoins) {
   86.83 +			result = join.findJoin(alias);
   86.84 +			if (result != null)
   86.85 +				return result;
   86.86 +		}
   86.87 +		return null;
   86.88 +	}
   86.89 +
   86.90 +	public SqlJoinBuilder join(String table, String alias) {
   86.91 +		SqlJoinBuilder join = findJoin(alias);
   86.92 +		if (join != null)
   86.93 +			return join;
   86.94 +		join = factory.createSqlJoinBuilder(table, alias);
   86.95 +		joins.add(join);
   86.96 +		return join;
   86.97 +	}
   86.98 +
   86.99 +	public SqlJoinBuilder leftjoin(String table, String alias) {
  86.100 +		SqlJoinBuilder join = findJoin(alias);
  86.101 +		if (join != null)
  86.102 +			return join;
  86.103 +		join = factory.createSqlJoinBuilder(table, alias);
  86.104 +		join.setLeft(true);
  86.105 +		leftJoins.add(join);
  86.106 +		return join;
  86.107 +	}
  86.108 +
  86.109 +	public SqlJoinBuilder join(String alias) {
  86.110 +		SqlJoinBuilder join = findJoin(alias);
  86.111 +		if (join != null)
  86.112 +			return join;
  86.113 +		join = factory.createSqlJoinBuilder(null, alias);
  86.114 +		joins.add(join);
  86.115 +		return join;
  86.116 +	}
  86.117 +
  86.118 +	public SqlJoinBuilder leftjoin(String alias) {
  86.119 +		SqlJoinBuilder join = findJoin(alias);
  86.120 +		if (join != null)
  86.121 +			return join;
  86.122 +		join = factory.createSqlJoinBuilder(null, alias);
  86.123 +		join.setLeft(true);
  86.124 +		leftJoins.add(join);
  86.125 +		return join;
  86.126 +	}
  86.127 +
  86.128 +	public SqlQueryBuilder subquery() {
  86.129 +		assert table == null : table;
  86.130 +		assert subquery == null : subquery;
  86.131 +		return subquery = factory.createSqlQueryBuilder();
  86.132 +	}
  86.133 +
  86.134 +	public SqlExprBuilder on() {
  86.135 +		return on;
  86.136 +	}
  86.137 +
  86.138 +	@Override
  86.139 +	public String toString() {
  86.140 +		StringBuilder sb = new StringBuilder();
  86.141 +		if (isLeft()) {
  86.142 +			sb.append("LEFT ");
  86.143 +		}
  86.144 +		sb.append("JOIN ").append(getJoinClause());
  86.145 +		sb.append(" ON (").append(on()).append(")");
  86.146 +		return sb.toString();
  86.147 +	}
  86.148 +
  86.149 +	public CharSequence getFromClause() {
  86.150 +		if (joins.isEmpty() && leftJoins.isEmpty())
  86.151 +			return getTable() + " " + alias;
  86.152 +		StringBuilder from = new StringBuilder();
  86.153 +		from.append(getTable()).append(" ").append(alias);
  86.154 +		for (SqlJoinBuilder join : joins) {
  86.155 +			appendJoin(from, join);
  86.156 +		}
  86.157 +		for (SqlJoinBuilder left : getLeftJoins()) {
  86.158 +			from.append("\n LEFT JOIN ").append(left.getJoinClause());
  86.159 +			from.append(" ON (").append(left.on()).append(")");
  86.160 +		}
  86.161 +		return from;
  86.162 +	}
  86.163 +
  86.164 +	protected CharSequence getJoinClause() {
  86.165 +		if (joins.isEmpty() && leftJoins.isEmpty())
  86.166 +			return getTable() + " " + alias;
  86.167 +		StringBuilder from = new StringBuilder();
  86.168 +		from.append("(");
  86.169 +		from.append(getFromClause());
  86.170 +		from.append(")");
  86.171 +		return