Merge branch 'master' into topic/constructor_rewrite
[dbsrgits/DBIx-Class.git] / t / sqlmaker / limit_dialects / torture.t
index 976b0c9..9c998a5 100644 (file)
@@ -2,11 +2,13 @@ use strict;
 use warnings;
 
 use Test::More;
+use Test::Exception;
 use lib qw(t/lib);
 use DBICTest;
 use DBIC::SqlMakerTest;
 
 my $schema = DBICTest->init_schema;
+my $native_limit_dialect = $schema->storage->sql_maker->{limit_dialect};
 
 my $attr = {};
 my @where_bind = (
@@ -28,13 +30,16 @@ my @order_bind = (
 );
 
 my $tests = {
+
   LimitOffset => {
     ordered_limit_offset => [
       '(
-        SELECT me.id, ? * ?, ?
+        SELECT me.id, owner.id, owner.name, ? * ?, ?
           FROM books me
+          JOIN owners owner
+            ON owner.id = me.owner
         WHERE source != ? AND me.title = ? AND source = ?
-        GROUP BY avg(me.id / ?)
+        GROUP BY AVG(me.id / ?), MAX(owner.id)
         HAVING ?
         ORDER BY ? / ?, ?
         LIMIT ?
@@ -50,15 +55,33 @@ my $tests = {
         [ { sqlt_datatype => 'integer' } => 3 ],
       ],
     ],
+    limit_offset_prefetch => [
+      '(
+        SELECT me.name, books.id, books.source, books.owner, books.title, books.price
+          FROM (
+            SELECT me.name, me.id
+              FROM owners me
+            LIMIT ? OFFSET ?
+          ) me
+          LEFT JOIN books books
+            ON books.owner = me.id
+      )',
+      [
+        [ { sqlt_datatype => 'integer' } => 3 ],
+        [ { sqlt_datatype => 'integer' } => 1 ],
+      ]
+    ],
   },
 
   LimitXY => {
     ordered_limit_offset => [
       '(
-        SELECT me.id, ? * ?, ?
+        SELECT me.id, owner.id, owner.name, ? * ?, ?
           FROM books me
+          JOIN owners owner
+            ON owner.id = me.owner
         WHERE source != ? AND me.title = ? AND source = ?
-        GROUP BY avg(me.id / ?)
+        GROUP BY AVG(me.id / ?), MAX(owner.id)
         HAVING ?
         ORDER BY ? / ?, ?
         LIMIT ?, ?
@@ -73,15 +96,33 @@ my $tests = {
         [ { sqlt_datatype => 'integer' } => 4 ],
       ],
     ],
+    limit_offset_prefetch => [
+      '(
+        SELECT me.name, books.id, books.source, books.owner, books.title, books.price
+          FROM (
+            SELECT me.name, me.id
+              FROM owners me
+            LIMIT ?,?
+          ) me
+          LEFT JOIN books books
+            ON books.owner = me.id
+      )',
+      [
+        [ { sqlt_datatype => 'integer' } => 1 ],
+        [ { sqlt_datatype => 'integer' } => 3 ],
+      ]
+    ],
   },
 
   SkipFirst => {
     ordered_limit_offset => [
       '(
-        SELECT SKIP ? FIRST ? me.id, ? * ?, ?
+        SELECT SKIP ? FIRST ? me.id, owner.id, owner.name, ? * ?, ?
           FROM books me
+          JOIN owners owner
+            ON owner.id = me.owner
         WHERE source != ? AND me.title = ? AND source = ?
-        GROUP BY avg(me.id / ?)
+        GROUP BY AVG(me.id / ?), MAX(owner.id)
         HAVING ?
         ORDER BY ? / ?, ?
       )',
@@ -95,15 +136,32 @@ my $tests = {
         @order_bind,
       ],
     ],
+    limit_offset_prefetch => [
+      '(
+        SELECT me.name, books.id, books.source, books.owner, books.title, books.price
+          FROM (
+            SELECT SKIP ? FIRST ? me.name, me.id
+              FROM owners me
+          ) me
+          LEFT JOIN books books
+            ON books.owner = me.id
+      )',
+      [
+        [ { sqlt_datatype => 'integer' } => 1 ],
+        [ { sqlt_datatype => 'integer' } => 3 ],
+      ]
+    ],
   },
 
   FirstSkip => {
     ordered_limit_offset => [
       '(
-        SELECT FIRST ? SKIP ? me.id, ? * ?, ?
+        SELECT FIRST ? SKIP ? me.id, owner.id, owner.name, ? * ?, ?
           FROM books me
+          JOIN owners owner
+            ON owner.id = me.owner
         WHERE source != ? AND me.title = ? AND source = ?
-        GROUP BY avg(me.id / ?)
+        GROUP BY AVG(me.id / ?), MAX(owner.id)
         HAVING ?
         ORDER BY ? / ?, ?
       )',
@@ -117,18 +175,35 @@ my $tests = {
         @order_bind,
       ],
     ],
