diff options
-rw-r--r-- | Bugzilla/Search.pm | 6 | ||||
-rw-r--r-- | Bugzilla/Search/Clause.pm | 36 | ||||
-rw-r--r-- | Bugzilla/Search/Condition.pm | 9 | ||||
-rw-r--r-- | Bugzilla/Search/Quicksearch.pm | 11 | ||||
-rw-r--r-- | template/en/default/pages/release-notes.html.tmpl | 25 | ||||
-rw-r--r-- | xt/lib/Bugzilla/Test/Search/Constants.pm | 83 | ||||
-rw-r--r-- | xt/lib/Bugzilla/Test/Search/FieldTest.pm | 32 |
7 files changed, 163 insertions, 39 deletions
diff --git a/Bugzilla/Search.pm b/Bugzilla/Search.pm index f3b698d0d..a27d3fe64 100644 --- a/Bugzilla/Search.pm +++ b/Bugzilla/Search.pm @@ -780,7 +780,7 @@ sub _sql { my ($self) = @_; return $self->{sql} if $self->{sql}; my $dbh = Bugzilla->dbh; - + my ($joins, $clause) = $self->_charts_to_conditions(); if (!$clause->as_string @@ -2485,9 +2485,9 @@ sub _content_matches { my ($chart_id, $joins, $fields, $operator, $value) = @$args{qw(chart_id joins fields operator value)}; my $dbh = Bugzilla->dbh; - + # "content" is an alias for columns containing text for which we - # can search a full-text index and retrieve results by relevance, + # can search a full-text index and retrieve results by relevance, # currently just bug comments (and summaries to some degree). # There's only one way to search a full-text index, so we only # accept the "matches" operator, which is specific to full-text diff --git a/Bugzilla/Search/Clause.pm b/Bugzilla/Search/Clause.pm index 38f6f30be..89210babb 100644 --- a/Bugzilla/Search/Clause.pm +++ b/Bugzilla/Search/Clause.pm @@ -98,25 +98,29 @@ sub walk_conditions { sub as_string { my ($self) = @_; - my @strings; - foreach my $child (@{ $self->children }) { - next if $child->isa(__PACKAGE__) && !$child->has_translated_conditions; - next if $child->isa('Bugzilla::Search::Condition') - && !$child->translated; + if (!$self->{sql}) { + my @strings; + foreach my $child (@{ $self->children }) { + next if $child->isa(__PACKAGE__) && !$child->has_translated_conditions; + next if $child->isa('Bugzilla::Search::Condition') + && !$child->translated; - my $string = $child->as_string; - if ($self->joiner eq 'AND') { - $string = "( $string )" if $string =~ /OR/; - } - else { - $string = "( $string )" if $string =~ /AND/; + my $string = $child->as_string; + next unless $string; + if ($self->joiner eq 'AND') { + $string = "( $string )" if $string =~ /OR/; + } + else { + $string = "( $string )" if $string =~ /AND/; + } + push(@strings, $string); } - push(@strings, $string); + + my $sql = join(' ' . $self->joiner . ' ', @strings); + $sql = "NOT( $sql )" if $sql && $self->negate; + $self->{sql} = $sql; } - - my $sql = join(' ' . $self->joiner . ' ', @strings); - $sql = "NOT( $sql )" if $sql && $self->negate; - return $sql; + return $self->{sql}; } # Search.pm converts URL parameters to Clause objects. This helps do the diff --git a/Bugzilla/Search/Condition.pm b/Bugzilla/Search/Condition.pm index 2268da197..167b4f01e 100644 --- a/Bugzilla/Search/Condition.pm +++ b/Bugzilla/Search/Condition.pm @@ -32,9 +32,16 @@ sub new { } sub field { return $_[0]->{field} } -sub operator { return $_[0]->{operator} } sub value { return $_[0]->{value} } +sub operator { + my ($self, $value) = @_; + if (@_ == 2) { + $self->{operator} = $value; + } + return $self->{operator}; +} + sub fov { my ($self) = @_; return ($self->field, $self->operator, $self->value); diff --git a/Bugzilla/Search/Quicksearch.pm b/Bugzilla/Search/Quicksearch.pm index 1fca2e322..61e4a926a 100644 --- a/Bugzilla/Search/Quicksearch.pm +++ b/Bugzilla/Search/Quicksearch.pm @@ -382,9 +382,14 @@ sub _handle_field_names { # Flag and requestee shortcut if ($or_operand =~ /^(?:flag:)?([^\?]+\?)([^\?]*)$/) { - addChart('flagtypes.name', 'substring', $1, $negate); - $chart++; $and = $or = 0; # Next chart for boolean AND - addChart('requestees.login_name', 'substring', $2, $negate); + my ($flagtype, $requestee) = ($1, $2); + addChart('flagtypes.name', 'substring', $flagtype, $negate); + if ($requestee) { + # AND + $chart++; + $and = $or = 0; + addChart('requestees.login_name', 'substring', $requestee, $negate); + } return 1; } diff --git a/template/en/default/pages/release-notes.html.tmpl b/template/en/default/pages/release-notes.html.tmpl index 32940b715..3d5b36b45 100644 --- a/template/en/default/pages/release-notes.html.tmpl +++ b/template/en/default/pages/release-notes.html.tmpl @@ -53,6 +53,31 @@ <h2 id="v42_point">Updates in this 4.2.x Release</h2> +<h3>4.2.6</h3> + +<p>The following important fixes/changes have been made in this release:</p> + +<ul> + <li>MySQL 5.6 is now supported. + (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=852560">[% terms.Bug %] 852560</a>)</li> + <li>A regression introduced in [% terms.Bugzilla %] 4.2.4 made Oracle crash + when installing [% terms.Bugzilla %] for the first time. + (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=858911">[% terms.Bug %] 858911</a>)</li> + <li>If a custom field depends on a product, component or classification, + the "mandatory" bit was ignored on [% terms.bug %] creation. + (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=782210">[% terms.Bug %] 782210</a>)</li> + <li>Queries involving flags were broken in several ways. These queries + have been fixed. + (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=828344">[% terms.Bug %] 828344</a>)</li> + <li>Tabular reports involving the empty resolution did not link [% terms.bug %] + counts correctly. + (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=212471">[% terms.Bug %] 212471</a>)</li> + <li>The <kbd>B[%%]ug.search</kbd> WebService method was returning all visible + [%+ terms.bugs %] when called with no arguments, ignoring the + <kbd>max_search_results</kbd> and <kbd>search_allow_no_criteria</kbd> parameters. + (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=859118">[% terms.Bug %] 859118</a>)</li> +</ul> + <h3>4.2.5</h3> <p>This release fixes one security issue. See the diff --git a/xt/lib/Bugzilla/Test/Search/Constants.pm b/xt/lib/Bugzilla/Test/Search/Constants.pm index 512d180d9..051570ff8 100644 --- a/xt/lib/Bugzilla/Test/Search/Constants.pm +++ b/xt/lib/Bugzilla/Test/Search/Constants.pm @@ -197,11 +197,14 @@ use constant GREATERTHAN_BROKEN => ( ); # allwords and allwordssubstr have these broken tests in common. -# -# allwordssubstr on cc fields matches against a single cc, -# instead of matching against all ccs on a bug. use constant ALLWORDS_BROKEN => ( + # allwordssubstr on cc fields matches against a single cc, + # instead of matching against all ccs on a bug. cc => { contains => [1] }, + # bug 828344 changed how these searches operate to revert back to the 4.0 + # behavour, so these tests need to be updated (bug 849117). + 'flagtypes.name' => { contains => [1] }, + longdesc => { contains => [1] }, ); # Fields that don't generally work at all with changed* searches, but @@ -330,6 +333,24 @@ use constant KNOWN_BROKEN => { # This should probably search the reporter. creation_ts => { contains => [1] }, }, + notequals => { + 'flagtypes.name' => { contains => [1, 5] }, + longdesc => { contains => [1] }, + }, + notregexp => { + 'flagtypes.name' => { contains => [1, 5] }, + longdesc => { contains => [1] }, + }, + notsubstring => { + 'flagtypes.name' => { contains => [5] }, + longdesc => { contains => [1] }, + }, + nowords => { + 'flagtypes.name' => { contains => [1, 5] }, + }, + nowordssubstr => { + 'flagtypes.name' => { contains => [5] }, + }, }; ################### @@ -360,17 +381,34 @@ use constant CHANGED_FROM_TO_BROKEN_NOT => ( # These are field/operator combinations that are broken when run under NOT(). use constant BROKEN_NOT => { - allwords => { - cc => { contains => [1] }, + allwords => { + cc => { contains => [1] }, + 'flagtypes.name' => { contains => [1, 5] }, + longdesc => { contains => [1] }, }, 'allwords-<1> <2>' => { cc => { }, }, allwordssubstr => { - cc => { contains => [1] }, + cc => { contains => [1] }, + 'flagtypes.name' => { contains => [5, 6] }, + longdesc => { contains => [1] }, }, 'allwordssubstr-<1>,<2>' => { - cc => { }, + cc => { }, + longdesc => { contains => [1] }, + }, + anyexact => { + 'flagtypes.name' => { contains => [1, 2, 5] }, + }, + anywords => { + 'flagtypes.name' => { contains => [1, 2, 5] }, + }, + anywordssubstr => { + 'flagtypes.name' => { contains => [5] }, + }, + casesubstring => { + 'flagtypes.name' => { contains => [5] }, }, changedafter => { "attach_data.thedata" => { contains => [2, 3, 4] }, @@ -397,7 +435,6 @@ use constant BROKEN_NOT => { dependson => { contains => [1, 3] }, work_time => { contains => [1] }, FIELD_TYPE_BUG_ID, { contains => [1 .. 4] }, - }, changedto => { CHANGED_BROKEN_NOT, @@ -406,10 +443,38 @@ use constant BROKEN_NOT => { "remaining_time" => { contains => [1] }, }, greaterthan => { - cc => { contains => [1] }, + cc => { contains => [1] }, + 'flagtypes.name' => { contains => [5] }, }, greaterthaneq => { cc => { contains => [1] }, + 'flagtypes.name' => { contains => [2, 5] }, + }, + equals => { + 'flagtypes.name' => { contains => [1, 5] }, + }, + notequals => { + longdesc => { contains => [1] }, + }, + notregexp => { + longdesc => { contains => [1] }, + }, + notsubstring => { + longdesc => { contains => [1] }, + }, + lessthan => { + 'flagtypes.name' => { contains => [5] }, + }, + lessthaneq => { + 'flagtypes.name' => { contains => [1, 5] }, + }, + regexp => { + 'flagtypes.name' => { contains => [1, 5] }, + longdesc => { contains => [1] }, + }, + substring => { + 'flagtypes.name' => { contains => [5] }, + longdesc => { contains => [1] }, }, }; diff --git a/xt/lib/Bugzilla/Test/Search/FieldTest.pm b/xt/lib/Bugzilla/Test/Search/FieldTest.pm index bd5fd905a..a625127c9 100644 --- a/xt/lib/Bugzilla/Test/Search/FieldTest.pm +++ b/xt/lib/Bugzilla/Test/Search/FieldTest.pm @@ -28,6 +28,7 @@ use strict; use warnings; use Bugzilla::Search; use Bugzilla::Test::Search::Constants; +use Bugzilla::Util qw(trim); use Data::Dumper; use Scalar::Util qw(blessed); @@ -72,6 +73,13 @@ sub bug { my $self = shift; return $self->search_test->bug(@_); } +sub number { + my ($self, $id) = @_; + foreach my $number (1..NUM_BUGS) { + return $number if $self->search_test->bug($number)->id == $id; + } + return 0; +} # The name displayed for this test by Test::More. Used in test descriptions. sub name { @@ -147,9 +155,18 @@ sub translated_value { return $self->{translated_value}; } # Used in failure diagnostic messages. -sub debug_value { - my ($self) = @_; - return "Value: '" . $self->translated_value . "'"; +sub debug_fail { + my ($self, $number, $results, $sql) = @_; + my @expected = @{ $self->test->{contains} }; + my @results = sort + map { $self->number($_) } + map { $_->[0] } + @$results; + return + " Value: '" . $self->translated_value . "'\n" . + "Expected: [" . join(',', @expected) . "]\n" . + " Results: [" . join(',', @results) . "]\n" . + trim($sql) . "\n"; } # True for a bug if we ran the "transform" function on it and the @@ -184,6 +201,7 @@ sub bug_is_contained { # The tests we know are broken for this operator/field combination. sub _known_broken { my ($self, $constant, $skip_pg_check) = @_; + $constant ||= KNOWN_BROKEN; my $field = $self->field; my $type = $self->field_object->type; @@ -192,8 +210,8 @@ sub _known_broken { my $value_name = "$operator-$value"; if (my $extra_name = $self->test->{extra_name}) { $value_name .= "-$extra_name"; - } - + } + my $value_broken = $constant->{$value_name}->{$field}; $value_broken ||= $constant->{$value_name}->{$type}; return $value_broken if $value_broken; @@ -600,12 +618,12 @@ sub _test_content_for_bug { if ($self->bug_is_contained($number)) { ok($result_ids{$bug_id}, "$name: contains bug $number ($bug_id)") - or diag Dumper($results) . $self->debug_value . "\n\nSQL: $sql"; + or diag $self->debug_fail($number, $results, $sql); } else { ok(!$result_ids{$bug_id}, "$name: does not contain bug $number ($bug_id)") - or diag Dumper($results) . $self->debug_value . "\n\nSQL: $sql"; + or diag $self->debug_fail($number, $results, $sql); } } } |