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-2009 Pentaho
009// All Rights Reserved.
010*/
011package mondrian.spi;
012
013import mondrian.olap.Evaluator;
014import mondrian.olap.Syntax;
015import mondrian.olap.type.Type;
016
017import java.util.List;
018
019/**
020 * Definition of a user-defined function.
021 *
022 * <p>The class must have a public, zero-arguments constructor, be on
023 * Mondrian's runtime class-path, and be referenced from the schema file:
024 *
025 * <blockquote><code>
026 * &lt;Schema&gt;<br/>
027 * &nbsp;&nbsp;&nbsp;&nbsp;....<br/>
028 * &nbsp;&nbsp;&nbsp;&nbsp;&lt;UserDefinedFunction name="MyFun"
029 * class="com.acme.MyFun"&gt;<br/>
030 * &lt;/Schema&gt;</code></blockquote>
031 *
032 * @author jhyde
033  */
034public interface UserDefinedFunction {
035    /**
036     * Returns the name with which the user-defined function will be used
037     * from within MDX expressions.
038     */
039    public String getName();
040
041    /**
042     * Returns a description of the user-defined function.
043     */
044    public String getDescription();
045
046    /**
047     * Returns the syntactic type of the user-defined function.
048     * Usually {@link Syntax#Function}.
049     */
050    public Syntax getSyntax();
051
052    /**
053     * Returns an array of the types of the parameters of this function.
054     */
055    public Type[] getParameterTypes();
056
057    /**
058     * Returns the return-type of this function.
059     *
060     * @param parameterTypes Parameter types
061     * @return Return type
062     */
063    public Type getReturnType(Type[] parameterTypes);
064
065    /**
066     * Applies this function to a set of arguments, and returns a result.
067     *
068     * @param evaluator Evaluator containts the runtime context, in particular
069     *   the current member of each dimension.
070     * @param arguments Expressions which yield the arguments of this function.
071     *   Most user-defined functions will evaluate all arguments before using
072     *   them. Functions such as <code>IIf</code> do not evaluate all
073     *   arguments; this technique is called <dfn>lazy evaluation</dfn>.
074     * @return The result value.
075     */
076    public Object execute(Evaluator evaluator, Argument[] arguments);
077
078    /**
079     * Returns a list of reserved words used by this function.
080     * May return an empty array or null if this function does not require
081     * any reserved words.
082     */
083    public String[] getReservedWords();
084
085    interface Argument {
086        /**
087         * Returns the type of the argument.
088         *
089         * @return Argument type
090         */
091        Type getType();
092
093        /**
094         * Evaluates the argument as a scalar expression.
095         *
096         * <p>The effect is the same as
097         * {@link #evaluate(mondrian.olap.Evaluator)} except if the argument
098         * evaluates to a member or tuple. This method will set the context
099         * to the member or tuple and evaluate the current measure, whereas
100         * {@code evaluate} would return the member or tuple.
101         *
102         * <p>The effect is similar to creating a calculated member in an MDX
103         * query:</p>
104         *
105         * <blockquote>WITH MEMBER [Measures].[Previous Period] AS<br/>
106         * &nbsp;&nbsp;([Measures].[Unit Sales], [Time].[Time].PrevMember)<br/>
107         * SELECT {[Measures].[Unit Sales],<br/>
108         * &nbsp;&nbsp;&nbsp;&nbsp;[Measures].[Previous Period]} on 0,<br/>
109         * &nbsp;&nbsp;[Time].[Time].Children on 1<br/>
110         * FROM [Sales]</blockquote>
111         *
112         * <p>Note how {@code [Measures].[Previous Period]} is defined as a
113         * tuple, but evaluates to a number.</p>
114         *
115         * @param evaluator Evaluation context
116         * @return Scalar expression at the given member or tuple
117         */
118        Object evaluateScalar(Evaluator evaluator);
119
120        /**
121         * Evaluates the argument.
122         *
123         * <p>If the argument is a set of members or tuples, this method may
124         * return either a {@link List} or an {@link Iterable}. It is not safe
125         * to blindly cast to {@code List}. For guaranteed type, call
126         * {@link #evaluateList(mondrian.olap.Evaluator)} or
127         * {@link #evaluateIterable(mondrian.olap.Evaluator)}.
128         *
129         * @param evaluator Evaluation context
130         * @return Result of evaluating the argument
131         */
132        Object evaluate(Evaluator evaluator);
133
134        /**
135         * Evaluates the argument to a list of members or tuples.
136         *
137         * @param eval Evaluation context
138         * @return List of members or tuples.
139         */
140        List evaluateList(Evaluator eval);
141
142        /**
143         * Evaluates the argument to an iterable over members or tuples.
144         *
145         * @param eval Evaluation context
146         * @return Iterable over members or tuples.
147         */
148        Iterable evaluateIterable(Evaluator eval);
149    }
150}
151
152// End UserDefinedFunction.java