- Fix leakage of $schema on in-memory new_related() calls
- Fix more cases of $schema leakage in SQLT::Parser::DBIC
- Fix leakage of $storage in ::Storage::DBI::Oracle
+ - Fix pessimization of Oracle RowNum limit dialect query when no
+ offset has been specified
- Remove useless vestigial pessimization in Ordered.pm for cases
when the position column is part of a unique constraint
- Fix dbicadmin to no longer ignore the documented 'config' option
my $idx_name = $self->_quote ('rownum__index');
my $order_group_having = $self->_parse_rs_attrs($rs_attrs);
+
+ # if no offset (e.g. first page) - we can skip one of the subqueries
+ if (! $offset) {
+ push @{$self->{limit_bind}}, [ $self->__rows_bindtype => $rows ];
+
+ return <<EOS;
+SELECT $outsel FROM (
+ SELECT $insel ${stripped_sql}${order_group_having}
+) $qalias WHERE ROWNUM <= ?
+EOS
+ }
+
#
# There are two ways to limit in Oracle, one vastly faster than the other
# on large resultsets: https://decipherinfosys.wordpress.com/2007/08/09/paging-and-countstopkey-optimization/
$rs_attrs->{from}, $rs_attrs->{order_by}
)
) {
- # if offset is 0 (first page) the we can skip a subquery
- if (! $offset) {
- push @{$self->{limit_bind}}, [ $self->__rows_bindtype => $rows ];
+ push @{$self->{limit_bind}}, [ $self->__total_bindtype => $offset + $rows ], [ $self->__offset_bindtype => $offset + 1 ];
- return <<EOS;
-SELECT $outsel FROM (
- SELECT $insel ${stripped_sql}${order_group_having}
-) $qalias WHERE ROWNUM <= ?
-EOS
- }
- else {
- push @{$self->{limit_bind}}, [ $self->__total_bindtype => $offset + $rows ], [ $self->__offset_bindtype => $offset + 1 ];
-
- return <<EOS;
+ return <<EOS;
SELECT $outsel FROM (
SELECT $outsel, ROWNUM $idx_name FROM (
SELECT $insel ${stripped_sql}${order_group_having}
) $qalias WHERE ROWNUM <= ?
) $qalias WHERE $idx_name >= ?
EOS
- }
}
else {
push @{$self->{limit_bind}}, [ $self->__offset_bindtype => $offset + 1 ], [ $self->__total_bindtype => $offset + $rows ];
FROM (
SELECT artistid
FROM (
- SELECT artistid, ROWNUM rownum__index
- FROM (
- SELECT me.artistid
- FROM artist me
- START WITH name = ?
- CONNECT BY parentid = PRIOR artistid
- ) me
+ SELECT me.artistid
+ FROM artist me
+ START WITH name = ?
+ CONNECT BY parentid = PRIOR artistid
) me
- WHERE rownum__index BETWEEN ? AND ?
+ WHERE ROWNUM <= ?
) me
)',
[
[ { 'sqlt_datatype' => 'varchar', 'dbic_colname' => 'name', 'sqlt_size' => 100 }
=> 'root'],
- [ $ROWS => 1 ],
- [ $TOTAL => 2 ],
+ [ $ROWS => 2 ],
],
);
use DBIC::SqlMakerTest;
use DBIx::Class::SQLMaker::LimitDialects;
-my ($TOTAL, $OFFSET) = (
+my ($TOTAL, $OFFSET, $ROWS) = (
DBIx::Class::SQLMaker::LimitDialects->__total_bindtype,
DBIx::Class::SQLMaker::LimitDialects->__offset_bindtype,
+ DBIx::Class::SQLMaker::LimitDialects->__rows_bindtype,
);
my $s = DBICTest->init_schema (no_deploy => 1, );
$rs_selectas_rel->as_query,
'(
SELECT id, owner FROM (
- SELECT id, owner, ROWNUM rownum__index FROM (
- SELECT me.id, me.owner FROM books me WHERE ( ( (EXISTS (SELECT COUNT( * ) FROM owners owner WHERE ( books.owner = owner.id ))) AND source = ? ) )
- ) me
- ) me WHERE rownum__index BETWEEN ? AND ?
+ SELECT me.id, me.owner FROM books me WHERE ( ( (EXISTS (SELECT COUNT( * ) FROM owners owner WHERE ( books.owner = owner.id ))) AND source = ? ) )
+ ) me
+ WHERE ROWNUM <= ?
)',
[
[ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'source' } => 'Library' ],
- [ $OFFSET => 1 ],
- [ $TOTAL => 1 ],
+ [ $ROWS => 1 ],
],
'Pagination with sub-query in WHERE works'
);
}
-
done_testing;