1 package com.daffodilwoods.daffodildb.server.sql99.dql.iterator.set; 2 3 import com.daffodilwoods.daffodildb.client.*; 4 import com.daffodilwoods.daffodildb.server.sql99.common.*; 5 import com.daffodilwoods.daffodildb.server.sql99.dql.iterator.*; 6 import com.daffodilwoods.daffodildb.server.sql99.utils.*; 7 import com.daffodilwoods.daffodildb.utils.comparator.*; 8 import com.daffodilwoods.database.resource.*; 9 import com.daffodilwoods.database.utility.P; 10 11 30 public class UnionDistinctIterator extends UnionAllOrderedIterator { 31 32 36 private SuperComparator leftComparator; 37 41 private SuperComparator rightComparator; 42 43 44 private int[] stateToSet = {FIRSTISCURRENT,FIRSTISCURRENT,BOTHHAVESAMEDATA,SECONDISCURRENT,SECONDISCURRENT}; 45 46 74 public UnionDistinctIterator(_Iterator leftIterator, _Iterator rightIterator, _Reference[] leftColumnReferences, _Reference[] rightColumnReferences, SuperComparator comparator0, int[] appropriateDataTypes, int[] appropriateSizes, _Reference[] orderLeftCD0, _Reference[] orderRightCD0, SuperComparator leftComparator0, SuperComparator rightComparator0) throws DException { 75 super(leftIterator, rightIterator, leftColumnReferences, rightColumnReferences, comparator0, appropriateDataTypes, appropriateSizes, orderLeftCD0, orderRightCD0); 76 leftComparator = leftComparator0; 77 rightComparator = rightComparator0; 78 } 79 80 106 public boolean first() throws com.daffodilwoods.database.resource.DException { 107 direction = FORWARD; 108 boolean leftFlag = leftIterator.first(); 109 boolean rightFlag = rightIterator.first(); 110 111 state = leftFlag ? rightFlag ? getState(compare(leftIterator.getColumnValues(orderLeftCD), rightIterator.getColumnValues(orderRightCD))) 112 : ONLYFIRSTHAVEDATA 113 : rightFlag ? ONLYSECONDHAVEDATA : AFTERLAST; 114 115 return state != AFTERLAST; 116 } 117 118 142 public boolean last() throws com.daffodilwoods.database.resource.DException { 143 direction = BACKWARD; 144 boolean leftFlag = leftIterator.last(); 145 boolean rightFlag = rightIterator.last(); 146 state = leftFlag ? rightFlag ? getState(-compare(leftIterator.getColumnValues(orderLeftCD), rightIterator.getColumnValues(orderRightCD)) ) 147 : ONLYFIRSTHAVEDATA 148 : rightFlag ? ONLYSECONDHAVEDATA : BEFOREFIRST; 149 150 return state != BEFOREFIRST; 151 } 152 153 218 public boolean next() throws com.daffodilwoods.database.resource.DException { 219 switch (state) { 220 case INVALIDSTATE: 221 throw new DException("DSE4116", null); 222 case BEFOREFIRST: 223 return first(); 224 case AFTERLAST: 225 return false; 226 case ONLYFIRSTHAVEDATA: 227 if (direction == BACKWARD) { 228 return iteratePositiveAfterNegativeWhenOneHasData(leftIterator, rightIterator, orderLeftCD, orderRightCD, 1); 229 } 230 direction = FORWARD; 231 Object val = leftIterator.getColumnValues(orderLeftCD); 232 boolean flag = moveForward(leftIterator, val, orderLeftCD, 1); 233 state = flag ? state : AFTERLAST; 234 return flag; 235 case ONLYSECONDHAVEDATA: 236 if (direction == BACKWARD) { 237 return iteratePositiveAfterNegativeWhenOneHasData(rightIterator, leftIterator, orderRightCD, orderLeftCD, -1); 238 } 239 direction = FORWARD; 240 Object val1 = rightIterator.getColumnValues(orderRightCD); 241 boolean flag1 = moveForward(rightIterator, val1, orderRightCD, -1); 242 state = flag1 ? state : AFTERLAST; 243 return flag1; 244 case FIRSTISCURRENT: 245 if (direction == BACKWARD) { 246 return iteratePositiveAfterNegativeWhenOneIsCurrent(leftIterator, rightIterator, orderLeftCD, orderRightCD, 1); 247 } 248 return iteratePositive(leftIterator, rightIterator, 1, orderLeftCD, orderRightCD); 249 case SECONDISCURRENT: 250 if (direction == BACKWARD) { 251 return iteratePositiveAfterNegativeWhenOneIsCurrent(rightIterator, leftIterator, orderRightCD, orderLeftCD, -1); 252 } 253 return iteratePositive(rightIterator, leftIterator, -1, orderRightCD, orderLeftCD); 254 case BOTHHAVESAMEDATA: 255 if (direction == BACKWARD) { 256 return iteratePositiveAfterNegativeWhenBothHaveSameData(leftIterator, rightIterator, orderLeftCD, orderRightCD, 1); 257 } 258 return iteratePositiveWhenBoth(); 259 } 260 return false; 261 } 262 263 291 private boolean iteratePositive(_Iterator currentIterator, _Iterator otherIterator, int reverse, _Reference[] currentReferences, _Reference[] otherReferences) throws DException { 292 direction = FORWARD; 293 Object toCompare = currentIterator.getColumnValues(currentReferences); 294 boolean flag = moveForward(currentIterator, toCompare, currentReferences, reverse); 295 if (!flag) { 296 state = reverse == 1 ? ONLYSECONDHAVEDATA : ONLYFIRSTHAVEDATA; 297 return true; 298 } 299 Object first = currentIterator.getColumnValues(currentReferences); 300 Object second = otherIterator.getColumnValues(otherReferences); 301 state = reverse == 1 ? getState(compare(first, second)) : getState(compare(second, first)); 302 return true; 303 } 304 305 337 private boolean iteratePositiveWhenBoth() throws DException { 338 direction = FORWARD; 339 boolean flag1 = moveForward(leftIterator, leftIterator.getColumnValues(orderLeftCD), orderLeftCD, 1); 340 boolean flag2 = moveForward(rightIterator, rightIterator.getColumnValues(orderRightCD), orderRightCD, -1); 341 if (flag1) { 342 if (flag2) { 343 int cmp = compare(leftIterator.getColumnValues(orderLeftCD), rightIterator.getColumnValues(orderRightCD)); 344 345 state = cmp == 0 ? BOTHHAVESAMEDATA : cmp < 0 ? FIRSTISCURRENT : SECONDISCURRENT; 346 } else { 347 state = ONLYFIRSTHAVEDATA; 348 } 349 } else { 350 if (flag2) { 351 state = ONLYSECONDHAVEDATA; 352 } else { 353 state = AFTERLAST; 354 } 355 } 356 return state != AFTERLAST; 357 } 358 359 397 private boolean iteratePositiveAfterNegativeWhenOneHasData(_Iterator currentIterator, _Iterator otherIterator, _Reference[] currentReferences, _Reference[] otherReferences, int reverse) throws DException { 398 boolean currentNext = moveForward(currentIterator, currentIterator.getColumnValues(currentReferences), currentReferences, reverse); 399 boolean otherFirst = otherIterator.first(); 400 if (currentNext && otherFirst) { 401 Object currentObject = currentIterator.getColumnValues(currentReferences); 402 Object otherObject = otherIterator.getColumnValues(otherReferences); 403 int cmp = compare(currentObject, otherObject); 404 if (cmp == 0) { 405 state = BOTHHAVESAMEDATA; 406 } else if (cmp > 0) { 407 state = state == ONLYSECONDHAVEDATA ? FIRSTISCURRENT 408 : state == ONLYFIRSTHAVEDATA ? SECONDISCURRENT : state; 409 currentIterator.previous(); 410 411 } else { 412 otherIterator.previous(); 413 } 414 } else if (currentNext) { 415 } else if (otherFirst) { 416 currentIterator.last(); 417 state = state == ONLYSECONDHAVEDATA ? FIRSTISCURRENT 418 : state == ONLYFIRSTHAVEDATA ? SECONDISCURRENT : state; 419 } else { 420 state = AFTERLAST; 421 return false; 422 } 423 return true; 424 } 425 426 467 private boolean iteratePositiveAfterNegativeWhenOneIsCurrent(_Iterator currentIterator, _Iterator otherIterator, _Reference[] currentReferences, _Reference[] otherReferences, int reverse) throws DException { 468 boolean currentNext = moveForward(currentIterator, currentIterator.getColumnValues(currentReferences), currentReferences, reverse); 469 boolean otherNext = moveForward(otherIterator, otherIterator.getColumnValues(otherReferences), otherReferences, reverse); 470 if (currentNext && otherNext) { 471 Object currentObject = currentIterator.getColumnValues(currentReferences); 472 Object otherObject = otherIterator.getColumnValues(otherReferences); 473 int cmp = compare(currentObject, otherObject); 474 if (cmp == 0) { 475 state = BOTHHAVESAMEDATA; 476 } else if (cmp > 0) { 477 state = -state; 478 currentIterator.previous(); 479 } else { 480 otherIterator.previous(); 481 } 482 } else if (currentNext) { 483 otherIterator.last(); 484 } else if (otherNext) { 485 currentIterator.last(); 486 state = -state; 487 } else { 488 state = AFTERLAST; 489 return false; 490 } 491 return true; 492 } 493 494 529 private boolean iteratePositiveAfterNegativeWhenBothHaveSameData(_Iterator currentIterator, _Iterator otherIterator, _Reference[] currentReferences, _Reference[] otherReferences, int reverse) throws DException { 530 boolean currentNext = moveForward(currentIterator, currentIterator.getColumnValues(currentReferences), currentReferences, reverse); 531 boolean otherNext = moveForward(otherIterator, otherIterator.getColumnValues(otherReferences), otherReferences, reverse); 532 if (currentNext && otherNext) { 533 Object currentObject = currentIterator.getColumnValues(currentReferences); 534 Object otherObject = otherIterator.getColumnValues(otherReferences); 535 int cmp = compare(currentObject, otherObject); 536 if (cmp == 0) { 537 state = BOTHHAVESAMEDATA; 538 } else if (cmp < 0) { 539 state = SECONDISCURRENT; 540 currentIterator.previous(); 541 } else { 542 state = FIRSTISCURRENT; 543 otherIterator.previous(); 544 } 545 } else if (currentNext) { 546 otherIterator.last(); 547 state = SECONDISCURRENT; 548 } else if (otherNext) { 549 currentIterator.last(); 550 state = FIRSTISCURRENT; 551 } else { 552 state = AFTERLAST; 553 return false; 554 } 555 return true; 556 } 557 558 568 private boolean moveForward(_Iterator iterator, Object value, _Reference[] references, int reverse) throws DException { 569 while (iterator.next()) { 570 SuperComparator comparator = reverse == 1 ? leftComparator : rightComparator; 571 if (comparator.compare(iterator.getColumnValues(references), value) != 0) { 572 return true; 573 } 574 } 575 return false; 576 } 577 578 635 public boolean previous() throws com.daffodilwoods.database.resource.DException { 636 switch (state) { 637 case INVALIDSTATE: 638 throw new DException("DSE4117", null); 639 case BEFOREFIRST: 640 return false; 641 case AFTERLAST: 642 return last(); 643 case ONLYFIRSTHAVEDATA: 644 if (direction == FORWARD) { 645 return iterateNegativeAfterPositiveWhenOneHasData(leftIterator, rightIterator, orderLeftCD, orderRightCD, 1); 646 } 647 direction = BACKWARD; 648 Object val = leftIterator.getColumnValues(orderLeftCD); 649 boolean flag = moveBackward(leftIterator, val, orderLeftCD, 1); 650 state = flag ? state : BEFOREFIRST; 651 return flag; 652 case ONLYSECONDHAVEDATA: 653 if (direction == FORWARD) { 654 return iterateNegativeAfterPositiveWhenOneHasData(rightIterator, leftIterator, orderRightCD, orderLeftCD, -1); 655 } 656 direction = BACKWARD; 657 Object val1 = rightIterator.getColumnValues(orderRightCD); 658 boolean flag1 = moveBackward(rightIterator, val1, orderRightCD, -1); 659 state = flag1 ? state : BEFOREFIRST; 660 return flag1; 661 case FIRSTISCURRENT: 662 if (direction == FORWARD) { 663 return iterateNegativeAfterPositiveWhenOneIsCurrent(leftIterator, rightIterator, orderLeftCD, orderRightCD, 1); 664 } 665 return iterateNegative(leftIterator, rightIterator, 1, orderLeftCD, orderRightCD); 666 case SECONDISCURRENT: 667 if (direction == FORWARD) { 668 return iterateNegativeAfterPositiveWhenOneIsCurrent(rightIterator, leftIterator, orderRightCD, orderLeftCD, -1); 669 } 670 return iterateNegative(rightIterator, leftIterator, -1, orderRightCD, orderLeftCD); 671 case BOTHHAVESAMEDATA: 672 if (direction == FORWARD) { 673 return iterateNegativeAfterPositiveWhenBothHaveSameData(rightIterator, leftIterator, orderRightCD, orderLeftCD, -1); 674 } 675 return iterateNegativeWhenBoth(); 676 } 677 return false; 678 } 679 680 710 private boolean iterateNegative(_Iterator firstIterator, _Iterator secondIterator, int reverse, _Reference[] firstReferences, _Reference[] secondReferences) throws DException { 711 direction = BACKWARD; 712 Object toCompare = firstIterator.getColumnValues(firstReferences); 713 int cmp = -1; 714 boolean flag = moveBackward(firstIterator, toCompare, firstReferences, reverse); if (!flag) { 716 state = reverse == 1 ? ONLYSECONDHAVEDATA : ONLYFIRSTHAVEDATA; 717 return true; 718 } 719 Object first = firstIterator.getColumnValues(firstReferences); 720 Object second = secondIterator.getColumnValues(secondReferences); 721 state = reverse == 1 ? getState(compare(second, first)) :getState(compare(first, second)); 722 723 724 return true; 725 } 726 727 730 731 763 private boolean iterateNegativeWhenBoth() throws DException { 764 direction = BACKWARD; 765 boolean flag1 = moveBackward(leftIterator, leftIterator.getColumnValues(orderLeftCD), orderLeftCD, 1); 766 boolean flag2 = moveBackward(rightIterator, rightIterator.getColumnValues(orderRightCD), orderRightCD, -1); 767 if (flag1) { 768 if (flag2) { 769 int cmp = compare(leftIterator.getColumnValues(orderLeftCD), rightIterator.getColumnValues(orderRightCD)); 770 state = cmp == 0 ? BOTHHAVESAMEDATA : cmp > 0 ? FIRSTISCURRENT : SECONDISCURRENT; 771 } else { 772 state = ONLYFIRSTHAVEDATA; 773 } 774 } else { 775 if (flag2) { 776 state = ONLYSECONDHAVEDATA; 777 } else { 778 state = BEFOREFIRST; 779 } 780 } 781 return state != BEFOREFIRST; 782 } 783 784 823 private boolean iterateNegativeAfterPositiveWhenOneHasData(_Iterator currentIterator, _Iterator otherIterator, _Reference[] currentReferences, _Reference[] otherReferences, int reverse) throws DException { 824 boolean currentPrevious = moveBackward(currentIterator, currentIterator.getColumnValues(currentReferences), currentReferences, reverse); 825 boolean otherLast = otherIterator.last(); 826 if (currentPrevious && otherLast) { 827 Object currentObject = currentIterator.getColumnValues(currentReferences); 828 Object otherObject = otherIterator.getColumnValues(otherReferences); 829 int cmp = compare(currentObject, otherObject); 830 if (cmp == 0) { 831 state = BOTHHAVESAMEDATA; 832 } else if (cmp < 0) { 833 state = state == ONLYSECONDHAVEDATA ? FIRSTISCURRENT 834 : state == ONLYFIRSTHAVEDATA ? SECONDISCURRENT : state; 835 currentIterator.next(); 836 } else { 837 otherIterator.next(); 838 } 839 } else if (currentPrevious) { 840 } else if (otherLast) { 841 currentIterator.first(); 842 state = state == ONLYSECONDHAVEDATA ? FIRSTISCURRENT 843 : state == ONLYFIRSTHAVEDATA ? SECONDISCURRENT : state; 844 } else { 845 state = BEFOREFIRST; 846 return false; 847 } 848 return true; 849 } 850 851 888 private boolean iterateNegativeAfterPositiveWhenOneIsCurrent(_Iterator currentIterator, _Iterator otherIterator, _Reference[] currentReferences, _Reference[] otherReferences, int reverse) throws DException { 889 boolean currentPrevious = moveBackward(currentIterator, currentIterator.getColumnValues(currentReferences), currentReferences, reverse); 890 boolean otherPrevious = moveBackward(otherIterator, otherIterator.getColumnValues(otherReferences), otherReferences, reverse); 891 if (currentPrevious && otherPrevious) { 892 Object currentObject = currentIterator.getColumnValues(currentReferences); 893 Object otherObject = otherIterator.getColumnValues(otherReferences); 894 int cmp = compare(currentObject, otherObject); 895 if (cmp == 0) { 896 state = BOTHHAVESAMEDATA; 897 } else if (cmp < 0) { 898 state = -state; 899 currentIterator.next(); 900 } else { 901 otherIterator.next(); 902 } 903 } else if (currentPrevious) { 904 otherIterator.first(); 905 } else if (otherPrevious) { 906 currentIterator.first(); 907 state = -state; 908 } else { 909 state = BEFOREFIRST; 910 return false; 911 } 912 return true; 913 } 914 915 951 private boolean iterateNegativeAfterPositiveWhenBothHaveSameData(_Iterator currentIterator, _Iterator otherIterator, _Reference[] currentReferences, _Reference[] otherReferences, int reverse) throws DException { 952 boolean currentPrevious = moveBackward(currentIterator, currentIterator.getColumnValues(currentReferences), currentReferences, reverse); 953 boolean otherPrevious = moveBackward(otherIterator, otherIterator.getColumnValues(otherReferences), otherReferences, reverse); 954 if (currentPrevious && otherPrevious) { 955 Object currentObject = currentIterator.getColumnValues(currentReferences); 956 Object otherObject = otherIterator.getColumnValues(otherReferences); 957 int cmp = compare(currentObject, otherObject); 958 if (cmp == 0) { 959 state = BOTHHAVESAMEDATA; 960 } else if (cmp < 0) { 961 state = SECONDISCURRENT; 962 currentIterator.next(); 963 } else { 964 state = FIRSTISCURRENT; 965 otherIterator.next(); 966 } 967 } else if (currentPrevious) { 968 otherIterator.first(); 969 state = FIRSTISCURRENT; 970 } else if (otherPrevious) { 971 currentIterator.first(); 972 state = SECONDISCURRENT; 973 } else { 974 state = BEFOREFIRST; 975 return false; 976 } 977 return true; 978 } 979 980 983 984 996 private boolean moveBackward(_Iterator iterator, Object value, _Reference[] references, int reverse) throws DException { 997 while (iterator.previous()) { 998 SuperComparator comparator = reverse == 1 ? leftComparator : rightComparator; 999 if (comparator.compare(iterator.getColumnValues(references), value) != 0) { 1000 return true; 1001 } 1002 } 1003 return false; 1004 } 1005 1006 1012 public _Iterator getBaseIterator(ColumnDetails column) throws com.daffodilwoods.database.resource.DException { 1013 return this; 1014 } 1015 1016 1021 public _ExecutionPlan getExecutionPlan() throws DException { 1022 _ExecutionPlan cplans[] = new _ExecutionPlan[2]; 1023 cplans[0] = leftIterator.getExecutionPlan(); 1024 cplans[1] = rightIterator.getExecutionPlan(); 1025 return new ExecutionPlan("UnionDistinctIterator", cplans, null, null, null); 1026 } 1027 1028 1033 public ExecutionPlanForBrowser getExecutionPlanForBrowser() throws DException { 1034 ExecutionPlanForBrowser cplans[] = new ExecutionPlanForBrowser[2]; 1035 cplans[0] = leftIterator.getExecutionPlanForBrowser(); 1036 cplans[1] = rightIterator.getExecutionPlanForBrowser(); 1037 return new ExecutionPlanForBrowser("Union Distinct", "Union Distinct Iterator", cplans, null, null, null); 1038 } 1039 1040 public String toString() { 1041 return "UnionDistinctIterator [" + leftIterator + "] [" + rightIterator + "] "; 1042 } 1043 1044 1045 private int getState(int compareResult){ 1046 return stateToSet[compareResult + 2 ]; 1047 } 1048 1049} 1050 | Popular Tags |