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