Change sql_interval to sql_date_math, like in upstream

(mozilla bug #602165, upstream commit 220a5e6608)
hinted-selects
Vitaliy Filippov 2014-10-24 16:49:49 +04:00
parent 1db6dfedf5
commit b0b415b5b1
14 changed files with 87 additions and 67 deletions

View File

@ -68,8 +68,9 @@ sub persist_login {
# Issuing a new cookie is a good time to clean up the old # Issuing a new cookie is a good time to clean up the old
# cookies. # cookies.
$dbh->do("DELETE FROM logincookies WHERE lastused < LOCALTIMESTAMP(0) - " $dbh->do("DELETE FROM logincookies WHERE lastused < "
. $dbh->sql_interval(MAX_LOGINCOOKIE_AGE, 'DAY')); . $dbh->sql_date_math('LOCALTIMESTAMP(0)', '-',
MAX_LOGINCOOKIE_AGE, 'DAY'));
$dbh->bz_commit_transaction(); $dbh->bz_commit_transaction();

View File

@ -319,7 +319,7 @@ EOT
# List of abstract methods we are checking the derived class implements # List of abstract methods we are checking the derived class implements
our @_abstract_methods = qw(new sql_regexp sql_not_regexp sql_limit sql_to_days our @_abstract_methods = qw(new sql_regexp sql_not_regexp sql_limit sql_to_days
sql_date_format sql_interval bz_explain sql_date_format sql_date_math bz_explain
sql_group_concat); sql_group_concat);
# This overridden import method will check implementation of inherited classes # This overridden import method will check implementation of inherited classes
@ -1902,13 +1902,13 @@ Formatted SQL for date formatting (scalar)
=back =back
=item C<sql_interval> =item C<sql_date_math>
=over =over
=item B<Description> =item B<Description>
Outputs proper SQL syntax for a time interval function. Outputs proper SQL syntax for adding some amount of time to a date.
Abstract method, should be overridden by database specific code. Abstract method, should be overridden by database specific code.
@ -1916,15 +1916,28 @@ Abstract method, should be overridden by database specific code.
=over =over
=item C<$interval> - the time interval requested (e.g. '30') (integer) =item C<$date>
=item C<$units> - the units the interval is in (e.g. 'MINUTE') (string) C<string> The date being added to or subtracted from.
=item C<$operator>
C<string> Either C<-> or C<+>, depending on whether you're subtracting
or adding.
=item C<$interval>
C<integer> The time interval you're adding or subtracting (e.g. C<30>)
=item C<$units>
C<string> the units the interval is in (e.g. 'MINUTE')
=back =back
=item B<Returns> =item B<Returns>
Formatted SQL for interval function (scalar) Formatted SQL for adding or subtracting a date and some amount of time (scalar)
=back =back

View File

@ -244,10 +244,10 @@ sub sql_date_format {
return "DATE_FORMAT($date, " . $self->quote($format) . ")"; return "DATE_FORMAT($date, " . $self->quote($format) . ")";
} }
sub sql_interval { sub sql_date_math {
my ($self, $interval, $units) = @_; my ($self, $date, $operator, $interval, $units) = @_;
return "INTERVAL $interval $units"; return "$date $operator INTERVAL $interval $units";
} }
sub sql_iposition { sub sql_iposition {

View File

@ -205,13 +205,15 @@ sub sql_date_format {
return "TO_CHAR($date, " . $self->quote($format) . ")"; return "TO_CHAR($date, " . $self->quote($format) . ")";
} }
sub sql_interval { sub sql_date_math {
my ($self, $interval, $units) = @_; my ($self, $date, $operator, $interval, $units) = @_;
my $time_sql;
if ($units =~ /YEAR|MONTH/i) { if ($units =~ /YEAR|MONTH/i) {
return "NUMTOYMINTERVAL($interval,'$units')"; $time_sql = "NUMTOYMINTERVAL($interval,'$units')";
} else{ } else{
return "NUMTODSINTERVAL($interval,'$units')"; $time_sql = "NUMTODSINTERVAL($interval,'$units')";
} }
return "$date $operator $time_sql";
} }
sub sql_position { sub sql_position {

View File

@ -171,10 +171,9 @@ sub sql_date_format {
return "TO_CHAR($date, " . $self->quote($format) . ")"; return "TO_CHAR($date, " . $self->quote($format) . ")";
} }
sub sql_interval { sub sql_date_math {
my ($self, $interval, $units) = @_; my ($self, $date, $operator, $interval, $units) = @_;
return "$date $operator $interval * INTERVAL '1 $units'";
return "$interval * INTERVAL '1 $units'";
} }
sub sql_string_concat { sub sql_string_concat {

View File

@ -2704,7 +2704,7 @@ sub _owner_idle_time_less
$unitinterval = 'YEAR'; $unitinterval = 'YEAR';
} }
my $cutoff = "NOW() - " . $dbh->sql_interval($quantity, $unitinterval); my $cutoff = $dbh->sql_date_math('NOW()', '-', $quantity, $unitinterval);
my $g = $self->{type} eq 'lessthaneq' ? ">=" : ">"; my $g = $self->{type} eq 'lessthaneq' ? ">=" : ">";
$self->{term} = [ $self->{term} = [
'OR', 'OR',

View File

@ -63,13 +63,14 @@ sub issue_new_user_account_token {
# But to prevent using this way to mailbomb an email address, make sure # But to prevent using this way to mailbomb an email address, make sure
# the last request is at least 10 minutes old before sending a new email. # the last request is at least 10 minutes old before sending a new email.
my $pending_requests = my $pending_requests = $dbh->selectrow_array(
$dbh->selectrow_array('SELECT COUNT(*) 'SELECT COUNT(*)
FROM tokens FROM tokens
WHERE tokentype = ? WHERE tokentype = ?
AND ' . $dbh->sql_istrcmp('eventdata', '?') . ' AND ' . $dbh->sql_istrcmp('eventdata', '?') . '
AND issuedate > NOW() - ' . $dbh->sql_interval(10, 'MINUTE'), AND issuedate > '
undef, ('account', $login_name)); . $dbh->sql_date_math('NOW()', '-', 10, 'MINUTE'),
undef, ('account', $login_name));
ThrowUserError('too_soon_for_new_token', {'type' => 'account'}) if $pending_requests; ThrowUserError('too_soon_for_new_token', {'type' => 'account'}) if $pending_requests;
@ -132,13 +133,12 @@ sub IssuePasswordToken {
my $user = shift; my $user = shift;
my $dbh = Bugzilla->dbh; my $dbh = Bugzilla->dbh;
my $too_soon = my $too_soon = $dbh->selectrow_array(
$dbh->selectrow_array('SELECT 1 FROM tokens 'SELECT 1 FROM tokens
WHERE userid = ? WHERE userid = ? AND tokentype = ?
AND tokentype = ? AND issuedate > '
AND issuedate > NOW() - ' . . $dbh->sql_date_math('NOW()', '-', 10, 'MINUTE'),
$dbh->sql_interval(10, 'MINUTE'), undef, ($user->id, 'password'));
undef, ($user->id, 'password'));
ThrowUserError('too_soon_for_new_token', {'type' => 'password'}) if $too_soon; ThrowUserError('too_soon_for_new_token', {'type' => 'password'}) if $too_soon;

View File

@ -1847,12 +1847,12 @@ sub account_ip_login_failures
{ {
my $self = shift; my $self = shift;
my $dbh = Bugzilla->dbh; my $dbh = Bugzilla->dbh;
my $time = $dbh->sql_interval(Bugzilla->params->{login_lockout_interval}, 'MINUTE'); my $time = $dbh->sql_date_math('LOCALTIMESTAMP(0)', '-', int(Bugzilla->params->{login_lockout_interval}), 'MINUTE');
my $ip_addr = remote_ip(); my $ip_addr = remote_ip();
trick_taint($ip_addr); trick_taint($ip_addr);
$self->{account_ip_login_failures} ||= Bugzilla->dbh->selectall_arrayref( $self->{account_ip_login_failures} ||= Bugzilla->dbh->selectall_arrayref(
"SELECT login_time, ip_addr, user_id FROM login_failure". "SELECT login_time, ip_addr, user_id FROM login_failure".
" WHERE user_id = ? AND login_time > LOCALTIMESTAMP(0) - $time AND ip_addr = ?". " WHERE user_id = ? AND login_time > $time AND ip_addr = ?".
" ORDER BY login_time", {Slice => {}}, $self->id, $ip_addr " ORDER BY login_time", {Slice => {}}, $self->id, $ip_addr
); );
return $self->{account_ip_login_failures}; return $self->{account_ip_login_failures};

3
contrib/sendunsentbugmail.pl Normal file → Executable file
View File

@ -35,7 +35,8 @@ my $list = $dbh->selectcol_arrayref(
'SELECT bug_id FROM bugs 'SELECT bug_id FROM bugs
WHERE lastdiffed IS NULL WHERE lastdiffed IS NULL
OR lastdiffed < delta_ts OR lastdiffed < delta_ts
AND delta_ts < NOW() - ' . $dbh->sql_interval(30, 'MINUTE') . AND delta_ts < '
. $dbh->sql_date_math('NOW()', '-', 30, 'MINUTE') .
' ORDER BY bug_id'); ' ORDER BY bug_id');
if (scalar(@$list) > 0) { if (scalar(@$list) > 0) {

View File

@ -164,9 +164,9 @@ my $reso_field_id = Bugzilla->get_field('resolution')->id;
my %since_dups = @{$dbh->selectcol_arrayref( my %since_dups = @{$dbh->selectcol_arrayref(
"SELECT dupe_of, COUNT(dupe) FROM duplicates". "SELECT dupe_of, COUNT(dupe) FROM duplicates".
" INNER JOIN bugs_activity ON bugs_activity.bug_id = duplicates.dupe". " INNER JOIN bugs_activity ON bugs_activity.bug_id = duplicates.dupe".
" WHERE added = ? AND fieldid = ? AND bug_when >= LOCALTIMESTAMP(0) - ". " WHERE added = ? AND fieldid = ? AND bug_when >= ".
$dbh->sql_interval('?', 'DAY') . " GROUP BY dupe_of", {Columns=>[1,2]}, $dbh->sql_date_math('LOCALTIMESTAMP(0)', '-', '?', 'DAY')." GROUP BY dupe_of",
Bugzilla->params->{duplicate_resolution}, {Columns=>[1,2]}, Bugzilla->params->{duplicate_resolution},
$reso_field_id, $changedsince $reso_field_id, $changedsince
)}; )};
add_indirect_dups(\%since_dups, \%dupe_relation); add_indirect_dups(\%since_dups, \%dupe_relation);

View File

@ -131,7 +131,7 @@ if ($query)
$sqlquery = " UNION ($sqlquery)" if $sqlquery; $sqlquery = " UNION ($sqlquery)" if $sqlquery;
my $tm = "CURRENT_DATE - ".$dbh->sql_interval($lastdays-1, 'DAY'); my $tm = $dbh->sql_date_math('CURRENT_DATE', '-', $lastdays-1, 'DAY');
my $join = $dbh->isa('Bugzilla::DB::Mysql') ? 'STRAIGHT_JOIN' : 'JOIN'; my $join = $dbh->isa('Bugzilla::DB::Mysql') ? 'STRAIGHT_JOIN' : 'JOIN';
my $bugsquery = " my $bugsquery = "
SELECT b.*, p.name product, c.name component, p.notimetracking product_notimetracking, SELECT b.*, p.name product, c.name component, p.notimetracking product_notimetracking,
@ -162,7 +162,7 @@ $vars->{token} = issue_session_token('fill-day-worktime');
$vars->{bugs} = $dbh->selectall_arrayref($bugsquery, {Slice=>{}}, $userid, $userid) || []; $vars->{bugs} = $dbh->selectall_arrayref($bugsquery, {Slice=>{}}, $userid, $userid) || [];
($vars->{timestamp}) = $dbh->selectrow_array("SELECT NOW()"); ($vars->{timestamp}) = $dbh->selectrow_array("SELECT NOW()");
($vars->{totaltime}) = $dbh->selectrow_array("SELECT ROUND(SUM(work_time),2) FROM longdescs WHERE bug_when >= CURRENT_DATE - ".$dbh->sql_interval('?', 'DAY')." AND who=?", undef, $lastdays-1, $userid); ($vars->{totaltime}) = $dbh->selectrow_array("SELECT ROUND(SUM(work_time),2) FROM longdescs WHERE bug_when >= ".$dbh->sql_date_math('CURRENT_DATE', '-', '?', 'DAY')." AND who=?", undef, $lastdays-1, $userid);
($vars->{prevdate1}) = $dbh->selectrow_array("SELECT DATE(MAX(bug_when)) FROM longdescs WHERE bug_when < CURRENT_DATE AND who=?", undef, $userid); ($vars->{prevdate1}) = $dbh->selectrow_array("SELECT DATE(MAX(bug_when)) FROM longdescs WHERE bug_when < CURRENT_DATE AND who=?", undef, $userid);
$vars->{totaltime} ||= 0; $vars->{totaltime} ||= 0;

View File

@ -258,11 +258,11 @@ if ($ARGS->{rescanallBugMail})
require Bugzilla::BugMail; require Bugzilla::BugMail;
Status('send_bugmail_start'); Status('send_bugmail_start');
my $time = $dbh->sql_interval(30, 'MINUTE'); my $time = $dbh->sql_date_math('NOW()', '-', 30, 'MINUTE');
my $list = $dbh->selectcol_arrayref( my $list = $dbh->selectcol_arrayref(
"SELECT bug_id FROM bugs WHERE (lastdiffed IS NULL OR lastdiffed < delta_ts)". "SELECT bug_id FROM bugs WHERE (lastdiffed IS NULL OR lastdiffed < delta_ts)".
" AND delta_ts < now() - $time ORDER BY bug_id" " AND delta_ts < $time ORDER BY bug_id"
); );
Status('send_bugmail_status', { bug_count => scalar @$list }); Status('send_bugmail_status', { bug_count => scalar @$list });
@ -759,10 +759,10 @@ BugCheck(
Status('unsent_bugmail_check'); Status('unsent_bugmail_check');
my $time = $dbh->sql_interval(30, 'MINUTE'); my $time = $dbh->sql_date_math('NOW()', '-', 30, 'MINUTE');
my $badbugs = $dbh->selectcol_arrayref( my $badbugs = $dbh->selectcol_arrayref(
"SELECT bug_id FROM bugs WHERE (lastdiffed IS NULL OR lastdiffed < delta_ts)". "SELECT bug_id FROM bugs WHERE (lastdiffed IS NULL OR lastdiffed < delta_ts)".
" AND delta_ts < now() - $time ORDER BY bug_id" " AND delta_ts < $time ORDER BY bug_id"
); );
if (@$badbugs) if (@$badbugs)
{ {

View File

@ -56,7 +56,7 @@ sub DoAccount
# First delete old tokens. # First delete old tokens.
Bugzilla::Token::CleanTokenTable(); Bugzilla::Token::CleanTokenTable();
my @token = $dbh->selectrow_array( my @token = $dbh->selectrow_array(
"SELECT tokentype, issuedate + " . $dbh->sql_interval(MAX_TOKEN_AGE, 'DAY') . ", eventdata". "SELECT tokentype, " . $dbh->sql_date_math('issuedate', '+', MAX_TOKEN_AGE, 'DAY') . ", eventdata".
" FROM tokens WHERE userid = ? AND tokentype LIKE 'email%'". " FROM tokens WHERE userid = ? AND tokentype LIKE 'email%'".
" ORDER BY tokentype ASC " . $dbh->sql_limit(1), undef, $user->id " ORDER BY tokentype ASC " . $dbh->sql_limit(1), undef, $user->id
); );

View File

@ -147,20 +147,22 @@ while (my ($schedule_id, $day, $time) = $sched_h->fetchrow_array) {
# A time greater than now means it still has to run today # A time greater than now means it still has to run today
elsif ($time >= $now_hour) { elsif ($time >= $now_hour) {
# set it to today + number of hours # set it to today + number of hours
$sth = $dbh->prepare("UPDATE whine_schedules " . $sth = $dbh->prepare(
"SET run_next = CURRENT_DATE + " . "UPDATE whine_schedules " .
$dbh->sql_interval('?', 'HOUR') . "SET run_next = " .
" WHERE id = ?"); $dbh->sql_date_math('CURRENT_DATE', '+', '?', 'HOUR') .
" WHERE id = ?");
$sth->execute($time, $schedule_id); $sth->execute($time, $schedule_id);
} }
# the target time is less than the current time # the target time is less than the current time
else { # set it for the next applicable day else { # set it for the next applicable day
$day = &get_next_date($day); $day = &get_next_date($day);
my $run_next = $dbh->sql_date_math('('
. $dbh->sql_date_math('CURRENT_DATE', '+', '?', 'DAY')
. ')', '+', '?', 'HOUR');
$sth = $dbh->prepare("UPDATE whine_schedules " . $sth = $dbh->prepare("UPDATE whine_schedules " .
"SET run_next = (CURRENT_DATE + " . "SET run_next = $run_next
$dbh->sql_interval('?', 'DAY') . ") + " . WHERE id = ?");
$dbh->sql_interval('?', 'HOUR') .
" WHERE id = ?");
$sth->execute($day, $time, $schedule_id); $sth->execute($day, $time, $schedule_id);
} }
@ -173,11 +175,12 @@ while (my ($schedule_id, $day, $time) = $sched_h->fetchrow_array) {
# midnight # midnight
my $target_time = ($time =~ /^\d+$/) ? $time : 0; my $target_time = ($time =~ /^\d+$/) ? $time : 0;
my $run_next = $dbh->sql_date_math('('
. $dbh->sql_date_math('CURRENT_DATE', '+', '?', 'DAY')
. ')', '+', '?', 'HOUR');
$sth = $dbh->prepare("UPDATE whine_schedules " . $sth = $dbh->prepare("UPDATE whine_schedules " .
"SET run_next = (CURRENT_DATE + " . "SET run_next = $run_next
$dbh->sql_interval('?', 'DAY') . ") + " . WHERE id = ?");
$dbh->sql_interval('?', 'HOUR') .
" WHERE id = ?");
$sth->execute($target_date, $target_time, $schedule_id); $sth->execute($target_date, $target_time, $schedule_id);
} }
} }
@ -565,21 +568,22 @@ sub reset_timer {
my $target_time = ($run_time =~ /^\d+$/) ? $run_time : 0; my $target_time = ($run_time =~ /^\d+$/) ? $run_time : 0;
my $nextdate = &get_next_date($run_day); my $nextdate = &get_next_date($run_day);
my $run_next = $dbh->sql_date_math('('
. $dbh->sql_date_math('CURRENT_DATE', '+', '?', 'DAY')
. ')', '+', '?', 'HOUR');
$sth = $dbh->prepare("UPDATE whine_schedules " . $sth = $dbh->prepare("UPDATE whine_schedules " .
"SET run_next = (CURRENT_DATE + " . "SET run_next = $run_next
$dbh->sql_interval('?', 'DAY') . ") + " . WHERE id = ?");
$dbh->sql_interval('?', 'HOUR') .
" WHERE id = ?");
$sth->execute($nextdate, $target_time, $schedule_id); $sth->execute($nextdate, $target_time, $schedule_id);
return; return;
} }
if ($minute_offset > 0) { if ($minute_offset > 0) {
# Scheduling is done in terms of whole minutes. # Scheduling is done in terms of whole minutes.
my $next_run = $dbh->selectrow_array('SELECT NOW() + ' .
$dbh->sql_interval('?', 'MINUTE'), my $next_run = $dbh->selectrow_array(
undef, $minute_offset); 'SELECT ' . $dbh->sql_date_math('NOW()', '+', '?', 'MINUTE'),
undef, $minute_offset);
$next_run = format_time($next_run, "%Y-%m-%d %R"); $next_run = format_time($next_run, "%Y-%m-%d %R");
$sth = $dbh->prepare("UPDATE whine_schedules " . $sth = $dbh->prepare("UPDATE whine_schedules " .