Convert many live-only SQL test to standalone is_same_sql_bind cases
Peter Rabbitson [Mon, 4 Nov 2013 09:03:54 +0000 (10:03 +0100)]
t/71mysql.t
t/73oracle_hq.t
t/746mssql.t
t/751msaccess.t
t/sqlmaker/hierarchical/oracle.t [new file with mode: 0644]
t/sqlmaker/limit_dialects/mssql_torture.t [new file with mode: 0644]
t/sqlmaker/msaccess.t
t/sqlmaker/mysql.t

index 58a5669..1e31e8c 100644 (file)
@@ -214,29 +214,6 @@ lives_ok { $cd->set_producers ([ $producer ]) } 'set_relationship doesnt die';
   );
 }
 
-{
-  # Test support for straight joins
-  my $cdsrc = $schema->source('CD');
-  my $artrel_info = $cdsrc->relationship_info ('artist');
-  $cdsrc->add_relationship(
-    'straight_artist',
-    $artrel_info->{class},
-    $artrel_info->{cond},
-    { %{$artrel_info->{attrs}}, join_type => 'straight' },
-  );
-  is_same_sql_bind (
-    $cdsrc->resultset->search({}, { prefetch => 'straight_artist' })->as_query,
-    '(
-      SELECT `me`.`cdid`, `me`.`artist`, `me`.`title`, `me`.`year`, `me`.`genreid`, `me`.`single_track`,
-             `straight_artist`.`artistid`, `straight_artist`.`name`, `straight_artist`.`rank`, `straight_artist`.`charfield`
-        FROM cd `me`
-        STRAIGHT_JOIN `artist` `straight_artist` ON `straight_artist`.`artistid` = `me`.`artist`
-    )',
-    [],
-    'straight joins correctly supported for mysql'
-  );
-}
-
 ## Can we properly deal with the null search problem?
 ##
 ## Only way is to do a SET SQL_AUTO_IS_NULL = 0; on connect
index c09cbfd..0f887fa 100644 (file)
@@ -36,11 +36,6 @@ BEGIN {
 
 use DBICTest;
 use DBICTest::Schema;
-use DBIC::SqlMakerTest;
-
-use DBIx::Class::SQLMaker::LimitDialects;
-my $ROWS = DBIx::Class::SQLMaker::LimitDialects->__rows_bindtype,
-my $TOTAL = DBIx::Class::SQLMaker::LimitDialects->__total_bindtype,
 
 my $schema = DBICTest::Schema->connect($dsn, $user, $pass);
 
@@ -114,35 +109,12 @@ do_creates($dbh);
       connect_by => { parentid => { -prior => { -ident => 'artistid' } } },
     });
 
-    is_same_sql_bind (
-      $rs->as_query,
-      '(
-        SELECT me.artistid, me.name, me.rank, me.charfield, me.parentid
-          FROM artist me
-        START WITH name = ?
-        CONNECT BY parentid = PRIOR artistid
-      )',
-      [ [ { 'sqlt_datatype' => 'varchar', 'dbic_colname' => 'name', 'sqlt_size' => 100 }
-            => 'root'] ],
-    );
     is_deeply (
       [ $rs->get_column ('name')->all ],
       [ qw/root child1 grandchild greatgrandchild child2/ ],
       'got artist tree',
     );
 
-    is_same_sql_bind (
-      $rs->count_rs->as_query,
-      '(
-        SELECT COUNT( * )
-          FROM artist me
-        START WITH name = ?
-        CONNECT BY parentid = PRIOR artistid
-      )',
-      [ [ { 'sqlt_datatype' => 'varchar', 'dbic_colname' => 'name', 'sqlt_size' => 100 }
-            => 'root'] ],
-    );
-
     is( $rs->count, 5, 'Connect By count ok' );
   }
 
@@ -158,19 +130,6 @@ do_creates($dbh);
       order_siblings_by => { -desc => 'name' },
     });
 
-    is_same_sql_bind (
-      $rs->as_query,
-      '(
-        SELECT me.artistid, me.name, me.rank, me.charfield, me.parentid
-          FROM artist me
-        START WITH name = ?
-        CONNECT BY parentid = PRIOR artistid
-        ORDER SIBLINGS BY name DESC
-      )',
-      [ [ { 'sqlt_datatype' => 'varchar', 'dbic_colname' => 'name', 'sqlt_size' => 100 }
-            => 'root'] ],
-    );
-
     is_deeply (
       [ $rs->get_column ('name')->all ],
       [ qw/root child2 child1 grandchild greatgrandchild/ ],
@@ -185,19 +144,6 @@ do_creates($dbh);
       connect_by => { parentid => { -prior => { -ident => 'artistid' } } },
     });
 
-    is_same_sql_bind (
-      $rs->as_query,
-      '(
-        SELECT me.artistid, me.name, me.rank, me.charfield, me.parentid
-          FROM artist me
-        WHERE ( parentid IS NULL )
-        START WITH name = ?
-        CONNECT BY parentid = PRIOR artistid
-      )',
-      [ [ { 'sqlt_datatype' => 'varchar', 'dbic_colname' => 'name', 'sqlt_size' => 100 }
-            => 'root'] ],
-    );
-
     is_deeply(
       [ $rs->get_column('name')->all ],
       [ 'root' ],
@@ -220,48 +166,12 @@ do_creates($dbh);
       }
     );
 
-    is_same_sql_bind (
-      $rs->as_query,
-      '(
-        SELECT me.artistid, me.name, me.rank, me.charfield, me.parentid
-          FROM artist me
-          LEFT JOIN cd cds ON cds.artist = me.artistid
-        WHERE ( cds.title LIKE ? )
-        START WITH me.name = ?
-        CONNECT BY parentid = PRIOR artistid
-      )',
-      [
-        [ { 'sqlt_datatype' => 'varchar', 'dbic_colname' => 'cds.title', 'sqlt_size' => 100 }
-            => '%cd'],
-        [ { 'sqlt_datatype' => 'varchar', 'dbic_colname' => 'me.name', 'sqlt_size' => 100 }
-            => 'root'],
-      ],
-    );
-
     is_deeply(
       [ $rs->get_column('name')->all ],
       [ 'grandchild' ],
       'Connect By with a join result name ok'
     );
 
