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