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