-    is_same_sql_bind (
-      $rs->count_rs->as_query,
-      '(
-        SELECT COUNT( * )
-          FROM artist me
-          LEFT JOIN cd cds ON cds.artist = me.artistid
-        WHERE ( cds.title LIKE ? )
-        START WITH me.name = ?
-        CONNECT BY parentid = PRIOR artistid
-      )',
-      [
-        [ { 'sqlt_datatype' => 'varchar', 'dbic_colname' => 'cds.title', 'sqlt_size' => 100 }
-            => '%cd'],
-        [ { 'sqlt_datatype' => 'varchar', 'dbic_colname' => 'me.name', 'sqlt_size' => 100 }
-            => 'root'],
-      ],
-    );
-
     is( $rs->count, 1, 'Connect By with a join; count ok' );
   }
 
@@ -273,22 +183,6 @@ do_creates($dbh);
       order_by => { -asc => [ 'LEVEL', 'name' ] },
     });
 
-    is_same_sql_bind (
-      $rs->as_query,
-      '(
-        SELECT me.artistid, me.name, me.rank, me.charfield, me.parentid
-          FROM artist me
-        START WITH name = ?
-        CONNECT BY parentid = PRIOR artistid
-        ORDER BY LEVEL ASC, name ASC
-      )',
-      [
-        [ { 'sqlt_datatype' => 'varchar', 'dbic_colname' => 'name', 'sqlt_size' => 100 }
-            => 'root'],
-      ],
-    );
-
-
     # Don't use "$rs->get_column ('name')->all" they build a query arround the $rs.
     #   If $rs has a order by, the order by is in the subquery and this doesn't work with Oracle 8i.
     # TODO: write extra test and fix order by handling on Oracle 8i
@@ -322,53 +216,12 @@ do_creates($dbh);
       rows => 2,
     });
 
-    is_same_sql_bind (
-      $rs->as_query,
-      '(
-        SELECT me.artistid, me.name, me.rank, me.charfield, me.parentid
-          FROM (
-            SELECT me.artistid, me.name, me.rank, me.charfield, me.parentid
-              FROM artist me
-            START WITH name = ?
-            CONNECT BY parentid = PRIOR artistid
-            ORDER BY name ASC, artistid DESC
-          ) me
-        WHERE ROWNUM <= ?
-      )',
-      [
-        [ { 'sqlt_datatype' => 'varchar', 'dbic_colname' => 'name', 'sqlt_size' => 100 }
-            => 'root'], [ $ROWS => 2 ],
-      ],
-    );
-
     is_deeply (
       [ $rs->get_column ('name')->all ],
       [qw/child1 child2/],
       'LIMIT a Connect By query - correct names'
     );
 
-    is_same_sql_bind (
-      $rs->count_rs->as_query,
-      '(
-        SELECT COUNT( * )
-          FROM (
-            SELECT me.artistid
-              FROM (
-                SELECT me.artistid
-                  FROM artist me
-                START WITH name = ?
-                CONNECT BY parentid = PRIOR artistid
-              ) me
-            WHERE ROWNUM <= ?
-          ) me
-      )',
-      [
-        [ { 'sqlt_datatype' => 'varchar', 'dbic_colname' => 'name', 'sqlt_size' => 100 }
-            => 'root'],
-        [ $ROWS => 2 ],
-      ],
-    );
-
     is( $rs->count, 2, 'Connect By; LIMIT count ok' );
   }
 
@@ -384,27 +237,6 @@ do_creates($dbh);
       having => \[ 'count(rank) < ?', [ cnt => 2 ] ],
     });
 
-    is_same_sql_bind (
-      $rs->as_query,
-      '(
-        SELECT COUNT(rank) + ?
-          FROM artist me
-        START WITH name = ?
-        CONNECT BY parentid = PRIOR artistid
-        GROUP BY( rank + ? ) HAVING count(rank) < ?
-      )',
-      [
-        [ { dbic_colname => '__cbind' }
-            => 3 ],
-        [ { 'sqlt_datatype' => 'varchar', 'dbic_colname' => 'name', 'sqlt_size' => 100 }
-            => 'root'],
-        [ { dbic_colname => '__gbind' }
-            => 1 ],
-        [ { dbic_colname => 'cnt' }
-            => 2 ],
-      ],
-    );
-
     is_deeply (
       [ $rs->get_column ('cnt')->all ],
       [4, 4],
@@ -437,19 +269,6 @@ do_creates($dbh);
       connect_by_nocycle => { parentid => { -prior => { -ident => 'artistid' } } },
     });
 
-    is_same_sql_bind (
-      $rs->as_query,
-      '(
-        SELECT me.artistid, me.name, me.rank, me.charfield, me.parentid, CONNECT_BY_ISCYCLE
-          FROM artist me
-        START WITH name = ?
-        CONNECT BY NOCYCLE parentid = PRIOR artistid
-      )',
-      [
-        [ { 'sqlt_datatype' => 'varchar', 'dbic_colname' => 'name', 'sqlt_size' => 100 }
-            => 'cycle-root'],
-      ],
-    );
     is_deeply (
       [ $rs->get_column ('name')->all ],
       [ qw/cycle-root cycle-child1 cycle-grandchild cycle-child2/ ],
@@ -461,20 +280,6 @@ do_creates($dbh);
       'got artist tree with nocycle (CONNECT_BY_ISCYCLE)',
     );
 
-    is_same_sql_bind (
-      $rs->count_rs->as_query,
-      '(
-        SELECT COUNT( * )
-          FROM artist me
-        START WITH name = ?
-        CONNECT BY NOCYCLE parentid = PRIOR artistid
-      )',
-      [
-        [ { 'sqlt_datatype' => 'varchar', 'dbic_colname' => 'name', 'sqlt_size' => 100 }
-            => 'cycle-root'],
-      ],
-    );
-
     is( $rs->count, 4, 'Connect By Nocycle count ok' );
   }
 }
index 57c44fb..2cc0281 100644 (file)
@@ -11,11 +11,6 @@ plan skip_all => 'Test needs ' . DBIx::Class::Optional::Dependencies->req_missin
 
 use lib qw(t/lib);
 use DBICTest;
