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