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
4291fb9f
Commit
4291fb9f
authored
Jun 11, 2010
by
Max Kanat-Alexander
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Bug 476722: Refactor Search.pm's funcdefs into a series of constants
and functions for interpreting search charts. r=jjclark, a=mkanat
parent
4f2d925a
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
424 additions
and
327 deletions
+424
-327
Search.pm
Bugzilla/Search.pm
+424
-327
No files found.
Bugzilla/Search.pm
View file @
4291fb9f
...
...
@@ -55,6 +55,180 @@ use Bugzilla::Keyword;
use
Date::
Format
;
use
Date::
Parse
;
# If you specify a search type in the boolean charts, this describes
# which operator maps to which internal function here.
use
constant
OPERATORS
=>
{
equals
=>
\&
_equals
,
notequals
=>
\&
_notequals
,
casesubstring
=>
\&
_casesubstring
,
substring
=>
\&
_substring
,
substr
=>
\&
_substring
,
notsubstring
=>
\&
_notsubstring
,
regexp
=>
\&
_regexp
,
notregexp
=>
\&
_notregexp
,
lessthan
=>
\&
_lessthan
,
lessthaneq
=>
\&
_lessthaneq
,
matches
=>
sub
{
ThrowUserError
(
"search_content_without_matches"
);
},
notmatches
=>
sub
{
ThrowUserError
(
"search_content_without_matches"
);
},
greaterthan
=>
\&
_greaterthan
,
greaterthaneq
=>
\&
_greaterthaneq
,
anyexact
=>
\&
_anyexact
,
anywordssubstr
=>
\&
_anywordsubstr
,
allwordssubstr
=>
\&
_allwordssubstr
,
nowordssubstr
=>
\&
_nowordssubstr
,
anywords
=>
\&
_anywords
,
allwords
=>
\&
_allwords
,
nowords
=>
\&
_nowords
,
changedbefore
=>
\&
_changedbefore_changedafter
,
changedafter
=>
\&
_changedbefore_changedafter
,
changedfrom
=>
\&
_changedfrom_changedto
,
changedto
=>
\&
_changedfrom_changedto
,
changedby
=>
\&
_changedby
,
};
use
constant
OPERATOR_FIELD_OVERRIDE
=>
{
# User fields
'attachments.submitter'
=>
{
_default
=>
\&
_attachments_submitter
,
},
assigned_to
=>
{
_non_changed
=>
\&
_assigned_to_reporter_nonchanged
,
},
cc
=>
{
_non_changed
=>
\&
_cc_nonchanged
,
},
commenter
=>
{
_default
=>
\&
_commenter
,
},
'requestees.login_name'
=>
{
_default
=>
\&
_requestees_login_name
,
},
'setters.login_name'
=>
{
_default
=>
\&
_setters_login_name
,
},
qa_contact
=>
{
_non_changed
=>
\&
_qa_contact_nonchanged
,
},
# General Bug Fields
alias
=>
{
_non_changed
=>
\&
_alias_nonchanged
,
},
'attach_data.thedata'
=>
{
_non_changed
=>
\&
_attach_data_thedata
,
},
# We check all attachment fields against this.
'attachments'
=>
{
_default
=>
\&
_attachments
,
},
blocked
=>
{
_non_changed
=>
\&
_blocked_nonchanged
,
},
bug_group
=>
{
_non_changed
=>
\&
_bug_group_nonchanged
,
},
changedin
=>
{
_default
=>
\&
_changedin_days_elapsed
,
},
classification
=>
{
_non_changed
=>
\&
_classification_nonchanged
,
},
component
=>
{
_non_changed
=>
\&
_component_nonchanged
,
},
content
=>
{
matches
=>
\&
_content_matches
,
notmatches
=>
\&
_content_matches
,
_default
=>
sub
{
ThrowUserError
(
"search_content_without_matches"
);
},
},
days_elapsed
=>
{
_default
=>
\&
_changedin_days_elapsed
,
},
dependson
=>
{
_non_changed
=>
\&
_dependson_nonchanged
,
},
keywords
=>
{
equals
=>
\&
_keywords_exact
,
notequals
=>
\&
_keywords_exact
,
anyexact
=>
\&
_keywords_exact
,
anyword
=>
\&
_keywords_exact
,
allwords
=>
\&
_keywords_exact
,
nowords
=>
\&
_keywords_exact
,
_non_changed
=>
\&
_keywords_nonchanged
,
},
'flagtypes.name'
=>
{
_default
=>
\&
_flagtypes_name
,
},
longdesc
=>
{
changedby
=>
\&
_long_desc_changedby
,
changedbefore
=>
\&
_long_desc_changedbefore_after
,
changedafter
=>
\&
_long_desc_changedbefore_after
,
_default
=>
\&
_long_desc
,
},
'longdescs.isprivate'
=>
{
_default
=>
\&
_longdescs_isprivate
,
},
owner_idle_time
=>
{
greaterthan
=>
\&
_owner_idle_time_greater_less
,
greaterthaneq
=>
\&
_owner_idle_time_greater_less
,
lessthan
=>
\&
_owner_idle_time_greater_less
,
lessthaneq
=>
\&
_owner_idle_time_greater_less
,
},
product
=>
{
_non_changed
=>
\&
_product_nonchanged
,
},
# Custom multi-select fields
_multi_select
=>
{
notequals
=>
\&
_multiselect_negative
,
notregexp
=>
\&
_multiselect_negative
,
notsubstring
=>
\&
_multiselect_negative
,
nowords
=>
\&
_multiselect_negative
,
nowordssubstr
=>
\&
_multiselect_negative
,
allwords
=>
\&
_multiselect_multiple
,
allwordssubstr
=>
\&
_multiselect_multiple
,
anyexact
=>
\&
_multiselect_multiple
,
_non_changed
=>
\&
_multiselect_nonchanged
,
},
# Timetracking Fields
percentage_complete
=>
{
_default
=>
\&
_percentage_complete
,
},
work_time
=>
{
changedby
=>
\&
_work_time_changedby
,
changedbefore
=>
\&
_work_time_changedbefore_after
,
changedafter
=>
\&
_work_time_changedbefore_after
,
_default
=>
\&
_work_time
,
},
};
# These are fields where special action is taken depending on the
# *value* passed in to the chart, sometimes.
use
constant
SPECIAL_PARSING
=>
{
# Pronoun Fields (Ones that can accept %user%, etc.)
assigned_to
=>
\&
_contact_pronoun
,
cc
=>
\&
_cc_pronoun
,
commenter
=>
\&
_commenter_pronoun
,
qa_contact
=>
\&
_contact_pronoun
,
reporter
=>
\&
_contact_pronoun
,
# Date Fields that accept the 1d, 1w, 1m, 1y, etc. format.
creation_ts
=>
\&
_timestamp_translate
,
deadline
=>
\&
_timestamp_translate
,
delta_ts
=>
\&
_timestamp_translate
,
};
# Backwards compatibility for times that we changed the names of fields.
use
constant
FIELD_MAP
=>
{
long_desc
=>
'longdesc'
,
};
# A SELECTed expression that we use as a placeholder if somebody selects
# <none> for the X, Y, or Z axis in report.cgi.
use
constant
EMPTY_COLUMN
=>
'-1'
;
...
...
@@ -219,7 +393,6 @@ sub init {
my
@groupby
;
my
@specialchart
;
my
@andlist
;
my
%
chartfields
;
my
%
special_order
=
%
{
SPECIAL_ORDER
()};
my
%
special_order_join
=
%
{
SPECIAL_ORDER_JOIN
()};
...
...
@@ -588,120 +761,6 @@ sub init {
}
}
my
$multi_fields
=
join
(
'|'
,
map
(
$_
->
name
,
@multi_select_fields
));
my
$chartid
;
my
$sequence
=
0
;
my
$f
;
my
$ff
;
my
$t
;
my
$q
;
my
$v
;
my
$term
;
my
%
funcsbykey
;
my
%
func_args
=
(
'chartid'
=>
\
$chartid
,
'sequence'
=>
\
$sequence
,
'f'
=>
\
$f
,
'ff'
=>
\
$ff
,
't'
=>
\
$t
,
'v'
=>
\
$v
,
'q'
=>
\
$q
,
'term'
=>
\
$term
,
'funcsbykey'
=>
\%
funcsbykey
,
'supptables'
=>
\
@supptables
,
'wherepart'
=>
\
@wherepart
,
'having'
=>
\
@having
,
'groupby'
=>
\
@groupby
,
'chartfields'
=>
\%
chartfields
,
'fields'
=>
\
@fields
,
);
my
@funcdefs
=
(
"^(?:assigned_to|reporter|qa_contact),(?:notequals|equals|anyexact),%group\\.([^%]+)%"
=>
\&
_contact_exact_group
,
"^(?:assigned_to|reporter|qa_contact),(?:equals|anyexact),(%\\w+%)"
=>
\&
_contact_exact
,
"^(?:assigned_to|reporter|qa_contact),(?:notequals),(%\\w+%)"
=>
\&
_contact_notequals
,
"^(assigned_to|reporter),(?!changed)"
=>
\&
_assigned_to_reporter_nonchanged
,
"^qa_contact,(?!changed)"
=>
\&
_qa_contact_nonchanged
,
"^(?:cc),(?:notequals|equals|anyexact),%group\\.([^%]+)%"
=>
\&
_cc_exact_group
,
"^cc,(?:equals|anyexact),(%\\w+%)"
=>
\&
_cc_exact
,
"^cc,(?:notequals),(%\\w+%)"
=>
\&
_cc_notequals
,
"^cc,(?!changed)"
=>
\&
_cc_nonchanged
,
"^long_?desc,changedby"
=>
\&
_long_desc_changedby
,
"^long_?desc,changedbefore"
=>
\&
_long_desc_changedbefore_after
,
"^long_?desc,changedafter"
=>
\&
_long_desc_changedbefore_after
,
"^content,(?:not)?matches"
=>
\&
_content_matches
,
"^content,"
=>
sub
{
ThrowUserError
(
"search_content_without_matches"
);
},
"^(?:deadline|creation_ts|delta_ts),(?:lessthan|lessthaneq|greaterthan|greaterthaneq|equals|notequals),(?:-|\\+)?(?:\\d+)(?:[dDwWmMyY])\$"
=>
\&
_timestamp_compare
,
"^commenter,(?:equals|anyexact),(%\\w+%)"
=>
\&
_commenter_exact
,
"^commenter,"
=>
\&
_commenter
,
# The _ is allowed for backwards-compatibility with 3.2 and lower.
"^long_?desc,"
=>
\&
_long_desc
,
"^longdescs\.isprivate,"
=>
\&
_longdescs_isprivate
,
"^work_time,changedby"
=>
\&
_work_time_changedby
,
"^work_time,changedbefore"
=>
\&
_work_time_changedbefore_after
,
"^work_time,changedafter"
=>
\&
_work_time_changedbefore_after
,
"^work_time,"
=>
\&
_work_time
,
"^percentage_complete,"
=>
\&
_percentage_complete
,
"^bug_group,(?!changed)"
=>
\&
_bug_group_nonchanged
,
"^attach_data\.thedata,changed"
=>
\&
_attach_data_thedata_changed
,
"^attach_data\.thedata,"
=>
\&
_attach_data_thedata
,
"^attachments\.submitter,"
=>
\&
_attachments_submitter
,
"^attachments\..*,"
=>
\&
_attachments
,
"^flagtypes.name,"
=>
\&
_flagtypes_name
,
"^requestees.login_name,"
=>
\&
_requestees_login_name
,
"^setters.login_name,"
=>
\&
_setters_login_name
,
"^(changedin|days_elapsed),"
=>
\&
_changedin_days_elapsed
,
"^component,(?!changed)"
=>
\&
_component_nonchanged
,
"^product,(?!changed)"
=>
\&
_product_nonchanged
,
"^classification,(?!changed)"
=>
\&
_classification_nonchanged
,
"^keywords,(?:equals|notequals|anyexact|anyword|allwords|nowords)"
=>
\&
_keywords_exact
,
"^keywords,(?!changed)"
=>
\&
_keywords_nonchanged
,
"^dependson,(?!changed)"
=>
\&
_dependson_nonchanged
,
"^blocked,(?!changed)"
=>
\&
_blocked_nonchanged
,
"^alias,(?!changed)"
=>
\&
_alias_nonchanged
,
"^owner_idle_time,(greaterthan|greaterthaneq|lessthan|lessthaneq)"
=>
\&
_owner_idle_time_greater_less
,
"^($multi_fields),(?:notequals|notregexp|notsubstring|nowords|nowordssubstr)"
=>
\&
_multiselect_negative
,
"^($multi_fields),(?:allwords|allwordssubstr|anyexact)"
=>
\&
_multiselect_multiple
,
"^($multi_fields),(?!changed)"
=>
\&
_multiselect_nonchanged
,
",equals"
=>
\&
_equals
,
",notequals"
=>
\&
_notequals
,
",casesubstring"
=>
\&
_casesubstring
,
",substring"
=>
\&
_substring
,
",substr"
=>
\&
_substring
,
",notsubstring"
=>
\&
_notsubstring
,
",regexp"
=>
\&
_regexp
,
",notregexp"
=>
\&
_notregexp
,
",lessthan"
=>
\&
_lessthan
,
",lessthaneq"
=>
\&
_lessthaneq
,
",matches"
=>
sub
{
ThrowUserError
(
"search_content_without_matches"
);
},
",notmatches"
=>
sub
{
ThrowUserError
(
"search_content_without_matches"
);
},
",greaterthan"
=>
\&
_greaterthan
,
",greaterthaneq"
=>
\&
_greaterthaneq
,
",anyexact"
=>
\&
_anyexact
,
",anywordssubstr"
=>
\&
_anywordsubstr
,
",allwordssubstr"
=>
\&
_allwordssubstr
,
",nowordssubstr"
=>
\&
_nowordssubstr
,
",anywords"
=>
\&
_anywords
,
",allwords"
=>
\&
_allwords
,
",nowords"
=>
\&
_nowords
,
",(changedbefore|changedafter)"
=>
\&
_changedbefore_changedafter
,
",(changedfrom|changedto)"
=>
\&
_changedfrom_changedto
,
",changedby"
=>
\&
_changedby
,
);
my
@funcnames
;
while
(
@funcdefs
)
{
my
$key
=
shift
(
@funcdefs
);
my
$value
=
shift
(
@funcdefs
);
if
(
$key
=~
/^[^,]*$/
)
{
die
"All defs in %funcs must have a comma in their name: $key"
;
}
if
(
exists
$funcsbykey
{
$key
})
{
die
"Duplicate key in %funcs: $key"
;
}
$funcsbykey
{
$key
}
=
$value
;
push
(
@funcnames
,
$key
);
}
# first we delete any sign of "Chart #-1" from the HTML form hash
# since we want to guarantee the user didn't hide something here
my
@badcharts
=
grep
/^(field|type|value)-1-/
,
$params
->
param
();
...
...
@@ -808,64 +867,72 @@ sub init {
# $suppstring = String which is pasted into query containing all table names
# get a list of field names to verify the user-submitted chart fields against
%
chartfields
=
@
{
$dbh
->
selectcol_arrayref
(
my
%
chartfields
=
@
{
$dbh
->
selectcol_arrayref
(
q{SELECT name, id FROM fielddefs}
,
{
Columns
=>
[
1
,
2
]
})};
my
(
$sequence
,
$chartid
);
$row
=
0
;
for
(
$chart
=-
1
;
$chart
<
0
||
$params
->
param
(
"field$chart-0-0"
)
;
$chart
++
)
{
$chart
++
)
{
$chartid
=
$chart
>=
0
?
$chart
:
""
;
my
@chartandlist
=
()
;
my
@chartandlist
;
for
(
$row
=
0
;
$params
->
param
(
"field$chart-$row-0"
)
;
$row
++
)
{
$row
++
)
{
my
@orlist
;
for
(
my
$col
=
0
;
$params
->
param
(
"field$chart-$row-$col"
)
;
$col
++
)
{
$f
=
$params
->
param
(
"field$chart-$row-$col"
)
||
"noop"
;
my
$original_f
=
$f
;
# Saved for search_description
$t
=
$params
->
param
(
"type$chart-$row-$col"
)
||
"noop"
;
$v
=
$params
->
param
(
"value$chart-$row-$col"
);
$v
=
""
if
!
defined
$v
;
$v
=
trim
(
$v
);
if
(
$f
eq
"noop"
||
$t
eq
"noop"
||
$v
eq
""
)
{
next
;
}
$col
++
)
{
my
$field
=
$params
->
param
(
"field$chart-$row-$col"
)
||
"noop"
;
my
$original_field
=
$field
;
# Saved for search_description
my
$operator
=
$params
->
param
(
"type$chart-$row-$col"
)
||
"noop"
;
my
$value
=
$params
->
param
(
"value$chart-$row-$col"
);
$value
=
""
if
!
defined
$value
;
$value
=
trim
(
$value
);
next
if
(
$field
eq
"noop"
||
$operator
eq
"noop"
||
$value
eq
""
);
# chart -1 is generated by other code above, not from the user-
# submitted form, so we'll blindly accept any values in chart -1
if
(
(
!
$chartfields
{
$f
})
&&
(
$chart
!=
-
1
)
)
{
ThrowCodeError
(
"invalid_field_name"
,
{
field
=>
$f
});
if
(
!
$chartfields
{
$field
}
and
$chart
!=
-
1
)
{
ThrowCodeError
(
"invalid_field_name"
,
{
field
=>
$field
});
}
# This is either from the internal chart (in which case we
# already know about it), or it was in %chartfields, so it is
# a valid field name, which means that it's ok.
trick_taint
(
$f
);
$q
=
$dbh
->
quote
(
$v
);
trick_taint
(
$q
);
my
$rhs
=
$v
;
$rhs
=~
tr
/,/
/
;
my
$func
;
$term
=
undef
;
foreach
my
$key
(
@funcnames
)
{
if
(
"$f,$t,$rhs"
=~
m/$key/
)
{
my
$ref
=
$funcsbykey
{
$key
};
$ff
=
$f
;
if
(
$f
!~
/\./
)
{
$ff
=
"bugs.$f"
;
}
$self
->
$ref
(
%
func_args
);
if
(
$term
)
{
last
;
}
}
}
trick_taint
(
$field
);
my
$quoted
=
$dbh
->
quote
(
$value
);
trick_taint
(
$quoted
);
my
$term
;
my
$full_field
=
$field
=~
/\./
?
$field
:
"bugs.$field"
;
$self
->
do_search_function
({
chartid
=>
\
$chartid
,
sequence
=>
\
$sequence
,
f
=>
\
$field
,
ff
=>
\
$full_field
,
t
=>
\
$operator
,
v
=>
\
$value
,
q
=>
\
$quoted
,
term
=>
\
$term
,
multi_fields
=>
\
@multi_select_fields
,
supptables
=>
\
@supptables
,
wherepart
=>
\
@wherepart
,
having
=>
\
@having
,
groupby
=>
\
@groupby
,
chartfields
=>
\%
chartfields
,
fields
=>
\
@fields
,
});
if
(
$term
)
{
$self
->
search_description
({
field
=>
$original_f
,
type
=>
$t
,
value
=>
$v
,
term
=>
$term
,
field
=>
$original_f
ield
,
type
=>
$operator
,
value
=>
$value
,
term
=>
$term
,
});
push
(
@orlist
,
$term
);
}
...
...
@@ -1003,6 +1070,80 @@ sub init {
###############################################################################
# Helper functions for the init() method.
###############################################################################
# This takes information about the current boolean chart and translates
# it into SQL, using the constants at the top of this file.
sub
do_search_function
{
my
(
$self
,
$args
)
=
@_
;
my
(
$field
,
$operator
,
$value
)
=
@$args
{
qw(f t v)
};
my
$actual_field
=
FIELD_MAP
->
{
$$field
}
||
$$field
;
if
(
my
$parse_func
=
SPECIAL_PARSING
->
{
$actual_field
})
{
$self
->
$parse_func
(
%
$args
);
# Some parsing functions set $term, though most do not.
# For the ones that set $term, we don't need to do any further
# parsing.
return
if
$
{
$args
->
{
term
}
};
}
my
$override
=
OPERATOR_FIELD_OVERRIDE
->
{
$actual_field
};
if
(
!
$override
)
{
# Multi-select fields get special handling.
if
(
grep
{
$_
->
name
eq
$actual_field
}
@
{
$args
->
{
multi_fields
}
})
{
$override
=
OPERATOR_FIELD_OVERRIDE
->
{
_multi_select
};
}
# And so do attachment fields, if they don't have a specific
# individual override.
elsif
(
$actual_field
=~
/^attachments\./
)
{
$override
=
OPERATOR_FIELD_OVERRIDE
->
{
attachments
};
}
}
if
(
$override
)
{
my
$search_func
=
$self
->
_pick_override_function
(
$override
,
$$operator
);
$self
->
$search_func
(
%
$args
)
if
$search_func
;
}
# Some search functions set $term, and some don't. For the ones that
# don't (or for fields that don't have overrides) we now call the
# direct operator function from OPERATORS.
if
(
!
$
{
$args
->
{
term
}
})
{
$self
->
_do_operator_function
(
$args
);
}
}
# A helper for various search functions that need to run operator
# functions directly.
sub
_do_operator_function
{
my
(
$self
,
$func_args
)
=
@_
;
my
$operator
=
$func_args
->
{
t
};
my
$operator_func
=
OPERATORS
->
{
$$operator
};
$self
->
$operator_func
(
%
$func_args
);
}
sub
_pick_override_function
{
my
(
$self
,
$override
,
$operator
)
=
@_
;
my
$search_func
=
$override
->
{
$operator
};
if
(
!
$search_func
)
{
# If we don't find an override for one specific operator,
# then there are some special override types:
# _non_changed: For any operator that doesn't have the word
# "changed" in it
# _default: Overrides all operators that aren't explicitly specified.
if
(
$override
->
{
_non_changed
}
and
$operator
!~
/changed/
)
{
$search_func
=
$override
->
{
_non_changed
};
}
elsif
(
$override
->
{
_default
})
{
$search_func
=
$override
->
{
_default
};
}
}
return
$search_func
;
}
sub
SqlifyDate
{
my
(
$str
)
=
@_
;
$str
=
""
if
!
defined
$str
;
...
...
@@ -1233,6 +1374,22 @@ sub translate_old_column {
# Search Functions
#####################################################################
sub
_contact_pronoun
{
my
$self
=
shift
;
my
%
func_args
=
@_
;
my
(
$value
,
$quoted
)
=
@func_args
{
qw(v q)
};
my
$user
=
$self
->
{
'user'
};
if
(
$$value
=~
/^\%group/
)
{
$self
->
_contact_exact_group
(
%
func_args
);
}
elsif
(
$$value
=~
/^(%\w+%)$/
)
{
$$value
=
pronoun
(
$1
,
$user
);
$$quoted
=
$$value
;
}
}
sub
_contact_exact_group
{
my
$self
=
shift
;
my
%
func_args
=
@_
;
...
...
@@ -1240,7 +1397,7 @@ sub _contact_exact_group {
@func_args
{
qw(chartid supptables f t v term)
};
my
$user
=
$self
->
{
'user'
};
$$v
=~
m/%group\
\.([^%]+)%/
;
$$v
=~
/\%group
\.([^%]+)%/
;
my
$group
=
$1
;
my
$groupid
=
Bugzilla::Group::
ValidateGroupName
(
$group
,
(
$user
));
$groupid
||
ThrowUserError
(
'invalid_group_name'
,{
name
=>
$group
});
...
...
@@ -1261,48 +1418,42 @@ sub _contact_exact_group {
}
}
sub
_contact_exact
{
my
$self
=
shift
;
my
%
func_args
=
@_
;
my
(
$term
,
$f
,
$v
)
=
@func_args
{
qw(term f v)
};
my
$user
=
$self
->
{
'user'
};
$$v
=~
m/(%\\w+%)/
;
$$term
=
"bugs.$$f = "
.
pronoun
(
$1
,
$user
);
}
sub
_contact_notequals
{
my
$self
=
shift
;
my
%
func_args
=
@_
;
my
(
$term
,
$f
,
$v
)
=
@func_args
{
qw(term f v)
};
my
$user
=
$self
->
{
'user'
};
$$v
=~
m/(%\\w+%)/
;
$$term
=
"bugs.$$f <> "
.
pronoun
(
$1
,
$user
);
}
sub
_assigned_to_reporter_nonchanged
{
my
$self
=
shift
;
my
%
func_args
=
@_
;
my
(
$f
,
$ff
,
$
funcsbykey
,
$
t
,
$term
)
=
@func_args
{
qw(f ff
funcsbykey
t term)
};
my
(
$f
,
$ff
,
$t
,
$term
)
=
@func_args
{
qw(f ff t term)
};
my
$real_f
=
$$f
;
$$f
=
"login_name"
;
$$ff
=
"profiles.login_name"
;
$
$funcsbykey
{
",$$t"
}(
$self
,
%
func_args
);
$$term
=
"bugs.$
real_
f IN (SELECT userid FROM profiles WHERE $$term)"
;
$
self
->
_do_operator_function
(
\
%
func_args
);
$$term
=
"bugs.$
$
f IN (SELECT userid FROM profiles WHERE $$term)"
;
}
sub
_qa_contact_nonchanged
{
my
$self
=
shift
;
my
%
func_args
=
@_
;
my
(
$supptables
,
$f
)
=
@func_args
{
qw(supptables f)
};
my
(
$supptables
,
$f
,
$ff
)
=
@func_args
{
qw(supptables f
ff
)
};
push
(
@$supptables
,
"LEFT JOIN profiles AS map_qa_contact "
.
"ON bugs.qa_contact = map_qa_contact.userid"
);
$$f
=
"COALESCE(map_$$f.login_name,'')"
;
$$ff
=
"COALESCE(map_$$f.login_name,'')"
;
}
sub
_cc_pronoun
{
my
$self
=
shift
;
my
%
func_args
=
@_
;
my
(
$full_field
,
$value
,
$quoted
)
=
@func_args
{
qw(ff v q)
};
my
$user
=
$self
->
{
'user'
};
if
(
$$value
=~
/\%group/
)
{
return
$self
->
_cc_exact_group
(
%
func_args
);
}
elsif
(
$$value
=~
/^(%\w+%)$/
)
{
$$value
=
pronoun
(
$1
,
$user
);
$$quoted
=
$$value
;
$$full_field
=
"profiles.userid"
;
}
}
sub
_cc_exact_group
{
...
...
@@ -1312,7 +1463,7 @@ sub _cc_exact_group {
@func_args
{
qw(chartid sequence supptables t v term)
};
my
$user
=
$self
->
{
'user'
};
$$v
=~
m/%group\
\
.([^%]+)%/
;
$$v
=~
m/%group\.([^%]+)%/
;
my
$group
=
$1
;
my
$groupid
=
Bugzilla::Group::
ValidateGroupName
(
$group
,
(
$user
));
$groupid
||
ThrowUserError
(
'invalid_group_name'
,{
name
=>
$group
});
...
...
@@ -1340,60 +1491,21 @@ sub _cc_exact_group {
}
}
sub
_cc_exact
{
my
$self
=
shift
;
my
%
func_args
=
@_
;
my
(
$chartid
,
$sequence
,
$supptables
,
$term
,
$v
)
=
@func_args
{
qw(chartid sequence supptables term v)
};
my
$user
=
$self
->
{
'user'
};
$$v
=~
m/(%\\w+%)/
;
my
$match
=
pronoun
(
$1
,
$user
);
my
$chartseq
=
$$chartid
;
if
(
$$chartid
eq
""
)
{
$chartseq
=
"CC$$sequence"
;
$$sequence
++
;
}
push
(
@$supptables
,
"LEFT JOIN cc AS cc_$chartseq "
.
"ON bugs.bug_id = cc_$chartseq.bug_id "
.
"AND cc_$chartseq.who = $match"
);
$$term
=
"cc_$chartseq.who IS NOT NULL"
;
}
sub
_cc_notequals
{
my
$self
=
shift
;
my
%
func_args
=
@_
;
my
(
$chartid
,
$sequence
,
$supptables
,
$term
,
$v
)
=
@func_args
{
qw(chartid sequence supptables term v)
};
my
$user
=
$self
->
{
'user'
};
$$v
=~
m/(%\\w+%)/
;
my
$match
=
pronoun
(
$1
,
$user
);
my
$chartseq
=
$$chartid
;
if
(
$$chartid
eq
""
)
{
$chartseq
=
"CC$$sequence"
;
$$sequence
++
;
}
push
(
@$supptables
,
"LEFT JOIN cc AS cc_$chartseq "
.
"ON bugs.bug_id = cc_$chartseq.bug_id "
.
"AND cc_$chartseq.who = $match"
);
$$term
=
"cc_$chartseq.who IS NULL"
;
}
sub
_cc_nonchanged
{
my
$self
=
shift
;
my
%
func_args
=
@_
;
my
(
$chartid
,
$sequence
,
$f
,
$ff
,
$t
,
$
funcsbykey
,
$
supptables
,
$term
,
$v
)
=
@func_args
{
qw(chartid sequence f ff t
funcsbykey
supptables term v)
};
my
(
$chartid
,
$sequence
,
$f
,
$ff
,
$t
,
$supptables
,
$term
,
$v
)
=
@func_args
{
qw(chartid sequence f ff t supptables term v)
};
my
$chartseq
=
$$chartid
;
if
(
$$chartid
eq
""
)
{
$chartseq
=
"CC$$sequence"
;
$$sequence
++
;
}
$$f
=
"login_name"
;
$$ff
=
"profiles.login_name"
;
$$funcsbykey
{
",$$t"
}(
$self
,
%
func_args
);
if
(
$$ff
eq
'bugs.cc'
)
{
$$ff
=
"profiles.login_name"
;
}
$self
->
_do_operator_function
(
\%
func_args
);
push
(
@$supptables
,
"LEFT JOIN cc AS cc_$chartseq "
.
"ON bugs.bug_id = cc_$chartseq.bug_id "
.
"AND cc_$chartseq.who IN"
.
...
...
@@ -1480,43 +1592,36 @@ sub _content_matches {
COLUMNS
->
{
'relevance'
}
->
{
name
}
=
$select_term
;
}
sub
_timestamp_
compar
e
{
sub
_timestamp_
translat
e
{
my
$self
=
shift
;
my
%
func_args
=
@_
;
my
(
$v
,
$q
)
=
@func_args
{
qw(v q)
};
my
(
$v
alue
,
$quoted
)
=
@func_args
{
qw(v q)
};
my
$dbh
=
Bugzilla
->
dbh
;
return
if
$$value
!~
/^[\+\-]?\d+[hdwmy]$/i
;
$$v
=
SqlifyDate
(
$$v
);
$$q
=
$dbh
->
quote
(
$$v
);
$$v
alue
=
SqlifyDate
(
$$value
);
$$q
uoted
=
$dbh
->
quote
(
$$value
);
}
sub
_commenter_
exact
{
sub
_commenter_
pronoun
{
my
$self
=
shift
;
my
%
func_args
=
@_
;
my
(
$chartid
,
$sequence
,
$supptables
,
$term
,
$v
)
=
@func_args
{
qw(chartid sequence supptables term v)
};
my
(
$full_field
,
$value
,
$quoted
)
=
@func_args
{
qw(ff v q)
};
my
$user
=
$self
->
{
'user'
};
$$v
=~
m/(%\\w+%)/
;
my
$match
=
pronoun
(
$1
,
$user
);
my
$chartseq
=
$$chartid
;
if
(
$$chartid
eq
""
)
{
$chartseq
=
"LD$$sequence"
;
$$sequence
++
;
if
(
$$value
=~
/^(%\w+%)$/
)
{
$$value
=
pronoun
(
$1
,
$user
);
$$quoted
=
$$value
;
$$full_field
=
"profiles.userid"
;
}
my
$table
=
"longdescs_$chartseq"
;
my
$extra
=
$user
->
is_insider
?
""
:
"AND $table.isprivate < 1"
;
push
(
@$supptables
,
"LEFT JOIN longdescs AS $table "
.
"ON $table.bug_id = bugs.bug_id $extra "
.
"AND $table.who IN ($match)"
);
$$term
=
"$table.who IS NOT NULL"
;
}
sub
_commenter
{
my
$self
=
shift
;
my
%
func_args
=
@_
;
my
(
$chartid
,
$sequence
,
$supptables
,
$f
,
$ff
,
$t
,
$
funcsbykey
,
$
term
)
=
@func_args
{
qw(chartid sequence supptables f ff t
funcsbykey
term)
};
my
(
$chartid
,
$sequence
,
$supptables
,
$f
,
$ff
,
$t
,
$term
)
=
@func_args
{
qw(chartid sequence supptables f ff t term)
};
my
$chartseq
=
$$chartid
;
if
(
$$chartid
eq
""
)
{
...
...
@@ -1525,9 +1630,10 @@ sub _commenter {
}
my
$table
=
"longdescs_$chartseq"
;
my
$extra
=
$self
->
{
'user'
}
->
is_insider
?
""
:
"AND $table.isprivate < 1"
;
$$f
=
"login_name"
;
$$ff
=
"profiles.login_name"
;
$$funcsbykey
{
",$$t"
}(
$self
,
%
func_args
);
if
(
$$ff
eq
'bugs.commenter'
)
{
$$ff
=
"profiles.login_name"
;
}
$self
->
_do_operator_function
(
\%
func_args
);
push
(
@$supptables
,
"LEFT JOIN longdescs AS $table "
.
"ON $table.bug_id = bugs.bug_id $extra "
.
"AND $table.who IN"
.
...
...
@@ -1539,27 +1645,27 @@ sub _commenter {
sub
_long_desc
{
my
$self
=
shift
;
my
%
func_args
=
@_
;
my
(
$chartid
,
$supptables
,
$f
)
=
@func_args
{
qw(chartid supptables f)
};
my
(
$chartid
,
$supptables
,
$f
f
)
=
@func_args
{
qw(chartid supptables f
f
)
};
my
$table
=
"longdescs_$$chartid"
;
my
$extra
=
$self
->
{
'user'
}
->
is_insider
?
""
:
"AND $table.isprivate < 1"
;
push
(
@$supptables
,
"LEFT JOIN longdescs AS $table "
.
"ON $table.bug_id = bugs.bug_id $extra"
);
$$f
=
"$table.thetext"
;
$$f
f
=
"$table.thetext"
;
}
sub
_longdescs_isprivate
{
my
$self
=
shift
;
my
%
func_args
=
@_
;
my
(
$chartid
,
$supptables
,
$f
)
=
@func_args
{
qw(chartid supptables f)
};
my
(
$chartid
,
$supptables
,
$f
f
)
=
@func_args
{
qw(chartid supptables f
f
)
};
my
$table
=
"longdescs_$$chartid"
;
my
$extra
=
$self
->
{
'user'
}
->
is_insider
?
""
:
"AND $table.isprivate < 1"
;
push
(
@$supptables
,
"LEFT JOIN longdescs AS $table "
.
"ON $table.bug_id = bugs.bug_id $extra"
);
$$f
=
"$table.isprivate"
;
$$f
f
=
"$table.isprivate"
;
}
sub
_work_time_changedby
{
...
...
@@ -1596,13 +1702,13 @@ sub _work_time_changedbefore_after {
sub
_work_time
{
my
$self
=
shift
;
my
%
func_args
=
@_
;
my
(
$chartid
,
$supptables
,
$f
)
=
@func_args
{
qw(chartid supptables f)
};
my
(
$chartid
,
$supptables
,
$f
f
)
=
@func_args
{
qw(chartid supptables f
f
)
};
my
$table
=
"longdescs_$$chartid"
;
push
(
@$supptables
,
"LEFT JOIN longdescs AS $table "
.
"ON $table.bug_id = bugs.bug_id"
);
$$f
=
"$table.work_time"
;
$$f
f
=
"$table.work_time"
;
}
sub
_percentage_complete
{
...
...
@@ -1669,14 +1775,14 @@ sub _percentage_complete {
sub
_bug_group_nonchanged
{
my
$self
=
shift
;
my
%
func_args
=
@_
;
my
(
$supptables
,
$chartid
,
$ff
,
$
f
,
$t
,
$funcsbykey
,
$term
)
=
@func_args
{
qw(supptables chartid ff
f t funcsbykey
term)
};
my
(
$supptables
,
$chartid
,
$ff
,
$
t
,
$term
)
=
@func_args
{
qw(supptables chartid ff
t
term)
};
push
(
@$supptables
,
"LEFT JOIN bug_group_map AS bug_group_map_$$chartid "
.
"ON bugs.bug_id = bug_group_map_$$chartid.bug_id"
);
$$ff
=
$$f
=
"groups_$$chartid.name"
;
$
$funcsbykey
{
",$$t"
}(
$self
,
%
func_args
);
$$ff
=
"groups_$$chartid.name"
;
$
self
->
_do_operator_function
(
\
%
func_args
);
push
(
@$supptables
,
"LEFT JOIN groups AS groups_$$chartid "
.
"ON groups_$$chartid.id = bug_group_map_$$chartid.group_id "
.
...
...
@@ -1684,21 +1790,11 @@ sub _bug_group_nonchanged {
$$term
=
"$$ff IS NOT NULL"
;
}
sub
_attach_data_thedata_changed
{
my
$self
=
shift
;
my
%
func_args
=
@_
;
my
(
$f
)
=
@func_args
{
qw(f)
};
# Searches for attachment data's change must search
# the creation timestamp of the attachment instead.
$$f
=
"attachments.whocares"
;
}
sub
_attach_data_thedata
{
my
$self
=
shift
;
my
%
func_args
=
@_
;
my
(
$chartid
,
$supptables
,
$f
)
=
@func_args
{
qw(chartid supptables f)
};
my
(
$chartid
,
$supptables
,
$f
f
)
=
@func_args
{
qw(chartid supptables f
f
)
};
my
$atable
=
"attachments_$$chartid"
;
my
$dtable
=
"attachdata_$$chartid"
;
...
...
@@ -1707,14 +1803,14 @@ sub _attach_data_thedata {
"ON bugs.bug_id = $atable.bug_id $extra"
);
push
(
@$supptables
,
"LEFT JOIN attach_data AS $dtable "
.
"ON $dtable.id = $atable.attach_id"
);
$$f
=
"$dtable.thedata"
;
$$f
f
=
"$dtable.thedata"
;
}
sub
_attachments_submitter
{
my
$self
=
shift
;
my
%
func_args
=
@_
;
my
(
$chartid
,
$supptables
,
$f
)
=
@func_args
{
qw(chartid supptables f)
};
my
(
$chartid
,
$supptables
,
$f
f
)
=
@func_args
{
qw(chartid supptables f
f
)
};
my
$atable
=
"map_attachment_submitter_$$chartid"
;
my
$extra
=
$self
->
{
'user'
}
->
is_insider
?
""
:
"AND $atable.isprivate = 0"
;
...
...
@@ -1722,14 +1818,14 @@ sub _attachments_submitter {
"ON bugs.bug_id = $atable.bug_id $extra"
);
push
(
@$supptables
,
"LEFT JOIN profiles AS attachers_$$chartid "
.
"ON $atable.submitter_id = attachers_$$chartid.userid"
);
$$f
=
"attachers_$$chartid.login_name"
;
$$f
f
=
"attachers_$$chartid.login_name"
;
}
sub
_attachments
{
my
$self
=
shift
;
my
%
func_args
=
@_
;
my
(
$chartid
,
$supptables
,
$f
,
$t
,
$v
,
$q
)
=
@func_args
{
qw(chartid supptables f t v q)
};
my
(
$chartid
,
$supptables
,
$f
,
$
ff
,
$
t
,
$v
,
$q
)
=
@func_args
{
qw(chartid supptables f
ff
t v q)
};
my
$dbh
=
Bugzilla
->
dbh
;
my
$table
=
"attachments_$$chartid"
;
...
...
@@ -1760,14 +1856,14 @@ sub _attachments {
if
(
$field
eq
"isobsolete"
&&
$$v
ne
"0"
&&
$$v
ne
"1"
)
{
ThrowUserError
(
"illegal_is_obsolete"
);
}
$$f
=
"$table.$field"
;
$$f
f
=
"$table.$field"
;
}
sub
_flagtypes_name
{
my
$self
=
shift
;
my
%
func_args
=
@_
;
my
(
$t
,
$chartid
,
$supptables
,
$ff
,
$
funcsbykey
,
$
having
,
$term
)
=
@func_args
{
qw(t chartid supptables ff
funcsbykey
having term)
};
my
(
$t
,
$chartid
,
$supptables
,
$ff
,
$having
,
$term
)
=
@func_args
{
qw(t chartid supptables ff having term)
};
my
$dbh
=
Bugzilla
->
dbh
;
# Matches bugs by flag name/status.
...
...
@@ -1801,7 +1897,7 @@ sub _flagtypes_name {
# variable.
$$ff
=
$dbh
->
sql_string_concat
(
"${flagtypes}.name"
,
"$flags.status"
);
$
$funcsbykey
{
",$$t"
}(
$self
,
%
func_args
);
$
self
->
_do_operator_function
(
\
%
func_args
);
# If this is a negative condition (f.e. flag isn't "review+"),
# we only want bugs where all flags match the condition, not
...
...
@@ -1822,7 +1918,7 @@ sub _flagtypes_name {
sub
_requestees_login_name
{
my
$self
=
shift
;
my
%
func_args
=
@_
;
my
(
$f
,
$chartid
,
$supptables
)
=
@func_args
{
qw(
f chartid supptables)
};
my
(
$f
f
,
$chartid
,
$supptables
)
=
@func_args
{
qw(f
f chartid supptables)
};
my
$attachments
=
"attachments_$$chartid"
;
my
$extra
=
$self
->
{
'user'
}
->
is_insider
?
""
:
"AND $attachments.isprivate = 0"
;
...
...
@@ -1837,13 +1933,13 @@ sub _requestees_login_name {
"ON $flags.attach_id = $attachments.attach_id "
.
"OR $flags.attach_id IS NULL"
);
$$f
=
"requestees_$$chartid.login_name"
;
$$f
f
=
"requestees_$$chartid.login_name"
;
}
sub
_setters_login_name
{
my
$self
=
shift
;
my
%
func_args
=
@_
;
my
(
$f
,
$chartid
,
$supptables
)
=
@func_args
{
qw(
f chartid supptables)
};
my
(
$f
f
,
$chartid
,
$supptables
)
=
@func_args
{
qw(f
f chartid supptables)
};
my
$attachments
=
"attachments_$$chartid"
;
my
$extra
=
$self
->
{
'user'
}
->
is_insider
?
""
:
"AND $attachments.isprivate = 0"
;
...
...
@@ -1858,27 +1954,26 @@ sub _setters_login_name {
"ON $flags.attach_id = $attachments.attach_id "
.
"OR $flags.attach_id IS NULL"
);
$$f
=
"setters_$$chartid.login_name"
;
$$f
f
=
"setters_$$chartid.login_name"
;
}
sub
_changedin_days_elapsed
{
my
$self
=
shift
;
my
%
func_args
=
@_
;
my
(
$f
)
=
@func_args
{
qw(
f)
};
my
(
$f
f
)
=
@func_args
{
qw(f
f)
};
my
$dbh
=
Bugzilla
->
dbh
;
$$f
=
"("
.
$dbh
->
sql_to_days
(
'NOW()'
)
.
" - "
.
$dbh
->
sql_to_days
(
'bugs.delta_ts'
)
.
")"
;
$$f
f
=
"("
.
$dbh
->
sql_to_days
(
'NOW()'
)
.
" - "
.
$dbh
->
sql_to_days
(
'bugs.delta_ts'
)
.
")"
;
}
sub
_component_nonchanged
{
my
$self
=
shift
;
my
%
func_args
=
@_
;
my
(
$f
,
$ff
,
$t
,
$funcsbykey
,
$term
)
=
@func_args
{
qw(f ff t funcsbykey term)
};
my
(
$ff
,
$t
,
$term
)
=
@func_args
{
qw(ff t term)
};
$$f
=
$$f
f
=
"components.name"
;
$
$funcsbykey
{
",$$t"
}(
$self
,
%
func_args
);
$$ff
=
"components.name"
;
$
self
->
_do_operator_function
(
\
%
func_args
);
$$term
=
build_subselect
(
"bugs.component_id"
,
"components.id"
,
"components"
,
...
...
@@ -1887,12 +1982,11 @@ sub _component_nonchanged {
sub
_product_nonchanged
{
my
$self
=
shift
;
my
%
func_args
=
@_
;
my
(
$f
,
$ff
,
$t
,
$funcsbykey
,
$term
)
=
@func_args
{
qw(f ff t funcsbykey term)
};
my
(
$ff
,
$t
,
$term
)
=
@func_args
{
qw(ff t term)
};
# Generate the restriction condition
$$f
=
$$f
f
=
"products.name"
;
$
$funcsbykey
{
",$$t"
}(
$self
,
%
func_args
);
$$ff
=
"products.name"
;
$
self
->
_do_operator_function
(
\
%
func_args
);
$$term
=
build_subselect
(
"bugs.product_id"
,
"products.id"
,
"products"
,
...
...
@@ -1902,14 +1996,14 @@ sub _product_nonchanged {
sub
_classification_nonchanged
{
my
$self
=
shift
;
my
%
func_args
=
@_
;
my
(
$chartid
,
$v
,
$ff
,
$
f
,
$funcsbykey
,
$
t
,
$supptables
,
$term
)
=
@func_args
{
qw(chartid v ff
f funcsbykey
t supptables term)
};
my
(
$chartid
,
$v
,
$ff
,
$t
,
$supptables
,
$term
)
=
@func_args
{
qw(chartid v ff t supptables term)
};
# Generate the restriction condition
push
@$supptables
,
"INNER JOIN products AS map_products "
.
"ON bugs.product_id = map_products.id"
;
$$f
=
$$f
f
=
"classifications.name"
;
$
$funcsbykey
{
",$$t"
}(
$self
,
%
func_args
);
$$ff
=
"classifications.name"
;
$
self
->
_do_operator_function
(
\
%
func_args
);
$$term
=
build_subselect
(
"map_products.classification_id"
,
"classifications.id"
,
"classifications"
,
...
...
@@ -1953,13 +2047,16 @@ sub _keywords_exact {
push
(
@$supptables
,
"LEFT JOIN keywords AS $table "
.
"ON $table.bug_id = bugs.bug_id"
);
}
else
{
$self
->
_keywords_nonchanged
(
%
func_args
);
}
}
sub
_keywords_nonchanged
{
my
$self
=
shift
;
my
%
func_args
=
@_
;
my
(
$chartid
,
$v
,
$ff
,
$
f
,
$
t
,
$term
,
$supptables
)
=
@func_args
{
qw(chartid v ff
f
t term supptables)
};
my
(
$chartid
,
$v
,
$ff
,
$t
,
$term
,
$supptables
)
=
@func_args
{
qw(chartid v ff t term supptables)
};
my
$k_table
=
"keywords_$$chartid"
;
my
$kd_table
=
"keyworddefs_$$chartid"
;
...
...
@@ -1969,18 +2066,18 @@ sub _keywords_nonchanged {
push
(
@$supptables
,
"LEFT JOIN keyworddefs AS $kd_table "
.
"ON $kd_table.id = $k_table.keywordid"
);
$$f
=
"$kd_table.name"
;
$$f
f
=
"$kd_table.name"
;
}
sub
_dependson_nonchanged
{
my
$self
=
shift
;
my
%
func_args
=
@_
;
my
(
$chartid
,
$ff
,
$f
,
$
funcsbykey
,
$
t
,
$term
,
$supptables
)
=
@func_args
{
qw(chartid ff f
funcsbykey
t term supptables)
};
my
(
$chartid
,
$ff
,
$f
,
$t
,
$term
,
$supptables
)
=
@func_args
{
qw(chartid ff f t term supptables)
};
my
$table
=
"dependson_"
.
$$chartid
;
$$ff
=
"$table.$$f"
;
$
$funcsbykey
{
",$$t"
}(
$self
,
%
func_args
);
$
self
->
_do_operator_function
(
\
%
func_args
);
push
(
@$supptables
,
"LEFT JOIN dependencies AS $table "
.
"ON $table.blocked = bugs.bug_id "
.
"AND ($$term)"
);
...
...
@@ -1990,12 +2087,12 @@ sub _dependson_nonchanged {
sub
_blocked_nonchanged
{
my
$self
=
shift
;
my
%
func_args
=
@_
;
my
(
$chartid
,
$ff
,
$f
,
$
funcsbykey
,
$
t
,
$term
,
$supptables
)
=
@func_args
{
qw(chartid ff f
funcsbykey
t term supptables)
};
my
(
$chartid
,
$ff
,
$f
,
$t
,
$term
,
$supptables
)
=
@func_args
{
qw(chartid ff f t term supptables)
};
my
$table
=
"blocked_"
.
$$chartid
;
$$ff
=
"$table.$$f"
;
$
$funcsbykey
{
",$$t"
}(
$self
,
%
func_args
);
$
self
->
_do_operator_function
(
\
%
func_args
);
push
(
@$supptables
,
"LEFT JOIN dependencies AS $table "
.
"ON $table.dependson = bugs.bug_id "
.
"AND ($$term)"
);
...
...
@@ -2005,12 +2102,11 @@ sub _blocked_nonchanged {
sub
_alias_nonchanged
{
my
$self
=
shift
;
my
%
func_args
=
@_
;
my
(
$ff
,
$funcsbykey
,
$t
,
$term
)
=
@func_args
{
qw(ff funcsbykey t term)
};
my
(
$ff
,
$t
,
$term
)
=
@func_args
{
qw(ff t term)
};
$$ff
=
"COALESCE(bugs.alias, '')"
;
$
$funcsbykey
{
",$$t"
}(
$self
,
%
func_args
);
$
self
->
_do_operator_function
(
\
%
func_args
);
}
sub
_owner_idle_time_greater_less
{
...
...
@@ -2059,7 +2155,7 @@ sub _owner_idle_time_greater_less {
sub
_multiselect_negative
{
my
$self
=
shift
;
my
%
func_args
=
@_
;
my
(
$f
,
$ff
,
$t
,
$
funcsbykey
,
$term
)
=
@func_args
{
qw(f ff t funcsbykey
term)
};
my
(
$f
,
$ff
,
$t
,
$
term
)
=
@func_args
{
qw(f ff t
term)
};
my
%
map
=
(
notequals
=>
'equals'
,
...
...
@@ -2072,14 +2168,15 @@ sub _multiselect_negative {
my
$table
=
"bug_$$f"
;
$$ff
=
"$table.value"
;
$$funcsbykey
{
","
.
$map
{
$$t
}}(
$self
,
%
func_args
);
$$t
=
$map
{
$$t
};
$self
->
_do_operator_function
(
\%
func_args
);
$$term
=
"bugs.bug_id NOT IN (SELECT bug_id FROM $table WHERE $$term)"
;
}
sub
_multiselect_multiple
{
my
$self
=
shift
;
my
%
func_args
=
@_
;
my
(
$f
,
$ff
,
$t
,
$v
,
$
funcsbykey
,
$term
)
=
@func_args
{
qw(f ff t v funcsbykey
term)
};
my
(
$f
,
$ff
,
$t
,
$v
,
$
term
)
=
@func_args
{
qw(f ff t v
term)
};
my
@terms
;
my
$table
=
"bug_$$f"
;
...
...
@@ -2087,7 +2184,7 @@ sub _multiselect_multiple {
foreach
my
$word
(
split
(
/[\s,]+/
,
$$v
))
{
$$v
=
$word
;
$
$funcsbykey
{
","
.
$$t
}(
$self
,
%
func_args
);
$
self
->
_do_operator_function
(
\
%
func_args
);
push
(
@terms
,
"bugs.bug_id IN
(SELECT bug_id FROM $table WHERE $$term)"
);
}
...
...
@@ -2103,13 +2200,13 @@ sub _multiselect_multiple {
sub
_multiselect_nonchanged
{
my
$self
=
shift
;
my
%
func_args
=
@_
;
my
(
$chartid
,
$f
,
$ff
,
$t
,
$
funcsbykey
,
$
supptables
)
=
@func_args
{
qw(chartid f ff t
funcsbykey
supptables)
};
my
(
$chartid
,
$f
,
$ff
,
$t
,
$supptables
)
=
@func_args
{
qw(chartid f ff t supptables)
};
my
$table
=
$$f
.
"_"
.
$$chartid
;
$$ff
=
"$table.value"
;
$
$funcsbykey
{
",$$t"
}(
$self
,
%
func_args
);
$
self
->
_do_operator_function
(
\
%
func_args
);
push
(
@$supptables
,
"LEFT JOIN bug_$$f AS $table "
.
"ON $table.bug_id = bugs.bug_id "
);
}
...
...
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