-use DBIC::SqlMakerTest;
-use DBIx::Class::SQLMaker::LimitDialects;
-
-my $OFFSET = DBIx::Class::SQLMaker::LimitDialects->__offset_bindtype;
-my $TOTAL  = DBIx::Class::SQLMaker::LimitDialects->__total_bindtype;
 
 my ($dsn, $user, $pass) = @ENV{map { "DBICTEST_MSSQL_ODBC_${_}" } qw/DSN USER PASS/};
 
@@ -373,77 +368,6 @@ SQL
           },
         );
 
-        is_same_sql_bind (
-          $owners->page(3)->as_query,
-          $dialect eq 'Top'
-            ? '(
-              SELECT TOP 2147483647 [me].[id], [me].[name],
-                                    [books].[id], [books].[source], [books].[owner], [books].[title], [books].[price]
-                FROM (
-                  SELECT TOP 2147483647 [me].[id], [me].[name]
-                    FROM (
-                      SELECT TOP 3 [me].[id], [me].[name], [ORDER__BY__001]
-                        FROM (
-                          SELECT TOP 9 [me].[id], [me].[name], name + ? AS [ORDER__BY__001]
-                            FROM [owners] [me]
-                            LEFT JOIN [books] [books]
-                              ON [books].[owner] = [me].[id]
-                          WHERE [books].[id] IS NOT NULL AND [me].[name] != ?
-                          GROUP BY [me].[id], [me].[name]
-                          ORDER BY name + ? ASC, [me].[id]
-                        ) [me]
-                      ORDER BY [ORDER__BY__001] DESC, [me].[id] DESC
-                    ) [me]
-                  ORDER BY [ORDER__BY__001] ASC, [me].[id]
-                ) [me]
-                LEFT JOIN [books] [books]
-                  ON [books].[owner] = [me].[id]
-              WHERE [books].[id] IS NOT NULL AND [me].[name] != ?
-              ORDER BY name + ? ASC, [me].[id]
-            )'
-            : '(
-              SELECT TOP 2147483647 [me].[id], [me].[name],
-                                    [books].[id], [books].[source], [books].[owner], [books].[title], [books].[price]
-                FROM (
-                  SELECT TOP 2147483647 [me].[id], [me].[name]
-                    FROM (
-                      SELECT [me].[id], [me].[name],
-                             ROW_NUMBER() OVER( ORDER BY [ORDER__BY__001] ASC, [me].[id] ) AS [rno__row__index]
-                        FROM (
-                          SELECT [me].[id], [me].[name], name + ? AS [ORDER__BY__001]
-                            FROM [owners] [me]
-                            LEFT JOIN [books] [books]
-                              ON [books].[owner] = [me].[id]
-                          WHERE [books].[id] IS NOT NULL AND [me].[name] != ?
-                          GROUP BY [me].[id], [me].[name]
-                        ) [me]
-                    ) [me]
-                  WHERE [rno__row__index] >= ? AND [rno__row__index] <= ?
-                ) [me]
-                LEFT JOIN [books] [books]
-                  ON [books].[owner] = [me].[id]
-              WHERE [books].[id] IS NOT NULL AND [me].[name] != ?
-              ORDER BY name + ? ASC, [me].[id]
-            )'
-          ,
-          [
-            [ { dbic_colname => 'test' }
-              => 'xxx' ],
-            [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'me.name' }
-              => 'somebogusstring' ],
-
-            ($dialect eq 'Top'
-              ? [ { dbic_colname => 'test' } => 'xxx' ]  # the extra re-order bind
-              : ([ $OFFSET => 7 ], [ $TOTAL => 9 ]) # parameterised RNO
-            ),
-
-            [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'me.name' }
-              => 'somebogusstring' ],
-            [ { dbic_colname => 'test' }
-              => 'xxx' ],
-          ],
-        ) if $quoted;
-
         is ($owners->page(1)->all, 3, "$test_type: has_many prefetch returns correct number of rows");
         is ($owners->page(1)->count, 3, "$test_type: has-many prefetch returns correct count");
 
@@ -471,88 +395,6 @@ SQL
           },
         );
 
-        is_same_sql_bind (
-          $books->page(3)->as_query,
-          $dialect eq 'Top'
-            ? '(
-              SELECT TOP 2147483647 [me].[id], [me].[source], [me].[owner], [me].[title], [me].[price],
-                                    [owner].[id], [owner].[name]
-                FROM (
-                  SELECT TOP 2147483647 [me].[id], [me].[source], [me].[owner], [me].[title], [me].[price]
-                    FROM (
-                      SELECT TOP 2 [me].[id], [me].[source], [me].[owner], [me].[title], [me].[price]
-                        FROM (
-                          SELECT TOP 6 [me].[id], [me].[source], [me].[owner], [me].[title], [me].[price]
-                            FROM [books] [me]
-                            JOIN [owners] [owner]
-                              ON [owner].[id] = [me].[owner]
-                          WHERE ( [owner].[name] = ? OR [owner].[name] = ? ) AND [source] = ?
-                          GROUP BY [me].[id], [me].[source], [me].[owner], [me].[title], [me].[price]
-                          HAVING 1 = ?
-                          ORDER BY [me].[owner] DESC, [me].[id]
-                        ) [me]
-                      ORDER BY [me].[owner] ASC, [me].[id] DESC
-                    ) [me]
-                  ORDER BY [me].[owner] DESC, [me].[id]
-                ) [me]
-                JOIN [owners] [owner]
-                  ON [owner].[id] = [me].[owner]
-              WHERE ( [owner].[name] = ? OR [owner].[name] = ? ) AND [source] = ?
-              ORDER BY [me].[owner] DESC, [me].[id]
-            )'
-            : '(
-              SELECT TOP 2147483647 [me].[id], [me].[source], [me].[owner], [me].[title], [me].[price],
-                                    [owner].[id], [owner].[name]
-                FROM (
-                  SELECT TOP 2147483647 [me].[id], [me].[source], [me].[owner], [me].[title], [me].[price]
-                    FROM (
-                      SELECT [me].[id], [me].[source], [me].[owner], [me].[title], [me].[price],
-                             ROW_NUMBER() OVER( ORDER BY [me].[owner] DESC, [me].[id] ) AS [rno__row__index]
-                        FROM (
-                          SELECT [me].[id], [me].[source], [me].[owner], [me].[title], [me].[price]
-                            FROM [books] [me]
-                            JOIN [owners] [owner]
-                              ON [owner].[id] = [me].[owner]
-                          WHERE ( [owner].[name] = ? OR [owner].[name] = ? ) AND [source] = ?
-                          GROUP BY [me].[id], [me].[source], [me].[owner], [me].[title], [me].[price]
-                          HAVING 1 = ?
-                        ) [me]
-                    ) [me]
-                  WHERE [rno__row__index] >= ? AND [rno__row__index] <= ?
-                ) [me]
-                JOIN [owners] [owner]
-                  ON [owner].[id] = [me].[owner]
-              WHERE ( [owner].[name] = ? OR [owner].[name] = ? ) AND [source] = ?
-              ORDER BY [me].[owner] DESC, [me].[id]
-            )'
-          ,
-          [
-            # inner
-            [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'owner.name' }
-              => 'wiggle' ],
-            [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'owner.name' }
-              => 'woggle' ],
-            [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'source' }
-              => 'Library' ],
-            [ { dbic_colname => 'test' }
-              => '1' ],
-
-            # top(?)
-            $dialect eq 'Top'
-              ? ()
-              : ( [ $OFFSET => 5 ], [ $TOTAL => 6 ] )
-            ,
-
-            # outer
-            [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'owner.name' }
-              => 'wiggle' ],
-            [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'owner.name' }
-              => 'woggle' ],
-            [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'source' }
-              => 'Library' ],
-          ],
-        ) if $quoted;
-
         is ($books->page(1)->all, 2, "$test_type: Prefetched grouped search returns correct number of rows");
         is ($books->page(1)->count, 2, "$test_type: Prefetched grouped search returns correct count");
 
