001 /* 002 // $Id: //open/mondrian/src/main/mondrian/rolap/agg/ValueColumnPredicate.java#6 $ 003 // This software is subject to the terms of the Common Public License 004 // Agreement, available at the following URL: 005 // http://www.opensource.org/licenses/cpl.html. 006 // Copyright (C) 2006-2008 Julian Hyde 007 // All Rights Reserved. 008 // You must accept the terms of that agreement to use this software. 009 */ 010 package mondrian.rolap.agg; 011 012 import mondrian.rolap.BitKey; 013 import mondrian.rolap.RolapStar; 014 import mondrian.rolap.StarPredicate; 015 import mondrian.rolap.StarColumnPredicate; 016 import mondrian.rolap.RolapUtil; 017 import mondrian.rolap.sql.SqlQuery; 018 019 import java.util.Collection; 020 021 /** 022 * A constraint which requires a column to have a particular value. 023 * 024 * @author jhyde 025 * @version $Id: //open/mondrian/src/main/mondrian/rolap/agg/ValueColumnPredicate.java#6 $ 026 * @since Nov 2, 2006 027 */ 028 public class ValueColumnPredicate 029 extends AbstractColumnPredicate 030 implements Comparable 031 { 032 private final Object value; 033 034 /** 035 * Creates a column constraint. 036 * 037 * @param value Value to constraint the column to. (We require that it is 038 * {@link Comparable} because we will sort the values in order to 039 * generate deterministic SQL.) 040 */ 041 public ValueColumnPredicate( 042 RolapStar.Column constrainedColumn, 043 Object value) 044 { 045 super(constrainedColumn); 046 // assert constrainedColumn != null; 047 assert value != null; 048 assert ! (value instanceof StarColumnPredicate); 049 this.value = value; 050 } 051 052 /** 053 * Returns the value which the column is compared to. 054 */ 055 public Object getValue() { 056 return value; 057 } 058 059 public String toString() { 060 return String.valueOf(value); 061 } 062 063 public boolean equalConstraint(StarPredicate that) { 064 return that instanceof ValueColumnPredicate && 065 getConstrainedColumnBitKey().equals(that.getConstrainedColumnBitKey()) && 066 this.value.equals(((ValueColumnPredicate) that).value); 067 } 068 069 public int compareTo(Object o) { 070 ValueColumnPredicate that = (ValueColumnPredicate) o; 071 int columnBitKeyComp = 072 getConstrainedColumnBitKey().compareTo(that.getConstrainedColumnBitKey()); 073 074 // First compare the column bitkeys. 075 if (columnBitKeyComp != 0) { 076 return columnBitKeyComp; 077 } 078 079 if (this.value instanceof Comparable && 080 that.value instanceof Comparable && 081 this.value.getClass() == that.value.getClass()) { 082 return ((Comparable) this.value).compareTo(that.value); 083 } else { 084 String thisComp = String.valueOf(this.value); 085 String thatComp = String.valueOf(that.value); 086 return thisComp.compareTo(thatComp); 087 } 088 } 089 090 public boolean equals(Object other) { 091 if (!(other instanceof ValueColumnPredicate)) { 092 return false; 093 } 094 final ValueColumnPredicate that = (ValueColumnPredicate) other; 095 int columnBitKeyComp = 096 getConstrainedColumnBitKey().compareTo(that.getConstrainedColumnBitKey()); 097 098 // First compare the column bitkeys. 099 if (columnBitKeyComp != 0) { 100 return false; 101 } 102 103 if (value != null) { 104 return value.equals(that.getValue()); 105 } else { 106 return null == that.getValue(); 107 } 108 } 109 110 public int hashCode() { 111 int hashCode = getConstrainedColumnBitKey().hashCode(); 112 113 if (value != null) { 114 hashCode = hashCode ^ value.hashCode(); 115 } 116 117 return hashCode; 118 } 119 120 public void values(Collection<Object> collection) { 121 collection.add(value); 122 } 123 124 public boolean evaluate(Object value) { 125 return this.value.equals(value); 126 } 127 128 public void describe(StringBuilder buf) { 129 buf.append(value); 130 } 131 132 public Overlap intersect(StarColumnPredicate predicate) { 133 throw new UnsupportedOperationException(); 134 } 135 136 public boolean mightIntersect(StarPredicate other) { 137 return ((StarColumnPredicate) other).evaluate(value); 138 } 139 140 public StarColumnPredicate minus(StarPredicate predicate) { 141 assert predicate != null; 142 if (((StarColumnPredicate) predicate).evaluate(value)) { 143 return LiteralStarPredicate.FALSE; 144 } else { 145 return this; 146 } 147 } 148 149 public StarColumnPredicate cloneWithColumn(RolapStar.Column column) { 150 return new ValueColumnPredicate(column, value); 151 } 152 153 public void toSql(SqlQuery sqlQuery, StringBuilder buf) { 154 final RolapStar.Column column = getConstrainedColumn(); 155 String expr = column.generateExprString(sqlQuery); 156 buf.append(expr); 157 Object key = getValue(); 158 if (key == RolapUtil.sqlNullValue) { 159 buf.append(" is null"); 160 } else { 161 buf.append(" = "); 162 sqlQuery.getDialect().quote(buf, key, column.getDatatype()); 163 } 164 } 165 166 public BitKey checkInList(BitKey inListLHSBitKey) { 167 // ValueColumn predicate by itself is not using IN list; when it is 168 // one of the children to an OR predicate, then using IN list 169 // is helpful. The later is checked by passing in a bitmap that 170 // represent the LHS or the IN list, i.e. the column that is 171 // constrained by the OR. 172 BitKey inListRHSBitKey = inListLHSBitKey.copy(); 173 174 if (!getConstrainedColumnBitKey().equals(inListLHSBitKey) || 175 value == RolapUtil.sqlNullValue) { 176 inListRHSBitKey.clear(); 177 } 178 179 return inListRHSBitKey; 180 } 181 182 public void toInListSql(SqlQuery sqlQuery, StringBuilder buf) { 183 sqlQuery.getDialect().quote( 184 buf, value, getConstrainedColumn().getDatatype()); 185 } 186 } 187 188 // End ValueColumnPredicate.java