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