1 #! /bin/sh /usr/share/dpatch/dpatch-run
2 ## 009_opt-bypass-redundant-sort.dpatch by <divanov@creditreform.bg>
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
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;
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
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;
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.
44 + // This position doesn't use a simple field, thus we can't use
45 + // any index for the sort.
53 + JRD_NOD node = (JRD_NOD) rse;
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];
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 &&
69 + sortStreamFound = true;
74 + if (sortStreamFound) {
75 + new_rse->rse_sorted = sort;
76 + sort = rse->rse_sorted = NULL;
81 + else if (new_rse->rse_jointype == blr_left) {
82 + node = new_rse->rse_relation[0];
89 + if (node->nod_type == nod_relation &&
90 + ((USHORT)(IPTR)node->nod_arg[e_rel_stream]) == sort_stream &&
91 + new_rse && new_rse != rse)
93 + new_rse->rse_sorted = sort;
94 + sort = rse->rse_sorted = NULL;