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