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