Move more code to DBIHacks, put back the update/delete rs check, just in case
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / DBI.pm
index aab6f31..60c6277 100644 (file)
@@ -1549,48 +1549,25 @@ sub _dbh_execute_inserts_with_no_binds {
 }
 
 sub update {
-  my ($self, $source, $data, $where, @args) = @_; 
+  my ($self, $source, @args) = @_; 
 
   my $bind_attrs = $self->source_bind_attributes($source);
-  $where = $self->_strip_cond_qualifiers ($where);
 
-  return $self->_execute('update' => [], $source, $bind_attrs, $data, $where, @args);
+  return $self->_execute('update' => [], $source, $bind_attrs, @args);
 }
 
 
 sub delete {
-  my ($self, $source, $where, @args) = @_;
+  my ($self, $source, @args) = @_;
 
   my $bind_attrs = $self->source_bind_attributes($source);
-  $where = $self->_strip_cond_qualifiers ($where);
 
-  return $self->_execute('delete' => [], $source, $bind_attrs, $where, @args);
-}
-
-# Most databases do not allow aliasing of tables in UPDATE/DELETE. Thus
-# a condition containing 'me' or other table prefixes will not work
-# at all. Since we employ subqueries when multiple tables are involved
-# (joins), it is relatively safe to strip all column qualifiers. Worst
-# case scenario the error message will be a bit misleading, if the
-# user supplies a foreign qualifier without a join (the message would
-# be "can't find column X", when in fact the user shoud join T containing
-# T.X)
-sub _strip_cond_qualifiers {
-  my ($self, $where) = @_;
-
-  my $sqlmaker = $self->sql_maker;
-  my ($sql, @bind) = $sqlmaker->_recurse_where($where);
-  return undef unless $sql;
-
-  my ($qquot, $qsep) = map { quotemeta $_ } ( ($sqlmaker->quote_char||''), ($sqlmaker->name_sep||'.') );
-  $sql =~ s/ (?: $qquot [\w\-]+ $qquot | [\w\-]+ ) $qsep //gx;
-
-  return \[$sql, @bind];
+  return $self->_execute('delete' => [], $source, $bind_attrs, @args);
 }
 
 # We were sent here because the $rs contains a complex search
 # which will require a subquery to select the correct rows
-# (i.e. joined or limited resultsets)
+# (i.e. joined or limited resultsets, or non-introspectable conditions)
 #
 # Generating a single PK column subquery is trivial and supported
 # by all RDBMS. However if we have a multicolumn PK, things get ugly.
@@ -1601,14 +1578,19 @@ sub _subq_update_delete {
 
   my $rsrc = $rs->result_source;
 
-  # we already check this, but double check naively just in case. Should be removed soon
+  # quick check if we got a sane rs on our hands
+  my @pcols = $rsrc->primary_columns;
+
   my $sel = $rs->_resolved_attrs->{select};
   $sel = [ $sel ] unless ref $sel eq 'ARRAY';
-  my @pcols = $rsrc->primary_columns;
-  if (@$sel != @pcols) {
+
+  if (
+      join ("\x00", map { join '.', $rs->{attrs}{alias}, $_ } sort @pcols)
+        ne
+      join ("\x00", sort @$sel )
+  ) {
     $self->throw_exception (
-      'Subquery update/delete can not be called on resultsets selecting a'
-     .' number of columns different than the number of primary keys'
+      '_subq_update_delete can not be called on resultsets selecting columns other than the primary keys'
     );
   }