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
You need to sign in or sign up before continuing.
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
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
420 additions
and
323 deletions
+420
-323
Search.pm
Bugzilla/Search.pm
+420
-323
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"
;
if
(
$$ff
eq
'bugs.cc'
)
{
$$ff
=
"profiles.login_name"
;
$$funcsbykey
{
",$$t"
}(
$self
,
%
func_args
);
}
$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
;
$$v
=
SqlifyDate
(
$$v
);
$$q
=
$dbh
->
quote
(
$$v
);
return
if
$$value
!~
/^[\+\-]?\d+[hdwmy]$/i
;
$$value
=
SqlifyDate
(
$$value
);
$$quoted
=
$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"
;
if
(
$$ff
eq
'bugs.commenter'
)
{
$$ff
=
"profiles.login_name"
;
$$funcsbykey
{
",$$t"
}(
$self
,
%
func_args
);
}
$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()'
)
.
" - "
.
$$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