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