+    limit_offset_prefetch => [
+      '(
+        SELECT me.name, books.id, books.source, books.owner, books.title, books.price
+          FROM (
+            SELECT FIRST ? SKIP ? me.name, me.id
+              FROM owners me
+          ) me
+          LEFT JOIN books books
+            ON books.owner = me.id
+      )',
+      [
+        [ { sqlt_datatype => 'integer' } => 3 ],
+        [ { sqlt_datatype => 'integer' } => 1 ],
+      ]
+    ],
   },
 
   RowNumberOver => do {
     my $unordered_sql = '(
-      SELECT me.id, bar, baz
+      SELECT me.id, owner__id, owner__name, bar, baz
         FROM (
-          SELECT me.id, bar, baz, ROW_NUMBER() OVER() AS rno__row__index
+          SELECT me.id, owner__id, owner__name, bar, baz, ROW_NUMBER() OVER() AS rno__row__index
             FROM (
-              SELECT me.id, ? * ? AS bar, ? AS baz
+              SELECT me.id, owner.id AS owner__id, owner.name AS owner__name, ? * ? AS bar, ? AS baz
                 FROM books me
+                JOIN owners owner
+                  ON owner.id = me.owner
               WHERE source != ? AND me.title = ? AND source = ?
-              GROUP BY avg(me.id / ?)
+              GROUP BY AVG(me.id / ?), MAX(owner.id)
               HAVING ?
             ) me
       ) me
@@ -136,15 +211,17 @@ my $tests = {
     )';
 
     my $ordered_sql = '(
-      SELECT me.id, bar, baz
+      SELECT me.id, owner__id, owner__name, bar, baz
         FROM (
-          SELECT me.id, bar, baz, ROW_NUMBER() OVER( ORDER BY ORDER__BY__1, ORDER__BY__2 ) AS rno__row__index
+          SELECT me.id, owner__id, owner__name, bar, baz, ROW_NUMBER() OVER( ORDER BY ORDER__BY__001, ORDER__BY__002 ) AS rno__row__index
             FROM (
-              SELECT me.id, ? * ? AS bar, ? AS baz,
-                     ? / ? AS ORDER__BY__1, ? AS ORDER__BY__2
+              SELECT me.id, owner.id AS owner__id, owner.name AS owner__name, ? * ? AS bar, ? AS baz,
+                     ? / ? AS ORDER__BY__001, ? AS ORDER__BY__002
                 FROM books me
+                JOIN owners owner
+                  ON owner.id = me.owner
               WHERE source != ? AND me.title = ? AND source = ?
-              GROUP BY avg(me.id / ?)
+              GROUP BY AVG(me.id / ?), MAX(owner.id)
               HAVING ?
             ) me
       ) me
@@ -194,18 +271,41 @@ my $tests = {
           [ { sqlt_datatype => 'integer' } => 7 ],
         ],
       ],
