better in handling
[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',
767b62e4 207 };
208
143f50df 209 $opt{expand_op} = {
210 'between' => '_expand_between',
2809a2ff 211 'not_between' => '_expand_between',
416026a9 212 'in' => '_expand_in',
2809a2ff 213 'not_in' => '_expand_in',
5c633220 214 'nest' => '_expand_nest',
f49b02a0 215 (map +($_ => '_expand_op_andor'), ('and', 'or')),
2809a2ff 216 (map +($_ => '_expand_op_is'), ('is', 'is_not')),
143f50df 217 };
ca158918 218
771e7f69 219 # placeholder for _expand_unop system
220 {
221 my %unops = (-ident => '_expand_ident', -value => '_expand_value');
222 foreach my $name (keys %unops) {
223 $opt{expand}{$name} = $unops{$name};
224 my ($op) = $name =~ /^-(.*)$/;
225 $opt{expand_op}{$op} = sub {
226 my ($self, $op, $arg, $k) = @_;
efcd97c3 227 return $self->_expand_expr_hashpair_cmp(
228 $k, { "-${op}" => $arg }
9bb6374d 229 );
771e7f69 230 };
231 }
232 }
233
ca158918 234 $opt{render} = {
235 (map +("-$_", "_render_$_"), qw(op func bind ident literal list)),
236 %{$opt{render}||{}}
237 };
238
9159df95 239 $opt{render_op} = {
2809a2ff 240 (map +($_ => '_render_op_between'), 'between', 'not_between'),
241 (map +($_ => '_render_op_in'), 'in', 'not_in'),
9159df95 242 (map +($_ => '_render_unop_postfix'),
2809a2ff 243 'is_null', 'is_not_null', 'asc', 'desc',
9159df95 244 ),
245 (not => '_render_op_not'),
246 (map +($_ => '_render_op_andor'), qw(and or)),
247 };
143f50df 248
b6251592 249 return bless \%opt, $class;
250}
96449e8e 251
e175845b 252sub sqltrue { +{ -literal => [ $_[0]->{sqltrue} ] } }
253sub sqlfalse { +{ -literal => [ $_[0]->{sqlfalse} ] } }
170e6c33 254
255sub _assert_pass_injection_guard {
256 if ($_[1] =~ $_[0]->{injection_guard}) {
257 my $class = ref $_[0];
258 puke "Possible SQL injection attempt '$_[1]'. If this is indeed a part of the "
259 . "desired SQL use literal SQL ( \'...' or \[ '...' ] ) or supply your own "
260 . "{injection_guard} attribute to ${class}->new()"
261 }
262}
263
264
96449e8e 265#======================================================================
266# INSERT methods
267#======================================================================
268
269sub insert {
02288357 270 my $self = shift;
271 my $table = $self->_table(shift);
272 my $data = shift || return;
273 my $options = shift;
96449e8e 274
275 my $method = $self->_METHOD_FOR_refkind("_insert", $data);
02288357 276 my ($sql, @bind) = $self->$method($data);
96449e8e 277 $sql = join " ", $self->_sqlcase('insert into'), $table, $sql;
02288357 278
e82e648a 279 if ($options->{returning}) {
ca4f826a 280 my ($s, @b) = $self->_insert_returning($options);
e82e648a 281 $sql .= $s;
282 push @bind, @b;
02288357 283 }
284
96449e8e 285 return wantarray ? ($sql, @bind) : $sql;
286}
287
60f3fd3f 288# So that subclasses can override INSERT ... RETURNING separately from
289# UPDATE and DELETE (e.g. DBIx::Class::SQLMaker::Oracle does this)
b17a3ece 290sub _insert_returning { shift->_returning(@_) }
291
95904db5 292sub _returning {
e82e648a 293 my ($self, $options) = @_;
6b1fe79d 294
e82e648a 295 my $f = $options->{returning};
296
79d310f2 297 my ($sql, @bind) = $self->render_aqt(
ff96fdd4 298 $self->_expand_maybe_list_expr($f, undef, -ident)
299 );
300 return wantarray
301 ? $self->_sqlcase(' returning ') . $sql
302 : ($self->_sqlcase(' returning ').$sql, @bind);
6b1fe79d 303}
304
96449e8e 305sub _insert_HASHREF { # explicit list of fields and then values
306 my ($self, $data) = @_;
307
308 my @fields = sort keys %$data;
309
fe3ae272 310 my ($sql, @bind) = $self->_insert_values($data);
96449e8e 311
312 # assemble SQL
313 $_ = $self->_quote($_) foreach @fields;
314 $sql = "( ".join(", ", @fields).") ".$sql;
315
316 return ($sql, @bind);
317}
318
319sub _insert_ARRAYREF { # just generate values(?,?) part (no list of fields)
320 my ($self, $data) = @_;
321
322 # no names (arrayref) so can't generate bindtype
323 $self->{bindtype} ne 'columns'
324 or belch "can't do 'columns' bindtype when called with arrayref";
325
19b6ccce 326 my (@values, @all_bind);
327 foreach my $value (@$data) {
328 my ($values, @bind) = $self->_insert_value(undef, $value);
329 push @values, $values;
330 push @all_bind, @bind;
331 }
332 my $sql = $self->_sqlcase('values')." ( ".join(", ", @values)." )";
333 return ($sql, @all_bind);
fe3ae272 334}
335
336sub _insert_ARRAYREFREF { # literal SQL with bind
337 my ($self, $data) = @_;
338
339 my ($sql, @bind) = @${$data};
340 $self->_assert_bindval_matches_bindtype(@bind);
341
342 return ($sql, @bind);
343}
344
345
346sub _insert_SCALARREF { # literal SQL without bind
347 my ($self, $data) = @_;
348
349 return ($$data);
350}
351
352sub _insert_values {
353 my ($self, $data) = @_;
354
96449e8e 355 my (@values, @all_bind);
fe3ae272 356 foreach my $column (sort keys %$data) {
19b6ccce 357 my ($values, @bind) = $self->_insert_value($column, $data->{$column});
358 push @values, $values;
359 push @all_bind, @bind;
360 }
361 my $sql = $self->_sqlcase('values')." ( ".join(", ", @values)." )";
362 return ($sql, @all_bind);
363}
96449e8e 364
19b6ccce 365sub _insert_value {
366 my ($self, $column, $v) = @_;
96449e8e 367
79d310f2 368 return $self->render_aqt(
720ca4f7 369 $self->_expand_insert_value($column, $v)
370 );
371}
96449e8e 372
720ca4f7 373sub _expand_insert_value {
374 my ($self, $column, $v) = @_;
96449e8e 375
720ca4f7 376 if (ref($v) eq 'ARRAY') {
377 if ($self->{array_datatypes}) {
378 return +{ -bind => [ $column, $v ] };
379 }
380 my ($sql, @bind) = @$v;
381 $self->_assert_bindval_matches_bindtype(@bind);
382 return +{ -literal => $v };
383 }
384 if (ref($v) eq 'HASH') {
385 if (grep !/^-/, keys %$v) {
386 belch "HASH ref as bind value in insert is not supported";
387 return +{ -bind => [ $column, $v ] };
388 }
389 }
390 if (!defined($v)) {
391 return +{ -bind => [ $column, undef ] };
392 }
393 local our $Cur_Col_Meta = $column;
79d310f2 394 return $self->expand_expr($v);
96449e8e 395}
396
397
96449e8e 398
399#======================================================================
400# UPDATE methods
401#======================================================================
402
403
404sub update {
95904db5 405 my $self = shift;
406 my $table = $self->_table(shift);
407 my $data = shift || return;
408 my $where = shift;
409 my $options = shift;
96449e8e 410
411 # first build the 'SET' part of the sql statement
96449e8e 412 puke "Unsupported data type specified to \$sql->update"
413 unless ref $data eq 'HASH';
414
9ade906e 415 my ($sql, @all_bind) = $self->_update_set_values($data);
a9e94508 416 $sql = $self->_sqlcase('update ') . $table . $self->_sqlcase(' set ')
9ade906e 417 . $sql;
418
419 if ($where) {
420 my($where_sql, @where_bind) = $self->where($where);
421 $sql .= $where_sql;
422 push @all_bind, @where_bind;
423 }
424
425 if ($options->{returning}) {
426 my ($returning_sql, @returning_bind) = $self->_update_returning($options);
427 $sql .= $returning_sql;
428 push @all_bind, @returning_bind;
429 }
430
431 return wantarray ? ($sql, @all_bind) : $sql;
432}
433
434sub _update_set_values {
435 my ($self, $data) = @_;
436
79d310f2 437 return $self->render_aqt(
89690da2 438 $self->_expand_update_set_values($data),
439 );
440}
96449e8e 441
89690da2 442sub _expand_update_set_values {
443 my ($self, $data) = @_;
444 $self->_expand_maybe_list_expr( [
445 map {
446 my ($k, $set) = @$_;
c4ed66f4 447 $set = { -bind => $_ } unless defined $set;
9103bd14 448 +{ -op => [ '=', $self->_expand_ident(-ident => $k), $set ] };
89690da2 449 }
450 map {
451 my $k = $_;
452 my $v = $data->{$k};
453 (ref($v) eq 'ARRAY'
454 ? ($self->{array_datatypes}
455 ? [ $k, +{ -bind => [ $k, $v ] } ]
456 : [ $k, +{ -literal => $v } ])
457 : do {
458 local our $Cur_Col_Meta = $k;
459 [ $k, $self->_expand_expr($v) ]
460 }
461 );
462 } sort keys %$data
463 ] );
96449e8e 464}
465
60f3fd3f 466# So that subclasses can override UPDATE ... RETURNING separately from
467# INSERT and DELETE
20bb2ad5 468sub _update_returning { shift->_returning(@_) }
96449e8e 469
470
471
472#======================================================================
473# SELECT
474#======================================================================
475
476
477sub select {
478 my $self = shift;
479 my $table = $self->_table(shift);
480 my $fields = shift || '*';
481 my $where = shift;
482 my $order = shift;
483
daa4ccdd 484 my ($fields_sql, @bind) = $self->_select_fields($fields);
96449e8e 485
daa4ccdd 486 my ($where_sql, @where_bind) = $self->where($where, $order);
487 push @bind, @where_bind;
488
489 my $sql = join(' ', $self->_sqlcase('select'), $fields_sql,
96449e8e 490 $self->_sqlcase('from'), $table)
491 . $where_sql;
492
9d48860e 493 return wantarray ? ($sql, @bind) : $sql;
96449e8e 494}
495
daa4ccdd 496sub _select_fields {
497 my ($self, $fields) = @_;
de63ce57 498 return $fields unless ref($fields);
79d310f2 499 return $self->render_aqt(
27592e2b 500 $self->_expand_maybe_list_expr($fields, undef, '-ident')
501 );
daa4ccdd 502}
503
96449e8e 504#======================================================================
505# DELETE
506#======================================================================
507
508
509sub delete {
85327cd5 510 my $self = shift;
511 my $table = $self->_table(shift);
512 my $where = shift;
513 my $options = shift;
96449e8e 514
515 my($where_sql, @bind) = $self->where($where);
a9e94508 516 my $sql = $self->_sqlcase('delete from ') . $table . $where_sql;
96449e8e 517
85327cd5 518 if ($options->{returning}) {
ca4f826a 519 my ($returning_sql, @returning_bind) = $self->_delete_returning($options);
85327cd5 520 $sql .= $returning_sql;
521 push @bind, @returning_bind;
522 }
523
9d48860e 524 return wantarray ? ($sql, @bind) : $sql;
96449e8e 525}
526
60f3fd3f 527# So that subclasses can override DELETE ... RETURNING separately from
528# INSERT and UPDATE
85327cd5 529sub _delete_returning { shift->_returning(@_) }
530
531
96449e8e 532
533#======================================================================
534# WHERE: entry point
535#======================================================================
536
537
538
539# Finally, a separate routine just to handle WHERE clauses
540sub where {
541 my ($self, $where, $order) = @_;
542
7ad12721 543 local $self->{convert_where} = $self->{convert};
544
96449e8e 545 # where ?
e175845b 546 my ($sql, @bind) = defined($where)
547 ? $self->_recurse_where($where)
548 : (undef);
417dd15e 549 $sql = (defined $sql and length $sql) ? $self->_sqlcase(' where ') . "( $sql )" : '';
96449e8e 550
551 # order by?
552 if ($order) {
26fe4d30 553 my ($order_sql, @order_bind) = $self->_order_by($order);
554 $sql .= $order_sql;
555 push @bind, @order_bind;
96449e8e 556 }
557
9d48860e 558 return wantarray ? ($sql, @bind) : $sql;
96449e8e 559}
560
c349b750 561{ our $Default_Scalar_To = -value }
562
79d310f2 563sub expand_expr {
54d3140f 564 my ($self, $expr, $default_scalar_to) = @_;
565 local our $Default_Scalar_To = $default_scalar_to if $default_scalar_to;
7d93797d 566 $self->_expand_expr($expr);
79d310f2 567}
568
569sub render_aqt {
570 my ($self, $aqt) = @_;
571 my ($k, $v, @rest) = %$aqt;
572 die "No" if @rest;
21225d32 573 if (my $meth = $self->{render}{$k}) {
79d310f2 574 return $self->$meth($v);
575 }
576 die "notreached: $k";
577}
578
6082a464 579sub render_expr {
580 my ($self, $expr) = @_;
581 $self->render_aqt($self->expand_expr($expr));
582}
583
24cd9525 584sub _normalize_op {
585 my ($self, $raw) = @_;
2809a2ff 586 s/^-(?=.)//, s/\s+/_/g for my $op = lc $raw;
24cd9525 587 $op;
588}
589
a2cd381d 590sub _expand_expr {
3a10d914 591 my ($self, $expr) = @_;
3ae10d16 592 our $Expand_Depth ||= 0; local $Expand_Depth = $Expand_Depth + 1;
252518da 593 return undef unless defined($expr);
59588695 594 if (ref($expr) eq 'HASH') {
767b62e4 595 return undef unless my $kc = keys %$expr;
596 if ($kc > 1) {
d6ac0cfb 597 return $self->_expand_op_andor(-and => $expr);
59588695 598 }
767b62e4 599 my ($key, $value) = %$expr;
70f98e4b 600 if ($key =~ /^-/ and $key =~ s/ [_\s]? \d+ $//x ) {
601 belch 'Use of [and|or|nest]_N modifiers is deprecated and will be removed in SQLA v2.0. '
602 . "You probably wanted ...-and => [ $key => COND1, $key => COND2 ... ]";
603 }
767b62e4 604 if (my $exp = $self->{expand}{$key}) {
d1aabfe4 605 return $self->$exp($key, $value);
767b62e4 606 }
3a10d914 607 return $self->_expand_expr_hashpair($key, $value);
a2cd381d 608 }
08264f40 609 if (ref($expr) eq 'ARRAY') {
124b41ca 610 my $logic = '-'.lc($self->{logic});
d6ac0cfb 611 return $self->_expand_op_andor($logic, $expr);
08264f40 612 }
ca3da680 613 if (my $literal = is_literal_value($expr)) {
614 return +{ -literal => $literal };
615 }
99a65fa8 616 if (!ref($expr) or Scalar::Util::blessed($expr)) {
cd90d4f0 617 return $self->_expand_expr_scalar($expr);
252518da 618 }
252518da 619 die "notreached";
a2cd381d 620}
96449e8e 621
59588695 622sub _expand_expr_hashpair {
124b41ca 623 my ($self, $k, $v) = @_;
d13725da 624 unless (defined($k) and length($k)) {
2d64004f 625 if (defined($k) and my $literal = is_literal_value($v)) {
d13725da 626 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 627 return { -literal => $literal };
d13725da 628 }
629 puke "Supplying an empty left hand side argument is not supported";
630 }
ef071fad 631 if ($k =~ /^-/) {
d0ae57ad 632 return $self->_expand_expr_hashpair_op($k, $v);
99a65fa8 633 }
1cc1e937 634 return $self->_expand_expr_hashpair_ident($k, $v);
635}
636
637sub _expand_expr_hashpair_ident {
638 my ($self, $k, $v) = @_;
710cdeed 639
cd90d4f0 640 local our $Cur_Col_Meta = $k;
641
2e670469 642 # hash with multiple or no elements is andor
643
644 if (ref($v) eq 'HASH' and keys %$v != 1) {
645 return $self->_expand_op_andor(-and => $v, $k);
646 }
647
710cdeed 648 # undef needs to be re-sent with cmp to achieve IS/IS NOT NULL
649
6d7a39b3 650 if (is_undef_value($v)) {
efcd97c3 651 return $self->_expand_expr_hashpair_cmp($k => undef);
99a65fa8 652 }
710cdeed 653
710cdeed 654 # scalars and objects get expanded as whatever requested or values
655
99a65fa8 656 if (!ref($v) or Scalar::Util::blessed($v)) {
cd90d4f0 657 return $self->_expand_expr_hashpair_scalar($k, $v);
99a65fa8 658 }
0cdafc4b 659
660 # single key hashref is a hashtriple
661
99a65fa8 662 if (ref($v) eq 'HASH') {
0b2789b3 663 return $self->_expand_expr_hashtriple($k, %$v);
99a65fa8 664 }
0cdafc4b 665
666 # arrayref needs re-engineering over the elements
667
99a65fa8 668 if (ref($v) eq 'ARRAY') {
e175845b 669 return $self->sqlfalse unless @$v;
99a65fa8 670 $self->_debug("ARRAY($k) means distribute over elements");
124b41ca 671 my $logic = lc(
70f98e4b 672 $v->[0] =~ /^-(and|or)$/i
673 ? shift(@{$v = [ @$v ]})
124b41ca 674 : '-'.lc($self->{logic} || 'OR')
99a65fa8 675 );
d6ac0cfb 676 return $self->_expand_op_andor(
6393fa8e 677 $logic => $v, $k
66e362e4 678 );
99a65fa8 679 }
0cdafc4b 680
99a65fa8 681 if (my $literal = is_literal_value($v)) {
682 unless (length $k) {
683 belch 'Hash-pairs consisting of an empty string with a literal are deprecated, and will be removed in 2.0: use -and => [ $literal ] instead';
684 return \$literal;
685 }
686 my ($sql, @bind) = @$literal;
687 if ($self->{bindtype} eq 'columns') {
688 for (@bind) {
6fb2bd90 689 $self->_assert_bindval_matches_bindtype($_);
aa8d7bdb 690 }
331e2209 691 }
99a65fa8 692 return +{ -literal => [ $self->_quote($k).' '.$sql, @bind ] };
331e2209 693 }
99a65fa8 694 die "notreached";
59588695 695}
696
cd90d4f0 697sub _expand_expr_scalar {
698 my ($self, $expr) = @_;
699
c349b750 700 return $self->_expand_expr({ (our $Default_Scalar_To) => $expr });
cd90d4f0 701}
702
703sub _expand_expr_hashpair_scalar {
704 my ($self, $k, $v) = @_;
705
706 return $self->_expand_expr_hashpair_cmp(
707 $k, $self->_expand_expr_scalar($v),
708 );
709}
710
d0ae57ad 711sub _expand_expr_hashpair_op {
712 my ($self, $k, $v) = @_;
710cdeed 713
2809a2ff 714 $self->_assert_pass_injection_guard($k =~ /\A-(.*)\Z/s);
24cd9525 715
2809a2ff 716 my $op = $self->_normalize_op($k);
710cdeed 717
718 # Ops prefixed with -not_ get converted
719
e57d8650 720 if (my ($rest) = $op =~/^not_(.*)$/) {
d0ae57ad 721 return +{ -op => [
722 'not',
723 $self->_expand_expr({ "-${rest}", $v })
2809a2ff 724 ] };
d0ae57ad 725 }
710cdeed 726
8e73de4b 727 { # Old SQLA compat
728
e57d8650 729 my $op = join(' ', split '_', $op);
730
8e73de4b 731 # the old special op system requires illegality for top-level use
732
733 if (
734 (our $Expand_Depth) == 1
735 and List::Util::first { $op =~ $_->{regex} } @{$self->{special_ops}}
736 ) {
737 puke "Illegal use of top-level '-$op'"
738 }
710cdeed 739
8e73de4b 740 # the old unary op system means we should touch nothing and let it work
710cdeed 741
8e73de4b 742 if (my $us = List::Util::first { $op =~ $_->{regex} } @{$self->{unary_ops}}) {
743 return { -op => [ $op, $v ] };
744 }
d0ae57ad 745 }
710cdeed 746
747 # an explicit node type is currently assumed to be expanded (this is almost
748 # certainly wrong and there should be expansion anyway)
749
d0ae57ad 750 if ($self->{render}{$k}) {
751 return { $k => $v };
752 }
710cdeed 753
754 # hashref RHS values get expanded and used as op/func args
755
d0ae57ad 756 if (
757 ref($v) eq 'HASH'
758 and keys %$v == 1
759 and (keys %$v)[0] =~ /^-/
760 ) {
761 my ($func) = $k =~ /^-(.*)$/;
8e73de4b 762 { # Old SQLA compat
763 if (List::Util::first { $func =~ $_->{regex} } @{$self->{special_ops}}) {
764 return +{ -op => [ $func, $self->_expand_expr($v) ] };
765 }
d0ae57ad 766 }
767 return +{ -func => [ $func, $self->_expand_expr($v) ] };
768 }
710cdeed 769
770 # scalars and literals get simply expanded
771
d0ae57ad 772 if (!ref($v) or is_literal_value($v)) {
315f078d 773 return +{ -op => [ $op, $self->_expand_expr($v) ] };
d0ae57ad 774 }
710cdeed 775
d0ae57ad 776 die "notreached";
777}
778
efcd97c3 779sub _expand_expr_hashpair_cmp {
780 my ($self, $k, $v) = @_;
781 $self->_expand_expr_hashtriple($k, $self->{cmp}, $v);
782}
783
0b2789b3 784sub _expand_expr_hashtriple {
785 my ($self, $k, $vk, $vv) = @_;
786
787 my $ik = $self->_expand_ident(-ident => $k);
788
24cd9525 789 my $op = $self->_normalize_op($vk);
0b2789b3 790 $self->_assert_pass_injection_guard($op);
24cd9525 791
792 if ($op =~ s/ _? \d+ $//x ) {
0b2789b3 793 return $self->_expand_expr($k, { $vk, $vv });
794 }
795 if (my $x = $self->{expand_op}{$op}) {
796 local our $Cur_Col_Meta = $k;
797 return $self->$x($op, $vv, $k);
798 }
8e73de4b 799 { # Old SQLA compat
24cd9525 800
801 my $op = join(' ', split '_', $op);
802
8e73de4b 803 if (my $us = List::Util::first { $op =~ $_->{regex} } @{$self->{special_ops}}) {
804 return { -op => [ $op, $ik, $vv ] };
805 }
806 if (my $us = List::Util::first { $op =~ $_->{regex} } @{$self->{unary_ops}}) {
807 return { -op => [
808 $self->{cmp},
809 $ik,
810 { -op => [ $op, $vv ] }
811 ] };
812 }
0b2789b3 813 }
814 if (ref($vv) eq 'ARRAY') {
815 my @raw = @$vv;
816 my $logic = (defined($raw[0]) and $raw[0] =~ /^-(and|or)$/i)
817 ? shift @raw : '-or';
818 my @values = map +{ $vk => $_ }, @raw;
819 if (
820 $op =~ $self->{inequality_op}
821 or $op =~ $self->{not_like_op}
822 ) {
823 if (lc($logic) eq '-or' and @values > 1) {
2809a2ff 824 belch "A multi-element arrayref as an argument to the inequality op '${\uc(join ' ', split '_', $op)}' "
0b2789b3 825 . 'is technically equivalent to an always-true 1=1 (you probably wanted '
826 . "to say ...{ \$inequality_op => [ -and => \@values ] }... instead)"
827 ;
828 }
829 }
830 unless (@values) {
831 # try to DWIM on equality operators
a4009a84 832 return ($self->_dwim_op_to_is($op,
833 "Supplying an empty arrayref to '%s' is deprecated",
834 "operator '%s' applied on an empty array (field '$k')"
835 ) ? $self->sqlfalse : $self->sqltrue);
0b2789b3 836 }
837 return $self->_expand_op_andor($logic => \@values, $k);
838 }
6d7a39b3 839 if (is_undef_value($vv)) {
a4009a84 840 my $is = ($self->_dwim_op_to_is($op,
5f2c2f1e 841 "Supplying an undefined argument to '%s' is deprecated",
842 "unexpected operator '%s' with undef operand",
a4009a84 843 ) ? 'is' : 'is not');
0b2789b3 844
845 return $self->_expand_expr_hashpair($k => { $is, undef });
846 }
847 local our $Cur_Col_Meta = $k;
848 return +{ -op => [
849 $op,
850 $ik,
851 $self->_expand_expr($vv)
852 ] };
853}
854
5f2c2f1e 855sub _dwim_op_to_is {
24cd9525 856 my ($self, $raw, $empty, $fail) = @_;
857
858 my $op = $self->_normalize_op($raw);
859
5f2c2f1e 860 if ($op =~ /^not$/i) {
a4009a84 861 return 0;
5f2c2f1e 862 }
863 if ($op =~ $self->{equality_op}) {
a4009a84 864 return 1;
5f2c2f1e 865 }
866 if ($op =~ $self->{like_op}) {
2809a2ff 867 belch(sprintf $empty, uc(join ' ', split '_', $op));
a4009a84 868 return 1;
5f2c2f1e 869 }
870 if ($op =~ $self->{inequality_op}) {
a4009a84 871 return 0;
5f2c2f1e 872 }
873 if ($op =~ $self->{not_like_op}) {
2809a2ff 874 belch(sprintf $empty, uc(join ' ', split '_', $op));
a4009a84 875 return 0;
5f2c2f1e 876 }
877 puke(sprintf $fail, $op);
878}
879
9103bd14 880sub _expand_ident {
83de255f 881 my ($self, $op, $body) = @_;
882 unless (defined($body) or (ref($body) and ref($body) eq 'ARRAY')) {
883 puke "$op requires a single plain scalar argument (a quotable identifier) or an arrayref of identifier parts";
884 }
9103bd14 885 my @parts = map split(/\Q${\($self->{name_sep}||'.')}\E/, $_),
886 ref($body) ? @$body : $body;
944f2c7b 887 return { -ident => $parts[-1] } if $self->{_dequalify_idents};
888 unless ($self->{quote_char}) {
889 $self->_assert_pass_injection_guard($_) for @parts;
890 }
9103bd14 891 return +{ -ident => \@parts };
892}
893
71f1364b 894sub _expand_value {
895 +{ -bind => [ our $Cur_Col_Meta, $_[2] ] };
896}
897
2a238661 898sub _expand_not {
899 +{ -op => [ 'not', $_[0]->_expand_expr($_[2]) ] };
900}
901
05d37f9c 902sub _expand_bool {
903 my ($self, undef, $v) = @_;
904 if (ref($v)) {
905 return $self->_expand_expr($v);
906 }
907 puke "-bool => undef not supported" unless defined($v);
908 return $self->_expand_ident(-ident => $v);
909}
910
d6ac0cfb 911sub _expand_op_andor {
9194eb8f 912 my ($self, $logic, $v, $k) = @_;
913 if (defined $k) {
5ce9d71b 914 $v = [ map +{ $k, $_ },
915 (ref($v) eq 'HASH')
916 ? (map +{ $_ => $v->{$_} }, sort keys %$v)
917 : @$v,
918 ];
9194eb8f 919 }
920 my ($logop) = $logic =~ /^-?(.*)$/;
70f98e4b 921 if (ref($v) eq 'HASH') {
2e670469 922 return undef unless keys %$v;
70f98e4b 923 return +{ -op => [
124b41ca 924 $logop,
0a8de350 925 map $self->_expand_expr({ $_ => $v->{$_} }),
70f98e4b 926 sort keys %$v
927 ] };
928 }
929 if (ref($v) eq 'ARRAY') {
124b41ca 930 $logop eq 'and' or $logop eq 'or' or puke "unknown logic: $logop";
70f98e4b 931
932 my @expr = grep {
933 (ref($_) eq 'ARRAY' and @$_)
934 or (ref($_) eq 'HASH' and %$_)
935 or 1
936 } @$v;
937
938 my @res;
939
940 while (my ($el) = splice @expr, 0, 1) {
941 puke "Supplying an empty left hand side argument is not supported in array-pairs"
942 unless defined($el) and length($el);
943 my $elref = ref($el);
944 if (!$elref) {
945 local our $Expand_Depth = 0;
946 push(@res, grep defined, $self->_expand_expr({ $el, shift(@expr) }));
947 } elsif ($elref eq 'ARRAY') {
948 push(@res, grep defined, $self->_expand_expr($el)) if @$el;
949 } elsif (my $l = is_literal_value($el)) {
950 push @res, { -literal => $l };
951 } elsif ($elref eq 'HASH') {
952 local our $Expand_Depth = 0;
953 push @res, grep defined, $self->_expand_expr($el) if %$el;
954 } else {
955 die "notreached";
956 }
957 }
958 # ???
959 # return $res[0] if @res == 1;
124b41ca 960 return { -op => [ $logop, @res ] };
70f98e4b 961 }
962 die "notreached";
963}
964
f49b02a0 965sub _expand_op_is {
966 my ($self, $op, $vv, $k) = @_;
967 puke "$op can only take undef as argument"
968 if defined($vv)
969 and not (
970 ref($vv) eq 'HASH'
971 and exists($vv->{-value})
972 and !defined($vv->{-value})
973 );
2809a2ff 974 return +{ -op => [ $op.'_null', $self->_expand_ident(-ident => $k) ] };
f49b02a0 975}
976
143f50df 977sub _expand_between {
978 my ($self, $op, $vv, $k) = @_;
979 local our $Cur_Col_Meta = $k;
980 my @rhs = map $self->_expand_expr($_),
981 ref($vv) eq 'ARRAY' ? @$vv : $vv;
982 unless (
983 (@rhs == 1 and ref($rhs[0]) eq 'HASH' and $rhs[0]->{-literal})
984 or
985 (@rhs == 2 and defined($rhs[0]) and defined($rhs[1]))
986 ) {
987 puke "Operator '${\uc($op)}' requires either an arrayref with two defined values or expressions, or a single literal scalarref/arrayref-ref";
988 }
989 return +{ -op => [
990 $op,
991 $self->_expand_ident(-ident => $k),
992 @rhs
993 ] }
994}
995
416026a9 996sub _expand_in {
3445a1e7 997 my ($self, $raw, $vv, $k) = @_;
998 $k = shift @{$vv = [ @$vv ]} unless defined $k;
999 local our $Cur_Col_Meta = $k;
1000 my $op = $self->_normalize_op($raw);
416026a9 1001 if (my $literal = is_literal_value($vv)) {
1002 my ($sql, @bind) = @$literal;
1003 my $opened_sql = $self->_open_outer_paren($sql);
1004 return +{ -op => [
1005 $op, $self->_expand_ident(-ident => $k),
1006 [ { -literal => [ $opened_sql, @bind ] } ]
1007 ] };
1008 }
1009 my $undef_err =
1010 'SQL::Abstract before v1.75 used to generate incorrect SQL when the '
1011 . "-${\uc($op)} operator was given an undef-containing list: !!!AUDIT YOUR CODE "
1012 . 'AND DATA!!! (the upcoming Data::Query-based version of SQL::Abstract '
1013 . 'will emit the logically correct SQL instead of raising this exception)'
1014 ;
1015 puke("Argument passed to the '${\uc($op)}' operator can not be undefined")
1016 if !defined($vv);
1017 my @rhs = map $self->_expand_expr($_),
1018 map { ref($_) ? $_ : { -bind => [ $k, $_ ] } }
1019 map { defined($_) ? $_: puke($undef_err) }
1020 (ref($vv) eq 'ARRAY' ? @$vv : $vv);
1021 return $self->${\($op =~ /^not/ ? 'sqltrue' : 'sqlfalse')} unless @rhs;
1022
1023 return +{ -op => [
1024 $op,
1025 $self->_expand_ident(-ident => $k),
1026 \@rhs
1027 ] };
1028}
1029
5c633220 1030sub _expand_nest {
1031 my ($self, $op, $v) = @_;
1032 # DBIx::Class requires a nest warning to be emitted once but the private
1033 # method it overrode to do so no longer exists
1034 if ($self->{is_dbic_sqlmaker}) {
1035 unless (our $Nest_Warned) {
1036 belch(
1037 "-nest in search conditions is deprecated, you most probably wanted:\n"
1038 .q|{..., -and => [ \%cond0, \@cond1, \'cond2', \[ 'cond3', [ col => bind ] ], etc. ], ... }|
1039 );
1040 $Nest_Warned = 1;
1041 }
1042 }
1043 return $self->_expand_expr($v);
1044}
1045
96449e8e 1046sub _recurse_where {
1047 my ($self, $where, $logic) = @_;
1048
5492d4c2 1049 # Special case: top level simple string treated as literal
1050
1051 my $where_exp = (ref($where)
ae56a156 1052 ? $self->_expand_expr($where, $logic)
5492d4c2 1053 : { -literal => [ $where ] });
e175845b 1054
e3e27543 1055 # dispatch expanded expression
311b2151 1056
79d310f2 1057 my ($sql, @bind) = defined($where_exp) ? $self->render_aqt($where_exp) : (undef);
abe1a491 1058 # DBIx::Class used to call _recurse_where in scalar context
1059 # something else might too...
1060 if (wantarray) {
1061 return ($sql, @bind);
1062 }
1063 else {
1064 belch "Calling _recurse_where in scalar context is deprecated and will go away before 2.0";
1065 return $sql;
1066 }
96449e8e 1067}
1068
181dcebf 1069sub _render_ident {
1070 my ($self, $ident) = @_;
cc422895 1071
9cf28dfb 1072 return $self->_convert($self->_quote($ident));
cc422895 1073}
1074
ca158918 1075sub _render_list {
1076 my ($self, $list) = @_;
1077 my @parts = grep length($_->[0]), map [ $self->render_aqt($_) ], @$list;
1078 return join(', ', map $_->[0], @parts), map @{$_}[1..$#$_], @parts;
1079}
1080
1081sub _render_func {
1082 my ($self, $rest) = @_;
1083 my ($func, @args) = @$rest;
1084 my @arg_sql;
1085 my @bind = map {
1086 my @x = @$_;
1087 push @arg_sql, shift @x;
1088 @x
1089 } map [ $self->render_aqt($_) ], @args;
1090 return ($self->_sqlcase($func).'('.join(', ', @arg_sql).')', @bind);
1091}
d13725da 1092
ca158918 1093sub _render_bind {
1094 my ($self, $bind) = @_;
1095 return ($self->_convert('?'), $self->_bindtype(@$bind));
1096}
1097
1098sub _render_literal {
1099 my ($self, $literal) = @_;
1100 $self->_assert_bindval_matches_bindtype(@{$literal}[1..$#$literal]);
1101 return @$literal;
1102}
1103
5305e436 1104sub _render_op {
1105 my ($self, $v) = @_;
1106 my ($op, @args) = @$v;
1107 if (my $r = $self->{render_op}{$op}) {
1108 return $self->$r($op, \@args);
1109 }
1110
1111 { # Old SQLA compat
1112
24cd9525 1113 my $op = join(' ', split '_', $op);
1114
5305e436 1115 my $us = List::Util::first { $op =~ $_->{regex} } @{$self->{special_ops}};
1116 if ($us and @args > 1) {
1117 puke "Special op '${op}' requires first value to be identifier"
1118 unless my ($ident) = map $_->{-ident}, grep ref($_) eq 'HASH', $args[0];
1119 my $k = join(($self->{name_sep}||'.'), @$ident);
1120 local our $Expand_Depth = 1;
1121 return $self->${\($us->{handler})}($k, $op, $args[1]);
1122 }
1123 if (my $us = List::Util::first { $op =~ $_->{regex} } @{$self->{unary_ops}}) {
1124 return $self->${\($us->{handler})}($op, $args[0]);
1125 }
1126
1127 }
1128 if (@args == 1) {
1129 return $self->_render_unop_prefix($op, \@args);
1130 } else {
1131 return $self->_render_op_multop($op, \@args);
1132 }
1133 die "notreached";
1134}
1135
1136
e748969f 1137sub _render_op_between {
1138 my ($self, $op, $args) = @_;
1139 my ($left, $low, $high) = @$args;
1140 my ($rhsql, @rhbind) = do {
1141 if (@$args == 2) {
1142 puke "Single arg to between must be a literal"
1143 unless $low->{-literal};
1144 @{$low->{-literal}}
1145 } else {
1146 my ($l, $h) = map [ $self->render_aqt($_) ], $low, $high;
1147 (join(' ', $l->[0], $self->_sqlcase('and'), $h->[0]),
1148 @{$l}[1..$#$l], @{$h}[1..$#$h])
1149 }
1150 };
1151 my ($lhsql, @lhbind) = $self->render_aqt($left);
1152 return (
2809a2ff 1153 join(' ',
1154 '(', $lhsql,
1155 $self->_sqlcase(join ' ', split '_', $op),
1156 $rhsql, ')'
1157 ),
e748969f 1158 @lhbind, @rhbind
1159 );
1160}
1161
7dda9b27 1162sub _render_op_in {
1163 my ($self, $op, $args) = @_;
1164 my ($lhs, $rhs) = @$args;
1165 my @in_bind;
1166 my @in_sql = map {
1167 my ($sql, @bind) = $self->render_aqt($_);
1168 push @in_bind, @bind;
1169 $sql;
1170 } @$rhs;
1171 my ($lhsql, @lbind) = $self->render_aqt($lhs);
1172 return (
2809a2ff 1173 $lhsql.' '.$self->_sqlcase(join ' ', split '_', $op).' ( '
7dda9b27 1174 .join(', ', @in_sql)
1175 .' )',
1176 @lbind, @in_bind
1177 );
1178}
1179
5edafff8 1180sub _render_op_andor {
1181 my ($self, $op, $args) = @_;
1182 my @parts = grep length($_->[0]), map [ $self->render_aqt($_) ], @$args;
1183 return '' unless @parts;
1184 return @{$parts[0]} if @parts == 1;
3f51d831 1185 my ($sql, @bind) = $self->_render_op_multop($op, $args);
1186 return '( '.$sql.' )', @bind;
1187}
1188
1189sub _render_op_multop {
1190 my ($self, $op, $args) = @_;
1191 my @parts = grep length($_->[0]), map [ $self->render_aqt($_) ], @$args;
1192 return '' unless @parts;
1193 return @{$parts[0]} if @parts == 1;
5edafff8 1194 my ($final_sql) = join(
2809a2ff 1195 ' '.$self->_sqlcase(join ' ', split '_', $op).' ',
5edafff8 1196 map $_->[0], @parts
1197 );
1198 return (
3f51d831 1199 $final_sql,
5edafff8 1200 map @{$_}[1..$#$_], @parts
1201 );
1202}
2ddaa002 1203sub _render_op_not {
1204 my ($self, $op, $v) = @_;
1205 my ($sql, @bind) = $self->_render_unop_prefix($op, $v);
1206 return "(${sql})", @bind;
1207}
1208
1209sub _render_unop_prefix {
1210 my ($self, $op, $v) = @_;
1211 my ($expr_sql, @bind) = $self->render_aqt($v->[0]);
24cd9525 1212
2809a2ff 1213 my $op_sql = $self->_sqlcase($op); # join ' ', split '_', $op);
2ddaa002 1214 return ("${op_sql} ${expr_sql}", @bind);
1215}
1216
b23fd5ff 1217sub _render_unop_postfix {
1218 my ($self, $op, $v) = @_;
715b4e6a 1219 my ($expr_sql, @bind) = $self->render_aqt($v->[0]);
24cd9525 1220 my $op_sql = $self->_sqlcase(join ' ', split '_', $op);
b23fd5ff 1221 return ($expr_sql.' '.$op_sql, @bind);
1222}
1223
4a1f01a3 1224# Some databases (SQLite) treat col IN (1, 2) different from
1225# col IN ( (1, 2) ). Use this to strip all outer parens while
1226# adding them back in the corresponding method
1227sub _open_outer_paren {
1228 my ($self, $sql) = @_;
a5f91feb 1229
ca4f826a 1230 while (my ($inner) = $sql =~ /^ \s* \( (.*) \) \s* $/xs) {
a5f91feb 1231
1232 # there are closing parens inside, need the heavy duty machinery
1233 # to reevaluate the extraction starting from $sql (full reevaluation)
ca4f826a 1234 if ($inner =~ /\)/) {
a5f91feb 1235 require Text::Balanced;
1236
1237 my (undef, $remainder) = do {
1238 # idiotic design - writes to $@ but *DOES NOT* throw exceptions
1239 local $@;
ca4f826a 1240 Text::Balanced::extract_bracketed($sql, '()', qr/\s*/);
a5f91feb 1241 };
1242
1243 # the entire expression needs to be a balanced bracketed thing
1244 # (after an extract no remainder sans trailing space)
1245 last if defined $remainder and $remainder =~ /\S/;
1246 }
1247
1248 $sql = $inner;
1249 }
1250
1251 $sql;
4a1f01a3 1252}
1253
96449e8e 1254
96449e8e 1255#======================================================================
1256# ORDER BY
1257#======================================================================
1258
33177570 1259sub _expand_order_by {
96449e8e 1260 my ($self, $arg) = @_;
1261
33177570 1262 return unless defined($arg) and not (ref($arg) eq 'ARRAY' and !@$arg);
2b6158af 1263
4325df6a 1264 my $expander = sub {
1265 my ($self, $dir, $expr) = @_;
52ca537e 1266 my @to_expand = ref($expr) eq 'ARRAY' ? @$expr : $expr;
1267 foreach my $arg (@to_expand) {
1268 if (
1269 ref($arg) eq 'HASH'
1270 and keys %$arg > 1
1271 and grep /^-(asc|desc)$/, keys %$arg
1272 ) {
1273 puke "ordering direction hash passed to order by must have exactly one key (-asc or -desc)";
1274 }
1275 }
7384c311 1276 my @exp = map +(
1277 defined($dir) ? { -op => [ $dir =~ /^-?(.*)$/ ,=> $_ ] } : $_
1278 ),
79d310f2 1279 map $self->expand_expr($_, -ident),
74156ee9 1280 map ref($_) eq 'ARRAY' ? @$_ : $_, @to_expand;
352d74bc 1281 return (@exp > 1 ? { -list => \@exp } : $exp[0]);
4325df6a 1282 };
18c743c8 1283
7384c311 1284 local @{$self->{expand}}{qw(-asc -desc)} = (($expander) x 2);
f267b646 1285
33177570 1286 return $self->$expander(undef, $arg);
1287}
1288
1289sub _order_by {
1290 my ($self, $arg) = @_;
1291
1292 return '' unless defined(my $expanded = $self->_expand_order_by($arg));
4325df6a 1293
79d310f2 1294 my ($sql, @bind) = $self->render_aqt($expanded);
4325df6a 1295
13cd9220 1296 return '' unless length($sql);
1297
4325df6a 1298 my $final_sql = $self->_sqlcase(' order by ').$sql;
1299
1300 return wantarray ? ($final_sql, @bind) : $final_sql;
f267b646 1301}
1302
2e3cc357 1303# _order_by no longer needs to call this so doesn't but DBIC uses it.
1304
33177570 1305sub _order_by_chunks {
1306 my ($self, $arg) = @_;
1307
1308 return () unless defined(my $expanded = $self->_expand_order_by($arg));
1309
2e3cc357 1310 return $self->_chunkify_order_by($expanded);
1311}
1312
1313sub _chunkify_order_by {
1314 my ($self, $expanded) = @_;
1b630cfe 1315
79d310f2 1316 return grep length, $self->render_aqt($expanded)
1b630cfe 1317 if $expanded->{-ident} or @{$expanded->{-literal}||[]} == 1;
1318
33177570 1319 for ($expanded) {
352d74bc 1320 if (ref() eq 'HASH' and my $l = $_->{-list}) {
1321 return map $self->_chunkify_order_by($_), @$l;
33177570 1322 }
79d310f2 1323 return [ $self->render_aqt($_) ];
33177570 1324 }
1325}
1326
96449e8e 1327#======================================================================
1328# DATASOURCE (FOR NOW, JUST PLAIN TABLE OR LIST OF TABLES)
1329#======================================================================
1330
1331sub _table {
1332 my $self = shift;
1333 my $from = shift;
79d310f2 1334 ($self->render_aqt(
8476c6a3 1335 $self->_expand_maybe_list_expr($from, undef, -ident)
7ad12721 1336 ))[0];
96449e8e 1337}
1338
1339
1340#======================================================================
1341# UTILITY FUNCTIONS
1342#======================================================================
1343
8476c6a3 1344sub _expand_maybe_list_expr {
1345 my ($self, $expr, $logic, $default) = @_;
bba04f52 1346 my $e = do {
1347 if (ref($expr) eq 'ARRAY') {
352d74bc 1348 return { -list => [
4ee3313d 1349 map $self->expand_expr($_, $default), @$expr
bba04f52 1350 ] } if @$expr > 1;
1351 $expr->[0]
1352 } else {
1353 $expr
1354 }
1355 };
4ee3313d 1356 return $self->expand_expr($e, $default);
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