fix and regression test for RT #62642
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / DBI / MultiColumnIn.pm
CommitLineData
4ce3b851 1package DBIx::Class::Storage::DBI::MultiColumnIn;
2
3use strict;
4use warnings;
5
6use base 'DBIx::Class::Storage::DBI';
2ad62d97 7use mro 'c3';
4ce3b851 8
9=head1 NAME
10
11DBIx::Class::Storage::DBI::MultiColumnIn - Storage component for RDBMS supporting multicolumn in clauses
12
13=head1 DESCRIPTION
14
15While ANSI SQL does not define a multicolumn in operator, many databases can
16in fact understand WHERE (cola, colb) IN ( SELECT subcol_a, subcol_b ... )
17The storage class for any such RDBMS should inherit from this class, in order
18to dramatically speed up update/delete operations on joined multipk resultsets.
19
cee28da6 20At this point the only overridden method is C<_multipk_update_delete()>
4ce3b851 21
22=cut
23
24sub _multipk_update_delete {
25 my $self = shift;
26 my ($rs, $op, $values) = @_;
27
28 my $rsrc = $rs->result_source;
e8fb771b 29 my @pcols = $rsrc->_pri_cols;
4ce3b851 30 my $attrs = $rs->_resolved_attrs;
31
32 # naive check - this is an internal method after all, we should know what we are doing
33 $self->throw_exception ('Number of columns selected by supplied resultset does not match number of primary keys')
34 if ( ref $attrs->{select} ne 'ARRAY' or @{$attrs->{select}} != @pcols );
35
36 # This is hideously ugly, but SQLA does not understand multicol IN expressions
9f6b5584 37 my $sqla = $self->_sql_maker;
4ce3b851 38 my ($sql, @bind) = @${$rs->as_query};
9f6b5584 39 $sql = sprintf ('(%s) IN %s', # the as_query stuff is already enclosed in ()s
40 join (', ', map { $sqla->_quote ($_) } @pcols),
4ce3b851 41 $sql,
42 );
43
44 return $self->$op (
45 $rsrc,
46 $op eq 'update' ? $values : (),
47 \[$sql, @bind],
48 );
49
50}
51
52=head1 AUTHORS
53
54See L<DBIx::Class/CONTRIBUTORS>
55
56=head1 LICENSE
57
58You may distribute this code under the same terms as Perl itself.
59
60=cut
61
621;