Commit 793c1035 authored by mkanat%bugzilla.org's avatar mkanat%bugzilla.org

Bug 408172: [Oracle] Bug lists longer than 1000 bugs fail

Patch By Xiaoou Wu <xiaoou.wu@oracle.com> r=mkanat, a=mkanat
parent 2c8316b9
......@@ -99,13 +99,14 @@ sub _retrieve {
'attachments.isprivate AS isprivate'
);
my $columns = join(", ", @columns);
my $records = Bugzilla->dbh->selectall_arrayref("SELECT $columns
FROM attachments
WHERE attach_id IN (" .
join(",", @$ids) . ")
ORDER BY attach_id",
{ Slice => {} });
my $dbh = Bugzilla->dbh;
my $records = $dbh->selectall_arrayref(
"SELECT $columns
FROM attachments
WHERE "
. Bugzilla->dbh->sql_in('attach_id', $ids)
. " ORDER BY attach_id",
{ Slice => {} });
return $records;
}
......
......@@ -635,8 +635,8 @@ sub update_cc {
my ($removed, $added) = diff_arrays(\@old_cc, \@new_cc);
if (scalar @$removed) {
$dbh->do('DELETE FROM cc WHERE bug_id = ? AND who IN (' .
join(',', @$removed) . ')', undef, $self->id);
$dbh->do('DELETE FROM cc WHERE bug_id = ? AND '
. $dbh->sql_in('who', $removed), undef, $self->id);
}
foreach my $user_id (@$added) {
$dbh->do('INSERT INTO cc (bug_id, who) VALUES (?,?)',
......@@ -722,8 +722,8 @@ sub update_keywords {
my ($removed, $added) = diff_arrays(\@old_ids, \@new_ids);
if (scalar @$removed) {
$dbh->do('DELETE FROM keywords WHERE bug_id = ? AND keywordid IN ('
. join(',', @$removed) . ')', undef, $self->id);
$dbh->do('DELETE FROM keywords WHERE bug_id = ? AND '
. $dbh->sql_in('keywordid', $removed), undef, $self->id);
}
foreach my $keyword_id (@$added) {
$dbh->do('INSERT INTO keywords (bug_id, keywordid) VALUES (?,?)',
......@@ -798,8 +798,8 @@ sub remove_from_db {
WHERE bug_id = ?", undef, $bug_id);
if (scalar(@$attach_ids)) {
$dbh->do("DELETE FROM attach_data WHERE id IN (" .
join(",", @$attach_ids) . ")");
$dbh->do("DELETE FROM attach_data WHERE "
. $dbh->sql_in('id', $attach_ids));
}
# Several of the previous tables also depend on attach_id.
......@@ -3018,7 +3018,7 @@ sub CountOpenDependencies {
my $sth = $dbh->prepare(
"SELECT blocked, COUNT(bug_status) " .
"FROM bugs, dependencies " .
"WHERE blocked IN (" . (join "," , @bug_list) . ") " .
"WHERE " . $dbh->sql_in('blocked', \@bug_list) .
"AND bug_id = dependson " .
"AND bug_status IN (" . join(', ', map {$dbh->quote($_)} BUG_STATE_OPEN) . ") " .
$dbh->sql_group_by('blocked'));
......
......@@ -391,6 +391,11 @@ sub sql_string_concat {
return '(' . join(' || ', @params) . ')';
}
sub sql_in {
my ($self, $column_name, $in_list_ref) = @_;
return " $column_name IN (" . join(',', @$in_list_ref) . ") ";
}
sub sql_fulltext_search {
my ($self, $column, $text) = @_;
......@@ -1918,6 +1923,32 @@ will not be usually used unless it was created as LOWER(column).
=back
=item C<sql_in>
=over
=item B<Description>
Returns SQL syntax for the C<IN ()> operator.
Only necessary where an C<IN> clause can have more than 1000 items.
=item B<Params>
=over
=item C<$column_name> - Column name (e.g. C<bug_id>)
=item C<$in_list_ref> - an arrayref containing values for C<IN ()>
=back
=item B<Returns>
Formatted SQL for the C<IN> operator.
=back
=item C<bz_lock_tables>
=over
......
......@@ -165,6 +165,22 @@ sub sql_position {
my ($self, $fragment, $text) = @_;
return "INSTR($text, $fragment)";
}
sub sql_in {
my ($self, $column_name, $in_list_ref) = @_;
my @in_list = @$in_list_ref;
return $self->SUPER::sql_in($column_name, $in_list_ref) if $#in_list < 1000;
my @in_str;
while (@in_list) {
my $length = $#in_list + 1;
my $splice = $length > 1000 ? 1000 : $length;
my @sub_in_list = splice(@in_list, 0, $splice);
push(@in_str,
$self->SUPER::sql_in($column_name, \@sub_in_list));
}
return "( " . join(" OR ", @in_str) . " )";
}
sub _fix_empty {
my ($string) = @_;
$string = '' if $string eq EMPTY_STRING;
......
......@@ -295,11 +295,12 @@ sub validate {
my $not = ($attach_id) ? "" : "NOT";
my $invalid_data =
$dbh->selectrow_array("SELECT 1 FROM flags
WHERE id IN (" . join(',', @flag_ids) . ")
AND ($field != ? OR attach_id IS $not NULL) " .
$dbh->sql_limit(1),
undef, $field_id);
$dbh->selectrow_array(
"SELECT 1 FROM flags
WHERE "
. $dbh->sql_in('id', \@flag_ids)
. " AND ($field != ? OR attach_id IS $not NULL) "
. $dbh->sql_limit(1), undef, $field_id);
if ($invalid_data) {
ThrowCodeError('invalid_flag_association',
......
......@@ -144,7 +144,7 @@ sub remove_from_db {
my $timestamp = $dbh->selectrow_array('SELECT NOW()');
$dbh->do('UPDATE bugs SET target_milestone = ?, delta_ts = ?
WHERE bug_id IN (' . join(', ', @$bug_ids) . ')',
WHERE ' . $dbh->sql_in('bug_id', $bug_ids),
undef, ($self->product->default_milestone, $timestamp));
require Bugzilla::Bug;
......
......@@ -145,8 +145,9 @@ sub new_from_list {
push(@detainted_ids, $id);
}
$objects = $dbh->selectall_arrayref(
"SELECT $columns FROM $table WHERE $id_field IN ("
. join(',', @detainted_ids) . ") ORDER BY $order", {Slice=>{}});
"SELECT $columns FROM $table WHERE "
. $dbh->sql_in($id_field, \@detainted_ids)
. "ORDER BY $order", {Slice=>{}});
} else {
return [];
}
......
......@@ -352,8 +352,8 @@ sub init {
$extra .= " AND actcheck.added = $sql_chvalue";
}
push(@supptables, "LEFT JOIN bugs_activity AS actcheck " .
"ON $extra AND actcheck.fieldid IN (" .
join(",", @actlist) . ")");
"ON $extra AND "
. $dbh->sql_in('actcheck.fieldid', \@actlist));
}
# Now that we're done using @list to determine if there are any
......@@ -1082,7 +1082,7 @@ sub init {
push(@list, $q);
}
if (@list) {
$term = "$ff IN (" . join (',', @list) . ")";
$term = $dbh->sql_in($ff, \@list);
}
},
",anywordssubstr" => sub {
......@@ -1519,7 +1519,7 @@ sub build_subselect {
my $dbh = Bugzilla->dbh;
my $list = $dbh->selectcol_arrayref($q);
return "1=2" unless @$list; # Could use boolean type on dbs which support it
return "$outer IN (" . join(',', @$list) . ")";
return $dbh->sql_in($outer, $list);
}
sub GetByWordList {
......
......@@ -1084,7 +1084,7 @@ if (@bugidlist) {
"LEFT JOIN group_control_map " .
"ON group_control_map.product_id = bugs.product_id " .
"AND group_control_map.group_id = bug_group_map.group_id " .
"WHERE bugs.bug_id IN (" . join(',',@bugidlist) . ") " .
"WHERE " . $dbh->sql_in('bugs.bug_id', \@bugidlist) .
$dbh->sql_group_by('bugs.bug_id'));
$sth->execute();
while (my ($bug_id, $min_membercontrol) = $sth->fetchrow_array()) {
......@@ -1161,19 +1161,23 @@ if ($dotweak) {
my @bug_statuses = map {$dbh->quote($_)} keys %$bugstatuses;
my $bug_status_ids =
$dbh->selectcol_arrayref('SELECT id FROM bug_status
WHERE value IN (' . join(', ', @bug_statuses) .')');
WHERE ' . $dbh->sql_in('value', \@bug_statuses));
# This query collects new statuses which are common to all current bug statuses.
# It also accepts transitions where the bug status doesn't change.
$bug_status_ids =
$dbh->selectcol_arrayref('SELECT DISTINCT new_status
FROM status_workflow sw1
WHERE NOT EXISTS (SELECT * FROM status_workflow sw2
WHERE sw2.old_status != sw1.new_status
AND sw2.old_status IN (' . join(', ', @$bug_status_ids) . ')
AND NOT EXISTS (SELECT * FROM status_workflow sw3
WHERE sw3.new_status = sw1.new_status
AND sw3.old_status = sw2.old_status))');
$dbh->selectcol_arrayref(
'SELECT DISTINCT new_status
FROM status_workflow sw1
WHERE NOT EXISTS
(SELECT * FROM status_workflow sw2
WHERE sw2.old_status != sw1.new_status
AND '
. $dbh->sql_in('sw2.old_status', $bug_status_ids)
. ' AND NOT EXISTS
(SELECT * FROM status_workflow sw3
WHERE sw3.new_status = sw1.new_status
AND sw3.old_status = sw2.old_status))');
$vars->{'current_bug_statuses'} = [keys %$bugstatuses];
$vars->{'new_bug_statuses'} = Bugzilla::Status->new_from_list($bug_status_ids);
......
......@@ -327,11 +327,9 @@ if ($cgi->param('product') ne $cgi->param('dontchange')) {
$product = Bugzilla::Product::check_product(scalar $cgi->param('product'));
@newprod_ids = ($product->id);
} else {
@newprod_ids = @{$dbh->selectcol_arrayref("SELECT DISTINCT product_id
FROM bugs
WHERE bug_id IN (" .
join(',', @idlist) .
")")};
@newprod_ids = @{$dbh->selectcol_arrayref(
"SELECT DISTINCT product_id FROM bugs WHERE "
. $dbh->sql_in('bug_id', \@idlist))};
if (scalar(@newprod_ids) == 1) {
$product = new Bugzilla::Product($newprod_ids[0]);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment