| 670 | |
| 671 | #ifdef WORDS_BIGENDIAN |
| 672 | void Sort::diddleKey(UCHAR* record, bool direction, bool duplicateHandling) |
| 673 | { |
| 674 | /************************************** |
| 675 | * |
| 676 | * Perform transformation between the natural form of a record |
| 677 | * and a form that can be sorted in unsigned comparison order. |
| 678 | * |
| 679 | * direction - true for SORT_put() and false for SORT_get() |
| 680 | * |
| 681 | **************************************/ |
| 682 | USHORT flag; |
| 683 | |
| 684 | for (sort_key_def* key = m_description.begin(), *end = m_description.end(); key < end; key++) |
| 685 | { |
| 686 | UCHAR* p = record + key->getSkdOffset(); |
| 687 | SORTP* lwp = (SORTP*) p; |
| 688 | USHORT n = key->getSkdLength(); |
| 689 | USHORT complement = key->skd_flags & SKD_descending; |
| 690 | |
| 691 | // This trick replaces possibly negative zero with positive zero, so that both |
| 692 | // would be transformed into the same sort key and thus properly compared (see CORE-3547). |
| 693 | // Note that it's done only once, per SORT_put(), i.e. the transformation is not symmetric. |
| 694 | if (direction) |
| 695 | { |
| 696 | if (key->skd_dtype == SKD_double) |
| 697 | { |
| 698 | if (*(double*) p == 0) |
| 699 | { |
| 700 | *(double*) p = 0; |
| 701 | } |
| 702 | } |
| 703 | else if (key->skd_dtype == SKD_float) |
| 704 | { |
| 705 | if (*(float*) p == 0) |
| 706 | { |
| 707 | *(float*) p = 0; |
| 708 | } |
| 709 | } |
| 710 | } |
| 711 | |
| 712 | switch (key->skd_dtype) |
| 713 | { |
| 714 | case SKD_ulong: |
| 715 | case SKD_ushort: |
| 716 | case SKD_bytes: |
| 717 | case SKD_sql_time: |
| 718 | break; |
| 719 | |
| 720 | // Stash embedded control info for non-fixed data types in the sort |
| 721 | // record and zap it so that it doesn't interfere with collation |
| 722 | |
| 723 | case SKD_varying: |
| 724 | if (direction) |
| 725 | { |
| 726 | USHORT& vlen = ((vary*) p)->vary_length; |
| 727 | if (!(m_flags & scb_sorted)) |
| 728 | { |
| 729 | *((USHORT*) (record + key->skd_vary_offset)) = vlen; |
no test coverage detected