Ignore built dist files and directories
[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
2146(literal table name, not quoted), or a ref to an arrayref
2147(list of literal table names, joined by commas, not quoted).
32eab2da 2148
96449e8e 2149=item $fields
32eab2da 2150
9d48860e 2151Specification of the list of fields to retrieve from
96449e8e 2152the source.
2153The argument can be either an arrayref (interpreted as a list
9d48860e 2154of field names, will be joined by commas and quoted), or a
96449e8e 2155plain scalar (literal SQL, not quoted).
521647e7 2156Please observe that this API is not as flexible as that of
2157the first argument C<$source>, for backwards compatibility reasons.
32eab2da 2158
96449e8e 2159=item $where
32eab2da 2160
96449e8e 2161Optional argument to specify the WHERE part of the query.
2162The argument is most often a hashref, but can also be
9d48860e 2163an arrayref or plain scalar --
96449e8e 2164see section L<WHERE clause|/"WHERE CLAUSES"> for details.
32eab2da 2165
96449e8e 2166=item $order
32eab2da 2167
96449e8e 2168Optional argument to specify the ORDER BY part of the query.
9d48860e 2169The argument can be a scalar, a hashref or an arrayref
96449e8e 2170-- see section L<ORDER BY clause|/"ORDER BY CLAUSES">
2171for details.
32eab2da 2172
96449e8e 2173=back
32eab2da 2174
32eab2da 2175
85327cd5 2176=head2 delete($table, \%where, \%options)
32eab2da 2177
86298391 2178This takes a table name and optional hashref L<WHERE clause|/WHERE CLAUSES>.
32eab2da 2179It returns an SQL DELETE statement and list of bind values.
2180
85327cd5 2181The optional C<\%options> hash reference may contain additional
2182options to generate the delete SQL. Currently supported options
2183are:
2184
2185=over 4
2186
2187=item returning
2188
2189See the C<returning> option to
2190L<insert|/insert($table, \@values || \%fieldvals, \%options)>.
2191
2192=back
2193
85783f3c 2194=head2 where(\%where, $order)
32eab2da 2195
2196This is used to generate just the WHERE clause. For example,
2197if you have an arbitrary data structure and know what the
2198rest of your SQL is going to look like, but want an easy way
2199to produce a WHERE clause, use this. It returns an SQL WHERE
2200clause and list of bind values.
2201
32eab2da 2202
2203=head2 values(\%data)
2204
2205This just returns the values from the hash C<%data>, in the same
2206order that would be returned from any of the other above queries.
2207Using this allows you to markedly speed up your queries if you
2208are affecting lots of rows. See below under the L</"PERFORMANCE"> section.
2209
32eab2da 2210=head2 generate($any, 'number', $of, \@data, $struct, \%types)
2211
2212Warning: This is an experimental method and subject to change.
2213
2214This returns arbitrarily generated SQL. It's a really basic shortcut.
2215It will return two different things, depending on return context:
2216
2217 my($stmt, @bind) = $sql->generate('create table', \$table, \@fields);
2218 my $stmt_and_val = $sql->generate('create table', \$table, \@fields);
2219
2220These would return the following:
2221
2222 # First calling form
2223 $stmt = "CREATE TABLE test (?, ?)";
2224 @bind = (field1, field2);
2225
2226 # Second calling form
2227 $stmt_and_val = "CREATE TABLE test (field1, field2)";
2228
2229Depending on what you're trying to do, it's up to you to choose the correct
2230format. In this example, the second form is what you would want.
2231
2232By the same token:
2233
2234 $sql->generate('alter session', { nls_date_format => 'MM/YY' });
2235
2236Might give you:
2237
2238 ALTER SESSION SET nls_date_format = 'MM/YY'
2239
2240You get the idea. Strings get their case twiddled, but everything
2241else remains verbatim.
2242
0da0fe34 2243=head1 EXPORTABLE FUNCTIONS
2244
2245=head2 is_plain_value
2246
2247Determines if the supplied argument is a plain value as understood by this
2248module:
2249
2250=over
2251
2252=item * The value is C<undef>
2253
2254=item * The value is a non-reference
2255
2256=item * The value is an object with stringification overloading
2257
2258=item * The value is of the form C<< { -value => $anything } >>
2259
2260=back
2261
9de2bd86 2262On failure returns C<undef>, on success returns a B<scalar> reference
966200cc 2263to the original supplied argument.
0da0fe34 2264
843a94b5 2265=over
2266
2267=item * Note
2268
2269The stringification overloading detection is rather advanced: it takes
2270into consideration not only the presence of a C<""> overload, but if that
2271fails also checks for enabled
2272L<autogenerated versions of C<"">|overload/Magic Autogeneration>, based
2273on either C<0+> or C<bool>.
2274
2275Unfortunately testing in the field indicates that this
2276detection B<< may tickle a latent bug in perl versions before 5.018 >>,
2277but only when very large numbers of stringifying objects are involved.
2278At the time of writing ( Sep 2014 ) there is no clear explanation of
2279the direct cause, nor is there a manageably small test case that reliably
2280reproduces the problem.
2281
2282If you encounter any of the following exceptions in B<random places within
2283your application stack> - this module may be to blame:
2284
2285 Operation "ne": no method found,
2286 left argument in overloaded package <something>,
2287 right argument in overloaded package <something>
2288
2289or perhaps even
2290
2291 Stub found while resolving method "???" overloading """" in package <something>
2292
2293If you fall victim to the above - please attempt to reduce the problem
2294to something that could be sent to the L<SQL::Abstract developers
1f490ae4 2295|DBIx::Class/GETTING HELP/SUPPORT>
843a94b5 2296(either publicly or privately). As a workaround in the meantime you can
2297set C<$ENV{SQLA_ISVALUE_IGNORE_AUTOGENERATED_STRINGIFICATION}> to a true
2298value, which will most likely eliminate your problem (at the expense of
2299not being able to properly detect exotic forms of stringification).
2300
2301This notice and environment variable will be removed in a future version,
2302as soon as the underlying problem is found and a reliable workaround is
2303devised.
2304
2305=back
2306
0da0fe34 2307=head2 is_literal_value
2308
2309Determines if the supplied argument is a literal value as understood by this
2310module:
2311
2312=over
2313
2314=item * C<\$sql_string>
2315
2316=item * C<\[ $sql_string, @bind_values ]>
2317
0da0fe34 2318=back
2319
9de2bd86 2320On failure returns C<undef>, on success returns an B<array> reference
966200cc 2321containing the unpacked version of the supplied literal SQL and bind values.
0da0fe34 2322
32eab2da 2323=head1 WHERE CLAUSES
2324
96449e8e 2325=head2 Introduction
2326
32eab2da 2327This module uses a variation on the idea from L<DBIx::Abstract>. It
2328is B<NOT>, repeat I<not> 100% compatible. B<The main logic of this
2329module is that things in arrays are OR'ed, and things in hashes
2330are AND'ed.>
2331
2332The easiest way to explain is to show lots of examples. After
2333each C<%where> hash shown, it is assumed you used:
2334
2335 my($stmt, @bind) = $sql->where(\%where);
2336
2337However, note that the C<%where> hash can be used directly in any
2338of the other functions as well, as described above.
2339
96449e8e 2340=head2 Key-value pairs
2341
32eab2da 2342So, let's get started. To begin, a simple hash:
2343
2344 my %where = (
2345 user => 'nwiger',
2346 status => 'completed'
2347 );
2348
2349Is converted to SQL C<key = val> statements:
2350
2351 $stmt = "WHERE user = ? AND status = ?";
2352 @bind = ('nwiger', 'completed');
2353
2354One common thing I end up doing is having a list of values that
2355a field can be in. To do this, simply specify a list inside of
2356an arrayref:
2357
2358 my %where = (
2359 user => 'nwiger',
2360 status => ['assigned', 'in-progress', 'pending'];
2361 );
2362
2363This simple code will create the following:
9d48860e 2364
32eab2da 2365 $stmt = "WHERE user = ? AND ( status = ? OR status = ? OR status = ? )";
2366 @bind = ('nwiger', 'assigned', 'in-progress', 'pending');
2367
9d48860e 2368A field associated to an empty arrayref will be considered a
7cac25e6 2369logical false and will generate 0=1.
8a68b5be 2370
b864ba9b 2371=head2 Tests for NULL values
2372
2373If the value part is C<undef> then this is converted to SQL <IS NULL>
2374
2375 my %where = (
2376 user => 'nwiger',
2377 status => undef,
2378 );
2379
2380becomes:
2381
2382 $stmt = "WHERE user = ? AND status IS NULL";
2383 @bind = ('nwiger');
2384
e9614080 2385To test if a column IS NOT NULL:
2386
2387 my %where = (
2388 user => 'nwiger',
2389 status => { '!=', undef },
2390 );
cc422895 2391
6e0c6552 2392=head2 Specific comparison operators
96449e8e 2393
32eab2da 2394If you want to specify a different type of operator for your comparison,
2395you can use a hashref for a given column:
2396
2397 my %where = (
2398 user => 'nwiger',
2399 status => { '!=', 'completed' }
2400 );
2401
2402Which would generate:
2403
2404 $stmt = "WHERE user = ? AND status != ?";
2405 @bind = ('nwiger', 'completed');
2406
2407To test against multiple values, just enclose the values in an arrayref:
2408
96449e8e 2409 status => { '=', ['assigned', 'in-progress', 'pending'] };
2410
f2d5020d 2411Which would give you:
96449e8e 2412
2413 "WHERE status = ? OR status = ? OR status = ?"
2414
2415
2416The hashref can also contain multiple pairs, in which case it is expanded
32eab2da 2417into an C<AND> of its elements:
2418
2419 my %where = (
2420 user => 'nwiger',
2421 status => { '!=', 'completed', -not_like => 'pending%' }
2422 );
2423
2424 # Or more dynamically, like from a form
2425 $where{user} = 'nwiger';
2426 $where{status}{'!='} = 'completed';
2427 $where{status}{'-not_like'} = 'pending%';
2428
2429 # Both generate this
2430 $stmt = "WHERE user = ? AND status != ? AND status NOT LIKE ?";
2431 @bind = ('nwiger', 'completed', 'pending%');
2432
96449e8e 2433
32eab2da 2434To get an OR instead, you can combine it with the arrayref idea:
2435
2436 my %where => (
2437 user => 'nwiger',
1a6f2a03 2438 priority => [ { '=', 2 }, { '>', 5 } ]
32eab2da 2439 );
2440
2441Which would generate:
2442
1a6f2a03 2443 $stmt = "WHERE ( priority = ? OR priority > ? ) AND user = ?";
2444 @bind = ('2', '5', 'nwiger');
32eab2da 2445
44b9e502 2446If you want to include literal SQL (with or without bind values), just use a
13cc86af 2447scalar reference or reference to an arrayref as the value:
44b9e502 2448
2449 my %where = (
2450 date_entered => { '>' => \["to_date(?, 'MM/DD/YYYY')", "11/26/2008"] },
2451 date_expires => { '<' => \"now()" }
2452 );
2453
2454Which would generate:
2455
13cc86af 2456 $stmt = "WHERE date_entered > to_date(?, 'MM/DD/YYYY') AND date_expires < now()";
44b9e502 2457 @bind = ('11/26/2008');
2458
96449e8e 2459
2460=head2 Logic and nesting operators
2461
2462In the example above,
2463there is a subtle trap if you want to say something like
32eab2da 2464this (notice the C<AND>):
2465
2466 WHERE priority != ? AND priority != ?
2467
2468Because, in Perl you I<can't> do this:
2469
13cc86af 2470 priority => { '!=' => 2, '!=' => 1 }
32eab2da 2471
2472As the second C<!=> key will obliterate the first. The solution
2473is to use the special C<-modifier> form inside an arrayref:
2474
9d48860e 2475 priority => [ -and => {'!=', 2},
96449e8e 2476 {'!=', 1} ]
2477
32eab2da 2478
2479Normally, these would be joined by C<OR>, but the modifier tells it
2480to use C<AND> instead. (Hint: You can use this in conjunction with the
2481C<logic> option to C<new()> in order to change the way your queries
2482work by default.) B<Important:> Note that the C<-modifier> goes
2483B<INSIDE> the arrayref, as an extra first element. This will
2484B<NOT> do what you think it might:
2485
2486 priority => -and => [{'!=', 2}, {'!=', 1}] # WRONG!
2487
2488Here is a quick list of equivalencies, since there is some overlap:
2489
2490 # Same
2491 status => {'!=', 'completed', 'not like', 'pending%' }
2492 status => [ -and => {'!=', 'completed'}, {'not like', 'pending%'}]
2493
2494 # Same
2495 status => {'=', ['assigned', 'in-progress']}
2496 status => [ -or => {'=', 'assigned'}, {'=', 'in-progress'}]
2497 status => [ {'=', 'assigned'}, {'=', 'in-progress'} ]
2498
e3f9dff4 2499
2500
96449e8e 2501=head2 Special operators : IN, BETWEEN, etc.
2502
32eab2da 2503You can also use the hashref format to compare a list of fields using the
2504C<IN> comparison operator, by specifying the list as an arrayref:
2505
2506 my %where = (
2507 status => 'completed',
2508 reportid => { -in => [567, 2335, 2] }
2509 );
2510
2511Which would generate:
2512
2513 $stmt = "WHERE status = ? AND reportid IN (?,?,?)";
2514 @bind = ('completed', '567', '2335', '2');
2515
9d48860e 2516The reverse operator C<-not_in> generates SQL C<NOT IN> and is used in
96449e8e 2517the same way.
2518
6e0c6552 2519If the argument to C<-in> is an empty array, 'sqlfalse' is generated
2520(by default : C<1=0>). Similarly, C<< -not_in => [] >> generates
2521'sqltrue' (by default : C<1=1>).
2522
e41c3bdd 2523In addition to the array you can supply a chunk of literal sql or
2524literal sql with bind:
6e0c6552 2525
e41c3bdd 2526 my %where = {
2527 customer => { -in => \[
2528 'SELECT cust_id FROM cust WHERE balance > ?',
2529 2000,
2530 ],
2531 status => { -in => \'SELECT status_codes FROM states' },
2532 };
6e0c6552 2533
e41c3bdd 2534would generate:
2535
2536 $stmt = "WHERE (
2537 customer IN ( SELECT cust_id FROM cust WHERE balance > ? )
2538 AND status IN ( SELECT status_codes FROM states )
2539 )";
2540 @bind = ('2000');
2541
0dfd2442 2542Finally, if the argument to C<-in> is not a reference, it will be
2543treated as a single-element array.
e41c3bdd 2544
2545Another pair of operators is C<-between> and C<-not_between>,
96449e8e 2546used with an arrayref of two values:
32eab2da 2547
2548 my %where = (
2549 user => 'nwiger',
2550 completion_date => {
2551 -not_between => ['2002-10-01', '2003-02-06']
2552 }
2553 );
2554
2555Would give you:
2556
2557 WHERE user = ? AND completion_date NOT BETWEEN ( ? AND ? )
2558
e41c3bdd 2559Just like with C<-in> all plausible combinations of literal SQL
2560are possible:
2561
2562 my %where = {
2563 start0 => { -between => [ 1, 2 ] },
2564 start1 => { -between => \["? AND ?", 1, 2] },
2565 start2 => { -between => \"lower(x) AND upper(y)" },
9d48860e 2566 start3 => { -between => [
e41c3bdd 2567 \"lower(x)",
2568 \["upper(?)", 'stuff' ],
2569 ] },
2570 };
2571
2572Would give you:
2573
2574 $stmt = "WHERE (
2575 ( start0 BETWEEN ? AND ? )
2576 AND ( start1 BETWEEN ? AND ? )
2577 AND ( start2 BETWEEN lower(x) AND upper(y) )
2578 AND ( start3 BETWEEN lower(x) AND upper(?) )
2579 )";
2580 @bind = (1, 2, 1, 2, 'stuff');
2581
2582
9d48860e 2583These are the two builtin "special operators"; but the
96449e8e 2584list can be expanded : see section L</"SPECIAL OPERATORS"> below.
2585
59f23b3d 2586=head2 Unary operators: bool
97a920ef 2587
2588If you wish to test against boolean columns or functions within your
2589database you can use the C<-bool> and C<-not_bool> operators. For
2590example to test the column C<is_user> being true and the column
827bb0eb 2591C<is_enabled> being false you would use:-
97a920ef 2592
2593 my %where = (
2594 -bool => 'is_user',
2595 -not_bool => 'is_enabled',
2596 );
2597
2598Would give you:
2599
277b5d3f 2600 WHERE is_user AND NOT is_enabled
97a920ef 2601
0b604e9d 2602If a more complex combination is required, testing more conditions,
2603then you should use the and/or operators:-
2604
2605 my %where = (
2606 -and => [
2607 -bool => 'one',
23401b81 2608 -not_bool => { two=> { -rlike => 'bar' } },
2609 -not_bool => { three => [ { '=', 2 }, { '>', 5 } ] },
0b604e9d 2610 ],
2611 );
2612
2613Would give you:
2614
23401b81 2615 WHERE
2616 one
2617 AND
2618 (NOT two RLIKE ?)
2619 AND
2620 (NOT ( three = ? OR three > ? ))
97a920ef 2621
2622
107b72f1 2623=head2 Nested conditions, -and/-or prefixes
96449e8e 2624
32eab2da 2625So far, we've seen how multiple conditions are joined with a top-level
2626C<AND>. We can change this by putting the different conditions we want in
2627hashes and then putting those hashes in an array. For example:
2628
2629 my @where = (
2630 {
2631 user => 'nwiger',
2632 status => { -like => ['pending%', 'dispatched'] },
2633 },
2634 {
2635 user => 'robot',
2636 status => 'unassigned',
2637 }
2638 );
2639
2640This data structure would create the following:
2641
2642 $stmt = "WHERE ( user = ? AND ( status LIKE ? OR status LIKE ? ) )
2643 OR ( user = ? AND status = ? ) )";
2644 @bind = ('nwiger', 'pending', 'dispatched', 'robot', 'unassigned');
2645
107b72f1 2646
48d9f5f8 2647Clauses in hashrefs or arrayrefs can be prefixed with an C<-and> or C<-or>
2648to change the logic inside :
32eab2da 2649
2650 my @where = (
2651 -and => [
2652 user => 'nwiger',
48d9f5f8 2653 [
2654 -and => [ workhrs => {'>', 20}, geo => 'ASIA' ],
2655 -or => { workhrs => {'<', 50}, geo => 'EURO' },
32eab2da 2656 ],
2657 ],
2658 );
2659
2660That would yield:
2661
13cc86af 2662 $stmt = "WHERE ( user = ?
2663 AND ( ( workhrs > ? AND geo = ? )
2664 OR ( workhrs < ? OR geo = ? ) ) )";
2665 @bind = ('nwiger', '20', 'ASIA', '50', 'EURO');
107b72f1 2666
cc422895 2667=head3 Algebraic inconsistency, for historical reasons
107b72f1 2668
7cac25e6 2669C<Important note>: when connecting several conditions, the C<-and->|C<-or>
2670operator goes C<outside> of the nested structure; whereas when connecting
2671several constraints on one column, the C<-and> operator goes
2672C<inside> the arrayref. Here is an example combining both features :
2673
2674 my @where = (
2675 -and => [a => 1, b => 2],
2676 -or => [c => 3, d => 4],
2677 e => [-and => {-like => 'foo%'}, {-like => '%bar'} ]
2678 )
2679
2680yielding
2681
9d48860e 2682 WHERE ( ( ( a = ? AND b = ? )
2683 OR ( c = ? OR d = ? )
7cac25e6 2684 OR ( e LIKE ? AND e LIKE ? ) ) )
2685
107b72f1 2686This difference in syntax is unfortunate but must be preserved for
2687historical reasons. So be careful : the two examples below would
2688seem algebraically equivalent, but they are not
2689
a948b1fe 2690 { col => [ -and =>
2691 { -like => 'foo%' },
2692 { -like => '%bar' },
2693 ] }
107b72f1 2694 # yields : WHERE ( ( col LIKE ? AND col LIKE ? ) )
2695
a948b1fe 2696 [ -and =>
2697 { col => { -like => 'foo%' } },
2698 { col => { -like => '%bar' } },
2699 ]
107b72f1 2700 # yields : WHERE ( ( col LIKE ? OR col LIKE ? ) )
2701
7cac25e6 2702
cc422895 2703=head2 Literal SQL and value type operators
96449e8e 2704
cc422895 2705The basic premise of SQL::Abstract is that in WHERE specifications the "left
2706side" is a column name and the "right side" is a value (normally rendered as
2707a placeholder). This holds true for both hashrefs and arrayref pairs as you
2708see in the L</WHERE CLAUSES> examples above. Sometimes it is necessary to
2709alter this behavior. There are several ways of doing so.
e9614080 2710
cc422895 2711=head3 -ident
2712
2713This is a virtual operator that signals the string to its right side is an
2714identifier (a column name) and not a value. For example to compare two
2715columns you would write:
32eab2da 2716
e9614080 2717 my %where = (
2718 priority => { '<', 2 },
cc422895 2719 requestor => { -ident => 'submitter' },
e9614080 2720 );
2721
2722which creates:
2723
2724 $stmt = "WHERE priority < ? AND requestor = submitter";
2725 @bind = ('2');
2726
cc422895 2727If you are maintaining legacy code you may see a different construct as
2728described in L</Deprecated usage of Literal SQL>, please use C<-ident> in new
2729code.
2730
2731=head3 -value
e9614080 2732
cc422895 2733This is a virtual operator that signals that the construct to its right side
2734is a value to be passed to DBI. This is for example necessary when you want
2735to write a where clause against an array (for RDBMS that support such
2736datatypes). For example:
e9614080 2737
32eab2da 2738 my %where = (
cc422895 2739 array => { -value => [1, 2, 3] }
32eab2da 2740 );
2741
cc422895 2742will result in:
32eab2da 2743
cc422895 2744 $stmt = 'WHERE array = ?';
2745 @bind = ([1, 2, 3]);
32eab2da 2746
cc422895 2747Note that if you were to simply say:
32eab2da 2748
2749 my %where = (
cc422895 2750 array => [1, 2, 3]
32eab2da 2751 );
2752
3af02ccb 2753the result would probably not be what you wanted:
cc422895 2754
2755 $stmt = 'WHERE array = ? OR array = ? OR array = ?';
2756 @bind = (1, 2, 3);
2757
2758=head3 Literal SQL
96449e8e 2759
cc422895 2760Finally, sometimes only literal SQL will do. To include a random snippet
2761of SQL verbatim, you specify it as a scalar reference. Consider this only
2762as a last resort. Usually there is a better way. For example:
96449e8e 2763
2764 my %where = (
cc422895 2765 priority => { '<', 2 },
2766 requestor => { -in => \'(SELECT name FROM hitmen)' },
96449e8e 2767 );
2768
cc422895 2769Would create:
96449e8e 2770
cc422895 2771 $stmt = "WHERE priority < ? AND requestor IN (SELECT name FROM hitmen)"
2772 @bind = (2);
2773
2774Note that in this example, you only get one bind parameter back, since
2775the verbatim SQL is passed as part of the statement.
2776
2777=head4 CAVEAT
2778
2779 Never use untrusted input as a literal SQL argument - this is a massive
2780 security risk (there is no way to check literal snippets for SQL
2781 injections and other nastyness). If you need to deal with untrusted input
2782 use literal SQL with placeholders as described next.
96449e8e 2783
cc422895 2784=head3 Literal SQL with placeholders and bind values (subqueries)
96449e8e 2785
2786If the literal SQL to be inserted has placeholders and bind values,
2787use a reference to an arrayref (yes this is a double reference --
2788not so common, but perfectly legal Perl). For example, to find a date
2789in Postgres you can use something like this:
2790
2791 my %where = (
3ae1c5e2 2792 date_column => \[ "= date '2008-09-30' - ?::integer", 10 ]
96449e8e 2793 )
2794
2795This would create:
2796
d2a8fe1a 2797 $stmt = "WHERE ( date_column = date '2008-09-30' - ?::integer )"
96449e8e 2798 @bind = ('10');
2799
deb148a2 2800Note that you must pass the bind values in the same format as they are returned
85783f3c 2801by L<where|/where(\%where, $order)>. This means that if you set L</bindtype>
1f490ae4 2802to C<columns>, you must provide the bind values in the
2803C<< [ column_meta => value ] >> format, where C<column_meta> is an opaque
2804scalar value; most commonly the column name, but you can use any scalar value
2805(including references and blessed references), L<SQL::Abstract> will simply
2806pass it through intact. So if C<bindtype> is set to C<columns> the above
2807example will look like:
deb148a2 2808
2809 my %where = (
3ae1c5e2 2810 date_column => \[ "= date '2008-09-30' - ?::integer", [ {} => 10 ] ]
deb148a2 2811 )
96449e8e 2812
2813Literal SQL is especially useful for nesting parenthesized clauses in the
2814main SQL query. Here is a first example :
2815
2816 my ($sub_stmt, @sub_bind) = ("SELECT c1 FROM t1 WHERE c2 < ? AND c3 LIKE ?",
2817 100, "foo%");
2818 my %where = (
2819 foo => 1234,
2820 bar => \["IN ($sub_stmt)" => @sub_bind],
2821 );
2822
2823This yields :
2824
9d48860e 2825 $stmt = "WHERE (foo = ? AND bar IN (SELECT c1 FROM t1
96449e8e 2826 WHERE c2 < ? AND c3 LIKE ?))";
2827 @bind = (1234, 100, "foo%");
2828
9d48860e 2829Other subquery operators, like for example C<"E<gt> ALL"> or C<"NOT IN">,
96449e8e 2830are expressed in the same way. Of course the C<$sub_stmt> and
9d48860e 2831its associated bind values can be generated through a former call
96449e8e 2832to C<select()> :
2833
2834 my ($sub_stmt, @sub_bind)
9d48860e 2835 = $sql->select("t1", "c1", {c2 => {"<" => 100},
96449e8e 2836 c3 => {-like => "foo%"}});
2837 my %where = (
2838 foo => 1234,
2839 bar => \["> ALL ($sub_stmt)" => @sub_bind],
2840 );
2841
2842In the examples above, the subquery was used as an operator on a column;
9d48860e 2843but the same principle also applies for a clause within the main C<%where>
96449e8e 2844hash, like an EXISTS subquery :
2845
9d48860e 2846 my ($sub_stmt, @sub_bind)
96449e8e 2847 = $sql->select("t1", "*", {c1 => 1, c2 => \"> t0.c0"});
48d9f5f8 2848 my %where = ( -and => [
96449e8e 2849 foo => 1234,
48d9f5f8 2850 \["EXISTS ($sub_stmt)" => @sub_bind],
2851 ]);
96449e8e 2852
2853which yields
2854
9d48860e 2855 $stmt = "WHERE (foo = ? AND EXISTS (SELECT * FROM t1
96449e8e 2856 WHERE c1 = ? AND c2 > t0.c0))";
2857 @bind = (1234, 1);
2858
2859
9d48860e 2860Observe that the condition on C<c2> in the subquery refers to
2861column C<t0.c0> of the main query : this is I<not> a bind
2862value, so we have to express it through a scalar ref.
96449e8e 2863Writing C<< c2 => {">" => "t0.c0"} >> would have generated
2864C<< c2 > ? >> with bind value C<"t0.c0"> ... not exactly
2865what we wanted here.
2866
96449e8e 2867Finally, here is an example where a subquery is used
2868for expressing unary negation:
2869
9d48860e 2870 my ($sub_stmt, @sub_bind)
96449e8e 2871 = $sql->where({age => [{"<" => 10}, {">" => 20}]});
2872 $sub_stmt =~ s/^ where //i; # don't want "WHERE" in the subclause
2873 my %where = (
2874 lname => {like => '%son%'},
48d9f5f8 2875 \["NOT ($sub_stmt)" => @sub_bind],
96449e8e 2876 );
2877
2878This yields
2879
2880 $stmt = "lname LIKE ? AND NOT ( age < ? OR age > ? )"
2881 @bind = ('%son%', 10, 20)
2882
cc422895 2883=head3 Deprecated usage of Literal SQL
2884
2885Below are some examples of archaic use of literal SQL. It is shown only as
2886reference for those who deal with legacy code. Each example has a much
2887better, cleaner and safer alternative that users should opt for in new code.
2888
2889=over
2890
2891=item *
2892
2893 my %where = ( requestor => \'IS NOT NULL' )
2894
2895 $stmt = "WHERE requestor IS NOT NULL"
2896
2897This used to be the way of generating NULL comparisons, before the handling
2898of C<undef> got formalized. For new code please use the superior syntax as
2899described in L</Tests for NULL values>.
96449e8e 2900
cc422895 2901=item *
2902
2903 my %where = ( requestor => \'= submitter' )
2904
2905 $stmt = "WHERE requestor = submitter"
2906
2907This used to be the only way to compare columns. Use the superior L</-ident>
2908method for all new code. For example an identifier declared in such a way
2909will be properly quoted if L</quote_char> is properly set, while the legacy
2910form will remain as supplied.
2911
2912=item *
2913
2914 my %where = ( is_ready => \"", completed => { '>', '2012-12-21' } )
2915
2916 $stmt = "WHERE completed > ? AND is_ready"
2917 @bind = ('2012-12-21')
2918
2919Using an empty string literal used to be the only way to express a boolean.
2920For all new code please use the much more readable
2921L<-bool|/Unary operators: bool> operator.
2922
2923=back
96449e8e 2924
2925=head2 Conclusion
2926
32eab2da 2927These pages could go on for a while, since the nesting of the data
2928structures this module can handle are pretty much unlimited (the
2929module implements the C<WHERE> expansion as a recursive function
2930internally). Your best bet is to "play around" with the module a
2931little to see how the data structures behave, and choose the best
2932format for your data based on that.
2933
2934And of course, all the values above will probably be replaced with
2935variables gotten from forms or the command line. After all, if you
2936knew everything ahead of time, you wouldn't have to worry about
2937dynamically-generating SQL and could just hardwire it into your
2938script.
2939
86298391 2940=head1 ORDER BY CLAUSES
2941
9d48860e 2942Some functions take an order by clause. This can either be a scalar (just a
18710f60 2943column name), a hashref of C<< { -desc => 'col' } >> or C<< { -asc => 'col' }
2944>>, a scalarref, an arrayref-ref, or an arrayref of any of the previous
2945forms. Examples:
1cfa1db3 2946
8c15b421 2947 Given | Will Generate
18710f60 2948 ---------------------------------------------------------------
8c15b421 2949 |
2950 'colA' | ORDER BY colA
2951 |
2952 [qw/colA colB/] | ORDER BY colA, colB
2953 |
2954 {-asc => 'colA'} | ORDER BY colA ASC
2955 |
2956 {-desc => 'colB'} | ORDER BY colB DESC
2957 |
2958 ['colA', {-asc => 'colB'}] | ORDER BY colA, colB ASC
2959 |
2960 { -asc => [qw/colA colB/] } | ORDER BY colA ASC, colB ASC
2961 |
2962 \'colA DESC' | ORDER BY colA DESC
2963 |
2964 \[ 'FUNC(colA, ?)', $x ] | ORDER BY FUNC(colA, ?)
2965 | /* ...with $x bound to ? */
2966 |
bd805d85 2967 [ | ORDER BY
2968 { -asc => 'colA' }, | colA ASC,
2969 { -desc => [qw/colB/] }, | colB DESC,
2970 { -asc => [qw/colC colD/] },| colC ASC, colD ASC,
2971 \'colE DESC', | colE DESC,
2972 \[ 'FUNC(colF, ?)', $x ], | FUNC(colF, ?)
2973 ] | /* ...with $x bound to ? */
18710f60 2974 ===============================================================
86298391 2975
96449e8e 2976
2977
2978=head1 SPECIAL OPERATORS
2979
e3f9dff4 2980 my $sqlmaker = SQL::Abstract->new(special_ops => [
3a2e1a5e 2981 {
2982 regex => qr/.../,
e3f9dff4 2983 handler => sub {
2984 my ($self, $field, $op, $arg) = @_;
2985 ...
3a2e1a5e 2986 },
2987 },
2988 {
2989 regex => qr/.../,
2990 handler => 'method_name',
e3f9dff4 2991 },
2992 ]);
2993
9d48860e 2994A "special operator" is a SQL syntactic clause that can be
e3f9dff4 2995applied to a field, instead of a usual binary operator.
9d48860e 2996For example :
e3f9dff4 2997
2998 WHERE field IN (?, ?, ?)
2999 WHERE field BETWEEN ? AND ?
3000 WHERE MATCH(field) AGAINST (?, ?)
96449e8e 3001
e3f9dff4 3002Special operators IN and BETWEEN are fairly standard and therefore
3a2e1a5e 3003are builtin within C<SQL::Abstract> (as the overridable methods
3004C<_where_field_IN> and C<_where_field_BETWEEN>). For other operators,
3005like the MATCH .. AGAINST example above which is specific to MySQL,
3006you can write your own operator handlers - supply a C<special_ops>
3007argument to the C<new> method. That argument takes an arrayref of
3008operator definitions; each operator definition is a hashref with two
3009entries:
96449e8e 3010
e3f9dff4 3011=over
3012
3013=item regex
3014
3015the regular expression to match the operator
96449e8e 3016
e3f9dff4 3017=item handler
3018
3a2e1a5e 3019Either a coderef or a plain scalar method name. In both cases
3020the expected return is C<< ($sql, @bind) >>.
3021
3022When supplied with a method name, it is simply called on the
13cc86af 3023L<SQL::Abstract> object as:
3a2e1a5e 3024
ca4f826a 3025 $self->$method_name($field, $op, $arg)
3a2e1a5e 3026
3027 Where:
3028
3a2e1a5e 3029 $field is the LHS of the operator
13cc86af 3030 $op is the part that matched the handler regex
3a2e1a5e 3031 $arg is the RHS
3032
3033When supplied with a coderef, it is called as:
3034
3035 $coderef->($self, $field, $op, $arg)
3036
e3f9dff4 3037
3038=back
3039
9d48860e 3040For example, here is an implementation
e3f9dff4 3041of the MATCH .. AGAINST syntax for MySQL
3042
3043 my $sqlmaker = SQL::Abstract->new(special_ops => [
9d48860e 3044
e3f9dff4 3045 # special op for MySql MATCH (field) AGAINST(word1, word2, ...)
9d48860e 3046 {regex => qr/^match$/i,
e3f9dff4 3047 handler => sub {
3048 my ($self, $field, $op, $arg) = @_;
3049 $arg = [$arg] if not ref $arg;
3050 my $label = $self->_quote($field);
3051 my ($placeholder) = $self->_convert('?');
3052 my $placeholders = join ", ", (($placeholder) x @$arg);
3053 my $sql = $self->_sqlcase('match') . " ($label) "
3054 . $self->_sqlcase('against') . " ($placeholders) ";
3055 my @bind = $self->_bindtype($field, @$arg);
3056 return ($sql, @bind);
3057 }
3058 },
9d48860e 3059
e3f9dff4 3060 ]);
96449e8e 3061
3062
59f23b3d 3063=head1 UNARY OPERATORS
3064
112b5232 3065 my $sqlmaker = SQL::Abstract->new(unary_ops => [
59f23b3d 3066 {
3067 regex => qr/.../,
3068 handler => sub {
3069 my ($self, $op, $arg) = @_;
3070 ...
3071 },
3072 },
3073 {
3074 regex => qr/.../,
3075 handler => 'method_name',
3076 },
3077 ]);
3078
9d48860e 3079A "unary operator" is a SQL syntactic clause that can be
59f23b3d 3080applied to a field - the operator goes before the field
3081
3082You can write your own operator handlers - supply a C<unary_ops>
3083argument to the C<new> method. That argument takes an arrayref of
3084operator definitions; each operator definition is a hashref with two
3085entries:
3086
3087=over
3088
3089=item regex
3090
3091the regular expression to match the operator
3092
3093=item handler
3094
3095Either a coderef or a plain scalar method name. In both cases
3096the expected return is C<< $sql >>.
3097
3098When supplied with a method name, it is simply called on the
13cc86af 3099L<SQL::Abstract> object as:
59f23b3d 3100
ca4f826a 3101 $self->$method_name($op, $arg)
59f23b3d 3102
3103 Where:
3104
3105 $op is the part that matched the handler regex
3106 $arg is the RHS or argument of the operator
3107
3108When supplied with a coderef, it is called as:
3109
3110 $coderef->($self, $op, $arg)
3111
3112
3113=back
3114
3115
32eab2da 3116=head1 PERFORMANCE
3117
3118Thanks to some benchmarking by Mark Stosberg, it turns out that
3119this module is many orders of magnitude faster than using C<DBIx::Abstract>.
3120I must admit this wasn't an intentional design issue, but it's a
3121byproduct of the fact that you get to control your C<DBI> handles
3122yourself.
3123
3124To maximize performance, use a code snippet like the following:
3125
3126 # prepare a statement handle using the first row
3127 # and then reuse it for the rest of the rows
3128 my($sth, $stmt);
3129 for my $href (@array_of_hashrefs) {
3130 $stmt ||= $sql->insert('table', $href);
3131 $sth ||= $dbh->prepare($stmt);
3132 $sth->execute($sql->values($href));
3133 }
3134
3135The reason this works is because the keys in your C<$href> are sorted
3136internally by B<SQL::Abstract>. Thus, as long as your data retains
3137the same structure, you only have to generate the SQL the first time
3138around. On subsequent queries, simply use the C<values> function provided
3139by this module to return your values in the correct order.
3140
b864ba9b 3141However this depends on the values having the same type - if, for
3142example, the values of a where clause may either have values
3143(resulting in sql of the form C<column = ?> with a single bind
3144value), or alternatively the values might be C<undef> (resulting in
3145sql of the form C<column IS NULL> with no bind value) then the
3146caching technique suggested will not work.
96449e8e 3147
32eab2da 3148=head1 FORMBUILDER
3149
3150If you use my C<CGI::FormBuilder> module at all, you'll hopefully
3151really like this part (I do, at least). Building up a complex query
3152can be as simple as the following:
3153
3154 #!/usr/bin/perl
3155
46dc2f3e 3156 use warnings;
3157 use strict;
3158
32eab2da 3159 use CGI::FormBuilder;
3160 use SQL::Abstract;
3161
3162 my $form = CGI::FormBuilder->new(...);
3163 my $sql = SQL::Abstract->new;
3164
3165 if ($form->submitted) {
3166 my $field = $form->field;
3167 my $id = delete $field->{id};
3168 my($stmt, @bind) = $sql->update('table', $field, {id => $id});
3169 }
3170
3171Of course, you would still have to connect using C<DBI> to run the
3172query, but the point is that if you make your form look like your
3173table, the actual query script can be extremely simplistic.
3174
3175If you're B<REALLY> lazy (I am), check out C<HTML::QuickTable> for
9d48860e 3176a fast interface to returning and formatting data. I frequently
32eab2da 3177use these three modules together to write complex database query
3178apps in under 50 lines.
3179
af733667 3180=head1 HOW TO CONTRIBUTE
3181
3182Contributions are always welcome, in all usable forms (we especially
3183welcome documentation improvements). The delivery methods include git-
3184or unified-diff formatted patches, GitHub pull requests, or plain bug
3185reports either via RT or the Mailing list. Contributors are generally
3186granted full access to the official repository after their first several
3187patches pass successful review.
3188
3189This project is maintained in a git repository. The code and related tools are
3190accessible at the following locations:
d8cc1792 3191
3192=over
3193
af733667 3194=item * Official repo: L<git://git.shadowcat.co.uk/dbsrgits/SQL-Abstract.git>
3195
3196=item * Official gitweb: L<http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits/SQL-Abstract.git>
3197
3198=item * GitHub mirror: L<https://github.com/dbsrgits/sql-abstract>
d8cc1792 3199
af733667 3200=item * Authorized committers: L<ssh://dbsrgits@git.shadowcat.co.uk/SQL-Abstract.git>
d8cc1792 3201
3202=back
32eab2da 3203
96449e8e 3204=head1 CHANGES
3205
3206Version 1.50 was a major internal refactoring of C<SQL::Abstract>.
3207Great care has been taken to preserve the I<published> behavior
3208documented in previous versions in the 1.* family; however,
9d48860e 3209some features that were previously undocumented, or behaved
96449e8e 3210differently from the documentation, had to be changed in order
3211to clarify the semantics. Hence, client code that was relying
9d48860e 3212on some dark areas of C<SQL::Abstract> v1.*
96449e8e 3213B<might behave differently> in v1.50.
32eab2da 3214
d2a8fe1a 3215The main changes are :
3216
96449e8e 3217=over
32eab2da 3218
9d48860e 3219=item *
32eab2da 3220
3ae1c5e2 3221support for literal SQL through the C<< \ [ $sql, @bind ] >> syntax.
96449e8e 3222
3223=item *
3224
145fbfc8 3225support for the { operator => \"..." } construct (to embed literal SQL)
3226
3227=item *
3228
9c37b9c0 3229support for the { operator => \["...", @bind] } construct (to embed literal SQL with bind values)
3230
3231=item *
3232
96449e8e 3233optional support for L<array datatypes|/"Inserting and Updating Arrays">
3234
9d48860e 3235=item *
96449e8e 3236
3237defensive programming : check arguments
3238
3239=item *
3240
3241fixed bug with global logic, which was previously implemented
7cac25e6 3242through global variables yielding side-effects. Prior versions would
96449e8e 3243interpret C<< [ {cond1, cond2}, [cond3, cond4] ] >>
3244as C<< "(cond1 AND cond2) OR (cond3 AND cond4)" >>.
3245Now this is interpreted
3246as C<< "(cond1 AND cond2) OR (cond3 OR cond4)" >>.
3247
96449e8e 3248
3249=item *
3250
3251fixed semantics of _bindtype on array args
3252
9d48860e 3253=item *
96449e8e 3254
3255dropped the C<_anoncopy> of the %where tree. No longer necessary,
3256we just avoid shifting arrays within that tree.
3257
3258=item *
3259
3260dropped the C<_modlogic> function
3261
3262=back
32eab2da 3263
32eab2da 3264=head1 ACKNOWLEDGEMENTS
3265
3266There are a number of individuals that have really helped out with
3267this module. Unfortunately, most of them submitted bugs via CPAN
3268so I have no idea who they are! But the people I do know are:
3269
9d48860e 3270 Ash Berlin (order_by hash term support)
b643abe1 3271 Matt Trout (DBIx::Class support)
32eab2da 3272 Mark Stosberg (benchmarking)
3273 Chas Owens (initial "IN" operator support)
3274 Philip Collins (per-field SQL functions)
3275 Eric Kolve (hashref "AND" support)
3276 Mike Fragassi (enhancements to "BETWEEN" and "LIKE")
3277 Dan Kubb (support for "quote_char" and "name_sep")
f5aab26e 3278 Guillermo Roditi (patch to cleanup "IN" and "BETWEEN", fix and tests for _order_by)
48d9f5f8 3279 Laurent Dami (internal refactoring, extensible list of special operators, literal SQL)
dbdf7648 3280 Norbert Buchmuller (support for literal SQL in hashpair, misc. fixes & tests)
e96c510a 3281 Peter Rabbitson (rewrite of SQLA::Test, misc. fixes & tests)
02288357 3282 Oliver Charles (support for "RETURNING" after "INSERT")
32eab2da 3283
3284Thanks!
3285
32eab2da 3286=head1 SEE ALSO
3287
86298391 3288L<DBIx::Class>, L<DBIx::Abstract>, L<CGI::FormBuilder>, L<HTML::QuickTable>.
32eab2da 3289
32eab2da 3290=head1 AUTHOR
3291
b643abe1 3292Copyright (c) 2001-2007 Nathan Wiger <nwiger@cpan.org>. All Rights Reserved.
3293
3294This module is actively maintained by Matt Trout <mst@shadowcatsystems.co.uk>
32eab2da 3295
abe72f94 3296For support, your best bet is to try the C<DBIx::Class> users mailing list.
3297While not an official support venue, C<DBIx::Class> makes heavy use of
3298C<SQL::Abstract>, and as such list members there are very familiar with
3299how to create queries.
3300
0d067ded 3301=head1 LICENSE
3302
d988ab87 3303This module is free software; you may copy this under the same
3304terms as perl itself (either the GNU General Public License or
3305the Artistic License)
32eab2da 3306
3307=cut