package org.olap.server.processor.sql; import java.util.HashSet; import java.util.List; import java.util.Set; import org.olap.server.database.physical.DimensionTable; import org.olap.server.database.physical.TableColumn; import org.olap.server.database.physical.TableJoin; import org.olap.server.processor.LevelMember; import org.olap4j.OlapException; import com.healthmarketscience.sqlbuilder.BinaryCondition; import com.healthmarketscience.sqlbuilder.ComboCondition; import com.healthmarketscience.sqlbuilder.Condition; import com.healthmarketscience.sqlbuilder.CustomCondition; import com.healthmarketscience.sqlbuilder.InCondition; import com.healthmarketscience.sqlbuilder.NotCondition; import com.healthmarketscience.sqlbuilder.SelectQuery; import com.healthmarketscience.sqlbuilder.Subquery; import com.healthmarketscience.sqlbuilder.UnaryCondition; public class SetSubquery { private TableJoin join; private TableColumn column; private Set<String> values; private String from_value, to_value; private String having_expression; private SetSubquery except, exists; public SetSubquery(TableJoin join, TableColumn column, List<String> values) { this.join = join; this.column = column; this.values = new HashSet<String>(values); } public SetSubquery(TableJoin join, TableColumn column, String from_value, String to_value) { this.join = join; this.column = column; this.from_value = from_value; this.to_value = to_value; } public SetSubquery(String havingExpressionString) { this.having_expression = havingExpressionString; } public SetSubquery or(SetSubquery q) throws OlapException { if( q.column!=column ) throw new OlapException("Incompatible members in set "+q.column.column+" vs "+column.column); if(values!=null && q.values!=null) values.addAll(q.values); if(q.from_value!=null) this.from_value = q.from_value; if(q.to_value!=null) this.to_value = q.to_value; return this; } public SetSubquery except(SetSubquery query) { this.except = query; return this; } public SetSubquery exists(SetSubquery query) { this.exists = query; return this; } public Condition condition() { if((values==null || values.size()==0) && from_value==null && to_value==null){ if(except==null) return null; else return new NotCondition(except.condition()); } DimensionTable dim_table = join.getDimensionTable(); SelectQuery dim_query = new SelectQuery(). addFromTable(dim_table.getDbTable()). addColumns(dim_table.getDbKey()); if(from_value!=null){ dim_query = dim_query.addCondition(BinaryCondition.greaterThan(column.getDbColumn(), from_value, true)); } if(to_value!=null){ dim_query = dim_query.addCondition(BinaryCondition.lessThan(column.getDbColumn(), to_value, true)); } if(values!=null && values.size()>0){ if(values.size()==1){ String value = values.iterator().next(); if(LevelMember.NULL_MEMBER.equals(value)) dim_query = dim_query.addCondition(UnaryCondition.isNull(column.getDbColumn())); else dim_query = dim_query.addCondition(BinaryCondition.equalTo(column.getDbColumn(), value)); }else{ if(values.contains(LevelMember.NULL_MEMBER)){ Set<String> values_without_null = new HashSet<String>(values); values_without_null.remove(LevelMember.NULL_MEMBER); dim_query = dim_query.addCondition(ComboCondition.or( UnaryCondition.isNull(column.getDbColumn()), new InCondition(column.getDbColumn(), values_without_null))); }else{ dim_query = dim_query.addCondition(new InCondition(column.getDbColumn(), values)); } } } Condition myCondition = new InCondition(join.getForeign_key(), new Subquery(dim_query) ); if(except!=null) myCondition = ComboCondition.and(myCondition, new NotCondition(except.condition()) ); if(exists!=null) myCondition = ComboCondition.and(myCondition, exists.condition()); return myCondition; } public Condition havingCondition(){ if(having_expression==null){ if(except == null || except.having_expression==null) return null; else return new NotCondition(except.havingCondition()); } Condition myCondition = new CustomCondition(having_expression); if(except!=null && except.having_expression!=null) myCondition = ComboCondition.and(myCondition, new NotCondition(except.havingCondition()) ); if(exists!=null && exists.having_expression!=null) myCondition = ComboCondition.and(myCondition, exists.havingCondition() ); return myCondition; } public void setHaving_expression(String having_expression) { this.having_expression = having_expression; } public boolean combined_with(SetSubquery query) { return column.equals(query.column); } }