1 13 package mondrian.olap.fun; 14 15 import mondrian.calc.*; 16 import mondrian.calc.impl.*; 17 import mondrian.mdx.DimensionExpr; 18 import mondrian.mdx.ResolvedFunCall; 19 import mondrian.olap.*; 20 import mondrian.olap.fun.extra.NthQuartileFunDef; 21 import mondrian.olap.fun.extra.CalculatedChildFunDef; 22 import mondrian.olap.type.DimensionType; 23 import mondrian.olap.type.LevelType; 24 import mondrian.olap.type.Type; 25 import org.eigenbase.xom.XOMUtil; 26 27 import java.io.PrintWriter ; 28 import java.util.*; 29 30 41 public class BuiltinFunTable extends FunTableImpl { 42 43 44 private static BuiltinFunTable instance; 45 46 50 protected BuiltinFunTable() { 51 super(); 52 } 53 54 protected void defineFunctions() { 55 defineReserved("NULL"); 56 57 60 if (false) define(new FunDefBase( 62 "SetToArray", 63 "SetToArray(<Set>[, <Set>]...[, <Numeric Expression>])", 64 "Converts one or more sets to an array for use in a user-defined function.", 65 "fa*") { 66 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 67 throw new UnsupportedOperationException (); 68 } 69 }); 70 71 define(HierarchyDimensionFunDef.instance); 74 75 define(new FunDefBase( 76 "Dimension", 77 "<Dimension>.Dimension", 78 "Returns the dimension that contains a specified hierarchy.", 79 "pdd") { 80 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 81 Dimension dimension = 82 ((DimensionExpr) call.getArg(0)).getDimension(); 83 return new ConstantCalc( 84 DimensionType.forDimension(dimension), 85 dimension); 86 } 87 88 }); 89 90 define(new FunDefBase( 91 "Dimension", 92 "<Level>.Dimension", 93 "Returns the dimension that contains a specified level.", 94 "pdl") { 95 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 96 final LevelCalc levelCalc = 97 compiler.compileLevel(call.getArg(0)); 98 return new AbstractDimensionCalc(call, new Calc[] {levelCalc}) { 99 public Dimension evaluateDimension(Evaluator evaluator) { 100 Level level = levelCalc.evaluateLevel(evaluator); 101 return level.getDimension(); 102 } 103 }; 104 } 105 }); 106 107 define(new FunDefBase( 108 "Dimension", 109 "<Member>.Dimension", 110 "Returns the dimension that contains a specified member.", 111 "pdm") { 112 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 113 final MemberCalc memberCalc = 114 compiler.compileMember(call.getArg(0)); 115 return new AbstractDimensionCalc(call, new Calc[] {memberCalc}) { 116 public Dimension evaluateDimension(Evaluator evaluator) { 117 Member member = memberCalc.evaluateMember(evaluator); 118 return member.getDimension(); 119 } 120 }; 121 } 122 }); 123 124 define(new FunDefBase( 125 "Dimensions", 126 "Dimensions(<Numeric Expression>)", 127 "Returns the dimension whose zero-based position within the cube is specified by a numeric expression.", 128 "fdn") { 129 public Type getResultType(Validator validator, Exp[] args) { 130 return DimensionType.Unknown; 131 } 132 133 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 134 final IntegerCalc integerCalc = 135 compiler.compileInteger(call.getArg(0)); 136 return new AbstractDimensionCalc(call, new Calc[] {integerCalc}) { 137 public Dimension evaluateDimension(Evaluator evaluator) { 138 int n = integerCalc.evaluateInteger(evaluator); 139 return nthDimension(evaluator, n); 140 } 141 }; 142 } 143 144 Dimension nthDimension(Evaluator evaluator, int n) { 145 Cube cube = evaluator.getCube(); 146 Dimension[] dimensions = cube.getDimensions(); 147 if (n >= dimensions.length || n < 0) { 148 throw newEvalException( 149 this, "Index '" + n + "' out of bounds"); 150 } 151 return dimensions[n]; 152 } 153 }); 154 define(new FunDefBase( 155 "Dimensions", 156 "Dimensions(<String Expression>)", 157 "Returns the dimension whose name is specified by a string.", 158 "fdS") { 159 public Type getResultType(Validator validator, Exp[] args) { 160 return DimensionType.Unknown; 161 } 162 163 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 164 final StringCalc stringCalc = 165 compiler.compileString(call.getArg(0)); 166 return new AbstractDimensionCalc(call, new Calc[] {stringCalc}) { 167 public Dimension evaluateDimension(Evaluator evaluator) { 168 String dimensionName = 169 stringCalc.evaluateString(evaluator); 170 return findDimension(dimensionName, evaluator); 171 } 172 }; 173 } 174 175 Dimension findDimension(String s, Evaluator evaluator) { 176 if (s.indexOf("[") == -1) { 177 s = Util.quoteMdxIdentifier(s); 178 } 179 OlapElement o = evaluator.getSchemaReader().lookupCompound( 180 evaluator.getCube(), 181 explode(s), 182 false, 183 Category.Dimension); 184 if (o instanceof Dimension) { 185 return (Dimension) o; 186 } else if (o == null) { 187 throw newEvalException(this, "Dimension '" + s + "' not found"); 188 } else { 189 throw newEvalException(this, "Dimensions(" + s + ") found " + o); 190 } 191 } 192 }); 193 194 define(LevelHierarchyFunDef.instance); 197 define(MemberHierarchyFunDef.instance); 198 199 define(MemberLevelFunDef.instance); 202 203 define(new FunDefBase( 204 "Levels", 205 "<Hierarchy>.Levels(<Numeric Expression>)", 206 "Returns the level whose position in a hierarchy is specified by a numeric expression.", 207 "mlhn") { 208 public Type getResultType(Validator validator, Exp[] args) { 209 final Type argType = args[0].getType(); 210 return LevelType.forType(argType); 211 } 212 213 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 214 final HierarchyCalc hierarchyCalc = 215 compiler.compileHierarchy(call.getArg(0)); 216 final IntegerCalc ordinalCalc = 217 compiler.compileInteger(call.getArg(1)); 218 return new AbstractLevelCalc(call, new Calc[] {hierarchyCalc, ordinalCalc}) { 219 public Level evaluateLevel(Evaluator evaluator) { 220 Hierarchy hierarchy = 221 hierarchyCalc.evaluateHierarchy(evaluator); 222 int ordinal = ordinalCalc.evaluateInteger(evaluator); 223 return nthLevel(hierarchy, ordinal); 224 } 225 }; 226 } 227 228 Level nthLevel(Hierarchy hierarchy, int n) { 229 Level[] levels = hierarchy.getLevels(); 230 231 if (n >= levels.length || n < 0) { 232 throw newEvalException( 233 this, "Index '" + n + "' out of bounds"); 234 } 235 return levels[n]; 236 } 237 }); 238 239 define(new FunDefBase( 240 "Levels", 241 "Levels(<String Expression>)", 242 "Returns the level whose name is specified by a string expression.", 243 "flS") { 244 public Type getResultType(Validator validator, Exp[] args) { 245 final Type argType = args[0].getType(); 246 return LevelType.forType(argType); 247 } 248 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 249 final StringCalc stringCalc = 250 compiler.compileString(call.getArg(0)); 251 return new AbstractLevelCalc(call, new Calc[] {stringCalc}) { 252 public Level evaluateLevel(Evaluator evaluator) { 253 String levelName = 254 stringCalc.evaluateString(evaluator); 255 return findLevel(evaluator, levelName); 256 } 257 }; 258 } 259 260 Level findLevel(Evaluator evaluator, String s) { 261 Cube cube = evaluator.getCube(); 262 OlapElement o = (s.startsWith("[")) ? 263 evaluator.getSchemaReader().lookupCompound( 264 cube, 265 explode(s), 266 false, 267 Category.Level) : 268 null; 271 272 if (o instanceof Level) { 273 return (Level) o; 274 } else if (o == null) { 275 throw newEvalException(this, "Level '" + s + "' not found"); 276 } else { 277 throw newEvalException(this, "Levels('" + s + "') found " + o); 278 } 279 } 280 }); 281 282 define(IsEmptyFunDef.FunctionResolver); 285 define(IsEmptyFunDef.PostfixResolver); 286 define(IsNullFunDef.Resolver); 287 define(IsFunDef.Resolver); 288 289 define(AncestorFunDef.Resolver); 292 293 define(new FunDefBase( 294 "Cousin", 295 "Cousin(<member>, <ancestor member>)", 296 "Returns the member with the same relative position under <ancestor member> as the member specified.", 297 "fmmm") { 298 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 299 final MemberCalc memberCalc = 300 compiler.compileMember(call.getArg(0)); 301 final MemberCalc ancestorMemberCalc = 302 compiler.compileMember(call.getArg(1)); 303 return new AbstractMemberCalc(call, new Calc[] {memberCalc, ancestorMemberCalc}) { 304 public Member evaluateMember(Evaluator evaluator) { 305 Member member = memberCalc.evaluateMember(evaluator); 306 Member ancestorMember = ancestorMemberCalc.evaluateMember(evaluator); 307 return cousin( 308 evaluator.getSchemaReader(), 309 member, 310 ancestorMember); 311 } 312 }; 313 } 314 315 }); 316 317 define(DimensionCurrentMemberFunDef.instance); 318 319 define(HierarchyCurrentMemberFunDef.instance); 320 321 define(new FunDefBase( 322 "DataMember", 323 "<Member>.DataMember", 324 "Returns the system-generated data member that is associated with a nonleaf member of a dimension.", 325 "pmm") { 326 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 327 final MemberCalc memberCalc = 328 compiler.compileMember(call.getArg(0)); 329 return new AbstractMemberCalc(call, new Calc[] {memberCalc}) { 330 public Member evaluateMember(Evaluator evaluator) { 331 Member member = memberCalc.evaluateMember(evaluator); 332 return member.getDataMember(); 333 } 334 }; 335 } 336 337 }); 338 339 define(new FunDefBase( 340 "DefaultMember", 341 "<Dimension>.DefaultMember", 342 "Returns the default member of a dimension.", 343 "pmd") { 344 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 345 final DimensionCalc dimensionCalc = 346 compiler.compileDimension(call.getArg(0)); 347 return new AbstractMemberCalc(call, new Calc[] {dimensionCalc}) { 348 public Member evaluateMember(Evaluator evaluator) { 349 Dimension dimension = 350 dimensionCalc.evaluateDimension(evaluator); 351 return evaluator.getSchemaReader() 352 .getHierarchyDefaultMember( 353 dimension.getHierarchies()[0]); 354 } 355 }; 356 } 357 }); 358 359 define(new FunDefBase( 360 "DefaultMember", 361 "<Hierarchy>.DefaultMember", 362 "Returns the default member of a hierarchy.", 363 "pmh") { 364 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 365 final HierarchyCalc hierarchyCalc = 366 compiler.compileHierarchy(call.getArg(0)); 367 return new AbstractMemberCalc(call, new Calc[] {hierarchyCalc}) { 368 public Member evaluateMember(Evaluator evaluator) { 369 Hierarchy hierarchy = 370 hierarchyCalc.evaluateHierarchy(evaluator); 371 return evaluator.getSchemaReader() 372 .getHierarchyDefaultMember(hierarchy); 373 } 374 }; 375 } 376 }); 377 378 define(new FunDefBase( 379 "FirstChild", 380 "<Member>.FirstChild", 381 "Returns the first child of a member.", 382 "pmm") { 383 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 384 final MemberCalc memberCalc = 385 compiler.compileMember(call.getArg(0)); 386 return new AbstractMemberCalc(call, new Calc[] {memberCalc}) { 387 public Member evaluateMember(Evaluator evaluator) { 388 Member member = memberCalc.evaluateMember(evaluator); 389 return firstChild(evaluator, member); 390 } 391 }; 392 } 393 394 Member firstChild(Evaluator evaluator, Member member) { 395 Member[] children = evaluator.getSchemaReader() 396 .getMemberChildren(member); 397 return (children.length == 0) 398 ? member.getHierarchy().getNullMember() 399 : children[0]; 400 } 401 }); 402 403 define(new FunDefBase( 404 "FirstSibling", 405 "<Member>.FirstSibling", 406 "Returns the first child of the parent of a member.", 407 "pmm") { 408 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 409 final MemberCalc memberCalc = 410 compiler.compileMember(call.getArg(0)); 411 return new AbstractMemberCalc(call, new Calc[] {memberCalc}) { 412 public Member evaluateMember(Evaluator evaluator) { 413 Member member = memberCalc.evaluateMember(evaluator); 414 return firstSibling(member, evaluator); 415 } 416 }; 417 } 418 419 Member firstSibling(Member member, Evaluator evaluator) { 420 Member parent = member.getParentMember(); 421 Member[] children; 422 if (parent == null) { 423 if (member.isNull()) { 424 return member; 425 } 426 children = evaluator.getSchemaReader().getHierarchyRootMembers(member.getHierarchy()); 427 } else { 428 children = evaluator.getSchemaReader().getMemberChildren(parent); 429 } 430 return children[0]; 431 } 432 }); 433 434 define(LeadLagFunDef.LagResolver); 435 436 define(new FunDefBase( 437 "LastChild", 438 "<Member>.LastChild", 439 "Returns the last child of a member.", 440 "pmm") { 441 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 442 final MemberCalc memberCalc = 443 compiler.compileMember(call.getArg(0)); 444 return new AbstractMemberCalc(call, new Calc[] {memberCalc}) { 445 public Member evaluateMember(Evaluator evaluator) { 446 Member member = memberCalc.evaluateMember(evaluator); 447 return lastChild(evaluator, member); 448 } 449 }; 450 } 451 452 Member lastChild(Evaluator evaluator, Member member) { 453 Member[] children = 454 evaluator.getSchemaReader().getMemberChildren(member); 455 return (children.length == 0) 456 ? member.getHierarchy().getNullMember() 457 : children[children.length - 1]; 458 } 459 }); 460 461 define(new FunDefBase( 462 "LastSibling", 463 "<Member>.LastSibling", 464 "Returns the last child of the parent of a member.", 465 "pmm") { 466 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 467 final MemberCalc memberCalc = 468 compiler.compileMember(call.getArg(0)); 469 return new AbstractMemberCalc(call, new Calc[] {memberCalc}) { 470 public Member evaluateMember(Evaluator evaluator) { 471 Member member = memberCalc.evaluateMember(evaluator); 472 return firstSibling(member, evaluator); 473 } 474 }; 475 } 476 477 Member firstSibling(Member member, Evaluator evaluator) { 478 Member parent = member.getParentMember(); 479 Member[] children; 480 final SchemaReader schemaReader = evaluator.getSchemaReader(); 481 if (parent == null) { 482 if (member.isNull()) { 483 return member; 484 } 485 children = schemaReader.getHierarchyRootMembers( 486 member.getHierarchy()); 487 } else { 488 children = schemaReader.getMemberChildren(parent); 489 } 490 return children[children.length - 1]; 491 } 492 }); 493 494 define(LeadLagFunDef.LeadResolver); 495 496 define(new FunDefBase( 497 "Members", 498 "Members(<String Expression>)", 499 "Returns the member whose name is specified by a string expression.", 500 "fmS") { 501 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 502 throw new UnsupportedOperationException (); 503 } 504 }); 505 506 define(new FunDefBase( 507 "NextMember", 508 "<Member>.NextMember", 509 "Returns the next member in the level that contains a specified member.", 510 "pmm") { 511 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 512 final MemberCalc memberCalc = 513 compiler.compileMember(call.getArg(0)); 514 return new AbstractMemberCalc(call, new Calc[] {memberCalc}) { 515 public Member evaluateMember(Evaluator evaluator) { 516 Member member = memberCalc.evaluateMember(evaluator); 517 return evaluator.getSchemaReader().getLeadMember(member, +1); 518 } 519 }; 520 } 521 522 }); 523 524 define(OpeningClosingPeriodFunDef.OpeningPeriodResolver); 525 define(OpeningClosingPeriodFunDef.ClosingPeriodResolver); 526 527 define(ParallelPeriodFunDef.Resolver); 528 529 530 define(new FunDefBase( 531 "Parent", 532 "<Member>.Parent", 533 "Returns the parent of a member.", 534 "pmm") { 535 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 536 final MemberCalc memberCalc = 537 compiler.compileMember(call.getArg(0)); 538 return new AbstractMemberCalc(call, new Calc[] {memberCalc}) { 539 public Member evaluateMember(Evaluator evaluator) { 540 Member member = memberCalc.evaluateMember(evaluator); 541 return memberParent(evaluator, member); 542 } 543 }; 544 } 545 546 Member memberParent(Evaluator evaluator, Member member) { 547 Member parent = evaluator.getSchemaReader().getMemberParent(member); 548 if (parent == null) { 549 parent = member.getHierarchy().getNullMember(); 550 } 551 return parent; 552 } 553 554 }); 555 556 define(new FunDefBase( 557 "PrevMember", 558 "<Member>.PrevMember", 559 "Returns the previous member in the level that contains a specified member.", 560 "pmm") { 561 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 562 final MemberCalc memberCalc = 563 compiler.compileMember(call.getArg(0)); 564 return new AbstractMemberCalc(call, new Calc[] {memberCalc}) { 565 public Member evaluateMember(Evaluator evaluator) { 566 Member member = memberCalc.evaluateMember(evaluator); 567 return evaluator.getSchemaReader().getLeadMember(member, -1); 568 } 569 }; 570 } 571 }); 572 573 define(new FunDefBase( 574 "StrToMember", 575 "StrToMember(<String Expression>)", 576 "Returns a member from a unique name String in MDX format.", 577 "fmS") { 578 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 579 final StringCalc memberNameCalc = 580 compiler.compileString(call.getArg(0)); 581 return new AbstractMemberCalc(call, new Calc[] {memberNameCalc}) { 582 public Member evaluateMember(Evaluator evaluator) { 583 String memberName = 584 memberNameCalc.evaluateString(evaluator); 585 return strToMember(evaluator, memberName); 586 } 587 }; 588 } 589 590 Member strToMember(Evaluator evaluator, String memberName) { 591 Cube cube = evaluator.getCube(); 592 SchemaReader schemaReader = evaluator.getSchemaReader(); 593 String [] uniqueNameParts = Util.explode(memberName); 594 Member member = (Member) schemaReader.lookupCompound(cube, 595 uniqueNameParts, true, Category.Member); 596 return member; 598 } 599 }); 600 601 define(ValidMeasureFunDef.instance); 602 603 define(AggregateFunDef.resolver); 606 607 define(new MultiResolver( 609 "$AggregateChildren", 610 "$AggregateChildren(<Hierarchy>)", 611 "Equivalent to 'Aggregate(<Hierarchy>.CurrentMember.Children); for internal use.", 612 new String [] {"Inh"}) { 613 protected FunDef createFunDef(Exp[] args, FunDef dummyFunDef) { 614 return new FunDefBase(dummyFunDef) { 615 public void unparse(Exp[] args, PrintWriter pw) { 616 pw.print(getName()); 617 pw.print("("); 618 args[0].unparse(pw); 619 pw.print(")"); 620 } 621 622 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 623 final HierarchyCalc hierarchyCalc = 624 compiler.compileHierarchy(call.getArg(0)); 625 final Calc valueCalc = new ValueCalc(call); 626 return new AbstractCalc(call) { 627 public Object evaluate(Evaluator evaluator) { 628 Hierarchy hierarchy = 629 hierarchyCalc.evaluateHierarchy(evaluator); 630 return aggregateChildren(evaluator, hierarchy, valueCalc); 631 } 632 633 public Calc[] getCalcs() { 634 return new Calc[] {hierarchyCalc, valueCalc}; 635 } 636 }; 637 } 638 639 Object aggregateChildren( 640 Evaluator evaluator, Hierarchy hierarchy, final Calc valueFunCall) { 641 Member member = evaluator.getParent().getContext(hierarchy.getDimension()); 642 List members = 643 (List) member.getPropertyValue( 644 Property.CONTRIBUTING_CHILDREN.name); 645 Aggregator aggregator = 646 (Aggregator) evaluator.getProperty( 647 Property.AGGREGATION_TYPE.name, null); 648 if (aggregator == null) { 649 throw FunUtil.newEvalException(null, "Could not find an aggregator in the current evaluation context"); 650 } 651 Aggregator rollup = aggregator.getRollup(); 652 if (rollup == null) { 653 throw FunUtil.newEvalException(null, "Don't know how to rollup aggregator '" + aggregator + "'"); 654 } 655 return rollup.aggregate(evaluator.push(), members, valueFunCall); 656 } 657 }; 658 } 659 }); 660 661 define(AvgFunDef.Resolver); 662 663 define(CorrelationFunDef.Resolver); 664 665 define(CountFunDef.Resolver); 666 667 define(new FunDefBase( 668 "Count", 669 "<Set>.Count", 670 "Returns the number of tuples in a set including empty cells.", 671 "pnx") { 672 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 673 final ListCalc memberListCalc = 674 compiler.compileList(call.getArg(0)); 675 return new AbstractIntegerCalc(call, new Calc[] {memberListCalc}) { 676 public int evaluateInteger(Evaluator evaluator) { 677 List memberList = 678 memberListCalc.evaluateList(evaluator); 679 return count(evaluator, memberList, true); 680 } 681 }; 682 } 683 }); 684 685 define(CovarianceFunDef.CovarianceResolver); 686 define(CovarianceFunDef.CovarianceNResolver); 687 688 define(new FunDefBase( 689 "IIf", 690 "IIf(<Logical Expression>, <String Expression1>, <String Expression2>)", 691 "Returns one of two string values determined by a logical test.", 692 "fSbSS") { 693 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 694 final BooleanCalc booleanCalc = 695 compiler.compileBoolean(call.getArg(0)); 696 final StringCalc calc1 = compiler.compileString(call.getArg(1)); 697 final StringCalc calc2 = compiler.compileString(call.getArg(2)); 698 return new AbstractStringCalc(call, new Calc[] {booleanCalc, calc1, calc2}) { 699 public String evaluateString(Evaluator evaluator) { 700 final boolean b = 701 booleanCalc.evaluateBoolean(evaluator); 702 StringCalc calc = b ? calc1 : calc2; 703 return calc.evaluateString(evaluator); 704 } 705 }; 706 } 707 }); 708 709 define(new FunDefBase( 710 "IIf", 711 "IIf(<Logical Expression>, <Numeric Expression1>, <Numeric Expression2>)", 712 "Returns one of two numeric values determined by a logical test.", 713 "fnbnn") { 714 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 715 final BooleanCalc booleanCalc = 716 compiler.compileBoolean(call.getArg(0)); 717 final Calc calc1 = compiler.compileScalar(call.getArg(1), true); 718 final Calc calc2 = compiler.compileScalar(call.getArg(2), true); 719 return new GenericCalc(call) { 720 public Object evaluate(Evaluator evaluator) { 721 final boolean b = 722 booleanCalc.evaluateBoolean(evaluator); 723 Calc calc = b ? calc1 : calc2; 724 return calc.evaluate(evaluator); 725 } 726 727 public Calc[] getCalcs() { 728 return new Calc[] {booleanCalc, calc1, calc2}; 729 } 730 }; 731 } 732 733 }); 734 735 define(LinReg.InterceptResolver); 736 define(LinReg.PointResolver); 737 define(LinReg.R2Resolver); 738 define(LinReg.SlopeResolver); 739 define(LinReg.VarianceResolver); 740 741 define(MinMaxFunDef.MaxResolver); 742 743 define(MedianFunDef.Resolver); 744 745 define(MinMaxFunDef.MinResolver); 746 747 define(new FunDefBase( 748 "Ordinal", 749 "<Level>.Ordinal", 750 "Returns the zero-based ordinal value associated with a level.", 751 "pnl") { 752 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 753 final LevelCalc levelCalc = 754 compiler.compileLevel(call.getArg(0)); 755 return new AbstractIntegerCalc(call, new Calc[] {levelCalc}) { 756 public int evaluateInteger(Evaluator evaluator) { 757 final Level level = levelCalc.evaluateLevel(evaluator); 758 return level.getDepth(); 759 } 760 }; 761 } 762 763 }); 764 765 define(RankFunDef.Resolver); 766 767 define(CacheFunDef.Resolver); 768 769 define(StdevFunDef.StdevResolver); 770 define(StdevFunDef.StddevResolver); 771 772 define(StdevPFunDef.StdevpResolver); 773 define(StdevPFunDef.StddevpResolver); 774 775 define(SumFunDef.Resolver); 776 777 define(new FunDefBase( 778 "Value", 779 "<Measure>.Value", 780 "Returns the value of a measure.", 781 "pnm") { 782 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 783 final MemberCalc memberCalc = 784 compiler.compileMember(call.getArg(0)); 785 return new AbstractCalc(call) { 786 public Object evaluate(Evaluator evaluator) { 787 Member member = memberCalc.evaluateMember(evaluator); 788 Member old = evaluator.setContext(member); 789 Object value = evaluator.evaluateCurrent(); 790 evaluator.setContext(old); 791 return value; 792 } 793 794 public boolean dependsOn(Dimension dimension) { 795 if (super.dependsOn(dimension)) { 796 return true; 797 } 798 if (memberCalc.getType().usesDimension(dimension, true) ) { 799 return false; 800 } 801 return true; 802 } 803 public Calc[] getCalcs() { 804 return new Calc[] {memberCalc}; 805 } 806 }; 807 } 808 809 }); 810 811 define(VarFunDef.VarResolver); 812 define(VarFunDef.VarianceResolver); 813 814 define(VarPFunDef.VariancePResolver); 815 define(VarPFunDef.VarPResolver); 816 817 820 define(AddCalculatedMembersFunDef.resolver); 821 822 define(new FunDefBase( 823 "Ascendants", 824 "Ascendants(<Member>)", 825 "Returns the set of the ascendants of a specified member.", 826 "fxm") { 827 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 828 final MemberCalc memberCalc = 829 compiler.compileMember(call.getArg(0)); 830 return new AbstractListCalc(call, new Calc[] {memberCalc}) { 831 public List evaluateList(Evaluator evaluator) { 832 Member member = memberCalc.evaluateMember(evaluator); 833 return ascendants(member); 834 } 835 }; 836 } 837 838 List<Member> ascendants(Member member) { 839 if (member.isNull()) { 840 return Collections.emptyList(); 841 } 842 Member[] members = member.getAncestorMembers(); 843 final List<Member> result = 844 new ArrayList<Member>(members.length + 1); 845 result.add(member); 846 XOMUtil.addAll(result, members); 847 return result; 848 } 849 }); 850 851 define(TopBottomCountFunDef.BottomCountResolver); 852 define(TopBottomPercentSumFunDef.BottomPercentResolver); 853 define(TopBottomPercentSumFunDef.BottomSumResolver); 854 define(TopBottomCountFunDef.TopCountResolver); 855 define(TopBottomPercentSumFunDef.TopPercentResolver); 856 define(TopBottomPercentSumFunDef.TopSumResolver); 857 858 define(new FunDefBase( 859 "Children", 860 "<Member>.Children", 861 "Returns the children of a member.", 862 "pxm") { 863 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 864 final MemberCalc memberCalc = 865 compiler.compileMember(call.getArg(0)); 866 return new AbstractListCalc(call, new Calc[] {memberCalc}, false) { 867 public List evaluateList(Evaluator evaluator) { 868 Member member = memberCalc.evaluateMember(evaluator); 871 Member[] children = getNonEmptyMemberChildren(evaluator, member); 872 return Arrays.asList(children); 873 } 874 }; 875 } 876 877 }); 878 879 define(CrossJoinFunDef.Resolver); 880 881 define(NonEmptyCrossJoinFunDef.Resolver); 882 883 define(CrossJoinFunDef.StarResolver); 884 885 define(DescendantsFunDef.Resolver); 886 887 define(new FunDefBase( 888 "Distinct", 889 "Distinct(<Set>)", 890 "Eliminates duplicate tuples from a set.", 891 "fxx") { 892 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 893 final ListCalc listCalc = 894 compiler.compileList(call.getArg(0)); 895 return new AbstractListCalc(call, new Calc[] {listCalc}) { 896 public List evaluateList(Evaluator evaluator) { 897 List list = listCalc.evaluateList(evaluator); 898 return distinct(list); 899 } 900 }; 901 } 902 903 List<Object > distinct(List list) { 904 Set<MemberHelper> set = new HashSet<MemberHelper>(list.size()); 905 List<Object > result = new ArrayList<Object >(); 906 907 for (Object element : list) { 908 MemberHelper lookupObj = new MemberHelper(element); 909 910 if (set.add(lookupObj)) { 911 result.add(element); 912 } 913 } 914 return result; 915 } 916 }); 917 918 define(DrilldownLevelFunDef.Resolver); 919 920 if (false) define(new FunDefBase( 921 "DrilldownLevelBottom", 922 "DrilldownLevelBottom(<Set>, <Count>[, [<Level>][, <Numeric Expression>]])", 923 "Drills down the bottom N members of a set, at a specified level, to one level below.", 924 "fx*") { 925 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 926 throw new UnsupportedOperationException (); 927 } 928 }); 929 930 if (false) define(new FunDefBase( 931 "DrilldownLevelTop", 932 "DrilldownLevelTop(<Set>, <Count>[, [<Level>][, <Numeric Expression>]])", 933 "Drills down the top N members of a set, at a specified level, to one level below.", 934 "fx*") { 935 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 936 throw new UnsupportedOperationException (); 937 } 938 }); 939 940 define(DrilldownMemberFunDef.Resolver); 941 942 if (false) define(new FunDefBase( 943 "DrilldownMemberBottom", 944 "DrilldownMemberBottom(<Set1>, <Set2>, <Count>[, [<Numeric Expression>][, RECURSIVE]])", 945 "Like DrilldownMember except that it includes only the bottom N children.", 946 "fx*") { 947 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 948 throw new UnsupportedOperationException (); 949 } 950 }); 951 952 if (false) define(new FunDefBase( 953 "DrilldownMemberTop", 954 "DrilldownMemberTop(<Set1>, <Set2>, <Count>[, [<Numeric Expression>][, RECURSIVE]])", 955 "Like DrilldownMember except that it includes only the top N children.", 956 "fx*") { 957 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 958 throw new UnsupportedOperationException (); 959 } 960 }); 961 962 if (false) define(new FunDefBase( 963 "DrillupLevel", 964 "DrillupLevel(<Set>[, <Level>])", 965 "Drills up the members of a set that are below a specified level.", 966 "fx*") { 967 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 968 throw new UnsupportedOperationException (); 969 } 970 }); 971 972 if (false) define(new FunDefBase( 973 "DrillupMember", 974 "DrillupMember(<Set1>, <Set2>)", 975 "Drills up the members in a set that are present in a second specified set.", 976 "fx*") { 977 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 978 throw new UnsupportedOperationException (); 979 } 980 }); 981 982 define(ExceptFunDef.Resolver); 983 984 if (false) define(new FunDefBase( 985 "Extract", 986 "Extract(<Set>, <Dimension>[, <Dimension>...])", 987 "Returns a set of tuples from extracted dimension elements. The opposite of Crossjoin.", 988 "fx*") { 989 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 990 throw new UnsupportedOperationException (); 991 } 992 }); 993 994 define(FilterFunDef.instance); 995 996 define(GenerateFunDef.ListResolver); 997 define(GenerateFunDef.StringResolver); 998 define(HeadTailFunDef.HeadResolver); 999 1000 define(HierarchizeFunDef.Resolver); 1001 1002 define(IntersectFunDef.resolver); 1003 define(LastPeriodsFunDef.Resolver); 1004 1005 define(new FunDefBase( 1006 "Members", 1007 "<Dimension>.Members", 1008 "Returns the set of members in a dimension.", 1009 "pxd") { 1010 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1011 final DimensionCalc dimensionCalc = 1012 compiler.compileDimension(call.getArg(0)); 1013 return new AbstractListCalc(call, new Calc[] {dimensionCalc}) { 1014 public List evaluateList(Evaluator evaluator) { 1015 Dimension dimension = 1016 dimensionCalc.evaluateDimension(evaluator); 1017 return dimensionMembers(dimension, evaluator, false); 1018 } 1019 }; 1020 } 1021 1022 }); 1023 1024 define(new FunDefBase( 1025 "AllMembers", 1026 "<Dimension>.AllMembers", 1027 "Returns a set that contains all members, including calculated members, of the specified dimension.", 1028 "pxd") { 1029 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1030 final DimensionCalc dimensionCalc = 1031 compiler.compileDimension(call.getArg(0)); 1032 return new AbstractListCalc(call, new Calc[] {dimensionCalc}) { 1033 public List evaluateList(Evaluator evaluator) { 1034 Dimension dimension = 1035 dimensionCalc.evaluateDimension(evaluator); 1036 return dimensionMembers(dimension, evaluator, true); 1037 } 1038 }; 1039 } 1040 1041 }); 1042 1043 define(new FunDefBase( 1044 "Members", 1045 "<Hierarchy>.Members", 1046 "Returns the set of members in a hierarchy.", 1047 "pxh") { 1048 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1049 final HierarchyCalc hierarchyCalc = 1050 compiler.compileHierarchy(call.getArg(0)); 1051 return new AbstractListCalc(call, new Calc[] {hierarchyCalc}) { 1052 public List evaluateList(Evaluator evaluator) { 1053 Hierarchy hierarchy = 1054 hierarchyCalc.evaluateHierarchy(evaluator); 1055 return hierarchyMembers(hierarchy, evaluator, false); 1056 } 1057 }; 1058 } 1059 1060 }); 1061 1062 define(new FunDefBase( 1063 "AllMembers", 1064 "<Hierarchy>.AllMembers", 1065 "Returns a set that contains all members, including calculated members, of the specified hierarchy.", 1066 "pxh") { 1067 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1068 final HierarchyCalc hierarchyCalc = 1069 compiler.compileHierarchy(call.getArg(0)); 1070 return new AbstractListCalc(call, new Calc[] {hierarchyCalc}) { 1071 public List evaluateList(Evaluator evaluator) { 1072 Hierarchy hierarchy = 1073 hierarchyCalc.evaluateHierarchy(evaluator); 1074 return hierarchyMembers(hierarchy, evaluator, true); 1075 } 1076 }; 1077 } 1078 }); 1079 1080 define(new FunDefBase( 1081 "Members", 1082 "<Level>.Members", 1083 "Returns the set of members in a level.", 1084 "pxl") { 1085 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1086 final LevelCalc levelCalc = 1087 compiler.compileLevel(call.getArg(0)); 1088 return new AbstractListCalc(call, new Calc[] {levelCalc}) { 1089 public List evaluateList(Evaluator evaluator) { 1090 Level level = levelCalc.evaluateLevel(evaluator); 1091 return levelMembers(level, evaluator, false); 1092 } 1093 }; 1094 } 1095 }); 1096 1097 define(new FunDefBase( 1098 "AllMembers", 1099 "<Level>.AllMembers", 1100 "Returns a set that contains all members, including calculated members, of the specified level.", 1101 "pxl") { 1102 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1103 final LevelCalc levelCalc = 1104 compiler.compileLevel(call.getArg(0)); 1105 return new AbstractListCalc(call, new Calc[] {levelCalc}) { 1106 public List evaluateList(Evaluator evaluator) { 1107 Level level = levelCalc.evaluateLevel(evaluator); 1108 return levelMembers(level, evaluator, true); 1109 } 1110 }; 1111 } 1112 }); 1113 1114 define(XtdFunDef.MtdResolver); 1115 define(OrderFunDef.Resolver); 1116 define(PeriodsToDateFunDef.Resolver); 1117 define(XtdFunDef.QtdResolver); 1118 1119 define(new FunDefBase( 1120 "StripCalculatedMembers", 1121 "StripCalculatedMembers(<Set>)", 1122 "Removes calculated members from a set.", 1123 "fxx") { 1124 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1125 final ListCalc listCalc = 1126 compiler.compileList(call.getArg(0)); 1127 return new AbstractListCalc(call, new Calc[] {listCalc}) { 1128 public List evaluateList(Evaluator evaluator) { 1129 final List<Member> list = listCalc.evaluateList(evaluator); 1130 removeCalculatedMembers(list); 1131 return list; 1132 } 1133 }; 1134 } 1135 1136 }); 1137 1138 define(new FunDefBase( 1139 "Siblings", 1140 "<Member>.Siblings", 1141 "Returns the siblings of a specified member, including the member itself.", 1142 "pxm") { 1143 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1144 final MemberCalc memberCalc = 1145 compiler.compileMember(call.getArg(0)); 1146 return new AbstractListCalc(call, new Calc[] {memberCalc}) { 1147 public List evaluateList(Evaluator evaluator) { 1148 final Member member = 1149 memberCalc.evaluateMember(evaluator); 1150 return memberSiblings(member, evaluator); 1151 } 1152 }; 1153 } 1154 1155 List memberSiblings(Member member, Evaluator evaluator) { 1156 if (member.isNull()) { 1157 return Collections.EMPTY_LIST; 1159 } 1160 Member parent = member.getParentMember(); 1161 final SchemaReader schemaReader = evaluator.getSchemaReader(); 1162 Member[] siblings = (parent == null) 1163 ? schemaReader.getHierarchyRootMembers(member.getHierarchy()) 1164 : schemaReader.getMemberChildren(parent); 1165 1166 return Arrays.asList(siblings); 1167 } 1168 }); 1169 1170 define(StrToSetFunDef.Resolver); 1171 define(SubsetFunDef.Resolver); 1172 define(HeadTailFunDef.TailResolver); 1173 define(ToggleDrillStateFunDef.Resolver); 1174 define(UnionFunDef.Resolver); 1175 define(VisualTotalsFunDef.Resolver); 1176 define(XtdFunDef.WtdResolver); 1177 define(XtdFunDef.YtdResolver); 1178 define(RangeFunDef.instance); define(SetFunDef.Resolver); 1181 define(FormatFunDef.Resolver); 1184 1185 define(new FunDefBase( 1186 "Caption", 1187 "<Dimension>.Caption", 1188 "Returns the caption of a dimension.", 1189 "pSd") { 1190 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1191 final DimensionCalc dimensionCalc = 1192 compiler.compileDimension(call.getArg(0)); 1193 return new AbstractStringCalc(call, new Calc[] {dimensionCalc}) { 1194 public String evaluateString(Evaluator evaluator) { 1195 final Dimension dimension = 1196 dimensionCalc.evaluateDimension(evaluator); 1197 return dimension.getCaption(); 1198 } 1199 }; 1200 } 1201 }); 1202 1203 define(new FunDefBase( 1204 "Caption", 1205 "<Hierarchy>.Caption", 1206 "Returns the caption of a hierarchy.", 1207 "pSh") { 1208 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1209 final HierarchyCalc hierarchyCalc = 1210 compiler.compileHierarchy(call.getArg(0)); 1211 return new AbstractStringCalc(call, new Calc[] {hierarchyCalc}) { 1212 public String evaluateString(Evaluator evaluator) { 1213 final Hierarchy hierarchy = 1214 hierarchyCalc.evaluateHierarchy(evaluator); 1215 return hierarchy.getCaption(); 1216 } 1217 }; 1218 } 1219 1220 }); 1221 1222 define(new FunDefBase( 1223 "Caption", 1224 "<Level>.Caption", 1225 "Returns the caption of a level.", 1226 "pSl") { 1227 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1228 final LevelCalc levelCalc = 1229 compiler.compileLevel(call.getArg(0)); 1230 return new AbstractStringCalc(call, new Calc[] {levelCalc}) { 1231 public String evaluateString(Evaluator evaluator) { 1232 final Level level = levelCalc.evaluateLevel(evaluator); 1233 return level.getCaption(); 1234 } 1235 }; 1236 } 1237 }); 1238 1239 define(new FunDefBase( 1240 "Caption", 1241 "<Member>.Caption", 1242 "Returns the caption of a member.", 1243 "pSm") { 1244 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1245 final MemberCalc memberCalc = 1246 compiler.compileMember(call.getArg(0)); 1247 return new AbstractStringCalc(call, new Calc[] {memberCalc}) { 1248 public String evaluateString(Evaluator evaluator) { 1249 final Member member = 1250 memberCalc.evaluateMember(evaluator); 1251 return member.getCaption(); 1252 } 1253 }; 1254 } 1255 }); 1256 1257 define(new FunDefBase( 1258 "Name", 1259 "<Dimension>.Name", 1260 "Returns the name of a dimension.", 1261 "pSd") { 1262 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1263 final DimensionCalc dimensionCalc = 1264 compiler.compileDimension(call.getArg(0)); 1265 return new AbstractStringCalc(call, new Calc[] {dimensionCalc}) { 1266 public String evaluateString(Evaluator evaluator) { 1267 final Dimension dimension = 1268 dimensionCalc.evaluateDimension(evaluator); 1269 return dimension.getName(); 1270 } 1271 }; 1272 } 1273 }); 1274 1275 define(new FunDefBase( 1276 "Name", 1277 "<Hierarchy>.Name", 1278 "Returns the name of a hierarchy.", 1279 "pSh") { 1280 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1281 final HierarchyCalc hierarchyCalc = 1282 compiler.compileHierarchy(call.getArg(0)); 1283 return new AbstractStringCalc(call, new Calc[] {hierarchyCalc}) { 1284 public String evaluateString(Evaluator evaluator) { 1285 final Hierarchy hierarchy = 1286 hierarchyCalc.evaluateHierarchy(evaluator); 1287 return hierarchy.getName(); 1288 } 1289 }; 1290 } 1291 }); 1292 1293 define(new FunDefBase( 1294 "Name", 1295 "<Level>.Name", 1296 "Returns the name of a level.", 1297 "pSl") { 1298 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1299 final LevelCalc levelCalc = 1300 compiler.compileLevel(call.getArg(0)); 1301 return new AbstractStringCalc(call, new Calc[] {levelCalc}) { 1302 public String evaluateString(Evaluator evaluator) { 1303 final Level level = levelCalc.evaluateLevel(evaluator); 1304 return level.getName(); 1305 } 1306 }; 1307 } 1308 }); 1309 1310 define(new FunDefBase( 1311 "Name", 1312 "<Member>.Name", 1313 "Returns the name of a member.", 1314 "pSm") { 1315 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1316 final MemberCalc memberCalc = 1317 compiler.compileMember(call.getArg(0)); 1318 return new AbstractStringCalc(call, new Calc[] {memberCalc}) { 1319 public String evaluateString(Evaluator evaluator) { 1320 final Member member = 1321 memberCalc.evaluateMember(evaluator); 1322 return member.getName(); 1323 } 1324 }; 1325 } 1326 }); 1327 1328 define(SetToStrFunDef.instance); 1329 1330 define(TupleToStrFunDef.instance); 1331 1332 define(new FunDefBase( 1333 "UniqueName", 1334 "<Dimension>.UniqueName", 1335 "Returns the unique name of a dimension.", 1336 "pSd") { 1337 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1338 final DimensionCalc dimensionCalc = 1339 compiler.compileDimension(call.getArg(0)); 1340 return new AbstractStringCalc(call, new Calc[] {dimensionCalc}) { 1341 public String evaluateString(Evaluator evaluator) { 1342 final Dimension dimension = 1343 dimensionCalc.evaluateDimension(evaluator); 1344 return dimension.getUniqueName(); 1345 } 1346 }; 1347 } 1348 }); 1349 1350 define(new FunDefBase( 1351 "UniqueName", 1352 "<Hierarchy>.UniqueName", 1353 "Returns the unique name of a hierarchy.", 1354 "pSh") { 1355 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1356 final HierarchyCalc hierarchyCalc = 1357 compiler.compileHierarchy(call.getArg(0)); 1358 return new AbstractStringCalc(call, new Calc[] {hierarchyCalc}) { 1359 public String evaluateString(Evaluator evaluator) { 1360 final Hierarchy hierarchy = 1361 hierarchyCalc.evaluateHierarchy(evaluator); 1362 return hierarchy.getUniqueName(); 1363 } 1364 }; 1365 } 1366 }); 1367 1368 define(new FunDefBase( 1369 "UniqueName", 1370 "<Level>.UniqueName", 1371 "Returns the unique name of a level.", 1372 "pSl") { 1373 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1374 final LevelCalc levelCalc = 1375 compiler.compileLevel(call.getArg(0)); 1376 return new AbstractStringCalc(call, new Calc[] {levelCalc}) { 1377 public String evaluateString(Evaluator evaluator) { 1378 final Level level = levelCalc.evaluateLevel(evaluator); 1379 return level.getUniqueName(); 1380 } 1381 }; 1382 } 1383 }); 1384 1385 define(new FunDefBase( 1386 "UniqueName", 1387 "<Member>.UniqueName", 1388 "Returns the unique name of a member.", 1389 "pSm") { 1390 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1391 final MemberCalc memberCalc = 1392 compiler.compileMember(call.getArg(0)); 1393 return new AbstractStringCalc(call, new Calc[] {memberCalc}) { 1394 public String evaluateString(Evaluator evaluator) { 1395 final Member member = 1396 memberCalc.evaluateMember(evaluator); 1397 return member.getUniqueName(); 1398 } 1399 }; 1400 } 1401 }); 1402 1403 if (false) define(new FunDefBase( 1406 "Current", 1407 "<Set>.Current", 1408 "Returns the current tuple from a set during an iteration.", 1409 "ptx") { 1410 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1411 throw new UnsupportedOperationException (); 1412 } 1413 }); 1414 1415 if (false) define(new FunDefBase( 1417 "Item", 1418 "<Set>.Item(<String Expression>[, <String Expression>...] | <Index>)", 1419 "Returns a tuple from a set.", 1420 "mx*") { 1421 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1422 throw new UnsupportedOperationException (); 1423 } 1424 }); 1425 1426 define(SetItemFunDef.intResolver); 1427 define(SetItemFunDef.stringResolver); 1428 define(TupleItemFunDef.instance); 1429 define(StrToTupleFunDef.Resolver); 1430 1431 define(TupleFunDef.Resolver); 1433 1434 define(CoalesceEmptyFunDef.Resolver); 1437 define(CaseTestFunDef.Resolver); 1438 define(CaseMatchFunDef.Resolver); 1439 define(PropertiesFunDef.Resolver); 1440 1441 define(new ParameterFunDef.ParameterResolver()); 1444 define(new ParameterFunDef.ParamRefResolver()); 1445 1446 define(new FunDefBase( 1449 "+", 1450 "<Numeric Expression> + <Numeric Expression>", 1451 "Adds two numbers.", 1452 "innn") { 1453 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1454 final DoubleCalc calc0 = compiler.compileDouble(call.getArg(0)); 1455 final DoubleCalc calc1 = compiler.compileDouble(call.getArg(1)); 1456 return new AbstractDoubleCalc(call, new Calc[] {calc0, calc1}) { 1457 public double evaluateDouble(Evaluator evaluator) { 1458 final double v0 = calc0.evaluateDouble(evaluator); 1459 final double v1 = calc1.evaluateDouble(evaluator); 1460 if (v0 == DoubleNull) { 1461 if (v1 == DoubleNull) { 1462 return DoubleNull; 1463 } else { 1464 return v1; 1465 } 1466 } else { 1467 if (v1 == DoubleNull) { 1468 return v0; 1469 } else { 1470 return v0 + v1; 1471 } 1472 } 1473 } 1474 }; 1475 } 1476 1477 }); 1478 1479 define(new FunDefBase( 1480 "-", 1481 "<Numeric Expression> - <Numeric Expression>", 1482 "Subtracts two numbers.", 1483 "innn") { 1484 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1485 final DoubleCalc calc0 = compiler.compileDouble(call.getArg(0)); 1486 final DoubleCalc calc1 = compiler.compileDouble(call.getArg(1)); 1487 return new AbstractDoubleCalc(call, new Calc[] {calc0, calc1}) { 1488 public double evaluateDouble(Evaluator evaluator) { 1489 final double v0 = calc0.evaluateDouble(evaluator); 1490 final double v1 = calc1.evaluateDouble(evaluator); 1491 if (v0 == DoubleNull) { 1492 if (v1 == DoubleNull) { 1493 return DoubleNull; 1494 } else { 1495 return - v1; 1496 } 1497 } else { 1498 if (v1 == DoubleNull) { 1499 return v0; 1500 } else { 1501 return v0 - v1; 1502 } 1503 } 1504 } 1505 }; 1506 } 1507 }); 1508 1509 define(new FunDefBase( 1510 "*", 1511 "<Numeric Expression> * <Numeric Expression>", 1512 "Multiplies two numbers.", 1513 "innn") { 1514 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1515 final DoubleCalc calc0 = compiler.compileDouble(call.getArg(0)); 1516 final DoubleCalc calc1 = compiler.compileDouble(call.getArg(1)); 1517 return new AbstractDoubleCalc(call, new Calc[] {calc0, calc1}) { 1518 public double evaluateDouble(Evaluator evaluator) { 1519 final double v0 = calc0.evaluateDouble(evaluator); 1520 final double v1 = calc1.evaluateDouble(evaluator); 1521 if (v0 == DoubleNull || v1 == DoubleNull) { 1523 return DoubleNull; 1524 } else { 1525 return v0 * v1; 1526 } 1527 } 1528 }; 1529 } 1530 }); 1531 1532 define(new FunDefBase( 1533 "/", 1534 "<Numeric Expression> / <Numeric Expression>", 1535 "Divides two numbers.", 1536 "innn") { 1537 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1538 final DoubleCalc calc0 = compiler.compileDouble(call.getArg(0)); 1539 final DoubleCalc calc1 = compiler.compileDouble(call.getArg(1)); 1540 return new AbstractDoubleCalc(call, new Calc[] {calc0, calc1}) { 1541 public double evaluateDouble(Evaluator evaluator) { 1542 final double v0 = calc0.evaluateDouble(evaluator); 1543 final double v1 = calc1.evaluateDouble(evaluator); 1544 if (v0 == DoubleNull || v1 == DoubleNull) { 1546 return DoubleNull; 1547 } else { 1548 return v0 / v1; 1549 } 1550 } 1551 }; 1552 } 1553 1554 public double evaluate(double d1, double d2) { 1556 return d1 / d2; 1557 } 1558 }); 1559 1560 define(new FunDefBase( 1561 "-", 1562 "- <Numeric Expression>", 1563 "Returns the negative of a number.", 1564 "Pnn") { 1565 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1566 final DoubleCalc calc = compiler.compileDouble(call.getArg(0)); 1567 return new AbstractDoubleCalc(call, new Calc[] {calc}) { 1568 public double evaluateDouble(Evaluator evaluator) { 1569 final double v = calc.evaluateDouble(evaluator); 1570 if (v == DoubleNull) { 1571 return DoubleNull; 1572 } else { 1573 return - v; 1574 } 1575 } 1576 }; 1577 } 1578 }); 1579 1580 define(new FunDefBase( 1581 "||", 1582 "<String Expression> || <String Expression>", 1583 "Concatenates two strings.", 1584 "iSSS") { 1585 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1586 final StringCalc calc0 = compiler.compileString(call.getArg(0)); 1587 final StringCalc calc1 = compiler.compileString(call.getArg(1)); 1588 return new AbstractStringCalc(call, new Calc[] {calc0, calc1}) { 1589 public String evaluateString(Evaluator evaluator) { 1590 final String s0 = calc0.evaluateString(evaluator); 1591 final String s1 = calc1.evaluateString(evaluator); 1592 return s0 + s1; 1593 } 1594 }; 1595 } 1596 1597 }); 1598 1599 define(new FunDefBase( 1600 "AND", 1601 "<Logical Expression> AND <Logical Expression>", 1602 "Returns the conjunction of two conditions.", 1603 "ibbb") { 1604 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1605 final BooleanCalc calc0 = compiler.compileBoolean(call.getArg(0)); 1606 final BooleanCalc calc1 = compiler.compileBoolean(call.getArg(1)); 1607 return new AbstractBooleanCalc(call, new Calc[] {calc0, calc1}) { 1608 public boolean evaluateBoolean(Evaluator evaluator) { 1609 boolean b0 = calc0.evaluateBoolean(evaluator); 1610 if (!evaluator.isEvalAxes() && !b0) { 1614 return false; 1615 } 1616 boolean b1 = calc1.evaluateBoolean(evaluator); 1617 return b0 && b1; 1618 } 1619 }; 1620 } 1621 }); 1622 1623 define(new FunDefBase( 1624 "OR", 1625 "<Logical Expression> OR <Logical Expression>", 1626 "Returns the disjunction of two conditions.", 1627 "ibbb") { 1628 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1629 final BooleanCalc calc0 = compiler.compileBoolean(call.getArg(0)); 1630 final BooleanCalc calc1 = compiler.compileBoolean(call.getArg(1)); 1631 return new AbstractBooleanCalc(call, new Calc[] {calc0, calc1}) { 1632 public boolean evaluateBoolean(Evaluator evaluator) { 1633 boolean b0 = calc0.evaluateBoolean(evaluator); 1634 if (!evaluator.isEvalAxes() && b0) { 1638 return true; 1639 } 1640 boolean b1 = calc1.evaluateBoolean(evaluator); 1641 return b0 || b1; 1642 } 1643 }; 1644 } 1645 }); 1646 1647 define(new FunDefBase( 1648 "XOR", 1649 "<Logical Expression> XOR <Logical Expression>", 1650 "Returns whether two conditions are mutually exclusive.", 1651 "ibbb") { 1652 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1653 final BooleanCalc calc0 = compiler.compileBoolean(call.getArg(0)); 1654 final BooleanCalc calc1 = compiler.compileBoolean(call.getArg(1)); 1655 return new AbstractBooleanCalc(call, new Calc[] {calc0, calc1}) { 1656 public boolean evaluateBoolean(Evaluator evaluator) { 1657 final boolean b0 = calc0.evaluateBoolean(evaluator); 1658 final boolean b1 = calc1.evaluateBoolean(evaluator); 1659 return b0 != b1; 1660 } 1661 }; 1662 } 1663 }); 1664 1665 define(new FunDefBase( 1666 "NOT", 1667 "NOT <Logical Expression>", 1668 "Returns the negation of a condition.", 1669 "Pbb") { 1670 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1671 final BooleanCalc calc = compiler.compileBoolean(call.getArg(0)); 1672 return new AbstractBooleanCalc(call, new Calc[] {calc}) { 1673 public boolean evaluateBoolean(Evaluator evaluator) { 1674 return !calc.evaluateBoolean(evaluator); 1675 } 1676 }; 1677 } 1678 }); 1679 1680 define(new FunDefBase( 1681 "=", 1682 "<String Expression> = <String Expression>", 1683 "Returns whether two expressions are equal.", 1684 "ibSS") { 1685 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1686 final StringCalc calc0 = compiler.compileString(call.getArg(0)); 1687 final StringCalc calc1 = compiler.compileString(call.getArg(1)); 1688 return new AbstractBooleanCalc(call, new Calc[] {calc0, calc1}) { 1689 public boolean evaluateBoolean(Evaluator evaluator) { 1690 final String b0 = calc0.evaluateString(evaluator); 1691 final String b1 = calc1.evaluateString(evaluator); 1692 if (b0 == null || b1 == null) { 1693 return BooleanNull; 1694 } 1695 return b0.equals(b1); 1696 } 1697 }; 1698 } 1699 }); 1700 1701 define(new FunDefBase( 1702 "=", 1703 "<Numeric Expression> = <Numeric Expression>", 1704 "Returns whether two expressions are equal.", 1705 "ibnn") { 1706 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1707 final DoubleCalc calc0 = compiler.compileDouble(call.getArg(0)); 1708 final DoubleCalc calc1 = compiler.compileDouble(call.getArg(1)); 1709 return new AbstractBooleanCalc(call, new Calc[] {calc0, calc1}) { 1710 public boolean evaluateBoolean(Evaluator evaluator) { 1711 final double v0 = calc0.evaluateDouble(evaluator); 1712 final double v1 = calc1.evaluateDouble(evaluator); 1713 if (v0 == Double.NaN || v1 == Double.NaN || v0 == DoubleNull || v1 == DoubleNull) { 1714 return BooleanNull; 1715 } 1716 return v0 == v1; 1717 } 1718 }; 1719 } 1720 }); 1721 1722 define(new FunDefBase( 1723 "<>", 1724 "<String Expression> <> <String Expression>", 1725 "Returns whether two expressions are not equal.", 1726 "ibSS") { 1727 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1728 final StringCalc calc0 = compiler.compileString(call.getArg(0)); 1729 final StringCalc calc1 = compiler.compileString(call.getArg(1)); 1730 return new AbstractBooleanCalc(call, new Calc[] {calc0, calc1}) { 1731 public boolean evaluateBoolean(Evaluator evaluator) { 1732 final String b0 = calc0.evaluateString(evaluator); 1733 final String b1 = calc1.evaluateString(evaluator); 1734 if (b0 == null || b1 == null) { 1735 return BooleanNull; 1736 } 1737 return !b0.equals(b1); 1738 } 1739 }; 1740 } 1741 }); 1742 1743 define(new FunDefBase( 1744 "<>", 1745 "<Numeric Expression> <> <Numeric Expression>", 1746 "Returns whether two expressions are not equal.", 1747 "ibnn") { 1748 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1749 final DoubleCalc calc0 = compiler.compileDouble(call.getArg(0)); 1750 final DoubleCalc calc1 = compiler.compileDouble(call.getArg(1)); 1751 return new AbstractBooleanCalc(call, new Calc[] {calc0, calc1}) { 1752 public boolean evaluateBoolean(Evaluator evaluator) { 1753 final double v0 = calc0.evaluateDouble(evaluator); 1754 final double v1 = calc1.evaluateDouble(evaluator); 1755 if (v0 == Double.NaN || v1 == Double.NaN || v0 == DoubleNull || v1 == DoubleNull) { 1756 return BooleanNull; 1757 } 1758 return v0 != v1; 1759 } 1760 }; 1761 } 1762 }); 1763 1764 define(new FunDefBase( 1765 "<", 1766 "<Numeric Expression> < <Numeric Expression>", 1767 "Returns whether an expression is less than another.", 1768 "ibnn") { 1769 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1770 final DoubleCalc calc0 = compiler.compileDouble(call.getArg(0)); 1771 final DoubleCalc calc1 = compiler.compileDouble(call.getArg(1)); 1772 return new AbstractBooleanCalc(call, new Calc[] {calc0, calc1}) { 1773 public boolean evaluateBoolean(Evaluator evaluator) { 1774 final double v0 = calc0.evaluateDouble(evaluator); 1775 final double v1 = calc1.evaluateDouble(evaluator); 1776 if (v0 == Double.NaN || v1 == Double.NaN || v0 == DoubleNull || v1 == DoubleNull) { 1777 return BooleanNull; 1778 } 1779 return v0 < v1; 1780 } 1781 }; 1782 } 1783 }); 1784 1785 define(new FunDefBase( 1786 "<", 1787 "<String Expression> < <String Expression>", 1788 "Returns whether an expression is less than another.", 1789 "ibSS") { 1790 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1791 final StringCalc calc0 = compiler.compileString(call.getArg(0)); 1792 final StringCalc calc1 = compiler.compileString(call.getArg(1)); 1793 return new AbstractBooleanCalc(call, new Calc[] {calc0, calc1}) { 1794 public boolean evaluateBoolean(Evaluator evaluator) { 1795 final String b0 = calc0.evaluateString(evaluator); 1796 final String b1 = calc1.evaluateString(evaluator); 1797 if (b0 == null || b1 == null) { 1798 return BooleanNull; 1799 } 1800 return b0.compareTo(b1) < 0; 1801 } 1802 }; 1803 } 1804 }); 1805 1806 define(new FunDefBase( 1807 "<=", 1808 "<Numeric Expression> <= <Numeric Expression>", 1809 "Returns whether an expression is less than or equal to another.", 1810 "ibnn") { 1811 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1812 final DoubleCalc calc0 = compiler.compileDouble(call.getArg(0)); 1813 final DoubleCalc calc1 = compiler.compileDouble(call.getArg(1)); 1814 return new AbstractBooleanCalc(call, new Calc[] {calc0, calc1}) { 1815 public boolean evaluateBoolean(Evaluator evaluator) { 1816 final double v0 = calc0.evaluateDouble(evaluator); 1817 final double v1 = calc1.evaluateDouble(evaluator); 1818 if (v0 == Double.NaN || v1 == Double.NaN || v0 == DoubleNull || v1 == DoubleNull) { 1819 return BooleanNull; 1820 } 1821 return v0 <= v1; 1822 } 1823 }; 1824 } 1825 }); 1826 1827 define(new FunDefBase( 1828 "<=", 1829 "<String Expression> <= <String Expression>", 1830 "Returns whether an expression is less than or equal to another.", 1831 "ibSS") { 1832 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1833 final StringCalc calc0 = compiler.compileString(call.getArg(0)); 1834 final StringCalc calc1 = compiler.compileString(call.getArg(1)); 1835 return new AbstractBooleanCalc(call, new Calc[] {calc0, calc1}) { 1836 public boolean evaluateBoolean(Evaluator evaluator) { 1837 final String b0 = calc0.evaluateString(evaluator); 1838 final String b1 = calc1.evaluateString(evaluator); 1839 if (b0 == null || b1 == null) { 1840 return BooleanNull; 1841 } 1842 return b0.compareTo(b1) <= 0; 1843 } 1844 }; 1845 } 1846 }); 1847 1848 define(new FunDefBase( 1849 ">", 1850 "<Numeric Expression> > <Numeric Expression>", 1851 "Returns whether an expression is greater than another.", 1852 "ibnn") { 1853 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1854 final DoubleCalc calc0 = compiler.compileDouble(call.getArg(0)); 1855 final DoubleCalc calc1 = compiler.compileDouble(call.getArg(1)); 1856 return new AbstractBooleanCalc(call, new Calc[] {calc0, calc1}) { 1857 public boolean evaluateBoolean(Evaluator evaluator) { 1858 final double v0 = calc0.evaluateDouble(evaluator); 1859 final double v1 = calc1.evaluateDouble(evaluator); 1860 if (v0 == Double.NaN || v1 == Double.NaN || v0 == DoubleNull || v1 == DoubleNull) { 1861 return BooleanNull; 1862 } 1863 return v0 > v1; 1864 } 1865 }; 1866 } 1867 }); 1868 1869 define(new FunDefBase( 1870 ">", 1871 "<String Expression> > <String Expression>", 1872 "Returns whether an expression is greater than another.", 1873 "ibSS") { 1874 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1875 final StringCalc calc0 = compiler.compileString(call.getArg(0)); 1876 final StringCalc calc1 = compiler.compileString(call.getArg(1)); 1877 return new AbstractBooleanCalc(call, new Calc[] {calc0, calc1}) { 1878 public boolean evaluateBoolean(Evaluator evaluator) { 1879 final String b0 = calc0.evaluateString(evaluator); 1880 final String b1 = calc1.evaluateString(evaluator); 1881 if (b0 == null || b1 == null) { 1882 return BooleanNull; 1883 } 1884 return b0.compareTo(b1) > 0; 1885 } 1886 }; 1887 } 1888 }); 1889 1890 define(new FunDefBase( 1891 ">=", 1892 "<Numeric Expression> >= <Numeric Expression>", 1893 "Returns whether an expression is greater than or equal to another.", 1894 "ibnn") { 1895 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1896 final DoubleCalc calc0 = compiler.compileDouble(call.getArg(0)); 1897 final DoubleCalc calc1 = compiler.compileDouble(call.getArg(1)); 1898 return new AbstractBooleanCalc(call, new Calc[] {calc0, calc1}) { 1899 public boolean evaluateBoolean(Evaluator evaluator) { 1900 final double v0 = calc0.evaluateDouble(evaluator); 1901 final double v1 = calc1.evaluateDouble(evaluator); 1902 if (v0 == Double.NaN || v1 == Double.NaN || v0 == DoubleNull || v1 == DoubleNull) { 1903 return BooleanNull; 1904 } 1905 return v0 >= v1; 1906 } 1907 }; 1908 } 1909 }); 1910 1911 define(new FunDefBase( 1912 ">=", 1913 "<String Expression> >= <String Expression>", 1914 "Returns whether an expression is greater than or equal to another.", 1915 "ibSS") { 1916 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 1917 final StringCalc calc0 = compiler.compileString(call.getArg(0)); 1918 final StringCalc calc1 = compiler.compileString(call.getArg(1)); 1919 return new AbstractBooleanCalc(call, new Calc[] {calc0, calc1}) { 1920 public boolean evaluateBoolean(Evaluator evaluator) { 1921 final String b0 = calc0.evaluateString(evaluator); 1922 final String b1 = calc1.evaluateString(evaluator); 1923 if (b0 == null || b1 == null) { 1924 return BooleanNull; 1925 } 1926 return b0.compareTo(b1) >= 0; 1927 } 1928 }; 1929 } 1930 }); 1931 1932 1934 define(NthQuartileFunDef.FirstQResolver); 1935 1936 define(NthQuartileFunDef.ThirdQResolver); 1937 1938 define(CalculatedChildFunDef.instance); 1939 1940 define(CastFunDef.Resolver); 1941 } 1942 1943 1944 public static BuiltinFunTable instance() { 1945 if (instance == null) { 1946 instance = new BuiltinFunTable(); 1947 instance.init(); 1948 } 1949 return instance; 1950 } 1951 1952 protected Member[] getNonEmptyMemberChildren(Evaluator evaluator, Member member) { 1953 SchemaReader sr = evaluator.getSchemaReader(); 1954 if (evaluator.isNonEmpty()) { 1955 return sr.getMemberChildren(member, evaluator); 1956 } else { 1957 return sr.getMemberChildren(member); 1958 } 1959 } 1960 1961 1965 protected static Member[] getNonEmptyLevelMembers( 1966 Evaluator evaluator, 1967 Level level) { 1968 SchemaReader sr = evaluator.getSchemaReader(); 1969 if (evaluator.isNonEmpty()) { 1970 final Member[] members = sr.getLevelMembers(level, evaluator); 1971 return Util.addLevelCalculatedMembers(sr, level, members); 1972 } 1973 return sr.getLevelMembers(level, true); 1974 } 1975 1976 static List<Member> levelMembers( 1977 Level level, 1978 Evaluator evaluator, 1979 final boolean includeCalcMembers) { 1980 Member[] members = getNonEmptyLevelMembers(evaluator, level); 1981 List<Member> memberList = 1982 new ArrayList<Member>(Arrays.asList(members)); 1983 if (!includeCalcMembers) { 1984 FunUtil.removeCalculatedMembers(memberList); 1985 } 1986 FunUtil.hierarchize(memberList, false); 1987 return memberList; 1988 } 1989 1990 static List<Member> hierarchyMembers( 1991 Hierarchy hierarchy, 1992 Evaluator evaluator, 1993 final boolean includeCalcMembers) { 1994 final List<Member> memberList; 1995 if (evaluator.isNonEmpty()) { 1996 memberList = new ArrayList<Member>(); 1999 for (Level level : hierarchy.getLevels()) { 2000 Member[] members = getNonEmptyLevelMembers(evaluator, level); 2001 memberList.addAll(Arrays.asList(members)); 2002 } 2003 } else { 2004 memberList = FunUtil.addMembers( 2005 evaluator.getSchemaReader(), 2006 new ArrayList<Member>(), hierarchy); 2007 if (!includeCalcMembers && memberList != null) { 2008 FunUtil.removeCalculatedMembers(memberList); 2009 } 2010 } 2011 FunUtil.hierarchize(memberList, false); 2012 return memberList; 2013 } 2014 2015 static List<Member> dimensionMembers( 2016 Dimension dimension, 2017 Evaluator evaluator, 2018 final boolean includeCalcMembers) { 2019 Hierarchy hierarchy = dimension.getHierarchy(); 2020 return hierarchyMembers(hierarchy, evaluator, includeCalcMembers); 2021 } 2022} 2023 2024 | Popular Tags |