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