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