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