];
}
- if ( defined $attrs->{order_by} ) {
- $attrs->{order_by} = (
- ref( $attrs->{order_by} ) eq 'ARRAY'
- ? [ @{ $attrs->{order_by} } ]
- : [ $attrs->{order_by} || () ]
- );
- }
+ for my $attr (qw(order_by group_by)) {
- if ($attrs->{group_by} and ref $attrs->{group_by} ne 'ARRAY') {
- $attrs->{group_by} = [ $attrs->{group_by} ];
- }
+ if ( defined $attrs->{$attr} ) {
+ $attrs->{$attr} = (
+ ref( $attrs->{$attr} ) eq 'ARRAY'
+ ? [ @{ $attrs->{$attr} } ]
+ : [ $attrs->{$attr} || () ]
+ );
+ delete $attrs->{$attr} unless @{$attrs->{$attr}};
+ }
+ }
# generate selections based on the prefetch helper
my ($prefetch, @prefetch_select, @prefetch_as);
--- /dev/null
+use strict;
+use warnings;
+
+use Test::More;
+
+use lib qw(t/lib);
+use DBICTest ':DiffSQL';
+
+my $schema = DBICTest->init_schema();
+
+my $rs = $schema->resultset('Artist')->search(
+ [ -and => [ {}, [] ], -or => [ {}, [] ] ],
+ {
+ select => [],
+ columns => {},
+ '+columns' => 'artistid',
+ join => [ {}, [ [ {}, {} ] ], {} ],
+ prefetch => [ [ [ {}, [] ], {} ], {}, [ {} ] ],
+ order_by => [],
+ group_by => [],
+ offset => 0,
+ }
+);
+
+is_same_sql_bind(
+ $rs->as_query,
+ '(SELECT me.artistid FROM artist me)',
+ [],
+);
+
+is_same_sql_bind(
+ $rs->count_rs->as_query,
+ '(SELECT COUNT(*) FROM artist me)',
+ [],
+);
+
+is_same_sql_bind(
+ $rs->as_subselect_rs->search({}, { columns => 'artistid' })->as_query,
+ '(SELECT me.artistid FROM (SELECT me.artistid FROM artist me) me)',
+ [],
+);
+
+{
+ local $TODO = 'Stupid misdesigned as_subselect_rs';
+ is_same_sql_bind(
+ $rs->as_subselect_rs->as_query,
+ $rs->as_subselect_rs->search({}, { columns => 'artistid' })->as_query,
+ );
+}
+
+done_testing;
my $tests = {
LimitOffset => {
+ limit_plain => [
+ "( SELECT me.artistid FROM artist me LIMIT ? )",
+ [
+ [ { sqlt_datatype => 'integer' } => 5 ]
+ ],
+ ],
limit => [
"(
SELECT me.id, owner.id, owner.name, ? * ?, ?
},
LimitXY => {
+ limit_plain => [
+ "( SELECT me.artistid FROM artist me LIMIT ? )",
+ [
+ [ { sqlt_datatype => 'integer' } => 5 ]
+ ],
+ ],
ordered_limit_offset => [
"(
SELECT me.id, owner.id, owner.name, ? * ?, ?
},
SkipFirst => {
+ limit_plain => [
+ "( SELECT FIRST ? me.artistid FROM artist me )",
+ [
+ [ { sqlt_datatype => 'integer' } => 5 ]
+ ],
+ ],
ordered_limit_offset => [
"(
SELECT SKIP ? FIRST ? me.id, owner.id, owner.name, ? * ?, ?
},
FirstSkip => {
+ limit_plain => [
+ "( SELECT FIRST ? me.artistid FROM artist me )",
+ [
+ [ { sqlt_datatype => 'integer' } => 5 ]
+ ],
+ ],
ordered_limit_offset => [
"(
SELECT FIRST ? SKIP ? me.id, owner.id, owner.name, ? * ?, ?
)";
{
+ limit_plain => [
+ "(
+ SELECT me.artistid
+ FROM (
+ SELECT me.artistid, ROW_NUMBER() OVER( ) AS rno__row__index
+ FROM (
+ SELECT me.artistid
+ FROM artist me
+ ) me
+ ) me
+ WHERE rno__row__index >= ? AND rno__row__index <= ?
+ )",
+ [
+ [ { sqlt_datatype => 'integer' } => 1 ],
+ [ { sqlt_datatype => 'integer' } => 5 ],
+ ],
+ ],
limit => [$unordered_sql,
[
@select_bind,
};
{
+ limit_plain => [
+ "(
+ SELECT me.artistid
+ FROM (
+ SELECT me.artistid
+ FROM artist me
+ ) me
+ WHERE ROWNUM <= ?
+ )",
+ [
+ [ { sqlt_datatype => 'integer' } => 5 ],
+ ],
+ ],
limit => [ $limit_sql->(),
[
@select_bind,
},
FetchFirst => {
+ limit_plain => [
+ "( SELECT me.artistid FROM artist me FETCH FIRST 5 ROWS ONLY )",
+ [],
+ ],
limit => [
"(
SELECT me.id, owner.id, owner.name, ? * ?, ?
},
Top => {
+ limit_plain => [
+ "( SELECT TOP 5 me.artistid FROM artist me )",
+ [],
+ ],
limit => [
"(
SELECT TOP 4 me.id, owner.id, owner.name, ? * ?, ?
},
GenericSubQ => {
+ limit_plain => [
+ "(
+ SELECT me.artistid
+ FROM (
+ SELECT me.artistid
+ FROM artist me
+ ) me
+ WHERE
+ (
+ SELECT COUNT(*)
+ FROM artist rownum__emulation
+ WHERE rownum__emulation.artistid < me.artistid
+ ) < ?
+ ORDER BY me.artistid ASC
+ )",
+ [
+ [ { sqlt_datatype => 'integer' } => 5 ]
+ ],
+ ],
ordered_limit => [
"(
SELECT me.id, owner__id, owner__name, bar, baz
delete $schema->storage->_sql_maker->{_cached_syntax};
$schema->storage->_sql_maker->limit_dialect ($limtype);
- my $can_run = ($limtype eq $native_limit_dialect or $limtype eq 'GenericSubQ');
+ # do the simplest thing possible first
+ if ($tests->{$limtype}{limit_plain}) {
+ is_same_sql_bind(
+ $schema->resultset('Artist')->search(
+ [ -and => [ {}, [] ], -or => [ {}, [] ] ],
+ {
+ columns => 'artistid',
+ join => [ {}, [ [ {}, {} ] ], {} ],
+ prefetch => [ [ [ {}, [] ], {} ], {}, [ {} ] ],
+ order_by => ( $limtype eq 'GenericSubQ' ? 'artistid' : [] ),
+ group_by => [],
+ rows => 5,
+ offset => 0,
+ }
+ )->as_query,
+ @{$tests->{$limtype}{limit_plain}},
+ "$limtype: Plain unordered ungrouped select with limit and no offset",
+ )
+ }
# chained search is necessary to exercise the recursive {where} parser
my $rs = $schema->resultset('BooksInLibrary')->search(
#
# not all tests run on all dialects (somewhere impossible, somewhere makes no sense)
#
+ my $can_run = ($limtype eq $native_limit_dialect or $limtype eq 'GenericSubQ');
# only limit, no offset, no order
if ($tests->{$limtype}{limit}) {