From: <di...@us...> - 2011-02-22 12:21:50
|
Revision: 52436 http://firebird.svn.sourceforge.net/firebird/?rev=52436&view=rev Author: dimitr Date: 2011-02-22 12:21:43 +0000 (Tue, 22 Feb 2011) Log Message: ----------- Better solution for CORE-3355, as suggested by Vlad. Modified Paths: -------------- firebird/branches/B2_1_Release/src/jrd/Optimizer.cpp firebird/branches/B2_1_Release/src/jrd/btr.cpp firebird/branches/B2_1_Release/src/jrd/opt.cpp Modified: firebird/branches/B2_1_Release/src/jrd/Optimizer.cpp =================================================================== --- firebird/branches/B2_1_Release/src/jrd/Optimizer.cpp 2011-02-22 10:12:22 UTC (rev 52435) +++ firebird/branches/B2_1_Release/src/jrd/Optimizer.cpp 2011-02-22 12:21:43 UTC (rev 52436) @@ -2315,6 +2315,8 @@ // check datatypes to ensure that the index scan is guaranteed // to deliver correct results + bool excludeBound = (boolean->nod_type == nod_gtr || boolean->nod_type == nod_lss); + if (value) { dsc desc1, desc2; CMP_get_desc(tdbb, optimizer->opt_csb, match, &desc1); @@ -2351,6 +2353,11 @@ value2 = cast; } } + // for "DATE <op> TIMESTAMP" we need <op> to include the boundary value + else if (desc1.dsc_dtype == dtype_sql_date && desc2.dsc_dtype == dtype_timestamp) + { + excludeBound = false; + } } // match the field to an index, if possible, and save the value to be matched @@ -2359,14 +2366,13 @@ const bool isDesc = (indexScratch->idx->idx_flags & idx_descending); int count = 0; IndexScratchSegment** segment = indexScratch->segments.begin(); - for (int i = 0; i < indexScratch->idx->idx_count; i++) { - + for (int i = 0; i < indexScratch->idx->idx_count; i++) + { if ((indexScratch->idx->idx_flags & idx_expressn) || (USHORT)(IPTR) match->nod_arg[e_fld_id] == indexScratch->idx->idx_rpt[i].idx_field) { - - switch (boolean->nod_type) { - + switch (boolean->nod_type) + { case nod_between: if (!forward || !OPT_computable(optimizer->opt_csb, value2, @@ -2416,9 +2422,9 @@ (segment[i]->scanType == segmentScanBetween))) { if (forward != isDesc) // (forward && !isDesc || !forward && isDesc) - segment[i]->excludeLower = (boolean->nod_type == nod_gtr); + segment[i]->excludeLower = excludeBound; else - segment[i]->excludeUpper = (boolean->nod_type == nod_gtr); + segment[i]->excludeUpper = excludeBound; if (forward) { @@ -2447,9 +2453,9 @@ (segment[i]->scanType == segmentScanBetween))) { if (forward != isDesc) - segment[i]->excludeUpper = (boolean->nod_type == nod_lss); + segment[i]->excludeUpper = excludeBound; else - segment[i]->excludeLower = (boolean->nod_type == nod_lss); + segment[i]->excludeLower = excludeBound; if (forward) { @@ -2470,7 +2476,6 @@ } break; - case nod_starts: // Check if validate for using index if (!forward || !validateStarts(indexScratch, boolean, i)) { @@ -2515,7 +2520,6 @@ // If this is the first segment, then this index is a candidate. indexScratch->candidate = true; } - } } Modified: firebird/branches/B2_1_Release/src/jrd/btr.cpp =================================================================== --- firebird/branches/B2_1_Release/src/jrd/btr.cpp 2011-02-22 10:12:22 UTC (rev 52435) +++ firebird/branches/B2_1_Release/src/jrd/btr.cpp 2011-02-22 12:21:43 UTC (rev 52436) @@ -2302,11 +2302,15 @@ } else if (target.dsc_dtype == dtype_sql_date) { - return (DTYPE_IS_TEXT(source.dsc_dtype) || source.dsc_dtype == dtype_sql_date); + return (DTYPE_IS_TEXT(source.dsc_dtype) || + source.dsc_dtype == dtype_sql_date || + source.dsc_dtype == dtype_timestamp); } else if (target.dsc_dtype == dtype_sql_time) { - return (DTYPE_IS_TEXT(source.dsc_dtype) || source.dsc_dtype == dtype_sql_time); + return (DTYPE_IS_TEXT(source.dsc_dtype) || + source.dsc_dtype == dtype_sql_time || + source.dsc_dtype == dtype_timestamp); } else if (target.dsc_dtype == dtype_timestamp) { Modified: firebird/branches/B2_1_Release/src/jrd/opt.cpp =================================================================== --- firebird/branches/B2_1_Release/src/jrd/opt.cpp 2011-02-22 10:12:22 UTC (rev 52435) +++ firebird/branches/B2_1_Release/src/jrd/opt.cpp 2011-02-22 12:21:43 UTC (rev 52436) @@ -1171,21 +1171,33 @@ for (tail = opt->opt_segments; (tail->opt_lower || tail->opt_upper) && tail->opt_match && (tail < end); tail++) { - switch (tail->opt_match->nod_type) + if (tail->opt_match->nod_type == nod_gtr || + tail->opt_match->nod_type == nod_lss) { - case nod_gtr: - if (retrieval->irb_generic & irb_descending) + dsc desc1, desc2; + CMP_get_desc(tdbb, opt->opt_csb, tail->opt_match->nod_arg[0], &desc1); + CMP_get_desc(tdbb, opt->opt_csb, tail->opt_match->nod_arg[1], &desc2); + + // for "DATE <op> TIMESTAMP" we need <op> to include the boundary value + if (desc1.dsc_dtype == dtype_sql_date && desc2.dsc_dtype == dtype_timestamp) + break; + + if (retrieval->irb_generic & irb_descending) + { + if (tail->opt_match->nod_type == nod_gtr) includeUpper = false; else includeLower = false; - break; - - case nod_lss: - if (retrieval->irb_generic & irb_descending) + } + else + { + if (tail->opt_match->nod_type == nod_gtr) includeLower = false; else includeUpper = false; - break; + } + + break; } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |