Merge 'trunk' into 'prefetch'
Peter Rabbitson [Sun, 14 Feb 2010 10:46:07 +0000 (10:46 +0000)]
r8598@Thesaurus (orig r8585):  ribasushi | 2010-02-08 12:48:31 +0100
Release 0.08118
r8600@Thesaurus (orig r8587):  ribasushi | 2010-02-08 12:52:33 +0100
Bump trunk version
r8606@Thesaurus (orig r8593):  ribasushi | 2010-02-08 16:16:44 +0100
cheaper lookup
r8609@Thesaurus (orig r8596):  ribasushi | 2010-02-10 12:40:37 +0100
Consolidate last_insert_id handling with a fallback-attempt on DBI::last_insert_id
r8614@Thesaurus (orig r8601):  caelum | 2010-02-10 21:29:51 +0100
workaround for Moose bug affecting Replicated storage
r8615@Thesaurus (orig r8602):  caelum | 2010-02-10 21:40:07 +0100
revert Moose bug workaround, bump Moose dep for Replicated to 0.98
r8616@Thesaurus (orig r8603):  caelum | 2010-02-10 22:48:34 +0100
add a couple proxy methods to Replicated so it can run
r8628@Thesaurus (orig r8615):  caelum | 2010-02-11 11:35:01 +0100
 r21090@hlagh (orig r7836):  caelum | 2009-11-02 06:40:52 -0500
 new branch to fix unhandled methods in Storage::DBI::Replicated
 r21091@hlagh (orig r7837):  caelum | 2009-11-02 06:42:00 -0500
 add test to display unhandled methods
 r21092@hlagh (orig r7838):  caelum | 2009-11-02 06:55:34 -0500
 minor fix to last committed test
 r21093@hlagh (orig r7839):  caelum | 2009-11-02 09:26:00 -0500
 minor test code cleanup
 r23125@hlagh (orig r8607):  caelum | 2010-02-10 19:25:51 -0500
 add unimplemented Storage::DBI methods to ::DBI::Replicated
 r23130@hlagh (orig r8612):  ribasushi | 2010-02-11 05:12:48 -0500
 Podtesting exclusion

r8630@Thesaurus (orig r8617):  frew | 2010-02-11 11:45:54 +0100
Changes (from a while ago)
r8631@Thesaurus (orig r8618):  caelum | 2010-02-11 11:46:58 +0100
savepoints for SQLAnywhere
r8640@Thesaurus (orig r8627):  ribasushi | 2010-02-11 12:33:19 +0100
 r8424@Thesaurus (orig r8411):  ribasushi | 2010-01-22 11:19:40 +0100
 Chaining POC test

r8641@Thesaurus (orig r8628):  ribasushi | 2010-02-11 12:34:19 +0100
 r8426@Thesaurus (orig r8413):  ribasushi | 2010-01-22 11:35:15 +0100
 Moev failing regression test away from trunk

r8642@Thesaurus (orig r8629):  ribasushi | 2010-02-11 12:34:56 +0100

r8643@Thesaurus (orig r8630):  ribasushi | 2010-02-11 12:35:03 +0100
 r8507@Thesaurus (orig r8494):  frew | 2010-02-01 04:33:08 +0100
 small refactor to put select/as/+select/+as etc merging in it's own function

r8644@Thesaurus (orig r8631):  ribasushi | 2010-02-11 12:35:11 +0100
 r8514@Thesaurus (orig r8501):  frew | 2010-02-02 05:12:29 +0100
 revert actual changes from yesterday as per ribasushis advice

r8645@Thesaurus (orig r8632):  ribasushi | 2010-02-11 12:35:16 +0100
 r8522@Thesaurus (orig r8509):  frew | 2010-02-02 19:39:33 +0100
 delete +stuff if stuff exists

r8646@Thesaurus (orig r8633):  ribasushi | 2010-02-11 12:35:23 +0100
 r8534@Thesaurus (orig r8521):  frew | 2010-02-03 06:14:44 +0100
 change deletion/overriding to fix t/76

r8647@Thesaurus (orig r8634):  ribasushi | 2010-02-11 12:35:30 +0100
 r8535@Thesaurus (orig r8522):  frew | 2010-02-03 06:57:15 +0100
 some basic readability factorings (aka, fewer nested ternaries and long maps)

