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