Index: /branches/release-30/lib/MT/Object.pm
===================================================================
--- /branches/release-30/lib/MT/Object.pm (revision 1174)
+++ /branches/release-30/lib/MT/Object.pm (revision 1410)
@@ -513,58 +513,16 @@
 
     my ($id, $ts) = ($obj->id, $obj->$by_field());
-    local @$args{qw( sort direction range_incl )}
-        = ($by_field, $next ? 'ascend' : 'descend', { $by_field => 1 });
-    my $iter = $class->load_iter({
+    local @$args{qw( sort range_incl )}
+        = ( [ { column => $by_field, desc => $next ? 'ASC' : 'DESC' },
+            { column => 'id', desc => $next ? 'ASC' : 'DESC' } ],
+            { $by_field => 1 });
+
+    my $obj = $class->load({
         $by_field => ($next ? [ $ts, undef ] : [ undef, $ts ]),
+        'id' => $id,
         %{$terms}
-    }, $args);
-
-    # This selection should always succeed, but handle situation if
-    # it fails by returning undef.
-    return unless $iter;
-
-    # The 'same' array will hold any entries that have matching
-    # timestamps; we will then sort those by id to find the correct
-    # adjacent object.
-    my @same; 
-    while (my $e = $iter->()) {
-        # Don't consider the object that is 'current'
-        next if $e->id == $id;
-        my $e_ts = $e->$by_field();
-        if ($e_ts eq $ts) {
-            # An object with the same timestamp should only be
-            # considered if the id is in the scope we're looking for
-            # (greater than for the 'next' object; less than for
-            # the 'previous' object).
-            push @same, $e
-                if $next && $e->id > $id or !$next && $e->id < $id;
-        } else {
-            # We found an object with a timestamp different than
-            # the 'current' object.
-            if (!@same) {
-                push @same, $e;
-                # We should check to see if this new timestamped object also
-                # has entries adjacent to _it_ that have the same timestamp.
-                while (my $e = $iter->()) {
-                    push(@same, $e), next if $e->$by_field() eq $e_ts;
-                    $iter->('finish'), last;
-                }
-            } else {
-                $iter->('finish');
-            }
-            return $e unless @same;
-            last;
-        }
-    }
-    if (@same) {
-        # If we only have 1 element in @same, return that.
-        return $same[0] if @same == 1;
-        # Sort remaining elements in @same by id.
-        @same = sort { $a->id <=> $b->id } @same;
-        # Return front of list (smallest id) if selecting 'next'
-        # object. Return tail of list (largest id) if selection 'previous'.
-        return $same[$next ? 0 : $#same];
-    }
-    return;
+    }, { not => { 'id' => 1 }, limit => 1, %$args });
+
+    return $obj;
 }
 
Index: /branches/release-30/lib/MT/ObjectDriver/Driver/DBI.pm
===================================================================
--- /branches/release-30/lib/MT/ObjectDriver/Driver/DBI.pm (revision 1174)
+++ /branches/release-30/lib/MT/ObjectDriver/Driver/DBI.pm (revision 1410)
@@ -348,10 +348,21 @@
         if ($args->{sort} || $args->{direction}) {
             my $order = $args->{sort} || 'id';
-            my $dir = $args->{direction} &&
-                      $args->{direction} eq 'descend' ? 'DESC' : 'ASC';
-            $stmt->order({
-                column => $dbd->db_column_name($tbl, $order),
-                desc   => $dir,
-            });
+            if (! ref($order)) {
+                my $dir = $args->{direction} &&
+                          $args->{direction} eq 'descend' ? 'DESC' : 'ASC';
+                $stmt->order({
+                    column => $dbd->db_column_name($tbl, $order),
+                    desc   => $dir,
+                });
+            } else {
+                my @order;
+                foreach my $ord (@$order) {
+                    push @order, {
+                        column => $dbd->db_column_name($tbl, $ord->{column}),
+                        desc => $ord->{desc},
+                    };
+                }
+                $stmt->order(\@order);
+            }
         }
     }
@@ -433,5 +444,19 @@
         ## TODO: support complex primary keys
         my $col = $args->{sort} || $class->primary_key;
-        $col = $driver->_decorate_column_name($class, $col);
+        if (ref $col eq 'ARRAY') {
+            if (ref $col->[0] eq 'HASH') {
+                # complex 'sort' array/hash structure
+                foreach (@$col) {
+                    $_->{column} = $driver->_decorate_column_name($class, $_->{column});
+                }
+            } else {
+                # primary key as array of column names
+                foreach (@$col) {
+                    $_ = $driver->_decorate_column_name($class, $_);
+                }
+            }
+        } else {
+            $col = $driver->_decorate_column_name($class, $col);
+        }
         my $op = $args->{direction} eq 'descend' ? '<' : '>';
         $stmt->add_where($col, { value => $start_val, op => $op });
