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