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