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