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