| 648 | } |
| 649 | |
| 650 | int Arg_comparator::compare_row() |
| 651 | { |
| 652 | int res= 0; |
| 653 | bool was_null= 0; |
| 654 | (*a)->bring_value(); |
| 655 | (*b)->bring_value(); |
| 656 | |
| 657 | if ((*a)->null_value || (*b)->null_value) |
| 658 | { |
| 659 | owner->null_value= 1; |
| 660 | return -1; |
| 661 | } |
| 662 | |
| 663 | uint n= (*a)->cols(); |
| 664 | for (uint i= 0; i<n; i++) |
| 665 | { |
| 666 | res= comparators[i].compare(); |
| 667 | /* Aggregate functions don't need special null handling. */ |
| 668 | if (owner->null_value && owner->type() == Item::FUNC_ITEM) |
| 669 | { |
| 670 | // NULL was compared |
| 671 | switch (((Item_func*)owner)->functype()) { |
| 672 | case Item_func::NE_FUNC: |
| 673 | break; // NE never aborts on NULL even if abort_on_null is set |
| 674 | case Item_func::LT_FUNC: |
| 675 | case Item_func::LE_FUNC: |
| 676 | case Item_func::GT_FUNC: |
| 677 | case Item_func::GE_FUNC: |
| 678 | return -1; // <, <=, > and >= always fail on NULL |
| 679 | default: // EQ_FUNC |
| 680 | if (((Item_bool_func2*)owner)->abort_on_null) |
| 681 | return -1; // We do not need correct NULL returning |
| 682 | } |
| 683 | was_null= 1; |
| 684 | owner->null_value= 0; |
| 685 | res= 0; // continue comparison (maybe we will meet explicit difference) |
| 686 | } |
| 687 | else if (res) |
| 688 | return res; |
| 689 | } |
| 690 | if (was_null) |
| 691 | { |
| 692 | /* |
| 693 | There was NULL(s) in comparison in some parts, but there was no |
| 694 | explicit difference in other parts, so we have to return NULL. |
| 695 | */ |
| 696 | owner->null_value= 1; |
| 697 | return -1; |
| 698 | } |
| 699 | return 0; |
| 700 | } |
| 701 | |
| 702 | |
| 703 | int Arg_comparator::compare_e_row() |
nothing calls this directly
no test coverage detected