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