r8648@Thesaurus (orig r8635):  ribasushi | 2010-02-11 12:36:01 +0100
 r8558@Thesaurus (orig r8545):  frew | 2010-02-04 20:32:54 +0100
 fix incorrect test in t/76select.t and posit an incorrect solution

r8649@Thesaurus (orig r8636):  ribasushi | 2010-02-11 12:38:47 +0100

r8650@Thesaurus (orig r8637):  ribasushi | 2010-02-11 12:38:57 +0100
 r8578@Thesaurus (orig r8565):  ribasushi | 2010-02-05 19:11:09 +0100
 Should not be needed

r8651@Thesaurus (orig r8638):  ribasushi | 2010-02-11 12:39:03 +0100
 r8579@Thesaurus (orig r8566):  ribasushi | 2010-02-05 19:13:24 +0100
 SQLA now fixed

r8652@Thesaurus (orig r8639):  ribasushi | 2010-02-11 12:39:10 +0100
 r8624@Thesaurus (orig r8611):  ribasushi | 2010-02-11 10:31:08 +0100
 MOAR testing

r8653@Thesaurus (orig r8640):  ribasushi | 2010-02-11 12:39:17 +0100
 r8626@Thesaurus (orig r8613):  frew | 2010-02-11 11:16:30 +0100
 fix bad test

r8654@Thesaurus (orig r8641):  ribasushi | 2010-02-11 12:39:23 +0100
 r8627@Thesaurus (orig r8614):  frew | 2010-02-11 11:21:52 +0100
 fix t/76, break rsc tests

r8655@Thesaurus (orig r8642):  ribasushi | 2010-02-11 12:39:30 +0100
 r8632@Thesaurus (orig r8619):  frew | 2010-02-11 11:53:50 +0100
 fix incorrect test

r8656@Thesaurus (orig r8643):  ribasushi | 2010-02-11 12:39:35 +0100
 r8633@Thesaurus (orig r8620):  frew | 2010-02-11 11:54:49 +0100
 make t/76s and t/88 pass by deleting from the correct attr hash

r8657@Thesaurus (orig r8644):  ribasushi | 2010-02-11 12:39:40 +0100
 r8634@Thesaurus (orig r8621):  frew | 2010-02-11 11:55:41 +0100
 fix a test due to ordering issues

r8658@Thesaurus (orig r8645):  ribasushi | 2010-02-11 12:39:45 +0100
 r8635@Thesaurus (orig r8622):  frew | 2010-02-11 11:58:23 +0100
 this is why you run tests before you commit them.

r8659@Thesaurus (orig r8646):  ribasushi | 2010-02-11 12:39:51 +0100
 r8636@Thesaurus (orig r8623):  frew | 2010-02-11 12:00:59 +0100
 fix another ordering issue

r8660@Thesaurus (orig r8647):  ribasushi | 2010-02-11 12:39:57 +0100
 r8637@Thesaurus (orig r8624):  frew | 2010-02-11 12:11:31 +0100
 fix for search/select_chains

r8661@Thesaurus (orig r8648):  ribasushi | 2010-02-11 12:40:03 +0100

r8662@Thesaurus (orig r8649):  caelum | 2010-02-11 12:40:07 +0100
test nanosecond precision for SQLAnywhere
r8663@Thesaurus (orig r8650):  ribasushi | 2010-02-11 12:40:09 +0100
 r8639@Thesaurus (orig r8626):  ribasushi | 2010-02-11 12:33:03 +0100
 Changes and small ommission

r8666@Thesaurus (orig r8653):  ribasushi | 2010-02-11 18:16:45 +0100
Changes
r8674@Thesaurus (orig r8661):  ribasushi | 2010-02-12 09:12:45 +0100
Fix moose dep
r8680@Thesaurus (orig r8667):  dew | 2010-02-12 18:05:11 +0100
Add is_ordered to DBIC::ResultSet
r8688@Thesaurus (orig r8675):  ribasushi | 2010-02-13 09:36:29 +0100
 r8667@Thesaurus (orig r8654):  ribasushi | 2010-02-11 18:17:35 +0100
 Try a dep-handling idea
 r8675@Thesaurus (orig r8662):  ribasushi | 2010-02-12 12:46:11 +0100
 Move optional deps out of the Makefile
 r8676@Thesaurus (orig r8663):  ribasushi | 2010-02-12 13:40:53 +0100
 Support methods to verify group dependencies
 r8677@Thesaurus (orig r8664):  ribasushi | 2010-02-12 13:45:18 +0100
 Move sqlt dephandling to Optional::Deps
 r8679@Thesaurus (orig r8666):  ribasushi | 2010-02-12 14:03:17 +0100
 Move replicated to Opt::Deps
 r8684@Thesaurus (orig r8671):  ribasushi | 2010-02-13 02:47:52 +0100
 Auto-POD for Optional Deps
 r8685@Thesaurus (orig r8672):  ribasushi | 2010-02-13 02:53:20 +0100
 Privatize the full list method
 r8686@Thesaurus (orig r8673):  ribasushi | 2010-02-13 02:59:51 +0100
 Scary warning
 r8687@Thesaurus (orig r8674):  ribasushi | 2010-02-13 09:35:01 +0100
 Changes

