Prune pointless puke parens
[scpubgit/Q-Branch.git] / lib / SQL / Abstract.pm
CommitLineData
96449e8e 1package SQL::Abstract; # see doc at end of file
2
96449e8e 3use strict;
4use warnings;
9d9d5bd6 5use Carp ();
312d830b 6use List::Util ();
7use Scalar::Util ();
96449e8e 8
0da0fe34 9use Exporter 'import';
10our @EXPORT_OK = qw(is_plain_value is_literal_value);
11
12BEGIN {
13 if ($] < 5.009_005) {
14 require MRO::Compat;
15 }
16 else {
17 require mro;
18 }
843a94b5 19
20 *SQL::Abstract::_ENV_::DETECT_AUTOGENERATED_STRINGIFICATION = $ENV{SQLA_ISVALUE_IGNORE_AUTOGENERATED_STRINGIFICATION}
21 ? sub () { 0 }
22 : sub () { 1 }
23 ;
0da0fe34 24}
25
96449e8e 26#======================================================================
27# GLOBALS
28#======================================================================
29
8eeec645 30our $VERSION = '1.84';
7479e27e 31
22f1a437 32# This would confuse some packagers
c520207b 33$VERSION = eval $VERSION if $VERSION =~ /_/; # numify for warning-free dev releases
96449e8e 34
35our $AUTOLOAD;
36
37# special operators (-in, -between). May be extended/overridden by user.
38# See section WHERE: BUILTIN SPECIAL OPERATORS below for implementation
39my @BUILTIN_SPECIAL_OPS = (
b8db59b8 40 {regex => qr/^ (?: not \s )? between $/ix, handler => '_where_field_BETWEEN'},
41 {regex => qr/^ (?: not \s )? in $/ix, handler => '_where_field_IN'},
cc422895 42 {regex => qr/^ ident $/ix, handler => '_where_op_IDENT'},
43 {regex => qr/^ value $/ix, handler => '_where_op_VALUE'},
b9b5a0b1 44 {regex => qr/^ is (?: \s+ not )? $/ix, handler => '_where_field_IS'},
96449e8e 45);
46
97a920ef 47# unaryish operators - key maps to handler
59f23b3d 48my @BUILTIN_UNARY_OPS = (
a47b433a 49 # the digits are backcompat stuff
b8db59b8 50 { regex => qr/^ and (?: [_\s]? \d+ )? $/xi, handler => '_where_op_ANDOR' },
51 { regex => qr/^ or (?: [_\s]? \d+ )? $/xi, handler => '_where_op_ANDOR' },
52 { regex => qr/^ nest (?: [_\s]? \d+ )? $/xi, handler => '_where_op_NEST' },
53 { regex => qr/^ (?: not \s )? bool $/xi, handler => '_where_op_BOOL' },
cc422895 54 { regex => qr/^ ident $/xi, handler => '_where_op_IDENT' },
b9b5a0b1 55 { regex => qr/^ value $/xi, handler => '_where_op_VALUE' },
59f23b3d 56);
97a920ef 57
96449e8e 58#======================================================================
59# DEBUGGING AND ERROR REPORTING
60#======================================================================
61
62sub _debug {
63 return unless $_[0]->{debug}; shift; # a little faster
64 my $func = (caller(1))[3];
65 warn "[$func] ", @_, "\n";
66}
67
68sub belch (@) {
69 my($func) = (caller(1))[3];
9d9d5bd6 70 Carp::carp "[$func] Warning: ", @_;
96449e8e 71}
72
73sub puke (@) {
74 my($func) = (caller(1))[3];
9d9d5bd6 75 Carp::croak "[$func] Fatal: ", @_;
96449e8e 76}
77
0da0fe34 78sub is_literal_value ($) {
79 ref $_[0] eq 'SCALAR' ? [ ${$_[0]} ]
80 : ( ref $_[0] eq 'REF' and ref ${$_[0]} eq 'ARRAY' ) ? [ @${ $_[0] } ]
0da0fe34 81 : undef;
82}
83
84# FIXME XSify - this can be done so much more efficiently
85sub is_plain_value ($) {
86 no strict 'refs';
966200cc 87 ! length ref $_[0] ? \($_[0])
0da0fe34 88 : (
89 ref $_[0] eq 'HASH' and keys %{$_[0]} == 1
90 and
91 exists $_[0]->{-value}
966200cc 92 ) ? \($_[0]->{-value})
0da0fe34 93 : (
a1c9e0ff 94 # reuse @_ for even moar speedz
95 defined ( $_[1] = Scalar::Util::blessed $_[0] )
0da0fe34 96 and
97 # deliberately not using Devel::OverloadInfo - the checks we are
98 # intersted in are much more limited than the fullblown thing, and
99 # this is a very hot piece of code
100 (
e8d729d4 101 # simply using ->can('(""') can leave behind stub methods that
102 # break actually using the overload later (see L<perldiag/Stub
103 # found while resolving method "%s" overloading "%s" in package
104 # "%s"> and the source of overload::mycan())
44e54b41 105 #
0da0fe34 106 # either has stringification which DBI SHOULD prefer out of the box
a1c9e0ff 107 grep { *{ (qq[${_}::(""]) }{CODE} } @{ $_[2] = mro::get_linear_isa( $_[1] ) }
0da0fe34 108 or
20e178a8 109 # has nummification or boolification, AND fallback is *not* disabled
0da0fe34 110 (
843a94b5 111 SQL::Abstract::_ENV_::DETECT_AUTOGENERATED_STRINGIFICATION
112 and
20e178a8 113 (
114 grep { *{"${_}::(0+"}{CODE} } @{$_[2]}
115 or
116 grep { *{"${_}::(bool"}{CODE} } @{$_[2]}
117 )
0da0fe34 118 and
119 (
120 # no fallback specified at all
a1c9e0ff 121 ! ( ($_[3]) = grep { *{"${_}::()"}{CODE} } @{$_[2]} )
0da0fe34 122 or
123 # fallback explicitly undef
a1c9e0ff 124 ! defined ${"$_[3]::()"}
0da0fe34 125 or
126 # explicitly true
a1c9e0ff 127 !! ${"$_[3]::()"}
0da0fe34 128 )
129 )
130 )
966200cc 131 ) ? \($_[0])
0da0fe34 132 : undef;
133}
134
135
96449e8e 136
137#======================================================================
138# NEW
139#======================================================================
140
141sub new {
142 my $self = shift;
143 my $class = ref($self) || $self;
144 my %opt = (ref $_[0] eq 'HASH') ? %{$_[0]} : @_;
145
146 # choose our case by keeping an option around
147 delete $opt{case} if $opt{case} && $opt{case} ne 'lower';
148
149 # default logic for interpreting arrayrefs
ef559da3 150 $opt{logic} = $opt{logic} ? uc $opt{logic} : 'OR';
96449e8e 151
152 # how to return bind vars
96449e8e 153 $opt{bindtype} ||= 'normal';
154
155 # default comparison is "=", but can be overridden
156 $opt{cmp} ||= '=';
157
3af02ccb 158 # try to recognize which are the 'equality' and 'inequality' ops
3cdadcbe 159 # (temporary quickfix (in 2007), should go through a more seasoned API)
160 $opt{equality_op} = qr/^( \Q$opt{cmp}\E | \= )$/ix;
161 $opt{inequality_op} = qr/^( != | <> )$/ix;
162
163 $opt{like_op} = qr/^ (is\s+)? r?like $/xi;
164 $opt{not_like_op} = qr/^ (is\s+)? not \s+ r?like $/xi;
96449e8e 165
166 # SQL booleans
167 $opt{sqltrue} ||= '1=1';
168 $opt{sqlfalse} ||= '0=1';
169
9d48860e 170 # special operators
96449e8e 171 $opt{special_ops} ||= [];
b6251592 172 # regexes are applied in order, thus push after user-defines
96449e8e 173 push @{$opt{special_ops}}, @BUILTIN_SPECIAL_OPS;
174
9d48860e 175 # unary operators
59f23b3d 176 $opt{unary_ops} ||= [];
177 push @{$opt{unary_ops}}, @BUILTIN_UNARY_OPS;
178
3af02ccb 179 # rudimentary sanity-check for user supplied bits treated as functions/operators
b6251592 180 # If a purported function matches this regular expression, an exception is thrown.
181 # Literal SQL is *NOT* subject to this check, only functions (and column names
182 # when quoting is not in effect)
96449e8e 183
b6251592 184 # FIXME
185 # need to guard against ()'s in column names too, but this will break tons of
186 # hacks... ideas anyone?
187 $opt{injection_guard} ||= qr/
188 \;
189 |
190 ^ \s* go \s
191 /xmi;
96449e8e 192
b6251592 193 return bless \%opt, $class;
194}
96449e8e 195
170e6c33 196
197sub _assert_pass_injection_guard {
198 if ($_[1] =~ $_[0]->{injection_guard}) {
199 my $class = ref $_[0];
200 puke "Possible SQL injection attempt '$_[1]'. If this is indeed a part of the "
201 . "desired SQL use literal SQL ( \'...' or \[ '...' ] ) or supply your own "
202 . "{injection_guard} attribute to ${class}->new()"
203 }
204}
205
206
96449e8e 207#======================================================================
208# INSERT methods
209#======================================================================
210
211sub insert {
02288357 212 my $self = shift;
213 my $table = $self->_table(shift);
214 my $data = shift || return;
215 my $options = shift;
96449e8e 216
217 my $method = $self->_METHOD_FOR_refkind("_insert", $data);
02288357 218 my ($sql, @bind) = $self->$method($data);
96449e8e 219 $sql = join " ", $self->_sqlcase('insert into'), $table, $sql;
02288357 220
e82e648a 221 if ($options->{returning}) {
78536e8b 222 my ($s, @b) = $self->_insert_returning ($options);
e82e648a 223 $sql .= $s;
224 push @bind, @b;
02288357 225 }
226
96449e8e 227 return wantarray ? ($sql, @bind) : $sql;
228}
229
60f3fd3f 230# So that subclasses can override INSERT ... RETURNING separately from
231# UPDATE and DELETE (e.g. DBIx::Class::SQLMaker::Oracle does this)
b17a3ece 232sub _insert_returning { shift->_returning(@_) }
233
95904db5 234sub _returning {
e82e648a 235 my ($self, $options) = @_;
6b1fe79d 236
e82e648a 237 my $f = $options->{returning};
238
239 my $fieldlist = $self->_SWITCH_refkind($f, {
240 ARRAYREF => sub {join ', ', map { $self->_quote($_) } @$f;},
241 SCALAR => sub {$self->_quote($f)},
242 SCALARREF => sub {$$f},
6b1fe79d 243 });
e82e648a 244 return $self->_sqlcase(' returning ') . $fieldlist;
6b1fe79d 245}
246
96449e8e 247sub _insert_HASHREF { # explicit list of fields and then values
248 my ($self, $data) = @_;
249
250 my @fields = sort keys %$data;
251
fe3ae272 252 my ($sql, @bind) = $self->_insert_values($data);
96449e8e 253
254 # assemble SQL
255 $_ = $self->_quote($_) foreach @fields;
256 $sql = "( ".join(", ", @fields).") ".$sql;
257
258 return ($sql, @bind);
259}
260
261sub _insert_ARRAYREF { # just generate values(?,?) part (no list of fields)
262 my ($self, $data) = @_;
263
264 # no names (arrayref) so can't generate bindtype
265 $self->{bindtype} ne 'columns'
266 or belch "can't do 'columns' bindtype when called with arrayref";
267
19b6ccce 268 my (@values, @all_bind);
269 foreach my $value (@$data) {
270 my ($values, @bind) = $self->_insert_value(undef, $value);
271 push @values, $values;
272 push @all_bind, @bind;
273 }
274 my $sql = $self->_sqlcase('values')." ( ".join(", ", @values)." )";
275 return ($sql, @all_bind);
fe3ae272 276}
277
278sub _insert_ARRAYREFREF { # literal SQL with bind
279 my ($self, $data) = @_;
280
281 my ($sql, @bind) = @${$data};
282 $self->_assert_bindval_matches_bindtype(@bind);
283
284 return ($sql, @bind);
285}
286
287
288sub _insert_SCALARREF { # literal SQL without bind
289 my ($self, $data) = @_;
290
291 return ($$data);
292}
293
294sub _insert_values {
295 my ($self, $data) = @_;
296
96449e8e 297 my (@values, @all_bind);
fe3ae272 298 foreach my $column (sort keys %$data) {
19b6ccce 299 my ($values, @bind) = $self->_insert_value($column, $data->{$column});
300 push @values, $values;
301 push @all_bind, @bind;
302 }
303 my $sql = $self->_sqlcase('values')." ( ".join(", ", @values)." )";
304 return ($sql, @all_bind);
305}
96449e8e 306
19b6ccce 307sub _insert_value {
308 my ($self, $column, $v) = @_;
96449e8e 309
19b6ccce 310 my (@values, @all_bind);
311 $self->_SWITCH_refkind($v, {
96449e8e 312
19b6ccce 313 ARRAYREF => sub {
314 if ($self->{array_datatypes}) { # if array datatype are activated
96449e8e 315 push @values, '?';
fe3ae272 316 push @all_bind, $self->_bindtype($column, $v);
19b6ccce 317 }
318 else { # else literal SQL with bind
319 my ($sql, @bind) = @$v;
320 $self->_assert_bindval_matches_bindtype(@bind);
321 push @values, $sql;
322 push @all_bind, @bind;
323 }
324 },
325
326 ARRAYREFREF => sub { # literal SQL with bind
327 my ($sql, @bind) = @${$v};
328 $self->_assert_bindval_matches_bindtype(@bind);
329 push @values, $sql;
330 push @all_bind, @bind;
331 },
332
333 # THINK : anything useful to do with a HASHREF ?
334 HASHREF => sub { # (nothing, but old SQLA passed it through)
335 #TODO in SQLA >= 2.0 it will die instead
336 belch "HASH ref as bind value in insert is not supported";
337 push @values, '?';
338 push @all_bind, $self->_bindtype($column, $v);
339 },
340
341 SCALARREF => sub { # literal SQL without bind
342 push @values, $$v;
343 },
344
345 SCALAR_or_UNDEF => sub {
346 push @values, '?';
347 push @all_bind, $self->_bindtype($column, $v);
348 },
96449e8e 349
19b6ccce 350 });
96449e8e 351
19b6ccce 352 my $sql = join(", ", @values);
96449e8e 353 return ($sql, @all_bind);
354}
355
356
96449e8e 357
358#======================================================================
359# UPDATE methods
360#======================================================================
361
362
363sub update {
95904db5 364 my $self = shift;
365 my $table = $self->_table(shift);
366 my $data = shift || return;
367 my $where = shift;
368 my $options = shift;
96449e8e 369
370 # first build the 'SET' part of the sql statement
371 my (@set, @all_bind);
372 puke "Unsupported data type specified to \$sql->update"
373 unless ref $data eq 'HASH';
374
375 for my $k (sort keys %$data) {
376 my $v = $data->{$k};
377 my $r = ref $v;
378 my $label = $self->_quote($k);
379
380 $self->_SWITCH_refkind($v, {
9d48860e 381 ARRAYREF => sub {
96449e8e 382 if ($self->{array_datatypes}) { # array datatype
383 push @set, "$label = ?";
384 push @all_bind, $self->_bindtype($k, $v);
385 }
386 else { # literal SQL with bind
387 my ($sql, @bind) = @$v;
fe3ae272 388 $self->_assert_bindval_matches_bindtype(@bind);
96449e8e 389 push @set, "$label = $sql";
fe3ae272 390 push @all_bind, @bind;
96449e8e 391 }
392 },
393 ARRAYREFREF => sub { # literal SQL with bind
394 my ($sql, @bind) = @${$v};
fe3ae272 395 $self->_assert_bindval_matches_bindtype(@bind);
96449e8e 396 push @set, "$label = $sql";
fe3ae272 397 push @all_bind, @bind;
96449e8e 398 },
399 SCALARREF => sub { # literal SQL without bind
400 push @set, "$label = $$v";
0ec3aec7 401 },
402 HASHREF => sub {
403 my ($op, $arg, @rest) = %$v;
404
405 puke 'Operator calls in update must be in the form { -op => $arg }'
406 if (@rest or not $op =~ /^\-(.+)/);
407
408 local $self->{_nested_func_lhs} = $k;
409 my ($sql, @bind) = $self->_where_unary_op ($1, $arg);
410
411 push @set, "$label = $sql";
412 push @all_bind, @bind;
413 },
96449e8e 414 SCALAR_or_UNDEF => sub {
415 push @set, "$label = ?";
416 push @all_bind, $self->_bindtype($k, $v);
417 },
418 });
419 }
420
421 # generate sql
422 my $sql = $self->_sqlcase('update') . " $table " . $self->_sqlcase('set ')
423 . join ', ', @set;
424
425 if ($where) {
426 my($where_sql, @where_bind) = $self->where($where);
427 $sql .= $where_sql;
428 push @all_bind, @where_bind;
429 }
430
95904db5 431 if ($options->{returning}) {
20bb2ad5 432 my ($returning_sql, @returning_bind) = $self->_update_returning ($options);
95904db5 433 $sql .= $returning_sql;
434 push @all_bind, @returning_bind;
435 }
436
96449e8e 437 return wantarray ? ($sql, @all_bind) : $sql;
438}
439
60f3fd3f 440# So that subclasses can override UPDATE ... RETURNING separately from
441# INSERT and DELETE
20bb2ad5 442sub _update_returning { shift->_returning(@_) }
96449e8e 443
444
445
446#======================================================================
447# SELECT
448#======================================================================
449
450
451sub select {
452 my $self = shift;
453 my $table = $self->_table(shift);
454 my $fields = shift || '*';
455 my $where = shift;
456 my $order = shift;
457
458 my($where_sql, @bind) = $self->where($where, $order);
459
460 my $f = (ref $fields eq 'ARRAY') ? join ', ', map { $self->_quote($_) } @$fields
461 : $fields;
9d48860e 462 my $sql = join(' ', $self->_sqlcase('select'), $f,
96449e8e 463 $self->_sqlcase('from'), $table)
464 . $where_sql;
465
9d48860e 466 return wantarray ? ($sql, @bind) : $sql;
96449e8e 467}
468
469#======================================================================
470# DELETE
471#======================================================================
472
473
474sub delete {
85327cd5 475 my $self = shift;
476 my $table = $self->_table(shift);
477 my $where = shift;
478 my $options = shift;
96449e8e 479
480 my($where_sql, @bind) = $self->where($where);
481 my $sql = $self->_sqlcase('delete from') . " $table" . $where_sql;
482
85327cd5 483 if ($options->{returning}) {
484 my ($returning_sql, @returning_bind) = $self->_delete_returning ($options);
485 $sql .= $returning_sql;
486 push @bind, @returning_bind;
487 }
488
9d48860e 489 return wantarray ? ($sql, @bind) : $sql;
96449e8e 490}
491
60f3fd3f 492# So that subclasses can override DELETE ... RETURNING separately from
493# INSERT and UPDATE
85327cd5 494sub _delete_returning { shift->_returning(@_) }
495
496
96449e8e 497
498#======================================================================
499# WHERE: entry point
500#======================================================================
501
502
503
504# Finally, a separate routine just to handle WHERE clauses
505sub where {
506 my ($self, $where, $order) = @_;
507
508 # where ?
509 my ($sql, @bind) = $self->_recurse_where($where);
510 $sql = $sql ? $self->_sqlcase(' where ') . "( $sql )" : '';
511
512 # order by?
513 if ($order) {
26fe4d30 514 my ($order_sql, @order_bind) = $self->_order_by($order);
515 $sql .= $order_sql;
516 push @bind, @order_bind;
96449e8e 517 }
518
9d48860e 519 return wantarray ? ($sql, @bind) : $sql;
96449e8e 520}
521
522
523sub _recurse_where {
524 my ($self, $where, $logic) = @_;
525
526 # dispatch on appropriate method according to refkind of $where
527 my $method = $self->_METHOD_FOR_refkind("_where", $where);
311b2151 528
9d48860e 529 my ($sql, @bind) = $self->$method($where, $logic);
311b2151 530
abe1a491 531 # DBIx::Class used to call _recurse_where in scalar context
532 # something else might too...
533 if (wantarray) {
534 return ($sql, @bind);
535 }
536 else {
537 belch "Calling _recurse_where in scalar context is deprecated and will go away before 2.0";
538 return $sql;
539 }
96449e8e 540}
541
542
543
544#======================================================================
545# WHERE: top-level ARRAYREF
546#======================================================================
547
548
549sub _where_ARRAYREF {
5e1d09d5 550 my ($self, $where, $logic) = @_;
96449e8e 551
5e1d09d5 552 $logic = uc($logic || $self->{logic});
96449e8e 553 $logic eq 'AND' or $logic eq 'OR' or puke "unknown logic: $logic";
554
555 my @clauses = @$where;
556
96449e8e 557 my (@sql_clauses, @all_bind);
96449e8e 558 # need to use while() so can shift() for pairs
b5a576d2 559 while (@clauses) {
560 my $el = shift @clauses;
561
562 $el = undef if (defined $el and ! length $el);
96449e8e 563
564 # switch according to kind of $el and get corresponding ($sql, @bind)
565 my ($sql, @bind) = $self->_SWITCH_refkind($el, {
566
567 # skip empty elements, otherwise get invalid trailing AND stuff
568 ARRAYREF => sub {$self->_recurse_where($el) if @$el},
569
c94a6c93 570 ARRAYREFREF => sub {
571 my ($s, @b) = @$$el;
572 $self->_assert_bindval_matches_bindtype(@b);
573 ($s, @b);
574 },
474e3335 575
96449e8e 576 HASHREF => sub {$self->_recurse_where($el, 'and') if %$el},
96449e8e 577
578 SCALARREF => sub { ($$el); },
579
b5a576d2 580 SCALAR => sub {
581 # top-level arrayref with scalars, recurse in pairs
582 $self->_recurse_where({$el => shift(@clauses)})
583 },
96449e8e 584
b5a576d2 585 UNDEF => sub {puke "Supplying an empty left hand side argument is not supported in array-pairs" },
96449e8e 586 });
587
4b7b6026 588 if ($sql) {
589 push @sql_clauses, $sql;
590 push @all_bind, @bind;
591 }
96449e8e 592 }
593
594 return $self->_join_sql_clauses($logic, \@sql_clauses, \@all_bind);
595}
596
474e3335 597#======================================================================
598# WHERE: top-level ARRAYREFREF
599#======================================================================
96449e8e 600
474e3335 601sub _where_ARRAYREFREF {
602 my ($self, $where) = @_;
c94a6c93 603 my ($sql, @bind) = @$$where;
604 $self->_assert_bindval_matches_bindtype(@bind);
474e3335 605 return ($sql, @bind);
606}
96449e8e 607
608#======================================================================
609# WHERE: top-level HASHREF
610#======================================================================
611
612sub _where_HASHREF {
613 my ($self, $where) = @_;
614 my (@sql_clauses, @all_bind);
615
2281c758 616 for my $k (sort keys %$where) {
96449e8e 617 my $v = $where->{$k};
618
2281c758 619 # ($k => $v) is either a special unary op or a regular hashpair
620 my ($sql, @bind) = do {
621 if ($k =~ /^-./) {
622 # put the operator in canonical form
623 my $op = $k;
b8db59b8 624 $op = substr $op, 1; # remove initial dash
2281c758 625 $op =~ s/^\s+|\s+$//g;# remove leading/trailing space
b8db59b8 626 $op =~ s/\s+/ /g; # compress whitespace
627
628 # so that -not_foo works correctly
629 $op =~ s/^not_/NOT /i;
2281c758 630
631 $self->_debug("Unary OP(-$op) within hashref, recursing...");
0ec3aec7 632 my ($s, @b) = $self->_where_unary_op ($op, $v);
633
634 # top level vs nested
635 # we assume that handled unary ops will take care of their ()s
636 $s = "($s)" unless (
637 List::Util::first {$op =~ $_->{regex}} @{$self->{unary_ops}}
638 or
923ce642 639 ( defined $self->{_nested_func_lhs} and $self->{_nested_func_lhs} eq $k )
0ec3aec7 640 );
641 ($s, @b);
2281c758 642 }
643 else {
b5a576d2 644 if (! length $k) {
645 if (is_literal_value ($v) ) {
646 belch 'Hash-pairs consisting of an empty string with a literal are deprecated, and will be removed in 2.0: use -and => [ $literal ] instead';
647 }
648 else {
649 puke "Supplying an empty left hand side argument is not supported in hash-pairs";
650 }
651 }
652
2281c758 653 my $method = $self->_METHOD_FOR_refkind("_where_hashpair", $v);
654 $self->$method($k, $v);
655 }
656 };
96449e8e 657
658 push @sql_clauses, $sql;
659 push @all_bind, @bind;
660 }
661
662 return $self->_join_sql_clauses('and', \@sql_clauses, \@all_bind);
663}
664
0ec3aec7 665sub _where_unary_op {
2281c758 666 my ($self, $op, $rhs) = @_;
96449e8e 667
ddd6fbb6 668 # top level special ops are illegal in general
669 # this includes the -ident/-value ops (dual purpose unary and special)
670 puke "Illegal use of top-level '-$op'"
671 if ! defined $self->{_nested_func_lhs} and List::Util::first {$op =~ $_->{regex}} @{$self->{special_ops}};
672
0ec3aec7 673 if (my $op_entry = List::Util::first {$op =~ $_->{regex}} @{$self->{unary_ops}}) {
674 my $handler = $op_entry->{handler};
675
676 if (not ref $handler) {
677 if ($op =~ s/ [_\s]? \d+ $//x ) {
678 belch 'Use of [and|or|nest]_N modifiers is deprecated and will be removed in SQLA v2.0. '
679 . "You probably wanted ...-and => [ -$op => COND1, -$op => COND2 ... ]";
680 }
681 return $self->$handler ($op, $rhs);
682 }
683 elsif (ref $handler eq 'CODE') {
684 return $handler->($self, $op, $rhs);
685 }
686 else {
687 puke "Illegal handler for operator $op - expecting a method name or a coderef";
688 }
689 }
690
3d86e3b1 691 $self->_debug("Generic unary OP: $op - recursing as function");
0ec3aec7 692
170e6c33 693 $self->_assert_pass_injection_guard($op);
b6251592 694
2281c758 695 my ($sql, @bind) = $self->_SWITCH_refkind ($rhs, {
696 SCALAR => sub {
ddd6fbb6 697 puke "Illegal use of top-level '-$op'"
923ce642 698 unless defined $self->{_nested_func_lhs};
a7661cfc 699
700 return (
701 $self->_convert('?'),
702 $self->_bindtype($self->{_nested_func_lhs}, $rhs)
703 );
2281c758 704 },
705 FALLBACK => sub {
706 $self->_recurse_where ($rhs)
707 },
708 });
96449e8e 709
953d164e 710 $sql = sprintf ('%s %s',
2281c758 711 $self->_sqlcase($op),
953d164e 712 $sql,
2281c758 713 );
96449e8e 714
2281c758 715 return ($sql, @bind);
97a920ef 716}
717
718sub _where_op_ANDOR {
2281c758 719 my ($self, $op, $v) = @_;
97a920ef 720
721 $self->_SWITCH_refkind($v, {
722 ARRAYREF => sub {
723 return $self->_where_ARRAYREF($v, $op);
724 },
725
726 HASHREF => sub {
59f23b3d 727 return ( $op =~ /^or/i )
97a920ef 728 ? $self->_where_ARRAYREF( [ map { $_ => $v->{$_} } ( sort keys %$v ) ], $op )
729 : $self->_where_HASHREF($v);
730 },
731
9d48860e 732 SCALARREF => sub {
48d9f5f8 733 puke "-$op => \\\$scalar makes little sense, use " .
a0d6d323 734 ($op =~ /^or/i
48d9f5f8 735 ? '[ \$scalar, \%rest_of_conditions ] instead'
736 : '-and => [ \$scalar, \%rest_of_conditions ] instead'
737 );
97a920ef 738 },
739
740 ARRAYREFREF => sub {
48d9f5f8 741 puke "-$op => \\[...] makes little sense, use " .
a0d6d323 742 ($op =~ /^or/i
48d9f5f8 743 ? '[ \[...], \%rest_of_conditions ] instead'
744 : '-and => [ \[...], \%rest_of_conditions ] instead'
745 );
97a920ef 746 },
747
748 SCALAR => sub { # permissively interpreted as SQL
48d9f5f8 749 puke "-$op => \$value makes little sense, use -bool => \$value instead";
97a920ef 750 },
751
752 UNDEF => sub {
753 puke "-$op => undef not supported";
754 },
755 });
756}
757
758sub _where_op_NEST {
9d48860e 759 my ($self, $op, $v) = @_;
97a920ef 760
96449e8e 761 $self->_SWITCH_refkind($v, {
762
96449e8e 763 SCALAR => sub { # permissively interpreted as SQL
01a01e57 764 belch "literal SQL should be -nest => \\'scalar' "
765 . "instead of -nest => 'scalar' ";
9d48860e 766 return ($v);
96449e8e 767 },
768
769 UNDEF => sub {
770 puke "-$op => undef not supported";
771 },
e9501094 772
773 FALLBACK => sub {
774 $self->_recurse_where ($v);
775 },
776
96449e8e 777 });
778}
779
780
97a920ef 781sub _where_op_BOOL {
9d48860e 782 my ($self, $op, $v) = @_;
97a920ef 783
b8db59b8 784 my ($s, @b) = $self->_SWITCH_refkind($v, {
785 SCALAR => sub { # interpreted as SQL column
786 $self->_convert($self->_quote($v));
787 },
ef03f1bc 788
b8db59b8 789 UNDEF => sub {
790 puke "-$op => undef not supported";
791 },
97a920ef 792
b8db59b8 793 FALLBACK => sub {
794 $self->_recurse_where ($v);
795 },
796 });
ef03f1bc 797
b8db59b8 798 $s = "(NOT $s)" if $op =~ /^not/i;
799 ($s, @b);
97a920ef 800}
801
802
cc422895 803sub _where_op_IDENT {
804 my $self = shift;
805 my ($op, $rhs) = splice @_, -2;
8aa76984 806 if (! defined $rhs or length ref $rhs) {
807 puke "-$op requires a single plain scalar argument (a quotable identifier)";
cc422895 808 }
809
810 # in case we are called as a top level special op (no '=')
811 my $lhs = shift;
812
813 $_ = $self->_convert($self->_quote($_)) for ($lhs, $rhs);
814
815 return $lhs
816 ? "$lhs = $rhs"
817 : $rhs
818 ;
819}
820
821sub _where_op_VALUE {
822 my $self = shift;
823 my ($op, $rhs) = splice @_, -2;
824
825 # in case we are called as a top level special op (no '=')
826 my $lhs = shift;
827
422ed2de 828 # special-case NULL
829 if (! defined $rhs) {
923ce642 830 return defined $lhs
422ed2de 831 ? $self->_convert($self->_quote($lhs)) . ' IS NULL'
832 : undef
833 ;
834 }
835
cc422895 836 my @bind =
837 $self->_bindtype (
923ce642 838 ( defined $lhs ? $lhs : $self->{_nested_func_lhs} ),
cc422895 839 $rhs,
840 )
841 ;
842
843 return $lhs
844 ? (
845 $self->_convert($self->_quote($lhs)) . ' = ' . $self->_convert('?'),
846 @bind
847 )
848 : (
849 $self->_convert('?'),
850 @bind,
851 )
852 ;
853}
854
96449e8e 855sub _where_hashpair_ARRAYREF {
856 my ($self, $k, $v) = @_;
857
858 if( @$v ) {
859 my @v = @$v; # need copy because of shift below
860 $self->_debug("ARRAY($k) means distribute over elements");
861
862 # put apart first element if it is an operator (-and, -or)
e3cecb45 863 my $op = (
864 (defined $v[0] && $v[0] =~ /^ - (?: AND|OR ) $/ix)
865 ? shift @v
866 : ''
04d940de 867 );
96449e8e 868 my @distributed = map { {$k => $_} } @v;
04d940de 869
870 if ($op) {
871 $self->_debug("OP($op) reinjected into the distributed array");
872 unshift @distributed, $op;
873 }
874
f67591bf 875 my $logic = $op ? substr($op, 1) : '';
96449e8e 876
f67591bf 877 return $self->_recurse_where(\@distributed, $logic);
9d48860e 878 }
96449e8e 879 else {
96449e8e 880 $self->_debug("empty ARRAY($k) means 0=1");
881 return ($self->{sqlfalse});
882 }
883}
884
885sub _where_hashpair_HASHREF {
eb49170d 886 my ($self, $k, $v, $logic) = @_;
887 $logic ||= 'and';
96449e8e 888
923ce642 889 local $self->{_nested_func_lhs} = defined $self->{_nested_func_lhs}
890 ? $self->{_nested_func_lhs}
891 : $k
892 ;
a7661cfc 893
eb49170d 894 my ($all_sql, @all_bind);
96449e8e 895
a47b433a 896 for my $orig_op (sort keys %$v) {
897 my $val = $v->{$orig_op};
96449e8e 898
899 # put the operator in canonical form
a47b433a 900 my $op = $orig_op;
b8db59b8 901
902 # FIXME - we need to phase out dash-less ops
903 $op =~ s/^-//; # remove possible initial dash
a47b433a 904 $op =~ s/^\s+|\s+$//g;# remove leading/trailing space
b8db59b8 905 $op =~ s/\s+/ /g; # compress whitespace
906
170e6c33 907 $self->_assert_pass_injection_guard($op);
b6251592 908
b9b5a0b1 909 # fixup is_not
910 $op =~ s/^is_not/IS NOT/i;
911
b8db59b8 912 # so that -not_foo works correctly
913 $op =~ s/^not_/NOT /i;
96449e8e 914
422ed2de 915 # another retarded special case: foo => { $op => { -value => undef } }
916 if (ref $val eq 'HASH' and keys %$val == 1 and exists $val->{-value} and ! defined $val->{-value} ) {
917 $val = undef;
918 }
919
96449e8e 920 my ($sql, @bind);
921
2281c758 922 # CASE: col-value logic modifiers
923 if ( $orig_op =~ /^ \- (and|or) $/xi ) {
924 ($sql, @bind) = $self->_where_hashpair_HASHREF($k, $val, $1);
925 }
96449e8e 926 # CASE: special operators like -in or -between
312d830b 927 elsif ( my $special_op = List::Util::first {$op =~ $_->{regex}} @{$self->{special_ops}} ) {
3a2e1a5e 928 my $handler = $special_op->{handler};
929 if (! $handler) {
a47b433a 930 puke "No handler supplied for special operator $orig_op";
3a2e1a5e 931 }
932 elsif (not ref $handler) {
933 ($sql, @bind) = $self->$handler ($k, $op, $val);
934 }
935 elsif (ref $handler eq 'CODE') {
936 ($sql, @bind) = $handler->($self, $k, $op, $val);
937 }
938 else {
a47b433a 939 puke "Illegal handler for special operator $orig_op - expecting a method name or a coderef";
3a2e1a5e 940 }
96449e8e 941 }
96449e8e 942 else {
cf838930 943 $self->_SWITCH_refkind($val, {
944
945 ARRAYREF => sub { # CASE: col => {op => \@vals}
946 ($sql, @bind) = $self->_where_field_op_ARRAYREF($k, $op, $val);
947 },
948
fe3ae272 949 ARRAYREFREF => sub { # CASE: col => {op => \[$sql, @bind]} (literal SQL with bind)
b3be7bd0 950 my ($sub_sql, @sub_bind) = @$$val;
fe3ae272 951 $self->_assert_bindval_matches_bindtype(@sub_bind);
b3be7bd0 952 $sql = join ' ', $self->_convert($self->_quote($k)),
953 $self->_sqlcase($op),
954 $sub_sql;
fe3ae272 955 @bind = @sub_bind;
b3be7bd0 956 },
957
cf838930 958 UNDEF => sub { # CASE: col => {op => undef} : sql "IS (NOT)? NULL"
3cdadcbe 959 my $is =
40f2f231 960 $op =~ /^not$/i ? 'is not' # legacy
961 : $op =~ $self->{equality_op} ? 'is'
3cdadcbe 962 : $op =~ $self->{like_op} ? belch("Supplying an undefined argument to '@{[ uc $op]}' is deprecated") && 'is'
963 : $op =~ $self->{inequality_op} ? 'is not'
964 : $op =~ $self->{not_like_op} ? belch("Supplying an undefined argument to '@{[ uc $op]}' is deprecated") && 'is not'
965 : puke "unexpected operator '$orig_op' with undef operand";
966
cf838930 967 $sql = $self->_quote($k) . $self->_sqlcase(" $is null");
968 },
a47b433a 969
2281c758 970 FALLBACK => sub { # CASE: col => {op/func => $stuff}
0ec3aec7 971 ($sql, @bind) = $self->_where_unary_op ($op, $val);
953d164e 972
973 $sql = join (' ',
974 $self->_convert($self->_quote($k)),
975 $self->{_nested_func_lhs} eq $k ? $sql : "($sql)", # top level vs nested
976 );
cf838930 977 },
978 });
96449e8e 979 }
980
eb49170d 981 ($all_sql) = (defined $all_sql and $all_sql) ? $self->_join_sql_clauses($logic, [$all_sql, $sql], []) : $sql;
96449e8e 982 push @all_bind, @bind;
983 }
eb49170d 984 return ($all_sql, @all_bind);
96449e8e 985}
986
b9b5a0b1 987sub _where_field_IS {
988 my ($self, $k, $op, $v) = @_;
989
990 my ($s) = $self->_SWITCH_refkind($v, {
991 UNDEF => sub {
992 join ' ',
993 $self->_convert($self->_quote($k)),
994 map { $self->_sqlcase($_)} ($op, 'null')
995 },
996 FALLBACK => sub {
997 puke "$op can only take undef as argument";
998 },
999 });
96449e8e 1000
b9b5a0b1 1001 $s;
1002}
96449e8e 1003
1004sub _where_field_op_ARRAYREF {
1005 my ($self, $k, $op, $vals) = @_;
1006
ce261791 1007 my @vals = @$vals; #always work on a copy
1008
1009 if(@vals) {
bd6a65ca 1010 $self->_debug(sprintf '%s means multiple elements: [ %s ]',
1011 $vals,
1012 join (', ', map { defined $_ ? "'$_'" : 'NULL' } @vals ),
1013 );
96449e8e 1014
4030915f 1015 # see if the first element is an -and/-or op
1016 my $logic;
bd6a65ca 1017 if (defined $vals[0] && $vals[0] =~ /^ - ( AND|OR ) $/ix) {
4030915f 1018 $logic = uc $1;
ce261791 1019 shift @vals;
4030915f 1020 }
1021
3cdadcbe 1022 # a long standing API wart - an attempt to change this behavior during
1023 # the 1.50 series failed *spectacularly*. Warn instead and leave the
1024 # behavior as is
1025 if (
1026 @vals > 1
1027 and
1028 (!$logic or $logic eq 'OR')
1029 and
1030 ( $op =~ $self->{inequality_op} or $op =~ $self->{not_like_op} )
1031 ) {
1032 my $o = uc($op);
1033 belch "A multi-element arrayref as an argument to the inequality op '$o' "
1034 . 'is technically equivalent to an always-true 1=1 (you probably wanted '
1035 . "to say ...{ \$inequality_op => [ -and => \@values ] }... instead)"
1036 ;
1037 }
1038
ce261791 1039 # distribute $op over each remaining member of @vals, append logic if exists
1040 return $self->_recurse_where([map { {$k => {$op, $_}} } @vals], $logic);
4030915f 1041
9d48860e 1042 }
96449e8e 1043 else {
9d48860e 1044 # try to DWIM on equality operators
3cdadcbe 1045 return
1046 $op =~ $self->{equality_op} ? $self->{sqlfalse}
1047 : $op =~ $self->{like_op} ? belch("Supplying an empty arrayref to '@{[ uc $op]}' is deprecated") && $self->{sqlfalse}
1048 : $op =~ $self->{inequality_op} ? $self->{sqltrue}
1049 : $op =~ $self->{not_like_op} ? belch("Supplying an empty arrayref to '@{[ uc $op]}' is deprecated") && $self->{sqltrue}
1050 : puke "operator '$op' applied on an empty array (field '$k')";
96449e8e 1051 }
1052}
1053
1054
1055sub _where_hashpair_SCALARREF {
1056 my ($self, $k, $v) = @_;
1057 $self->_debug("SCALAR($k) means literal SQL: $$v");
1058 my $sql = $self->_quote($k) . " " . $$v;
1059 return ($sql);
1060}
1061
fe3ae272 1062# literal SQL with bind
96449e8e 1063sub _where_hashpair_ARRAYREFREF {
1064 my ($self, $k, $v) = @_;
1065 $self->_debug("REF($k) means literal SQL: @${$v}");
c94a6c93 1066 my ($sql, @bind) = @$$v;
fe3ae272 1067 $self->_assert_bindval_matches_bindtype(@bind);
96449e8e 1068 $sql = $self->_quote($k) . " " . $sql;
96449e8e 1069 return ($sql, @bind );
1070}
1071
fe3ae272 1072# literal SQL without bind
96449e8e 1073sub _where_hashpair_SCALAR {
1074 my ($self, $k, $v) = @_;
1075 $self->_debug("NOREF($k) means simple key=val: $k $self->{cmp} $v");
9d48860e 1076 my $sql = join ' ', $self->_convert($self->_quote($k)),
1077 $self->_sqlcase($self->{cmp}),
96449e8e 1078 $self->_convert('?');
1079 my @bind = $self->_bindtype($k, $v);
1080 return ( $sql, @bind);
1081}
1082
1083
1084sub _where_hashpair_UNDEF {
1085 my ($self, $k, $v) = @_;
1086 $self->_debug("UNDEF($k) means IS NULL");
1087 my $sql = $self->_quote($k) . $self->_sqlcase(' is null');
1088 return ($sql);
1089}
1090
1091#======================================================================
1092# WHERE: TOP-LEVEL OTHERS (SCALARREF, SCALAR, UNDEF)
1093#======================================================================
1094
1095
1096sub _where_SCALARREF {
1097 my ($self, $where) = @_;
1098
1099 # literal sql
1100 $self->_debug("SCALAR(*top) means literal SQL: $$where");
1101 return ($$where);
1102}
1103
1104
1105sub _where_SCALAR {
1106 my ($self, $where) = @_;
1107
1108 # literal sql
1109 $self->_debug("NOREF(*top) means literal SQL: $where");
1110 return ($where);
1111}
1112
1113
1114sub _where_UNDEF {
1115 my ($self) = @_;
1116 return ();
1117}
1118
1119
1120#======================================================================
1121# WHERE: BUILTIN SPECIAL OPERATORS (-in, -between)
1122#======================================================================
1123
1124
1125sub _where_field_BETWEEN {
1126 my ($self, $k, $op, $vals) = @_;
1127
4d8b3dc4 1128 my ($label, $and, $placeholder);
cf02fc47 1129 $label = $self->_convert($self->_quote($k));
1130 $and = ' ' . $self->_sqlcase('and') . ' ';
1131 $placeholder = $self->_convert('?');
96449e8e 1132 $op = $self->_sqlcase($op);
1133
7f54040f 1134 my $invalid_args = "Operator '$op' requires either an arrayref with two defined values or expressions, or a single literal scalarref/arrayref-ref";
1135
4d8b3dc4 1136 my ($clause, @bind) = $self->_SWITCH_refkind($vals, {
1137 ARRAYREFREF => sub {
c94a6c93 1138 my ($s, @b) = @$$vals;
1139 $self->_assert_bindval_matches_bindtype(@b);
1140 ($s, @b);
4d8b3dc4 1141 },
1142 SCALARREF => sub {
1143 return $$vals;
1144 },
1145 ARRAYREF => sub {
7f54040f 1146 puke $invalid_args if @$vals != 2;
4d8b3dc4 1147
1148 my (@all_sql, @all_bind);
1149 foreach my $val (@$vals) {
1150 my ($sql, @bind) = $self->_SWITCH_refkind($val, {
1151 SCALAR => sub {
5e5cbf51 1152 return ($placeholder, $self->_bindtype($k, $val) );
4d8b3dc4 1153 },
1154 SCALARREF => sub {
0336eddb 1155 return $$val;
4d8b3dc4 1156 },
1157 ARRAYREFREF => sub {
1158 my ($sql, @bind) = @$$val;
c94a6c93 1159 $self->_assert_bindval_matches_bindtype(@bind);
0336eddb 1160 return ($sql, @bind);
4d8b3dc4 1161 },
0336eddb 1162 HASHREF => sub {
1163 my ($func, $arg, @rest) = %$val;
0e49a487 1164 puke "Only simple { -func => arg } functions accepted as sub-arguments to BETWEEN"
0336eddb 1165 if (@rest or $func !~ /^ \- (.+)/x);
0ec3aec7 1166 $self->_where_unary_op ($1 => $arg);
7f54040f 1167 },
1168 FALLBACK => sub {
1169 puke $invalid_args,
1170 },
4d8b3dc4 1171 });
1172 push @all_sql, $sql;
1173 push @all_bind, @bind;
1174 }
1175
1176 return (
1177 (join $and, @all_sql),
5e5cbf51 1178 @all_bind
4d8b3dc4 1179 );
1180 },
1181 FALLBACK => sub {
7f54040f 1182 puke $invalid_args,
4d8b3dc4 1183 },
1184 });
cf02fc47 1185
cf02fc47 1186 my $sql = "( $label $op $clause )";
96449e8e 1187 return ($sql, @bind)
1188}
1189
1190
1191sub _where_field_IN {
1192 my ($self, $k, $op, $vals) = @_;
1193
1194 # backwards compatibility : if scalar, force into an arrayref
1195 $vals = [$vals] if defined $vals && ! ref $vals;
1196
96449e8e 1197 my ($label) = $self->_convert($self->_quote($k));
1198 my ($placeholder) = $self->_convert('?');
96449e8e 1199 $op = $self->_sqlcase($op);
1200
8a0d798a 1201 my ($sql, @bind) = $self->_SWITCH_refkind($vals, {
1202 ARRAYREF => sub { # list of choices
1203 if (@$vals) { # nonempty list
0336eddb 1204 my (@all_sql, @all_bind);
1205
1206 for my $val (@$vals) {
1207 my ($sql, @bind) = $self->_SWITCH_refkind($val, {
1208 SCALAR => sub {
1209 return ($placeholder, $val);
1210 },
1211 SCALARREF => sub {
1212 return $$val;
1213 },
1214 ARRAYREFREF => sub {
1215 my ($sql, @bind) = @$$val;
1216 $self->_assert_bindval_matches_bindtype(@bind);
1217 return ($sql, @bind);
1218 },
1219 HASHREF => sub {
1220 my ($func, $arg, @rest) = %$val;
0e49a487 1221 puke "Only simple { -func => arg } functions accepted as sub-arguments to IN"
0336eddb 1222 if (@rest or $func !~ /^ \- (.+)/x);
0ec3aec7 1223 $self->_where_unary_op ($1 => $arg);
279eb282 1224 },
1225 UNDEF => sub {
032dfe20 1226 puke(
1227 'SQL::Abstract before v1.75 used to generate incorrect SQL when the '
1228 . "-$op operator was given an undef-containing list: !!!AUDIT YOUR CODE "
1229 . 'AND DATA!!! (the upcoming Data::Query-based version of SQL::Abstract '
1230 . 'will emit the logically correct SQL instead of raising this exception)'
1231 );
279eb282 1232 },
0336eddb 1233 });
1234 push @all_sql, $sql;
1235 push @all_bind, @bind;
1236 }
96449e8e 1237
88a89939 1238 return (
1239 sprintf ('%s %s ( %s )',
1240 $label,
1241 $op,
1242 join (', ', @all_sql)
1243 ),
1244 $self->_bindtype($k, @all_bind),
0336eddb 1245 );
8a0d798a 1246 }
1247 else { # empty list : some databases won't understand "IN ()", so DWIM
1248 my $sql = ($op =~ /\bnot\b/i) ? $self->{sqltrue} : $self->{sqlfalse};
1249 return ($sql);
1250 }
1251 },
1252
4a1f01a3 1253 SCALARREF => sub { # literal SQL
1254 my $sql = $self->_open_outer_paren ($$vals);
1255 return ("$label $op ( $sql )");
1256 },
8a0d798a 1257 ARRAYREFREF => sub { # literal SQL with bind
1258 my ($sql, @bind) = @$$vals;
fe3ae272 1259 $self->_assert_bindval_matches_bindtype(@bind);
4a1f01a3 1260 $sql = $self->_open_outer_paren ($sql);
8a0d798a 1261 return ("$label $op ( $sql )", @bind);
1262 },
1263
ff8ca6b4 1264 UNDEF => sub {
1265 puke "Argument passed to the '$op' operator can not be undefined";
1266 },
1267
8a0d798a 1268 FALLBACK => sub {
ff8ca6b4 1269 puke "special op $op requires an arrayref (or scalarref/arrayref-ref)";
8a0d798a 1270 },
1271 });
1272
1273 return ($sql, @bind);
96449e8e 1274}
1275
4a1f01a3 1276# Some databases (SQLite) treat col IN (1, 2) different from
1277# col IN ( (1, 2) ). Use this to strip all outer parens while
1278# adding them back in the corresponding method
1279sub _open_outer_paren {
1280 my ($self, $sql) = @_;
a5f91feb 1281
1282 while ( my ($inner) = $sql =~ /^ \s* \( (.*) \) \s* $/xs ) {
1283
1284 # there are closing parens inside, need the heavy duty machinery
1285 # to reevaluate the extraction starting from $sql (full reevaluation)
1286 if ( $inner =~ /\)/ ) {
1287 require Text::Balanced;
1288
1289 my (undef, $remainder) = do {
1290 # idiotic design - writes to $@ but *DOES NOT* throw exceptions
1291 local $@;
1292 Text::Balanced::extract_bracketed( $sql, '()', qr/\s*/ );
1293 };
1294
1295 # the entire expression needs to be a balanced bracketed thing
1296 # (after an extract no remainder sans trailing space)
1297 last if defined $remainder and $remainder =~ /\S/;
1298 }
1299
1300 $sql = $inner;
1301 }
1302
1303 $sql;
4a1f01a3 1304}
1305
96449e8e 1306
96449e8e 1307#======================================================================
1308# ORDER BY
1309#======================================================================
1310
1311sub _order_by {
1312 my ($self, $arg) = @_;
1313
f267b646 1314 my (@sql, @bind);
1315 for my $c ($self->_order_by_chunks ($arg) ) {
1316 $self->_SWITCH_refkind ($c, {
1317 SCALAR => sub { push @sql, $c },
1318 ARRAYREF => sub { push @sql, shift @$c; push @bind, @$c },
1319 });
1320 }
1321
1322 my $sql = @sql
1323 ? sprintf ('%s %s',
1324 $self->_sqlcase(' order by'),
1325 join (', ', @sql)
1326 )
1327 : ''
1328 ;
1329
1330 return wantarray ? ($sql, @bind) : $sql;
1331}
1332
1333sub _order_by_chunks {
1334 my ($self, $arg) = @_;
1335
1336 return $self->_SWITCH_refkind($arg, {
96449e8e 1337
1338 ARRAYREF => sub {
f267b646 1339 map { $self->_order_by_chunks ($_ ) } @$arg;
96449e8e 1340 },
1341
c94a6c93 1342 ARRAYREFREF => sub {
1343 my ($s, @b) = @$$arg;
1344 $self->_assert_bindval_matches_bindtype(@b);
1345 [ $s, @b ];
1346 },
f267b646 1347
96449e8e 1348 SCALAR => sub {$self->_quote($arg)},
f267b646 1349
1350 UNDEF => sub {return () },
1351
96449e8e 1352 SCALARREF => sub {$$arg}, # literal SQL, no quoting
96449e8e 1353
f267b646 1354 HASHREF => sub {
5e436130 1355 # get first pair in hash
1356 my ($key, $val, @rest) = %$arg;
1357
1358 return () unless $key;
1359
1360 if ( @rest or not $key =~ /^-(desc|asc)/i ) {
1361 puke "hash passed to _order_by must have exactly one key (-desc or -asc)";
f267b646 1362 }
5e436130 1363
1364 my $direction = $1;
96449e8e 1365
e9bd3547 1366 my @ret;
f267b646 1367 for my $c ($self->_order_by_chunks ($val)) {
e9bd3547 1368 my ($sql, @bind);
96449e8e 1369
f267b646 1370 $self->_SWITCH_refkind ($c, {
1371 SCALAR => sub {
e9bd3547 1372 $sql = $c;
f267b646 1373 },
1374 ARRAYREF => sub {
e9bd3547 1375 ($sql, @bind) = @$c;
f267b646 1376 },
1377 });
96449e8e 1378
5e436130 1379 $sql = $sql . ' ' . $self->_sqlcase($direction);
96449e8e 1380
e9bd3547 1381 push @ret, [ $sql, @bind];
1382 }
96449e8e 1383
e9bd3547 1384 return @ret;
f267b646 1385 },
1386 });
96449e8e 1387}
1388
1389
96449e8e 1390#======================================================================
1391# DATASOURCE (FOR NOW, JUST PLAIN TABLE OR LIST OF TABLES)
1392#======================================================================
1393
1394sub _table {
1395 my $self = shift;
1396 my $from = shift;
1397 $self->_SWITCH_refkind($from, {
1398 ARRAYREF => sub {join ', ', map { $self->_quote($_) } @$from;},
1399 SCALAR => sub {$self->_quote($from)},
1400 SCALARREF => sub {$$from},
96449e8e 1401 });
1402}
1403
1404
1405#======================================================================
1406# UTILITY FUNCTIONS
1407#======================================================================
1408
955e77ca 1409# highly optimized, as it's called way too often
96449e8e 1410sub _quote {
955e77ca 1411 # my ($self, $label) = @_;
96449e8e 1412
955e77ca 1413 return '' unless defined $_[1];
955e77ca 1414 return ${$_[1]} if ref($_[1]) eq 'SCALAR';
96449e8e 1415
439834d3 1416 $_[0]->{quote_char} or
1417 ($_[0]->_assert_pass_injection_guard($_[1]), return $_[1]);
96449e8e 1418
07d7c35c 1419 my $qref = ref $_[0]->{quote_char};
439834d3 1420 my ($l, $r) =
1421 !$qref ? ($_[0]->{quote_char}, $_[0]->{quote_char})
1422 : ($qref eq 'ARRAY') ? @{$_[0]->{quote_char}}
1423 : puke "Unsupported quote_char format: $_[0]->{quote_char}";
1424
46be4313 1425 my $esc = $_[0]->{escape_char} || $r;
96449e8e 1426
07d7c35c 1427 # parts containing * are naturally unquoted
1428 return join( $_[0]->{name_sep}||'', map
439834d3 1429 +( $_ eq '*' ? $_ : do { (my $n = $_) =~ s/(\Q$esc\E|\Q$r\E)/$esc$1/g; $l . $n . $r } ),
955e77ca 1430 ( $_[0]->{name_sep} ? split (/\Q$_[0]->{name_sep}\E/, $_[1] ) : $_[1] )
1431 );
96449e8e 1432}
1433
1434
1435# Conversion, if applicable
d7c862e0 1436sub _convert {
07d7c35c 1437 #my ($self, $arg) = @_;
07d7c35c 1438 if ($_[0]->{convert}) {
1439 return $_[0]->_sqlcase($_[0]->{convert}) .'(' . $_[1] . ')';
96449e8e 1440 }
07d7c35c 1441 return $_[1];
96449e8e 1442}
1443
1444# And bindtype
d7c862e0 1445sub _bindtype {
07d7c35c 1446 #my ($self, $col, @vals) = @_;
07d7c35c 1447 # called often - tighten code
1448 return $_[0]->{bindtype} eq 'columns'
1449 ? map {[$_[1], $_]} @_[2 .. $#_]
1450 : @_[2 .. $#_]
1451 ;
96449e8e 1452}
1453
fe3ae272 1454# Dies if any element of @bind is not in [colname => value] format
1455# if bindtype is 'columns'.
1456sub _assert_bindval_matches_bindtype {
c94a6c93 1457# my ($self, @bind) = @_;
1458 my $self = shift;
fe3ae272 1459 if ($self->{bindtype} eq 'columns') {
c94a6c93 1460 for (@_) {
1461 if (!defined $_ || ref($_) ne 'ARRAY' || @$_ != 2) {
3a06278c 1462 puke "bindtype 'columns' selected, you need to pass: [column_name => bind_value]"
fe3ae272 1463 }
1464 }
1465 }
1466}
1467
96449e8e 1468sub _join_sql_clauses {
1469 my ($self, $logic, $clauses_aref, $bind_aref) = @_;
1470
1471 if (@$clauses_aref > 1) {
1472 my $join = " " . $self->_sqlcase($logic) . " ";
1473 my $sql = '( ' . join($join, @$clauses_aref) . ' )';
1474 return ($sql, @$bind_aref);
1475 }
1476 elsif (@$clauses_aref) {
1477 return ($clauses_aref->[0], @$bind_aref); # no parentheses
1478 }
1479 else {
1480 return (); # if no SQL, ignore @$bind_aref
1481 }
1482}
1483
1484
1485# Fix SQL case, if so requested
1486sub _sqlcase {
96449e8e 1487 # LDNOTE: if $self->{case} is true, then it contains 'lower', so we
1488 # don't touch the argument ... crooked logic, but let's not change it!
07d7c35c 1489 return $_[0]->{case} ? $_[1] : uc($_[1]);
96449e8e 1490}
1491
1492
1493#======================================================================
1494# DISPATCHING FROM REFKIND
1495#======================================================================
1496
1497sub _refkind {
1498 my ($self, $data) = @_;
96449e8e 1499
955e77ca 1500 return 'UNDEF' unless defined $data;
1501
1502 # blessed objects are treated like scalars
1503 my $ref = (Scalar::Util::blessed $data) ? '' : ref $data;
1504
1505 return 'SCALAR' unless $ref;
1506
1507 my $n_steps = 1;
1508 while ($ref eq 'REF') {
96449e8e 1509 $data = $$data;
955e77ca 1510 $ref = (Scalar::Util::blessed $data) ? '' : ref $data;
1511 $n_steps++ if $ref;
96449e8e 1512 }
1513
848556bc 1514 return ($ref||'SCALAR') . ('REF' x $n_steps);
96449e8e 1515}
1516
1517sub _try_refkind {
1518 my ($self, $data) = @_;
1519 my @try = ($self->_refkind($data));
1520 push @try, 'SCALAR_or_UNDEF' if $try[0] eq 'SCALAR' || $try[0] eq 'UNDEF';
1521 push @try, 'FALLBACK';
955e77ca 1522 return \@try;
96449e8e 1523}
1524
1525sub _METHOD_FOR_refkind {
1526 my ($self, $meth_prefix, $data) = @_;
f39eaa60 1527
1528 my $method;
955e77ca 1529 for (@{$self->_try_refkind($data)}) {
f39eaa60 1530 $method = $self->can($meth_prefix."_".$_)
1531 and last;
1532 }
1533
1534 return $method || puke "cannot dispatch on '$meth_prefix' for ".$self->_refkind($data);
96449e8e 1535}
1536
1537
1538sub _SWITCH_refkind {
1539 my ($self, $data, $dispatch_table) = @_;
1540
f39eaa60 1541 my $coderef;
955e77ca 1542 for (@{$self->_try_refkind($data)}) {
f39eaa60 1543 $coderef = $dispatch_table->{$_}
1544 and last;
1545 }
1546
1547 puke "no dispatch entry for ".$self->_refkind($data)
1548 unless $coderef;
1549
96449e8e 1550 $coderef->();
1551}
1552
1553
1554
1555
1556#======================================================================
1557# VALUES, GENERATE, AUTOLOAD
1558#======================================================================
1559
1560# LDNOTE: original code from nwiger, didn't touch code in that section
1561# I feel the AUTOLOAD stuff should not be the default, it should
1562# only be activated on explicit demand by user.
1563
1564sub values {
1565 my $self = shift;
1566 my $data = shift || return;
1567 puke "Argument to ", __PACKAGE__, "->values must be a \\%hash"
1568 unless ref $data eq 'HASH';
bab725ce 1569
1570 my @all_bind;
1571 foreach my $k ( sort keys %$data ) {
1572 my $v = $data->{$k};
1573 $self->_SWITCH_refkind($v, {
9d48860e 1574 ARRAYREF => sub {
bab725ce 1575 if ($self->{array_datatypes}) { # array datatype
1576 push @all_bind, $self->_bindtype($k, $v);
1577 }
1578 else { # literal SQL with bind
1579 my ($sql, @bind) = @$v;
1580 $self->_assert_bindval_matches_bindtype(@bind);
1581 push @all_bind, @bind;
1582 }
1583 },
1584 ARRAYREFREF => sub { # literal SQL with bind
1585 my ($sql, @bind) = @${$v};
1586 $self->_assert_bindval_matches_bindtype(@bind);
1587 push @all_bind, @bind;
1588 },
1589 SCALARREF => sub { # literal SQL without bind
1590 },
1591 SCALAR_or_UNDEF => sub {
1592 push @all_bind, $self->_bindtype($k, $v);
1593 },
1594 });
1595 }
1596
1597 return @all_bind;
96449e8e 1598}
1599
1600sub generate {
1601 my $self = shift;
1602
1603 my(@sql, @sqlq, @sqlv);
1604
1605 for (@_) {
1606 my $ref = ref $_;
1607 if ($ref eq 'HASH') {
1608 for my $k (sort keys %$_) {
1609 my $v = $_->{$k};
1610 my $r = ref $v;
1611 my $label = $self->_quote($k);
1612 if ($r eq 'ARRAY') {
fe3ae272 1613 # literal SQL with bind
1614 my ($sql, @bind) = @$v;
1615 $self->_assert_bindval_matches_bindtype(@bind);
96449e8e 1616 push @sqlq, "$label = $sql";
fe3ae272 1617 push @sqlv, @bind;
96449e8e 1618 } elsif ($r eq 'SCALAR') {
fe3ae272 1619 # literal SQL without bind
96449e8e 1620 push @sqlq, "$label = $$v";
9d48860e 1621 } else {
96449e8e 1622 push @sqlq, "$label = ?";
1623 push @sqlv, $self->_bindtype($k, $v);
1624 }
1625 }
1626 push @sql, $self->_sqlcase('set'), join ', ', @sqlq;
1627 } elsif ($ref eq 'ARRAY') {
1628 # unlike insert(), assume these are ONLY the column names, i.e. for SQL
1629 for my $v (@$_) {
1630 my $r = ref $v;
fe3ae272 1631 if ($r eq 'ARRAY') { # literal SQL with bind
1632 my ($sql, @bind) = @$v;
1633 $self->_assert_bindval_matches_bindtype(@bind);
1634 push @sqlq, $sql;
1635 push @sqlv, @bind;
1636 } elsif ($r eq 'SCALAR') { # literal SQL without bind
96449e8e 1637 # embedded literal SQL
1638 push @sqlq, $$v;
9d48860e 1639 } else {
96449e8e 1640 push @sqlq, '?';
1641 push @sqlv, $v;
1642 }
1643 }
1644 push @sql, '(' . join(', ', @sqlq) . ')';
1645 } elsif ($ref eq 'SCALAR') {
1646 # literal SQL
1647 push @sql, $$_;
1648 } else {
1649 # strings get case twiddled
1650 push @sql, $self->_sqlcase($_);
1651 }
1652 }
1653
1654 my $sql = join ' ', @sql;
1655
1656 # this is pretty tricky
1657 # if ask for an array, return ($stmt, @bind)
1658 # otherwise, s/?/shift @sqlv/ to put it inline
1659 if (wantarray) {
1660 return ($sql, @sqlv);
1661 } else {
1662 1 while $sql =~ s/\?/my $d = shift(@sqlv);
1663 ref $d ? $d->[1] : $d/e;
1664 return $sql;
1665 }
1666}
1667
1668
1669sub DESTROY { 1 }
1670
1671sub AUTOLOAD {
1672 # This allows us to check for a local, then _form, attr
1673 my $self = shift;
1674 my($name) = $AUTOLOAD =~ /.*::(.+)/;
1675 return $self->generate($name, @_);
1676}
1677
16781;
1679
1680
1681
1682__END__
32eab2da 1683
1684=head1 NAME
1685
1686SQL::Abstract - Generate SQL from Perl data structures
1687
1688=head1 SYNOPSIS
1689
1690 use SQL::Abstract;
1691
1692 my $sql = SQL::Abstract->new;
1693
85783f3c 1694 my($stmt, @bind) = $sql->select($source, \@fields, \%where, $order);
32eab2da 1695
1696 my($stmt, @bind) = $sql->insert($table, \%fieldvals || \@values);
1697
1698 my($stmt, @bind) = $sql->update($table, \%fieldvals, \%where);
1699
1700 my($stmt, @bind) = $sql->delete($table, \%where);
1701
1702 # Then, use these in your DBI statements
1703 my $sth = $dbh->prepare($stmt);
1704 $sth->execute(@bind);
1705
1706 # Just generate the WHERE clause
85783f3c 1707 my($stmt, @bind) = $sql->where(\%where, $order);
32eab2da 1708
1709 # Return values in the same order, for hashed queries
1710 # See PERFORMANCE section for more details
1711 my @bind = $sql->values(\%fieldvals);
1712
1713=head1 DESCRIPTION
1714
1715This module was inspired by the excellent L<DBIx::Abstract>.
1716However, in using that module I found that what I really wanted
1717to do was generate SQL, but still retain complete control over my
1718statement handles and use the DBI interface. So, I set out to
1719create an abstract SQL generation module.
1720
1721While based on the concepts used by L<DBIx::Abstract>, there are
1722several important differences, especially when it comes to WHERE
1723clauses. I have modified the concepts used to make the SQL easier
1724to generate from Perl data structures and, IMO, more intuitive.
1725The underlying idea is for this module to do what you mean, based
1726on the data structures you provide it. The big advantage is that
1727you don't have to modify your code every time your data changes,
1728as this module figures it out.
1729
1730To begin with, an SQL INSERT is as easy as just specifying a hash
1731of C<key=value> pairs:
1732
1733 my %data = (
1734 name => 'Jimbo Bobson',
1735 phone => '123-456-7890',
1736 address => '42 Sister Lane',
1737 city => 'St. Louis',
1738 state => 'Louisiana',
1739 );
1740
1741The SQL can then be generated with this:
1742
1743 my($stmt, @bind) = $sql->insert('people', \%data);
1744
1745Which would give you something like this:
1746
1747 $stmt = "INSERT INTO people
1748 (address, city, name, phone, state)
1749 VALUES (?, ?, ?, ?, ?)";
1750 @bind = ('42 Sister Lane', 'St. Louis', 'Jimbo Bobson',
1751 '123-456-7890', 'Louisiana');
1752
1753These are then used directly in your DBI code:
1754
1755 my $sth = $dbh->prepare($stmt);
1756 $sth->execute(@bind);
1757
96449e8e 1758=head2 Inserting and Updating Arrays
1759
1760If your database has array types (like for example Postgres),
1761activate the special option C<< array_datatypes => 1 >>
9d48860e 1762when creating the C<SQL::Abstract> object.
96449e8e 1763Then you may use an arrayref to insert and update database array types:
1764
1765 my $sql = SQL::Abstract->new(array_datatypes => 1);
1766 my %data = (
1767 planets => [qw/Mercury Venus Earth Mars/]
1768 );
9d48860e 1769
96449e8e 1770 my($stmt, @bind) = $sql->insert('solar_system', \%data);
1771
1772This results in:
1773
1774 $stmt = "INSERT INTO solar_system (planets) VALUES (?)"
1775
1776 @bind = (['Mercury', 'Venus', 'Earth', 'Mars']);
1777
1778
1779=head2 Inserting and Updating SQL
1780
1781In order to apply SQL functions to elements of your C<%data> you may
1782specify a reference to an arrayref for the given hash value. For example,
1783if you need to execute the Oracle C<to_date> function on a value, you can
1784say something like this:
32eab2da 1785
1786 my %data = (
1787 name => 'Bill',
3ae1c5e2 1788 date_entered => \[ "to_date(?,'MM/DD/YYYY')", "03/02/2003" ],
9d48860e 1789 );
32eab2da 1790
1791The first value in the array is the actual SQL. Any other values are
1792optional and would be included in the bind values array. This gives
1793you:
1794
1795 my($stmt, @bind) = $sql->insert('people', \%data);
1796
9d48860e 1797 $stmt = "INSERT INTO people (name, date_entered)
32eab2da 1798 VALUES (?, to_date(?,'MM/DD/YYYY'))";
1799 @bind = ('Bill', '03/02/2003');
1800
1801An UPDATE is just as easy, all you change is the name of the function:
1802
1803 my($stmt, @bind) = $sql->update('people', \%data);
1804
1805Notice that your C<%data> isn't touched; the module will generate
1806the appropriately quirky SQL for you automatically. Usually you'll
1807want to specify a WHERE clause for your UPDATE, though, which is
1808where handling C<%where> hashes comes in handy...
1809
96449e8e 1810=head2 Complex where statements
1811
32eab2da 1812This module can generate pretty complicated WHERE statements
1813easily. For example, simple C<key=value> pairs are taken to mean
1814equality, and if you want to see if a field is within a set
1815of values, you can use an arrayref. Let's say we wanted to
1816SELECT some data based on this criteria:
1817
1818 my %where = (
1819 requestor => 'inna',
1820 worker => ['nwiger', 'rcwe', 'sfz'],
1821 status => { '!=', 'completed' }
1822 );
1823
1824 my($stmt, @bind) = $sql->select('tickets', '*', \%where);
1825
1826The above would give you something like this:
1827
1828 $stmt = "SELECT * FROM tickets WHERE
1829 ( requestor = ? ) AND ( status != ? )
1830 AND ( worker = ? OR worker = ? OR worker = ? )";
1831 @bind = ('inna', 'completed', 'nwiger', 'rcwe', 'sfz');
1832
1833Which you could then use in DBI code like so:
1834
1835 my $sth = $dbh->prepare($stmt);
1836 $sth->execute(@bind);
1837
1838Easy, eh?
1839
0da0fe34 1840=head1 METHODS
32eab2da 1841
13cc86af 1842The methods are simple. There's one for every major SQL operation,
32eab2da 1843and a constructor you use first. The arguments are specified in a
13cc86af 1844similar order for each method (table, then fields, then a where
32eab2da 1845clause) to try and simplify things.
1846
32eab2da 1847=head2 new(option => 'value')
1848
1849The C<new()> function takes a list of options and values, and returns
1850a new B<SQL::Abstract> object which can then be used to generate SQL
1851through the methods below. The options accepted are:
1852
1853=over
1854
1855=item case
1856
1857If set to 'lower', then SQL will be generated in all lowercase. By
1858default SQL is generated in "textbook" case meaning something like:
1859
1860 SELECT a_field FROM a_table WHERE some_field LIKE '%someval%'
1861
96449e8e 1862Any setting other than 'lower' is ignored.
1863
32eab2da 1864=item cmp
1865
1866This determines what the default comparison operator is. By default
1867it is C<=>, meaning that a hash like this:
1868
1869 %where = (name => 'nwiger', email => 'nate@wiger.org');
1870
1871Will generate SQL like this:
1872
1873 WHERE name = 'nwiger' AND email = 'nate@wiger.org'
1874
1875However, you may want loose comparisons by default, so if you set
1876C<cmp> to C<like> you would get SQL such as:
1877
1878 WHERE name like 'nwiger' AND email like 'nate@wiger.org'
1879
3af02ccb 1880You can also override the comparison on an individual basis - see
32eab2da 1881the huge section on L</"WHERE CLAUSES"> at the bottom.
1882
96449e8e 1883=item sqltrue, sqlfalse
1884
1885Expressions for inserting boolean values within SQL statements.
6e0c6552 1886By default these are C<1=1> and C<1=0>. They are used
1887by the special operators C<-in> and C<-not_in> for generating
1888correct SQL even when the argument is an empty array (see below).
96449e8e 1889
32eab2da 1890=item logic
1891
1892This determines the default logical operator for multiple WHERE
7cac25e6 1893statements in arrays or hashes. If absent, the default logic is "or"
1894for arrays, and "and" for hashes. This means that a WHERE
32eab2da 1895array of the form:
1896
1897 @where = (
9d48860e 1898 event_date => {'>=', '2/13/99'},
1899 event_date => {'<=', '4/24/03'},
32eab2da 1900 );
1901
7cac25e6 1902will generate SQL like this:
32eab2da 1903
1904 WHERE event_date >= '2/13/99' OR event_date <= '4/24/03'
1905
1906This is probably not what you want given this query, though (look
1907at the dates). To change the "OR" to an "AND", simply specify:
1908
1909 my $sql = SQL::Abstract->new(logic => 'and');
1910
1911Which will change the above C<WHERE> to:
1912
1913 WHERE event_date >= '2/13/99' AND event_date <= '4/24/03'
1914
96449e8e 1915The logic can also be changed locally by inserting
7cac25e6 1916a modifier in front of an arrayref :
96449e8e 1917
9d48860e 1918 @where = (-and => [event_date => {'>=', '2/13/99'},
7cac25e6 1919 event_date => {'<=', '4/24/03'} ]);
96449e8e 1920
1921See the L</"WHERE CLAUSES"> section for explanations.
1922
32eab2da 1923=item convert
1924
1925This will automatically convert comparisons using the specified SQL
1926function for both column and value. This is mostly used with an argument
1927of C<upper> or C<lower>, so that the SQL will have the effect of
1928case-insensitive "searches". For example, this:
1929
1930 $sql = SQL::Abstract->new(convert => 'upper');
1931 %where = (keywords => 'MaKe iT CAse inSeNSItive');
1932
1933Will turn out the following SQL:
1934
1935 WHERE upper(keywords) like upper('MaKe iT CAse inSeNSItive')
1936
1937The conversion can be C<upper()>, C<lower()>, or any other SQL function
1938that can be applied symmetrically to fields (actually B<SQL::Abstract> does
1939not validate this option; it will just pass through what you specify verbatim).
1940
1941=item bindtype
1942
1943This is a kludge because many databases suck. For example, you can't
1944just bind values using DBI's C<execute()> for Oracle C<CLOB> or C<BLOB> fields.
1945Instead, you have to use C<bind_param()>:
1946
1947 $sth->bind_param(1, 'reg data');
1948 $sth->bind_param(2, $lots, {ora_type => ORA_CLOB});
1949
1950The problem is, B<SQL::Abstract> will normally just return a C<@bind> array,
1951which loses track of which field each slot refers to. Fear not.
1952
1953If you specify C<bindtype> in new, you can determine how C<@bind> is returned.
1954Currently, you can specify either C<normal> (default) or C<columns>. If you
1955specify C<columns>, you will get an array that looks like this:
1956
1957 my $sql = SQL::Abstract->new(bindtype => 'columns');
1958 my($stmt, @bind) = $sql->insert(...);
1959
1960 @bind = (
1961 [ 'column1', 'value1' ],
1962 [ 'column2', 'value2' ],
1963 [ 'column3', 'value3' ],
1964 );
1965
1966You can then iterate through this manually, using DBI's C<bind_param()>.
e3f9dff4 1967
32eab2da 1968 $sth->prepare($stmt);
1969 my $i = 1;
1970 for (@bind) {
1971 my($col, $data) = @$_;
1972 if ($col eq 'details' || $col eq 'comments') {
1973 $sth->bind_param($i, $data, {ora_type => ORA_CLOB});
1974 } elsif ($col eq 'image') {
1975 $sth->bind_param($i, $data, {ora_type => ORA_BLOB});
1976 } else {
1977 $sth->bind_param($i, $data);
1978 }
1979 $i++;
1980 }
1981 $sth->execute; # execute without @bind now
1982
1983Now, why would you still use B<SQL::Abstract> if you have to do this crap?
1984Basically, the advantage is still that you don't have to care which fields
1985are or are not included. You could wrap that above C<for> loop in a simple
1986sub called C<bind_fields()> or something and reuse it repeatedly. You still
1987get a layer of abstraction over manual SQL specification.
1988
3ae1c5e2 1989Note that if you set L</bindtype> to C<columns>, the C<\[ $sql, @bind ]>
deb148a2 1990construct (see L</Literal SQL with placeholders and bind values (subqueries)>)
1991will expect the bind values in this format.
1992
32eab2da 1993=item quote_char
1994
1995This is the character that a table or column name will be quoted
9d48860e 1996with. By default this is an empty string, but you could set it to
32eab2da 1997the character C<`>, to generate SQL like this:
1998
1999 SELECT `a_field` FROM `a_table` WHERE `some_field` LIKE '%someval%'
2000
96449e8e 2001Alternatively, you can supply an array ref of two items, the first being the left
2002hand quote character, and the second the right hand quote character. For
2003example, you could supply C<['[',']']> for SQL Server 2000 compliant quotes
2004that generates SQL like this:
2005
2006 SELECT [a_field] FROM [a_table] WHERE [some_field] LIKE '%someval%'
2007
9d48860e 2008Quoting is useful if you have tables or columns names that are reserved
96449e8e 2009words in your database's SQL dialect.
32eab2da 2010
46be4313 2011=item escape_char
2012
2013This is the character that will be used to escape L</quote_char>s appearing
2014in an identifier before it has been quoted.
2015
80790166 2016The parameter default in case of a single L</quote_char> character is the quote
46be4313 2017character itself.
2018
2019When opening-closing-style quoting is used (L</quote_char> is an arrayref)
2020this parameter defaults to the B<closing (right)> L</quote_char>. Occurences
2021of the B<opening (left)> L</quote_char> within the identifier are currently left
2022untouched. The default for opening-closing-style quotes may change in future
2023versions, thus you are B<strongly encouraged> to specify the escape character
2024explicitly.
2025
32eab2da 2026=item name_sep
2027
2028This is the character that separates a table and column name. It is
2029necessary to specify this when the C<quote_char> option is selected,
2030so that tables and column names can be individually quoted like this:
2031
2032 SELECT `table`.`one_field` FROM `table` WHERE `table`.`other_field` = 1
2033
b6251592 2034=item injection_guard
2035
2036A regular expression C<qr/.../> that is applied to any C<-function> and unquoted
2037column name specified in a query structure. This is a safety mechanism to avoid
2038injection attacks when mishandling user input e.g.:
2039
2040 my %condition_as_column_value_pairs = get_values_from_user();
2041 $sqla->select( ... , \%condition_as_column_value_pairs );
2042
2043If the expression matches an exception is thrown. Note that literal SQL
2044supplied via C<\'...'> or C<\['...']> is B<not> checked in any way.
2045
2046Defaults to checking for C<;> and the C<GO> keyword (TransactSQL)
2047
96449e8e 2048=item array_datatypes
32eab2da 2049
9d48860e 2050When this option is true, arrayrefs in INSERT or UPDATE are
2051interpreted as array datatypes and are passed directly
96449e8e 2052to the DBI layer.
2053When this option is false, arrayrefs are interpreted
2054as literal SQL, just like refs to arrayrefs
2055(but this behavior is for backwards compatibility; when writing
2056new queries, use the "reference to arrayref" syntax
2057for literal SQL).
32eab2da 2058
32eab2da 2059
96449e8e 2060=item special_ops
32eab2da 2061
9d48860e 2062Takes a reference to a list of "special operators"
96449e8e 2063to extend the syntax understood by L<SQL::Abstract>.
2064See section L</"SPECIAL OPERATORS"> for details.
32eab2da 2065
59f23b3d 2066=item unary_ops
2067
9d48860e 2068Takes a reference to a list of "unary operators"
59f23b3d 2069to extend the syntax understood by L<SQL::Abstract>.
2070See section L</"UNARY OPERATORS"> for details.
2071
32eab2da 2072
32eab2da 2073
96449e8e 2074=back
32eab2da 2075
02288357 2076=head2 insert($table, \@values || \%fieldvals, \%options)
32eab2da 2077
2078This is the simplest function. You simply give it a table name
2079and either an arrayref of values or hashref of field/value pairs.
2080It returns an SQL INSERT statement and a list of bind values.
96449e8e 2081See the sections on L</"Inserting and Updating Arrays"> and
2082L</"Inserting and Updating SQL"> for information on how to insert
2083with those data types.
32eab2da 2084
02288357 2085The optional C<\%options> hash reference may contain additional
2086options to generate the insert SQL. Currently supported options
2087are:
2088
2089=over 4
2090
2091=item returning
2092
2093Takes either a scalar of raw SQL fields, or an array reference of
2094field names, and adds on an SQL C<RETURNING> statement at the end.
2095This allows you to return data generated by the insert statement
2096(such as row IDs) without performing another C<SELECT> statement.
2097Note, however, this is not part of the SQL standard and may not
2098be supported by all database engines.
2099
2100=back
2101
95904db5 2102=head2 update($table, \%fieldvals, \%where, \%options)
32eab2da 2103
2104This takes a table, hashref of field/value pairs, and an optional
86298391 2105hashref L<WHERE clause|/WHERE CLAUSES>. It returns an SQL UPDATE function and a list
32eab2da 2106of bind values.
96449e8e 2107See the sections on L</"Inserting and Updating Arrays"> and
2108L</"Inserting and Updating SQL"> for information on how to insert
2109with those data types.
32eab2da 2110
95904db5 2111The optional C<\%options> hash reference may contain additional
2112options to generate the update SQL. Currently supported options
2113are:
2114
2115=over 4
2116
2117=item returning
2118
2119See the C<returning> option to
2120L<insert|/insert($table, \@values || \%fieldvals, \%options)>.
2121
2122=back
2123
96449e8e 2124=head2 select($source, $fields, $where, $order)
32eab2da 2125
9d48860e 2126This returns a SQL SELECT statement and associated list of bind values, as
96449e8e 2127specified by the arguments :
32eab2da 2128
96449e8e 2129=over
32eab2da 2130
96449e8e 2131=item $source
32eab2da 2132
9d48860e 2133Specification of the 'FROM' part of the statement.
96449e8e 2134The argument can be either a plain scalar (interpreted as a table
2135name, will be quoted), or an arrayref (interpreted as a list
2136of table names, joined by commas, quoted), or a scalarref
2137(literal table name, not quoted), or a ref to an arrayref
2138(list of literal table names, joined by commas, not quoted).
32eab2da 2139
96449e8e 2140=item $fields
32eab2da 2141
9d48860e 2142Specification of the list of fields to retrieve from
96449e8e 2143the source.
2144The argument can be either an arrayref (interpreted as a list
9d48860e 2145of field names, will be joined by commas and quoted), or a
96449e8e 2146plain scalar (literal SQL, not quoted).
521647e7 2147Please observe that this API is not as flexible as that of
2148the first argument C<$source>, for backwards compatibility reasons.
32eab2da 2149
96449e8e 2150=item $where
32eab2da 2151
96449e8e 2152Optional argument to specify the WHERE part of the query.
2153The argument is most often a hashref, but can also be
9d48860e 2154an arrayref or plain scalar --
96449e8e 2155see section L<WHERE clause|/"WHERE CLAUSES"> for details.
32eab2da 2156
96449e8e 2157=item $order
32eab2da 2158
96449e8e 2159Optional argument to specify the ORDER BY part of the query.
9d48860e 2160The argument can be a scalar, a hashref or an arrayref
96449e8e 2161-- see section L<ORDER BY clause|/"ORDER BY CLAUSES">
2162for details.
32eab2da 2163
96449e8e 2164=back
32eab2da 2165
32eab2da 2166
85327cd5 2167=head2 delete($table, \%where, \%options)
32eab2da 2168
86298391 2169This takes a table name and optional hashref L<WHERE clause|/WHERE CLAUSES>.
32eab2da 2170It returns an SQL DELETE statement and list of bind values.
2171
85327cd5 2172The optional C<\%options> hash reference may contain additional
2173options to generate the delete SQL. Currently supported options
2174are:
2175
2176=over 4
2177
2178=item returning
2179
2180See the C<returning> option to
2181L<insert|/insert($table, \@values || \%fieldvals, \%options)>.
2182
2183=back
2184
85783f3c 2185=head2 where(\%where, $order)
32eab2da 2186
2187This is used to generate just the WHERE clause. For example,
2188if you have an arbitrary data structure and know what the
2189rest of your SQL is going to look like, but want an easy way
2190to produce a WHERE clause, use this. It returns an SQL WHERE
2191clause and list of bind values.
2192
32eab2da 2193
2194=head2 values(\%data)
2195
2196This just returns the values from the hash C<%data>, in the same
2197order that would be returned from any of the other above queries.
2198Using this allows you to markedly speed up your queries if you
2199are affecting lots of rows. See below under the L</"PERFORMANCE"> section.
2200
32eab2da 2201=head2 generate($any, 'number', $of, \@data, $struct, \%types)
2202
2203Warning: This is an experimental method and subject to change.
2204
2205This returns arbitrarily generated SQL. It's a really basic shortcut.
2206It will return two different things, depending on return context:
2207
2208 my($stmt, @bind) = $sql->generate('create table', \$table, \@fields);
2209 my $stmt_and_val = $sql->generate('create table', \$table, \@fields);
2210
2211These would return the following:
2212
2213 # First calling form
2214 $stmt = "CREATE TABLE test (?, ?)";
2215 @bind = (field1, field2);
2216
2217 # Second calling form
2218 $stmt_and_val = "CREATE TABLE test (field1, field2)";
2219
2220Depending on what you're trying to do, it's up to you to choose the correct
2221format. In this example, the second form is what you would want.
2222
2223By the same token:
2224
2225 $sql->generate('alter session', { nls_date_format => 'MM/YY' });
2226
2227Might give you:
2228
2229 ALTER SESSION SET nls_date_format = 'MM/YY'
2230
2231You get the idea. Strings get their case twiddled, but everything
2232else remains verbatim.
2233
0da0fe34 2234=head1 EXPORTABLE FUNCTIONS
2235
2236=head2 is_plain_value
2237
2238Determines if the supplied argument is a plain value as understood by this
2239module:
2240
2241=over
2242
2243=item * The value is C<undef>
2244
2245=item * The value is a non-reference
2246
2247=item * The value is an object with stringification overloading
2248
2249=item * The value is of the form C<< { -value => $anything } >>
2250
2251=back
2252
966200cc 2253On failure returns C<undef>, on sucess returns a B<scalar> reference
2254to the original supplied argument.
0da0fe34 2255
843a94b5 2256=over
2257
2258=item * Note
2259
2260The stringification overloading detection is rather advanced: it takes
2261into consideration not only the presence of a C<""> overload, but if that
2262fails also checks for enabled
2263L<autogenerated versions of C<"">|overload/Magic Autogeneration>, based
2264on either C<0+> or C<bool>.
2265
2266Unfortunately testing in the field indicates that this
2267detection B<< may tickle a latent bug in perl versions before 5.018 >>,
2268but only when very large numbers of stringifying objects are involved.
2269At the time of writing ( Sep 2014 ) there is no clear explanation of
2270the direct cause, nor is there a manageably small test case that reliably
2271reproduces the problem.
2272
2273If you encounter any of the following exceptions in B<random places within
2274your application stack> - this module may be to blame:
2275
2276 Operation "ne": no method found,
2277 left argument in overloaded package <something>,
2278 right argument in overloaded package <something>
2279
2280or perhaps even
2281
2282 Stub found while resolving method "???" overloading """" in package <something>
2283
2284If you fall victim to the above - please attempt to reduce the problem
2285to something that could be sent to the L<SQL::Abstract developers
1f490ae4 2286|DBIx::Class/GETTING HELP/SUPPORT>
843a94b5 2287(either publicly or privately). As a workaround in the meantime you can
2288set C<$ENV{SQLA_ISVALUE_IGNORE_AUTOGENERATED_STRINGIFICATION}> to a true
2289value, which will most likely eliminate your problem (at the expense of
2290not being able to properly detect exotic forms of stringification).
2291
2292This notice and environment variable will be removed in a future version,
2293as soon as the underlying problem is found and a reliable workaround is
2294devised.
2295
2296=back
2297
0da0fe34 2298=head2 is_literal_value
2299
2300Determines if the supplied argument is a literal value as understood by this
2301module:
2302
2303=over
2304
2305=item * C<\$sql_string>
2306
2307=item * C<\[ $sql_string, @bind_values ]>
2308
0da0fe34 2309=back
2310
966200cc 2311On failure returns C<undef>, on sucess returns an B<array> reference
2312containing the unpacked version of the supplied literal SQL and bind values.
0da0fe34 2313
32eab2da 2314=head1 WHERE CLAUSES
2315
96449e8e 2316=head2 Introduction
2317
32eab2da 2318This module uses a variation on the idea from L<DBIx::Abstract>. It
2319is B<NOT>, repeat I<not> 100% compatible. B<The main logic of this
2320module is that things in arrays are OR'ed, and things in hashes
2321are AND'ed.>
2322
2323The easiest way to explain is to show lots of examples. After
2324each C<%where> hash shown, it is assumed you used:
2325
2326 my($stmt, @bind) = $sql->where(\%where);
2327
2328However, note that the C<%where> hash can be used directly in any
2329of the other functions as well, as described above.
2330
96449e8e 2331=head2 Key-value pairs
2332
32eab2da 2333So, let's get started. To begin, a simple hash:
2334
2335 my %where = (
2336 user => 'nwiger',
2337 status => 'completed'
2338 );
2339
2340Is converted to SQL C<key = val> statements:
2341
2342 $stmt = "WHERE user = ? AND status = ?";
2343 @bind = ('nwiger', 'completed');
2344
2345One common thing I end up doing is having a list of values that
2346a field can be in. To do this, simply specify a list inside of
2347an arrayref:
2348
2349 my %where = (
2350 user => 'nwiger',
2351 status => ['assigned', 'in-progress', 'pending'];
2352 );
2353
2354This simple code will create the following:
9d48860e 2355
32eab2da 2356 $stmt = "WHERE user = ? AND ( status = ? OR status = ? OR status = ? )";
2357 @bind = ('nwiger', 'assigned', 'in-progress', 'pending');
2358
9d48860e 2359A field associated to an empty arrayref will be considered a
7cac25e6 2360logical false and will generate 0=1.
8a68b5be 2361
b864ba9b 2362=head2 Tests for NULL values
2363
2364If the value part is C<undef> then this is converted to SQL <IS NULL>
2365
2366 my %where = (
2367 user => 'nwiger',
2368 status => undef,
2369 );
2370
2371becomes:
2372
2373 $stmt = "WHERE user = ? AND status IS NULL";
2374 @bind = ('nwiger');
2375
e9614080 2376To test if a column IS NOT NULL:
2377
2378 my %where = (
2379 user => 'nwiger',
2380 status => { '!=', undef },
2381 );
cc422895 2382
6e0c6552 2383=head2 Specific comparison operators
96449e8e 2384
32eab2da 2385If you want to specify a different type of operator for your comparison,
2386you can use a hashref for a given column:
2387
2388 my %where = (
2389 user => 'nwiger',
2390 status => { '!=', 'completed' }
2391 );
2392
2393Which would generate:
2394
2395 $stmt = "WHERE user = ? AND status != ?";
2396 @bind = ('nwiger', 'completed');
2397
2398To test against multiple values, just enclose the values in an arrayref:
2399
96449e8e 2400 status => { '=', ['assigned', 'in-progress', 'pending'] };
2401
f2d5020d 2402Which would give you:
96449e8e 2403
2404 "WHERE status = ? OR status = ? OR status = ?"
2405
2406
2407The hashref can also contain multiple pairs, in which case it is expanded
32eab2da 2408into an C<AND> of its elements:
2409
2410 my %where = (
2411 user => 'nwiger',
2412 status => { '!=', 'completed', -not_like => 'pending%' }
2413 );
2414
2415 # Or more dynamically, like from a form
2416 $where{user} = 'nwiger';
2417 $where{status}{'!='} = 'completed';
2418 $where{status}{'-not_like'} = 'pending%';
2419
2420 # Both generate this
2421 $stmt = "WHERE user = ? AND status != ? AND status NOT LIKE ?";
2422 @bind = ('nwiger', 'completed', 'pending%');
2423
96449e8e 2424
32eab2da 2425To get an OR instead, you can combine it with the arrayref idea:
2426
2427 my %where => (
2428 user => 'nwiger',
1a6f2a03 2429 priority => [ { '=', 2 }, { '>', 5 } ]
32eab2da 2430 );
2431
2432Which would generate:
2433
1a6f2a03 2434 $stmt = "WHERE ( priority = ? OR priority > ? ) AND user = ?";
2435 @bind = ('2', '5', 'nwiger');
32eab2da 2436
44b9e502 2437If you want to include literal SQL (with or without bind values), just use a
13cc86af 2438scalar reference or reference to an arrayref as the value:
44b9e502 2439
2440 my %where = (
2441 date_entered => { '>' => \["to_date(?, 'MM/DD/YYYY')", "11/26/2008"] },
2442 date_expires => { '<' => \"now()" }
2443 );
2444
2445Which would generate:
2446
13cc86af 2447 $stmt = "WHERE date_entered > to_date(?, 'MM/DD/YYYY') AND date_expires < now()";
44b9e502 2448 @bind = ('11/26/2008');
2449
96449e8e 2450
2451=head2 Logic and nesting operators
2452
2453In the example above,
2454there is a subtle trap if you want to say something like
32eab2da 2455this (notice the C<AND>):
2456
2457 WHERE priority != ? AND priority != ?
2458
2459Because, in Perl you I<can't> do this:
2460
13cc86af 2461 priority => { '!=' => 2, '!=' => 1 }
32eab2da 2462
2463As the second C<!=> key will obliterate the first. The solution
2464is to use the special C<-modifier> form inside an arrayref:
2465
9d48860e 2466 priority => [ -and => {'!=', 2},
96449e8e 2467 {'!=', 1} ]
2468
32eab2da 2469
2470Normally, these would be joined by C<OR>, but the modifier tells it
2471to use C<AND> instead. (Hint: You can use this in conjunction with the
2472C<logic> option to C<new()> in order to change the way your queries
2473work by default.) B<Important:> Note that the C<-modifier> goes
2474B<INSIDE> the arrayref, as an extra first element. This will
2475B<NOT> do what you think it might:
2476
2477 priority => -and => [{'!=', 2}, {'!=', 1}] # WRONG!
2478
2479Here is a quick list of equivalencies, since there is some overlap:
2480
2481 # Same
2482 status => {'!=', 'completed', 'not like', 'pending%' }
2483 status => [ -and => {'!=', 'completed'}, {'not like', 'pending%'}]
2484
2485 # Same
2486 status => {'=', ['assigned', 'in-progress']}
2487 status => [ -or => {'=', 'assigned'}, {'=', 'in-progress'}]
2488 status => [ {'=', 'assigned'}, {'=', 'in-progress'} ]
2489
e3f9dff4 2490
2491
96449e8e 2492=head2 Special operators : IN, BETWEEN, etc.
2493
32eab2da 2494You can also use the hashref format to compare a list of fields using the
2495C<IN> comparison operator, by specifying the list as an arrayref:
2496
2497 my %where = (
2498 status => 'completed',
2499 reportid => { -in => [567, 2335, 2] }
2500 );
2501
2502Which would generate:
2503
2504 $stmt = "WHERE status = ? AND reportid IN (?,?,?)";
2505 @bind = ('completed', '567', '2335', '2');
2506
9d48860e 2507The reverse operator C<-not_in> generates SQL C<NOT IN> and is used in
96449e8e 2508the same way.
2509
6e0c6552 2510If the argument to C<-in> is an empty array, 'sqlfalse' is generated
2511(by default : C<1=0>). Similarly, C<< -not_in => [] >> generates
2512'sqltrue' (by default : C<1=1>).
2513
e41c3bdd 2514In addition to the array you can supply a chunk of literal sql or
2515literal sql with bind:
6e0c6552 2516
e41c3bdd 2517 my %where = {
2518 customer => { -in => \[
2519 'SELECT cust_id FROM cust WHERE balance > ?',
2520 2000,
2521 ],
2522 status => { -in => \'SELECT status_codes FROM states' },
2523 };
6e0c6552 2524
e41c3bdd 2525would generate:
2526
2527 $stmt = "WHERE (
2528 customer IN ( SELECT cust_id FROM cust WHERE balance > ? )
2529 AND status IN ( SELECT status_codes FROM states )
2530 )";
2531 @bind = ('2000');
2532
0dfd2442 2533Finally, if the argument to C<-in> is not a reference, it will be
2534treated as a single-element array.
e41c3bdd 2535
2536Another pair of operators is C<-between> and C<-not_between>,
96449e8e 2537used with an arrayref of two values:
32eab2da 2538
2539 my %where = (
2540 user => 'nwiger',
2541 completion_date => {
2542 -not_between => ['2002-10-01', '2003-02-06']
2543 }
2544 );
2545
2546Would give you:
2547
2548 WHERE user = ? AND completion_date NOT BETWEEN ( ? AND ? )
2549
e41c3bdd 2550Just like with C<-in> all plausible combinations of literal SQL
2551are possible:
2552
2553 my %where = {
2554 start0 => { -between => [ 1, 2 ] },
2555 start1 => { -between => \["? AND ?", 1, 2] },
2556 start2 => { -between => \"lower(x) AND upper(y)" },
9d48860e 2557 start3 => { -between => [
e41c3bdd 2558 \"lower(x)",
2559 \["upper(?)", 'stuff' ],
2560 ] },
2561 };
2562
2563Would give you:
2564
2565 $stmt = "WHERE (
2566 ( start0 BETWEEN ? AND ? )
2567 AND ( start1 BETWEEN ? AND ? )
2568 AND ( start2 BETWEEN lower(x) AND upper(y) )
2569 AND ( start3 BETWEEN lower(x) AND upper(?) )
2570 )";
2571 @bind = (1, 2, 1, 2, 'stuff');
2572
2573
9d48860e 2574These are the two builtin "special operators"; but the
96449e8e 2575list can be expanded : see section L</"SPECIAL OPERATORS"> below.
2576
59f23b3d 2577=head2 Unary operators: bool
97a920ef 2578
2579If you wish to test against boolean columns or functions within your
2580database you can use the C<-bool> and C<-not_bool> operators. For
2581example to test the column C<is_user> being true and the column
827bb0eb 2582C<is_enabled> being false you would use:-
97a920ef 2583
2584 my %where = (
2585 -bool => 'is_user',
2586 -not_bool => 'is_enabled',
2587 );
2588
2589Would give you:
2590
277b5d3f 2591 WHERE is_user AND NOT is_enabled
97a920ef 2592
0b604e9d 2593If a more complex combination is required, testing more conditions,
2594then you should use the and/or operators:-
2595
2596 my %where = (
2597 -and => [
2598 -bool => 'one',
23401b81 2599 -not_bool => { two=> { -rlike => 'bar' } },
2600 -not_bool => { three => [ { '=', 2 }, { '>', 5 } ] },
0b604e9d 2601 ],
2602 );
2603
2604Would give you:
2605
23401b81 2606 WHERE
2607 one
2608 AND
2609 (NOT two RLIKE ?)
2610 AND
2611 (NOT ( three = ? OR three > ? ))
97a920ef 2612
2613
107b72f1 2614=head2 Nested conditions, -and/-or prefixes
96449e8e 2615
32eab2da 2616So far, we've seen how multiple conditions are joined with a top-level
2617C<AND>. We can change this by putting the different conditions we want in
2618hashes and then putting those hashes in an array. For example:
2619
2620 my @where = (
2621 {
2622 user => 'nwiger',
2623 status => { -like => ['pending%', 'dispatched'] },
2624 },
2625 {
2626 user => 'robot',
2627 status => 'unassigned',
2628 }
2629 );
2630
2631This data structure would create the following:
2632
2633 $stmt = "WHERE ( user = ? AND ( status LIKE ? OR status LIKE ? ) )
2634 OR ( user = ? AND status = ? ) )";
2635 @bind = ('nwiger', 'pending', 'dispatched', 'robot', 'unassigned');
2636
107b72f1 2637
48d9f5f8 2638Clauses in hashrefs or arrayrefs can be prefixed with an C<-and> or C<-or>
2639to change the logic inside :
32eab2da 2640
2641 my @where = (
2642 -and => [
2643 user => 'nwiger',
48d9f5f8 2644 [
2645 -and => [ workhrs => {'>', 20}, geo => 'ASIA' ],
2646 -or => { workhrs => {'<', 50}, geo => 'EURO' },
32eab2da 2647 ],
2648 ],
2649 );
2650
2651That would yield:
2652
13cc86af 2653 $stmt = "WHERE ( user = ?
2654 AND ( ( workhrs > ? AND geo = ? )
2655 OR ( workhrs < ? OR geo = ? ) ) )";
2656 @bind = ('nwiger', '20', 'ASIA', '50', 'EURO');
107b72f1 2657
cc422895 2658=head3 Algebraic inconsistency, for historical reasons
107b72f1 2659
7cac25e6 2660C<Important note>: when connecting several conditions, the C<-and->|C<-or>
2661operator goes C<outside> of the nested structure; whereas when connecting
2662several constraints on one column, the C<-and> operator goes
2663C<inside> the arrayref. Here is an example combining both features :
2664
2665 my @where = (
2666 -and => [a => 1, b => 2],
2667 -or => [c => 3, d => 4],
2668 e => [-and => {-like => 'foo%'}, {-like => '%bar'} ]
2669 )
2670
2671yielding
2672
9d48860e 2673 WHERE ( ( ( a = ? AND b = ? )
2674 OR ( c = ? OR d = ? )
7cac25e6 2675 OR ( e LIKE ? AND e LIKE ? ) ) )
2676
107b72f1 2677This difference in syntax is unfortunate but must be preserved for
2678historical reasons. So be careful : the two examples below would
2679seem algebraically equivalent, but they are not
2680
a948b1fe 2681 { col => [ -and =>
2682 { -like => 'foo%' },
2683 { -like => '%bar' },
2684 ] }
107b72f1 2685 # yields : WHERE ( ( col LIKE ? AND col LIKE ? ) )
2686
a948b1fe 2687 [ -and =>
2688 { col => { -like => 'foo%' } },
2689 { col => { -like => '%bar' } },
2690 ]
107b72f1 2691 # yields : WHERE ( ( col LIKE ? OR col LIKE ? ) )
2692
7cac25e6 2693
cc422895 2694=head2 Literal SQL and value type operators
96449e8e 2695
cc422895 2696The basic premise of SQL::Abstract is that in WHERE specifications the "left
2697side" is a column name and the "right side" is a value (normally rendered as
2698a placeholder). This holds true for both hashrefs and arrayref pairs as you
2699see in the L</WHERE CLAUSES> examples above. Sometimes it is necessary to
2700alter this behavior. There are several ways of doing so.
e9614080 2701
cc422895 2702=head3 -ident
2703
2704This is a virtual operator that signals the string to its right side is an
2705identifier (a column name) and not a value. For example to compare two
2706columns you would write:
32eab2da 2707
e9614080 2708 my %where = (
2709 priority => { '<', 2 },
cc422895 2710 requestor => { -ident => 'submitter' },
e9614080 2711 );
2712
2713which creates:
2714
2715 $stmt = "WHERE priority < ? AND requestor = submitter";
2716 @bind = ('2');
2717
cc422895 2718If you are maintaining legacy code you may see a different construct as
2719described in L</Deprecated usage of Literal SQL>, please use C<-ident> in new
2720code.
2721
2722=head3 -value
e9614080 2723
cc422895 2724This is a virtual operator that signals that the construct to its right side
2725is a value to be passed to DBI. This is for example necessary when you want
2726to write a where clause against an array (for RDBMS that support such
2727datatypes). For example:
e9614080 2728
32eab2da 2729 my %where = (
cc422895 2730 array => { -value => [1, 2, 3] }
32eab2da 2731 );
2732
cc422895 2733will result in:
32eab2da 2734
cc422895 2735 $stmt = 'WHERE array = ?';
2736 @bind = ([1, 2, 3]);
32eab2da 2737
cc422895 2738Note that if you were to simply say:
32eab2da 2739
2740 my %where = (
cc422895 2741 array => [1, 2, 3]
32eab2da 2742 );
2743
3af02ccb 2744the result would probably not be what you wanted:
cc422895 2745
2746 $stmt = 'WHERE array = ? OR array = ? OR array = ?';
2747 @bind = (1, 2, 3);
2748
2749=head3 Literal SQL
96449e8e 2750
cc422895 2751Finally, sometimes only literal SQL will do. To include a random snippet
2752of SQL verbatim, you specify it as a scalar reference. Consider this only
2753as a last resort. Usually there is a better way. For example:
96449e8e 2754
2755 my %where = (
cc422895 2756 priority => { '<', 2 },
2757 requestor => { -in => \'(SELECT name FROM hitmen)' },
96449e8e 2758 );
2759
cc422895 2760Would create:
96449e8e 2761
cc422895 2762 $stmt = "WHERE priority < ? AND requestor IN (SELECT name FROM hitmen)"
2763 @bind = (2);
2764
2765Note that in this example, you only get one bind parameter back, since
2766the verbatim SQL is passed as part of the statement.
2767
2768=head4 CAVEAT
2769
2770 Never use untrusted input as a literal SQL argument - this is a massive
2771 security risk (there is no way to check literal snippets for SQL
2772 injections and other nastyness). If you need to deal with untrusted input
2773 use literal SQL with placeholders as described next.
96449e8e 2774
cc422895 2775=head3 Literal SQL with placeholders and bind values (subqueries)
96449e8e 2776
2777If the literal SQL to be inserted has placeholders and bind values,
2778use a reference to an arrayref (yes this is a double reference --
2779not so common, but perfectly legal Perl). For example, to find a date
2780in Postgres you can use something like this:
2781
2782 my %where = (
3ae1c5e2 2783 date_column => \[ "= date '2008-09-30' - ?::integer", 10 ]
96449e8e 2784 )
2785
2786This would create:
2787
d2a8fe1a 2788 $stmt = "WHERE ( date_column = date '2008-09-30' - ?::integer )"
96449e8e 2789 @bind = ('10');
2790
deb148a2 2791Note that you must pass the bind values in the same format as they are returned
85783f3c 2792by L<where|/where(\%where, $order)>. This means that if you set L</bindtype>
1f490ae4 2793to C<columns>, you must provide the bind values in the
2794C<< [ column_meta => value ] >> format, where C<column_meta> is an opaque
2795scalar value; most commonly the column name, but you can use any scalar value
2796(including references and blessed references), L<SQL::Abstract> will simply
2797pass it through intact. So if C<bindtype> is set to C<columns> the above
2798example will look like:
deb148a2 2799
2800 my %where = (
3ae1c5e2 2801 date_column => \[ "= date '2008-09-30' - ?::integer", [ {} => 10 ] ]
deb148a2 2802 )
96449e8e 2803
2804Literal SQL is especially useful for nesting parenthesized clauses in the
2805main SQL query. Here is a first example :
2806
2807 my ($sub_stmt, @sub_bind) = ("SELECT c1 FROM t1 WHERE c2 < ? AND c3 LIKE ?",
2808 100, "foo%");
2809 my %where = (
2810 foo => 1234,
2811 bar => \["IN ($sub_stmt)" => @sub_bind],
2812 );
2813
2814This yields :
2815
9d48860e 2816 $stmt = "WHERE (foo = ? AND bar IN (SELECT c1 FROM t1
96449e8e 2817 WHERE c2 < ? AND c3 LIKE ?))";
2818 @bind = (1234, 100, "foo%");
2819
9d48860e 2820Other subquery operators, like for example C<"E<gt> ALL"> or C<"NOT IN">,
96449e8e 2821are expressed in the same way. Of course the C<$sub_stmt> and
9d48860e 2822its associated bind values can be generated through a former call
96449e8e 2823to C<select()> :
2824
2825 my ($sub_stmt, @sub_bind)
9d48860e 2826 = $sql->select("t1", "c1", {c2 => {"<" => 100},
96449e8e 2827 c3 => {-like => "foo%"}});
2828 my %where = (
2829 foo => 1234,
2830 bar => \["> ALL ($sub_stmt)" => @sub_bind],
2831 );
2832
2833In the examples above, the subquery was used as an operator on a column;
9d48860e 2834but the same principle also applies for a clause within the main C<%where>
96449e8e 2835hash, like an EXISTS subquery :
2836
9d48860e 2837 my ($sub_stmt, @sub_bind)
96449e8e 2838 = $sql->select("t1", "*", {c1 => 1, c2 => \"> t0.c0"});
48d9f5f8 2839 my %where = ( -and => [
96449e8e 2840 foo => 1234,
48d9f5f8 2841 \["EXISTS ($sub_stmt)" => @sub_bind],
2842 ]);
96449e8e 2843
2844which yields
2845
9d48860e 2846 $stmt = "WHERE (foo = ? AND EXISTS (SELECT * FROM t1
96449e8e 2847 WHERE c1 = ? AND c2 > t0.c0))";
2848 @bind = (1234, 1);
2849
2850
9d48860e 2851Observe that the condition on C<c2> in the subquery refers to
2852column C<t0.c0> of the main query : this is I<not> a bind
2853value, so we have to express it through a scalar ref.
96449e8e 2854Writing C<< c2 => {">" => "t0.c0"} >> would have generated
2855C<< c2 > ? >> with bind value C<"t0.c0"> ... not exactly
2856what we wanted here.
2857
96449e8e 2858Finally, here is an example where a subquery is used
2859for expressing unary negation:
2860
9d48860e 2861 my ($sub_stmt, @sub_bind)
96449e8e 2862 = $sql->where({age => [{"<" => 10}, {">" => 20}]});
2863 $sub_stmt =~ s/^ where //i; # don't want "WHERE" in the subclause
2864 my %where = (
2865 lname => {like => '%son%'},
48d9f5f8 2866 \["NOT ($sub_stmt)" => @sub_bind],
96449e8e 2867 );
2868
2869This yields
2870
2871 $stmt = "lname LIKE ? AND NOT ( age < ? OR age > ? )"
2872 @bind = ('%son%', 10, 20)
2873
cc422895 2874=head3 Deprecated usage of Literal SQL
2875
2876Below are some examples of archaic use of literal SQL. It is shown only as
2877reference for those who deal with legacy code. Each example has a much
2878better, cleaner and safer alternative that users should opt for in new code.
2879
2880=over
2881
2882=item *
2883
2884 my %where = ( requestor => \'IS NOT NULL' )
2885
2886 $stmt = "WHERE requestor IS NOT NULL"
2887
2888This used to be the way of generating NULL comparisons, before the handling
2889of C<undef> got formalized. For new code please use the superior syntax as
2890described in L</Tests for NULL values>.
96449e8e 2891
cc422895 2892=item *
2893
2894 my %where = ( requestor => \'= submitter' )
2895
2896 $stmt = "WHERE requestor = submitter"
2897
2898This used to be the only way to compare columns. Use the superior L</-ident>
2899method for all new code. For example an identifier declared in such a way
2900will be properly quoted if L</quote_char> is properly set, while the legacy
2901form will remain as supplied.
2902
2903=item *
2904
2905 my %where = ( is_ready => \"", completed => { '>', '2012-12-21' } )
2906
2907 $stmt = "WHERE completed > ? AND is_ready"
2908 @bind = ('2012-12-21')
2909
2910Using an empty string literal used to be the only way to express a boolean.
2911For all new code please use the much more readable
2912L<-bool|/Unary operators: bool> operator.
2913
2914=back
96449e8e 2915
2916=head2 Conclusion
2917
32eab2da 2918These pages could go on for a while, since the nesting of the data
2919structures this module can handle are pretty much unlimited (the
2920module implements the C<WHERE> expansion as a recursive function
2921internally). Your best bet is to "play around" with the module a
2922little to see how the data structures behave, and choose the best
2923format for your data based on that.
2924
2925And of course, all the values above will probably be replaced with
2926variables gotten from forms or the command line. After all, if you
2927knew everything ahead of time, you wouldn't have to worry about
2928dynamically-generating SQL and could just hardwire it into your
2929script.
2930
86298391 2931=head1 ORDER BY CLAUSES
2932
9d48860e 2933Some functions take an order by clause. This can either be a scalar (just a
18710f60 2934column name), a hashref of C<< { -desc => 'col' } >> or C<< { -asc => 'col' }
2935>>, a scalarref, an arrayref-ref, or an arrayref of any of the previous
2936forms. Examples:
1cfa1db3 2937
8c15b421 2938 Given | Will Generate
18710f60 2939 ---------------------------------------------------------------
8c15b421 2940 |
2941 'colA' | ORDER BY colA
2942 |
2943 [qw/colA colB/] | ORDER BY colA, colB
2944 |
2945 {-asc => 'colA'} | ORDER BY colA ASC
2946 |
2947 {-desc => 'colB'} | ORDER BY colB DESC
2948 |
2949 ['colA', {-asc => 'colB'}] | ORDER BY colA, colB ASC
2950 |
2951 { -asc => [qw/colA colB/] } | ORDER BY colA ASC, colB ASC
2952 |
2953 \'colA DESC' | ORDER BY colA DESC
2954 |
2955 \[ 'FUNC(colA, ?)', $x ] | ORDER BY FUNC(colA, ?)
2956 | /* ...with $x bound to ? */
2957 |
bd805d85 2958 [ | ORDER BY
2959 { -asc => 'colA' }, | colA ASC,
2960 { -desc => [qw/colB/] }, | colB DESC,
2961 { -asc => [qw/colC colD/] },| colC ASC, colD ASC,
2962 \'colE DESC', | colE DESC,
2963 \[ 'FUNC(colF, ?)', $x ], | FUNC(colF, ?)
2964 ] | /* ...with $x bound to ? */
18710f60 2965 ===============================================================
86298391 2966
96449e8e 2967
2968
2969=head1 SPECIAL OPERATORS
2970
e3f9dff4 2971 my $sqlmaker = SQL::Abstract->new(special_ops => [
3a2e1a5e 2972 {
2973 regex => qr/.../,
e3f9dff4 2974 handler => sub {
2975 my ($self, $field, $op, $arg) = @_;
2976 ...
3a2e1a5e 2977 },
2978 },
2979 {
2980 regex => qr/.../,
2981 handler => 'method_name',
e3f9dff4 2982 },
2983 ]);
2984
9d48860e 2985A "special operator" is a SQL syntactic clause that can be
e3f9dff4 2986applied to a field, instead of a usual binary operator.
9d48860e 2987For example :
e3f9dff4 2988
2989 WHERE field IN (?, ?, ?)
2990 WHERE field BETWEEN ? AND ?
2991 WHERE MATCH(field) AGAINST (?, ?)
96449e8e 2992
e3f9dff4 2993Special operators IN and BETWEEN are fairly standard and therefore
3a2e1a5e 2994are builtin within C<SQL::Abstract> (as the overridable methods
2995C<_where_field_IN> and C<_where_field_BETWEEN>). For other operators,
2996like the MATCH .. AGAINST example above which is specific to MySQL,
2997you can write your own operator handlers - supply a C<special_ops>
2998argument to the C<new> method. That argument takes an arrayref of
2999operator definitions; each operator definition is a hashref with two
3000entries:
96449e8e 3001
e3f9dff4 3002=over
3003
3004=item regex
3005
3006the regular expression to match the operator
96449e8e 3007
e3f9dff4 3008=item handler
3009
3a2e1a5e 3010Either a coderef or a plain scalar method name. In both cases
3011the expected return is C<< ($sql, @bind) >>.
3012
3013When supplied with a method name, it is simply called on the
13cc86af 3014L<SQL::Abstract> object as:
3a2e1a5e 3015
3016 $self->$method_name ($field, $op, $arg)
3017
3018 Where:
3019
3a2e1a5e 3020 $field is the LHS of the operator
13cc86af 3021 $op is the part that matched the handler regex
3a2e1a5e 3022 $arg is the RHS
3023
3024When supplied with a coderef, it is called as:
3025
3026 $coderef->($self, $field, $op, $arg)
3027
e3f9dff4 3028
3029=back
3030
9d48860e 3031For example, here is an implementation
e3f9dff4 3032of the MATCH .. AGAINST syntax for MySQL
3033
3034 my $sqlmaker = SQL::Abstract->new(special_ops => [
9d48860e 3035
e3f9dff4 3036 # special op for MySql MATCH (field) AGAINST(word1, word2, ...)
9d48860e 3037 {regex => qr/^match$/i,
e3f9dff4 3038 handler => sub {
3039 my ($self, $field, $op, $arg) = @_;
3040 $arg = [$arg] if not ref $arg;
3041 my $label = $self->_quote($field);
3042 my ($placeholder) = $self->_convert('?');
3043 my $placeholders = join ", ", (($placeholder) x @$arg);
3044 my $sql = $self->_sqlcase('match') . " ($label) "
3045 . $self->_sqlcase('against') . " ($placeholders) ";
3046 my @bind = $self->_bindtype($field, @$arg);
3047 return ($sql, @bind);
3048 }
3049 },
9d48860e 3050
e3f9dff4 3051 ]);
96449e8e 3052
3053
59f23b3d 3054=head1 UNARY OPERATORS
3055
112b5232 3056 my $sqlmaker = SQL::Abstract->new(unary_ops => [
59f23b3d 3057 {
3058 regex => qr/.../,
3059 handler => sub {
3060 my ($self, $op, $arg) = @_;
3061 ...
3062 },
3063 },
3064 {
3065 regex => qr/.../,
3066 handler => 'method_name',
3067 },
3068 ]);
3069
9d48860e 3070A "unary operator" is a SQL syntactic clause that can be
59f23b3d 3071applied to a field - the operator goes before the field
3072
3073You can write your own operator handlers - supply a C<unary_ops>
3074argument to the C<new> method. That argument takes an arrayref of
3075operator definitions; each operator definition is a hashref with two
3076entries:
3077
3078=over
3079
3080=item regex
3081
3082the regular expression to match the operator
3083
3084=item handler
3085
3086Either a coderef or a plain scalar method name. In both cases
3087the expected return is C<< $sql >>.
3088
3089When supplied with a method name, it is simply called on the
13cc86af 3090L<SQL::Abstract> object as:
59f23b3d 3091
3092 $self->$method_name ($op, $arg)
3093
3094 Where:
3095
3096 $op is the part that matched the handler regex
3097 $arg is the RHS or argument of the operator
3098
3099When supplied with a coderef, it is called as:
3100
3101 $coderef->($self, $op, $arg)
3102
3103
3104=back
3105
3106
32eab2da 3107=head1 PERFORMANCE
3108
3109Thanks to some benchmarking by Mark Stosberg, it turns out that
3110this module is many orders of magnitude faster than using C<DBIx::Abstract>.
3111I must admit this wasn't an intentional design issue, but it's a
3112byproduct of the fact that you get to control your C<DBI> handles
3113yourself.
3114
3115To maximize performance, use a code snippet like the following:
3116
3117 # prepare a statement handle using the first row
3118 # and then reuse it for the rest of the rows
3119 my($sth, $stmt);
3120 for my $href (@array_of_hashrefs) {
3121 $stmt ||= $sql->insert('table', $href);
3122 $sth ||= $dbh->prepare($stmt);
3123 $sth->execute($sql->values($href));
3124 }
3125
3126The reason this works is because the keys in your C<$href> are sorted
3127internally by B<SQL::Abstract>. Thus, as long as your data retains
3128the same structure, you only have to generate the SQL the first time
3129around. On subsequent queries, simply use the C<values> function provided
3130by this module to return your values in the correct order.
3131
b864ba9b 3132However this depends on the values having the same type - if, for
3133example, the values of a where clause may either have values
3134(resulting in sql of the form C<column = ?> with a single bind
3135value), or alternatively the values might be C<undef> (resulting in
3136sql of the form C<column IS NULL> with no bind value) then the
3137caching technique suggested will not work.
96449e8e 3138
32eab2da 3139=head1 FORMBUILDER
3140
3141If you use my C<CGI::FormBuilder> module at all, you'll hopefully
3142really like this part (I do, at least). Building up a complex query
3143can be as simple as the following:
3144
3145 #!/usr/bin/perl
3146
46dc2f3e 3147 use warnings;
3148 use strict;
3149
32eab2da 3150 use CGI::FormBuilder;
3151 use SQL::Abstract;
3152
3153 my $form = CGI::FormBuilder->new(...);
3154 my $sql = SQL::Abstract->new;
3155
3156 if ($form->submitted) {
3157 my $field = $form->field;
3158 my $id = delete $field->{id};
3159 my($stmt, @bind) = $sql->update('table', $field, {id => $id});
3160 }
3161
3162Of course, you would still have to connect using C<DBI> to run the
3163query, but the point is that if you make your form look like your
3164table, the actual query script can be extremely simplistic.
3165
3166If you're B<REALLY> lazy (I am), check out C<HTML::QuickTable> for
9d48860e 3167a fast interface to returning and formatting data. I frequently
32eab2da 3168use these three modules together to write complex database query
3169apps in under 50 lines.
3170
af733667 3171=head1 HOW TO CONTRIBUTE
3172
3173Contributions are always welcome, in all usable forms (we especially
3174welcome documentation improvements). The delivery methods include git-
3175or unified-diff formatted patches, GitHub pull requests, or plain bug
3176reports either via RT or the Mailing list. Contributors are generally
3177granted full access to the official repository after their first several
3178patches pass successful review.
3179
3180This project is maintained in a git repository. The code and related tools are
3181accessible at the following locations:
d8cc1792 3182
3183=over
3184
af733667 3185=item * Official repo: L<git://git.shadowcat.co.uk/dbsrgits/SQL-Abstract.git>
3186
3187=item * Official gitweb: L<http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits/SQL-Abstract.git>
3188
3189=item * GitHub mirror: L<https://github.com/dbsrgits/sql-abstract>
d8cc1792 3190
af733667 3191=item * Authorized committers: L<ssh://dbsrgits@git.shadowcat.co.uk/SQL-Abstract.git>
d8cc1792 3192
3193=back
32eab2da 3194
96449e8e 3195=head1 CHANGES
3196
3197Version 1.50 was a major internal refactoring of C<SQL::Abstract>.
3198Great care has been taken to preserve the I<published> behavior
3199documented in previous versions in the 1.* family; however,
9d48860e 3200some features that were previously undocumented, or behaved
96449e8e 3201differently from the documentation, had to be changed in order
3202to clarify the semantics. Hence, client code that was relying
9d48860e 3203on some dark areas of C<SQL::Abstract> v1.*
96449e8e 3204B<might behave differently> in v1.50.
32eab2da 3205
d2a8fe1a 3206The main changes are :
3207
96449e8e 3208=over
32eab2da 3209
9d48860e 3210=item *
32eab2da 3211
3ae1c5e2 3212support for literal SQL through the C<< \ [ $sql, @bind ] >> syntax.
96449e8e 3213
3214=item *
3215
145fbfc8 3216support for the { operator => \"..." } construct (to embed literal SQL)
3217
3218=item *
3219
9c37b9c0 3220support for the { operator => \["...", @bind] } construct (to embed literal SQL with bind values)
3221
3222=item *
3223
96449e8e 3224optional support for L<array datatypes|/"Inserting and Updating Arrays">
3225
9d48860e 3226=item *
96449e8e 3227
3228defensive programming : check arguments
3229
3230=item *
3231
3232fixed bug with global logic, which was previously implemented
7cac25e6 3233through global variables yielding side-effects. Prior versions would
96449e8e 3234interpret C<< [ {cond1, cond2}, [cond3, cond4] ] >>
3235as C<< "(cond1 AND cond2) OR (cond3 AND cond4)" >>.
3236Now this is interpreted
3237as C<< "(cond1 AND cond2) OR (cond3 OR cond4)" >>.
3238
96449e8e 3239
3240=item *
3241
3242fixed semantics of _bindtype on array args
3243
9d48860e 3244=item *
96449e8e 3245
3246dropped the C<_anoncopy> of the %where tree. No longer necessary,
3247we just avoid shifting arrays within that tree.
3248
3249=item *
3250
3251dropped the C<_modlogic> function
3252
3253=back
32eab2da 3254
32eab2da 3255=head1 ACKNOWLEDGEMENTS
3256
3257There are a number of individuals that have really helped out with
3258this module. Unfortunately, most of them submitted bugs via CPAN
3259so I have no idea who they are! But the people I do know are:
3260
9d48860e 3261 Ash Berlin (order_by hash term support)
b643abe1 3262 Matt Trout (DBIx::Class support)
32eab2da 3263 Mark Stosberg (benchmarking)
3264 Chas Owens (initial "IN" operator support)
3265 Philip Collins (per-field SQL functions)
3266 Eric Kolve (hashref "AND" support)
3267 Mike Fragassi (enhancements to "BETWEEN" and "LIKE")
3268 Dan Kubb (support for "quote_char" and "name_sep")
f5aab26e 3269 Guillermo Roditi (patch to cleanup "IN" and "BETWEEN", fix and tests for _order_by)
48d9f5f8 3270 Laurent Dami (internal refactoring, extensible list of special operators, literal SQL)
dbdf7648 3271 Norbert Buchmuller (support for literal SQL in hashpair, misc. fixes & tests)
e96c510a 3272 Peter Rabbitson (rewrite of SQLA::Test, misc. fixes & tests)
02288357 3273 Oliver Charles (support for "RETURNING" after "INSERT")
32eab2da 3274
3275Thanks!
3276
32eab2da 3277=head1 SEE ALSO
3278
86298391 3279L<DBIx::Class>, L<DBIx::Abstract>, L<CGI::FormBuilder>, L<HTML::QuickTable>.
32eab2da 3280
32eab2da 3281=head1 AUTHOR
3282
b643abe1 3283Copyright (c) 2001-2007 Nathan Wiger <nwiger@cpan.org>. All Rights Reserved.
3284
3285This module is actively maintained by Matt Trout <mst@shadowcatsystems.co.uk>
32eab2da 3286
abe72f94 3287For support, your best bet is to try the C<DBIx::Class> users mailing list.
3288While not an official support venue, C<DBIx::Class> makes heavy use of
3289C<SQL::Abstract>, and as such list members there are very familiar with
3290how to create queries.
3291
0d067ded 3292=head1 LICENSE
3293
d988ab87 3294This module is free software; you may copy this under the same
3295terms as perl itself (either the GNU General Public License or
3296the Artistic License)
32eab2da 3297
3298=cut