From afc3d38954d1f8b43a42b11a6c4b74b567b288ee Mon Sep 17 00:00:00 2001 From: arnobrinkman Date: Sat, 15 Feb 2003 01:35:19 +0000 Subject: [PATCH] More optimizer enhancements. When an equal-node and other nodes (geq, leq, between...) are available for an index retrieval, then use the equal node always instead of the others. --- src/jrd/opt.cpp | 72 ++++++++++++++++++++++++++++--------------------- 1 file changed, 42 insertions(+), 30 deletions(-) diff --git a/src/jrd/opt.cpp b/src/jrd/opt.cpp index 676ab8a817..ca9bf73bc3 100644 --- a/src/jrd/opt.cpp +++ b/src/jrd/opt.cpp @@ -5603,7 +5603,7 @@ static SSHORT match_index(TDBB tdbb, /* match the field to an index, if possible, and save the value to be matched as either the lower or upper bound for retrieval, or both */ - for (i = 0, ptr = opt->opt_rpt; i < idx->idx_count; i++, ptr++) + for (i = 0, ptr = opt->opt_rpt; i < idx->idx_count; i++, ptr++) { if #ifdef EXPRESSION_INDICES (idx->idx_expression || @@ -5614,39 +5614,51 @@ static SSHORT match_index(TDBB tdbb, #endif { ++count; + /* AB: If we have already an exact match don't + override it with worser matches, but increment the + count so that the node will be marked as matched! */ + if (ptr->opt_match && ptr->opt_match->nod_type == nod_eql) { + break; + } switch (boolean->nod_type) { - case nod_between: - if (!forward || - !computable(opt->opt_csb, boolean->nod_arg[2], stream, - TRUE)) return 0; - ptr->opt_lower = value; - ptr->opt_upper = boolean->nod_arg[2]; - ptr->opt_match = boolean; - break; - case nod_eql: - ptr->opt_lower = ptr->opt_upper = value; - ptr->opt_match = boolean; - break; - case nod_gtr: - case nod_geq: - if (forward) + case nod_between: + if (!forward || !computable(opt->opt_csb, + boolean->nod_arg[2], stream, TRUE)) { + return 0; + } ptr->opt_lower = value; - else - ptr->opt_upper = value; - ptr->opt_match = boolean; - break; - case nod_lss: - case nod_leq: - if (forward) - ptr->opt_upper = value; - else - ptr->opt_lower = value; - ptr->opt_match = boolean; - break; - default: /* Shut up compiler warnings */ - break; + ptr->opt_upper = boolean->nod_arg[2]; + ptr->opt_match = boolean; + break; + case nod_eql: + ptr->opt_lower = ptr->opt_upper = value; + ptr->opt_match = boolean; + break; + case nod_gtr: + case nod_geq: + if (forward) { + ptr->opt_lower = value; + } + else { + ptr->opt_upper = value; + } + ptr->opt_match = boolean; + break; + case nod_lss: + case nod_leq: + if (forward) { + ptr->opt_upper = value; + } + else { + ptr->opt_lower = value; + } + ptr->opt_match = boolean; + break; + default: /* Shut up compiler warnings */ + break; } } + } return count; }