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