Convert many live-only SQL test to standalone is_same_sql_bind cases
[dbsrgits/DBIx-Class.git] / t / sqlmaker / limit_dialects / mssql_torture.t
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;