+      limit_offset_prefetch => [
+        '(
+          SELECT me.name, books.id, books.source, books.owner, books.title, books.price
+            FROM (
+              SELECT me.name, me.id
+                FROM (
+                  SELECT me.name, me.id, ROW_NUMBER() OVER() AS rno__row__index
+                  FROM (
+                    SELECT me.name, me.id  FROM owners me
+                  ) me
+                ) me
+              WHERE rno__row__index >= ? AND rno__row__index <= ?
+            ) me
+            LEFT JOIN books books
+              ON books.owner = me.id
+        )',
+        [
+          [ { sqlt_datatype => 'integer' } => 2 ],
+          [ { sqlt_datatype => 'integer' } => 4 ],
+        ]
+      ],
     };
   },
 
   RowNum => do {
     my $limit_sql = sub {
       sprintf '(
-        SELECT me.id, bar, baz
+        SELECT me.id, owner__id, owner__name, bar, baz
           FROM (
-            SELECT me.id, ? * ? AS bar, ? AS baz
+            SELECT me.id, owner.id AS owner__id, owner.name AS owner__name, ? * ? AS bar, ? AS baz
               FROM books me
+              JOIN owners owner
+                ON owner.id = me.owner
             WHERE source != ? AND me.title = ? AND source = ?
-            GROUP BY avg(me.id / ?)
+            GROUP BY AVG(me.id / ?), MAX(owner.id)
             HAVING ?
             %s
           ) me
@@ -225,14 +325,16 @@ my $tests = {
       ],
       limit_offset => [
         '(
-          SELECT me.id, bar, baz
+          SELECT me.id, owner__id, owner__name, bar, baz
             FROM (
-              SELECT me.id, bar, baz, ROWNUM rownum__index
+              SELECT me.id, owner__id, owner__name, bar, baz, ROWNUM rownum__index
                 FROM (
-                  SELECT me.id, ? * ? AS bar, ? AS baz
+                  SELECT me.id, owner.id AS owner__id, owner.name AS owner__name, ? * ? AS bar, ? AS baz
                     FROM books me
+                    JOIN owners owner
+                      ON owner.id = me.owner
                   WHERE source != ? AND me.title = ? AND source = ?
-                  GROUP BY avg(me.id / ?)
+                  GROUP BY AVG(me.id / ?), MAX(owner.id)
                   HAVING ?
                 ) me
             ) me
@@ -259,14 +361,16 @@ my $tests = {
       ],
       ordered_limit_offset => [
         '(
-          SELECT me.id, bar, baz
+          SELECT me.id, owner__id, owner__name, bar, baz
             FROM (
-              SELECT me.id, bar, baz, ROWNUM rownum__index
+              SELECT me.id, owner__id, owner__name, bar, baz, ROWNUM rownum__index
                 FROM (
-                  SELECT me.id, ? * ? AS bar, ? AS baz
+                  SELECT me.id, owner.id AS owner__id, owner.name AS owner__name, ? * ? AS bar, ? AS baz
                     FROM books me
+                    JOIN owners owner
+                      ON owner.id = me.owner
                   WHERE source != ? AND me.title = ? AND source = ?
-                  GROUP BY avg(me.id / ?)
+                  GROUP BY AVG(me.id / ?), MAX(owner.id)
                   HAVING ?
                   ORDER BY ? / ?, ?
                 ) me
@@ -284,17 +388,39 @@ my $tests = {
           [ { sqlt_datatype => 'integer' } => 4 ],
         ],
       ],
+      limit_offset_prefetch => [
+        '(
+          SELECT me.name, books.id, books.source, books.owner, books.title, books.price
+            FROM (
+              SELECT me.name, me.id
+                FROM (
+                  SELECT me.name, me.id, ROWNUM rownum__index
+                    FROM (
+                      SELECT me.name, me.id
+                        FROM owners me
+                    ) me
+                ) me WHERE rownum__index BETWEEN ? AND ?
+            ) me
+            LEFT JOIN books books
+              ON books.owner = me.id
+        )',
+        [
+          [ { sqlt_datatype => 'integer' } => 2 ],
+          [ { sqlt_datatype => 'integer' } => 4 ],
+        ]
+      ],
     };
   },
 
-
   FetchFirst => {
     limit => [
       '(
-        SELECT me.id, ? * ?, ?
+        SELECT me.id, owner.id, owner.name, ? * ?, ?
           FROM books me
+          JOIN owners owner
+            ON owner.id = me.owner
         WHERE source != ? AND me.title = ? AND source = ?
-        GROUP BY avg(me.id / ?)
+        GROUP BY AVG(me.id / ?), MAX(owner.id)
         HAVING ?
         FETCH FIRST 4 ROWS ONLY
       )',
@@ -307,12 +433,14 @@ my $tests = {
     ],
     limit_offset => [
       '(
-        SELECT me.id, bar, baz
+        SELECT me.id, owner__id, owner__name, bar, baz
           FROM (
-            SELECT me.id, ? * ? AS bar, ? AS baz
+            SELECT me.id, owner.id AS owner__id, owner.name AS owner__name, ? * ? AS bar, ? AS baz
               FROM books me
+              JOIN owners owner
+                ON owner.id = me.owner
             WHERE source != ? AND me.title = ? AND source = ?
-            GROUP BY avg(me.id / ?)
+            GROUP BY AVG(me.id / ?), MAX(owner.id)
             HAVING ?
             ORDER BY me.id
             FETCH FIRST 7 ROWS ONLY
@@ -329,10 +457,12 @@ my $tests = {
     ],
     ordered_limit => [
       '(
-        SELECT me.id, ? * ?, ?
+        SELECT me.id, owner.id, owner.name, ? * ?, ?
           FROM books me
+          JOIN owners owner
+            ON owner.id = me.owner
         WHERE source != ? AND me.title = ? AND source = ?
-        GROUP BY avg(me.id / ?)
+        GROUP BY AVG(me.id / ?), MAX(owner.id)
         HAVING ?
         ORDER BY ? / ?, ?
         FETCH FIRST 4 ROWS ONLY
@@ -347,22 +477,24 @@ my $tests = {
     ],
     ordered_limit_offset => [
       '(
-        SELECT me.id, bar, baz
+        SELECT me.id, owner__id, owner__name, bar, baz
           FROM (
-            SELECT me.id, bar, baz, ORDER__BY__1, ORDER__BY__2
+            SELECT me.id, owner__id, owner__name, bar, baz, ORDER__BY__001, ORDER__BY__002
               FROM (
-                SELECT me.id, ? * ? AS bar, ? AS baz, ? / ? AS ORDER__BY__1, ? AS ORDER__BY__2
+                SELECT me.id, owner.id AS owner__id, owner.name AS owner__name, ? * ? AS bar, ? AS baz, ? / ? AS ORDER__BY__001, ? AS ORDER__BY__002
                   FROM books me
+                  JOIN owners owner
+                    ON owner.id = me.owner
                 WHERE source != ? AND me.title = ? AND source = ?
-                GROUP BY avg(me.id / ?)
+                GROUP BY AVG(me.id / ?), MAX(owner.id)
                 HAVING ?
                 ORDER BY ? / ?, ?
                 FETCH FIRST 7 ROWS ONLY
               ) me
-            ORDER BY ORDER__BY__1 DESC, ORDER__BY__2 DESC
+            ORDER BY ORDER__BY__001 DESC, ORDER__BY__002 DESC
             FETCH FIRST 4 ROWS ONLY
           ) me
-        ORDER BY ORDER__BY__1, ORDER__BY__2
+        ORDER BY ORDER__BY__001, ORDER__BY__002
       )',
       [
         @select_bind,
@@ -373,15 +505,36 @@ my $tests = {
         (map { [ @$_ ] } @order_bind),  # without this is_deeply throws a fit
       ],
     ],
+    limit_offset_prefetch => [
+      '(
+        SELECT me.name, books.id, books.source, books.owner, books.title, books.price
+          FROM (
+            SELECT me.name, me.id
+              FROM (
+                SELECT me.name, me.id
+                  FROM owners me
+                ORDER BY me.id
+                FETCH FIRST 4 ROWS ONLY
+              ) me
+              ORDER BY me.id DESC
+            FETCH FIRST 3 ROWS ONLY
+          ) me
+          LEFT JOIN books books
+            ON books.owner = me.id
+      )',
+      [],
+    ],
   },
 
   Top => {
     limit => [
       '(
-        SELECT TOP 4 me.id, ? * ?, ?
+        SELECT TOP 4 me.id, owner.id, owner.name, ? * ?, ?
           FROM books me
+          JOIN owners owner
+            ON owner.id = me.owner
         WHERE source != ? AND me.title = ? AND source = ?
-        GROUP BY avg(me.id / ?)
+        GROUP BY AVG(me.id / ?), MAX(owner.id)
         HAVING ?
       )',
       [
@@ -393,12 +546,14 @@ my $tests = {
     ],
     limit_offset => [
       '(
-        SELECT TOP 4 me.id, bar, baz
+        SELECT TOP 4 me.id, owner__id, owner__name, bar, baz
           FROM (
-            SELECT TOP 7 me.id, ? * ? AS bar, ? AS baz
+            SELECT TOP 7 me.id, owner.id AS owner__id, owner.name AS owner__name, ? * ? AS bar, ? AS baz
               FROM books me
+              JOIN owners owner
+                ON owner.id = me.owner
             WHERE source != ? AND me.title = ? AND source = ?
-            GROUP BY avg(me.id / ?)
+            GROUP BY AVG(me.id / ?), MAX(owner.id)
             HAVING ?
             ORDER BY me.id
           ) me
@@ -413,10 +568,12 @@ my $tests = {
     ],
     ordered_limit => [
       '(
-        SELECT TOP 4 me.id, ? * ?, ?
+        SELECT TOP 4 me.id, owner.id, owner.name, ? * ?, ?
           FROM books me
+          JOIN owners owner
+            ON owner.id = me.owner
         WHERE source != ? AND me.title = ? AND source = ?
-        GROUP BY avg(me.id / ?)
+        GROUP BY AVG(me.id / ?), MAX(owner.id)
         HAVING ?
         ORDER BY ? / ?, ?
       )',
@@ -430,20 +587,22 @@ my $tests = {
     ],
     ordered_limit_offset => [
       '(
-        SELECT me.id, bar, baz
+        SELECT me.id, owner__id, owner__name, bar, baz
           FROM (
-            SELECT TOP 4 me.id, bar, baz, ORDER__BY__1, ORDER__BY__2
+            SELECT TOP 4 me.id, owner__id, owner__name, bar, baz, ORDER__BY__001, ORDER__BY__002
               FROM (
-                SELECT TOP 7 me.id, ? * ? AS bar, ? AS baz, ? / ? AS ORDER__BY__1, ? AS ORDER__BY__2
+                SELECT TOP 7 me.id, owner.id AS owner__id, owner.name AS owner__name, ? * ? AS bar, ? AS baz, ? / ? AS ORDER__BY__001, ? AS ORDER__BY__002
                   FROM books me
+                  JOIN owners owner
+                    ON owner.id = me.owner
                 WHERE source != ? AND me.title = ? AND source = ?
-                GROUP BY avg(me.id / ?)
+                GROUP BY AVG(me.id / ?), MAX(owner.id)
                 HAVING ?
                 ORDER BY ? / ?, ?
               ) me
-            ORDER BY ORDER__BY__1 DESC, ORDER__BY__2 DESC
+            ORDER BY ORDER__BY__001 DESC, ORDER__BY__002 DESC
           ) me
-        ORDER BY ORDER__BY__1, ORDER__BY__2
+        ORDER BY ORDER__BY__001, ORDER__BY__002
       )',
       [
         @select_bind,
@@ -454,64 +613,36 @@ my $tests = {
         (map { [ @$_ ] } @order_bind),  # without this is_deeply throws a fit
       ],
     ],
-  },
-
-  RowCountOrGenericSubQ => {
-    limit => [
+    limit_offset_prefetch => [
       '(
-        SET ROWCOUNT 4
-        SELECT me.id, ? * ?, ?
-          FROM books me
-        WHERE source != ? AND me.title = ? AND source = ?
-        GROUP BY avg(me.id / ?)
-        HAVING ?
-        ORDER BY me.id
-        SET ROWCOUNT 0
-      )',
-      [
-        @select_bind,
-        @where_bind,
-        @group_bind,
-        @having_bind,
-      ],
-    ],
-    limit_offset => [
-      '(
-        SELECT me.id, bar, baz
+        SELECT me.name, books.id, books.source, books.owner, books.title, books.price
           FROM (
-            SELECT me.id, ? * ? AS bar, ? AS baz
-              FROM books me
-            WHERE source != ? AND me.title = ? AND source = ?
-            GROUP BY avg( me.id / ? )
-            HAVING ?
+            SELECT TOP 3 me.name, me.id
+              FROM (
+                SELECT TOP 4 me.name, me.id
+                  FROM owners me
+                ORDER BY me.id
+              ) me
+              ORDER BY me.id DESC
           ) me
-        WHERE (
-          SELECT COUNT( * )
-            FROM books rownum__emulation
-          WHERE rownum__emulation.id < me.id
-        ) BETWEEN ? AND ?
-        ORDER BY me.id
+          LEFT JOIN books books
+            ON books.owner = me.id
       )',
-      [
-        @select_bind,
-        @where_bind,
-        @group_bind,
-        @having_bind,
-        [ { sqlt_datatype => 'integer' } => 3 ],
-        [ { sqlt_datatype => 'integer' } => 6 ],
-      ],
+      [],
     ],
   },
 
   GenericSubQ => {
     limit => [
       '(
-        SELECT me.id, bar, baz
+        SELECT me.id, owner__id, owner__name, bar, baz
           FROM (
-            SELECT me.id, ? * ? AS bar, ? AS baz
+            SELECT me.id, owner.id AS owner__id, owner.name AS owner__name, ? * ? AS bar, ? AS baz
               FROM books me
+              JOIN owners owner
+                ON owner.id = me.owner
             WHERE source != ? AND me.title = ? AND source = ?
-            GROUP BY avg( me.id / ? )
+            GROUP BY AVG(me.id / ?), MAX(owner.id)
             HAVING ?
           ) me
         WHERE (
@@ -531,12 +662,14 @@ my $tests = {
     ],
     limit_offset => [
       '(
-        SELECT me.id, bar, baz
+        SELECT me.id, owner__id, owner__name, bar, baz
           FROM (
-            SELECT me.id, ? * ? AS bar, ? AS baz
+            SELECT me.id, owner.id AS owner__id, owner.name AS owner__name, ? * ? AS bar, ? AS baz
               FROM books me
+              JOIN owners owner
+                ON owner.id = me.owner
             WHERE source != ? AND me.title = ? AND source = ?
-            GROUP BY avg( me.id / ? )
+            GROUP BY AVG(me.id / ?), MAX(owner.id)
             HAVING ?
           ) me
         WHERE (
@@ -555,20 +688,47 @@ my $tests = {
         [ { sqlt_datatype => 'integer' } => 6 ],
       ],
     ],
+    limit_offset_prefetch => [
+      '(
+        SELECT me.name, books.id, books.source, books.owner, books.title, books.price
+          FROM (
+            SELECT me.name, me.id
+              FROM (
+                SELECT me.name, me.id  FROM owners me
+              ) me
+            WHERE (
+              SELECT COUNT(*)
+                FROM owners rownum__emulation
+              WHERE rownum__emulation.id < me.id
+            ) BETWEEN ? AND ?
+            ORDER BY me.id
+          ) me
+          LEFT JOIN books books
+            ON books.owner = me.id
+        ORDER BY me.id
+      )',
+      [
+        [ { sqlt_datatype => 'integer' } => 1 ],
+        [ { sqlt_datatype => 'integer' } => 3 ],
+      ],
+    ],
   }
 };
 
 for my $limtype (sort keys %$tests) {
 
+  Test::Builder->new->is_passing or exit;
+
   delete $schema->storage->_sql_maker->{_cached_syntax};
   $schema->storage->_sql_maker->limit_dialect ($limtype);
 
   # chained search is necessary to exercise the recursive {where} parser
   my $rs = $schema->resultset('BooksInLibrary')->search({ 'me.title' => { '=' => 'kama sutra' } })->search({ source => { '!=', 'Study' } }, {
-    columns => { identifier => 'me.id' }, # people actually do that. BLEH!!! :)
+    columns => [ { identifier => 'me.id' }, 'owner.id', 'owner.name' ], # people actually do that. BLEH!!! :)
+    join => 'owner',  # single-rel manual prefetch
     rows => 4,
     '+columns' => { bar => \['? * ?', [ $attr => 11 ], [ $attr => 12 ]], baz => \[ '?', [ $attr => 13 ]] },
-    group_by => \[ 'avg(me.id / ?)', [ $attr => 21 ] ],
+    group_by => \[ 'AVG(me.id / ?), MAX(owner.id)', [ $attr => 21 ] ],
     having => \[ '?', [ $attr => 31 ] ],
     ($limtype =~ /GenericSubQ/ ? ( order_by => 'me.id' ) : () ),  # needs a simple-column stable order to be happy
   });
@@ -608,6 +768,27 @@ for my $limtype (sort keys %$tests) {
     @{$tests->{$limtype}{ordered_limit_offset}},
     "$limtype: Ordered limit+offset with select/group/having",
   ) if $tests->{$limtype}{ordered_limit_offset};
+
+  # complex prefetch on partial-fetch root with limit
+  my $pref_rs = $schema->resultset('Owners')->search({}, {
+    rows => 3,
+    offset => 1,
+    columns => 'name',  # only the owner name, still prefetch all the books
+    prefetch => 'books',
+    ($limtype =~ /GenericSubQ/ ? ( order_by => 'me.id' ) : () ),  # needs a simple-column stable order to be happy
+  });
+
+  is_same_sql_bind (
+    $pref_rs->as_query,
+    @{$tests->{$limtype}{limit_offset_prefetch}},
+    "$limtype: Prefetch with limit+offset",
+  ) if $tests->{$limtype}{limit_offset_prefetch};
+
+  # we can actually run the query
+  if ($limtype eq $native_limit_dialect or $limtype eq 'GenericSubQ') {
+    lives_ok { is ($pref_rs->all, 1, 'Expected count of objects on limtied prefetch') }
+      "Complex limited prefetch works with supported limit $limtype"
+  }
 }
 
 done_testing;