1 11 package mondrian.olap.fun; 12 13 import mondrian.calc.*; 14 import mondrian.calc.ExpCompiler.ResultStyle; 15 import mondrian.calc.impl.AbstractIterCalc; 16 import mondrian.calc.impl.AbstractListCalc; 17 import mondrian.mdx.MdxVisitorImpl; 18 import mondrian.mdx.ResolvedFunCall; 19 import mondrian.olap.*; 20 import mondrian.olap.type.SetType; 21 import mondrian.olap.type.TupleType; 22 import mondrian.olap.type.Type; 23 import mondrian.resource.MondrianResource; 24 import mondrian.util.Bug; 25 import mondrian.util.UnsupportedList; 26 27 import java.util.*; 28 29 36 class CrossJoinFunDef extends FunDefBase { 37 static final ReflectiveMultiResolver Resolver = new ReflectiveMultiResolver( 38 "Crossjoin", 39 "Crossjoin(<Set1>, <Set2>)", 40 "Returns the cross product of two sets.", 41 new String []{"fxxx"}, 42 CrossJoinFunDef.class); 43 44 static final StarCrossJoinResolver StarResolver = new StarCrossJoinResolver(); 45 46 private static int counterTag = 0; 47 48 private final int ctag = counterTag++; 50 51 public CrossJoinFunDef(FunDef dummyFunDef) { 52 super(dummyFunDef); 53 } 54 55 public Type getResultType(Validator validator, Exp[] args) { 56 List<Type> list = new ArrayList<Type>(); 58 for (Exp arg : args) { 59 final Type type = arg.getType(); 60 if (type instanceof SetType) { 61 addTypes(type, list); 62 } else if (getName().equals("*")) { 63 addTypes(type, list); 66 } else { 67 throw Util.newInternal("arg to crossjoin must be a set"); 68 } 69 } 70 final Type[] types = list.toArray(new Type[list.size()]); 71 final TupleType tupleType = new TupleType(types); 72 return new SetType(tupleType); 73 } 74 75 79 private static void addTypes(final Type type, List<Type> list) { 80 if (type instanceof SetType) { 81 SetType setType = (SetType) type; 82 addTypes(setType.getElementType(), list); 83 } else if (type instanceof TupleType) { 84 TupleType tupleType = (TupleType) type; 85 for (Type elementType : tupleType.elementTypes) { 86 addTypes(elementType, list); 87 } 88 } else { 89 list.add(type); 90 } 91 } 92 public Calc compileCall(final ResolvedFunCall call, ExpCompiler compiler) { 93 ResultStyle[] rs = compiler.getAcceptableResultStyles(); 94 for (ResultStyle r : rs) { 96 switch (r) { 97 case ITERABLE: 98 case ANY: 99 return compileCallIterable(call, compiler); 101 case LIST: 102 return compileCallImmutableList(call, compiler); 104 case MUTABLE_LIST: 105 return compileCallMutableList(call, compiler); 107 } 108 } 109 throw ResultStyleException.generate( 110 new ResultStyle[] { 111 ResultStyle.ITERABLE, 112 ResultStyle.LIST, 113 ResultStyle.MUTABLE_LIST, 114 ResultStyle.ANY 115 }, 116 rs 117 ); 118 } 119 120 126 protected IterCalc compileCallIterable( 127 final ResolvedFunCall call, 128 ExpCompiler compiler) 129 { 130 final Calc calc1 = toIter(compiler, call.getArg(0)); 131 final Calc calc2 = toIter(compiler, call.getArg(1)); 132 Calc[] calcs = new Calc[] {calc1, calc2}; 133 138 checkIterListResultStyles(calc1); 140 checkIterListResultStyles(calc2); 141 142 if (isMemberType(calc1)) { 143 if (isMemberType(calc2)) { 145 if (calc1.getResultStyle() == ResultStyle.ITERABLE) { 147 if (calc2.getResultStyle() == ResultStyle.ITERABLE) { 148 return new IterMemberIterMemberIterCalc(call, calcs); 149 } else { 150 return new IterMemberListMemberIterCalc(call, calcs); 151 } 152 } else { 153 if (calc2.getResultStyle() == ResultStyle.ITERABLE) { 154 return new ListMemberIterMemberIterCalc(call, calcs); 155 } else { 156 return new ListMemberListMemberIterCalc(call, calcs); 157 } 158 } 159 } else { 160 if (calc1.getResultStyle() == ResultStyle.ITERABLE) { 162 if (calc2.getResultStyle() == ResultStyle.ITERABLE) { 163 return new IterMemberIterMemberArrayIterCalc(call, calcs); 164 } else { 165 return new IterMemberListMemberArrayIterCalc(call, calcs); 166 } 167 } else { 168 if (calc2.getResultStyle() == ResultStyle.ITERABLE) { 169 return new ListMemberIterMemberArrayIterCalc(call, calcs); 170 } else { 171 return new ListMemberListMemberArrayIterCalc(call, calcs); 172 } 173 } 174 } 175 } else { 176 if (isMemberType(calc2)) { 178 if (calc1.getResultStyle() == ResultStyle.ITERABLE) { 180 if (calc2.getResultStyle() == ResultStyle.ITERABLE) { 181 return new IterMemberArrayIterMemberIterCalc(call, calcs); 182 } else { 183 return new IterMemberArrayListMemberIterCalc(call, calcs); 184 } 185 } else { 186 if (calc2.getResultStyle() == ResultStyle.ITERABLE) { 187 return new ListMemberArrayIterMemberIterCalc(call, calcs); 188 } else { 189 return new ListMemberArrayListMemberIterCalc(call, calcs); 190 } 191 } 192 } else { 193 if (calc1.getResultStyle() == ResultStyle.ITERABLE) { 195 if (calc2.getResultStyle() == ResultStyle.ITERABLE) { 196 return new IterMemberArrayIterMemberArrayIterCalc(call, calcs); 197 } else { 198 return new IterMemberArrayListMemberArrayIterCalc(call, calcs); 199 } 200 } else { 201 if (calc2.getResultStyle() == ResultStyle.ITERABLE) { 202 return new ListMemberArrayIterMemberArrayIterCalc(call, calcs); 203 } else { 204 return new ListMemberArrayListMemberArrayIterCalc(call, calcs); 205 } 206 } 207 } 208 } 209 } 210 private Calc toIter(ExpCompiler compiler, final Exp exp) { 211 final Type type = exp.getType(); 215 if (type instanceof SetType) { 216 return compiler.compile(exp, 218 ExpCompiler.ITERABLE_LIST_MUTABLE_LIST_RESULT_STYLE_ARRAY); 219 } else { 220 return new SetFunDef.IterSetCalc( 222 new DummyExp(new SetType(type)), 223 new Exp[] {exp}, 224 compiler, 225 ExpCompiler.ITERABLE_LIST_MUTABLE_LIST_RESULT_STYLE_ARRAY); 226 } 227 } 228 private abstract class BaseIterCalc extends AbstractIterCalc { 229 protected BaseIterCalc(ResolvedFunCall call, Calc[] calcs) { 230 super(call, calcs); 231 } 232 public Iterable evaluateIterable(Evaluator evaluator) { 233 ResolvedFunCall call = (ResolvedFunCall) exp; 234 SchemaReader schemaReader = evaluator.getSchemaReader(); 237 NativeEvaluator nativeEvaluator = 238 schemaReader.getNativeSetEvaluator( 239 call.getFunDef(), call.getArgs(), evaluator, this); 240 if (nativeEvaluator != null) { 241 return (Iterable ) nativeEvaluator.execute( 242 ResultStyle.ITERABLE); 243 } 244 245 Calc[] calcs = getCalcs(); 246 Calc calc1 = calcs[0]; 247 Calc calc2 = calcs[1]; 248 249 Evaluator oldEval = null; 250 assert (oldEval = evaluator.push()) != null; 251 252 Object o1 = calc1.evaluate(evaluator); 253 assert oldEval.equals(evaluator) : "calc1 changed context"; 254 255 if (o1 instanceof List) { 256 List l1 = (List) o1; 257 l1 = nonEmptyOptimizeList(evaluator, l1, call); 259 if (l1.isEmpty()) { 260 return Collections.EMPTY_LIST; 261 } 262 o1 = l1; 263 } 264 265 Object o2 = calc2.evaluate(evaluator); 266 assert oldEval.equals(evaluator) : "calc2 changed context"; 267 268 if (o2 instanceof List) { 269 List l2 = (List) o2; 270 l2 = nonEmptyOptimizeList(evaluator, l2, call); 272 if (l2.isEmpty()) { 273 return Collections.EMPTY_LIST; 274 } 275 o2 = l2; 276 } 277 278 return makeIterable(o1, o2); 279 } 280 281 293 protected abstract Iterable <Member[]> makeIterable(Object o1, Object o2); 294 295 303 protected abstract Member[] makeNext(Object o1, Object o2); 304 305 protected Iterable <Member[]> makeIterableIterable( 306 final Iterable it1, 307 final Iterable it2) 308 { 309 Iterable <Member[]> iterable = new Iterable <Member[]>() { 314 public Iterator<Member[]> iterator() { 315 return new Iterator<Member[]>() { 316 Iterator i1 = it1.iterator(); 317 Object o1 = null; 318 Iterator i2 = it2.iterator(); 319 Object o2 = null; 320 public boolean hasNext() { 321 if (o2 != null) { 322 return true; 323 } 324 if (! hasNextO1()) { 325 return false; 326 } 327 if (! hasNextO2()) { 328 o1 = null; 329 if (! hasNextO1()) { 331 return false; 332 } 333 i2 = it2.iterator(); 335 if (! hasNextO2()) { 336 return false; 337 } 338 } 339 return true; 340 } 341 public Member[] next() { 342 try { 343 return makeNext(o1, o2); 344 } finally { 345 o2 = null; 346 } 347 } 348 public void remove() { 349 throw new UnsupportedOperationException ("remove"); 350 } 351 352 private boolean hasNextO1() { 353 while (o1 == null) { 354 if (! i1.hasNext()) { 355 return false; 356 } 357 o1 = i1.next(); 358 } 359 return true; 360 } 361 private boolean hasNextO2() { 362 o2 = null; 363 while (o2 == null) { 364 if (! i2.hasNext()) { 365 return false; 366 } 367 o2 = i2.next(); 368 } 369 return true; 370 } 371 }; 372 } 373 }; 374 375 return iterable; 376 } 377 378 protected Iterable <Member[]> makeIterableList( 379 final Iterable it1, 380 final List l2) 381 { 382 Iterable <Member[]> iterable = new Iterable <Member[]>() { 383 public Iterator<Member[]> iterator() { 384 return new Iterator<Member[]>() { 385 Iterator i1 = it1.iterator(); 386 Object o1 = null; 387 int index2 = 0; 388 Object o2 = null; 389 public boolean hasNext() { 390 if (o2 != null) { 391 return true; 392 } 393 if (! hasNextO1()) { 394 return false; 395 } 396 if (! hasNextO2()) { 397 o1 = null; 398 if (! hasNextO1()) { 400 return false; 401 } 402 index2 = 0; 404 if (! hasNextO2()) { 405 return false; 406 } 407 } 408 return true; 409 } 410 public Member[] next() { 411 try { 412 return makeNext(o1, o2); 413 } finally { 414 o2 = null; 415 } 416 } 417 public void remove() { 418 throw new UnsupportedOperationException ("remove"); 419 } 420 421 private boolean hasNextO1() { 422 while (o1 == null) { 423 if (! i1.hasNext()) { 424 return false; 425 } 426 o1 = i1.next(); 427 } 428 return true; 429 } 430 private boolean hasNextO2() { 431 o2 = null; 432 while (o2 == null) { 433 if (index2 == l2.size()) { 434 return false; 435 } 436 o2 = l2.get(index2++); 437 } 438 return true; 439 } 440 }; 441 } 442 }; 443 return iterable; 444 } 445 446 protected Iterable <Member[]> makeListIterable( 447 final List l1, 448 final Iterable it2) 449 { 450 Iterable <Member[]> iterable = new Iterable <Member[]>() { 451 public Iterator<Member[]> iterator() { 452 return new Iterator<Member[]>() { 453 int index1 = 0; 454 Object o1 = null; 455 Iterator i2 = it2.iterator(); 456 Object o2 = null; 457 public boolean hasNext() { 458 if (o2 != null) { 459 return true; 460 } 461 if (! hasNextO1()) { 462 return false; 463 } 464 if (! hasNextO2()) { 465 o1 = null; 466 if (! hasNextO1()) { 468 return false; 469 } 470 i2 = it2.iterator(); 472 if (! hasNextO2()) { 473 return false; 474 } 475 } 476 return true; 477 } 478 public Member[] next() { 479 try { 480 return makeNext(o1, o2); 481 } finally { 482 o2 = null; 483 } 484 } 485 public void remove() { 486 throw new UnsupportedOperationException ("remove"); 487 } 488 489 private boolean hasNextO1() { 490 while (o1 == null) { 491 if (index1 == l1.size()) { 492 return false; 493 } 494 o1 = l1.get(index1++); 495 } 496 return true; 497 } 498 private boolean hasNextO2() { 499 o2 = null; 500 while (o2 == null) { 501 if (! i2.hasNext()) { 502 return false; 503 } 504 o2 = i2.next(); 505 } 506 return true; 507 } 508 }; 509 } 510 }; 511 512 return iterable; 513 } 514 515 protected Iterable <Member[]> makeListList( 516 final List l1, 517 final List l2) 518 { 519 Iterable <Member[]> iterable = new Iterable <Member[]>() { 520 public Iterator<Member[]> iterator() { 521 return new Iterator<Member[]>() { 522 int index1 = 0; 523 Object o1 = null; 524 int index2 = 0; 525 Object o2 = null; 526 public boolean hasNext() { 527 if (o2 != null) { 528 return true; 529 } 530 if (! hasNextO1()) { 531 return false; 532 } 533 if (! hasNextO2()) { 534 o1 = null; 535 if (! hasNextO1()) { 537 return false; 538 } 539 index2 = 0; 541 if (! hasNextO2()) { 542 return false; 543 } 544 } 545 return true; 546 } 547 public Member[] next() { 548 try { 549 return makeNext(o1, o2); 550 } finally { 551 o2 = null; 552 } 553 } 554 public void remove() { 555 throw new UnsupportedOperationException ("remove"); 556 } 557 558 private boolean hasNextO1() { 559 while (o1 == null) { 560 if (index1 == l1.size()) { 561 return false; 562 } 563 o1 = l1.get(index1++); 564 } 565 return true; 566 } 567 private boolean hasNextO2() { 568 o2 = null; 569 while (o2 == null) { 570 if (index2 == l2.size()) { 571 return false; 572 } 573 o2 = l2.get(index2++); 574 } 575 return true; 576 } 577 }; 578 } 579 }; 580 return iterable; 581 } 582 } 583 584 586 abstract class BaseMemberMemberIterCalc 588 extends BaseIterCalc { 589 BaseMemberMemberIterCalc(ResolvedFunCall call, Calc[] calcs) { 590 super(call, calcs); 591 } 592 protected Member[] makeNext(Object o1, Object o2) { 593 return new Member[] {(Member) o1, (Member) o2}; 594 } 595 } 596 597 abstract class BaseMemberMemberArrayIterCalc 599 extends BaseIterCalc { 600 BaseMemberMemberArrayIterCalc(ResolvedFunCall call, Calc[] calcs) { 601 super(call, calcs); 602 } 603 protected Member[] makeNext(Object o1, Object o2) { 604 Member m1 = (Member) o1; 605 Member[] ma2 = (Member[]) o2; 606 Member[] ma = new Member[ma2.length+1]; 607 ma[0] = m1; 608 System.arraycopy(ma2, 0, ma, 1, ma2.length); 609 return ma; 610 } 611 } 612 613 abstract class BaseMemberArrayMemberIterCalc 615 extends BaseIterCalc { 616 BaseMemberArrayMemberIterCalc(ResolvedFunCall call, Calc[] calcs) { 617 super(call, calcs); 618 } 619 protected Member[] makeNext(Object o1, Object o2) { 620 Member[] ma1 = (Member[]) o1; 621 Member m2 = (Member) o2; 622 Member[] ma = new Member[ma1.length+1]; 623 System.arraycopy(ma1, 0, ma, 0, ma1.length); 624 ma[ma1.length] = m2; 625 return ma; 626 } 627 } 628 629 abstract class BaseMemberArrayMemberArrayIterCalc 631 extends BaseIterCalc { 632 BaseMemberArrayMemberArrayIterCalc(ResolvedFunCall call, Calc[] calcs) { 633 super(call, calcs); 634 } 635 protected Member[] makeNext(Object o1, Object o2) { 636 Member[] ma1 = (Member[]) o1; 637 Member[] ma2 = (Member[]) o2; 638 Member[] ma = new Member[ma1.length+ma2.length]; 639 System.arraycopy(ma1, 0, ma, 0, ma1.length); 640 System.arraycopy(ma2, 0, ma, ma1.length, ma2.length); 641 return ma; 642 } 643 } 644 645 647 class IterMemberIterMemberIterCalc 649 extends BaseMemberMemberIterCalc { 650 IterMemberIterMemberIterCalc(ResolvedFunCall call, Calc[] calcs) { 651 super(call, calcs); 652 } 653 protected Iterable <Member[]> makeIterable(Object o1, Object o2) { 654 Iterable <Member> it1 = (Iterable <Member>) o1; 655 Iterable <Member> it2 = (Iterable <Member>) o2; 656 return makeIterableIterable(it1, it2); 657 } 658 } 659 660 class IterMemberListMemberIterCalc 662 extends BaseMemberMemberIterCalc { 663 IterMemberListMemberIterCalc(ResolvedFunCall call, Calc[] calcs) { 664 super(call, calcs); 665 } 666 protected Iterable <Member[]> makeIterable(Object o1, Object o2) { 667 Iterable <Member> it1 = (Iterable <Member>) o1; 668 List<Member> l2 = (List<Member>) o2; 669 670 if (l2 instanceof RandomAccess) { 671 return makeIterableList(it1, l2); 673 } else { 674 return makeIterableIterable(it1, l2); 676 } 677 } 678 } 679 class ListMemberIterMemberIterCalc 681 extends BaseMemberMemberIterCalc { 682 ListMemberIterMemberIterCalc(ResolvedFunCall call, Calc[] calcs) { 683 super(call, calcs); 684 } 685 protected Iterable <Member[]> makeIterable(Object o1, Object o2) { 686 List<Member> l1 = (List<Member>) o1; 687 Iterable <Member> it2 = (Iterable <Member>) o2; 688 689 if (l1 instanceof RandomAccess) { 690 return makeListIterable(l1, it2); 692 } else { 693 return makeIterableIterable(l1, it2); 695 } 696 } 697 } 698 699 class ListMemberListMemberIterCalc 701 extends BaseMemberMemberIterCalc { 702 ListMemberListMemberIterCalc(ResolvedFunCall call, Calc[] calcs) { 703 super(call, calcs); 704 } 705 protected Iterable <Member[]> makeIterable(Object o1, Object o2) { 706 List<Member> l1 = (List<Member>) o1; 707 List<Member> l2 = (List<Member>) o2; 708 709 if (l1 instanceof RandomAccess) { 710 if (l2 instanceof RandomAccess) { 712 return makeListList(l1, l2); 714 } else { 715 return makeListIterable(l1, l2); 717 } 718 } else { 719 if (l2 instanceof RandomAccess) { 721 return makeIterableList(l1, l2); 723 } else { 724 return makeIterableIterable(l1, l2); 726 } 727 } 728 } 729 } 730 731 733 class IterMemberIterMemberArrayIterCalc 735 extends BaseMemberMemberArrayIterCalc { 736 IterMemberIterMemberArrayIterCalc(ResolvedFunCall call, Calc[] calcs) { 737 super(call, calcs); 738 } 739 protected Iterable <Member[]> makeIterable(Object o1, Object o2) { 740 Iterable <Member> it1 = (Iterable <Member>) o1; 741 Iterable <Member[]> it2 = (Iterable <Member[]>) o2; 742 return makeIterableIterable(it1, it2); 743 } 744 } 745 746 class IterMemberListMemberArrayIterCalc 748 extends BaseMemberMemberArrayIterCalc { 749 IterMemberListMemberArrayIterCalc(ResolvedFunCall call, Calc[] calcs) { 750 super(call, calcs); 751 } 752 protected Iterable <Member[]> makeIterable(Object o1, Object o2) { 753 Iterable <Member> it1 = (Iterable <Member>) o1; 754 List<Member[]> l2 = (List<Member[]>) o2; 755 756 if (l2 instanceof RandomAccess) { 757 return makeIterableList(it1, l2); 759 } else { 760 return makeIterableIterable(it1, l2); 762 } 763 } 764 } 765 766 class ListMemberIterMemberArrayIterCalc 768 extends BaseMemberMemberArrayIterCalc { 769 ListMemberIterMemberArrayIterCalc(ResolvedFunCall call, Calc[] calcs) { 770 super(call, calcs); 771 } 772 protected Iterable <Member[]> makeIterable(Object o1, Object o2) { 773 List<Member> l1 = (List<Member>) o1; 774 Iterable <Member[]> it2 = (Iterable <Member[]>) o2; 775 776 if (l1 instanceof RandomAccess) { 777 return makeListIterable(l1, it2); 779 } else { 780 return makeIterableIterable(l1, it2); 782 } 783 } 784 } 785 786 class ListMemberListMemberArrayIterCalc 788 extends BaseMemberMemberArrayIterCalc { 789 ListMemberListMemberArrayIterCalc(ResolvedFunCall call, Calc[] calcs) { 790 super(call, calcs); 791 } 792 protected Iterable <Member[]> makeIterable(Object o1, Object o2) { 793 List<Member> l1 = (List<Member>) o1; 794 List<Member[]> l2 = (List<Member[]>) o2; 795 796 if (l1 instanceof RandomAccess) { 797 if (l2 instanceof RandomAccess) { 799 return makeListList(l1, l2); 801 } else { 802 return makeListIterable(l1, l2); 804 } 805 } else { 806 if (l2 instanceof RandomAccess) { 808 return makeIterableList(l1, l2); 810 } else { 811 return makeIterableIterable(l1, l2); 813 } 814 } 815 } 816 } 817 818 820 class IterMemberArrayIterMemberIterCalc 822 extends BaseMemberArrayMemberIterCalc { 823 IterMemberArrayIterMemberIterCalc(ResolvedFunCall call, Calc[] calcs) { 824 super(call, calcs); 825 } 826 protected Iterable <Member[]> makeIterable(Object o1, Object o2) { 827 Iterable <Member[]> it1 = (Iterable <Member[]>) o1; 828 Iterable <Member> it2 = (Iterable <Member>) o2; 829 return makeIterableIterable(it1, it2); 830 } 831 } 832 833 class IterMemberArrayListMemberIterCalc 835 extends BaseMemberArrayMemberIterCalc { 836 IterMemberArrayListMemberIterCalc(ResolvedFunCall call, Calc[] calcs) { 837 super(call, calcs); 838 } 839 protected Iterable <Member[]> makeIterable(Object o1, Object o2) { 840 Iterable <Member[]> it1 = (Iterable <Member[]>) o1; 841 List<Member> l2 = (List<Member>) o2; 842 843 if (l2 instanceof RandomAccess) { 844 return makeIterableList(it1, l2); 846 } else { 847 return makeIterableIterable(it1, l2); 849 } 850 } 851 } 852 853 class ListMemberArrayIterMemberIterCalc 855 extends BaseMemberArrayMemberIterCalc { 856 ListMemberArrayIterMemberIterCalc(ResolvedFunCall call, Calc[] calcs) { 857 super(call, calcs); 858 } 859 protected Iterable <Member[]> makeIterable(Object o1, Object o2) { 860 List<Member[]> l1 = (List<Member[]>) o1; 861 Iterable <Member> it2 = (Iterable <Member>) o2; 862 863 if (l1 instanceof RandomAccess) { 864 return makeListIterable(l1, it2); 866 } else { 867 return makeIterableIterable(l1, it2); 869 } 870 } 871 } 872 873 class ListMemberArrayListMemberIterCalc 875 extends BaseMemberArrayMemberIterCalc { 876 ListMemberArrayListMemberIterCalc(ResolvedFunCall call, Calc[] calcs) { 877 super(call, calcs); 878 } 879 protected Iterable <Member[]> makeIterable(Object o1, Object o2) { 880 List<Member[]> l1 = (List<Member[]>) o1; 881 List<Member> l2 = (List<Member>) o2; 882 883 if (l1 instanceof RandomAccess) { 884 if (l2 instanceof RandomAccess) { 886 return makeListList(l1, l2); 888 } else { 889 return makeListIterable(l1, l2); 891 } 892 } else { 893 if (l2 instanceof RandomAccess) { 895 return makeIterableList(l1, l2); 897 } else { 898 return makeIterableIterable(l1, l2); 900 } 901 } 902 } 903 } 904 905 907 class IterMemberArrayIterMemberArrayIterCalc 909 extends BaseMemberArrayMemberArrayIterCalc { 910 IterMemberArrayIterMemberArrayIterCalc(ResolvedFunCall call, Calc[] calcs) { 911 super(call, calcs); 912 } 913 protected Iterable <Member[]> makeIterable(Object o1, Object o2) { 914 Iterable <Member[]> it1 = (Iterable <Member[]>) o1; 915 Iterable <Member[]> it2 = (Iterable <Member[]>) o2; 916 return makeIterableIterable(it1, it2); 917 } 918 } 919 920 class IterMemberArrayListMemberArrayIterCalc 922 extends BaseMemberArrayMemberArrayIterCalc { 923 IterMemberArrayListMemberArrayIterCalc(ResolvedFunCall call, Calc[] calcs) { 924 super(call, calcs); 925 } 926 protected Iterable <Member[]> makeIterable(Object o1, Object o2) { 927 Iterable <Member[]> it1 = (Iterable <Member[]>) o1; 928 List<Member[]> l2 = (List<Member[]>) o2; 929 930 if (l2 instanceof RandomAccess) { 931 return makeIterableList(it1, l2); 933 } else { 934 return makeIterableIterable(it1, l2); 936 } 937 } 938 } 939 940 class ListMemberArrayIterMemberArrayIterCalc 942 extends BaseMemberArrayMemberArrayIterCalc { 943 ListMemberArrayIterMemberArrayIterCalc(ResolvedFunCall call, Calc[] calcs) { 944 super(call, calcs); 945 } 946 protected Iterable <Member[]> makeIterable(Object o1, Object o2) { 947 List<Member[]> l1 = (List<Member[]>) o1; 948 Iterable <Member[]> it2 = (Iterable <Member[]>) o2; 949 950 if (l1 instanceof RandomAccess) { 951 return makeListIterable(l1, it2); 953 } else { 954 return makeIterableIterable(l1, it2); 956 } 957 } 958 } 959 960 class ListMemberArrayListMemberArrayIterCalc 962 extends BaseMemberArrayMemberArrayIterCalc { 963 ListMemberArrayListMemberArrayIterCalc(ResolvedFunCall call, Calc[] calcs) { 964 super(call, calcs); 965 } 966 protected Iterable <Member[]> makeIterable(Object o1, Object o2) { 967 List<Member[]> l1 = (List<Member[]>) o1; 968 List<Member[]> l2 = (List<Member[]>) o2; 969 970 if (l1 instanceof RandomAccess) { 971 if (l2 instanceof RandomAccess) { 973 return makeListList(l1, l2); 975 } else { 976 return makeListIterable(l1, l2); 978 } 979 } else { 980 if (l2 instanceof RandomAccess) { 982 return makeIterableList(l1, l2); 984 } else { 985 return makeIterableIterable(l1, l2); 987 } 988 } 989 } 990 } 991 992 998 protected ListCalc compileCallImmutableList(final ResolvedFunCall call, 999 ExpCompiler compiler) { 1000 final ListCalc listCalc1 = toList(compiler, call.getArg(0)); 1001 final ListCalc listCalc2 = toList(compiler, call.getArg(1)); 1002 Calc[] calcs = new Calc[] {listCalc1, listCalc2}; 1003 1010 checkListResultStyles(listCalc1); 1012 checkListResultStyles(listCalc2); 1013 1014 if (isMemberType(listCalc1)) { 1015 if (isMemberType(listCalc2)) { 1017 return new ImmutableListMemberListMemberListCalc(call, calcs); 1019 } else { 1020 return new ImmutableListMemberListMemberArrayListCalc(call, calcs); 1022 } 1023 } else { 1024 if (isMemberType(listCalc2)) { 1026 return new ImmutableListMemberArrayListMemberListCalc(call, calcs); 1028 } else { 1029 return new ImmutableListMemberArrayListMemberArrayListCalc(call, calcs); 1031 } 1032 } 1033 } 1034 1035 private ListCalc toList(ExpCompiler compiler, final Exp exp) { 1036 final Type type = exp.getType(); 1040 if (type instanceof SetType) { 1041 return (ListCalc) compiler.compile(exp, 1042 ExpCompiler.LIST_MUTABLE_LIST_RESULT_STYLE_ARRAY); 1043 } else { 1044 return new SetFunDef.ListSetCalc( 1045 new DummyExp(new SetType(type)), 1046 new Exp[] {exp}, 1047 compiler, 1048 ExpCompiler.LIST_MUTABLE_LIST_RESULT_STYLE_ARRAY 1049 ); 1050 } 1051 } 1052 1053 abstract class BaseListCalc extends AbstractListCalc { 1054 protected BaseListCalc(ResolvedFunCall call, 1055 Calc[] calcs, 1056 boolean mutable) { 1057 super(call, calcs, mutable); 1058 } 1059 public List<Member[]> evaluateList(Evaluator evaluator) { 1060 ResolvedFunCall call = (ResolvedFunCall) exp; 1061 SchemaReader schemaReader = evaluator.getSchemaReader(); 1064 NativeEvaluator nativeEvaluator = 1065 schemaReader.getNativeSetEvaluator( 1066 call.getFunDef(), call.getArgs(), evaluator, this); 1067 if (nativeEvaluator != null) { 1068 return (List) nativeEvaluator.execute( 1069 ResultStyle.LIST); 1070 } 1071 1072 Calc[] calcs = getCalcs(); 1073 ListCalc listCalc1 = (ListCalc) calcs[0]; 1074 ListCalc listCalc2 = (ListCalc) calcs[1]; 1075 1076 Evaluator oldEval = null; 1077 assert (oldEval = evaluator.push()) != null; 1078 1079 List l1 = listCalc1.evaluateList(evaluator); 1080 assert oldEval.equals(evaluator) : "listCalc1 changed context"; 1081 1082 List l2 = listCalc2.evaluateList(evaluator); 1083 assert oldEval.equals(evaluator) : "listCalc2 changed context"; 1084 1085 l1 = nonEmptyOptimizeList(evaluator, l1, call); 1087 if (l1.isEmpty()) { 1088 return Collections.EMPTY_LIST; 1089 } 1090 l2 = nonEmptyOptimizeList(evaluator, l2, call); 1092 if (l2.isEmpty()) { 1093 return Collections.EMPTY_LIST; 1094 } 1095 1096 return makeList(l1, l2); 1097 } 1098 1099 protected abstract List<Member[]> makeList(List l1, List l2); 1100 } 1101 1102 public abstract class BaseImmutableList 1103 extends UnsupportedList<Member[]> { 1104 protected BaseImmutableList() { 1105 } 1106 public abstract int size(); 1107 public abstract Member[] get(int index); 1108 1109 public Object [] toArray() { 1110 int size = size(); 1111 Object [] result = new Object [size]; 1112 for (int i = 0; i < size; i++) { 1113 result[i] = get(i); 1114 } 1115 return result; 1116 } 1117 public List<Member[]> toArrayList() { 1118 List<Member[]> l = new ArrayList<Member[]>(size()); 1119 Iterator i = iterator(); 1120 while (i.hasNext()) { 1121 l.add((Member[]) i.next()); 1122 } 1123 return l; 1124 } 1125 public ListIterator<Member[]> listIterator() { 1126 return new ListItr(0); 1127 } 1128 public ListIterator<Member[]> listIterator(int index) { 1129 return new ListItr(index); 1130 } 1131 public Iterator<Member[]> iterator() { 1132 return new Itr(); 1133 } 1134 } 1135 1136 class ImmutableListMemberListMemberListCalc 1138 extends BaseListCalc { 1139 ImmutableListMemberListMemberListCalc(ResolvedFunCall call, Calc[] calcs) { 1140 super(call, calcs, false); 1141 } 1142 protected List<Member[]> makeList(final List l1, final List l2) { 1143 final int size = l1.size() * l2.size(); 1144 class Outer extends BaseImmutableList { 1161 Outer() {} 1162 public int size() { 1163 return size; 1164 } 1165 public Member[] get(int index) { 1166 int i = (index / l2.size()); 1167 int j = (index % l2.size()); 1168 Member m1 = (Member) l1.get(i); 1169 Member m2 = (Member) l2.get(j); 1170 return new Member[] { m1, m2 }; 1171 } 1172 public List<Member[]> subList(int fromIndex, int toIndex) { 1173 class Inner extends Outer { 1174 int fromIndex; 1175 int toIndex; 1176 Inner(int fromIndex, int toIndex) { 1177 this.fromIndex = fromIndex; 1178 this.toIndex = toIndex; 1179 } 1180 public int size() { 1181 return (this.toIndex - this.fromIndex); 1182 } 1183 public Member[] get(int index) { 1184 return Outer.this.get(index + this.fromIndex); 1185 } 1186 public List<Member[]> subList(int fromIndex, int toIndex) { 1187 return new Inner(this.fromIndex+fromIndex, this.fromIndex+toIndex); 1188 } 1189 } 1190 return new Inner(fromIndex, toIndex); 1191 } 1192 }; 1193 return new Outer(); 1194 } 1195 } 1196 1197 class ImmutableListMemberListMemberArrayListCalc 1199 extends BaseListCalc { 1200 ImmutableListMemberListMemberArrayListCalc(ResolvedFunCall call, Calc[] calcs) { 1201 super(call, calcs, false); 1202 } 1203 protected List<Member[]> makeList(final List l1, final List l2) { 1204 final int len2 = ((Member[])l2.get(0)).length; 1205 final int size = (l1.size() * l2.size()); 1206 class Outer extends BaseImmutableList { 1207 Outer() {} 1208 public int size() { 1209 return size; 1210 } 1211 public Member[] get(int index) { 1212 int i = (index / l2.size()); 1213 int j = (index % l2.size()); 1214 Member[] ma = new Member[1 + len2]; 1215 Member m1 = (Member) l1.get(i); 1216 Member[] ma2 = (Member[]) l2.get(j); 1217 ma[0] = m1; 1218 System.arraycopy(ma2, 0, ma, 1, len2); 1219 return ma; 1220 } 1221 public List<Member[]> subList(int fromIndex, int toIndex) { 1222 class Inner extends Outer { 1223 int fromIndex; 1224 int toIndex; 1225 Inner(int fromIndex, int toIndex) { 1226 this.fromIndex = fromIndex; 1227 this.toIndex = toIndex; 1228 } 1229 public int size() { 1230 return (this.toIndex - this.fromIndex); 1231 } 1232 public Member[] get(int index) { 1233 return Outer.this.get(index + this.fromIndex); 1234 } 1235 public List<Member[]> subList(int fromIndex, int toIndex) { 1236 return new Inner(this.fromIndex+fromIndex, this.fromIndex+toIndex); 1237 } 1238 } 1239 return new Inner(fromIndex, toIndex); 1240 } 1241 }; 1242 return new Outer(); 1243 } 1244 } 1245 class ImmutableListMemberArrayListMemberListCalc 1247 extends BaseListCalc { 1248 ImmutableListMemberArrayListMemberListCalc(ResolvedFunCall call, Calc[] calcs) { 1249 super(call, calcs, false); 1250 } 1251 protected List<Member[]> makeList(final List l1, final List l2) { 1252 final int len1 = ((Member[])l1.get(0)).length; 1253 final int size = (l1.size() * l2.size()); 1254 class Outer extends BaseImmutableList { 1255 Outer() {} 1256 public int size() { 1257 return size; 1258 } 1259 public Member[] get(int index) { 1260 int i = (index / l2.size()); 1261 int j = (index % l2.size()); 1262 Member[] ma = new Member[len1 + 1]; 1263 Member[] ma1 = (Member[]) l1.get(i); 1264 Member m2 = (Member) l2.get(j); 1265 System.arraycopy(ma1, 0, ma, 0, len1); 1266 ma[len1] = m2; 1267 return ma; 1268 } 1269 public List<Member[]> subList(int fromIndex, int toIndex) { 1270 class Inner extends Outer { 1271 int fromIndex; 1272 int toIndex; 1273 Inner(int fromIndex, int toIndex) { 1274 this.fromIndex = fromIndex; 1275 this.toIndex = toIndex; 1276 } 1277 public int size() { 1278 return (this.toIndex - this.fromIndex); 1279 } 1280 public Member[] get(int index) { 1281 return Outer.this.get(index + this.fromIndex); 1282 } 1283 public List<Member[]> subList(int fromIndex, int toIndex) { 1284 return new Inner(this.fromIndex+fromIndex, this.fromIndex+toIndex); 1285 } 1286 } 1287 return new Inner(fromIndex, toIndex); 1288 } 1289 } 1290 return new Outer(); 1291 } 1292 } 1293 class ImmutableListMemberArrayListMemberArrayListCalc 1295 extends BaseListCalc { 1296 ImmutableListMemberArrayListMemberArrayListCalc(ResolvedFunCall call, Calc[] calcs) { 1297 super(call, calcs, false); 1298 } 1299 protected List<Member[]> makeList(final List l1, final List l2) { 1300 final int len1 = ((Member[])l1.get(0)).length; 1301 final int len2 = ((Member[])l2.get(0)).length; 1302 final int size = (l1.size() * l2.size()); 1303 1304 class Outer extends BaseImmutableList { 1305 Outer() {} 1306 public int size() { 1307 return size; 1308 } 1309 public Member[] get(int index) { 1310 int i = (index / l2.size()); 1311 int j = (index % l2.size()); 1312 Member[] ma = new Member[len1 + len2]; 1313 Member[] ma1 = (Member[]) l1.get(i); 1314 Member[] ma2 = (Member[]) l2.get(j); 1315 System.arraycopy(ma1, 0, ma, 0, len1); 1316 System.arraycopy(ma2, 0, ma, len1, len2); 1317 return ma; 1318 } 1319 public List<Member[]> subList(int fromIndex, int toIndex) { 1320 class Inner extends Outer { 1321 int fromIndex; 1322 int toIndex; 1323 Inner(int fromIndex, int toIndex) { 1324 this.fromIndex = fromIndex; 1325 this.toIndex = toIndex; 1326 } 1327 public int size() { 1328 return (this.toIndex - this.fromIndex); 1329 } 1330 public Member[] get(int index) { 1331 return Outer.this.get(index + this.fromIndex); 1332 } 1333 public List<Member[]> subList(int fromIndex, int toIndex) { 1334 return new Inner(this.fromIndex+fromIndex, this.fromIndex+toIndex); 1335 } 1336 } 1337 return new Inner(fromIndex, toIndex); 1338 } 1339 } 1340 return new Outer(); 1341 } 1342 } 1343 1344 1350 protected ListCalc compileCallMutableList(final ResolvedFunCall call, 1351 ExpCompiler compiler) { 1352 final ListCalc listCalc1 = toList(compiler, call.getArg(0)); 1353 final ListCalc listCalc2 = toList(compiler, call.getArg(1)); 1354 1355 Calc[] calcs = new Calc[] {listCalc1, listCalc2}; 1356 1364 checkListResultStyles(listCalc1); 1366 checkListResultStyles(listCalc2); 1367 1368 if (isMemberType(listCalc1)) { 1369 if (isMemberType(listCalc2)) { 1371 return new MutableListMemberListMemberListCalc(call, calcs); 1373 } else { 1374 return new MutableListMemberListMemberArrayListCalc(call, calcs); 1376 } 1377 } else { 1378 if (isMemberType(listCalc2)) { 1380 return new MutableListMemberArrayListMemberListCalc(call, calcs); 1382 } else { 1383 return new MutableListMemberArrayListMemberArrayListCalc(call, calcs); 1385 } 1386 } 1387 } 1388 1389 1394 public abstract class BaseMutableList 1395 extends UnsupportedList<Member[]> { 1396 protected final Member[] members; 1397 protected BaseMutableList(Member[] members) { 1398 this.members = members; 1399 } 1400 public abstract int size(); 1401 public abstract Member[] get(int index); 1402 public abstract Member[] set(int index, Member[] element); 1403 public abstract Member[] remove(int index); 1404 public abstract List<Member[]> subList(int fromIndex, int toIndex); 1405 1406 public Object [] toArray() { 1407 int size = size(); 1408 Object [] result = new Object [size]; 1409 for (int i = 0; i < size; i++) { 1410 result[i] = get(i); 1411 } 1412 return result; 1413 } 1414 public List<Member[]> toArrayList() { 1415 List<Member[]> l = new ArrayList<Member[]>(size()); 1416 Iterator i = iterator(); 1417 while (i.hasNext()) { 1418 l.add((Member[]) i.next()); 1419 } 1420 return l; 1421 } 1422 public ListIterator<Member[]> listIterator() { 1423 return new LocalListItr(0); 1424 } 1425 public ListIterator<Member[]> listIterator(int index) { 1426 return new LocalListItr(index); 1427 } 1428 public Iterator<Member[]> iterator() { 1429 return new LocalItr(); 1430 } 1431 private class LocalItr extends Itr { 1432 public LocalItr() { 1433 super(); 1434 } 1435 public void remove() { 1436 if (lastRet == -1) { 1437 throw new IllegalStateException (); 1438 } 1439 1441 try { 1442 CrossJoinFunDef.BaseMutableList.this.remove(lastRet); 1443 if (lastRet < cursor) { 1444 cursor--; 1445 } 1446 lastRet = -1; 1447 } catch(IndexOutOfBoundsException e) { 1449 throw new ConcurrentModificationException(); 1450 } 1451 } 1452 } 1453 private class LocalListItr extends ListItr { 1454 public LocalListItr(int index) { 1455 super(index); 1456 } 1457 public void set(Member[] o) { 1458 if (lastRet == -1) 1459 throw new IllegalStateException (); 1460 try { 1461 CrossJoinFunDef.BaseMutableList.this.set(lastRet, o); 1462 } catch(IndexOutOfBoundsException e) { 1463 throw new ConcurrentModificationException(); 1464 } 1465 } 1466 } 1467 1468 } 1469 1470 class MutableListMemberListMemberListCalc 1472 extends BaseListCalc { 1473 MutableListMemberListMemberListCalc(ResolvedFunCall call, Calc[] calcs) { 1474 super(call, calcs, true); 1475 } 1476 protected List<Member[]> makeList(final List l1, final List l2) { 1477 int size1 = l1.size(); 1478 int size2 = l2.size(); 1480 int arraySize = (2 * (size1 * size2)); 1482 1483 Member[] members = new Member[arraySize]; 1484 for (int i = 0; i < size1; i++) { 1485 Member m1 = (Member) l1.get(i); 1486 int ii = i*size2; 1487 for (int j = 0; j < size2; j++) { 1488 Member m2 = (Member) l2.get(j); 1489 members[2*(ii + j)] = m1; 1490 members[2*(ii + j)+1] = m2; 1491 } 1492 } 1493 return makeList(members); 1494 } 1495 protected List<Member[]> makeList(Member[] members) { 1496 List<Member[]> list = new BaseMutableList(members) { 1505 int size = members.length/2; 1506 public int size() { 1507 return size; 1508 } 1509 public Member[] get(int index) { 1510 int i = index+index; 1511 return new Member[] { members[i], members[i+1] }; 1512 } 1513 public Member[] set(int index, Member[] element) { 1514 int i = index+index; 1515 Member[] oldValue = 1516 new Member[] { members[i], members[i+1] }; 1517 1518 members[i] = element[0]; 1519 members[i+1] = element[1]; 1520 1521 return oldValue; 1522 } 1523 public Member[] remove(int index) { 1524 int i = index+index; 1525 Member[] oldValue = 1526 new Member[] { members[i], members[i+1] }; 1527 1528 System.arraycopy(members, i+2, members, i, 1529 members.length - (i+2)); 1530 1531 size--; 1532 return oldValue; 1533 } 1534 public List<Member[]> subList(int fromIndex, int toIndex) { 1535 int from = fromIndex + fromIndex; 1536 int to = toIndex + toIndex; 1537 Member[] sublist = new Member[to - from]; 1538 System.arraycopy(members, from, sublist, 0, to - from); 1539 return makeList(sublist); 1540 } 1541 }; 1542 return list; 1543 } 1544 } 1545 1546 class MutableListMemberListMemberArrayListCalc 1548 extends BaseListCalc { 1549 MutableListMemberListMemberArrayListCalc(ResolvedFunCall call, Calc[] calcs) { 1550 super(call, calcs, true); 1551 } 1552 protected List<Member[]> makeList(final List l1, final List l2) { 1553 int size1 = l1.size(); 1554 int size2 = l2.size(); 1556 int len2 = ((Member[])l2.get(0)).length; 1557 int totalLen = 1+len2; 1558 int arraySize = (totalLen * (size1 * size2)); 1559 1560 Member[] members = new Member[arraySize]; 1561 for (int i = 0; i < size1; i++) { 1562 Member m1 = (Member) l1.get(i); 1563 int ii = i*size2; 1564 for (int j = 0; j < size2; j++) { 1565 Member[] ma2 = (Member[]) l2.get(j); 1566 members[totalLen*(ii + j)] = m1; 1567 for (int k = 0; k < len2; k++) { 1568 Member m2 = (Member) ma2[k]; 1569 members[totalLen*(ii + j)+k+1] = m2; 1570 } 1571 } 1572 } 1573 1574 return makeList(members, totalLen); 1575 } 1576 protected List<Member[]> makeList(Member[] members, final int totalLen) { 1577 List<Member[]> list = new BaseMutableList(members) { 1589 int size = members.length/totalLen; 1590 public int size() { 1591 return size; 1592 } 1593 public Member[] get(int index) { 1594 int i = totalLen*index; 1595 Member[] ma = new Member[totalLen]; 1596 System.arraycopy(members, i, ma, 0, totalLen); 1597 return ma; 1598 } 1599 public Member[] set(int index, Member[] element) { 1600 int i = totalLen*index; 1601 Member[] oldValue = new Member[totalLen]; 1602 System.arraycopy(members, i, oldValue, 0, totalLen); 1603 1604 System.arraycopy(element, 0, members, i, totalLen); 1605 1606 return oldValue; 1607 } 1608 public Member[] remove(int index) { 1609 int i = totalLen*index; 1610 Member[] oldValue = new Member[totalLen]; 1611 System.arraycopy(members, i, oldValue, 0, totalLen); 1612 1613 System.arraycopy(members, i+totalLen, 1614 members, i, 1615 members.length-(i+totalLen)); 1616 1617 size--; 1618 return oldValue; 1619 } 1620 public List<Member[]> subList(int fromIndex, int toIndex) { 1621 int from = totalLen*fromIndex; 1622 int to = totalLen*toIndex; 1623 Member[] sublist = new Member[to - from]; 1624 System.arraycopy(members, from, sublist, 0, to - from); 1625 return makeList(sublist, totalLen); 1626 } 1627 }; 1628 return list; 1629 } 1630 } 1631 class MutableListMemberArrayListMemberListCalc 1633 extends BaseListCalc { 1634 MutableListMemberArrayListMemberListCalc(ResolvedFunCall call, Calc[] calcs) { 1635 super(call, calcs, true); 1636 } 1637 protected List<Member[]> makeList(final List l1, final List l2) { 1638 int size1 = l1.size(); 1639 int len1 = ((Member[])l1.get(0)).length; 1640 int size2 = l2.size(); 1641 int totalLen = 1+len1; 1643 int arraySize = (totalLen * (size1 * size2)); 1644 1645 Member[] members = new Member[arraySize]; 1646 for (int i = 0; i < size1; i++) { 1647 Member[] ma1 = (Member[]) l1.get(i); 1648 int ii = i*size2; 1649 for (int j = 0; j < size2; j++) { 1650 for (int k = 0; k < len1; k++) { 1651 Member m1 = (Member) ma1[k]; 1652 members[totalLen*(ii + j)+k] = m1; 1653 } 1654 Member m2 = (Member) l2.get(j); 1655 members[totalLen*(ii + j)+len1] = m2; 1656 } 1657 } 1658 1659 return makeList(members, totalLen); 1660 } 1661 protected List<Member[]> makeList(Member[] members, final int totalLen) { 1662 List<Member[]> list = new BaseMutableList(members) { 1674 int size = members.length/totalLen; 1675 public int size() { 1676 return size; 1677 } 1678 public Member[] get(int index) { 1679 int i = totalLen*index; 1680 Member[] ma = new Member[totalLen]; 1681 System.arraycopy(members, i, ma, 0, totalLen); 1682 return ma; 1683 } 1684 public Member[] set(int index, Member[] element) { 1685 int i = totalLen*index; 1686 Member[] oldValue = new Member[totalLen]; 1687 System.arraycopy(members, i, oldValue, 0, totalLen); 1688 1689 System.arraycopy(element, 0, members, i, totalLen); 1690 1691 return oldValue; 1692 } 1693 public Member[] remove(int index) { 1694 int i = totalLen*index; 1695 Member[] oldValue = new Member[totalLen]; 1696 System.arraycopy(members, i, oldValue, 0, totalLen); 1697 1698 System.arraycopy(members, i+totalLen, 1699 members, i, 1700 members.length-(i+totalLen)); 1701 1702 size--; 1703 return oldValue; 1704 } 1705 public List<Member[]> subList(int fromIndex, int toIndex) { 1706 int from = totalLen*fromIndex; 1707 int to = totalLen*toIndex; 1708 Member[] sublist = new Member[to - from]; 1709 System.arraycopy(members, from, sublist, 0, to - from); 1710 return makeList(sublist, totalLen); 1711 } 1712 }; 1713 return list; 1714 } 1715 } 1716 class MutableListMemberArrayListMemberArrayListCalc 1718 extends BaseListCalc { 1719 MutableListMemberArrayListMemberArrayListCalc(ResolvedFunCall call, Calc[] calcs) { 1720 super(call, calcs, true); 1721 } 1722 protected List<Member[]> makeList(final List l1, final List l2) { 1723 int size1 = l1.size(); 1724 int len1 = ((Member[])l1.get(0)).length; 1725 int size2 = l2.size(); 1726 int len2 = ((Member[])l2.get(0)).length; 1727 int totalLen = len1+len2; 1728 int arraySize = (totalLen * (size1 * size2)); 1729 1730 Member[] members = new Member[arraySize]; 1731 for (int i = 0; i < size1; i++) { 1732 Member[] ma1 = (Member[]) l1.get(i); 1733 int ii = i*size2; 1734 for (int j = 0; j < size2; j++) { 1735 for (int k = 0; k < len1; k++) { 1736 Member m1 = (Member) ma1[k]; 1737 members[totalLen*(ii + j)+k] = m1; 1738 } 1739 Member[] ma2 = (Member[]) l2.get(j); 1740 for (int k = 0; k < len2; k++) { 1741 Member m2 = (Member) ma2[k]; 1742 members[totalLen*(ii + j)+len1+k] = m2; 1743 } 1744 } 1745 } 1746 return makeList(members, totalLen); 1747 } 1748 protected List<Member[]> makeList(Member[] members, final int totalLen) { 1749 1750 List<Member[]> list = new BaseMutableList(members) { 1765 int size = members.length/totalLen; 1766 public int size() { 1767 return size; 1768 } 1769 public Member[] get(int index) { 1770 int i = totalLen*index; 1771 Member[] ma = new Member[totalLen]; 1772 System.arraycopy(members, i, ma, 0, totalLen); 1773 return ma; 1774 } 1775 public Member[] set(int index, Member[] element) { 1776 int i = totalLen*index; 1777 Member[] oldValue = new Member[totalLen]; 1778 System.arraycopy(members, i, oldValue, 0, totalLen); 1779 1780 System.arraycopy(element, 0, members, i, totalLen); 1781 1782 return oldValue; 1783 } 1784 1785 public Member[] remove(int index) { 1786 int i = totalLen*index; 1787 Member[] oldValue = new Member[totalLen]; 1788 System.arraycopy(members, i, oldValue, 0, totalLen); 1789 1790 System.arraycopy(members, i+totalLen, 1791 members, i, 1792 members.length-(i+totalLen)); 1793 1794 size--; 1795 return oldValue; 1796 } 1797 public List<Member[]> subList(int fromIndex, int toIndex) { 1798 int from = totalLen*fromIndex; 1799 int to = totalLen*toIndex; 1800 Member[] sublist = new Member[to - from]; 1801 System.arraycopy(members, from, sublist, 0, to - from); 1802 return makeList(sublist, totalLen); 1803 } 1804 }; 1805 return list; 1806 } 1807 } 1808 1809 1810 protected List nonEmptyOptimizeList( 1811 Evaluator evaluator, 1812 List list, 1813 ResolvedFunCall call) { 1814 1815 int opSize = MondrianProperties.instance().CrossJoinOptimizerSize.get(); 1816 int size = list.size(); 1817 1818 if (size > opSize && evaluator.isNonEmpty()) { 1819 final int missCount = evaluator.getMissCount(); 1823 1824 list = nonEmptyList(evaluator, list, call); 1825 size = list.size(); 1826 if (size == 0) { 1828 return Collections.EMPTY_LIST; 1829 } 1830 final int missCount2 = evaluator.getMissCount(); 1831 final int puntMissCountListSize = 1000; 1832 if (missCount2 > missCount && size > puntMissCountListSize) { 1833 return Collections.EMPTY_LIST; 1841 } 1842 } 1843 return list; 1844 } 1845 List crossJoin( 1846 List list1, 1847 List list2, 1848 Evaluator evaluator, 1849 ResolvedFunCall call) 1850 { 1851 if (list1.isEmpty() || list2.isEmpty()) { 1852 return Collections.EMPTY_LIST; 1853 } 1854 long size = (long)list1.size() * (long)list2.size(); 1857 int resultLimit = MondrianProperties.instance().ResultLimit.get(); 1858 1859 if (resultLimit > 0 && resultLimit < size) { 1865 throw MondrianResource.instance().LimitExceededDuringCrossjoin.ex( 1866 size, resultLimit); 1867 } 1868 1869 if (size > Integer.MAX_VALUE) { 1872 throw MondrianResource.instance().LimitExceededDuringCrossjoin.ex( 1873 size, Integer.MAX_VALUE); 1874 } 1875 1876 List<Member[]> result = new ArrayList<Member[]>((int) size); 1881 1882 boolean neitherSideIsTuple = true; 1883 int arity0 = 1; 1884 int arity1 = 1; 1885 if (list1.get(0) instanceof Member[]) { 1886 arity0 = ((Member[]) list1.get(0)).length; 1887 neitherSideIsTuple = false; 1888 } 1889 if (list2.get(0) instanceof Member[]) { 1890 arity1 = ((Member[]) list2.get(0)).length; 1891 neitherSideIsTuple = false; 1892 } 1893 1894 if (neitherSideIsTuple) { 1895 for (Member o0 : (List<Member>) list1) { 1897 for (Member o1 : (List<Member>) list2) { 1898 result.add(new Member[]{o0, o1}); 1899 } 1900 } 1901 } else { 1902 Member[] row = new Member[arity0 + arity1]; 1905 for (int i = 0, m = list1.size(); i < m; i++) { 1906 int x = 0; 1907 Object o0 = list1.get(i); 1908 if (o0 instanceof Member) { 1909 row[x++] = (Member) o0; 1910 } else { 1911 assertTrue(o0 instanceof Member[]); 1912 final Member[] members = (Member[]) o0; 1913 for (Member member : members) { 1914 row[x++] = member; 1915 } 1916 } 1917 for (int j = 0, n = list2.size(); j < n; j++) { 1918 Object o1 = list2.get(j); 1919 if (o1 instanceof Member) { 1920 row[x++] = (Member) o1; 1921 } else { 1922 assertTrue(o1 instanceof Member[]); 1923 final Member[] members = (Member[]) o1; 1924 for (Member member : members) { 1925 row[x++] = member; 1926 } 1927 } 1928 result.add(row.clone()); 1929 x = arity0; 1930 } 1931 } 1932 } 1933 return result; 1934 } 1935 1936 1941 private static class MeasureVisitor extends MdxVisitorImpl { 1942 1943 Set<Member> measureSet; 1945 Set<Member> queryMeasureSet; 1946 ResolvedFunCall crossJoinCall; 1949 1950 MeasureVisitor( 1951 Set<Member> queryMeasureSet, 1952 ResolvedFunCall crossJoinCall) 1953 { 1954 this.queryMeasureSet = queryMeasureSet; 1955 this.crossJoinCall = crossJoinCall; 1956 } 1957 1958 public Object visit(mondrian.mdx.ParameterExpr parameterExpr) { 1959 final Parameter parameter = parameterExpr.getParameter(); 1960 final Type type = parameter.getType(); 1961 if (type instanceof mondrian.olap.type.MemberType) { 1962 final Object value = parameter.getValue(); 1963 if (value instanceof Member) { 1964 final Member member = (Member) value; 1965 process(member); 1966 } 1967 } 1968 1969 return null; 1970 } 1971 public Object visit(mondrian.mdx.MemberExpr memberExpr) { 1972 Member member = memberExpr.getMember(); 1973 process(member); 1974 return null; 1975 } 1976 private void process(final Member member) { 1977 for (Member measure : queryMeasureSet) { 1978 if (measure.equals(member)) { 1979 if (validMeasure(measure)) { 1980 if (measureSet == null) { 1981 measureSet = new HashSet<Member>(); 1982 } 1983 measureSet.add(measure); 1984 break; 1985 } 1986 } 1987 } 1988 } 1989 1990 2002 private boolean validMeasure(Member measure) 2003 { 2004 if (measure.isCalculated()) { 2005 Exp measureExp = measure.getExpression(); 2007 ResolvedFunCallFinder finder = 2008 new ResolvedFunCallFinder(crossJoinCall); 2009 measureExp.accept(finder); 2010 if (finder.found) { 2011 Exp [] args = crossJoinCall.getArgs(); 2014 for (int i = 0; i < args.length; i++) { 2015 Set<Member> measureSet = new HashSet<Member>(); 2016 measureSet.add(measure); 2017 MeasureVisitor measureFinder = 2018 new MeasureVisitor(measureSet, null); 2019 args[i].accept(measureFinder); 2020 measureSet = measureFinder.measureSet; 2021 if (measureSet != null && measureSet.size() > 0) { 2022 throw FunUtil.newEvalException(null, 2024 "Infinite loop detected in " + 2025 crossJoinCall.toString()); 2026 } 2027 } 2028 return false; 2029 } 2030 } 2031 return true; 2032 } 2033 } 2034 2035 2039 private static class ResolvedFunCallFinder 2040 extends MdxVisitorImpl 2041 { 2042 private ResolvedFunCall call; 2043 public boolean found; 2044 2045 public ResolvedFunCallFinder(ResolvedFunCall call) 2046 { 2047 this.call = call; 2048 found = false; 2049 } 2050 2051 public Object visit(ResolvedFunCall funCall) 2052 { 2053 if (funCall == call) { 2054 found = true; 2055 } 2056 return null; 2057 } 2058 2059 public Object visit(mondrian.mdx.MemberExpr memberExpr) { 2060 Member member = memberExpr.getMember(); 2061 if (member.isCalculated()) { 2062 Exp memberExp = member.getExpression(); 2063 memberExp.accept(this); 2064 } 2065 return null; 2066 } 2067 } 2068 2069 2131 protected List nonEmptyList( 2132 Evaluator evaluator, 2133 List list, 2134 ResolvedFunCall call) 2135 { 2136 return nonEmptyListNEW(evaluator, list, call); 2137 } 2139 2140 protected static List nonEmptyListOLD( 2146 Evaluator evaluator, 2147 List list, 2148 ResolvedFunCall call) 2149 { 2150 if (list.isEmpty()) { 2151 return list; 2152 } 2153 2154 List result = new ArrayList((list.size() + 2) >> 1); 2162 2163 Query query = evaluator.getQuery(); 2176 Set<Member> measureSet = null; 2177 Set<Member> queryMeasureSet = query.getMeasuresMembers(); 2178 if (queryMeasureSet.size() > 0) { 2181 MeasureVisitor visitor = 2182 new MeasureVisitor(queryMeasureSet, call); 2183 QueryAxis[] axes = query.getAxes(); 2184 QueryAxis slicerAxis = query.getSlicerAxis(); 2185 if (slicerAxis != null) { 2186 slicerAxis.accept(visitor); 2187 } 2188 if (visitor.measureSet != null) { 2189 measureSet = visitor.measureSet; 2192 2193 } else if (axes.length > 0) { 2194 for (int i = 0; i < axes.length; i++) { 2195 if (axes[i] != null) { 2196 axes[i].accept(visitor); 2197 } 2198 } 2199 measureSet = visitor.measureSet; 2201 } 2202 } 2203 2204 evaluator = evaluator.push(); 2206 if (list.get(0) instanceof Member[]) { 2207 for (Member[] ms : ((List<Member[]>) list)) { 2208 evaluator.setContext(ms); 2209 if (measureSet == null) { 2211 Object value = evaluator.evaluateCurrent(); 2212 if (value != null && !(value instanceof Throwable )) { 2213 result.add(ms); 2214 } 2215 } else { 2216 Iterator<Member> measureIter = measureSet.iterator(); 2217 MEASURES_LOOP: 2218 while (measureIter.hasNext()) { 2219 Member measure = measureIter.next(); 2220 evaluator.setContext(measure); 2221 Object value = evaluator.evaluateCurrent(); 2222 if (value != null && !(value instanceof Throwable )) { 2223 result.add(ms); 2224 break MEASURES_LOOP; 2225 } 2226 } 2227 } 2228 } 2229 } else { 2230 for (Iterator listItr = list.iterator(); listItr.hasNext();) { 2231 Member m = (Member) listItr.next(); 2232 evaluator.setContext(m); 2233 if (measureSet == null) { 2235 Object value = evaluator.evaluateCurrent(); 2236 if (value != null && !(value instanceof Throwable )) { 2237 result.add(m); 2238 } 2239 } else { 2240 Iterator<Member> measureIter = measureSet.iterator(); 2241 measuresLoop: 2242 while (measureIter.hasNext()) { 2243 Member measure = measureIter.next(); 2244 evaluator.setContext(measure); 2245 Object value = evaluator.evaluateCurrent(); 2246 if (value != null && !(value instanceof Throwable )) { 2247 result.add(m); 2248 break measuresLoop; 2249 } 2250 } 2251 } 2252 } 2253 } 2254 return result; 2255 } 2256 2257 2263 private static class MeasureVisitorNEW extends MdxVisitorImpl { 2264 2265 Set<Member> queryMeasureSet; 2266 ResolvedFunCall crossJoinCall; 2270 2271 MeasureVisitorNEW(Set<Member> queryMeasureSet, 2272 ResolvedFunCall crossJoinCall) { 2273 this.queryMeasureSet = queryMeasureSet; 2274 this.crossJoinCall = crossJoinCall; 2275 } 2276 2277 public Object visit(mondrian.mdx.ResolvedFunCall funcall) { 2278 Exp[] exps = funcall.getArgs(); 2279 if (exps != null) { 2280 for (Exp exp: exps) { 2281 exp.accept(this); 2282 } 2283 } 2284 return null; 2285 } 2286 public Object visit(mondrian.mdx.ParameterExpr parameterExpr) { 2287 final Parameter parameter = parameterExpr.getParameter(); 2288 final Type type = parameter.getType(); 2289 if (type instanceof mondrian.olap.type.MemberType) { 2290 final Object value = parameter.getValue(); 2291 if (value instanceof Member) { 2292 final Member member = (Member) value; 2293 process(member); 2294 } 2295 } 2296 2297 return null; 2298 } 2299 public Object visit(mondrian.mdx.MemberExpr memberExpr) { 2300 Member member = memberExpr.getMember(); 2301 process(member); 2302 return null; 2303 } 2304 private void process(final Member member) { 2305 if (member.isMeasure()) { 2306 if (member.isCalculated()) { 2307 Exp exp = member.getExpression(); 2308 ResolvedFunCallFinder finder = 2309 new ResolvedFunCallFinder(crossJoinCall); 2310 exp.accept(finder); 2311 if (! finder.found) { 2312 exp.accept(this); 2313 queryMeasureSet.add(member); 2314 } 2315 } else { 2316 queryMeasureSet.add(member); 2317 } 2318 } 2319 } 2320 } 2321 2322 2337 protected List nonEmptyListNEW( 2338 Evaluator evaluator, 2339 List list, 2340 ResolvedFunCall call) 2341 { 2342 if (list.isEmpty()) { 2343 return list; 2344 } 2345 2346 List result = new ArrayList((list.size() + 2) >> 1); 2347 2348 final Query query = evaluator.getQuery(); 2352 2353 final String measureSetKey = "MEASURE_SET-"+ctag; 2354 Set<Member> measureSet = 2355 (Set<Member>) query.getEvalCache(measureSetKey); 2356 if (measureSet == null) { 2360 measureSet = new HashSet<Member>(); 2361 Set<Member> queryMeasureSet = query.getMeasuresMembers(); 2362 MeasureVisitorNEW visitor = new MeasureVisitorNEW(measureSet, call); 2363 for (Member m : queryMeasureSet) { 2364 if (m.isCalculated()) { 2365 Exp exp = m.getExpression(); 2366 exp.accept(visitor); 2367 } else { 2368 measureSet.add(m); 2369 } 2370 } 2371 2372 Formula[] formula = query.getFormulas(); 2373 if (formula != null) { 2374 for (Formula f: formula) { 2375 f.accept(visitor); 2376 } 2377 } 2378 2379 query.putEvalCache(measureSetKey, measureSet); 2380 } 2381 2382 final String allMemberListKey = "ALL_MEMBER_LIST-"+ctag; 2383 List<Member> allMemberList = 2384 (List<Member>) query.getEvalCache(allMemberListKey); 2385 2386 final String nonAllMembersKey = "NON_ALL_MEMBERS-"+ctag; 2387 Member[][] nonAllMembers = 2388 (Member[][]) query.getEvalCache(nonAllMembersKey); 2389 if (nonAllMembers == null) { 2390 Member[] evalMembers = (Member[]) evaluator.getMembers().clone(); 2395 2396 Member[] listMembers = (list.get(0) instanceof Member[]) 2397 ? (Member[]) list.get(0) 2398 : new Member[] { (Member) list.get(0) }; 2399 2400 2401 for (Member lm : listMembers) { 2403 Hierarchy h = lm.getHierarchy(); 2404 for (int i = 0; i < evalMembers.length; i++) { 2405 Member em = evalMembers[i]; 2406 if ((em != null) && h.equals(em.getHierarchy())) { 2407 evalMembers[i] = null; 2408 } 2409 } 2410 } 2411 2412 SchemaReader schemaReader = evaluator.getSchemaReader(); 2419 allMemberList = new ArrayList<Member>(); 2420 List<Member[]> nonAllMemberList = new ArrayList<Member[]>(); 2421 for (int i = 0, j = 0; i < evalMembers.length; i++) { 2422 Member em = evalMembers[i]; 2423 if (em == null) { 2424 continue; 2427 } 2428 if (em.isMeasure()) { 2429 continue; 2430 } 2431 if (em.isCalculated()) { 2432 continue; 2433 } 2434 if (! em.isAll()) { 2436 Hierarchy h = em.getHierarchy(); 2437 Member[] rootMembers = schemaReader.getHierarchyRootMembers(h); 2438 if (h.hasAll()) { 2439 boolean found = false; 2441 for (Member m : rootMembers) { 2442 if (m.isAll()) { 2443 allMemberList.add(m); 2444 found = true; 2445 break; 2446 } 2447 } 2448 if (! found) { 2449System.out.println("CrossJoinFunDef.nonEmptyListNEW: ERROR"); 2450 } 2451 } else { 2452 nonAllMemberList.add(rootMembers); 2454 } 2455 } 2456 } 2457 nonAllMembers = 2458 (Member[][]) nonAllMemberList.toArray(new Member[0][]); 2459 2460 query.putEvalCache(allMemberListKey, allMemberList); 2461 query.putEvalCache(nonAllMembersKey, nonAllMembers); 2462 } 2463 2464 evaluator = evaluator.push(); 2468 2469 evaluator.setContext(allMemberList); 2471 2472 if (list.get(0) instanceof Member[]) { 2477 for (Member[] ms : ((List<Member[]>) list)) { 2478 evaluator.setContext(ms); 2479 if (checkData(nonAllMembers, nonAllMembers.length-1, 2480 measureSet, evaluator)) { 2481 result.add(ms); 2482 } 2483 } 2484 } else { 2485 for (Member m : ((List<Member>) list)) { 2486 evaluator.setContext(m); 2487 if (checkData(nonAllMembers, nonAllMembers.length-1, 2488 measureSet, evaluator)) { 2489 result.add(m); 2490 } 2491 } 2492 } 2493 2494 return result; 2495 } 2496 2497 2511 private static boolean checkData( 2512 Member[][] nonAllMembers, 2513 int cnt, 2514 Set<Member> measureSet, 2515 Evaluator evaluator) { 2516 2517 if (cnt < 0) { 2518 if (measureSet.isEmpty()) { 2520 Object value = evaluator.evaluateCurrent(); 2521 if (value != null && !(value instanceof Throwable )) { 2522 return true; 2523 } 2524 } else { 2525 boolean found = false; 2528 for (Member measure : measureSet) { 2529 evaluator.setContext(measure); 2530 Object value = evaluator.evaluateCurrent(); 2531 if (value != null && !(value instanceof Throwable )) { 2532 found = true; 2533 } 2534 } 2535 return found; 2536 } 2537 } else { 2538 boolean found = false; 2539 for (Member m : nonAllMembers[cnt]) { 2540 evaluator.setContext(m); 2541 if (checkData(nonAllMembers, cnt-1, measureSet, evaluator)) { 2542 found = true; 2543 } 2544 } 2545 return found; 2546 } 2547 return false; 2548 } 2549 2550 private static class StarCrossJoinResolver extends MultiResolver { 2551 public StarCrossJoinResolver() { 2552 super( 2553 "*", 2554 "<Set1> * <Set2>", 2555 "Returns the cross product of two sets.", 2556 new String []{"ixxx", "ixmx", "ixxm", "ixmm"}); 2557 } 2558 2559 public FunDef resolve( 2560 Exp[] args, Validator validator, int[] conversionCount) { 2561 if (validator.requiresExpression()) { 2566 return null; 2567 } 2568 return super.resolve(args, validator, conversionCount); 2569 } 2570 2571 protected FunDef createFunDef(Exp[] args, FunDef dummyFunDef) { 2572 return new CrossJoinFunDef(dummyFunDef); 2573 } 2574 } 2575 2576 2577} 2578 2579 | Popular Tags |