Sort bindings by the ORDER BY key list (virtual variables) using bubble * sort; later keys break ties, direction is per key (#1334). */
| 3743 | /* Sort bindings by the ORDER BY key list (virtual variables) using bubble |
| 3744 | * sort; later keys break ties, direction is per key (#1334). */ |
| 3745 | static void sort_bindings(binding_t *vbindings, int count, const cbm_return_clause_t *wc) { |
| 3746 | for (int i = 0; i < count - SKIP_ONE; i++) { |
| 3747 | for (int j = 0; j < count - i - SKIP_ONE; j++) { |
| 3748 | int cmp = 0; |
| 3749 | for (int k = 0; k < wc->order_key_count && cmp == 0; k++) { |
| 3750 | const char *va = binding_get_virtual(&vbindings[j], wc->order_keys[k], NULL); |
| 3751 | const char *vb2 = |
| 3752 | binding_get_virtual(&vbindings[j + SKIP_ONE], wc->order_keys[k], NULL); |
| 3753 | char *ea = NULL; |
| 3754 | char *eb = NULL; |
| 3755 | double da = strtod(va, &ea); |
| 3756 | double db = strtod(vb2, &eb); |
| 3757 | cmp = (ea != va && eb != vb2) ? ((da > db) - (da < db)) : strcmp(va, vb2); |
| 3758 | if (wc->order_descs[k]) { |
| 3759 | cmp = -cmp; |
| 3760 | } |
| 3761 | } |
| 3762 | if (cmp > 0) { |
| 3763 | binding_t tmp = vbindings[j]; |
| 3764 | vbindings[j] = vbindings[j + SKIP_ONE]; |
| 3765 | vbindings[j + SKIP_ONE] = tmp; |
| 3766 | } |
| 3767 | } |
| 3768 | } |
| 3769 | } |
| 3770 | |
| 3771 | /* Apply skip and limit to a binding array, freeing discarded entries */ |
| 3772 | static void bindings_skip_limit(binding_t *vbindings, int *count, int skip, int limit) { |
no test coverage detected