index 48ff756..8d8aa7e 100644 (file)
@@ -164,6 +164,8 @@ EOF
 
   s/^'//, s/'\z// for @bind;
 
+  # test is duplicated in t/sqlmaker/msaccess.t, keep a duplicate here anyway, just to be safe
+  # -- ribasushi
   is_same_sql_bind(
     $sql,
     \@bind,
@@ -195,6 +197,8 @@ EOF
 
   s/^'//, s/'\z// for @bind;
 
+  # test is duplicated in t/sqlmaker/msaccess.t, keep a duplicate here anyway, just to be safe
+  # -- ribasushi
   is_same_sql_bind(
     $sql,
     \@bind,
diff --git a/t/sqlmaker/hierarchical/oracle.t b/t/sqlmaker/hierarchical/oracle.t
new file mode 100644 (file)
index 0000000..1283140
--- /dev/null
@@ -0,0 +1,314 @@
+use strict;
+use warnings;
+
+use Test::More;
+use lib qw(t/lib);
+
+use DBIx::Class::Optional::Dependencies;
+plan skip_all => 'Test needs ' . DBIx::Class::Optional::Dependencies->req_missing_for ('id_shortener')
+  unless DBIx::Class::Optional::Dependencies->req_ok_for ('id_shortener');
+
+use DBICTest::Schema::Artist;
+BEGIN {
+  DBICTest::Schema::Artist->add_column('parentid');
+
+  DBICTest::Schema::Artist->has_many(
+    children => 'DBICTest::Schema::Artist',
+    { 'foreign.parentid' => 'self.artistid' }
+  );
+
+  DBICTest::Schema::Artist->belongs_to(
+    parent => 'DBICTest::Schema::Artist',
+    { 'foreign.artistid' => 'self.parentid' }
+  );
+}
+
+use DBICTest;
+use DBICTest::Schema;
+use DBIC::SqlMakerTest;
+
+use DBIx::Class::SQLMaker::LimitDialects;
+my $ROWS = DBIx::Class::SQLMaker::LimitDialects->__rows_bindtype;
+my $TOTAL = DBIx::Class::SQLMaker::LimitDialects->__total_bindtype;
+
+for my $q ( '', '"' ) {
+
+  my $schema = DBICTest->init_schema(
+    storage_type => 'DBIx::Class::Storage::DBI::Oracle::Generic',
+    no_deploy => 1,
+    quote_char => $q,
+  );
+
+  # select the whole tree
+  {
+    my $rs = $schema->resultset('Artist')->search({}, {
+      start_with => { name => 'root' },
+      connect_by => { parentid => { -prior => { -ident => 'artistid' } } },
+    });
+
+    is_same_sql_bind (
+      $rs->as_query,
+      "(
+        SELECT ${q}me${q}.${q}artistid${q}, ${q}me${q}.${q}name${q}, ${q}me${q}.${q}rank${q}, ${q}me${q}.${q}charfield${q}, ${q}me${q}.${q}parentid${q}
+          FROM ${q}artist${q} ${q}me${q}
+        START WITH ${q}name${q} = ?
+        CONNECT BY ${q}parentid${q} = PRIOR ${q}artistid${q}
+      )",
+      [ [ { 'sqlt_datatype' => 'varchar', 'dbic_colname' => 'name', 'sqlt_size' => 100 }
+            => 'root'] ],
+    );
+
+    is_same_sql_bind (
+      $rs->count_rs->as_query,
+      "(
+        SELECT COUNT( * )
+          FROM ${q}artist${q} ${q}me${q}
+        START WITH ${q}name${q} = ?
+        CONNECT BY ${q}parentid${q} = PRIOR ${q}artistid${q}
+      )",
+      [ [ { 'sqlt_datatype' => 'varchar', 'dbic_colname' => 'name', 'sqlt_size' => 100 }
+            => 'root'] ],
+    );
+  }
+
+  # use order siblings by statement
+  {
+    my $rs = $schema->resultset('Artist')->search({}, {
+      start_with => { name => 'root' },
+      connect_by => { parentid => { -prior => { -ident =>  'artistid' } } },
+      order_siblings_by => { -desc => 'name' },
+    });
+
+    is_same_sql_bind (
+      $rs->as_query,
+      "(
+        SELECT ${q}me${q}.${q}artistid${q}, ${q}me${q}.${q}name${q}, ${q}me${q}.${q}rank${q}, ${q}me${q}.${q}charfield${q}, ${q}me${q}.${q}parentid${q}
+          FROM ${q}artist${q} ${q}me${q}
+        START WITH ${q}name${q} = ?
+        CONNECT BY ${q}parentid${q} = PRIOR ${q}artistid${q}
+        ORDER SIBLINGS BY ${q}name${q} DESC
+      )",
+      [ [ { 'sqlt_datatype' => 'varchar', 'dbic_colname' => 'name', 'sqlt_size' => 100 }
+            => 'root'] ],
+    );
+  }
+
+  # get the root node
+  {
+    my $rs = $schema->resultset('Artist')->search({ parentid => undef }, {
+      start_with => { name => 'root' },
+      connect_by => { parentid => { -prior => { -ident => 'artistid' } } },
+    });
+
+    is_same_sql_bind (
+      $rs->as_query,
+      "(
+        SELECT ${q}me${q}.${q}artistid${q}, ${q}me${q}.${q}name${q}, ${q}me${q}.${q}rank${q}, ${q}me${q}.${q}charfield${q}, ${q}me${q}.${q}parentid${q}
+          FROM ${q}artist${q} ${q}me${q}
+        WHERE ( ${q}parentid${q} IS NULL )
+        START WITH ${q}name${q} = ?
+        CONNECT BY ${q}parentid${q} = PRIOR ${q}artistid${q}
+      )",
+      [ [ { 'sqlt_datatype' => 'varchar', 'dbic_colname' => 'name', 'sqlt_size' => 100 }
+            => 'root'] ],
+    );
+  }
+
+  # combine a connect by with a join
+  {
+    my $rs = $schema->resultset('Artist')->search(
+      {'cds.title' => { -like => '%cd'} },
+      {
+        join => 'cds',
+        start_with => { 'me.name' => 'root' },
+        connect_by => { parentid => { -prior => { -ident => 'artistid' } } },
+      }
+    );
+
+    is_same_sql_bind (
+      $rs->as_query,
+      "(
+        SELECT ${q}me${q}.${q}artistid${q}, ${q}me${q}.${q}name${q}, ${q}me${q}.${q}rank${q}, ${q}me${q}.${q}charfield${q}, ${q}me${q}.${q}parentid${q}
+          FROM ${q}artist${q} ${q}me${q}
+          LEFT JOIN cd ${q}cds${q} ON ${q}cds${q}.${q}artist${q} = ${q}me${q}.${q}artistid${q}
+        WHERE ( ${q}cds${q}.${q}title${q} LIKE ? )
+        START WITH ${q}me${q}.${q}name${q} = ?
+        CONNECT BY ${q}parentid${q} = PRIOR ${q}artistid${q}
+      )",
+      [
+        [ { 'sqlt_datatype' => 'varchar', 'dbic_colname' => 'cds.title', 'sqlt_size' => 100 }
+            => '%cd'],
+        [ { 'sqlt_datatype' => 'varchar', 'dbic_colname' => 'me.name', 'sqlt_size' => 100 }
+            => 'root'],
+      ],
+    );
+
+    is_same_sql_bind (
+      $rs->count_rs->as_query,
+      "(
+        SELECT COUNT( * )
+          FROM ${q}artist${q} ${q}me${q}
+          LEFT JOIN cd ${q}cds${q} ON ${q}cds${q}.${q}artist${q} = ${q}me${q}.${q}artistid${q}
+        WHERE ( ${q}cds${q}.${q}title${q} LIKE ? )
+        START WITH ${q}me${q}.${q}name${q} = ?
+        CONNECT BY ${q}parentid${q} = PRIOR ${q}artistid${q}
+      )",
+      [
+        [ { 'sqlt_datatype' => 'varchar', 'dbic_colname' => 'cds.title', 'sqlt_size' => 100 }
+            => '%cd'],
+        [ { 'sqlt_datatype' => 'varchar', 'dbic_colname' => 'me.name', 'sqlt_size' => 100 }
+              => 'root'],
+      ],
+    );
+  }
+
+  # combine a connect by with order_by
+  {
+    my $rs = $schema->resultset('Artist')->search({}, {
+      start_with => { name => 'root' },
+      connect_by => { parentid => { -prior => { -ident => 'artistid' } } },
+      order_by => { -asc => [ 'LEVEL', 'name' ] },
+    });
+
+    is_same_sql_bind (
+      $rs->as_query,
+      "(
+        SELECT ${q}me${q}.${q}artistid${q}, ${q}me${q}.${q}name${q}, ${q}me${q}.${q}rank${q}, ${q}me${q}.${q}charfield${q}, ${q}me${q}.${q}parentid${q}
+          FROM ${q}artist${q} ${q}me${q}
+        START WITH ${q}name${q} = ?
+        CONNECT BY ${q}parentid${q} = PRIOR ${q}artistid${q}
+        ORDER BY ${q}LEVEL${q} ASC, ${q}name${q} ASC
+      )",
+      [
+        [ { 'sqlt_datatype' => 'varchar', 'dbic_colname' => 'name', 'sqlt_size' => 100 }
+            => 'root'],
+      ],
+    );
+  }
+
+  # limit a connect by
+  {
+    my $rs = $schema->resultset('Artist')->search({}, {
+      start_with => { name => 'root' },
+      connect_by => { parentid => { -prior => { -ident => 'artistid' } } },
+      order_by => [ { -asc => 'name' }, {  -desc => 'artistid' } ],
+      rows => 2,
+    });
+
+    is_same_sql_bind (
+      $rs->as_query,
+      "(
+        SELECT ${q}me${q}.${q}artistid${q}, ${q}me${q}.${q}name${q}, ${q}me${q}.${q}rank${q}, ${q}me${q}.${q}charfield${q}, ${q}me${q}.${q}parentid${q}
+          FROM (
+            SELECT ${q}me${q}.${q}artistid${q}, ${q}me${q}.${q}name${q}, ${q}me${q}.${q}rank${q}, ${q}me${q}.${q}charfield${q}, ${q}me${q}.${q}parentid${q}
+              FROM ${q}artist${q} ${q}me${q}
+            START WITH ${q}name${q} = ?
+            CONNECT BY ${q}parentid${q} = PRIOR ${q}artistid${q}
+            ORDER BY ${q}name${q} ASC, ${q}artistid${q} DESC
+          ) ${q}me${q}
+        WHERE ROWNUM <= ?
+      )",
+      [
+        [ { 'sqlt_datatype' => 'varchar', 'dbic_colname' => 'name', 'sqlt_size' => 100 }
+            => 'root'], [ $ROWS => 2 ],
+      ],
+    );
+
+    is_same_sql_bind (
+      $rs->count_rs->as_query,
+      "(
+        SELECT COUNT( * )
+          FROM (
+            SELECT ${q}me${q}.${q}artistid${q}
+              FROM (
+                SELECT ${q}me${q}.${q}artistid${q}
+                  FROM ${q}artist${q} ${q}me${q}
+                START WITH ${q}name${q} = ?
+                CONNECT BY ${q}parentid${q} = PRIOR ${q}artistid${q}
+              ) ${q}me${q}
+            WHERE ROWNUM <= ?
+          ) ${q}me${q}
+      )",
+      [
+        [ { 'sqlt_datatype' => 'varchar', 'dbic_colname' => 'name', 'sqlt_size' => 100 }
+            => 'root'],
+        [ $ROWS => 2 ],
+      ],
+    );
+  }
+
+  # combine a connect_by with group_by and having
+  # add some bindvals to make sure things still work
+  {
+    my $rs = $schema->resultset('Artist')->search({}, {
+      select => \[ 'COUNT(rank) + ?', [ __cbind => 3 ] ],
+      as => 'cnt',
+      start_with => { name => 'root' },
+      connect_by => { parentid => { -prior => { -ident => 'artistid' } } },
+      group_by => \[ 'rank + ? ', [ __gbind =>  1] ],
+      having => \[ 'count(rank) < ?', [ cnt => 2 ] ],
+    });
+
+    is_same_sql_bind (
+      $rs->as_query,
+      "(
+        SELECT COUNT(rank) + ?
+          FROM ${q}artist${q} ${q}me${q}
+        START WITH ${q}name${q} = ?
+        CONNECT BY ${q}parentid${q} = PRIOR ${q}artistid${q}
+        GROUP BY( rank + ? )
+        HAVING count(rank) < ?
+      )",
+      [
+        [ { dbic_colname => '__cbind' }
+            => 3 ],
+        [ { 'sqlt_datatype' => 'varchar', 'dbic_colname' => 'name', 'sqlt_size' => 100 }
+            => 'root'],
+        [ { dbic_colname => '__gbind' }
+            => 1 ],
+        [ { dbic_colname => 'cnt' }
+            => 2 ],
+      ],
+    );
+  }
+
+  # select the whole cycle tree with nocylce
+  {
+    my $rs = $schema->resultset('Artist')->search({}, {
+      start_with => { name => 'cycle-root' },
+      '+select'  => \ 'CONNECT_BY_ISCYCLE',
+      '+as'      => [ 'connector' ],
+      connect_by_nocycle => { parentid => { -prior => { -ident => 'artistid' } } },
+    });
+
+    is_same_sql_bind (
+      $rs->as_query,
+      "(
+        SELECT ${q}me${q}.${q}artistid${q}, ${q}me${q}.${q}name${q}, ${q}me${q}.${q}rank${q}, ${q}me${q}.${q}charfield${q}, ${q}me${q}.${q}parentid${q}, CONNECT_BY_ISCYCLE
+          FROM ${q}artist${q} ${q}me${q}
+        START WITH ${q}name${q} = ?
+        CONNECT BY NOCYCLE ${q}parentid${q} = PRIOR ${q}artistid${q}
+      )",
+      [
+        [ { 'sqlt_datatype' => 'varchar', 'dbic_colname' => 'name', 'sqlt_size' => 100 }
+            => 'cycle-root'],
+      ],
+    );
+
+    is_same_sql_bind (
+      $rs->count_rs->as_query,
+      "(
+        SELECT COUNT( * )
+          FROM ${q}artist${q} ${q}me${q}
+        START WITH ${q}name${q} = ?
+        CONNECT BY NOCYCLE ${q}parentid${q} = PRIOR ${q}artistid${q}
+      )",
+      [
+        [ { 'sqlt_datatype' => 'varchar', 'dbic_colname' => 'name', 'sqlt_size' => 100 }
+            => 'cycle-root'],
+      ],
+    );
+  }
+}
+
+done_testing;
diff --git a/t/sqlmaker/limit_dialects/mssql_torture.t b/t/sqlmaker/limit_dialects/mssql_torture.t
new file mode 100644 (file)
index 0000000..7806dfb
--- /dev/null
@@ -0,0 +1,259 @@
+use strict;
+use warnings;
+use Test::More;
+use lib qw(t/lib);
+use DBICTest;
+use DBIC::SqlMakerTest;
+use DBIx::Class::SQLMaker::LimitDialects;
+my $OFFSET = DBIx::Class::SQLMaker::LimitDialects->__offset_bindtype;
+my $TOTAL  = DBIx::Class::SQLMaker::LimitDialects->__total_bindtype;
+
+my $schema = DBICTest->init_schema (
+  storage_type => 'DBIx::Class::Storage::DBI::MSSQL',
+  no_deploy => 1,
+  quote_names => 1
+);
+# prime caches
+$schema->storage->sql_maker;
+
+# more involved limit dialect torture testcase migrated from the
+# live mssql tests
+my $tests = {
+  pref_hm_and_page_and_group_rs => {
+
+    rs => scalar $schema->resultset ('Owners')->search (
+      {
+        'books.id' => { '!=', undef },
+        'me.name' => { '!=', 'somebogusstring' },
+      },
+      {
+        prefetch => 'books',
+        order_by => [ { -asc => \['name + ?', [ test => 'xxx' ]] }, 'me.id' ], # test bindvar propagation
+        group_by => [ map { "me.$_" } $schema->source('Owners')->columns ], # the literal order_by requires an explicit group_by
+        rows     => 3,
+        unsafe_subselect_ok => 1,
+      },
+    )->page(3),
+
+    result => {
+      Top => [
+        '(
+          SELECT TOP 2147483647 [me].[id], [me].[name],
+                                [books].[id], [books].[source], [books].[owner], [books].[title], [books].[price]
+            FROM (
+              SELECT TOP 2147483647 [me].[id], [me].[name]
+                FROM (
+                  SELECT TOP 3 [me].[id], [me].[name], [ORDER__BY__001]
+                    FROM (
+                      SELECT TOP 9 [me].[id], [me].[name], name + ? AS [ORDER__BY__001]
+                        FROM [owners] [me]
+                        LEFT JOIN [books] [books]
+                          ON [books].[owner] = [me].[id]
+                      WHERE [books].[id] IS NOT NULL AND [me].[name] != ?
+                      GROUP BY [me].[id], [me].[name]
+                      ORDER BY name + ? ASC, [me].[id]
+                    ) [me]
+                  ORDER BY [ORDER__BY__001] DESC, [me].[id] DESC
+                ) [me]
+              ORDER BY [ORDER__BY__001] ASC, [me].[id]
+            ) [me]
+            LEFT JOIN [books] [books]
+              ON [books].[owner] = [me].[id]
+          WHERE [books].[id] IS NOT NULL AND [me].[name] != ?
+          ORDER BY name + ? ASC, [me].[id]
+        )',
+        [
+          [ { dbic_colname => 'test' }
+            => 'xxx' ],
+
+          [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'me.name' }
+            => 'somebogusstring' ],
+
+          [ { dbic_colname => 'test' } => 'xxx' ],  # the extra re-order bind
+
+          [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'me.name' }
+            => 'somebogusstring' ],
+
+          [ { dbic_colname => 'test' }
+            => 'xxx' ],
+        ],
+      ],
+
+      RowNumberOver => [
+        '(
+          SELECT TOP 2147483647 [me].[id], [me].[name],
+                                [books].[id], [books].[source], [books].[owner], [books].[title], [books].[price]
+            FROM (
+              SELECT TOP 2147483647 [me].[id], [me].[name]
+                FROM (
+                  SELECT [me].[id], [me].[name],
+                         ROW_NUMBER() OVER( ORDER BY [ORDER__BY__001] ASC, [me].[id] ) AS [rno__row__index]
+                    FROM (
+                      SELECT [me].[id], [me].[name], name + ? AS [ORDER__BY__001]
+                        FROM [owners] [me]
+                        LEFT JOIN [books] [books]
+                          ON [books].[owner] = [me].[id]
+                      WHERE [books].[id] IS NOT NULL AND [me].[name] != ?
+                      GROUP BY [me].[id], [me].[name]
+                    ) [me]
+                ) [me]
+              WHERE [rno__row__index] >= ? AND [rno__row__index] <= ?
+            ) [me]
+            LEFT JOIN [books] [books]
+              ON [books].[owner] = [me].[id]
+          WHERE [books].[id] IS NOT NULL AND [me].[name] != ?
+          ORDER BY name + ? ASC, [me].[id]
+        )',
+        [
+          [ { dbic_colname => 'test' }
+            => 'xxx' ],
+
+          [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'me.name' }
+            => 'somebogusstring' ],
+
+          [ $OFFSET => 7 ], # parameterised RNO
+
+          [ $TOTAL => 9 ],
+
+          [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'me.name' }
+            => 'somebogusstring' ],
+
+          [ { dbic_colname => 'test' }
+            => 'xxx' ],
+        ],
+      ],
+    }
+  },
+
+  pref_bt_and_page_and_group_rs => {
+
+    rs => scalar $schema->resultset ('BooksInLibrary')->search (
+      {
+        'owner.name' => [qw/wiggle woggle/],
+      },
+      {
+        distinct => 1,
+        having => \['1 = ?', [ test => 1 ] ], #test having propagation
+        prefetch => 'owner',
+        rows     => 2,  # 3 results total
+        order_by => [{ -desc => 'me.owner' }, 'me.id'],
+        unsafe_subselect_ok => 1,
+      },
+    )->page(3),
+
+    result => {
+      Top => [
+        '(
+          SELECT TOP 2147483647 [me].[id], [me].[source], [me].[owner], [me].[title], [me].[price],
+                                [owner].[id], [owner].[name]
+            FROM (
+              SELECT TOP 2147483647 [me].[id], [me].[source], [me].[owner], [me].[title], [me].[price]
+                FROM (
+                  SELECT TOP 2 [me].[id], [me].[source], [me].[owner], [me].[title], [me].[price]
+                    FROM (
+                      SELECT TOP 6 [me].[id], [me].[source], [me].[owner], [me].[title], [me].[price]
+                        FROM [books] [me]
+                        JOIN [owners] [owner]
+                          ON [owner].[id] = [me].[owner]
+                      WHERE ( [owner].[name] = ? OR [owner].[name] = ? ) AND [source] = ?
+                      GROUP BY [me].[id], [me].[source], [me].[owner], [me].[title], [me].[price]
+                      HAVING 1 = ?
+                      ORDER BY [me].[owner] DESC, [me].[id]
+                    ) [me]
+                  ORDER BY [me].[owner] ASC, [me].[id] DESC
+                ) [me]
+              ORDER BY [me].[owner] DESC, [me].[id]
+            ) [me]
+            JOIN [owners] [owner]
+              ON [owner].[id] = [me].[owner]
+          WHERE ( [owner].[name] = ? OR [owner].[name] = ? ) AND [source] = ?
+          ORDER BY [me].[owner] DESC, [me].[id]
+        )',
+        [
+          # inner
+          [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'owner.name' }
+            => 'wiggle' ],
+          [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'owner.name' }
+            => 'woggle' ],
+          [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'source' }
+            => 'Library' ],
+          [ { dbic_colname => 'test' }
+            => '1' ],
+
+          # outer
+          [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'owner.name' }
+            => 'wiggle' ],
+          [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'owner.name' }
+            => 'woggle' ],
+          [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'source' }
+            => 'Library' ],
+        ],
+      ],
+      RowNumberOver => [
+        '(
+          SELECT TOP 2147483647 [me].[id], [me].[source], [me].[owner], [me].[title], [me].[price],
+                                [owner].[id], [owner].[name]
+            FROM (
+              SELECT TOP 2147483647 [me].[id], [me].[source], [me].[owner], [me].[title], [me].[price]
+                FROM (
+                  SELECT [me].[id], [me].[source], [me].[owner], [me].[title], [me].[price],
+                         ROW_NUMBER() OVER( ORDER BY [me].[owner] DESC, [me].[id] ) AS [rno__row__index]
+                    FROM (
+                      SELECT [me].[id], [me].[source], [me].[owner], [me].[title], [me].[price]
+                        FROM [books] [me]
+                        JOIN [owners] [owner]
+                          ON [owner].[id] = [me].[owner]
+                      WHERE ( [owner].[name] = ? OR [owner].[name] = ? ) AND [source] = ?
+                      GROUP BY [me].[id], [me].[source], [me].[owner], [me].[title], [me].[price]
+                      HAVING 1 = ?
+                    ) [me]
+                ) [me]
+              WHERE [rno__row__index] >= ? AND [rno__row__index] <= ?
+            ) [me]
+            JOIN [owners] [owner]
+              ON [owner].[id] = [me].[owner]
+          WHERE ( [owner].[name] = ? OR [owner].[name] = ? ) AND [source] = ?
+          ORDER BY [me].[owner] DESC, [me].[id]
+        )',
+        [
+          # inner
+          [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'owner.name' }
+            => 'wiggle' ],
+          [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'owner.name' }
+            => 'woggle' ],
+          [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'source' }
+            => 'Library' ],
+          [ { dbic_colname => 'test' }
+            => '1' ],
+
+          [ $OFFSET => 5 ],
+          [ $TOTAL => 6 ],
+
+          # outer
+          [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'owner.name' }
+            => 'wiggle' ],
+          [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'owner.name' }
+            => 'woggle' ],
+          [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'source' }
+            => 'Library' ],
+        ],
+      ],
+    },
+  },
+};
+
+for my $tname (keys %$tests) {
+  for my $limtype (keys %{$tests->{$tname}{result}} ) {
+
+    delete $schema->storage->_sql_maker->{_cached_syntax};
+    $schema->storage->_sql_maker->limit_dialect ($limtype);
+
+    is_same_sql_bind(
+      $tests->{$tname}{rs}->as_query,
+      @{ $tests->{$tname}{result}{$limtype} },
+      "Correct SQL for $limtype on $tname",
+    );
+  }
+}
+
+done_testing;
index 6d76f82..2805d03 100644 (file)
@@ -5,9 +5,81 @@ use lib qw(t/lib);
 use DBICTest;
 use DBIC::SqlMakerTest;
 
