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