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