Merge 'mssql_top_fixes' into 'trunk'
Peter Rabbitson [Fri, 3 Jul 2009 18:20:42 +0000 (18:20 +0000)]
r6554@Thesaurus (orig r6553):  frew | 2009-06-09 00:06:42 +0200
branch for mssql top issues
r6572@Thesaurus (orig r6571):  frew | 2009-06-09 23:18:46 +0200
more tests for SQL Server!
r6573@Thesaurus (orig r6572):  frew | 2009-06-09 23:49:10 +0200
Added AmbiguousGlob.pm for silly servers like mssql and mysql.  See docs for more info
r6574@Thesaurus (orig r6573):  frew | 2009-06-09 23:55:22 +0200
fix plan
r6602@Thesaurus (orig r6601):  frew | 2009-06-10 17:03:30 +0200
more failing tests
r6608@Thesaurus (orig r6607):  frew | 2009-06-10 20:05:53 +0200
don't use eval!
r6610@Thesaurus (orig r6609):  frew | 2009-06-10 20:07:49 +0200
beginning of DWIM for IDENTITY_INSERT
r6628@Thesaurus (orig r6627):  frew | 2009-06-11 18:13:02 +0200
still busted :-(
r6631@Thesaurus (orig r6630):  frew | 2009-06-11 19:39:00 +0200
general function to go from column names and ident to result source
r6632@Thesaurus (orig r6631):  frew | 2009-06-11 19:40:11 +0200
Use new _resolve_column_sources method and begin insert_bulk method
r6635@Thesaurus (orig r6634):  frew | 2009-06-11 20:12:38 +0200
updated _resolve_column_source to _resolve_column_info as per ribasushi's suggestion
r6650@Thesaurus (orig r6649):  frew | 2009-06-12 17:13:32 +0200
Now I just need to check if the actual values are set...
r6651@Thesaurus (orig r6650):  frew | 2009-06-12 17:26:53 +0200
Insert Identity works!
r6652@Thesaurus (orig r6651):  frew | 2009-06-12 17:34:13 +0200
silly warns.
r6684@Thesaurus (orig r6683):  frew | 2009-06-15 16:49:00 +0200
failing test
r6686@Thesaurus (orig r6685):  ribasushi | 2009-06-15 18:10:26 +0200
make all resolved attrs visible to sqla
r6698@Thesaurus (orig r6697):  ribasushi | 2009-06-17 02:31:37 +0200
Half way working stuff, needs a LOT of tweaking still
r6729@Thesaurus (orig r6728):  ribasushi | 2009-06-19 19:49:27 +0200
Merge badness
r6730@Thesaurus (orig r6729):  ribasushi | 2009-06-19 19:49:40 +0200
fix eol
r6731@Thesaurus (orig r6730):  ribasushi | 2009-06-19 19:55:47 +0200
augment inheritance
r6735@Thesaurus (orig r6734):  ribasushi | 2009-06-20 10:34:42 +0200
Maybe I've nailed it
r6746@Thesaurus (orig r6745):  ribasushi | 2009-06-20 23:53:55 +0200
Test and merge fixes
r6747@Thesaurus (orig r6746):  ribasushi | 2009-06-21 00:01:09 +0200
Really fix tests
r6748@Thesaurus (orig r6747):  ribasushi | 2009-06-21 00:01:54 +0200
Really fix tests
r6749@Thesaurus (orig r6748):  ribasushi | 2009-06-21 00:18:33 +0200
Now really final
r6750@Thesaurus (orig r6749):  ribasushi | 2009-06-21 00:22:23 +0200
whoops
r6751@Thesaurus (orig r6750):  ribasushi | 2009-06-21 00:42:18 +0200
That should be all
r6752@Thesaurus (orig r6751):  ribasushi | 2009-06-21 08:54:00 +0200
Make sure quoting works
r6755@Thesaurus (orig r6754):  ribasushi | 2009-06-21 15:21:23 +0200
Groundwork for sanification of the toplimit test
r6863@Thesaurus (orig r6862):  ribasushi | 2009-06-30 01:13:49 +0200
Make sure storage classes use c3, just like the rest of dbic (tested on 5.8 as well)
r6869@Thesaurus (orig r6868):  ribasushi | 2009-06-30 09:53:27 +0200
Some fixes after review
r6874@Thesaurus (orig r6873):  ribasushi | 2009-06-30 11:54:34 +0200
Fix borked next invocation
r6896@Thesaurus (orig r6895):  frew | 2009-06-30 21:38:26 +0200
silly misspells and trailing whitespace
r6955@Thesaurus (orig r6954):  ribasushi | 2009-07-03 01:21:28 +0200
Some hack consolidation
r6962@Thesaurus (orig r6961):  ribasushi | 2009-07-03 12:06:57 +0200
Fix some mssql shortcommings when confronted with the new subequeried prefetch sql
r6963@Thesaurus (orig r6962):  ribasushi | 2009-07-03 12:47:57 +0200
Ask for newer DBD::Pg in author mode, suggest the newer version otherwise (proper array support). Make test more resilient as well
r6964@Thesaurus (orig r6963):  ribasushi | 2009-07-03 12:49:16 +0200
Switch to C3 mro throughout the ::Storage hierarchy (DBIx::Class brings in MRO::Compat, and all ::Storage's are based on it, tested on 5.8
r6969@Thesaurus (orig r6968):  ribasushi | 2009-07-03 19:54:04 +0200
Duh
r6970@Thesaurus (orig r6969):  frew | 2009-07-03 19:59:48 +0200
fix tests for new codez
r6971@Thesaurus (orig r6970):  ribasushi | 2009-07-03 20:18:53 +0200
detabify
r6972@Thesaurus (orig r6971):  ribasushi | 2009-07-03 20:20:07 +0200
changes

1  2 
Changes
lib/DBIx/Class/ResultSet.pm
lib/DBIx/Class/Storage/DBI/mysql.pm

diff --combined Changes
+++ b/Changes
@@@ -6,12 -6,6 +6,12 @@@ Revision history for DBIx::Clas
          - New resultsed method count_rs, returns a ::ResultSetColumn
            which in turn returns a single count value
          - Even better support of count with limit
 +        - New on_connect_call/on_disconnect_call functionality (check
 +          POD of Storage::DBI)
 +        - Automatic datetime handling environment/session setup for
 +          Oracle via connect_call_datetime_setup()
 +        - MySQL can now be turned into a sane database by adding
 +          { on_connect_call => 'set_ansi_mode' } to the connect() call
          - count/all on related left-joined empty resultsets now correctly
            returns 0/()
          - Fixed regression when both page and offset are specified on
@@@ -36,6 -30,7 +36,7 @@@
          - Storage::DBI::connected() improvements for Oracle and Sybase
          - Fixed prefetch+incomplete select regression introduced in
            0.08100
+         - MSSQL limit (TOP emulation) fixes and improvements
  
  0.08107 2009-06-14 08:21:00 (UTC)
          - Fix serialization regression introduced in 0.08103 (affects
@@@ -1279,8 -1279,15 +1279,15 @@@ sub _count_subq_rs 
      $sub_attrs->{from}, $sub_attrs->{alias}
    );
  
+   # this is so that ordering can be thrown away in things like Top limit
+   $sub_attrs->{-for_count_only} = 1;
+   my $sub_rs = $rsrc->resultset_class->new ($rsrc, $sub_attrs);
    $attrs->{from} = [{
-     count_subq => $rsrc->resultset_class->new ($rsrc, $sub_attrs )->as_query
+     -alias => 'count_subq',
+     -source_handle => $rsrc->handle,
+     count_subq => $sub_rs->as_query,
    }];
  
    # the subquery replaces this
@@@ -2226,15 -2233,12 +2233,15 @@@ store. If the appropriate relationship
  can also be passed an object representing the foreign row, and the
  value will be set to its primary key.
  
 -To create related objects, pass a hashref for the value if the related
 -item is a foreign key relationship (L<DBIx::Class::Relationship/belongs_to>),
 -and use the name of the relationship as the key. (NOT the name of the field,
 -necessarily). For C<has_many> and C<has_one> relationships, pass an arrayref
 -of hashrefs containing the data for each of the rows to create in the foreign
 -tables, again using the relationship name as the key.
 +To create related objects, pass a hashref of related-object column values
 +B<keyed on the relationship name>. If the relationship is of type C<multi>
 +(L<DBIx::Class::Relationship/has_many>) - pass an arrayref of hashrefs.
 +The process will correctly identify columns holding foreign keys, and will
 +transparrently populate them from the keys of the corresponding relation.
 +This can be applied recursively, and will work correctly for a structure
 +with an arbitrary depth and width, as long as the relationships actually
 +exists and the correct column data has been supplied.
 +
  
  Instead of hashrefs of plain related data (key/value pairs), you may
  also pass new or inserted objects. New objects (not inserted yet, see
@@@ -2857,11 -2861,11 +2864,11 @@@ sub _resolved_attrs 
        ];
    }
  
-   if ( $attrs->{order_by} ) {
+   if ( defined $attrs->{order_by} ) {
      $attrs->{order_by} = (
        ref( $attrs->{order_by} ) eq 'ARRAY'
        ? [ @{ $attrs->{order_by} } ]
-       : [ $attrs->{order_by} ]
+       : [ $attrs->{order_by} || () ]
      );
    }
  
      $attrs->{group_by} = [ $attrs->{group_by} ];
    }
  
-   # If the order_by is otherwise empty - we will use this for TOP limit
-   # emulation and the like.
-   # Although this is needed only if the order_by is not defined, it is
-   # actually cheaper to just populate this rather than properly examining
-   # order_by (stuf like [ {} ] and the like)
-   $attrs->{_virtual_order_by} = [ $self->result_source->primary_columns ];
    $attrs->{collapse} ||= {};
    if ( my $prefetch = delete $attrs->{prefetch} ) {
      $prefetch = $self->_merge_attr( {}, $prefetch );
      push @{ $attrs->{select} }, @{$attrs->{prefetch_select}};
      push @{ $attrs->{as} }, (map { $_->[1] } @prefetch);
  
-     push( @{ $attrs->{order_by} }, @$prefetch_ordering );
+     push( @{$attrs->{order_by}}, @$prefetch_ordering );
      $attrs->{_collapse_order_by} = \@$prefetch_ordering;
    }
  
@@@ -3,22 -3,27 +3,27 @@@ package DBIx::Class::Storage::DBI::mysq
  use strict;
  use warnings;
  
- use base qw/DBIx::Class::Storage::DBI::MultiColumnIn/;
+ use base qw/
+   DBIx::Class::Storage::DBI::MultiColumnIn
+   DBIx::Class::Storage::DBI::AmbiguousGlob
+   DBIx::Class::Storage::DBI
+ /;
+ use mro 'c3';
  
  __PACKAGE__->sql_maker_class('DBIx::Class::SQLAHacks::MySQL');
  
  sub with_deferred_fk_checks {
    my ($self, $sub) = @_;
  
 -  $self->dbh->do('SET foreign_key_checks=0');
 +  $self->_do_query('SET FOREIGN_KEY_CHECKS = 0');
    $sub->();
 -  $self->dbh->do('SET foreign_key_checks=1');
 +  $self->_do_query('SET FOREIGN_KEY_CHECKS = 1');
  }
  
  sub connect_call_set_ansi_mode {
    my $self = shift;
 -  $self->dbh->do(q|SET sql_mode = 'ANSI,TRADITIONAL'|);
 -  $self->dbh->do(q|SET sql_mode = 'ANSI,TRADITIONAL'|);
 +  $self->_do_query(q|SET SQL_MODE = 'ANSI,TRADITIONAL'|);
 +  $self->_do_query(q|SET SQL_AUTO_IS_NULL = 0|);
  }
  
  sub _dbh_last_insert_id {
@@@ -47,7 -52,7 +52,7 @@@ sub _svp_rollback 
  
      $self->dbh->do("ROLLBACK TO SAVEPOINT $name")
  }
-  
  sub is_replicating {
      my $status = shift->dbh->selectrow_hashref('show slave status');
      return ($status->{Slave_IO_Running} eq 'Yes') && ($status->{Slave_SQL_Running} eq 'Yes');
@@@ -63,19 -68,6 +68,6 @@@ sub _subq_update_delete 
    return shift->_per_row_update_delete (@_);
  }
  
- # MySql chokes on things like:
- # COUNT(*) FROM (SELECT tab1.col, tab2.col FROM tab1 JOIN tab2 ... )
- # claiming that col is a duplicate column (it loses the table specifiers by
- # the time it gets to the *). Thus for any subquery count we select only the
- # primary keys of the main table in the inner query. This hopefully still
- # hits the indexes and keeps mysql happy.
- # (mysql does not care if the SELECT and the GROUP BY match)
- sub _subq_count_select {
-   my ($self, $source, $rs_attrs) = @_;
-   my @pcols = map { join '.', $rs_attrs->{alias}, $_ } ($source->primary_columns);
-   return @pcols ? \@pcols : [ 1 ];
- }
  1;
  
  =head1 NAME