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