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