]>
Commit | Line | Data |
---|---|---|
32938903 AM |
1 | #! /bin/sh /usr/share/dpatch/dpatch-run |
2 | ## 009_opt-bypass-redundant-sort.dpatch by <divanov@creditreform.bg> | |
3 | ## | |
4 | ## All lines beginning with `## DP:' are a description of the patch. | |
5 | ## DP: RP: optimize sort with OUTER JOIN if all the fields in the sort list | |
6 | ## DP: are from one stream, check the stream is the most outer stream, if true | |
7 | ## DP: update rse and ignore the sort | |
8 | ||
9 | @DPATCH@ | |
10 | ||
11 | --- firebird2-1.5.2.orig/src/jrd/opt.cpp | |
12 | +++ firebird2-1.5.2/src/jrd/opt.cpp | |
13 | @@ -1518,7 +1518,89 @@ | |
14 | set_position(sort, project, NULL); | |
15 | sort = rse->rse_sorted = NULL; | |
16 | } | |
17 | - } | |
18 | + } | |
19 | + | |
20 | + // RP: optimize sort with OUTER JOIN | |
21 | + // if all the fields in the sort list are from one stream, check the stream is | |
22 | + // the most outer stream, if true update rse and ignore the sort | |
23 | + if (sort) { | |
24 | + UCHAR sort_stream = 0; | |
25 | + bool usableSort = true; | |
26 | + sort_ptr = sort->nod_arg; | |
27 | + sort_end = sort_ptr + sort->nod_count; | |
28 | + for (; sort_ptr < sort_end; sort_ptr++) { | |
29 | + if ((*sort_ptr)->nod_type == nod_field) { | |
30 | + // Get stream for this field at this position. | |
31 | + const UCHAR current_stream = (UCHAR)(IPTR)(*sort_ptr)->nod_arg[e_fld_stream]; | |
32 | + // If this is the first position node, save this stream. | |
33 | + if (sort_ptr == sort->nod_arg) { | |
34 | + sort_stream = current_stream; | |
35 | + } | |
36 | + else if (current_stream != sort_stream) { | |
37 | + // If the current stream is different then the previous stream | |
38 | + // then we can't use this sort for an indexed order retrieval. | |
39 | + usableSort = false; | |
40 | + break; | |
41 | + } | |
42 | + } | |
43 | + else { | |
44 | + // This position doesn't use a simple field, thus we can't use | |
45 | + // any index for the sort. | |
46 | + usableSort = false; | |
47 | + break; | |
48 | + } | |
49 | + } | |
50 | + | |
51 | + if (usableSort) { | |
52 | + RSE new_rse = NULL; | |
53 | + JRD_NOD node = (JRD_NOD) rse; | |
54 | + while (node) { | |
55 | + if (node->nod_type == nod_rse) { | |
56 | + new_rse = (RSE) node; | |
57 | + if (new_rse->rse_jointype == blr_inner) { | |
58 | + if (new_rse->rse_count == 1) { | |
59 | + node = new_rse->rse_relation[0]; | |
60 | + } | |
61 | + else { | |
62 | + bool sortStreamFound = false; | |
63 | + for (int i = 0; i < new_rse->rse_count; i++) { | |
64 | + JRD_NOD subNode = (JRD_NOD) new_rse->rse_relation[i]; | |
65 | + if (subNode->nod_type == nod_relation && | |
66 | + ((USHORT)(IPTR)subNode->nod_arg[e_rel_stream]) == sort_stream && | |
67 | + new_rse != rse) | |
68 | + { | |
69 | + sortStreamFound = true; | |
70 | + break; | |
71 | + } | |
72 | + | |
73 | + } | |
74 | + if (sortStreamFound) { | |
75 | + new_rse->rse_sorted = sort; | |
76 | + sort = rse->rse_sorted = NULL; | |
77 | + } | |
78 | + node = NULL; | |
79 | + } | |
80 | + } | |
81 | + else if (new_rse->rse_jointype == blr_left) { | |
82 | + node = new_rse->rse_relation[0]; | |
83 | + } | |
84 | + else { | |
85 | + node = NULL; | |
86 | + } | |
87 | + } | |
88 | + else { | |
89 | + if (node->nod_type == nod_relation && | |
90 | + ((USHORT)(IPTR)node->nod_arg[e_rel_stream]) == sort_stream && | |
91 | + new_rse && new_rse != rse) | |
92 | + { | |
93 | + new_rse->rse_sorted = sort; | |
94 | + sort = rse->rse_sorted = NULL; | |
95 | + } | |
96 | + node = NULL; | |
97 | + } | |
98 | + } | |
99 | + } | |
100 | + } | |
101 | } | |
102 | ||
103 |