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