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