Skip to content

Commit

Permalink
MONDRIAN: Implement a lot of Visual Basic for Applications (VBA) func…
Browse files Browse the repository at this point in the history
…tions;

    Add a mechanism to define an MDX function based on a Java method, invoking the method by reflection.
    More support for a DateTime data type.

[git-p4: depot-paths = "//open/mondrian/": change = 10394]
  • Loading branch information
julianhyde committed Jan 6, 2008
1 parent ef68124 commit 091933e
Show file tree
Hide file tree
Showing 26 changed files with 8,371 additions and 301 deletions.
520 changes: 490 additions & 30 deletions doc/mdx.html

Large diffs are not rendered by default.

3,820 changes: 3,820 additions & 0 deletions doc/vba_functions.html

Large diffs are not rendered by default.

37 changes: 37 additions & 0 deletions src/main/mondrian/calc/DateTimeCalc.java
@@ -0,0 +1,37 @@
/*
// $Id$
// This software is subject to the terms of the Common Public License
// Agreement, available at the following URL:
// http://www.opensource.org/licenses/cpl.html.
// Copyright (C) 2006-2007 Julian Hyde
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
*/
package mondrian.calc;

import mondrian.olap.Evaluator;

import java.util.Date;

/**
* Compiled expression whose result is a {@link Date}, representing an MDX
* DateTime value.
*
* <p>When implementing this interface, it is convenient to extend
* {@link mondrian.calc.impl.AbstractDateTimeCalc}, but it is not required.
*
* @author jhyde
* @version $Id$
* @since Sep 26, 2005
*/
public interface DateTimeCalc extends Calc {
/**
* Evaluates this expression to yield a {@link Date} value.
*
* @param evaluator Evaluation context
* @return evaluation result
*/
Date evaluateDateTime(Evaluator evaluator);
}

