Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
bugzilla
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
etersoft
bugzilla
Commits
1d0b78d2
Commit
1d0b78d2
authored
Apr 18, 2013
by
Byron Jones
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Bug 828344: Make "contains all of the words" look for all words within the same comment or flag
r=LpSolit, a=LpSolit
parent
9f72d3d0
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
138 additions
and
50 deletions
+138
-50
Search.pm
Bugzilla/Search.pm
+117
-31
Clause.pm
Bugzilla/Search/Clause.pm
+20
-16
Quicksearch.pm
Bugzilla/Search/Quicksearch.pm
+1
-3
No files found.
Bugzilla/Search.pm
View file @
1d0b78d2
...
...
@@ -265,12 +265,14 @@ use constant OPERATOR_FIELD_OVERRIDE => {
},
dependson
=>
MULTI_SELECT_OVERRIDE
,
keywords
=>
MULTI_SELECT_OVERRIDE
,
'flagtypes.name'
=>
MULTI_SELECT_OVERRIDE
,
'flagtypes.name'
=>
{
_non_changed
=>
\&
_flagtypes_nonchanged
,
},
longdesc
=>
{
%
{
MULTI_SELECT_OVERRIDE
()
},
changedby
=>
\&
_long_desc_changedby
,
changedbefore
=>
\&
_long_desc_changedbefore_after
,
changedafter
=>
\&
_long_desc_changedbefore_after
,
_non_changed
=>
\&
_long_desc_nonchanged
,
},
'longdescs.count'
=>
{
changedby
=>
\&
_long_desc_changedby
,
...
...
@@ -750,8 +752,16 @@ 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
&&
!
Bugzilla
->
params
->
{
'search_allow_no_criteria'
}
&&
!
$self
->
{
allow_unlimited
})
{
ThrowUserError
(
'buglist_parameters_required'
);
}
my
$select
=
join
(
', '
,
$self
->
_sql_select
);
my
$from
=
$self
->
_sql_from
(
$joins
);
my
$where
=
$self
->
_sql_where
(
$clause
);
...
...
@@ -1291,14 +1301,7 @@ sub _sql_where {
# SQL a bit more readable for debugging.
my
$where
=
join
(
"\n AND "
,
$self
->
_standard_where
);
my
$clause_sql
=
$main_clause
->
as_string
;
if
(
$clause_sql
)
{
$where
.=
"\n AND "
.
$clause_sql
;
}
elsif
(
!
Bugzilla
->
params
->
{
'search_allow_no_criteria'
}
&&
!
$self
->
{
allow_unlimited
})
{
ThrowUserError
(
'buglist_parameters_required'
);
}
$where
.=
"\n AND "
.
$clause_sql
if
$clause_sql
;
return
$where
;
}
...
...
@@ -1978,24 +1981,13 @@ sub _quote_unless_numeric {
sub
build_subselect
{
my
(
$outer
,
$inner
,
$table
,
$cond
,
$negate
)
=
@_
;
if
(
$table
eq
'longdescs'
)
{
# There is no index on the longdescs.thetext column and so it takes
# a long time to scan the whole table unconditionally. For this table,
# we return the subselect and let the DB optimizer restrict the search
# to some given bug list only based on other search criteria available.
my
$not
=
$negate
?
"NOT"
:
""
;
return
"$outer $not IN (SELECT DISTINCT $inner FROM $table WHERE $cond)"
;
}
else
{
# Execute subselects immediately to avoid dependent subqueries, which are
# large performance hits on MySql
my
$q
=
"SELECT DISTINCT $inner FROM $table WHERE $cond"
;
my
$dbh
=
Bugzilla
->
dbh
;
my
$list
=
$dbh
->
selectcol_arrayref
(
$q
);
return
$negate
?
"1=1"
:
"1=2"
unless
@$list
;
return
$dbh
->
sql_in
(
$outer
,
$list
,
$negate
);
}
# Execute subselects immediately to avoid dependent subqueries, which are
# large performance hits on MySql
my
$q
=
"SELECT DISTINCT $inner FROM $table WHERE $cond"
;
my
$dbh
=
Bugzilla
->
dbh
;
my
$list
=
$dbh
->
selectcol_arrayref
(
$q
);
return
$negate
?
"1=1"
:
"1=2"
unless
@$list
;
return
$dbh
->
sql_in
(
$outer
,
$list
,
$negate
);
}
# Used by anyexact to get the list of input values. This allows us to
...
...
@@ -2416,14 +2408,51 @@ sub _long_desc_changedbefore_after {
}
}
sub
_long_desc_nonchanged
{
my
(
$self
,
$args
)
=
@_
;
my
(
$chart_id
,
$operator
,
$value
,
$joins
,
$bugs_table
)
=
@$args
{
qw(chart_id operator value joins bugs_table)
};
my
$dbh
=
Bugzilla
->
dbh
;
my
$table
=
"longdescs_$chart_id"
;
my
$join_args
=
{
chart_id
=>
$chart_id
,
sequence
=>
$chart_id
,
field
=>
'longdesc'
,
full_field
=>
"$table.thetext"
,
operator
=>
$operator
,
value
=>
$value
,
all_values
=>
$value
,
quoted
=>
$dbh
->
quote
(
$value
),
joins
=>
[]
,
bugs_table
=>
$bugs_table
,
};
$self
->
_do_operator_function
(
$join_args
);
# If the user is not part of the insiders group, they cannot see
# private comments
if
(
!
$self
->
_user
->
is_insider
)
{
$join_args
->
{
term
}
.=
" AND $table.isprivate = 0"
;
}
my
$join
=
{
table
=>
'longdescs'
,
as
=>
$table
,
extra
=>
[
$join_args
->
{
term
}
],
};
push
(
@$joins
,
$join
);
$args
->
{
term
}
=
"$table.comment_id IS NOT NULL"
;
}
sub
_content_matches
{
my
(
$self
,
$args
)
=
@_
;
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
...
...
@@ -2671,6 +2700,63 @@ sub _multiselect_multiple {
}
}
sub
_flagtypes_nonchanged
{
my
(
$self
,
$args
)
=
@_
;
my
(
$chart_id
,
$operator
,
$value
,
$joins
,
$bugs_table
)
=
@$args
{
qw(chart_id operator value joins bugs_table)
};
my
$dbh
=
Bugzilla
->
dbh
;
my
$join
;
# join to the attachments table
my
$attach_table
=
"attachments_$chart_id"
;
$join
=
{
table
=>
'attachments'
,
as
=>
$attach_table
,
from
=>
"$bugs_table.bug_id"
,
to
=>
"bug_id"
,
extra
=>
[
(
$self
->
_user
->
is_insider
?
''
:
"$attach_table.isprivate = 0"
)
],
};
push
(
@$joins
,
$join
);
# join to the flags table
my
$flags_table
=
"flags_$chart_id"
;
$join
=
{
table
=>
'flags'
,
as
=>
$flags_table
,
from
=>
"$bugs_table.bug_id"
,
to
=>
"bug_id"
,
extra
=>
[
"($flags_table.attach_id = $attach_table.attach_id "
.
" OR $flags_table.attach_id IS NULL)"
],
};
push
(
@$joins
,
$join
);
# join to the flagtypes table
my
$flagtypes_table
=
"flagtypes_$chart_id"
;
$join
=
{
table
=>
'flagtypes'
,
as
=>
$flagtypes_table
,
from
=>
"$flags_table.type_id"
,
to
=>
"id"
,
};
push
(
@$joins
,
$join
);
# join to the profiles table for the requestee
my
$flag_profile_table
=
"flag_profiles_$chart_id"
;
$join
=
{
table
=>
'profiles'
,
as
=>
$flag_profile_table
,
from
=>
"$flags_table.requestee_id"
,
to
=>
"userid"
,
};
push
(
@$joins
,
$join
);
$args
->
{
full_field
}
=
$dbh
->
sql_string_concat
(
"$flagtypes_table.name"
,
"$flags_table.status"
,
"COALESCE($flag_profile_table.login_name, '')"
);
$self
->
_do_operator_function
(
$args
);
}
sub
_multiselect_nonchanged
{
my
(
$self
,
$args
)
=
@_
;
my
(
$chart_id
,
$joins
,
$field
,
$operator
)
=
...
...
Bugzilla/Search/Clause.pm
View file @
1d0b78d2
...
...
@@ -84,25 +84,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
...
...
Bugzilla/Search/Quicksearch.pm
View file @
1d0b78d2
...
...
@@ -364,10 +364,8 @@ sub _handle_field_names {
my
(
$or_operand
,
$negate
,
$unknownFields
,
$ambiguous_fields
)
=
@_
;
# Flag and requestee shortcut
if
(
$or_operand
=~
/^(?:flag:)?([^\?]+\?
)(
[^\?]*)$/
)
{
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
);
return
1
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment