From: Rafael Kitover Date: Fri, 7 May 2010 09:57:24 +0000 (+0000) Subject: detect row_number() over support in MSSQL if version detection fails X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=a218ef4eb924a4db078cc00a525510a7b955c1eb;p=dbsrgits%2FDBIx-Class-Historic.git detect row_number() over support in MSSQL if version detection fails --- diff --git a/lib/DBIx/Class/Storage/DBI/MSSQL.pm b/lib/DBIx/Class/Storage/DBI/MSSQL.pm index 38c615b..dbba2fa 100644 --- a/lib/DBIx/Class/Storage/DBI/MSSQL.pm +++ b/lib/DBIx/Class/Storage/DBI/MSSQL.pm @@ -205,11 +205,23 @@ sub sql_maker { unless ($self->_sql_maker) { unless ($self->{_sql_maker_opts}{limit_dialect}) { + my $have_rno = 0; - my $version = $self->_server_info->{normalized_dbms_version} || 0; + if (exists $self->_server_info->{normalized_dbms_version}) { + $have_rno = 1 if $self->_server_info->{normalized_dbms_version} >= 9; + } + else { + # User is connecting via DBD::Sybase and has no permission to run + # stored procedures like xp_msver, or version detection failed for some + # other reason. + # So, we use a query to check if RNO is implemented. + $have_rno = 1 if (eval { local $@; ($self->_get_dbh + ->selectrow_array('SELECT row_number() OVER (ORDER BY rand())') + )[0] } || 0); + } $self->{_sql_maker_opts} = { - limit_dialect => ($version >= 9 ? 'RowNumberOver' : 'Top'), + limit_dialect => ($have_rno ? 'RowNumberOver' : 'Top'), %{$self->{_sql_maker_opts}||{}} }; } diff --git a/t/74mssql.t b/t/74mssql.t index a882e99..78e4691 100644 --- a/t/74mssql.t +++ b/t/74mssql.t @@ -172,6 +172,38 @@ SQL is $rs->first, undef, 'rolled back'; $rs->reset; + + # test RNO detection when version detection fails + SKIP: { + my $storage = $schema->storage; + my $version = $storage->_server_info->{normalized_dbms_version}; + + skip 1, 'could not detect SQL Server version' if not defined $version; + + my $have_rno = $version >= 9 ? 1 : 0; + + # Delete version information to force RNO check when rebuilding SQLA + # instance. + no strict 'refs'; + no warnings 'redefine'; + local *{(ref $storage).'::_get_server_version'} = sub { undef }; + + my $server_info = { %{ $storage->_server_info_hash } }; # clone + + delete @$server_info{qw/dbms_version normalized_dbms_version/}; + + local $storage->{_server_info_hash} = $server_info; + local $storage->{_sql_maker} = undef; + local $storage->{_sql_maker_opts} = undef; + + $storage->sql_maker; + + my $rno_detected = + ($storage->{_sql_maker_opts}{limit_dialect} eq 'RowNumberOver'); + + ok ((not ($have_rno xor $rno_detected)), + 'row_number() over support detected correctly'); + } } # test op-induced autoconnect