// End DateTimeCalc.java
6 changes: 6 additions & 0 deletions src/main/mondrian/calc/ExpCompiler.java
Expand Up @@ -106,6 +106,12 @@ Calc compileAs(
*/
StringCalc compileString(Exp exp);

/**
* Compiles an expression which yields a {@link java.util.Date} result.
* The expression is implicitly converted into a scalar.
*/
DateTimeCalc compileDateTime(Exp exp);

/**
* Compiles an expression which yields an immutable {@link java.util.List}
* result.
Expand Down
11 changes: 9 additions & 2 deletions src/main/mondrian/calc/ResultStyle.java
Expand Up @@ -44,10 +44,17 @@ public enum ResultStyle {

/**
* Indicates that the expression results its result as an immutable
* value. This is typical for expressions which return string and
* value. This is typical for expressions which return string, datetime and
* numeric values.
*/
VALUE;
VALUE,

/**
* Indicates that the expression results its result as an immutable
* value which will never be null. This is typical for expressions which
* return string, datetime and numeric values.
*/
VALUE_NOT_NULL;

// ---------------------------------------------------------------
// There follow a set of convenience constants for commonly-used
Expand Down
47 changes: 47 additions & 0 deletions src/main/mondrian/calc/impl/AbstractDateTimeCalc.java
@@ -0,0 +1,47 @@
/*
// $Id$
// This software is subject to the terms of the Common Public License
// Agreement, available at the following URL:
// http://www.opensource.org/licenses/cpl.html.
// Copyright (C) 2008-2008 Julian Hyde
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
*/
package mondrian.calc.impl;

import mondrian.olap.Evaluator;
import mondrian.olap.Exp;
import mondrian.calc.*;

/**
* Abstract implementation of the {@link mondrian.calc.DateTimeCalc} interface.
*
* <p>The derived class must
* implement the {@link #evaluateDateTime(mondrian.olap.Evaluator)} method,
* and the {@link #evaluate(mondrian.olap.Evaluator)} method will call it.
*
* @author jhyde
* @version $Id$
* @since Sep 26, 2005
*/
public abstract class AbstractDateTimeCalc
extends AbstractCalc
implements DateTimeCalc
{
private final Calc[] calcs;

protected AbstractDateTimeCalc(Exp exp, Calc[] calcs) {
super(exp);
this.calcs = calcs;
}

public Object evaluate(Evaluator evaluator) {
return evaluateDateTime(evaluator);
}

public Calc[] getCalcs() {
return calcs;
}
}

// End AbstractDateTimeCalc.java
39 changes: 28 additions & 11 deletions src/main/mondrian/calc/impl/AbstractExpCompiler.java
Expand Up @@ -192,9 +192,17 @@ public HierarchyCalc compileHierarchy(Exp exp) {

public IntegerCalc compileInteger(Exp exp) {
final Calc calc = compileScalar(exp, false);
if (calc instanceof IntegerCalc) {
final Type type = calc.getType();
if (type instanceof DecimalType
&& ((DecimalType) type).getScale() == 0) {
return (IntegerCalc) calc;
} else if (calc instanceof DoubleCalc) {
} else if (type instanceof NumericType) {
if (calc instanceof ConstantCalc) {
ConstantCalc constantCalc = (ConstantCalc) calc;
return new ConstantCalc(
new DecimalType(Integer.MAX_VALUE, 0),
constantCalc.evaluateInteger(null));
}
final DoubleCalc doubleCalc = (DoubleCalc) calc;
return new AbstractIntegerCalc(exp, new Calc[] {doubleCalc}) {
public int evaluateInteger(Evaluator evaluator) {
Expand All @@ -210,6 +218,10 @@ public StringCalc compileString(Exp exp) {
return (StringCalc) compile(exp);
}

public DateTimeCalc compileDateTime(Exp exp) {
return (DateTimeCalc) compile(exp);
}

public ListCalc compileList(Exp exp) {
return compileList(exp, false);
}
Expand All @@ -226,15 +238,14 @@ public IterCalc compileIter(Exp exp) {
return (IterCalc) compileAs(exp, null, ResultStyle.ITERABLE_ONLY);
}

/**
* compiles a boolean calc, support for converting
* integers and doubles.
*
* @param exp the expression to generate a calc for
*/
public BooleanCalc compileBoolean(Exp exp) {
final Calc calc = compileScalar(exp, false);
if (calc instanceof BooleanCalc) {
if (calc instanceof ConstantCalc
&& !(calc.evaluate(null) instanceof Boolean)) {
return ConstantCalc.constantBoolean(
((ConstantCalc) calc).evaluateBoolean(null));
}
return (BooleanCalc) calc;
} else if (calc instanceof DoubleCalc) {
final DoubleCalc doubleCalc = (DoubleCalc) calc;
Expand All @@ -256,14 +267,20 @@ public boolean evaluateBoolean(Evaluator evaluator) {
}

public DoubleCalc compileDouble(Exp exp) {
return (DoubleCalc) compileScalar(exp, false);
final DoubleCalc calc = (DoubleCalc) compileScalar(exp, false);
if (calc instanceof ConstantCalc
&& !(calc.evaluate(null) instanceof Double)) {
return ConstantCalc.constantDouble(
calc.evaluateDouble(null));
}
return calc;
}

public TupleCalc compileTuple(Exp exp) {
return (TupleCalc) compile(exp);
}

public Calc compileScalar(Exp exp, boolean convert) {
public Calc compileScalar(Exp exp, boolean specific) {
final Type type = exp.getType();
if (type instanceof MemberType) {
MemberType memberType = (MemberType) type;
Expand Down Expand Up @@ -299,7 +316,7 @@ public Calc compileScalar(Exp exp, boolean convert) {
new DummyExp(tupleType.getValueType()), tupleCalc);
return scalarCalc.optimize();
} else if (type instanceof ScalarType) {
if (convert) {
if (specific) {
if (type instanceof BooleanType) {
return compileBoolean(exp);
} else if (type instanceof NumericType) {
Expand Down
9 changes: 7 additions & 2 deletions src/main/mondrian/calc/impl/AbstractIntegerCalc.java
Expand Up @@ -11,8 +11,8 @@

import mondrian.olap.Evaluator;
import mondrian.olap.Exp;
import mondrian.olap.fun.FunUtil;
import mondrian.olap.type.NumericType;
import mondrian.calc.impl.AbstractCalc;
import mondrian.calc.IntegerCalc;
import mondrian.calc.Calc;

Expand All @@ -39,7 +39,12 @@ protected AbstractIntegerCalc(Exp exp, Calc[] calcs) {
}

public Object evaluate(Evaluator evaluator) {
return evaluateInteger(evaluator);
int i = evaluateInteger(evaluator);
if (i == FunUtil.IntegerNull) {
return null;
} else {
return i;
}
}

public Calc[] getCalcs() {
Expand Down
93 changes: 70 additions & 23 deletions src/main/mondrian/calc/impl/ConstantCalc.java
Expand Up @@ -35,26 +35,32 @@ public ConstantCalc(Type type, Object o) {
this.d = initializeDouble(o);
}

public ResultStyle getResultStyle() {
return o == null
? ResultStyle.VALUE
: ResultStyle.VALUE_NOT_NULL;
}

private double initializeDouble(Object o) {
double value;
if(o instanceof Number){
value = ((Number) o).doubleValue();
if (o instanceof Number) {
value = ((Number) o).doubleValue();
} else {
if(o == null){
if (o == null) {
value = FunUtil.DoubleNull;
} else {
value = 0;
}
}
return value;
}
private int initializeInteger(Object o) {

private int initializeInteger(Object o) {
int value;
if(o instanceof Number){
value = ((Number) o).intValue();
if (o instanceof Number) {
value = ((Number) o).intValue();
} else {
if(o == null){
if (o == null) {
value = FunUtil.IntegerNull;
} else {
value = 0;
Expand Down Expand Up @@ -91,60 +97,101 @@ public Calc[] getCalcs() {
}

/**
* Creates an expression which evaluates to an integer.
* Creates an expression which evaluates to a given integer.
*
* @param i Integer value
* @return Constant integer expression
*/
public static ConstantCalc constantInteger(int i) {
return new ConstantCalc(new NumericType(), i);
return new ConstantCalc(new DecimalType(Integer.MAX_VALUE, 0), i);
}

/**
* Creates an expression which evaluates to a string.
* Creates an expression which evaluates to a given double.
*
* @param v Double value
* @return Constant double expression
*/
public static DoubleCalc constantDouble(double v) {
return new ConstantCalc(new NumericType(), v);
}

/**
* Creates an expression which evaluates to a given string.
*
* @param s String value
* @return Constant string expression
*/
public static StringCalc constantString(String s) {
return new ConstantCalc(new StringType(), s);
}

/**
* Creates an expression which evaluates to a given boolean.
*
* @param b Boolean value
* @return Constant boolean expression
*/
public static BooleanCalc constantBoolean(boolean b) {
return new ConstantCalc(new BooleanType(), b);
}

/**
* Creates an expression which evaluates to null.
*
* @param type Type
* @return Constant null expression
*/
public static ConstantCalc constantNull(Type type) {
return new ConstantCalc(type, null);
}

/**
* Creates an expression which evaluates to a member.
* Creates an expression which evaluates to a given member.
*
* @param member Member
* @return Constant member expression
*/
public static Calc constantMember(Member member) {
return new ConstantCalc(
MemberType.forMember(member),
member);
MemberType.forMember(member),
member);
}

/**
* Creates an expression which evaluates to a level.
* Creates an expression which evaluates to a given level.
*
* @param level Level
* @return Constant level expression
*/
public static Calc constantLevel(Level level) {
return new ConstantCalc(
LevelType.forLevel(level),
level);
LevelType.forLevel(level),
level);
}

/**
* Creates an expression which evaluates to a hierarchy.
* Creates an expression which evaluates to a given hierarchy.
*
* @param hierarchy Hierarchy
* @return Constant hierarchy expression
*/
public static Calc constantHierarchy(Hierarchy hierarchy) {
return new ConstantCalc(
HierarchyType.forHierarchy(hierarchy),
hierarchy);
HierarchyType.forHierarchy(hierarchy),
hierarchy);
}

/**
* Creates an expression which evaluates to a dimension.
* Creates an expression which evaluates to a given dimension.
*
* @param dimension Dimension
* @return Constant dimension expression
*/
public static Calc constantDimension(Dimension dimension) {
return new ConstantCalc(
DimensionType.forDimension(dimension),
dimension);
DimensionType.forDimension(dimension),
dimension);
}
}

Expand Down

0 comments on commit 091933e

Please sign in to comment.