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