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