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) 2004-2005 TONBELLER AG
008// Copyright (C) 2006-2010 Pentaho and others
009// All Rights Reserved.
010*/
011package mondrian.rolap.agg;
012
013import mondrian.olap.Util;
014import mondrian.rolap.*;
015import mondrian.rolap.sql.SqlQuery;
016
017import java.util.*;
018
019/**
020 * A <code>AbstractColumnPredicate</code> is an abstract implementation for
021 * {@link mondrian.rolap.StarColumnPredicate}.
022 */
023public abstract class AbstractColumnPredicate implements StarColumnPredicate {
024    protected final RolapStar.Column constrainedColumn;
025    private BitKey constrainedColumnBitKey;
026
027    /**
028     * Creates an AbstractColumnPredicate.
029     *
030     * @param constrainedColumn Constrained column
031     */
032    protected AbstractColumnPredicate(RolapStar.Column constrainedColumn) {
033        this.constrainedColumn = constrainedColumn;
034    }
035
036    public String toString() {
037        final StringBuilder buf = new StringBuilder();
038        buf.append(constrainedColumn.getExpression().getGenericExpression());
039        describe(buf);
040        return buf.toString();
041    }
042
043    public RolapStar.Column getConstrainedColumn() {
044        return constrainedColumn;
045    }
046
047    public List<RolapStar.Column> getConstrainedColumnList() {
048        return Collections.singletonList(constrainedColumn);
049    }
050
051    public BitKey getConstrainedColumnBitKey() {
052        // Check whether constrainedColumn are null.
053        // Example: FastBatchingCellReaderTest.testAggregateDistinctCount5().
054        if (constrainedColumnBitKey == null
055            && constrainedColumn != null
056            && constrainedColumn.getTable() != null)
057        {
058            constrainedColumnBitKey =
059                BitKey.Factory.makeBitKey(
060                    constrainedColumn.getStar().getColumnCount());
061            constrainedColumnBitKey.set(constrainedColumn.getBitPosition());
062        }
063        return constrainedColumnBitKey;
064    }
065
066    public boolean evaluate(List<Object> valueList) {
067        assert valueList.size() == 1;
068        return evaluate(valueList.get(0));
069    }
070
071    public boolean equalConstraint(StarPredicate that) {
072        return false;
073    }
074
075    public StarPredicate or(StarPredicate predicate) {
076        if (predicate instanceof StarColumnPredicate) {
077            StarColumnPredicate starColumnPredicate =
078                (StarColumnPredicate) predicate;
079            if (starColumnPredicate.getConstrainedColumn()
080                == getConstrainedColumn())
081            {
082                return orColumn(starColumnPredicate);
083            }
084        }
085        final List<StarPredicate> list = new ArrayList<StarPredicate>(2);
086        list.add(this);
087        list.add(predicate);
088        return new OrPredicate(list);
089    }
090
091    public StarColumnPredicate orColumn(StarColumnPredicate predicate) {
092        assert predicate.getConstrainedColumn() == getConstrainedColumn();
093        if (predicate instanceof ListColumnPredicate) {
094            ListColumnPredicate that = (ListColumnPredicate) predicate;
095            final List<StarColumnPredicate> list =
096                new ArrayList<StarColumnPredicate>();
097            list.add(this);
098            list.addAll(that.getPredicates());
099            return new ListColumnPredicate(
100                getConstrainedColumn(),
101                list);
102        } else {
103            final List<StarColumnPredicate> list =
104                new ArrayList<StarColumnPredicate>(2);
105            list.add(this);
106            list.add(predicate);
107            return new ListColumnPredicate(
108                getConstrainedColumn(),
109                list);
110        }
111    }
112
113    public StarPredicate and(StarPredicate predicate) {
114        final List<StarPredicate> list = new ArrayList<StarPredicate>(2);
115        list.add(this);
116        list.add(predicate);
117        return new AndPredicate(list);
118    }
119
120    public void toSql(SqlQuery sqlQuery, StringBuilder buf) {
121        throw Util.needToImplement(this);
122    }
123
124    protected static List<StarColumnPredicate> cloneListWithColumn(
125        RolapStar.Column column,
126        List<StarColumnPredicate> list)
127    {
128        List<StarColumnPredicate> newList =
129            new ArrayList<StarColumnPredicate>(list.size());
130        for (StarColumnPredicate predicate : list) {
131            newList.add(predicate.cloneWithColumn(column));
132        }
133        return newList;
134    }
135
136    /**
137     * Factory for {@link mondrian.rolap.StarPredicate}s and
138     * {@link mondrian.rolap.StarColumnPredicate}s.
139     */
140    public static class Factory {
141        /**
142         * Returns a predicate which tests whether the column's
143         * value is equal to a given constant.
144         *
145         * @param column Constrained column
146         * @param value Value
147         * @return Predicate which tests whether the column's value is equal
148         *   to a column constraint's value
149         */
150        public static StarColumnPredicate equal(
151            RolapStar.Column column,
152            Object value)
153        {
154            return new ValueColumnPredicate(column, value);
155        }
156
157        /**
158         * Returns predicate which is the OR of a list of predicates.
159         *
160         * @param column Column being constrained
161         * @param list List of predicates
162         * @return Predicate which is an OR of the list of predicates
163         */
164        public static StarColumnPredicate or(
165            RolapStar.Column column,
166            List<StarColumnPredicate> list)
167        {
168            return new ListColumnPredicate(column, list);
169        }
170
171        /**
172         * Returns a predicate which always evaluates to TRUE or FALSE.
173         * @param b Truth value
174         * @return Predicate which always evaluates to truth value
175         */
176        public static LiteralStarPredicate bool(boolean b) {
177            return b ? LiteralStarPredicate.TRUE : LiteralStarPredicate.FALSE;
178        }
179
180        /**
181         * Returns a predicate which tests whether the column's
182         * value is equal to column predicate's value.
183         *
184         * @param predicate Column predicate
185         * @return Predicate which tests whether the column's value is equal
186         *   to a column predicate's value
187         */
188        public static StarColumnPredicate equal(
189            ValueColumnPredicate predicate)
190        {
191            return equal(
192                predicate.getConstrainedColumn(),
193                predicate.getValue());
194        }
195    }
196}
197
198// End AbstractColumnPredicate.java