Fix oversight in 096ab902 breaking { -value => $array } insertion
Peter Rabbitson [Wed, 20 May 2015 13:25:06 +0000 (15:25 +0200)]
This was never tested for, but also never shipped

lib/DBIx/Class/Row.pm
lib/DBIx/Class/Storage/DBI.pm
t/72pg.t

index 5425fd8..77628ad 100644 (file)
@@ -1221,11 +1221,16 @@ sub store_column {
   $self->throw_exception( "set_column called for ${column} without value" )
     if @_ < 3;
 
-  # stringify all refs explicitly, guards against overloaded objects
+  return $self->{_column_data}{$column} = $value
+    unless length ref $value and my $vref = is_plain_value( $value );
+
+  # if we are dealing with a value/ref - there are a couple possibilities
+  # unpack the underlying piece of data and stringify all objects explicitly
+  # ( to accomodate { -value => ... } and guard against overloaded objects
   # with defined stringification AND fallback => 0 (ugh!)
-  $self->{_column_data}{$column} = ( length ref $value and is_plain_value( $value ) )
-    ? "$value"
-    : $value
+  $self->{_column_data}{$column} = defined blessed $$vref
+    ? "$$vref"
+    : $$vref
   ;
 }
 
index 3e746ad..40ae3f9 100644 (file)
@@ -2286,10 +2286,12 @@ sub _dbh_execute_for_fetch {
 
       # FIXME SUBOPTIMAL - DBI needs fixing to always stringify regardless of DBD
       # For the time being forcibly stringify whatever is stringifiable
-      (length ref $v and is_plain_value $v)
-        ? "$v"
-        : $v
-      ;
+      my $vref;
+
+      ( !length ref $v or ! ($vref = is_plain_value $v) )   ? $v
+    : defined blessed( $$vref )                             ? "$$vref"
+                                                            : $$vref
+    ;
     } map { $_->[0] } @$proto_bind ];
   };
 
index e1e8e0e..e03cd2b 100644 (file)
--- a/t/72pg.t
+++ b/t/72pg.t
@@ -287,6 +287,49 @@ for my $use_insert_returning ($test_server_supports_insert_returning
       $row->discard_changes;
       is_deeply ($row->arrayfield, [3,4], 'Array value made it to storage');
     }
+
+    my $arr = [ 1..10 ];
+    # exercise the creation-logic even more (akin to t/100populate.t)
+    for my $insert_value (
+      $arr,
+      { -value => $arr },
+      \[ '?', $arr ],
+    ) {
+      $arr_rs->delete;
+
+      my @objs = (
+        $arr_rs->create({ arrayfield => $insert_value }),
+        $arr_rs->populate([ { arrayfield => $insert_value } ]),
+        $arr_rs->populate([ ['arrayfield'], [ $insert_value ] ]),
+      );
+
+      my $loose_obj = $arr_rs->new({ arrayfield => $insert_value });
+
+      unless (is_literal_value $insert_value) {
+        is_deeply( $_->arrayfield, $arr, 'array value preserved during set_columns' )
+          for ($loose_obj, @objs)
+      }
+
+      push @objs, $loose_obj->insert;
+
+      $_->discard_changes for @objs;
+      is_deeply( $_->arrayfield, $arr, 'array value correct after discard_changes' )
+        for (@objs);
+
+      # insert couple more in void ctx
+      $arr_rs->populate([ { arrayfield => $insert_value } ]);
+      $arr_rs->populate([ ['arrayfield'], [ $insert_value ] ]);
+
+      # should have a total of 6 now, all pristine
+      my @retrieved_objs = $arr_rs->search({
+        arrayfield => ref $insert_value eq 'ARRAY'
+          ? { -value => $insert_value }
+          : { '=' => $insert_value }
+      })->all;
+      is scalar @retrieved_objs, 6, 'Correct count of inserted rows';
+      is_deeply( $_->arrayfield, $arr, 'array value correct after storage retrieval' )
+        for (@retrieved_objs);
+    }
   }
 
 ########## Case check