X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=t%2Fsqlmaker%2Flimit_dialects%2Fmssql_torture.t;fp=t%2Fsqlmaker%2Flimit_dialects%2Fmssql_torture.t;h=7806dfbc3f3108d913d0f715e8ae176da6aee659;hb=ac0c08254241f41a5cb1b586fc1b24ce2d33b79b;hp=0000000000000000000000000000000000000000;hpb=6b3e39473d9f38d9f5c97b6a162a95d99163c656;p=dbsrgits%2FDBIx-Class.git diff --git a/t/sqlmaker/limit_dialects/mssql_torture.t b/t/sqlmaker/limit_dialects/mssql_torture.t new file mode 100644 index 0000000..7806dfb --- /dev/null +++ b/t/sqlmaker/limit_dialects/mssql_torture.t @@ -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;