1 10 package mondrian.olap.fun; 11 12 import mondrian.olap.*; 13 import mondrian.olap.type.Type; 14 import mondrian.resource.MondrianResource; 15 import mondrian.calc.Calc; 16 import mondrian.calc.ExpCompiler; 17 import mondrian.calc.impl.GenericCalc; 18 import mondrian.mdx.ResolvedFunCall; 19 import mondrian.olap.fun.FunUtil; 20 21 41 public class CastFunDef extends FunDefBase { 42 static final ResolverBase Resolver = new ResolverImpl(); 43 44 private CastFunDef(FunDef dummyFunDef) { 45 super(dummyFunDef); 46 } 47 48 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 49 final Type targetType = call.getType(); 50 final Exp arg = call.getArg(0); 51 final Calc calc = compiler.compileScalar(arg, false); 52 return new GenericCalc(arg) { 53 public Calc[] getCalcs() { 54 return new Calc[] {calc}; 55 } 56 57 public Object evaluate(Evaluator evaluator) { 58 return calc.evaluate(evaluator); 59 } 60 61 public String evaluateString(Evaluator evaluator) { 62 final Object o = evaluate(evaluator); 63 if (o == null) { 64 return null; 65 } 66 return String.valueOf(o); 67 } 68 69 public int evaluateInteger(Evaluator evaluator) { 70 final Object o = evaluate(evaluator); 71 if (o == null) { 72 return FunUtil.IntegerNull; 73 } 74 if (o instanceof String ) { 75 return Integer.parseInt((String ) o); 76 } 77 if (o instanceof Number ) { 78 return ((Number ) o).intValue(); 79 } 80 throw cannotConvert(o); 81 } 82 83 public double evaluateDouble(Evaluator evaluator) { 84 final Object o = evaluate(evaluator); 85 if (o == null) { 86 return FunUtil.DoubleNull; 87 } 88 if (o instanceof String ) { 89 return Double.valueOf((String ) o); 90 } 91 if (o instanceof Number ) { 92 return ((Number ) o).doubleValue(); 93 } 94 throw cannotConvert(o); 95 } 96 97 public boolean evaluateBoolean(Evaluator evaluator) { 98 final Object o = evaluate(evaluator); 99 if (o == null) { 100 return FunUtil.BooleanNull; 101 } 102 if (o instanceof Boolean ) { 103 return (Boolean ) o; 104 } 105 if (o instanceof String ) { 106 return Boolean.valueOf((String ) o); 107 } 108 throw cannotConvert(o); 109 } 110 111 private RuntimeException cannotConvert(Object o) { 112 return Util.newInternal( 113 "cannot convert value '" + o + 114 "' to targetType '" + targetType + 115 "'"); 116 } 117 }; 118 } 119 120 123 private static class ResolverImpl extends ResolverBase { 124 125 public ResolverImpl() { 126 super("Cast", "Cast(<Expression> AS <Type>)", 127 "Converts values to another type.", Syntax.Cast); 128 } 129 130 public FunDef resolve( 131 Exp[] args, Validator validator, int[] conversionCount) { 132 if (args.length != 2) { 133 return null; 134 } 135 if (!(args[1] instanceof Literal)) { 136 return null; 137 } 138 Literal literal = (Literal) args[1]; 139 String typeName = (String ) literal.getValue(); 140 int returnCategory; 141 if (typeName.equalsIgnoreCase("String")) { 142 returnCategory = Category.String; 143 } else if (typeName.equalsIgnoreCase("Numeric")) { 144 returnCategory = Category.Numeric; 145 } else if (typeName.equalsIgnoreCase("Boolean")) { 146 returnCategory = Category.Logical; 147 } else if (typeName.equalsIgnoreCase("Integer")) { 148 returnCategory = Category.Integer; 149 } else { 150 throw MondrianResource.instance().CastInvalidType.ex(typeName); 151 } 152 final FunDef dummyFunDef = 153 createDummyFunDef(this, returnCategory, args); 154 return new CastFunDef(dummyFunDef); 155 } 156 } 157 } 158 159 | Popular Tags |