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