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