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) 2005-2005 Julian Hyde
008// Copyright (C) 2005-2011 Pentaho
009// All Rights Reserved.
010*/
011package mondrian.olap.type;
012
013import mondrian.olap.*;
014
015/**
016 * Type of an MDX expression.
017 *
018 * @author jhyde
019 * @since Feb 17, 2005
020 */
021public interface Type {
022    /**
023     * Returns whether this type contains a given dimension.<p/>
024     *
025     * For example:
026     * <ul>
027     * <li><code>DimensionType([Gender])</code> uses only the
028     *     <code>[Gender]</code> dimension.</li>
029     * <li><code>TupleType(MemberType([Gender]), MemberType([Store]))</code>
030     *     uses <code>[Gender]</code>  and <code>[Store]</code>
031     *     dimensions.</li>
032     * </ul><p/>
033     *
034     * The <code>definitely</code> parameter comes into play when the
035     * dimensional information is incomplete. For example, when applied to
036     * <code>TupleType(MemberType(null), MemberType([Store]))</code>,
037     * <code>usesDimension([Gender], false)</code> returns true because it
038     * is possible that the expression returns a member of the
039     * <code>[Gender]</code> dimension; but
040     * <code>usesDimension([Gender], true)</code> returns true because it
041     * is possible that the expression returns a member of the
042     * <code>[Gender]</code> dimension.
043     *
044     * @param dimension Dimension
045     * @param definitely If true, returns true only if this type definitely
046     *    uses the dimension
047     *
048     * @return whether this Type uses the given Dimension
049     */
050    boolean usesDimension(Dimension dimension, boolean definitely);
051
052    /**
053     * Returns whether this type contains a given hierarchy.<p/>
054     *
055     * For example:
056     * <ul>
057     * <li><code>HierarchyType([Customer].[Gender])</code> uses only the
058     *     <code>[Customer].[Gender]</code> hierarchy.</li>
059     * <li><code>TupleType(MemberType([Customer].[Gender]),
060     *           MemberType([Store].[Store]))</code>
061     *     uses <code>[Gender]</code>  and <code>[Store]</code>
062     *     dimensions.</li>
063     * </ul><p/>
064     *
065     * The <code>definitely</code> parameter comes into play when the
066     * dimensional information is incomplete. For example, when applied to
067     * <code>TupleType(MemberType([Customer]), MemberType([Store]))</code>,
068     * <code>usesDimension([Customer].[Gender], false)</code> returns true
069     * because the expression returns a member of one hierarchy of the
070     * <code>[Customer]</code> dimension and that might be a member of the
071     * <code>[Customer].[Gender]</code> hierarchy; but
072     * <code>usesDimension([Customer].[Gender], true)</code> returns false
073     * because might return a member of a different hierarchy, such as
074     * <code>[Customer].[State]</code>.
075     *
076     * @param hierarchy Hierarchy
077     * @param definitely If true, returns true only if this type definitely
078     *    uses the hierarchy
079     *
080     * @return whether this Type uses the given Hierarchy
081     */
082    boolean usesHierarchy(Hierarchy hierarchy, boolean definitely);
083
084    /**
085     * Returns the Dimension of this Type, or null if not known.
086     * If not applicable, throws.
087     *
088     * @return the Dimension of this Type, or null if not known.
089     */
090    Dimension getDimension();
091
092    /**
093     * Returns the Hierarchy of this Type, or null if not known.
094     * If not applicable, throws.
095     *
096     * @return the Hierarchy of this type, or null if not known
097     */
098    Hierarchy getHierarchy();
099
100    /**
101     * Returns the Level of this Type, or null if not known.
102     * If not applicable, throws.
103     *
104     * @return the Level of this Type
105     */
106    Level getLevel();
107
108    /**
109     * Returns a Type which is more general than this and the given Type.
110     * The type returned is broad enough to hold any value of either type,
111     * but no broader. If there is no such type, returns null.
112     *
113     * <p>Some examples:<ul>
114     * <li>The common type for StringType and NumericType is ScalarType.
115     * <li>The common type for NumericType and DecimalType(4, 2) is
116     *     NumericType.
117     * <li>DimensionType and NumericType have no common type.
118     * </ul></p>
119     *
120     * <p>If <code>conversionCount</code> is not null, implicit conversions
121     * such as HierarchyType to DimensionType are considered; the parameter
122     * is incremented by the number of conversions performed.
123     *
124     * <p>Some examples:<ul>
125     * <li>The common type for HierarchyType(hierarchy=Time.Weekly)
126     *     and LevelType(dimension=Time), if conversions are allowed, is
127     *     HierarchyType(dimension=Time).
128     * </ul>
129     *
130     * <p>One use of common types is to determine the types of the arguments
131     * to the <code>Iif</code> function. For example, the call
132     *
133     * <blockquote><code>Iif(1 &gt; 2, [Measures].[Unit Sales],
134     * 5)</code></blockquote>
135     *
136     * has type ScalarType, because DecimalType(-1, 0) is a subtype of
137     * ScalarType, and MeasureType can be converted implicitly to ScalarType.
138     *
139     * @param type Type
140     *
141     * @param conversionCount Number of conversions; output parameter that is
142     * incremented each time a conversion is performed; if null, conversions
143     * are not considered
144     *
145     * @return More general type
146     */
147    Type computeCommonType(Type type, int[] conversionCount);
148
149    /**
150     * Returns whether a value is valid for a type.
151     *
152     * @param value Value
153     * @return Whether value is valid for this type
154     */
155    boolean isInstance(Object value);
156
157    /**
158     * Returns the number of fields in a tuple type, or a set of tuples.
159     * For most other types, in particular member type, returns 1.
160     *
161     * @return Arity of type
162     */
163    int getArity();
164}
165
166// End Type.java