r8691@Thesaurus (orig r8678):  ribasushi | 2010-02-13 10:07:15 +0100
Autogen comment for Dependencies.pod
r8692@Thesaurus (orig r8679):  ribasushi | 2010-02-13 10:11:24 +0100
Ask for newer M::I
r8698@Thesaurus (orig r8685):  ribasushi | 2010-02-13 11:11:10 +0100
Add author/license to pod
r8699@Thesaurus (orig r8686):  arcanez | 2010-02-13 13:43:22 +0100
fix typo per nuba on irc
r8705@Thesaurus (orig r8692):  ribasushi | 2010-02-13 15:15:33 +0100
 r8001@Thesaurus (orig r7989):  goraxe | 2009-11-30 01:14:47 +0100
 Branch for dbicadmin script refactor

 r8003@Thesaurus (orig r7991):  goraxe | 2009-11-30 01:26:39 +0100
 add DBIx::Class::Admin
 r8024@Thesaurus (orig r8012):  goraxe | 2009-12-02 22:49:27 +0100
 get deployment tests to pass
 r8025@Thesaurus (orig r8013):  goraxe | 2009-12-02 22:50:42 +0100
 get deployment tests to pass
 r8026@Thesaurus (orig r8014):  goraxe | 2009-12-02 23:52:40 +0100
 all ddl tests now pass
 r8083@Thesaurus (orig r8071):  goraxe | 2009-12-12 17:01:11 +0100
 add quite attribute to DBIx::Class admin
 r8086@Thesaurus (orig r8074):  goraxe | 2009-12-12 17:36:58 +0100
 add tests for data manipulation ported from 89dbicadmin.t
 r8088@Thesaurus (orig r8076):  goraxe | 2009-12-12 17:38:07 +0100
 add sleep 1 to t/admin/02ddl.t so insert into upgrade table does not happen too quickly
 r8089@Thesaurus (orig r8077):  goraxe | 2009-12-12 17:40:33 +0100
 update DBIx::Class::Admin data manip functions to pass the test
 r8095@Thesaurus (orig r8083):  goraxe | 2009-12-12 19:36:22 +0100
 change passing of preversion to be a parameter
 r8096@Thesaurus (orig r8084):  goraxe | 2009-12-12 19:38:26 +0100
 add some pod to DBIx::Class::Admin
 r8103@Thesaurus (orig r8091):  goraxe | 2009-12-12 22:08:55 +0100
 some changes to make DBIx::Class::Admin more compatible with dbicadmin interface
 r8104@Thesaurus (orig r8092):  goraxe | 2009-12-12 22:09:39 +0100
 commit refactored dbicadmin script and very minor changes to its existing test suite
 r8107@Thesaurus (orig r8095):  goraxe | 2009-12-12 22:34:35 +0100
 add compatability for --op for dbicadmin, revert test suite
 r8127@Thesaurus (orig r8115):  goraxe | 2009-12-15 22:14:20 +0100
 dep check to end of module
 r8128@Thesaurus (orig r8116):  goraxe | 2009-12-15 23:15:25 +0100
 add namespace::autoclean to DBIx::Class::Admin
 r8129@Thesaurus (orig r8117):  goraxe | 2009-12-15 23:16:00 +0100
 update test suite to skip if cannot load DBIx::Class::Admin
 r8130@Thesaurus (orig r8118):  goraxe | 2009-12-15 23:18:35 +0100
 add deps check for 89dbicadmin.t
 r8131@Thesaurus (orig r8119):  goraxe | 2009-12-15 23:19:01 +0100
 include deps for dbicadmin DBIx::Class::Admin to Makefile.PL
 r8149@Thesaurus (orig r8137):  goraxe | 2009-12-17 23:21:50 +0100
 use DBICTest::_database over creating a schema object to steal conn info
 r8338@Thesaurus (orig r8326):  goraxe | 2010-01-15 19:00:17 +0100
 change white space to not be tabs
 r8339@Thesaurus (orig r8327):  goraxe | 2010-01-15 19:10:42 +0100
 remove Module::Load from test suite
 r8358@Thesaurus (orig r8346):  ribasushi | 2010-01-17 17:52:10 +0100
 Real detabify
 r8359@Thesaurus (orig r8347):  ribasushi | 2010-01-17 18:01:53 +0100
 Fix POD (spacing matters)
 r8360@Thesaurus (orig r8348):  ribasushi | 2010-01-17 21:57:53 +0100
 More detabification
 r8361@Thesaurus (orig r8349):  ribasushi | 2010-01-17 22:33:12 +0100
 Test cleanup
 r8362@Thesaurus (orig r8350):  ribasushi | 2010-01-17 22:41:11 +0100
 More tets cleanup
 r8363@Thesaurus (orig r8351):  ribasushi | 2010-01-17 22:43:57 +0100
 And more cleanup
 r8364@Thesaurus (orig r8352):  ribasushi | 2010-01-17 22:51:21 +0100
 Disallow mucking with INC
 r8365@Thesaurus (orig r8353):  ribasushi | 2010-01-17 23:23:15 +0100
 More cleanup
 r8366@Thesaurus (orig r8354):  ribasushi | 2010-01-17 23:27:49 +0100
 Add lib path to ENV so that $^X can see it
 r8367@Thesaurus (orig r8355):  ribasushi | 2010-01-17 23:33:10 +0100
 Move script-test
 r8368@Thesaurus (orig r8356):  goraxe | 2010-01-17 23:35:03 +0100
 change warns/dies -> carp/throw_exception
 r8369@Thesaurus (orig r8357):  goraxe | 2010-01-17 23:53:54 +0100
 add goraxe to contributors
 r8370@Thesaurus (orig r8358):  goraxe | 2010-01-17 23:54:15 +0100
 remove comment headers
 r8404@Thesaurus (orig r8391):  caelum | 2010-01-20 20:54:29 +0100
 minor fixups
 r8405@Thesaurus (orig r8392):  goraxe | 2010-01-20 21:13:24 +0100
 add private types to coerce
 r8406@Thesaurus (orig r8393):  goraxe | 2010-01-20 21:17:19 +0100
 remove un-needed coerce from schema_class of type Str
 r8411@Thesaurus (orig r8398):  caelum | 2010-01-21 23:36:25 +0100
 minor documentation updates
 r8436@Thesaurus (orig r8423):  caelum | 2010-01-25 02:56:30 +0100
 this code never runs anyway
 r8440@Thesaurus (orig r8427):  caelum | 2010-01-26 14:05:53 +0100
 prefer JSON::DWIW for barekey support
 r8693@Thesaurus (orig r8680):  ribasushi | 2010-02-13 10:27:18 +0100
 dbicadmin dependencies
 r8694@Thesaurus (orig r8681):  ribasushi | 2010-02-13 10:28:04 +0100
 Some cleaup, make use of Text::CSV
 r8695@Thesaurus (orig r8682):  ribasushi | 2010-02-13 10:34:19 +0100
 We use Try::Tiny in a single spot, not grounds for inlusion in deps
 r8696@Thesaurus (orig r8683):  ribasushi | 2010-02-13 10:37:30 +0100
 POD section
 r8697@Thesaurus (orig r8684):  ribasushi | 2010-02-13 11:05:17 +0100
 Switch tests to Optional::Deps
 r8700@Thesaurus (orig r8687):  ribasushi | 2010-02-13 14:32:50 +0100
 Switch Admin/dbicadmin to Opt::Deps
 r8702@Thesaurus (orig r8689):  ribasushi | 2010-02-13 14:39:24 +0100
 JSON dep is needed for Admin.pm itself
 r8703@Thesaurus (orig r8690):  ribasushi | 2010-02-13 15:06:28 +0100
 Test fixes
 r8704@Thesaurus (orig r8691):  ribasushi | 2010-02-13 15:13:31 +0100
 Changes

