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