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