clean up naming and provide aliases
[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
bd00b85c 1261 return $self->_expand_maybe_list_expr($arg)
1262 if ref($arg) eq 'HASH' and ($arg->{-op}||[''])->[0] eq ',';
e5feec9f 1263
4325df6a 1264 my $expander = sub {
1265 my ($self, $dir, $expr) = @_;
52ca537e 1266 my @to_expand = ref($expr) eq 'ARRAY' ? @$expr : $expr;
1267 foreach my $arg (@to_expand) {
1268 if (
1269 ref($arg) eq 'HASH'
1270 and keys %$arg > 1
1271 and grep /^-(asc|desc)$/, keys %$arg
1272 ) {
1273 puke "ordering direction hash passed to order by must have exactly one key (-asc or -desc)";
1274 }
1275 }
7384c311 1276 my @exp = map +(
1277 defined($dir) ? { -op => [ $dir =~ /^-?(.*)$/ ,=> $_ ] } : $_
1278 ),
79d310f2 1279 map $self->expand_expr($_, -ident),
74156ee9 1280 map ref($_) eq 'ARRAY' ? @$_ : $_, @to_expand;
4e78f98d 1281 return undef unless @exp;
1282 return undef if @exp == 1 and not defined($exp[0]);
1283 return +{ -op => [ ',', @exp ] };
4325df6a 1284 };
18c743c8 1285
def45151 1286 local @{$self->{expand}}{qw(asc desc)} = (($expander) x 2);
f267b646 1287
33177570 1288 return $self->$expander(undef, $arg);
1289}
1290
1291sub _order_by {
1292 my ($self, $arg) = @_;
1293
1294 return '' unless defined(my $expanded = $self->_expand_order_by($arg));
4325df6a 1295
79d310f2 1296 my ($sql, @bind) = $self->render_aqt($expanded);
4325df6a 1297
13cd9220 1298 return '' unless length($sql);
1299
4325df6a 1300 my $final_sql = $self->_sqlcase(' order by ').$sql;
1301
1302 return wantarray ? ($final_sql, @bind) : $final_sql;
f267b646 1303}
1304
2e3cc357 1305# _order_by no longer needs to call this so doesn't but DBIC uses it.
1306
33177570 1307sub _order_by_chunks {
1308 my ($self, $arg) = @_;
1309
1310 return () unless defined(my $expanded = $self->_expand_order_by($arg));
1311
2e3cc357 1312 return $self->_chunkify_order_by($expanded);
1313}
1314
1315sub _chunkify_order_by {
1316 my ($self, $expanded) = @_;
1b630cfe 1317
79d310f2 1318 return grep length, $self->render_aqt($expanded)
1b630cfe 1319 if $expanded->{-ident} or @{$expanded->{-literal}||[]} == 1;
1320
33177570 1321 for ($expanded) {
4a27fded 1322 if (ref() eq 'HASH' and $_->{-op} and $_->{-op}[0] eq ',') {
1323 my ($comma, @list) = @{$_->{-op}};
1324 return map $self->_chunkify_order_by($_), @list;
33177570 1325 }
79d310f2 1326 return [ $self->render_aqt($_) ];
33177570 1327 }
1328}
1329
96449e8e 1330#======================================================================
1331# DATASOURCE (FOR NOW, JUST PLAIN TABLE OR LIST OF TABLES)
1332#======================================================================
1333
1334sub _table {
1335 my $self = shift;
1336 my $from = shift;
79d310f2 1337 ($self->render_aqt(
dbc10abd 1338 $self->_expand_maybe_list_expr($from, -ident)
7ad12721 1339 ))[0];
96449e8e 1340}
1341
1342
1343#======================================================================
1344# UTILITY FUNCTIONS
1345#======================================================================
1346
8476c6a3 1347sub _expand_maybe_list_expr {
dbc10abd 1348 my ($self, $expr, $default) = @_;
bd00b85c 1349 return { -op => [
1350 ',', map $self->expand_expr($_, $default),
1351 @{$expr->{-op}}[1..$#{$expr->{-op}}]
1352 ] } if ref($expr) eq 'HASH' and ($expr->{-op}||[''])->[0] eq ',';
2c99e31e 1353 return +{ -op => [ ',',
1354 map $self->expand_expr($_, $default),
1355 ref($expr) eq 'ARRAY' ? @$expr : $expr
1356 ] };
8476c6a3 1357}
1358
955e77ca 1359# highly optimized, as it's called way too often
96449e8e 1360sub _quote {
955e77ca 1361 # my ($self, $label) = @_;
96449e8e 1362
955e77ca 1363 return '' unless defined $_[1];
955e77ca 1364 return ${$_[1]} if ref($_[1]) eq 'SCALAR';
d3162b5c 1365 puke 'Identifier cannot be hashref' if ref($_[1]) eq 'HASH';
96449e8e 1366
d3162b5c 1367 unless ($_[0]->{quote_char}) {
1368 if (ref($_[1]) eq 'ARRAY') {
1369 return join($_[0]->{name_sep}||'.', @{$_[1]});
1370 } else {
1371 $_[0]->_assert_pass_injection_guard($_[1]);
1372 return $_[1];
1373 }
1374 }
96449e8e 1375
07d7c35c 1376 my $qref = ref $_[0]->{quote_char};
439834d3 1377 my ($l, $r) =
1378 !$qref ? ($_[0]->{quote_char}, $_[0]->{quote_char})
1379 : ($qref eq 'ARRAY') ? @{$_[0]->{quote_char}}
1380 : puke "Unsupported quote_char format: $_[0]->{quote_char}";
1381
46be4313 1382 my $esc = $_[0]->{escape_char} || $r;
96449e8e 1383
07d7c35c 1384 # parts containing * are naturally unquoted
d3162b5c 1385 return join(
1386 $_[0]->{name_sep}||'',
1387 map +(
1388 $_ eq '*'
1389 ? $_
1390 : do { (my $n = $_) =~ s/(\Q$esc\E|\Q$r\E)/$esc$1/g; $l . $n . $r }
1391 ),
1392 (ref($_[1]) eq 'ARRAY'
1393 ? @{$_[1]}
1394 : (
1395 $_[0]->{name_sep}
1396 ? split (/\Q$_[0]->{name_sep}\E/, $_[1] )
1397 : $_[1]
1398 )
1399 )
955e77ca 1400 );
96449e8e 1401}
1402
1403
1404# Conversion, if applicable
d7c862e0 1405sub _convert {
07d7c35c 1406 #my ($self, $arg) = @_;
7ad12721 1407 if ($_[0]->{convert_where}) {
1408 return $_[0]->_sqlcase($_[0]->{convert_where}) .'(' . $_[1] . ')';
96449e8e 1409 }
07d7c35c 1410 return $_[1];
96449e8e 1411}
1412
1413# And bindtype
d7c862e0 1414sub _bindtype {
07d7c35c 1415 #my ($self, $col, @vals) = @_;
07d7c35c 1416 # called often - tighten code
1417 return $_[0]->{bindtype} eq 'columns'
1418 ? map {[$_[1], $_]} @_[2 .. $#_]
1419 : @_[2 .. $#_]
1420 ;
96449e8e 1421}
1422
fe3ae272 1423# Dies if any element of @bind is not in [colname => value] format
1424# if bindtype is 'columns'.
1425sub _assert_bindval_matches_bindtype {
c94a6c93 1426# my ($self, @bind) = @_;
1427 my $self = shift;
fe3ae272 1428 if ($self->{bindtype} eq 'columns') {
c94a6c93 1429 for (@_) {
1430 if (!defined $_ || ref($_) ne 'ARRAY' || @$_ != 2) {
3a06278c 1431 puke "bindtype 'columns' selected, you need to pass: [column_name => bind_value]"
fe3ae272 1432 }
1433 }
1434 }
1435}
1436
96449e8e 1437sub _join_sql_clauses {
1438 my ($self, $logic, $clauses_aref, $bind_aref) = @_;
1439
1440 if (@$clauses_aref > 1) {
1441 my $join = " " . $self->_sqlcase($logic) . " ";
1442 my $sql = '( ' . join($join, @$clauses_aref) . ' )';
1443 return ($sql, @$bind_aref);
1444 }
1445 elsif (@$clauses_aref) {
1446 return ($clauses_aref->[0], @$bind_aref); # no parentheses
1447 }
1448 else {
1449 return (); # if no SQL, ignore @$bind_aref
1450 }
1451}
1452
1453
1454# Fix SQL case, if so requested
1455sub _sqlcase {
96449e8e 1456 # LDNOTE: if $self->{case} is true, then it contains 'lower', so we
1457 # don't touch the argument ... crooked logic, but let's not change it!
07d7c35c 1458 return $_[0]->{case} ? $_[1] : uc($_[1]);
96449e8e 1459}
1460
1461
1462#======================================================================
1463# DISPATCHING FROM REFKIND
1464#======================================================================
1465
1466sub _refkind {
1467 my ($self, $data) = @_;
96449e8e 1468
955e77ca 1469 return 'UNDEF' unless defined $data;
1470
1471 # blessed objects are treated like scalars
1472 my $ref = (Scalar::Util::blessed $data) ? '' : ref $data;
1473
1474 return 'SCALAR' unless $ref;
1475
1476 my $n_steps = 1;
1477 while ($ref eq 'REF') {
96449e8e 1478 $data = $$data;
955e77ca 1479 $ref = (Scalar::Util::blessed $data) ? '' : ref $data;
1480 $n_steps++ if $ref;
96449e8e 1481 }
1482
848556bc 1483 return ($ref||'SCALAR') . ('REF' x $n_steps);
96449e8e 1484}
1485
1486sub _try_refkind {
1487 my ($self, $data) = @_;
1488 my @try = ($self->_refkind($data));
1489 push @try, 'SCALAR_or_UNDEF' if $try[0] eq 'SCALAR' || $try[0] eq 'UNDEF';
1490 push @try, 'FALLBACK';
955e77ca 1491 return \@try;
96449e8e 1492}
1493
1494sub _METHOD_FOR_refkind {
1495 my ($self, $meth_prefix, $data) = @_;
f39eaa60 1496
1497 my $method;
955e77ca 1498 for (@{$self->_try_refkind($data)}) {
f39eaa60 1499 $method = $self->can($meth_prefix."_".$_)
1500 and last;
1501 }
1502
1503 return $method || puke "cannot dispatch on '$meth_prefix' for ".$self->_refkind($data);
96449e8e 1504}
1505
1506
1507sub _SWITCH_refkind {
1508 my ($self, $data, $dispatch_table) = @_;
1509
f39eaa60 1510 my $coderef;
955e77ca 1511 for (@{$self->_try_refkind($data)}) {
f39eaa60 1512 $coderef = $dispatch_table->{$_}
1513 and last;
1514 }
1515
1516 puke "no dispatch entry for ".$self->_refkind($data)
1517 unless $coderef;
1518
96449e8e 1519 $coderef->();
1520}
1521
1522
1523
1524
1525#======================================================================
1526# VALUES, GENERATE, AUTOLOAD
1527#======================================================================
1528
1529# LDNOTE: original code from nwiger, didn't touch code in that section
1530# I feel the AUTOLOAD stuff should not be the default, it should
1531# only be activated on explicit demand by user.
1532
1533sub values {
1534 my $self = shift;
1535 my $data = shift || return;
1536 puke "Argument to ", __PACKAGE__, "->values must be a \\%hash"
1537 unless ref $data eq 'HASH';
bab725ce 1538
1539 my @all_bind;
ca4f826a 1540 foreach my $k (sort keys %$data) {
bab725ce 1541 my $v = $data->{$k};
1542 $self->_SWITCH_refkind($v, {
9d48860e 1543 ARRAYREF => sub {
bab725ce 1544 if ($self->{array_datatypes}) { # array datatype
1545 push @all_bind, $self->_bindtype($k, $v);
1546 }
1547 else { # literal SQL with bind
1548 my ($sql, @bind) = @$v;
1549 $self->_assert_bindval_matches_bindtype(@bind);
1550 push @all_bind, @bind;
1551 }
1552 },
1553 ARRAYREFREF => sub { # literal SQL with bind
1554 my ($sql, @bind) = @${$v};
1555 $self->_assert_bindval_matches_bindtype(@bind);
1556 push @all_bind, @bind;
1557 },
1558 SCALARREF => sub { # literal SQL without bind
1559 },
1560 SCALAR_or_UNDEF => sub {
1561 push @all_bind, $self->_bindtype($k, $v);
1562 },
1563 });
1564 }
1565
1566 return @all_bind;
96449e8e 1567}
1568
1569sub generate {
1570 my $self = shift;
1571
1572 my(@sql, @sqlq, @sqlv);
1573
1574 for (@_) {
1575 my $ref = ref $_;
1576 if ($ref eq 'HASH') {
1577 for my $k (sort keys %$_) {
1578 my $v = $_->{$k};
1579 my $r = ref $v;
1580 my $label = $self->_quote($k);
1581 if ($r eq 'ARRAY') {
fe3ae272 1582 # literal SQL with bind
1583 my ($sql, @bind) = @$v;
1584 $self->_assert_bindval_matches_bindtype(@bind);
96449e8e 1585 push @sqlq, "$label = $sql";
fe3ae272 1586 push @sqlv, @bind;
96449e8e 1587 } elsif ($r eq 'SCALAR') {
fe3ae272 1588 # literal SQL without bind
96449e8e 1589 push @sqlq, "$label = $$v";
9d48860e 1590 } else {
96449e8e 1591 push @sqlq, "$label = ?";
1592 push @sqlv, $self->_bindtype($k, $v);
1593 }
1594 }
1595 push @sql, $self->_sqlcase('set'), join ', ', @sqlq;
1596 } elsif ($ref eq 'ARRAY') {
1597 # unlike insert(), assume these are ONLY the column names, i.e. for SQL
1598 for my $v (@$_) {
1599 my $r = ref $v;
fe3ae272 1600 if ($r eq 'ARRAY') { # literal SQL with bind
1601 my ($sql, @bind) = @$v;
1602 $self->_assert_bindval_matches_bindtype(@bind);
1603 push @sqlq, $sql;
1604 push @sqlv, @bind;
1605 } elsif ($r eq 'SCALAR') { # literal SQL without bind
96449e8e 1606 # embedded literal SQL
1607 push @sqlq, $$v;
9d48860e 1608 } else {
96449e8e 1609 push @sqlq, '?';
1610 push @sqlv, $v;
1611 }
1612 }
1613 push @sql, '(' . join(', ', @sqlq) . ')';
1614 } elsif ($ref eq 'SCALAR') {
1615 # literal SQL
1616 push @sql, $$_;
1617 } else {
1618 # strings get case twiddled
1619 push @sql, $self->_sqlcase($_);
1620 }
1621 }
1622
1623 my $sql = join ' ', @sql;
1624
1625 # this is pretty tricky
1626 # if ask for an array, return ($stmt, @bind)
1627 # otherwise, s/?/shift @sqlv/ to put it inline
1628 if (wantarray) {
1629 return ($sql, @sqlv);
1630 } else {
1631 1 while $sql =~ s/\?/my $d = shift(@sqlv);
1632 ref $d ? $d->[1] : $d/e;
1633 return $sql;
1634 }
1635}
1636
1637
1638sub DESTROY { 1 }
1639
1640sub AUTOLOAD {
1641 # This allows us to check for a local, then _form, attr
1642 my $self = shift;
1643 my($name) = $AUTOLOAD =~ /.*::(.+)/;
1644 return $self->generate($name, @_);
1645}
1646
16471;
1648
1649
1650
1651__END__
32eab2da 1652
1653=head1 NAME
1654
1655SQL::Abstract - Generate SQL from Perl data structures
1656
1657=head1 SYNOPSIS
1658
1659 use SQL::Abstract;
1660
1661 my $sql = SQL::Abstract->new;
1662
85783f3c 1663 my($stmt, @bind) = $sql->select($source, \@fields, \%where, $order);
32eab2da 1664
1665 my($stmt, @bind) = $sql->insert($table, \%fieldvals || \@values);
1666
1667 my($stmt, @bind) = $sql->update($table, \%fieldvals, \%where);
1668
1669 my($stmt, @bind) = $sql->delete($table, \%where);
1670
1671 # Then, use these in your DBI statements
1672 my $sth = $dbh->prepare($stmt);
1673 $sth->execute(@bind);
1674
1675 # Just generate the WHERE clause
85783f3c 1676 my($stmt, @bind) = $sql->where(\%where, $order);
32eab2da 1677
1678 # Return values in the same order, for hashed queries
1679 # See PERFORMANCE section for more details
1680 my @bind = $sql->values(\%fieldvals);
1681
1682=head1 DESCRIPTION
1683
1684This module was inspired by the excellent L<DBIx::Abstract>.
1685However, in using that module I found that what I really wanted
1686to do was generate SQL, but still retain complete control over my
1687statement handles and use the DBI interface. So, I set out to
1688create an abstract SQL generation module.
1689
1690While based on the concepts used by L<DBIx::Abstract>, there are
1691several important differences, especially when it comes to WHERE
1692clauses. I have modified the concepts used to make the SQL easier
1693to generate from Perl data structures and, IMO, more intuitive.
1694The underlying idea is for this module to do what you mean, based
1695on the data structures you provide it. The big advantage is that
1696you don't have to modify your code every time your data changes,
1697as this module figures it out.
1698
1699To begin with, an SQL INSERT is as easy as just specifying a hash
1700of C<key=value> pairs:
1701
1702 my %data = (
1703 name => 'Jimbo Bobson',
1704 phone => '123-456-7890',
1705 address => '42 Sister Lane',
1706 city => 'St. Louis',
1707 state => 'Louisiana',
1708 );
1709
1710The SQL can then be generated with this:
1711
1712 my($stmt, @bind) = $sql->insert('people', \%data);
1713
1714Which would give you something like this:
1715
1716 $stmt = "INSERT INTO people
1717 (address, city, name, phone, state)
1718 VALUES (?, ?, ?, ?, ?)";
1719 @bind = ('42 Sister Lane', 'St. Louis', 'Jimbo Bobson',
1720 '123-456-7890', 'Louisiana');
1721
1722These are then used directly in your DBI code:
1723
1724 my $sth = $dbh->prepare($stmt);
1725 $sth->execute(@bind);
1726
96449e8e 1727=head2 Inserting and Updating Arrays
1728
1729If your database has array types (like for example Postgres),
1730activate the special option C<< array_datatypes => 1 >>
9d48860e 1731when creating the C<SQL::Abstract> object.
96449e8e 1732Then you may use an arrayref to insert and update database array types:
1733
1734 my $sql = SQL::Abstract->new(array_datatypes => 1);
1735 my %data = (
1736 planets => [qw/Mercury Venus Earth Mars/]
1737 );
9d48860e 1738
96449e8e 1739 my($stmt, @bind) = $sql->insert('solar_system', \%data);
1740
1741This results in:
1742
1743 $stmt = "INSERT INTO solar_system (planets) VALUES (?)"
1744
1745 @bind = (['Mercury', 'Venus', 'Earth', 'Mars']);
1746
1747
1748=head2 Inserting and Updating SQL
1749
1750In order to apply SQL functions to elements of your C<%data> you may
1751specify a reference to an arrayref for the given hash value. For example,
1752if you need to execute the Oracle C<to_date> function on a value, you can
1753say something like this:
32eab2da 1754
1755 my %data = (
1756 name => 'Bill',
3ae1c5e2 1757 date_entered => \[ "to_date(?,'MM/DD/YYYY')", "03/02/2003" ],
9d48860e 1758 );
32eab2da 1759
1760The first value in the array is the actual SQL. Any other values are
1761optional and would be included in the bind values array. This gives
1762you:
1763
1764 my($stmt, @bind) = $sql->insert('people', \%data);
1765
9d48860e 1766 $stmt = "INSERT INTO people (name, date_entered)
32eab2da 1767 VALUES (?, to_date(?,'MM/DD/YYYY'))";
1768 @bind = ('Bill', '03/02/2003');
1769
1770An UPDATE is just as easy, all you change is the name of the function:
1771
1772 my($stmt, @bind) = $sql->update('people', \%data);
1773
1774Notice that your C<%data> isn't touched; the module will generate
1775the appropriately quirky SQL for you automatically. Usually you'll
1776want to specify a WHERE clause for your UPDATE, though, which is
1777where handling C<%where> hashes comes in handy...
1778
96449e8e 1779=head2 Complex where statements
1780
32eab2da 1781This module can generate pretty complicated WHERE statements
1782easily. For example, simple C<key=value> pairs are taken to mean
1783equality, and if you want to see if a field is within a set
1784of values, you can use an arrayref. Let's say we wanted to
1785SELECT some data based on this criteria:
1786
1787 my %where = (
1788 requestor => 'inna',
1789 worker => ['nwiger', 'rcwe', 'sfz'],
1790 status => { '!=', 'completed' }
1791 );
1792
1793 my($stmt, @bind) = $sql->select('tickets', '*', \%where);
1794
1795The above would give you something like this:
1796
1797 $stmt = "SELECT * FROM tickets WHERE
1798 ( requestor = ? ) AND ( status != ? )
1799 AND ( worker = ? OR worker = ? OR worker = ? )";
1800 @bind = ('inna', 'completed', 'nwiger', 'rcwe', 'sfz');
1801
1802Which you could then use in DBI code like so:
1803
1804 my $sth = $dbh->prepare($stmt);
1805 $sth->execute(@bind);
1806
1807Easy, eh?
1808
0da0fe34 1809=head1 METHODS
32eab2da 1810
13cc86af 1811The methods are simple. There's one for every major SQL operation,
32eab2da 1812and a constructor you use first. The arguments are specified in a
13cc86af 1813similar order for each method (table, then fields, then a where
32eab2da 1814clause) to try and simplify things.
1815
32eab2da 1816=head2 new(option => 'value')
1817
1818The C<new()> function takes a list of options and values, and returns
1819a new B<SQL::Abstract> object which can then be used to generate SQL
1820through the methods below. The options accepted are:
1821
1822=over
1823
1824=item case
1825
1826If set to 'lower', then SQL will be generated in all lowercase. By
1827default SQL is generated in "textbook" case meaning something like:
1828
1829 SELECT a_field FROM a_table WHERE some_field LIKE '%someval%'
1830
96449e8e 1831Any setting other than 'lower' is ignored.
1832
32eab2da 1833=item cmp
1834
1835This determines what the default comparison operator is. By default
1836it is C<=>, meaning that a hash like this:
1837
1838 %where = (name => 'nwiger', email => 'nate@wiger.org');
1839
1840Will generate SQL like this:
1841
1842 WHERE name = 'nwiger' AND email = 'nate@wiger.org'
1843
1844However, you may want loose comparisons by default, so if you set
1845C<cmp> to C<like> you would get SQL such as:
1846
1847 WHERE name like 'nwiger' AND email like 'nate@wiger.org'
1848
3af02ccb 1849You can also override the comparison on an individual basis - see
32eab2da 1850the huge section on L</"WHERE CLAUSES"> at the bottom.
1851
96449e8e 1852=item sqltrue, sqlfalse
1853
1854Expressions for inserting boolean values within SQL statements.
6e0c6552 1855By default these are C<1=1> and C<1=0>. They are used
1856by the special operators C<-in> and C<-not_in> for generating
1857correct SQL even when the argument is an empty array (see below).
96449e8e 1858
32eab2da 1859=item logic
1860
1861This determines the default logical operator for multiple WHERE
7cac25e6 1862statements in arrays or hashes. If absent, the default logic is "or"
1863for arrays, and "and" for hashes. This means that a WHERE
32eab2da 1864array of the form:
1865
1866 @where = (
9d48860e 1867 event_date => {'>=', '2/13/99'},
1868 event_date => {'<=', '4/24/03'},
32eab2da 1869 );
1870
7cac25e6 1871will generate SQL like this:
32eab2da 1872
1873 WHERE event_date >= '2/13/99' OR event_date <= '4/24/03'
1874
1875This is probably not what you want given this query, though (look
1876at the dates). To change the "OR" to an "AND", simply specify:
1877
1878 my $sql = SQL::Abstract->new(logic => 'and');
1879
1880Which will change the above C<WHERE> to:
1881
1882 WHERE event_date >= '2/13/99' AND event_date <= '4/24/03'
1883
96449e8e 1884The logic can also be changed locally by inserting
be21dde3 1885a modifier in front of an arrayref:
96449e8e 1886
9d48860e 1887 @where = (-and => [event_date => {'>=', '2/13/99'},
7cac25e6 1888 event_date => {'<=', '4/24/03'} ]);
96449e8e 1889
1890See the L</"WHERE CLAUSES"> section for explanations.
1891
32eab2da 1892=item convert
1893
1894This will automatically convert comparisons using the specified SQL
1895function for both column and value. This is mostly used with an argument
1896of C<upper> or C<lower>, so that the SQL will have the effect of
1897case-insensitive "searches". For example, this:
1898
1899 $sql = SQL::Abstract->new(convert => 'upper');
1900 %where = (keywords => 'MaKe iT CAse inSeNSItive');
1901
1902Will turn out the following SQL:
1903
1904 WHERE upper(keywords) like upper('MaKe iT CAse inSeNSItive')
1905
1906The conversion can be C<upper()>, C<lower()>, or any other SQL function
1907that can be applied symmetrically to fields (actually B<SQL::Abstract> does
1908not validate this option; it will just pass through what you specify verbatim).
1909
1910=item bindtype
1911
1912This is a kludge because many databases suck. For example, you can't
1913just bind values using DBI's C<execute()> for Oracle C<CLOB> or C<BLOB> fields.
1914Instead, you have to use C<bind_param()>:
1915
1916 $sth->bind_param(1, 'reg data');
1917 $sth->bind_param(2, $lots, {ora_type => ORA_CLOB});
1918
1919The problem is, B<SQL::Abstract> will normally just return a C<@bind> array,
1920which loses track of which field each slot refers to. Fear not.
1921
1922If you specify C<bindtype> in new, you can determine how C<@bind> is returned.
1923Currently, you can specify either C<normal> (default) or C<columns>. If you
1924specify C<columns>, you will get an array that looks like this:
1925
1926 my $sql = SQL::Abstract->new(bindtype => 'columns');
1927 my($stmt, @bind) = $sql->insert(...);
1928
1929 @bind = (
1930 [ 'column1', 'value1' ],
1931 [ 'column2', 'value2' ],
1932 [ 'column3', 'value3' ],
1933 );
1934
1935You can then iterate through this manually, using DBI's C<bind_param()>.
e3f9dff4 1936
32eab2da 1937 $sth->prepare($stmt);
1938 my $i = 1;
1939 for (@bind) {
1940 my($col, $data) = @$_;
1941 if ($col eq 'details' || $col eq 'comments') {
1942 $sth->bind_param($i, $data, {ora_type => ORA_CLOB});
1943 } elsif ($col eq 'image') {
1944 $sth->bind_param($i, $data, {ora_type => ORA_BLOB});
1945 } else {
1946 $sth->bind_param($i, $data);
1947 }
1948 $i++;
1949 }
1950 $sth->execute; # execute without @bind now
1951
1952Now, why would you still use B<SQL::Abstract> if you have to do this crap?
1953Basically, the advantage is still that you don't have to care which fields
1954are or are not included. You could wrap that above C<for> loop in a simple
1955sub called C<bind_fields()> or something and reuse it repeatedly. You still
1956get a layer of abstraction over manual SQL specification.
1957
3ae1c5e2 1958Note that if you set L</bindtype> to C<columns>, the C<\[ $sql, @bind ]>
deb148a2 1959construct (see L</Literal SQL with placeholders and bind values (subqueries)>)
1960will expect the bind values in this format.
1961
32eab2da 1962=item quote_char
1963
1964This is the character that a table or column name will be quoted
9d48860e 1965with. By default this is an empty string, but you could set it to
32eab2da 1966the character C<`>, to generate SQL like this:
1967
1968 SELECT `a_field` FROM `a_table` WHERE `some_field` LIKE '%someval%'
1969
96449e8e 1970Alternatively, you can supply an array ref of two items, the first being the left
1971hand quote character, and the second the right hand quote character. For
1972example, you could supply C<['[',']']> for SQL Server 2000 compliant quotes
1973that generates SQL like this:
1974
1975 SELECT [a_field] FROM [a_table] WHERE [some_field] LIKE '%someval%'
1976
9d48860e 1977Quoting is useful if you have tables or columns names that are reserved
96449e8e 1978words in your database's SQL dialect.
32eab2da 1979
46be4313 1980=item escape_char
1981
1982This is the character that will be used to escape L</quote_char>s appearing
1983in an identifier before it has been quoted.
1984
80790166 1985The parameter default in case of a single L</quote_char> character is the quote
46be4313 1986character itself.
1987
1988When opening-closing-style quoting is used (L</quote_char> is an arrayref)
9de2bd86 1989this parameter defaults to the B<closing (right)> L</quote_char>. Occurrences
46be4313 1990of the B<opening (left)> L</quote_char> within the identifier are currently left
1991untouched. The default for opening-closing-style quotes may change in future
1992versions, thus you are B<strongly encouraged> to specify the escape character
1993explicitly.
1994
32eab2da 1995=item name_sep
1996
1997This is the character that separates a table and column name. It is
1998necessary to specify this when the C<quote_char> option is selected,
1999so that tables and column names can be individually quoted like this:
2000
2001 SELECT `table`.`one_field` FROM `table` WHERE `table`.`other_field` = 1
2002
b6251592 2003=item injection_guard
2004
2005A regular expression C<qr/.../> that is applied to any C<-function> and unquoted
2006column name specified in a query structure. This is a safety mechanism to avoid
2007injection attacks when mishandling user input e.g.:
2008
2009 my %condition_as_column_value_pairs = get_values_from_user();
2010 $sqla->select( ... , \%condition_as_column_value_pairs );
2011
2012If the expression matches an exception is thrown. Note that literal SQL
2013supplied via C<\'...'> or C<\['...']> is B<not> checked in any way.
2014
2015Defaults to checking for C<;> and the C<GO> keyword (TransactSQL)
2016
96449e8e 2017=item array_datatypes
32eab2da 2018
9d48860e 2019When this option is true, arrayrefs in INSERT or UPDATE are
2020interpreted as array datatypes and are passed directly
96449e8e 2021to the DBI layer.
2022When this option is false, arrayrefs are interpreted
2023as literal SQL, just like refs to arrayrefs
2024(but this behavior is for backwards compatibility; when writing
2025new queries, use the "reference to arrayref" syntax
2026for literal SQL).
32eab2da 2027
32eab2da 2028
96449e8e 2029=item special_ops
32eab2da 2030
9d48860e 2031Takes a reference to a list of "special operators"
96449e8e 2032to extend the syntax understood by L<SQL::Abstract>.
2033See section L</"SPECIAL OPERATORS"> for details.
32eab2da 2034
59f23b3d 2035=item unary_ops
2036
9d48860e 2037Takes a reference to a list of "unary operators"
59f23b3d 2038to extend the syntax understood by L<SQL::Abstract>.
2039See section L</"UNARY OPERATORS"> for details.
2040
32eab2da 2041
32eab2da 2042
96449e8e 2043=back
32eab2da 2044
02288357 2045=head2 insert($table, \@values || \%fieldvals, \%options)
32eab2da 2046
2047This is the simplest function. You simply give it a table name
2048and either an arrayref of values or hashref of field/value pairs.
2049It returns an SQL INSERT statement and a list of bind values.
96449e8e 2050See the sections on L</"Inserting and Updating Arrays"> and
2051L</"Inserting and Updating SQL"> for information on how to insert
2052with those data types.
32eab2da 2053
02288357 2054The optional C<\%options> hash reference may contain additional
2055options to generate the insert SQL. Currently supported options
2056are:
2057
2058=over 4
2059
2060=item returning
2061
2062Takes either a scalar of raw SQL fields, or an array reference of
2063field names, and adds on an SQL C<RETURNING> statement at the end.
2064This allows you to return data generated by the insert statement
2065(such as row IDs) without performing another C<SELECT> statement.
2066Note, however, this is not part of the SQL standard and may not
2067be supported by all database engines.
2068
2069=back
2070
95904db5 2071=head2 update($table, \%fieldvals, \%where, \%options)
32eab2da 2072
2073This takes a table, hashref of field/value pairs, and an optional
86298391 2074hashref L<WHERE clause|/WHERE CLAUSES>. It returns an SQL UPDATE function and a list
32eab2da 2075of bind values.
96449e8e 2076See the sections on L</"Inserting and Updating Arrays"> and
2077L</"Inserting and Updating SQL"> for information on how to insert
2078with those data types.
32eab2da 2079
95904db5 2080The optional C<\%options> hash reference may contain additional
2081options to generate the update SQL. Currently supported options
2082are:
2083
2084=over 4
2085
2086=item returning
2087
2088See the C<returning> option to
2089L<insert|/insert($table, \@values || \%fieldvals, \%options)>.
2090
2091=back
2092
96449e8e 2093=head2 select($source, $fields, $where, $order)
32eab2da 2094
9d48860e 2095This returns a SQL SELECT statement and associated list of bind values, as
be21dde3 2096specified by the arguments:
32eab2da 2097
96449e8e 2098=over
32eab2da 2099
96449e8e 2100=item $source
32eab2da 2101
9d48860e 2102Specification of the 'FROM' part of the statement.
96449e8e 2103The argument can be either a plain scalar (interpreted as a table
2104name, will be quoted), or an arrayref (interpreted as a list
2105of table names, joined by commas, quoted), or a scalarref
063097a3 2106(literal SQL, not quoted).
32eab2da 2107
96449e8e 2108=item $fields
32eab2da 2109
9d48860e 2110Specification of the list of fields to retrieve from
96449e8e 2111the source.
2112The argument can be either an arrayref (interpreted as a list
9d48860e 2113of field names, will be joined by commas and quoted), or a
96449e8e 2114plain scalar (literal SQL, not quoted).
521647e7 2115Please observe that this API is not as flexible as that of
2116the first argument C<$source>, for backwards compatibility reasons.
32eab2da 2117
96449e8e 2118=item $where
32eab2da 2119
96449e8e 2120Optional argument to specify the WHERE part of the query.
2121The argument is most often a hashref, but can also be
9d48860e 2122an arrayref or plain scalar --
96449e8e 2123see section L<WHERE clause|/"WHERE CLAUSES"> for details.
32eab2da 2124
96449e8e 2125=item $order
32eab2da 2126
96449e8e 2127Optional argument to specify the ORDER BY part of the query.
9d48860e 2128The argument can be a scalar, a hashref or an arrayref
96449e8e 2129-- see section L<ORDER BY clause|/"ORDER BY CLAUSES">
2130for details.
32eab2da 2131
96449e8e 2132=back
32eab2da 2133
32eab2da 2134
85327cd5 2135=head2 delete($table, \%where, \%options)
32eab2da 2136
86298391 2137This takes a table name and optional hashref L<WHERE clause|/WHERE CLAUSES>.
32eab2da 2138It returns an SQL DELETE statement and list of bind values.
2139
85327cd5 2140The optional C<\%options> hash reference may contain additional
2141options to generate the delete SQL. Currently supported options
2142are:
2143
2144=over 4
2145
2146=item returning
2147
2148See the C<returning> option to
2149L<insert|/insert($table, \@values || \%fieldvals, \%options)>.
2150
2151=back
2152
85783f3c 2153=head2 where(\%where, $order)
32eab2da 2154
2155This is used to generate just the WHERE clause. For example,
2156if you have an arbitrary data structure and know what the
2157rest of your SQL is going to look like, but want an easy way
2158to produce a WHERE clause, use this. It returns an SQL WHERE
2159clause and list of bind values.
2160
32eab2da 2161
2162=head2 values(\%data)
2163
2164This just returns the values from the hash C<%data>, in the same
2165order that would be returned from any of the other above queries.
2166Using this allows you to markedly speed up your queries if you
2167are affecting lots of rows. See below under the L</"PERFORMANCE"> section.
2168
32eab2da 2169=head2 generate($any, 'number', $of, \@data, $struct, \%types)
2170
2171Warning: This is an experimental method and subject to change.
2172
2173This returns arbitrarily generated SQL. It's a really basic shortcut.
2174It will return two different things, depending on return context:
2175
2176 my($stmt, @bind) = $sql->generate('create table', \$table, \@fields);
2177 my $stmt_and_val = $sql->generate('create table', \$table, \@fields);
2178
2179These would return the following:
2180
2181 # First calling form
2182 $stmt = "CREATE TABLE test (?, ?)";
2183 @bind = (field1, field2);
2184
2185 # Second calling form
2186 $stmt_and_val = "CREATE TABLE test (field1, field2)";
2187
2188Depending on what you're trying to do, it's up to you to choose the correct
2189format. In this example, the second form is what you would want.
2190
2191By the same token:
2192
2193 $sql->generate('alter session', { nls_date_format => 'MM/YY' });
2194
2195Might give you:
2196
2197 ALTER SESSION SET nls_date_format = 'MM/YY'
2198
2199You get the idea. Strings get their case twiddled, but everything
2200else remains verbatim.
2201
0da0fe34 2202=head1 EXPORTABLE FUNCTIONS
2203
2204=head2 is_plain_value
2205
2206Determines if the supplied argument is a plain value as understood by this
2207module:
2208
2209=over
2210
2211=item * The value is C<undef>
2212
2213=item * The value is a non-reference
2214
2215=item * The value is an object with stringification overloading
2216
2217=item * The value is of the form C<< { -value => $anything } >>
2218
2219=back
2220
9de2bd86 2221On failure returns C<undef>, on success returns a B<scalar> reference
966200cc 2222to the original supplied argument.
0da0fe34 2223
843a94b5 2224=over
2225
2226=item * Note
2227
2228The stringification overloading detection is rather advanced: it takes
2229into consideration not only the presence of a C<""> overload, but if that
2230fails also checks for enabled
2231L<autogenerated versions of C<"">|overload/Magic Autogeneration>, based
2232on either C<0+> or C<bool>.
2233
2234Unfortunately testing in the field indicates that this
2235detection B<< may tickle a latent bug in perl versions before 5.018 >>,
2236but only when very large numbers of stringifying objects are involved.
2237At the time of writing ( Sep 2014 ) there is no clear explanation of
2238the direct cause, nor is there a manageably small test case that reliably
2239reproduces the problem.
2240
2241If you encounter any of the following exceptions in B<random places within
2242your application stack> - this module may be to blame:
2243
2244 Operation "ne": no method found,
2245 left argument in overloaded package <something>,
2246 right argument in overloaded package <something>
2247
2248or perhaps even
2249
2250 Stub found while resolving method "???" overloading """" in package <something>
2251
2252If you fall victim to the above - please attempt to reduce the problem
2253to something that could be sent to the L<SQL::Abstract developers
1f490ae4 2254|DBIx::Class/GETTING HELP/SUPPORT>
843a94b5 2255(either publicly or privately). As a workaround in the meantime you can
2256set C<$ENV{SQLA_ISVALUE_IGNORE_AUTOGENERATED_STRINGIFICATION}> to a true
2257value, which will most likely eliminate your problem (at the expense of
2258not being able to properly detect exotic forms of stringification).
2259
2260This notice and environment variable will be removed in a future version,
2261as soon as the underlying problem is found and a reliable workaround is
2262devised.
2263
2264=back
2265
0da0fe34 2266=head2 is_literal_value
2267
2268Determines if the supplied argument is a literal value as understood by this
2269module:
2270
2271=over
2272
2273=item * C<\$sql_string>
2274
2275=item * C<\[ $sql_string, @bind_values ]>
2276
0da0fe34 2277=back
2278
9de2bd86 2279On failure returns C<undef>, on success returns an B<array> reference
966200cc 2280containing the unpacked version of the supplied literal SQL and bind values.
0da0fe34 2281
32eab2da 2282=head1 WHERE CLAUSES
2283
96449e8e 2284=head2 Introduction
2285
32eab2da 2286This module uses a variation on the idea from L<DBIx::Abstract>. It
2287is B<NOT>, repeat I<not> 100% compatible. B<The main logic of this
2288module is that things in arrays are OR'ed, and things in hashes
2289are AND'ed.>
2290
2291The easiest way to explain is to show lots of examples. After
2292each C<%where> hash shown, it is assumed you used:
2293
2294 my($stmt, @bind) = $sql->where(\%where);
2295
2296However, note that the C<%where> hash can be used directly in any
2297of the other functions as well, as described above.
2298
96449e8e 2299=head2 Key-value pairs
2300
32eab2da 2301So, let's get started. To begin, a simple hash:
2302
2303 my %where = (
2304 user => 'nwiger',
2305 status => 'completed'
2306 );
2307
2308Is converted to SQL C<key = val> statements:
2309
2310 $stmt = "WHERE user = ? AND status = ?";
2311 @bind = ('nwiger', 'completed');
2312
2313One common thing I end up doing is having a list of values that
2314a field can be in. To do this, simply specify a list inside of
2315an arrayref:
2316
2317 my %where = (
2318 user => 'nwiger',
2319 status => ['assigned', 'in-progress', 'pending'];
2320 );
2321
2322This simple code will create the following:
9d48860e 2323
32eab2da 2324 $stmt = "WHERE user = ? AND ( status = ? OR status = ? OR status = ? )";
2325 @bind = ('nwiger', 'assigned', 'in-progress', 'pending');
2326
9d48860e 2327A field associated to an empty arrayref will be considered a
7cac25e6 2328logical false and will generate 0=1.
8a68b5be 2329
b864ba9b 2330=head2 Tests for NULL values
2331
2332If the value part is C<undef> then this is converted to SQL <IS NULL>
2333
2334 my %where = (
2335 user => 'nwiger',
2336 status => undef,
2337 );
2338
2339becomes:
2340
2341 $stmt = "WHERE user = ? AND status IS NULL";
2342 @bind = ('nwiger');
2343
e9614080 2344To test if a column IS NOT NULL:
2345
2346 my %where = (
2347 user => 'nwiger',
2348 status => { '!=', undef },
2349 );
cc422895 2350
6e0c6552 2351=head2 Specific comparison operators
96449e8e 2352
32eab2da 2353If you want to specify a different type of operator for your comparison,
2354you can use a hashref for a given column:
2355
2356 my %where = (
2357 user => 'nwiger',
2358 status => { '!=', 'completed' }
2359 );
2360
2361Which would generate:
2362
2363 $stmt = "WHERE user = ? AND status != ?";
2364 @bind = ('nwiger', 'completed');
2365
2366To test against multiple values, just enclose the values in an arrayref:
2367
96449e8e 2368 status => { '=', ['assigned', 'in-progress', 'pending'] };
2369
f2d5020d 2370Which would give you:
96449e8e 2371
2372 "WHERE status = ? OR status = ? OR status = ?"
2373
2374
2375The hashref can also contain multiple pairs, in which case it is expanded
32eab2da 2376into an C<AND> of its elements:
2377
2378 my %where = (
2379 user => 'nwiger',
2380 status => { '!=', 'completed', -not_like => 'pending%' }
2381 );
2382
2383 # Or more dynamically, like from a form
2384 $where{user} = 'nwiger';
2385 $where{status}{'!='} = 'completed';
2386 $where{status}{'-not_like'} = 'pending%';
2387
2388 # Both generate this
2389 $stmt = "WHERE user = ? AND status != ? AND status NOT LIKE ?";
2390 @bind = ('nwiger', 'completed', 'pending%');
2391
96449e8e 2392
32eab2da 2393To get an OR instead, you can combine it with the arrayref idea:
2394
2395 my %where => (
2396 user => 'nwiger',
1a6f2a03 2397 priority => [ { '=', 2 }, { '>', 5 } ]
32eab2da 2398 );
2399
2400Which would generate:
2401
1a6f2a03 2402 $stmt = "WHERE ( priority = ? OR priority > ? ) AND user = ?";
2403 @bind = ('2', '5', 'nwiger');
32eab2da 2404
44b9e502 2405If you want to include literal SQL (with or without bind values), just use a
13cc86af 2406scalar reference or reference to an arrayref as the value:
44b9e502 2407
2408 my %where = (
2409 date_entered => { '>' => \["to_date(?, 'MM/DD/YYYY')", "11/26/2008"] },
2410 date_expires => { '<' => \"now()" }
2411 );
2412
2413Which would generate:
2414
13cc86af 2415 $stmt = "WHERE date_entered > to_date(?, 'MM/DD/YYYY') AND date_expires < now()";
44b9e502 2416 @bind = ('11/26/2008');
2417
96449e8e 2418
2419=head2 Logic and nesting operators
2420
2421In the example above,
2422there is a subtle trap if you want to say something like
32eab2da 2423this (notice the C<AND>):
2424
2425 WHERE priority != ? AND priority != ?
2426
2427Because, in Perl you I<can't> do this:
2428
13cc86af 2429 priority => { '!=' => 2, '!=' => 1 }
32eab2da 2430
2431As the second C<!=> key will obliterate the first. The solution
2432is to use the special C<-modifier> form inside an arrayref:
2433
9d48860e 2434 priority => [ -and => {'!=', 2},
96449e8e 2435 {'!=', 1} ]
2436
32eab2da 2437
2438Normally, these would be joined by C<OR>, but the modifier tells it
2439to use C<AND> instead. (Hint: You can use this in conjunction with the
2440C<logic> option to C<new()> in order to change the way your queries
2441work by default.) B<Important:> Note that the C<-modifier> goes
2442B<INSIDE> the arrayref, as an extra first element. This will
2443B<NOT> do what you think it might:
2444
2445 priority => -and => [{'!=', 2}, {'!=', 1}] # WRONG!
2446
2447Here is a quick list of equivalencies, since there is some overlap:
2448
2449 # Same
2450 status => {'!=', 'completed', 'not like', 'pending%' }
2451 status => [ -and => {'!=', 'completed'}, {'not like', 'pending%'}]
2452
2453 # Same
2454 status => {'=', ['assigned', 'in-progress']}
2455 status => [ -or => {'=', 'assigned'}, {'=', 'in-progress'}]
2456 status => [ {'=', 'assigned'}, {'=', 'in-progress'} ]
2457
e3f9dff4 2458
2459
be21dde3 2460=head2 Special operators: IN, BETWEEN, etc.
96449e8e 2461
32eab2da 2462You can also use the hashref format to compare a list of fields using the
2463C<IN> comparison operator, by specifying the list as an arrayref:
2464
2465 my %where = (
2466 status => 'completed',
2467 reportid => { -in => [567, 2335, 2] }
2468 );
2469
2470Which would generate:
2471
2472 $stmt = "WHERE status = ? AND reportid IN (?,?,?)";
2473 @bind = ('completed', '567', '2335', '2');
2474
9d48860e 2475The reverse operator C<-not_in> generates SQL C<NOT IN> and is used in
96449e8e 2476the same way.
2477
6e0c6552 2478If the argument to C<-in> is an empty array, 'sqlfalse' is generated
be21dde3 2479(by default: C<1=0>). Similarly, C<< -not_in => [] >> generates
2480'sqltrue' (by default: C<1=1>).
6e0c6552 2481
e41c3bdd 2482In addition to the array you can supply a chunk of literal sql or
2483literal sql with bind:
6e0c6552 2484
e41c3bdd 2485 my %where = {
2486 customer => { -in => \[
2487 'SELECT cust_id FROM cust WHERE balance > ?',
2488 2000,
2489 ],
2490 status => { -in => \'SELECT status_codes FROM states' },
2491 };
6e0c6552 2492
e41c3bdd 2493would generate:
2494
2495 $stmt = "WHERE (
2496 customer IN ( SELECT cust_id FROM cust WHERE balance > ? )
2497 AND status IN ( SELECT status_codes FROM states )
2498 )";
2499 @bind = ('2000');
2500
0dfd2442 2501Finally, if the argument to C<-in> is not a reference, it will be
2502treated as a single-element array.
e41c3bdd 2503
2504Another pair of operators is C<-between> and C<-not_between>,
96449e8e 2505used with an arrayref of two values:
32eab2da 2506
2507 my %where = (
2508 user => 'nwiger',
2509 completion_date => {
2510 -not_between => ['2002-10-01', '2003-02-06']
2511 }
2512 );
2513
2514Would give you:
2515
2516 WHERE user = ? AND completion_date NOT BETWEEN ( ? AND ? )
2517
e41c3bdd 2518Just like with C<-in> all plausible combinations of literal SQL
2519are possible:
2520
2521 my %where = {
2522 start0 => { -between => [ 1, 2 ] },
2523 start1 => { -between => \["? AND ?", 1, 2] },
2524 start2 => { -between => \"lower(x) AND upper(y)" },
9d48860e 2525 start3 => { -between => [
e41c3bdd 2526 \"lower(x)",
2527 \["upper(?)", 'stuff' ],
2528 ] },
2529 };
2530
2531Would give you:
2532
2533 $stmt = "WHERE (
2534 ( start0 BETWEEN ? AND ? )
2535 AND ( start1 BETWEEN ? AND ? )
2536 AND ( start2 BETWEEN lower(x) AND upper(y) )
2537 AND ( start3 BETWEEN lower(x) AND upper(?) )
2538 )";
2539 @bind = (1, 2, 1, 2, 'stuff');
2540
2541
9d48860e 2542These are the two builtin "special operators"; but the
be21dde3 2543list can be expanded: see section L</"SPECIAL OPERATORS"> below.
96449e8e 2544
59f23b3d 2545=head2 Unary operators: bool
97a920ef 2546
2547If you wish to test against boolean columns or functions within your
2548database you can use the C<-bool> and C<-not_bool> operators. For
2549example to test the column C<is_user> being true and the column
827bb0eb 2550C<is_enabled> being false you would use:-
97a920ef 2551
2552 my %where = (
2553 -bool => 'is_user',
2554 -not_bool => 'is_enabled',
2555 );
2556
2557Would give you:
2558
277b5d3f 2559 WHERE is_user AND NOT is_enabled
97a920ef 2560
0b604e9d 2561If a more complex combination is required, testing more conditions,
2562then you should use the and/or operators:-
2563
2564 my %where = (
2565 -and => [
2566 -bool => 'one',
23401b81 2567 -not_bool => { two=> { -rlike => 'bar' } },
2568 -not_bool => { three => [ { '=', 2 }, { '>', 5 } ] },
0b604e9d 2569 ],
2570 );
2571
2572Would give you:
2573
23401b81 2574 WHERE
2575 one
2576 AND
2577 (NOT two RLIKE ?)
2578 AND
2579 (NOT ( three = ? OR three > ? ))
97a920ef 2580
2581
107b72f1 2582=head2 Nested conditions, -and/-or prefixes
96449e8e 2583
32eab2da 2584So far, we've seen how multiple conditions are joined with a top-level
2585C<AND>. We can change this by putting the different conditions we want in
2586hashes and then putting those hashes in an array. For example:
2587
2588 my @where = (
2589 {
2590 user => 'nwiger',
2591 status => { -like => ['pending%', 'dispatched'] },
2592 },
2593 {
2594 user => 'robot',
2595 status => 'unassigned',
2596 }
2597 );
2598
2599This data structure would create the following:
2600
2601 $stmt = "WHERE ( user = ? AND ( status LIKE ? OR status LIKE ? ) )
2602 OR ( user = ? AND status = ? ) )";
2603 @bind = ('nwiger', 'pending', 'dispatched', 'robot', 'unassigned');
2604
107b72f1 2605
48d9f5f8 2606Clauses in hashrefs or arrayrefs can be prefixed with an C<-and> or C<-or>
be21dde3 2607to change the logic inside:
32eab2da 2608
2609 my @where = (
2610 -and => [
2611 user => 'nwiger',
48d9f5f8 2612 [
2613 -and => [ workhrs => {'>', 20}, geo => 'ASIA' ],
2614 -or => { workhrs => {'<', 50}, geo => 'EURO' },
32eab2da 2615 ],
2616 ],
2617 );
2618
2619That would yield:
2620
13cc86af 2621 $stmt = "WHERE ( user = ?
2622 AND ( ( workhrs > ? AND geo = ? )
2623 OR ( workhrs < ? OR geo = ? ) ) )";
2624 @bind = ('nwiger', '20', 'ASIA', '50', 'EURO');
107b72f1 2625
cc422895 2626=head3 Algebraic inconsistency, for historical reasons
107b72f1 2627
7cac25e6 2628C<Important note>: when connecting several conditions, the C<-and->|C<-or>
2629operator goes C<outside> of the nested structure; whereas when connecting
2630several constraints on one column, the C<-and> operator goes
be21dde3 2631C<inside> the arrayref. Here is an example combining both features:
7cac25e6 2632
2633 my @where = (
2634 -and => [a => 1, b => 2],
2635 -or => [c => 3, d => 4],
2636 e => [-and => {-like => 'foo%'}, {-like => '%bar'} ]
2637 )
2638
2639yielding
2640
9d48860e 2641 WHERE ( ( ( a = ? AND b = ? )
2642 OR ( c = ? OR d = ? )
7cac25e6 2643 OR ( e LIKE ? AND e LIKE ? ) ) )
2644
107b72f1 2645This difference in syntax is unfortunate but must be preserved for
be21dde3 2646historical reasons. So be careful: the two examples below would
107b72f1 2647seem algebraically equivalent, but they are not
2648
a948b1fe 2649 { col => [ -and =>
2650 { -like => 'foo%' },
2651 { -like => '%bar' },
2652 ] }
be21dde3 2653 # yields: WHERE ( ( col LIKE ? AND col LIKE ? ) )
107b72f1 2654
a948b1fe 2655 [ -and =>
2656 { col => { -like => 'foo%' } },
2657 { col => { -like => '%bar' } },
2658 ]
be21dde3 2659 # yields: WHERE ( ( col LIKE ? OR col LIKE ? ) )
107b72f1 2660
7cac25e6 2661
cc422895 2662=head2 Literal SQL and value type operators
96449e8e 2663
cc422895 2664The basic premise of SQL::Abstract is that in WHERE specifications the "left
2665side" is a column name and the "right side" is a value (normally rendered as
2666a placeholder). This holds true for both hashrefs and arrayref pairs as you
2667see in the L</WHERE CLAUSES> examples above. Sometimes it is necessary to
2668alter this behavior. There are several ways of doing so.
e9614080 2669
cc422895 2670=head3 -ident
2671
2672This is a virtual operator that signals the string to its right side is an
2673identifier (a column name) and not a value. For example to compare two
2674columns you would write:
32eab2da 2675
e9614080 2676 my %where = (
2677 priority => { '<', 2 },
cc422895 2678 requestor => { -ident => 'submitter' },
e9614080 2679 );
2680
2681which creates:
2682
2683 $stmt = "WHERE priority < ? AND requestor = submitter";
2684 @bind = ('2');
2685
cc422895 2686If you are maintaining legacy code you may see a different construct as
2687described in L</Deprecated usage of Literal SQL>, please use C<-ident> in new
2688code.
2689
2690=head3 -value
e9614080 2691
cc422895 2692This is a virtual operator that signals that the construct to its right side
2693is a value to be passed to DBI. This is for example necessary when you want
2694to write a where clause against an array (for RDBMS that support such
2695datatypes). For example:
e9614080 2696
32eab2da 2697 my %where = (
cc422895 2698 array => { -value => [1, 2, 3] }
32eab2da 2699 );
2700
cc422895 2701will result in:
32eab2da 2702
cc422895 2703 $stmt = 'WHERE array = ?';
2704 @bind = ([1, 2, 3]);
32eab2da 2705
cc422895 2706Note that if you were to simply say:
32eab2da 2707
2708 my %where = (
cc422895 2709 array => [1, 2, 3]
32eab2da 2710 );
2711
3af02ccb 2712the result would probably not be what you wanted:
cc422895 2713
2714 $stmt = 'WHERE array = ? OR array = ? OR array = ?';
2715 @bind = (1, 2, 3);
2716
2717=head3 Literal SQL
96449e8e 2718
cc422895 2719Finally, sometimes only literal SQL will do. To include a random snippet
2720of SQL verbatim, you specify it as a scalar reference. Consider this only
2721as a last resort. Usually there is a better way. For example:
96449e8e 2722
2723 my %where = (
cc422895 2724 priority => { '<', 2 },
2725 requestor => { -in => \'(SELECT name FROM hitmen)' },
96449e8e 2726 );
2727
cc422895 2728Would create:
96449e8e 2729
cc422895 2730 $stmt = "WHERE priority < ? AND requestor IN (SELECT name FROM hitmen)"
2731 @bind = (2);
2732
2733Note that in this example, you only get one bind parameter back, since
2734the verbatim SQL is passed as part of the statement.
2735
2736=head4 CAVEAT
2737
2738 Never use untrusted input as a literal SQL argument - this is a massive
2739 security risk (there is no way to check literal snippets for SQL
2740 injections and other nastyness). If you need to deal with untrusted input
2741 use literal SQL with placeholders as described next.
96449e8e 2742
cc422895 2743=head3 Literal SQL with placeholders and bind values (subqueries)
96449e8e 2744
2745If the literal SQL to be inserted has placeholders and bind values,
2746use a reference to an arrayref (yes this is a double reference --
2747not so common, but perfectly legal Perl). For example, to find a date
2748in Postgres you can use something like this:
2749
2750 my %where = (
3ae1c5e2 2751 date_column => \[ "= date '2008-09-30' - ?::integer", 10 ]
96449e8e 2752 )
2753
2754This would create:
2755
d2a8fe1a 2756 $stmt = "WHERE ( date_column = date '2008-09-30' - ?::integer )"
96449e8e 2757 @bind = ('10');
2758
deb148a2 2759Note that you must pass the bind values in the same format as they are returned
85783f3c 2760by L<where|/where(\%where, $order)>. This means that if you set L</bindtype>
1f490ae4 2761to C<columns>, you must provide the bind values in the
2762C<< [ column_meta => value ] >> format, where C<column_meta> is an opaque
2763scalar value; most commonly the column name, but you can use any scalar value
2764(including references and blessed references), L<SQL::Abstract> will simply
2765pass it through intact. So if C<bindtype> is set to C<columns> the above
2766example will look like:
deb148a2 2767
2768 my %where = (
3ae1c5e2 2769 date_column => \[ "= date '2008-09-30' - ?::integer", [ {} => 10 ] ]
deb148a2 2770 )
96449e8e 2771
2772Literal SQL is especially useful for nesting parenthesized clauses in the
be21dde3 2773main SQL query. Here is a first example:
96449e8e 2774
2775 my ($sub_stmt, @sub_bind) = ("SELECT c1 FROM t1 WHERE c2 < ? AND c3 LIKE ?",
2776 100, "foo%");
2777 my %where = (
2778 foo => 1234,
2779 bar => \["IN ($sub_stmt)" => @sub_bind],
2780 );
2781
be21dde3 2782This yields:
96449e8e 2783
9d48860e 2784 $stmt = "WHERE (foo = ? AND bar IN (SELECT c1 FROM t1
96449e8e 2785 WHERE c2 < ? AND c3 LIKE ?))";
2786 @bind = (1234, 100, "foo%");
2787
9d48860e 2788Other subquery operators, like for example C<"E<gt> ALL"> or C<"NOT IN">,
96449e8e 2789are expressed in the same way. Of course the C<$sub_stmt> and
9d48860e 2790its associated bind values can be generated through a former call
96449e8e 2791to C<select()> :
2792
2793 my ($sub_stmt, @sub_bind)
9d48860e 2794 = $sql->select("t1", "c1", {c2 => {"<" => 100},
96449e8e 2795 c3 => {-like => "foo%"}});
2796 my %where = (
2797 foo => 1234,
2798 bar => \["> ALL ($sub_stmt)" => @sub_bind],
2799 );
2800
2801In the examples above, the subquery was used as an operator on a column;
9d48860e 2802but the same principle also applies for a clause within the main C<%where>
be21dde3 2803hash, like an EXISTS subquery:
96449e8e 2804
9d48860e 2805 my ($sub_stmt, @sub_bind)
96449e8e 2806 = $sql->select("t1", "*", {c1 => 1, c2 => \"> t0.c0"});
48d9f5f8 2807 my %where = ( -and => [
96449e8e 2808 foo => 1234,
48d9f5f8 2809 \["EXISTS ($sub_stmt)" => @sub_bind],
2810 ]);
96449e8e 2811
2812which yields
2813
9d48860e 2814 $stmt = "WHERE (foo = ? AND EXISTS (SELECT * FROM t1
96449e8e 2815 WHERE c1 = ? AND c2 > t0.c0))";
2816 @bind = (1234, 1);
2817
2818
9d48860e 2819Observe that the condition on C<c2> in the subquery refers to
be21dde3 2820column C<t0.c0> of the main query: this is I<not> a bind
9d48860e 2821value, so we have to express it through a scalar ref.
96449e8e 2822Writing C<< c2 => {">" => "t0.c0"} >> would have generated
2823C<< c2 > ? >> with bind value C<"t0.c0"> ... not exactly
2824what we wanted here.
2825
96449e8e 2826Finally, here is an example where a subquery is used
2827for expressing unary negation:
2828
9d48860e 2829 my ($sub_stmt, @sub_bind)
96449e8e 2830 = $sql->where({age => [{"<" => 10}, {">" => 20}]});
2831 $sub_stmt =~ s/^ where //i; # don't want "WHERE" in the subclause
2832 my %where = (
2833 lname => {like => '%son%'},
48d9f5f8 2834 \["NOT ($sub_stmt)" => @sub_bind],
96449e8e 2835 );
2836
2837This yields
2838
2839 $stmt = "lname LIKE ? AND NOT ( age < ? OR age > ? )"
2840 @bind = ('%son%', 10, 20)
2841
cc422895 2842=head3 Deprecated usage of Literal SQL
2843
2844Below are some examples of archaic use of literal SQL. It is shown only as
2845reference for those who deal with legacy code. Each example has a much
2846better, cleaner and safer alternative that users should opt for in new code.
2847
2848=over
2849
2850=item *
2851
2852 my %where = ( requestor => \'IS NOT NULL' )
2853
2854 $stmt = "WHERE requestor IS NOT NULL"
2855
2856This used to be the way of generating NULL comparisons, before the handling
2857of C<undef> got formalized. For new code please use the superior syntax as
2858described in L</Tests for NULL values>.
96449e8e 2859
cc422895 2860=item *
2861
2862 my %where = ( requestor => \'= submitter' )
2863
2864 $stmt = "WHERE requestor = submitter"
2865
2866This used to be the only way to compare columns. Use the superior L</-ident>
2867method for all new code. For example an identifier declared in such a way
2868will be properly quoted if L</quote_char> is properly set, while the legacy
2869form will remain as supplied.
2870
2871=item *
2872
2873 my %where = ( is_ready => \"", completed => { '>', '2012-12-21' } )
2874
2875 $stmt = "WHERE completed > ? AND is_ready"
2876 @bind = ('2012-12-21')
2877
2878Using an empty string literal used to be the only way to express a boolean.
2879For all new code please use the much more readable
2880L<-bool|/Unary operators: bool> operator.
2881
2882=back
96449e8e 2883
2884=head2 Conclusion
2885
32eab2da 2886These pages could go on for a while, since the nesting of the data
2887structures this module can handle are pretty much unlimited (the
2888module implements the C<WHERE> expansion as a recursive function
2889internally). Your best bet is to "play around" with the module a
2890little to see how the data structures behave, and choose the best
2891format for your data based on that.
2892
2893And of course, all the values above will probably be replaced with
2894variables gotten from forms or the command line. After all, if you
2895knew everything ahead of time, you wouldn't have to worry about
2896dynamically-generating SQL and could just hardwire it into your
2897script.
2898
86298391 2899=head1 ORDER BY CLAUSES
2900
9d48860e 2901Some functions take an order by clause. This can either be a scalar (just a
18710f60 2902column name), a hashref of C<< { -desc => 'col' } >> or C<< { -asc => 'col' }
2903>>, a scalarref, an arrayref-ref, or an arrayref of any of the previous
2904forms. Examples:
1cfa1db3 2905
8c15b421 2906 Given | Will Generate
18710f60 2907 ---------------------------------------------------------------
8c15b421 2908 |
2909 'colA' | ORDER BY colA
2910 |
2911 [qw/colA colB/] | ORDER BY colA, colB
2912 |
2913 {-asc => 'colA'} | ORDER BY colA ASC
2914 |
2915 {-desc => 'colB'} | ORDER BY colB DESC
2916 |
2917 ['colA', {-asc => 'colB'}] | ORDER BY colA, colB ASC
2918 |
2919 { -asc => [qw/colA colB/] } | ORDER BY colA ASC, colB ASC
2920 |
2921 \'colA DESC' | ORDER BY colA DESC
2922 |
2923 \[ 'FUNC(colA, ?)', $x ] | ORDER BY FUNC(colA, ?)
2924 | /* ...with $x bound to ? */
2925 |
bd805d85 2926 [ | ORDER BY
2927 { -asc => 'colA' }, | colA ASC,
2928 { -desc => [qw/colB/] }, | colB DESC,
2929 { -asc => [qw/colC colD/] },| colC ASC, colD ASC,
2930 \'colE DESC', | colE DESC,
2931 \[ 'FUNC(colF, ?)', $x ], | FUNC(colF, ?)
2932 ] | /* ...with $x bound to ? */
18710f60 2933 ===============================================================
86298391 2934
96449e8e 2935
2936
2937=head1 SPECIAL OPERATORS
2938
e3f9dff4 2939 my $sqlmaker = SQL::Abstract->new(special_ops => [
3a2e1a5e 2940 {
2941 regex => qr/.../,
e3f9dff4 2942 handler => sub {
2943 my ($self, $field, $op, $arg) = @_;
2944 ...
3a2e1a5e 2945 },
2946 },
2947 {
2948 regex => qr/.../,
2949 handler => 'method_name',
e3f9dff4 2950 },
2951 ]);
2952
9d48860e 2953A "special operator" is a SQL syntactic clause that can be
e3f9dff4 2954applied to a field, instead of a usual binary operator.
be21dde3 2955For example:
e3f9dff4 2956
2957 WHERE field IN (?, ?, ?)
2958 WHERE field BETWEEN ? AND ?
2959 WHERE MATCH(field) AGAINST (?, ?)
96449e8e 2960
e3f9dff4 2961Special operators IN and BETWEEN are fairly standard and therefore
3a2e1a5e 2962are builtin within C<SQL::Abstract> (as the overridable methods
2963C<_where_field_IN> and C<_where_field_BETWEEN>). For other operators,
2964like the MATCH .. AGAINST example above which is specific to MySQL,
2965you can write your own operator handlers - supply a C<special_ops>
2966argument to the C<new> method. That argument takes an arrayref of
2967operator definitions; each operator definition is a hashref with two
2968entries:
96449e8e 2969
e3f9dff4 2970=over
2971
2972=item regex
2973
2974the regular expression to match the operator
96449e8e 2975
e3f9dff4 2976=item handler
2977
3a2e1a5e 2978Either a coderef or a plain scalar method name. In both cases
2979the expected return is C<< ($sql, @bind) >>.
2980
2981When supplied with a method name, it is simply called on the
13cc86af 2982L<SQL::Abstract> object as:
3a2e1a5e 2983
ca4f826a 2984 $self->$method_name($field, $op, $arg)
3a2e1a5e 2985
2986 Where:
2987
3a2e1a5e 2988 $field is the LHS of the operator
13cc86af 2989 $op is the part that matched the handler regex
3a2e1a5e 2990 $arg is the RHS
2991
2992When supplied with a coderef, it is called as:
2993
2994 $coderef->($self, $field, $op, $arg)
2995
e3f9dff4 2996
2997=back
2998
9d48860e 2999For example, here is an implementation
e3f9dff4 3000of the MATCH .. AGAINST syntax for MySQL
3001
3002 my $sqlmaker = SQL::Abstract->new(special_ops => [
9d48860e 3003
e3f9dff4 3004 # special op for MySql MATCH (field) AGAINST(word1, word2, ...)
9d48860e 3005 {regex => qr/^match$/i,
e3f9dff4 3006 handler => sub {
3007 my ($self, $field, $op, $arg) = @_;
3008 $arg = [$arg] if not ref $arg;
3009 my $label = $self->_quote($field);
3010 my ($placeholder) = $self->_convert('?');
3011 my $placeholders = join ", ", (($placeholder) x @$arg);
3012 my $sql = $self->_sqlcase('match') . " ($label) "
3013 . $self->_sqlcase('against') . " ($placeholders) ";
3014 my @bind = $self->_bindtype($field, @$arg);
3015 return ($sql, @bind);
3016 }
3017 },
9d48860e 3018
e3f9dff4 3019 ]);
96449e8e 3020
3021
59f23b3d 3022=head1 UNARY OPERATORS
3023
112b5232 3024 my $sqlmaker = SQL::Abstract->new(unary_ops => [
59f23b3d 3025 {
3026 regex => qr/.../,
3027 handler => sub {
3028 my ($self, $op, $arg) = @_;
3029 ...
3030 },
3031 },
3032 {
3033 regex => qr/.../,
3034 handler => 'method_name',
3035 },
3036 ]);
3037
9d48860e 3038A "unary operator" is a SQL syntactic clause that can be
59f23b3d 3039applied to a field - the operator goes before the field
3040
3041You can write your own operator handlers - supply a C<unary_ops>
3042argument to the C<new> method. That argument takes an arrayref of
3043operator definitions; each operator definition is a hashref with two
3044entries:
3045
3046=over
3047
3048=item regex
3049
3050the regular expression to match the operator
3051
3052=item handler
3053
3054Either a coderef or a plain scalar method name. In both cases
3055the expected return is C<< $sql >>.
3056
3057When supplied with a method name, it is simply called on the
13cc86af 3058L<SQL::Abstract> object as:
59f23b3d 3059
ca4f826a 3060 $self->$method_name($op, $arg)
59f23b3d 3061
3062 Where:
3063
3064 $op is the part that matched the handler regex
3065 $arg is the RHS or argument of the operator
3066
3067When supplied with a coderef, it is called as:
3068
3069 $coderef->($self, $op, $arg)
3070
3071
3072=back
3073
3074
32eab2da 3075=head1 PERFORMANCE
3076
3077Thanks to some benchmarking by Mark Stosberg, it turns out that
3078this module is many orders of magnitude faster than using C<DBIx::Abstract>.
3079I must admit this wasn't an intentional design issue, but it's a
3080byproduct of the fact that you get to control your C<DBI> handles
3081yourself.
3082
3083To maximize performance, use a code snippet like the following:
3084
3085 # prepare a statement handle using the first row
3086 # and then reuse it for the rest of the rows
3087 my($sth, $stmt);
3088 for my $href (@array_of_hashrefs) {
3089 $stmt ||= $sql->insert('table', $href);
3090 $sth ||= $dbh->prepare($stmt);
3091 $sth->execute($sql->values($href));
3092 }
3093
3094The reason this works is because the keys in your C<$href> are sorted
3095internally by B<SQL::Abstract>. Thus, as long as your data retains
3096the same structure, you only have to generate the SQL the first time
3097around. On subsequent queries, simply use the C<values> function provided
3098by this module to return your values in the correct order.
3099
b864ba9b 3100However this depends on the values having the same type - if, for
3101example, the values of a where clause may either have values
3102(resulting in sql of the form C<column = ?> with a single bind
3103value), or alternatively the values might be C<undef> (resulting in
3104sql of the form C<column IS NULL> with no bind value) then the
3105caching technique suggested will not work.
96449e8e 3106
32eab2da 3107=head1 FORMBUILDER
3108
3109If you use my C<CGI::FormBuilder> module at all, you'll hopefully
3110really like this part (I do, at least). Building up a complex query
3111can be as simple as the following:
3112
3113 #!/usr/bin/perl
3114
46dc2f3e 3115 use warnings;
3116 use strict;
3117
32eab2da 3118 use CGI::FormBuilder;
3119 use SQL::Abstract;
3120
3121 my $form = CGI::FormBuilder->new(...);
3122 my $sql = SQL::Abstract->new;
3123
3124 if ($form->submitted) {
3125 my $field = $form->field;
3126 my $id = delete $field->{id};
3127 my($stmt, @bind) = $sql->update('table', $field, {id => $id});
3128 }
3129
3130Of course, you would still have to connect using C<DBI> to run the
3131query, but the point is that if you make your form look like your
3132table, the actual query script can be extremely simplistic.
3133
3134If you're B<REALLY> lazy (I am), check out C<HTML::QuickTable> for
9d48860e 3135a fast interface to returning and formatting data. I frequently
32eab2da 3136use these three modules together to write complex database query
3137apps in under 50 lines.
3138
af733667 3139=head1 HOW TO CONTRIBUTE
3140
3141Contributions are always welcome, in all usable forms (we especially
3142welcome documentation improvements). The delivery methods include git-
3143or unified-diff formatted patches, GitHub pull requests, or plain bug
3144reports either via RT or the Mailing list. Contributors are generally
3145granted full access to the official repository after their first several
3146patches pass successful review.
3147
3148This project is maintained in a git repository. The code and related tools are
3149accessible at the following locations:
d8cc1792 3150
3151=over
3152
af733667 3153=item * Official repo: L<git://git.shadowcat.co.uk/dbsrgits/SQL-Abstract.git>
3154
3155=item * Official gitweb: L<http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits/SQL-Abstract.git>
3156
3157=item * GitHub mirror: L<https://github.com/dbsrgits/sql-abstract>
d8cc1792 3158
af733667 3159=item * Authorized committers: L<ssh://dbsrgits@git.shadowcat.co.uk/SQL-Abstract.git>
d8cc1792 3160
3161=back
32eab2da 3162
96449e8e 3163=head1 CHANGES
3164
3165Version 1.50 was a major internal refactoring of C<SQL::Abstract>.
3166Great care has been taken to preserve the I<published> behavior
3167documented in previous versions in the 1.* family; however,
9d48860e 3168some features that were previously undocumented, or behaved
96449e8e 3169differently from the documentation, had to be changed in order
3170to clarify the semantics. Hence, client code that was relying
9d48860e 3171on some dark areas of C<SQL::Abstract> v1.*
96449e8e 3172B<might behave differently> in v1.50.
32eab2da 3173
be21dde3 3174The main changes are:
d2a8fe1a 3175
96449e8e 3176=over
32eab2da 3177
9d48860e 3178=item *
32eab2da 3179
3ae1c5e2 3180support for literal SQL through the C<< \ [ $sql, @bind ] >> syntax.
96449e8e 3181
3182=item *
3183
145fbfc8 3184support for the { operator => \"..." } construct (to embed literal SQL)
3185
3186=item *
3187
9c37b9c0 3188support for the { operator => \["...", @bind] } construct (to embed literal SQL with bind values)
3189
3190=item *
3191
96449e8e 3192optional support for L<array datatypes|/"Inserting and Updating Arrays">
3193
9d48860e 3194=item *
96449e8e 3195
be21dde3 3196defensive programming: check arguments
96449e8e 3197
3198=item *
3199
3200fixed bug with global logic, which was previously implemented
7cac25e6 3201through global variables yielding side-effects. Prior versions would
96449e8e 3202interpret C<< [ {cond1, cond2}, [cond3, cond4] ] >>
3203as C<< "(cond1 AND cond2) OR (cond3 AND cond4)" >>.
3204Now this is interpreted
3205as C<< "(cond1 AND cond2) OR (cond3 OR cond4)" >>.
3206
96449e8e 3207
3208=item *
3209
3210fixed semantics of _bindtype on array args
3211
9d48860e 3212=item *
96449e8e 3213
3214dropped the C<_anoncopy> of the %where tree. No longer necessary,
3215we just avoid shifting arrays within that tree.
3216
3217=item *
3218
3219dropped the C<_modlogic> function
3220
3221=back
32eab2da 3222
32eab2da 3223=head1 ACKNOWLEDGEMENTS
3224
3225There are a number of individuals that have really helped out with
3226this module. Unfortunately, most of them submitted bugs via CPAN
3227so I have no idea who they are! But the people I do know are:
3228
9d48860e 3229 Ash Berlin (order_by hash term support)
b643abe1 3230 Matt Trout (DBIx::Class support)
32eab2da 3231 Mark Stosberg (benchmarking)
3232 Chas Owens (initial "IN" operator support)
3233 Philip Collins (per-field SQL functions)
3234 Eric Kolve (hashref "AND" support)
3235 Mike Fragassi (enhancements to "BETWEEN" and "LIKE")
3236 Dan Kubb (support for "quote_char" and "name_sep")
f5aab26e 3237 Guillermo Roditi (patch to cleanup "IN" and "BETWEEN", fix and tests for _order_by)
48d9f5f8 3238 Laurent Dami (internal refactoring, extensible list of special operators, literal SQL)
dbdf7648 3239 Norbert Buchmuller (support for literal SQL in hashpair, misc. fixes & tests)
e96c510a 3240 Peter Rabbitson (rewrite of SQLA::Test, misc. fixes & tests)
02288357 3241 Oliver Charles (support for "RETURNING" after "INSERT")
32eab2da 3242
3243Thanks!
3244
32eab2da 3245=head1 SEE ALSO
3246
86298391 3247L<DBIx::Class>, L<DBIx::Abstract>, L<CGI::FormBuilder>, L<HTML::QuickTable>.
32eab2da 3248
32eab2da 3249=head1 AUTHOR
3250
b643abe1 3251Copyright (c) 2001-2007 Nathan Wiger <nwiger@cpan.org>. All Rights Reserved.
3252
3253This module is actively maintained by Matt Trout <mst@shadowcatsystems.co.uk>
32eab2da 3254
abe72f94 3255For support, your best bet is to try the C<DBIx::Class> users mailing list.
3256While not an official support venue, C<DBIx::Class> makes heavy use of
3257C<SQL::Abstract>, and as such list members there are very familiar with
3258how to create queries.
3259
0d067ded 3260=head1 LICENSE
3261
d988ab87 3262This module is free software; you may copy this under the same
3263terms as perl itself (either the GNU General Public License or
3264the Artistic License)
32eab2da 3265
3266=cut