r8707@Thesaurus (orig r8694):  ribasushi | 2010-02-13 16:37:57 +0100
Test for optional deps manager
r8710@Thesaurus (orig r8697):  caelum | 2010-02-14 05:22:03 +0100
add doc on maximum cursors for SQLAnywhere
r8711@Thesaurus (orig r8698):  ribasushi | 2010-02-14 09:23:09 +0100
Cleanup dependencies / Admin inheritance
r8712@Thesaurus (orig r8699):  ribasushi | 2010-02-14 09:28:29 +0100
Some formatting
r8715@Thesaurus (orig r8702):  ribasushi | 2010-02-14 10:46:51 +0100
This is Moose, so use CMOP

1  2 
lib/DBIx/Class/ResultSet.pm
lib/DBIx/Class/ResultSource.pm
t/inflate/hri.t

@@@ -971,104 -976,127 +976,103 @@@ sub _construct_object 
    return @new;
  }
  
 -sub _collapse_result {
 -  my ($self, $as_proto, $row) = @_;
 -
 -  my @copy = @$row;
 -
 -  # 'foo'         => [ undef, 'foo' ]
 -  # 'foo.bar'     => [ 'foo', 'bar' ]
 -  # 'foo.bar.baz' => [ 'foo.bar', 'baz' ]
 -
 -  my @construct_as = map { [ (/^(?:(.*)\.)?([^.]+)$/) ] } @$as_proto;
 -
 -  my %collapse = %{$self->{_attrs}{collapse}||{}};
 +# two arguments: $as_proto is an arrayref of column names,
 +# $row_ref is an arrayref of the data. If none of the row data
 +# is defined we return undef (that's copied from the old
 +# _collapse_result). Next we decide whether we need to collapse
 +# the resultset (i.e. we prefetch something) or not. $collapse
 +# indicates that. The do-while loop will run once if we do not need
 +# to collapse the result and will run as long as _merge_result returns
 +# a true value. It will return undef if the current added row does not
 +# match the previous row. A bit of stashing and cursor magic is
 +# required so that the cursor is not mixed up.
 +
 +# "$rows" is a bit misleading. In the end, there should only be one
 +# element in this arrayref. 
  
 -  my @pri_index;
 -
 -  # if we're doing collapsing (has_many prefetch) we need to grab records
 -  # until the PK changes, so fill @pri_index. if not, we leave it empty so
 -  # we know we don't have to bother.
 -
 -  # the reason for not using the collapse stuff directly is because if you
 -  # had for e.g. two artists in a row with no cds, the collapse info for
 -  # both would be NULL (undef) so you'd lose the second artist
 -
 -  # store just the index so we can check the array positions from the row
 -  # without having to contruct the full hash
 -
 -  if (keys %collapse) {
 -    my %pri = map { ($_ => 1) } $self->result_source->primary_columns;
 -    foreach my $i (0 .. $#construct_as) {
 -      next if defined($construct_as[$i][0]); # only self table
 -      if (delete $pri{$construct_as[$i][1]}) {
 -        push(@pri_index, $i);
 -      }
 -      last unless keys %pri; # short circuit (Johnny Five Is Alive!)
 +sub _collapse_result {
 +    my ( $self, $as_proto, $row_ref ) = @_;
 +    my $has_def;
 +    for (@$row_ref) {
 +        if ( defined $_ ) {
 +            $has_def++;
 +            last;
 +        }
      }
 -  }
 -
 -  # no need to do an if, it'll be empty if @pri_index is empty anyway
 -
 -  my %pri_vals = map { ($_ => $copy[$_]) } @pri_index;
 -
 -  my @const_rows;
 +    return undef unless $has_def;
 +
 +    my $collapse = keys %{ $self->{_attrs}{collapse} || {} };
 +    my $rows     = [];
 +    my @row      = @$row_ref;
 +    do {
 +        my $i = 0;
 +        my $row = { map { $_ => $row[ $i++ ] } @$as_proto };
 +        $row = $self->result_source->_parse_row($row, $collapse);
 +        unless ( scalar @$rows ) {
 +            push( @$rows, $row );
 +        }
 +        $collapse = undef unless ( $self->_merge_result( $rows, $row ) );
 +      } while (
 +        $collapse
 +        && do { @row = $self->cursor->next; $self->{stashed_row} = \@row if @row; }
 +      );
  
 -  do { # no need to check anything at the front, we always want the first row
 +    return $rows->[0];
  
 -    my %const;
 +}
  
 -    foreach my $this_as (@construct_as) {
 -      $const{$this_as->[0]||''}{$this_as->[1]} = shift(@copy);
 +# _merge_result accepts an arrayref of rows objects (again, an arrayref of two elements)
 +# and a row object which should be merged into the first object.
 +# First we try to find out whether $row is already in $rows. If this is the case
 +# we try to merge them by iteration through their relationship data. We call
 +# _merge_result again on them, so they get merged.
 +
 +# If we don't find the $row in $rows, we append it to $rows and return undef.
 +# _merge_result returns 1 otherwise (i.e. $row has been found in $rows).
 +
 +sub _merge_result {
 +    my ( $self, $rows, $row ) = @_;
 +    my ( $columns, $rels ) = @$row;
 +    my $found = undef;
 +    foreach my $seen (@$rows) {
 +        my $match = 1;
 +        foreach my $column ( keys %$columns ) {
 +            if (   defined $seen->[0]->{$column} ^ defined $columns->{$column}
 +                or defined $columns->{$column}
 +                && $seen->[0]->{$column} ne $columns->{$column} )
 +            {
 +
 +                $match = 0;
 +                last;
 +            }
 +        }
 +        if ($match) {
 +            $found = $seen;
 +            last;
 +        }
      }
 +    if ($found) {
 +        foreach my $rel ( keys %$rels ) {
 +            my $old_rows = $found->[1]->{$rel};
 +            $self->_merge_result(
 +                ref $found->[1]->{$rel}->[0] eq 'HASH' ? [ $found->[1]->{$rel} ]
 +                : $found->[1]->{$rel},
 +                ref $rels->{$rel}->[0] eq 'HASH' ? [ $rels->{$rel}->[0], $rels->{$rel}->[1] ]
 +                : $rels->{$rel}->[0]
 +            );
  
 -    push(@const_rows, \%const);
 -
 -  } until ( # no pri_index => no collapse => drop straight out
 -      !@pri_index
 -    or
 -      do { # get another row, stash it, drop out if different PK
 -
 -        @copy = $self->cursor->next;
 -        $self->{stashed_row} = \@copy;
 -
 -        # last thing in do block, counts as true if anything doesn't match
 -
 -        # check xor defined first for NULL vs. NOT NULL then if one is
 -        # defined the other must be so check string equality
 -
 -        grep {
 -          (defined $pri_vals{$_} ^ defined $copy[$_])
 -          || (defined $pri_vals{$_} && ($pri_vals{$_} ne $copy[$_]))
 -        } @pri_index;
 -      }
 -  );
 -
 -  my $alias = $self->{attrs}{alias};
 -  my $info = [];
 -
 -  my %collapse_pos;
 -
 -  my @const_keys;
 -
 -  foreach my $const (@const_rows) {
 -    scalar @const_keys or do {
 -      @const_keys = sort { length($a) <=> length($b) } keys %$const;
 -    };
 -    foreach my $key (@const_keys) {
 -      if (length $key) {
 -        my $target = $info;
 -        my @parts = split(/\./, $key);
 -        my $cur = '';
 -        my $data = $const->{$key};
 -        foreach my $p (@parts) {
 -          $target = $target->[1]->{$p} ||= [];
 -          $cur .= ".${p}";
 -          if ($cur eq ".${key}" && (my @ckey = @{$collapse{$cur}||[]})) {
 -            # collapsing at this point and on final part
 -            my $pos = $collapse_pos{$cur};
 -            CK: foreach my $ck (@ckey) {
 -              if (!defined $pos->{$ck} || $pos->{$ck} ne $data->{$ck}) {
 -                $collapse_pos{$cur} = $data;
 -                delete @collapse_pos{ # clear all positioning for sub-entries
 -                  grep { m/^\Q${cur}.\E/ } keys %collapse_pos
 -                };
 -                push(@$target, []);
 -                last CK;
 -              }
 -            }
 -          }
 -          if (exists $collapse{$cur}) {
 -            $target = $target->[-1];
 -          }
          }
 -        $target->[0] = $data;
 -      } else {
 -        $info->[0] = $const->{$key};
 -      }
 +
 +    }
 +    else {
 +        push( @$rows, $row );
 +        return undef;
      }
 -  }
  
 -  return $info;
 +    return 1;
  }
  
 +
  =head2 result_source
  
  =over 4
Simple merge
diff --cc t/inflate/hri.t
Simple merge