-use DBIx::Class::SQLMaker::ACCESS ();
+# the entire point of the subclass is that parenthesis have to be
+# just right for ACCESS to be happy
+# globalize for entirety of the test
+$SQL::Abstract::Test::parenthesis_significant = 1;
 
-my $sa = DBIx::Class::SQLMaker::ACCESS->new;
+my $schema = DBICTest->init_schema (storage_type => 'DBIx::Class::Storage::DBI::ACCESS', no_deploy => 1, quote_names => 1);
+
+is_same_sql_bind(
+  $schema->resultset('Artist')->search(
+    {
+      artistid => 1,
+    },
+    {
+      join => [{ cds => 'tracks' }],
+      '+select' => [ 'tracks.title' ],
+      '+as'     => [ 'track_title'  ],
+    }
+  )->as_query,
+  '(
+    SELECT [me].[artistid], [me].[name], [me].[rank], [me].[charfield],
+           [tracks].[title]
+      FROM (
+        (
+          [artist] [me]
+          LEFT JOIN cd [cds]
+            ON [cds].[artist] = [me].[artistid]
+        )
+        LEFT JOIN [track] [tracks]
+          ON [tracks].[cd] = [cds].[cdid]
+      )
+    WHERE ( [artistid] = ? )
+  )',
+  [
+    [{ sqlt_datatype => 'integer', dbic_colname => 'artistid' }
+      => 1 ],
+  ],
+  'correct SQL for two-step left join'
+);
+
+is_same_sql_bind(
+  $schema->resultset('Track')->search(
+    {
+      trackid => 1,
+    },
+    {
+      join => [{ cd => 'artist' }],
+      '+select' => [ 'artist.name' ],
+      '+as'     => [ 'artist_name'  ],
+    }
+  )->as_query,
+  '(
+    SELECT [me].[trackid], [me].[cd], [me].[position], [me].[title], [me].[last_updated_on], [me].[last_updated_at],
+           [artist].[name]
+      FROM (
+        (
+          [track] [me]
+          INNER JOIN cd [cd]
+            ON [cd].[cdid] = [me].[cd]
+        )
+        INNER JOIN [artist] [artist]
+          ON [artist].[artistid] = [cd].[artist]
+      )
+    WHERE ( [trackid] = ? )
+  )',
+  [
+    [{ sqlt_datatype => 'integer', dbic_colname => 'trackid' }
+      => 1 ],
+  ],
+  'correct SQL for two-step inner join',
+);
+
+
+my $sa = $schema->storage->sql_maker;
+# the legacy tests assume no quoting - leave things as-is
+local $sa->{quote_char};
 
 #  my ($self, $table, $fields, $where, $order, @rest) = @_;
 my ($sql, @bind) = $sa->select(
index b00691f..2755a3d 100644 (file)
@@ -115,4 +115,27 @@ bless ( $schema->storage, 'DBIx::Class::Storage::DBI::mysql' );
   $schema->storage->debug ($orig_debug);
 }
 
+# Test support for straight joins
+{
+  my $cdsrc = $schema->source('CD');
+  my $artrel_info = $cdsrc->relationship_info ('artist');
+  $cdsrc->add_relationship(
+    'straight_artist',
+    $artrel_info->{class},
+    $artrel_info->{cond},
+    { %{$artrel_info->{attrs}}, join_type => 'straight' },
+  );
+  is_same_sql_bind (
+    $cdsrc->resultset->search({}, { prefetch => 'straight_artist' })->as_query,
+    '(
+      SELECT `me`.`cdid`, `me`.`artist`, `me`.`title`, `me`.`year`, `me`.`genreid`, `me`.`single_track`,
+             `straight_artist`.`artistid`, `straight_artist`.`name`, `straight_artist`.`rank`, `straight_artist`.`charfield`
+        FROM cd `me`
+        STRAIGHT_JOIN `artist` `straight_artist` ON `straight_artist`.`artistid` = `me`.`artist`
+    )',
+    [],
+    'straight joins correctly supported for mysql'
+  );
+}
+
 done_testing;