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