• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

dbsrgits / sql-abstract / 19

pending completion
19

Pull #14

travis-ci

web-flow
Do not replace the literal string '0' with ''
Pull Request #14: Do not replace the literal string '0' with ''

1 of 1 new or added line in 1 file covered. (100.0%)

805 of 912 relevant lines covered (88.27%)

37268.84 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.36
/lib/SQL/Abstract.pm
1
package SQL::Abstract; # see doc at end of file
2

3
use strict;
180✔
4
use warnings;
180✔
5
use Carp ();
180✔
6
use List::Util ();
180✔
7
use Scalar::Util ();
180✔
8

9
use Exporter 'import';
180✔
10
our @EXPORT_OK = qw(is_plain_value is_literal_value);
11

12
BEGIN {
13
  if ($] < 5.009_005) {
180✔
14
    require MRO::Compat;
15✔
15
  }
16
  else {
17
    require mro;
165✔
18
  }
19

20
  *SQL::Abstract::_ENV_::DETECT_AUTOGENERATED_STRINGIFICATION = $ENV{SQLA_ISVALUE_IGNORE_AUTOGENERATED_STRINGIFICATION}
21
    ? sub () { 0 }
22
    : sub () { 1 }
23
  ;
180✔
24
}
25

26
#======================================================================
27
# GLOBALS
28
#======================================================================
29

30
our $VERSION  = '1.85';
31

32
# This would confuse some packagers
33
$VERSION = eval $VERSION if $VERSION =~ /_/; # numify for warning-free dev releases
34

35
our $AUTOLOAD;
36

37
# special operators (-in, -between). May be extended/overridden by user.
38
# See section WHERE: BUILTIN SPECIAL OPERATORS below for implementation
39
my @BUILTIN_SPECIAL_OPS = (
40
  {regex => qr/^ (?: not \s )? between $/ix, handler => '_where_field_BETWEEN'},
41
  {regex => qr/^ (?: not \s )? in      $/ix, handler => '_where_field_IN'},
42
  {regex => qr/^ ident                 $/ix, handler => '_where_op_IDENT'},
43
  {regex => qr/^ value                 $/ix, handler => '_where_op_VALUE'},
44
  {regex => qr/^ is (?: \s+ not )?     $/ix, handler => '_where_field_IS'},
45
);
46

47
# unaryish operators - key maps to handler
48
my @BUILTIN_UNARY_OPS = (
49
  # the digits are backcompat stuff
50
  { regex => qr/^ and  (?: [_\s]? \d+ )? $/xi, handler => '_where_op_ANDOR' },
51
  { regex => qr/^ or   (?: [_\s]? \d+ )? $/xi, handler => '_where_op_ANDOR' },
52
  { regex => qr/^ nest (?: [_\s]? \d+ )? $/xi, handler => '_where_op_NEST' },
53
  { regex => qr/^ (?: not \s )? bool     $/xi, handler => '_where_op_BOOL' },
54
  { regex => qr/^ ident                  $/xi, handler => '_where_op_IDENT' },
55
  { regex => qr/^ value                  $/xi, handler => '_where_op_VALUE' },
56
);
57

58
#======================================================================
59
# DEBUGGING AND ERROR REPORTING
60
#======================================================================
61

62
sub _debug {
63
  return unless $_[0]->{debug}; shift; # a little faster
13,920✔
64
  my $func = (caller(1))[3];
×
65
  warn "[$func] ", @_, "\n";
×
66
}
67

68
sub belch (@) {
69
  my($func) = (caller(1))[3];
1,776✔
70
  Carp::carp "[$func] Warning: ", @_;
1,776✔
71
}
72

73
sub puke (@) {
74
  my($func) = (caller(1))[3];
1,392✔
75
  Carp::croak "[$func] Fatal: ", @_;
1,392✔
76
}
77

78
sub is_literal_value ($) {
79
    ref $_[0] eq 'SCALAR'                                     ? [ ${$_[0]} ]
156✔
80
  : ( ref $_[0] eq 'REF' and ref ${$_[0]} eq 'ARRAY' )        ? [ @${ $_[0] } ]
600✔
81
  : undef;
82
}
83

84
# FIXME XSify - this can be done so much more efficiently
85
sub is_plain_value ($) {
86
  no strict 'refs';
180✔
87
    ! length ref $_[0]                                        ? \($_[0])
88
  : (
89
    ref $_[0] eq 'HASH' and keys %{$_[0]} == 1
90
      and
91
    exists $_[0]->{-value}
92
  )                                                           ? \($_[0]->{-value})
93
  : (
94
      # reuse @_ for even moar speedz
95
      defined ( $_[1] = Scalar::Util::blessed $_[0] )
96
        and
97
      # deliberately not using Devel::OverloadInfo - the checks we are
98
      # intersted in are much more limited than the fullblown thing, and
99
      # this is a very hot piece of code
100
      (
101
        # simply using ->can('(""') can leave behind stub methods that
102
        # break actually using the overload later (see L<perldiag/Stub
103
        # found while resolving method "%s" overloading "%s" in package
104
        # "%s"> and the source of overload::mycan())
105
        #
106
        # either has stringification which DBI SHOULD prefer out of the box
107
        grep { *{ (qq[${_}::(""]) }{CODE} } @{ $_[2] = mro::get_linear_isa( $_[1] ) }
108
          or
109
        # has nummification or boolification, AND fallback is *not* disabled
110
        (
111
          SQL::Abstract::_ENV_::DETECT_AUTOGENERATED_STRINGIFICATION
112
            and
113
          (
114
            grep { *{"${_}::(0+"}{CODE} } @{$_[2]}
115
              or
116
            grep { *{"${_}::(bool"}{CODE} } @{$_[2]}
117
          )
118
            and
119
          (
120
            # no fallback specified at all
121
            ! ( ($_[3]) = grep { *{"${_}::()"}{CODE} } @{$_[2]} )
122
              or
123
            # fallback explicitly undef
124
            ! defined ${"$_[3]::()"}
125
              or
126
            # explicitly true
127
            !! ${"$_[3]::()"}
584✔
128
          )
129
        )
130
      )
131
    )                                                          ? \($_[0])
132
  : undef;
133
}
134

135

136

137
#======================================================================
138
# NEW
139
#======================================================================
140

141
sub new {
142
  my $self = shift;
7,332✔
143
  my $class = ref($self) || $self;
7,332✔
144
  my %opt = (ref $_[0] eq 'HASH') ? %{$_[0]} : @_;
7,332✔
145

146
  # choose our case by keeping an option around
147
  delete $opt{case} if $opt{case} && $opt{case} ne 'lower';
7,332✔
148

149
  # default logic for interpreting arrayrefs
150
  $opt{logic} = $opt{logic} ? uc $opt{logic} : 'OR';
7,332✔
151

152
  # how to return bind vars
153
  $opt{bindtype} ||= 'normal';
7,332✔
154

155
  # default comparison is "=", but can be overridden
156
  $opt{cmp} ||= '=';
7,332✔
157

158
  # try to recognize which are the 'equality' and 'inequality' ops
159
  # (temporary quickfix (in 2007), should go through a more seasoned API)
160
  $opt{equality_op}   = qr/^( \Q$opt{cmp}\E | \= )$/ix;
7,332✔
161
  $opt{inequality_op} = qr/^( != | <> )$/ix;
7,332✔
162

163
  $opt{like_op}       = qr/^ (is\s+)? r?like $/xi;
7,332✔
164
  $opt{not_like_op}   = qr/^ (is\s+)? not \s+ r?like $/xi;
7,332✔
165

166
  # SQL booleans
167
  $opt{sqltrue}  ||= '1=1';
7,332✔
168
  $opt{sqlfalse} ||= '0=1';
7,332✔
169

170
  # special operators
171
  $opt{special_ops} ||= [];
7,332✔
172
  # regexes are applied in order, thus push after user-defines
173
  push @{$opt{special_ops}}, @BUILTIN_SPECIAL_OPS;
7,332✔
174

175
  # unary operators
176
  $opt{unary_ops} ||= [];
7,332✔
177
  push @{$opt{unary_ops}}, @BUILTIN_UNARY_OPS;
7,332✔
178

179
  # rudimentary sanity-check for user supplied bits treated as functions/operators
180
  # If a purported  function matches this regular expression, an exception is thrown.
181
  # Literal SQL is *NOT* subject to this check, only functions (and column names
182
  # when quoting is not in effect)
183

184
  # FIXME
185
  # need to guard against ()'s in column names too, but this will break tons of
186
  # hacks... ideas anyone?
187
  $opt{injection_guard} ||= qr/
7,332✔
188
    \;
189
      |
190
    ^ \s* go \s
191
  /xmi;
192

193
  return bless \%opt, $class;
7,332✔
194
}
195

196

197
sub _assert_pass_injection_guard {
198
  if ($_[1] =~ $_[0]->{injection_guard}) {
21,624✔
199
    my $class = ref $_[0];
60✔
200
    puke "Possible SQL injection attempt '$_[1]'. If this is indeed a part of the "
60✔
201
     . "desired SQL use literal SQL ( \'...' or \[ '...' ] ) or supply your own "
202
     . "{injection_guard} attribute to ${class}->new()"
203
  }
204
}
205

206

207
#======================================================================
208
# INSERT methods
209
#======================================================================
210

211
sub insert {
212
  my $self    = shift;
588✔
213
  my $table   = $self->_table(shift);
588✔
214
  my $data    = shift || return;
588✔
215
  my $options = shift;
588✔
216

217
  my $method       = $self->_METHOD_FOR_refkind("_insert", $data);
588✔
218
  my ($sql, @bind) = $self->$method($data);
588✔
219
  $sql = join " ", $self->_sqlcase('insert into'), $table, $sql;
564✔
220

221
  if ($options->{returning}) {
564✔
222
    my ($s, @b) = $self->_insert_returning($options);
120✔
223
    $sql .= $s;
120✔
224
    push @bind, @b;
120✔
225
  }
226

227
  return wantarray ? ($sql, @bind) : $sql;
564✔
228
}
229

230
# So that subclasses can override INSERT ... RETURNING separately from
231
# UPDATE and DELETE (e.g. DBIx::Class::SQLMaker::Oracle does this)
232
sub _insert_returning { shift->_returning(@_) }
120✔
233

234
sub _returning {
235
  my ($self, $options) = @_;
264✔
236

237
  my $f = $options->{returning};
264✔
238

239
  my $fieldlist = $self->_SWITCH_refkind($f, {
98✔
240
    ARRAYREF     => sub {join ', ', map { $self->_quote($_) } @$f;},
72✔
241
    SCALAR       => sub {$self->_quote($f)},
96✔
242
    SCALARREF    => sub {$$f},
96✔
243
  });
264✔
244
  return $self->_sqlcase(' returning ') . $fieldlist;
264✔
245
}
246

247
sub _insert_HASHREF { # explicit list of fields and then values
248
  my ($self, $data) = @_;
336✔
249

250
  my @fields = sort keys %$data;
336✔
251

252
  my ($sql, @bind) = $self->_insert_values($data);
336✔
253

254
  # assemble SQL
255
  $_ = $self->_quote($_) foreach @fields;
312✔
256
  $sql = "( ".join(", ", @fields).") ".$sql;
312✔
257

258
  return ($sql, @bind);
312✔
259
}
260

261
sub _insert_ARRAYREF { # just generate values(?,?) part (no list of fields)
262
  my ($self, $data) = @_;
252✔
263

264
  # no names (arrayref) so can't generate bindtype
265
  $self->{bindtype} ne 'columns'
252✔
266
    or belch "can't do 'columns' bindtype when called with arrayref";
267

268
  my (@values, @all_bind);
252✔
269
  foreach my $value (@$data) {
252✔
270
    my ($values, @bind) = $self->_insert_value(undef, $value);
1,872✔
271
    push @values, $values;
1,872✔
272
    push @all_bind, @bind;
1,872✔
273
  }
274
  my $sql = $self->_sqlcase('values')." ( ".join(", ", @values)." )";
252✔
275
  return ($sql, @all_bind);
252✔
276
}
277

278
sub _insert_ARRAYREFREF { # literal SQL with bind
279
  my ($self, $data) = @_;
×
280

281
  my ($sql, @bind) = @${$data};
×
282
  $self->_assert_bindval_matches_bindtype(@bind);
×
283

284
  return ($sql, @bind);
×
285
}
286

287

288
sub _insert_SCALARREF { # literal SQL without bind
289
  my ($self, $data) = @_;
×
290

291
  return ($$data);
×
292
}
293

294
sub _insert_values {
295
  my ($self, $data) = @_;
336✔
296

297
  my (@values, @all_bind);
336✔
298
  foreach my $column (sort keys %$data) {
336✔
299
    my ($values, @bind) = $self->_insert_value($column, $data->{$column});
1,140✔
300
    push @values, $values;
1,116✔
301
    push @all_bind, @bind;
1,116✔
302
  }
303
  my $sql = $self->_sqlcase('values')." ( ".join(", ", @values)." )";
312✔
304
  return ($sql, @all_bind);
312✔
305
}
306

307
sub _insert_value {
308
  my ($self, $column, $v) = @_;
3,012✔
309

310
  my (@values, @all_bind);
3,012✔
311
  $self->_SWITCH_refkind($v, {
312

313
    ARRAYREF => sub {
314
      if ($self->{array_datatypes}) { # if array datatype are activated
60✔
315
        push @values, '?';
48✔
316
        push @all_bind, $self->_bindtype($column, $v);
48✔
317
      }
318
      else {                  # else literal SQL with bind
319
        my ($sql, @bind) = @$v;
12✔
320
        $self->_assert_bindval_matches_bindtype(@bind);
12✔
321
        push @values, $sql;
12✔
322
        push @all_bind, @bind;
12✔
323
      }
324
    },
325

326
    ARRAYREFREF => sub {        # literal SQL with bind
327
      my ($sql, @bind) = @${$v};
132✔
328
      $self->_assert_bindval_matches_bindtype(@bind);
132✔
329
      push @values, $sql;
108✔
330
      push @all_bind, @bind;
108✔
331
    },
332

333
    # THINK: anything useful to do with a HASHREF ?
334
    HASHREF => sub {       # (nothing, but old SQLA passed it through)
335
      #TODO in SQLA >= 2.0 it will die instead
336
      belch "HASH ref as bind value in insert is not supported";
24✔
337
      push @values, '?';
24✔
338
      push @all_bind, $self->_bindtype($column, $v);
24✔
339
    },
340

341
    SCALARREF => sub {          # literal SQL without bind
342
      push @values, $$v;
72✔
343
    },
344

345
    SCALAR_or_UNDEF => sub {
346
      push @values, '?';
2,724✔
347
      push @all_bind, $self->_bindtype($column, $v);
2,724✔
348
    },
349

350
  });
3,012✔
351

352
  my $sql = join(", ", @values);
2,988✔
353
  return ($sql, @all_bind);
2,988✔
354
}
355

356

357

358
#======================================================================
359
# UPDATE methods
360
#======================================================================
361

362

363
sub update {
364
  my $self    = shift;
456✔
365
  my $table   = $self->_table(shift);
456✔
366
  my $data    = shift || return;
456✔
367
  my $where   = shift;
456✔
368
  my $options = shift;
456✔
369

370
  # first build the 'SET' part of the sql statement
371
  puke "Unsupported data type specified to \$sql->update"
456✔
372
    unless ref $data eq 'HASH';
373

374
  my ($sql, @all_bind) = $self->_update_set_values($data);
456✔
375
  $sql = $self->_sqlcase('update ') . $table . $self->_sqlcase(' set ')
432✔
376
          . $sql;
377

378
  if ($where) {
432✔
379
    my($where_sql, @where_bind) = $self->where($where);
360✔
380
    $sql .= $where_sql;
360✔
381
    push @all_bind, @where_bind;
360✔
382
  }
383

384
  if ($options->{returning}) {
432✔
385
    my ($returning_sql, @returning_bind) = $self->_update_returning($options);
72✔
386
    $sql .= $returning_sql;
72✔
387
    push @all_bind, @returning_bind;
72✔
388
  }
389

390
  return wantarray ? ($sql, @all_bind) : $sql;
432✔
391
}
392

393
sub _update_set_values {
394
  my ($self, $data) = @_;
456✔
395

396
  my (@set, @all_bind);
456✔
397
  for my $k (sort keys %$data) {
456✔
398
    my $v = $data->{$k};
936✔
399
    my $r = ref $v;
936✔
400
    my $label = $self->_quote($k);
936✔
401

402
    $self->_SWITCH_refkind($v, {
403
      ARRAYREF => sub {
404
        if ($self->{array_datatypes}) { # array datatype
48✔
405
          push @set, "$label = ?";
48✔
406
          push @all_bind, $self->_bindtype($k, $v);
48✔
407
        }
408
        else {                          # literal SQL with bind
409
          my ($sql, @bind) = @$v;
×
410
          $self->_assert_bindval_matches_bindtype(@bind);
×
411
          push @set, "$label = $sql";
×
412
          push @all_bind, @bind;
×
413
        }
414
      },
415
      ARRAYREFREF => sub { # literal SQL with bind
416
        my ($sql, @bind) = @${$v};
120✔
417
        $self->_assert_bindval_matches_bindtype(@bind);
120✔
418
        push @set, "$label = $sql";
96✔
419
        push @all_bind, @bind;
96✔
420
      },
421
      SCALARREF => sub {  # literal SQL without bind
422
        push @set, "$label = $$v";
×
423
      },
424
      HASHREF => sub {
425
        my ($op, $arg, @rest) = %$v;
48✔
426

427
        puke 'Operator calls in update must be in the form { -op => $arg }'
48✔
428
          if (@rest or not $op =~ /^\-(.+)/);
429

430
        local $self->{_nested_func_lhs} = $k;
48✔
431
        my ($sql, @bind) = $self->_where_unary_op($1, $arg);
48✔
432

433
        push @set, "$label = $sql";
48✔
434
        push @all_bind, @bind;
48✔
435
      },
436
      SCALAR_or_UNDEF => sub {
437
        push @set, "$label = ?";
720✔
438
        push @all_bind, $self->_bindtype($k, $v);
720✔
439
      },
440
    });
936✔
441
  }
442

443
  # generate sql
444
  my $sql = join ', ', @set;
432✔
445

446
  return ($sql, @all_bind);
432✔
447
}
448

449
# So that subclasses can override UPDATE ... RETURNING separately from
450
# INSERT and DELETE
451
sub _update_returning { shift->_returning(@_) }
72✔
452

453

454

455
#======================================================================
456
# SELECT
457
#======================================================================
458

459

460
sub select {
461
  my $self   = shift;
1,224✔
462
  my $table  = $self->_table(shift);
1,224✔
463
  my $fields = shift || '*';
1,224✔
464
  my $where  = shift;
1,224✔
465
  my $order  = shift;
1,224✔
466

467
  my ($fields_sql, @bind) = $self->_select_fields($fields);
1,224✔
468

469
  my ($where_sql, @where_bind) = $self->where($where, $order);
1,224✔
470
  push @bind, @where_bind;
1,068✔
471

472
  my $sql = join(' ', $self->_sqlcase('select'), $fields_sql,
1,068✔
473
                      $self->_sqlcase('from'),   $table)
474
          . $where_sql;
475

476
  return wantarray ? ($sql, @bind) : $sql;
1,068✔
477
}
478

479
sub _select_fields {
480
  my ($self, $fields) = @_;
1,224✔
481
  return ref $fields eq 'ARRAY' ? join ', ', map { $self->_quote($_) } @$fields
1,224✔
482
                                : $fields;
483
}
484

485
#======================================================================
486
# DELETE
487
#======================================================================
488

489

490
sub delete {
491
  my $self    = shift;
120✔
492
  my $table   = $self->_table(shift);
120✔
493
  my $where   = shift;
120✔
494
  my $options = shift;
120✔
495

496
  my($where_sql, @bind) = $self->where($where);
120✔
497
  my $sql = $self->_sqlcase('delete from ') . $table . $where_sql;
120✔
498

499
  if ($options->{returning}) {
120✔
500
    my ($returning_sql, @returning_bind) = $self->_delete_returning($options);
72✔
501
    $sql .= $returning_sql;
72✔
502
    push @bind, @returning_bind;
72✔
503
  }
504

505
  return wantarray ? ($sql, @bind) : $sql;
120✔
506
}
507

508
# So that subclasses can override DELETE ... RETURNING separately from
509
# INSERT and UPDATE
510
sub _delete_returning { shift->_returning(@_) }
72✔
511

512

513

514
#======================================================================
515
# WHERE: entry point
516
#======================================================================
517

518

519

520
# Finally, a separate routine just to handle WHERE clauses
521
sub where {
522
  my ($self, $where, $order) = @_;
7,428✔
523

524
  # where ?
525
  my ($sql, @bind) = $self->_recurse_where($where);
7,428✔
526
  $sql = (defined $sql and $sql =~ /[^\s]/) ? $self->_sqlcase(' where ') . "( $sql )" : '';
6,108✔
527

528
  # order by?
529
  if ($order) {
6,108✔
530
    my ($order_sql, @order_bind) = $self->_order_by($order);
600✔
531
    $sql .= $order_sql;
600✔
532
    push @bind, @order_bind;
600✔
533
  }
534

535
  return wantarray ? ($sql, @bind) : $sql;
6,108✔
536
}
537

538

539
sub _recurse_where {
540
  my ($self, $where, $logic) = @_;
17,652✔
541

542
  # dispatch on appropriate method according to refkind of $where
543
  my $method = $self->_METHOD_FOR_refkind("_where", $where);
17,652✔
544

545
  my ($sql, @bind) =  $self->$method($where, $logic);
17,652✔
546

547
  # DBIx::Class used to call _recurse_where in scalar context
548
  # something else might too...
549
  if (wantarray) {
16,164✔
550
    return ($sql, @bind);
16,164✔
551
  }
552
  else {
553
    belch "Calling _recurse_where in scalar context is deprecated and will go away before 2.0";
×
554
    return $sql;
×
555
  }
556
}
557

558

559

560
#======================================================================
561
# WHERE: top-level ARRAYREF
562
#======================================================================
563

564

565
sub _where_ARRAYREF {
566
  my ($self, $where, $logic) = @_;
4,740✔
567

568
  $logic = uc($logic || $self->{logic});
4,740✔
569
  $logic eq 'AND' or $logic eq 'OR' or puke "unknown logic: $logic";
4,740✔
570

571
  my @clauses = @$where;
4,740✔
572

573
  my (@sql_clauses, @all_bind);
4,740✔
574
  # need to use while() so can shift() for pairs
575
  while (@clauses) {
4,740✔
576
    my $el = shift @clauses;
8,256✔
577

578
    $el = undef if (defined $el and ! length $el);
8,256✔
579

580
    # switch according to kind of $el and get corresponding ($sql, @bind)
581
    my ($sql, @bind) = $self->_SWITCH_refkind($el, {
105✔
582

583
      # skip empty elements, otherwise get invalid trailing AND stuff
584
      ARRAYREF  => sub {$self->_recurse_where($el)        if @$el},
75✔
585

586
      ARRAYREFREF => sub {
587
        my ($s, @b) = @$$el;
12✔
588
        $self->_assert_bindval_matches_bindtype(@b);
12✔
589
        ($s, @b);
12✔
590
      },
591

592
      HASHREF   => sub {$self->_recurse_where($el, 'and') if %$el},
3,276✔
593

594
      SCALARREF => sub { ($$el);                                 },
×
595

596
      SCALAR    => sub {
597
        # top-level arrayref with scalars, recurse in pairs
598
        $self->_recurse_where({$el => shift(@clauses)})
4,164✔
599
      },
600

601
      UNDEF     => sub {puke "Supplying an empty left hand side argument is not supported in array-pairs" },
624✔
602
    });
8,256✔
603

604
    if ($sql) {
7,488✔
605
      push @sql_clauses, $sql;
7,476✔
606
      push @all_bind, @bind;
7,476✔
607
    }
608
  }
609

610
  return $self->_join_sql_clauses($logic, \@sql_clauses, \@all_bind);
3,972✔
611
}
612

613
#======================================================================
614
# WHERE: top-level ARRAYREFREF
615
#======================================================================
616

617
sub _where_ARRAYREFREF {
618
    my ($self, $where) = @_;
72✔
619
    my ($sql, @bind) = @$$where;
72✔
620
    $self->_assert_bindval_matches_bindtype(@bind);
72✔
621
    return ($sql, @bind);
72✔
622
}
623

624
#======================================================================
625
# WHERE: top-level HASHREF
626
#======================================================================
627

628
sub _where_HASHREF {
629
  my ($self, $where) = @_;
13,968✔
630
  my (@sql_clauses, @all_bind);
13,968✔
631

632
  for my $k (sort keys %$where) {
13,968✔
633
    my $v = $where->{$k};
16,704✔
634

635
    # ($k => $v) is either a special unary op or a regular hashpair
636
    my ($sql, @bind) = do {
16,704✔
637
      if ($k =~ /^-./) {
16,704✔
638
        # put the operator in canonical form
639
        my $op = $k;
2,700✔
640
        $op = substr $op, 1;  # remove initial dash
2,700✔
641
        $op =~ s/^\s+|\s+$//g;# remove leading/trailing space
2,700✔
642
        $op =~ s/\s+/ /g;     # compress whitespace
2,700✔
643

644
        # so that -not_foo works correctly
645
        $op =~ s/^not_/NOT /i;
2,700✔
646

647
        $self->_debug("Unary OP(-$op) within hashref, recursing...");
2,700✔
648
        my ($s, @b) = $self->_where_unary_op($op, $v);
2,700✔
649

650
        # top level vs nested
651
        # we assume that handled unary ops will take care of their ()s
652
        $s = "($s)" unless (
3,535✔
653
          List::Util::first {$op =~ $_->{regex}} @{$self->{unary_ops}}
3,932✔
654
            or
655
          ( defined $self->{_nested_func_lhs} and $self->{_nested_func_lhs} eq $k )
1,005✔
656
        );
657
        ($s, @b);
2,412✔
658
      }
659
      else {
660
        if (! length $k) {
14,004✔
661
          if (is_literal_value ($v) ) {
528✔
662
            belch 'Hash-pairs consisting of an empty string with a literal are deprecated, and will be removed in 2.0: use -and => [ $literal ] instead';
240✔
663
          }
664
          else {
665
            puke "Supplying an empty left hand side argument is not supported in hash-pairs";
288✔
666
          }
667
        }
668

669
        my $method = $self->_METHOD_FOR_refkind("_where_hashpair", $v);
13,716✔
670
        $self->$method($k, $v);
13,716✔
671
      }
672
    };
673

674
    push @sql_clauses, $sql;
15,744✔
675
    push @all_bind, @bind;
15,744✔
676
  }
677

678
  return $self->_join_sql_clauses('and', \@sql_clauses, \@all_bind);
13,008✔
679
}
680

681
sub _where_unary_op {
682
  my ($self, $op, $rhs) = @_;
5,352✔
683

684
  # top level special ops are illegal in general
685
  # this includes the -ident/-value ops (dual purpose unary and special)
686
  puke "Illegal use of top-level '-$op'"
687
    if ! defined $self->{_nested_func_lhs} and List::Util::first { $op =~ $_->{regex} } @{$self->{special_ops}};
5,352✔
688

689
  if (my $op_entry = List::Util::first { $op =~ $_->{regex} } @{$self->{unary_ops}}) {
5,328✔
690
    my $handler = $op_entry->{handler};
2,448✔
691

692
    if (not ref $handler) {
2,448✔
693
      if ($op =~ s/ [_\s]? \d+ $//x ) {
2,448✔
694
        belch 'Use of [and|or|nest]_N modifiers is deprecated and will be removed in SQLA v2.0. '
108✔
695
            . "You probably wanted ...-and => [ -$op => COND1, -$op => COND2 ... ]";
696
      }
697
      return $self->$handler($op, $rhs);
2,448✔
698
    }
699
    elsif (ref $handler eq 'CODE') {
700
      return $handler->($self, $op, $rhs);
×
701
    }
702
    else {
703
      puke "Illegal handler for operator $op - expecting a method name or a coderef";
×
704
    }
705
  }
706

707
  $self->_debug("Generic unary OP: $op - recursing as function");
2,880✔
708

709
  $self->_assert_pass_injection_guard($op);
2,880✔
710

711
  my ($sql, @bind) = $self->_SWITCH_refkind($rhs, {
712
    SCALAR =>   sub {
713
      puke "Illegal use of top-level '-$op'"
1,449✔
714
        unless defined $self->{_nested_func_lhs};
1,035✔
715

716
      return (
717
        $self->_convert('?'),
1,449✔
718
        $self->_bindtype($self->{_nested_func_lhs}, $rhs)
1,035✔
719
      );
720
    },
721
    FALLBACK => sub {
722
      $self->_recurse_where($rhs)
372✔
723
    },
724
  });
2,856✔
725

726
  $sql = sprintf('%s %s',
2,832✔
727
    $self->_sqlcase($op),
728
    $sql,
729
  );
730

731
  return ($sql, @bind);
2,832✔
732
}
733

734
sub _where_op_ANDOR {
735
  my ($self, $op, $v) = @_;
1,752✔
736

737
  $self->_SWITCH_refkind($v, {
738
    ARRAYREF => sub {
739
      return $self->_where_ARRAYREF($v, $op);
912✔
740
    },
741

742
    HASHREF => sub {
743
      return ($op =~ /^or/i)
469✔
744
        ? $self->_where_ARRAYREF([ map { $_ => $v->{$_} } (sort keys %$v) ], $op)
840✔
745
        : $self->_where_HASHREF($v);
746
    },
747

748
    SCALARREF  => sub {
749
      puke "-$op => \\\$scalar makes little sense, use " .
×
750
        ($op =~ /^or/i
751
          ? '[ \$scalar, \%rest_of_conditions ] instead'
752
          : '-and => [ \$scalar, \%rest_of_conditions ] instead'
753
        );
754
    },
755

756
    ARRAYREFREF => sub {
757
      puke "-$op => \\[...] makes little sense, use " .
×
758
        ($op =~ /^or/i
759
          ? '[ \[...], \%rest_of_conditions ] instead'
760
          : '-and => [ \[...], \%rest_of_conditions ] instead'
761
        );
762
    },
763

764
    SCALAR => sub { # permissively interpreted as SQL
765
      puke "-$op => \$value makes little sense, use -bool => \$value instead";
×
766
    },
767

768
    UNDEF => sub {
769
      puke "-$op => undef not supported";
×
770
    },
771
   });
1,752✔
772
}
773

774
sub _where_op_NEST {
775
  my ($self, $op, $v) = @_;
312✔
776

777
  $self->_SWITCH_refkind($v, {
778

779
    SCALAR => sub { # permissively interpreted as SQL
780
      belch "literal SQL should be -nest => \\'scalar' "
×
781
          . "instead of -nest => 'scalar' ";
782
      return ($v);
×
783
    },
784

785
    UNDEF => sub {
786
      puke "-$op => undef not supported";
×
787
    },
788

789
    FALLBACK => sub {
790
      $self->_recurse_where($v);
312✔
791
    },
792

793
   });
312✔
794
}
795

796

797
sub _where_op_BOOL {
798
  my ($self, $op, $v) = @_;
288✔
799

800
  my ($s, @b) = $self->_SWITCH_refkind($v, {
801
    SCALAR => sub { # interpreted as SQL column
802
      $self->_convert($self->_quote($v));
168✔
803
    },
804

805
    UNDEF => sub {
806
      puke "-$op => undef not supported";
×
807
    },
808

809
    FALLBACK => sub {
810
      $self->_recurse_where($v);
120✔
811
    },
812
  });
288✔
813

814
  $s = "(NOT $s)" if $op =~ /^not/i;
288✔
815
  ($s, @b);
288✔
816
}
817

818

819
sub _where_op_IDENT {
820
  my $self = shift;
96✔
821
  my ($op, $rhs) = splice @_, -2;
96✔
822
  if (! defined $rhs or length ref $rhs) {
96✔
823
    puke "-$op requires a single plain scalar argument (a quotable identifier)";
24✔
824
  }
825

826
  # in case we are called as a top level special op (no '=')
827
  my $lhs = shift;
72✔
828

829
  $_ = $self->_convert($self->_quote($_)) for ($lhs, $rhs);
72✔
830

831
  return $lhs
72✔
832
    ? "$lhs = $rhs"
833
    : $rhs
834
  ;
835
}
836

837
sub _where_op_VALUE {
838
  my $self = shift;
144✔
839
  my ($op, $rhs) = splice @_, -2;
144✔
840

841
  # in case we are called as a top level special op (no '=')
842
  my $lhs = shift;
144✔
843

844
  # special-case NULL
845
  if (! defined $rhs) {
144✔
846
    return defined $lhs
48✔
847
      ? $self->_convert($self->_quote($lhs)) . ' IS NULL'
848
      : undef
849
    ;
850
  }
851

852
  my @bind =
56✔
853
    $self->_bindtype(
854
      (defined $lhs ? $lhs : $self->{_nested_func_lhs}),
40✔
855
      $rhs,
856
    )
857
  ;
858

859
  return $lhs
96✔
860
    ? (
861
      $self->_convert($self->_quote($lhs)) . ' = ' . $self->_convert('?'),
862
      @bind
863
    )
864
    : (
865
      $self->_convert('?'),
866
      @bind,
867
    )
868
  ;
869
}
870

871
sub _where_hashpair_ARRAYREF {
872
  my ($self, $k, $v) = @_;
552✔
873

874
  if (@$v) {
552✔
875
    my @v = @$v; # need copy because of shift below
540✔
876
    $self->_debug("ARRAY($k) means distribute over elements");
540✔
877

878
    # put apart first element if it is an operator (-and, -or)
879
    my $op = (
540✔
880
       (defined $v[0] && $v[0] =~ /^ - (?: AND|OR ) $/ix)
881
         ? shift @v
882
         : ''
883
    );
884
    my @distributed = map { {$k =>  $_} } @v;
540✔
885

886
    if ($op) {
540✔
887
      $self->_debug("OP($op) reinjected into the distributed array");
264✔
888
      unshift @distributed, $op;
264✔
889
    }
890

891
    my $logic = $op ? substr($op, 1) : '';
540✔
892

893
    return $self->_recurse_where(\@distributed, $logic);
540✔
894
  }
895
  else {
896
    $self->_debug("empty ARRAY($k) means 0=1");
12✔
897
    return ($self->{sqlfalse});
12✔
898
  }
899
}
900

901
sub _where_hashpair_HASHREF {
902
  my ($self, $k, $v, $logic) = @_;
6,996✔
903
  $logic ||= 'and';
6,996✔
904

905
  local $self->{_nested_func_lhs} = defined $self->{_nested_func_lhs}
4,081✔
906
    ? $self->{_nested_func_lhs}
907
    : $k
2,915✔
908
  ;
909

910
  my ($all_sql, @all_bind);
6,996✔
911

912
  for my $orig_op (sort keys %$v) {
6,996✔
913
    my $val = $v->{$orig_op};
7,080✔
914

915
    # put the operator in canonical form
916
    my $op = $orig_op;
7,080✔
917

918
    # FIXME - we need to phase out dash-less ops
919
    $op =~ s/^-//;        # remove possible initial dash
7,080✔
920
    $op =~ s/^\s+|\s+$//g;# remove leading/trailing space
7,080✔
921
    $op =~ s/\s+/ /g;     # compress whitespace
7,080✔
922

923
    $self->_assert_pass_injection_guard($op);
7,080✔
924

925
    # fixup is_not
926
    $op =~ s/^is_not/IS NOT/i;
7,056✔
927

928
    # so that -not_foo works correctly
929
    $op =~ s/^not_/NOT /i;
7,056✔
930

931
    # another retarded special case: foo => { $op => { -value => undef } }
932
    if (ref $val eq 'HASH' and keys %$val == 1 and exists $val->{-value} and ! defined $val->{-value} ) {
7,056✔
933
      $val = undef;
336✔
934
    }
935

936
    my ($sql, @bind);
7,056✔
937

938
    # CASE: col-value logic modifiers
939
    if ($orig_op =~ /^ \- (and|or) $/xi) {
7,056✔
940
      ($sql, @bind) = $self->_where_hashpair_HASHREF($k, $val, $1);
12✔
941
    }
942
    # CASE: special operators like -in or -between
943
    elsif (my $special_op = List::Util::first { $op =~ $_->{regex} } @{$self->{special_ops}}) {
31,404✔
944
      my $handler = $special_op->{handler};
1,644✔
945
      if (! $handler) {
1,644✔
946
        puke "No handler supplied for special operator $orig_op";
×
947
      }
948
      elsif (not ref $handler) {
949
        ($sql, @bind) = $self->$handler($k, $op, $val);
1,608✔
950
      }
951
      elsif (ref $handler eq 'CODE') {
952
        ($sql, @bind) = $handler->($self, $k, $op, $val);
36✔
953
      }
954
      else {
955
        puke "Illegal handler for special operator $orig_op - expecting a method name or a coderef";
×
956
      }
957
    }
958
    else {
959
      $self->_SWITCH_refkind($val, {
960

961
        ARRAYREF => sub {       # CASE: col => {op => \@vals}
962
          ($sql, @bind) = $self->_where_field_op_ARRAYREF($k, $op, $val);
1,788✔
963
        },
964

965
        ARRAYREFREF => sub {    # CASE: col => {op => \[$sql, @bind]} (literal SQL with bind)
966
          my ($sub_sql, @sub_bind) = @$$val;
120✔
967
          $self->_assert_bindval_matches_bindtype(@sub_bind);
120✔
968
          $sql  = join ' ', $self->_convert($self->_quote($k)),
96✔
969
                            $self->_sqlcase($op),
970
                            $sub_sql;
971
          @bind = @sub_bind;
96✔
972
        },
973

974
        UNDEF => sub {          # CASE: col => {op => undef} : sql "IS (NOT)? NULL"
975
          my $is =
77✔
976
            $op =~ /^not$/i               ? 'is not'  # legacy
977
          : $op =~ $self->{equality_op}   ? 'is'
978
          : $op =~ $self->{like_op}       ? belch("Supplying an undefined argument to '@{[ uc $op]}' is deprecated") && 'is'
979
          : $op =~ $self->{inequality_op} ? 'is not'
980
          : $op =~ $self->{not_like_op}   ? belch("Supplying an undefined argument to '@{[ uc $op]}' is deprecated") && 'is not'
847✔
981
          : puke "unexpected operator '$orig_op' with undef operand";
982

983
          $sql = $self->_quote($k) . $self->_sqlcase(" $is null");
924✔
984
        },
985

986
        FALLBACK => sub {       # CASE: col => {op/func => $stuff}
987
          ($sql, @bind) = $self->_where_unary_op($op, $val);
2,568✔
988

989
          $sql = join(' ',
1,484✔
990
            $self->_convert($self->_quote($k)),
991
            $self->{_nested_func_lhs} eq $k ? $sql : "($sql)",  # top level vs nested
1,060✔
992
          );
993
        },
994
      });
5,400✔
995
    }
996

997
    ($all_sql) = (defined $all_sql and $all_sql) ? $self->_join_sql_clauses($logic, [$all_sql, $sql], []) : $sql;
6,732✔
998
    push @all_bind, @bind;
6,732✔
999
  }
1000
  return ($all_sql, @all_bind);
6,648✔
1001
}
1002

1003
sub _where_field_IS {
1004
  my ($self, $k, $op, $v) = @_;
480✔
1005

1006
  my ($s) = $self->_SWITCH_refkind($v, {
1007
    UNDEF => sub {
1008
      join ' ',
560✔
1009
        $self->_convert($self->_quote($k)),
1010
        map { $self->_sqlcase($_)} ($op, 'null')
480✔
1011
    },
1012
    FALLBACK => sub {
1013
      puke "$op can only take undef as argument";
×
1014
    },
1015
  });
480✔
1016

1017
  $s;
480✔
1018
}
1019

1020
sub _where_field_op_ARRAYREF {
1021
  my ($self, $k, $op, $vals) = @_;
1,788✔
1022

1023
  my @vals = @$vals;  #always work on a copy
1,788✔
1024

1025
  if (@vals) {
1,788✔
1026
    $self->_debug(sprintf '%s means multiple elements: [ %s ]',
1,064✔
1027
      $vals,
1028
      join(', ', map { defined $_ ? "'$_'" : 'NULL' } @vals ),
1,272✔
1029
    );
1030

1031
    # see if the first element is an -and/-or op
1032
    my $logic;
1,272✔
1033
    if (defined $vals[0] && $vals[0] =~ /^ - (AND|OR) $/ix) {
1,272✔
1034
      $logic = uc $1;
24✔
1035
      shift @vals;
24✔
1036
    }
1037

1038
    # a long standing API wart - an attempt to change this behavior during
1039
    # the 1.50 series failed *spectacularly*. Warn instead and leave the
1040
    # behavior as is
1041
    if (
1,272✔
1042
      @vals > 1
1043
        and
1044
      (!$logic or $logic eq 'OR')
1045
        and
1046
      ($op =~ $self->{inequality_op} or $op =~ $self->{not_like_op})
1047
    ) {
1048
      my $o = uc($op);
432✔
1049
      belch "A multi-element arrayref as an argument to the inequality op '$o' "
432✔
1050
          . 'is technically equivalent to an always-true 1=1 (you probably wanted '
1051
          . "to say ...{ \$inequality_op => [ -and => \@values ] }... instead)"
1052
      ;
1053
    }
1054

1055
    # distribute $op over each remaining member of @vals, append logic if exists
1056
    return $self->_recurse_where([map { {$k => {$op, $_}} } @vals], $logic);
1,272✔
1057

1058
  }
1059
  else {
1060
    # try to DWIM on equality operators
1061
    return
1062
      $op =~ $self->{equality_op}   ? $self->{sqlfalse}
43✔
1063
    : $op =~ $self->{like_op}       ? belch("Supplying an empty arrayref to '@{[ uc $op]}' is deprecated") && $self->{sqlfalse}
1064
    : $op =~ $self->{inequality_op} ? $self->{sqltrue}
1065
    : $op =~ $self->{not_like_op}   ? belch("Supplying an empty arrayref to '@{[ uc $op]}' is deprecated") && $self->{sqltrue}
258✔
1066
    : puke "operator '$op' applied on an empty array (field '$k')";
215✔
1067
  }
1068
}
1069

1070

1071
sub _where_hashpair_SCALARREF {
1072
  my ($self, $k, $v) = @_;
384✔
1073
  $self->_debug("SCALAR($k) means literal SQL: $$v");
384✔
1074
  my $sql = $self->_quote($k) . " " . $$v;
384✔
1075
  return ($sql);
384✔
1076
}
1077

1078
# literal SQL with bind
1079
sub _where_hashpair_ARRAYREFREF {
1080
  my ($self, $k, $v) = @_;
324✔
1081
  $self->_debug("REF($k) means literal SQL: @${$v}");
324✔
1082
  my ($sql, @bind) = @$$v;
324✔
1083
  $self->_assert_bindval_matches_bindtype(@bind);
324✔
1084
  $sql  = $self->_quote($k) . " " . $sql;
300✔
1085
  return ($sql, @bind );
300✔
1086
}
1087

1088
# literal SQL without bind
1089
sub _where_hashpair_SCALAR {
1090
  my ($self, $k, $v) = @_;
5,280✔
1091
  $self->_debug("NOREF($k) means simple key=val: $k $self->{cmp} $v");
5,280✔
1092
  my $sql = join ' ', $self->_convert($self->_quote($k)),
3,080✔
1093
                      $self->_sqlcase($self->{cmp}),
2,200✔
1094
                      $self->_convert('?');
1095
  my @bind =  $self->_bindtype($k, $v);
5,268✔
1096
  return ($sql, @bind);
5,268✔
1097
}
1098

1099

1100
sub _where_hashpair_UNDEF {
1101
  my ($self, $k, $v) = @_;
192✔
1102
  $self->_debug("UNDEF($k) means IS NULL");
192✔
1103
  my $sql = $self->_quote($k) . $self->_sqlcase(' is null');
192✔
1104
  return ($sql);
192✔
1105
}
1106

1107
#======================================================================
1108
# WHERE: TOP-LEVEL OTHERS (SCALARREF, SCALAR, UNDEF)
1109
#======================================================================
1110

1111

1112
sub _where_SCALARREF {
1113
  my ($self, $where) = @_;
72✔
1114

1115
  # literal sql
1116
  $self->_debug("SCALAR(*top) means literal SQL: $$where");
72✔
1117
  return ($$where);
72✔
1118
}
1119

1120

1121
sub _where_SCALAR {
1122
  my ($self, $where) = @_;
×
1123

1124
  # literal sql
1125
  $self->_debug("NOREF(*top) means literal SQL: $where");
×
1126
  return ($where);
×
1127
}
1128

1129

1130
sub _where_UNDEF {
1131
  my ($self) = @_;
552✔
1132
  return ();
552✔
1133
}
1134

1135

1136
#======================================================================
1137
# WHERE: BUILTIN SPECIAL OPERATORS (-in, -between)
1138
#======================================================================
1139

1140

1141
sub _where_field_BETWEEN {
1142
  my ($self, $k, $op, $vals) = @_;
540✔
1143

1144
  my ($label, $and, $placeholder);
540✔
1145
  $label       = $self->_convert($self->_quote($k));
540✔
1146
  $and         = ' ' . $self->_sqlcase('and') . ' ';
540✔
1147
  $placeholder = $self->_convert('?');
540✔
1148
  $op               = $self->_sqlcase($op);
540✔
1149

1150
  my $invalid_args = "Operator '$op' requires either an arrayref with two defined values or expressions, or a single literal scalarref/arrayref-ref";
540✔
1151

1152
  my ($clause, @bind) = $self->_SWITCH_refkind($vals, {
1153
    ARRAYREFREF => sub {
1154
      my ($s, @b) = @$$vals;
60✔
1155
      $self->_assert_bindval_matches_bindtype(@b);
60✔
1156
      ($s, @b);
60✔
1157
    },
1158
    SCALARREF => sub {
1159
      return $$vals;
36✔
1160
    },
1161
    ARRAYREF => sub {
1162
      puke $invalid_args if @$vals != 2;
420✔
1163

1164
      my (@all_sql, @all_bind);
336✔
1165
      foreach my $val (@$vals) {
336✔
1166
        my ($sql, @bind) = $self->_SWITCH_refkind($val, {
1167
           SCALAR => sub {
1168
             return ($placeholder, $self->_bindtype($k, $val) );
468✔
1169
           },
1170
           SCALARREF => sub {
1171
             return $$val;
72✔
1172
           },
1173
           ARRAYREFREF => sub {
1174
             my ($sql, @bind) = @$$val;
48✔
1175
             $self->_assert_bindval_matches_bindtype(@bind);
48✔
1176
             return ($sql, @bind);
48✔
1177
           },
1178
           HASHREF => sub {
1179
             my ($func, $arg, @rest) = %$val;
24✔
1180
             puke "Only simple { -func => arg } functions accepted as sub-arguments to BETWEEN"
24✔
1181
               if (@rest or $func !~ /^ \- (.+)/x);
1182
             $self->_where_unary_op($1 => $arg);
24✔
1183
           },
1184
           FALLBACK => sub {
1185
             puke $invalid_args,
36✔
1186
           },
1187
        });
648✔
1188
        push @all_sql, $sql;
612✔
1189
        push @all_bind, @bind;
612✔
1190
      }
1191

1192
      return (
1193
        (join $and, @all_sql),
300✔
1194
        @all_bind
1195
      );
1196
    },
1197
    FALLBACK => sub {
1198
      puke $invalid_args,
24✔
1199
    },
1200
  });
540✔
1201

1202
  my $sql = "( $label $op $clause )";
396✔
1203
  return ($sql, @bind)
396✔
1204
}
1205

1206

1207
sub _where_field_IN {
1208
  my ($self, $k, $op, $vals) = @_;
444✔
1209

1210
  # backwards compatibility: if scalar, force into an arrayref
1211
  $vals = [$vals] if defined $vals && ! ref $vals;
444✔
1212

1213
  my ($label)       = $self->_convert($self->_quote($k));
444✔
1214
  my ($placeholder) = $self->_convert('?');
444✔
1215
  $op               = $self->_sqlcase($op);
444✔
1216

1217
  my ($sql, @bind) = $self->_SWITCH_refkind($vals, {
1218
    ARRAYREF => sub {     # list of choices
1219
      if (@$vals) { # nonempty list
300✔
1220
        my (@all_sql, @all_bind);
264✔
1221

1222
        for my $val (@$vals) {
264✔
1223
          my ($sql, @bind) = $self->_SWITCH_refkind($val, {
1224
            SCALAR => sub {
1225
              return ($placeholder, $val);
684✔
1226
            },
1227
            SCALARREF => sub {
1228
              return $$val;
12✔
1229
            },
1230
            ARRAYREFREF => sub {
1231
              my ($sql, @bind) = @$$val;
12✔
1232
              $self->_assert_bindval_matches_bindtype(@bind);
12✔
1233
              return ($sql, @bind);
12✔
1234
            },
1235
            HASHREF => sub {
1236
              my ($func, $arg, @rest) = %$val;
12✔
1237
              puke "Only simple { -func => arg } functions accepted as sub-arguments to IN"
12✔
1238
                if (@rest or $func !~ /^ \- (.+)/x);
1239
              $self->_where_unary_op($1 => $arg);
12✔
1240
            },
1241
            UNDEF => sub {
1242
              puke(
48✔
1243
                'SQL::Abstract before v1.75 used to generate incorrect SQL when the '
1244
              . "-$op operator was given an undef-containing list: !!!AUDIT YOUR CODE "
1245
              . 'AND DATA!!! (the upcoming Data::Query-based version of SQL::Abstract '
1246
              . 'will emit the logically correct SQL instead of raising this exception)'
1247
              );
1248
            },
1249
          });
768✔
1250
          push @all_sql, $sql;
720✔
1251
          push @all_bind, @bind;
720✔
1252
        }
1253

1254
        return (
1255
          sprintf('%s %s ( %s )',
216✔
1256
            $label,
1257
            $op,
1258
            join(', ', @all_sql)
1259
          ),
1260
          $self->_bindtype($k, @all_bind),
1261
        );
1262
      }
1263
      else { # empty list: some databases won't understand "IN ()", so DWIM
1264
        my $sql = ($op =~ /\bnot\b/i) ? $self->{sqltrue} : $self->{sqlfalse};
36✔
1265
        return ($sql);
36✔
1266
      }
1267
    },
1268

1269
    SCALARREF => sub {  # literal SQL
1270
      my $sql = $self->_open_outer_paren($$vals);
48✔
1271
      return ("$label $op ( $sql )");
48✔
1272
    },
1273
    ARRAYREFREF => sub {  # literal SQL with bind
1274
      my ($sql, @bind) = @$$vals;
84✔
1275
      $self->_assert_bindval_matches_bindtype(@bind);
84✔
1276
      $sql = $self->_open_outer_paren($sql);
60✔
1277
      return ("$label $op ( $sql )", @bind);
60✔
1278
    },
1279

1280
    UNDEF => sub {
1281
      puke "Argument passed to the '$op' operator can not be undefined";
12✔
1282
    },
1283

1284
    FALLBACK => sub {
1285
      puke "special op $op requires an arrayref (or scalarref/arrayref-ref)";
×
1286
    },
1287
  });
444✔
1288

1289
  return ($sql, @bind);
360✔
1290
}
1291

1292
# Some databases (SQLite) treat col IN (1, 2) different from
1293
# col IN ( (1, 2) ). Use this to strip all outer parens while
1294
# adding them back in the corresponding method
1295
sub _open_outer_paren {
1296
  my ($self, $sql) = @_;
108✔
1297

1298
  while (my ($inner) = $sql =~ /^ \s* \( (.*) \) \s* $/xs) {
108✔
1299

1300
    # there are closing parens inside, need the heavy duty machinery
1301
    # to reevaluate the extraction starting from $sql (full reevaluation)
1302
    if ($inner =~ /\)/) {
84✔
1303
      require Text::Balanced;
72✔
1304

1305
      my (undef, $remainder) = do {
72✔
1306
        # idiotic design - writes to $@ but *DOES NOT* throw exceptions
1307
        local $@;
72✔
1308
        Text::Balanced::extract_bracketed($sql, '()', qr/\s*/);
72✔
1309
      };
1310

1311
      # the entire expression needs to be a balanced bracketed thing
1312
      # (after an extract no remainder sans trailing space)
1313
      last if defined $remainder and $remainder =~ /\S/;
72✔
1314
    }
1315

1316
    $sql = $inner;
72✔
1317
  }
1318

1319
  $sql;
108✔
1320
}
1321

1322

1323
#======================================================================
1324
# ORDER BY
1325
#======================================================================
1326

1327
sub _order_by {
1328
  my ($self, $arg) = @_;
624✔
1329

1330
  my (@sql, @bind);
624✔
1331
  for my $c ($self->_order_by_chunks($arg) ) {
624✔
1332
    $self->_SWITCH_refkind($c, {
1333
      SCALAR => sub { push @sql, $c },
456✔
1334
      ARRAYREF => sub { push @sql, shift @$c; push @bind, @$c },
624✔
1335
    });
1,080✔
1336
  }
1337

1338
  my $sql = @sql
600✔
1339
    ? sprintf('%s %s',
1340
        $self->_sqlcase(' order by'),
1341
        join(', ', @sql)
1342
      )
1343
    : ''
1344
  ;
1345

1346
  return wantarray ? ($sql, @bind) : $sql;
600✔
1347
}
1348

1349
sub _order_by_chunks {
1350
  my ($self, $arg) = @_;
2,124✔
1351

1352
  return $self->_SWITCH_refkind($arg, {
1353

1354
    ARRAYREF => sub {
1355
      map { $self->_order_by_chunks($_ ) } @$arg;
564✔
1356
    },
1357

1358
    ARRAYREFREF => sub {
1359
      my ($s, @b) = @$$arg;
120✔
1360
      $self->_assert_bindval_matches_bindtype(@b);
120✔
1361
      [ $s, @b ];
120✔
1362
    },
1363

1364
    SCALAR    => sub {$self->_quote($arg)},
912✔
1365

1366
    UNDEF     => sub {return () },
×
1367

1368
    SCALARREF => sub {$$arg}, # literal SQL, no quoting
48✔
1369

1370
    HASHREF   => sub {
1371
      # get first pair in hash
1372
      my ($key, $val, @rest) = %$arg;
480✔
1373

1374
      return () unless $key;
480✔
1375

1376
      if (@rest or not $key =~ /^-(desc|asc)/i) {
480✔
1377
        puke "hash passed to _order_by must have exactly one key (-desc or -asc)";
24✔
1378
      }
1379

1380
      my $direction = $1;
456✔
1381

1382
      my @ret;
456✔
1383
      for my $c ($self->_order_by_chunks($val)) {
456✔
1384
        my ($sql, @bind);
600✔
1385

1386
        $self->_SWITCH_refkind($c, {
1387
          SCALAR => sub {
1388
            $sql = $c;
504✔
1389
          },
1390
          ARRAYREF => sub {
1391
            ($sql, @bind) = @$c;
96✔
1392
          },
1393
        });
600✔
1394

1395
        $sql = $sql . ' ' . $self->_sqlcase($direction);
600✔
1396

1397
        push @ret, [ $sql, @bind];
600✔
1398
      }
1399

1400
      return @ret;
456✔
1401
    },
1402
  });
2,124✔
1403
}
1404

1405

1406
#======================================================================
1407
# DATASOURCE (FOR NOW, JUST PLAIN TABLE OR LIST OF TABLES)
1408
#======================================================================
1409

1410
sub _table  {
1411
  my $self = shift;
2,388✔
1412
  my $from = shift;
2,388✔
1413
  $self->_SWITCH_refkind($from, {
70✔
1414
    ARRAYREF     => sub {join ', ', map { $self->_quote($_) } @$from;},
48✔
1415
    SCALAR       => sub {$self->_quote($from)},
2,340✔
1416
    SCALARREF    => sub {$$from},
×
1417
  });
2,388✔
1418
}
1419

1420

1421
#======================================================================
1422
# UTILITY FUNCTIONS
1423
#======================================================================
1424

1425
# highly optimized, as it's called way too often
1426
sub _quote {
1427
  # my ($self, $label) = @_;
1428

1429
  return '' unless defined $_[1];
17,544✔
1430
  return ${$_[1]} if ref($_[1]) eq 'SCALAR';
17,496✔
1431

1432
  $_[0]->{quote_char} or
10,192✔
1433
    ($_[0]->_assert_pass_injection_guard($_[1]), return $_[1]);
7,280✔
1434

1435
  my $qref = ref $_[0]->{quote_char};
5,808✔
1436
  my ($l, $r) =
1437
      !$qref             ? ($_[0]->{quote_char}, $_[0]->{quote_char})
1438
    : ($qref eq 'ARRAY') ? @{$_[0]->{quote_char}}
5,808✔
1439
    : puke "Unsupported quote_char format: $_[0]->{quote_char}";
1440

1441
  my $esc = $_[0]->{escape_char} || $r;
5,808✔
1442

1443
  # parts containing * are naturally unquoted
1444
  return join($_[0]->{name_sep}||'', map
1445
    +( $_ eq '*' ? $_ : do { (my $n = $_) =~ s/(\Q$esc\E|\Q$r\E)/$esc$1/g; $l . $n . $r } ),
5,823✔
1446
    ( $_[0]->{name_sep} ? split (/\Q$_[0]->{name_sep}\E/, $_[1] ) : $_[1] )
2,420✔
1447
  );
1448
}
1449

1450

1451
# Conversion, if applicable
1452
sub _convert {
1453
  #my ($self, $arg) = @_;
1454
  if ($_[0]->{convert}) {
18,636✔
1455
    return $_[0]->_sqlcase($_[0]->{convert}) .'(' . $_[1] . ')';
456✔
1456
  }
1457
  return $_[1];
18,180✔
1458
}
1459

1460
# And bindtype
1461
sub _bindtype {
1462
  #my ($self, $col, @vals) = @_;
1463
  # called often - tighten code
1464
  return $_[0]->{bindtype} eq 'columns'
700✔
1465
    ? map {[$_[1], $_]} @_[2 .. $#_]
12,516✔
1466
    : @_[2 .. $#_]
1467
  ;
1468
}
1469

1470
# Dies if any element of @bind is not in [colname => value] format
1471
# if bindtype is 'columns'.
1472
sub _assert_bindval_matches_bindtype {
1473
#  my ($self, @bind) = @_;
1474
  my $self = shift;
1,140✔
1475
  if ($self->{bindtype} eq 'columns') {
1,140✔
1476
    for (@_) {
360✔
1477
      if (!defined $_ || ref($_) ne 'ARRAY' || @$_ != 2) {
372✔
1478
        puke "bindtype 'columns' selected, you need to pass: [column_name => bind_value]"
120✔
1479
      }
1480
    }
1481
  }
1482
}
1483

1484
sub _join_sql_clauses {
1485
  my ($self, $logic, $clauses_aref, $bind_aref) = @_;
17,064✔
1486

1487
  if (@$clauses_aref > 1) {
17,064✔
1488
    my $join  = " " . $self->_sqlcase($logic) . " ";
4,296✔
1489
    my $sql = '( ' . join($join, @$clauses_aref) . ' )';
4,296✔
1490
    return ($sql, @$bind_aref);
4,296✔
1491
  }
1492
  elsif (@$clauses_aref) {
1493
    return ($clauses_aref->[0], @$bind_aref); # no parentheses
12,768✔
1494
  }
1495
  else {
1496
    return (); # if no SQL, ignore @$bind_aref
×
1497
  }
1498
}
1499

1500

1501
# Fix SQL case, if so requested
1502
sub _sqlcase {
1503
  # LDNOTE: if $self->{case} is true, then it contains 'lower', so we
1504
  # don't touch the argument ... crooked logic, but let's not change it!
1505
  return $_[0]->{case} ? $_[1] : uc($_[1]);
27,816✔
1506
}
1507

1508

1509
#======================================================================
1510
# DISPATCHING FROM REFKIND
1511
#======================================================================
1512

1513
sub _refkind {
1514
  my ($self, $data) = @_;
64,704✔
1515

1516
  return 'UNDEF' unless defined $data;
64,704✔
1517

1518
  # blessed objects are treated like scalars
1519
  my $ref = (Scalar::Util::blessed $data) ? '' : ref $data;
61,680✔
1520

1521
  return 'SCALAR' unless $ref;
61,680✔
1522

1523
  my $n_steps = 1;
37,992✔
1524
  while ($ref eq 'REF') {
37,992✔
1525
    $data = $$data;
1,296✔
1526
    $ref = (Scalar::Util::blessed $data) ? '' : ref $data;
1,296✔
1527
    $n_steps++ if $ref;
1,296✔
1528
  }
1529

1530
  return ($ref||'SCALAR') . ('REF' x $n_steps);
37,992✔
1531
}
1532

1533
sub _try_refkind {
1534
  my ($self, $data) = @_;
64,548✔
1535
  my @try = ($self->_refkind($data));
64,548✔
1536
  push @try, 'SCALAR_or_UNDEF' if $try[0] eq 'SCALAR' || $try[0] eq 'UNDEF';
64,548✔
1537
  push @try, 'FALLBACK';
64,548✔
1538
  return \@try;
64,548✔
1539
}
1540

1541
sub _METHOD_FOR_refkind {
1542
  my ($self, $meth_prefix, $data) = @_;
31,956✔
1543

1544
  my $method;
31,956✔
1545
  for (@{$self->_try_refkind($data)}) {
31,956✔
1546
    $method = $self->can($meth_prefix."_".$_)
31,956✔
1547
      and last;
1548
  }
1549

1550
  return $method || puke "cannot dispatch on '$meth_prefix' for ".$self->_refkind($data);
31,956✔
1551
}
1552

1553

1554
sub _SWITCH_refkind {
1555
  my ($self, $data, $dispatch_table) = @_;
32,592✔
1556

1557
  my $coderef;
32,592✔
1558
  for (@{$self->_try_refkind($data)}) {
32,592✔
1559
    $coderef = $dispatch_table->{$_}
42,312✔
1560
      and last;
1561
  }
1562

1563
  puke "no dispatch entry for ".$self->_refkind($data)
32,592✔
1564
    unless $coderef;
1565

1566
  $coderef->();
32,592✔
1567
}
1568

1569

1570

1571

1572
#======================================================================
1573
# VALUES, GENERATE, AUTOLOAD
1574
#======================================================================
1575

1576
# LDNOTE: original code from nwiger, didn't touch code in that section
1577
# I feel the AUTOLOAD stuff should not be the default, it should
1578
# only be activated on explicit demand by user.
1579

1580
sub values {
1581
    my $self = shift;
72✔
1582
    my $data = shift || return;
72✔
1583
    puke "Argument to ", __PACKAGE__, "->values must be a \\%hash"
72✔
1584
        unless ref $data eq 'HASH';
1585

1586
    my @all_bind;
72✔
1587
    foreach my $k (sort keys %$data) {
72✔
1588
        my $v = $data->{$k};
444✔
1589
        $self->_SWITCH_refkind($v, {
1590
          ARRAYREF => sub {
1591
            if ($self->{array_datatypes}) { # array datatype
12✔
1592
              push @all_bind, $self->_bindtype($k, $v);
×
1593
            }
1594
            else {                          # literal SQL with bind
1595
              my ($sql, @bind) = @$v;
12✔
1596
              $self->_assert_bindval_matches_bindtype(@bind);
12✔
1597
              push @all_bind, @bind;
12✔
1598
            }
1599
          },
1600
          ARRAYREFREF => sub { # literal SQL with bind
1601
            my ($sql, @bind) = @${$v};
12✔
1602
            $self->_assert_bindval_matches_bindtype(@bind);
12✔
1603
            push @all_bind, @bind;
12✔
1604
          },
1605
          SCALARREF => sub {  # literal SQL without bind
1606
          },
1607
          SCALAR_or_UNDEF => sub {
1608
            push @all_bind, $self->_bindtype($k, $v);
396✔
1609
          },
1610
        });
444✔
1611
    }
1612

1613
    return @all_bind;
72✔
1614
}
1615

1616
sub generate {
1617
    my $self  = shift;
×
1618

1619
    my(@sql, @sqlq, @sqlv);
×
1620

1621
    for (@_) {
×
1622
        my $ref = ref $_;
×
1623
        if ($ref eq 'HASH') {
×
1624
            for my $k (sort keys %$_) {
×
1625
                my $v = $_->{$k};
×
1626
                my $r = ref $v;
×
1627
                my $label = $self->_quote($k);
×
1628
                if ($r eq 'ARRAY') {
×
1629
                    # literal SQL with bind
1630
                    my ($sql, @bind) = @$v;
×
1631
                    $self->_assert_bindval_matches_bindtype(@bind);
×
1632
                    push @sqlq, "$label = $sql";
×
1633
                    push @sqlv, @bind;
×
1634
                } elsif ($r eq 'SCALAR') {
1635
                    # literal SQL without bind
1636
                    push @sqlq, "$label = $$v";
×
1637
                } else {
1638
                    push @sqlq, "$label = ?";
×
1639
                    push @sqlv, $self->_bindtype($k, $v);
×
1640
                }
1641
            }
1642
            push @sql, $self->_sqlcase('set'), join ', ', @sqlq;
×
1643
        } elsif ($ref eq 'ARRAY') {
1644
            # unlike insert(), assume these are ONLY the column names, i.e. for SQL
1645
            for my $v (@$_) {
×
1646
                my $r = ref $v;
×
1647
                if ($r eq 'ARRAY') {   # literal SQL with bind
×
1648
                    my ($sql, @bind) = @$v;
×
1649
                    $self->_assert_bindval_matches_bindtype(@bind);
×
1650
                    push @sqlq, $sql;
×
1651
                    push @sqlv, @bind;
×
1652
                } elsif ($r eq 'SCALAR') {  # literal SQL without bind
1653
                    # embedded literal SQL
1654
                    push @sqlq, $$v;
×
1655
                } else {
1656
                    push @sqlq, '?';
×
1657
                    push @sqlv, $v;
×
1658
                }
1659
            }
1660
            push @sql, '(' . join(', ', @sqlq) . ')';
×
1661
        } elsif ($ref eq 'SCALAR') {
1662
            # literal SQL
1663
            push @sql, $$_;
×
1664
        } else {
1665
            # strings get case twiddled
1666
            push @sql, $self->_sqlcase($_);
×
1667
        }
1668
    }
1669

1670
    my $sql = join ' ', @sql;
×
1671

1672
    # this is pretty tricky
1673
    # if ask for an array, return ($stmt, @bind)
1674
    # otherwise, s/?/shift @sqlv/ to put it inline
1675
    if (wantarray) {
×
1676
        return ($sql, @sqlv);
×
1677
    } else {
1678
        1 while $sql =~ s/\?/my $d = shift(@sqlv);
×
1679
                             ref $d ? $d->[1] : $d/e;
×
1680
        return $sql;
×
1681
    }
1682
}
1683

1684

1685
sub DESTROY { 1 }
7,332✔
1686

1687
sub AUTOLOAD {
1688
    # This allows us to check for a local, then _form, attr
1689
    my $self = shift;
×
1690
    my($name) = $AUTOLOAD =~ /.*::(.+)/;
×
1691
    return $self->generate($name, @_);
×
1692
}
1693

1694
1;
1695

1696

1697

1698
__END__
1699

1700
=head1 NAME
1701

1702
SQL::Abstract - Generate SQL from Perl data structures
1703

1704
=head1 SYNOPSIS
1705

1706
    use SQL::Abstract;
1707

1708
    my $sql = SQL::Abstract->new;
1709

1710
    my($stmt, @bind) = $sql->select($source, \@fields, \%where, $order);
1711

1712
    my($stmt, @bind) = $sql->insert($table, \%fieldvals || \@values);
1713

1714
    my($stmt, @bind) = $sql->update($table, \%fieldvals, \%where);
1715

1716
    my($stmt, @bind) = $sql->delete($table, \%where);
1717

1718
    # Then, use these in your DBI statements
1719
    my $sth = $dbh->prepare($stmt);
1720
    $sth->execute(@bind);
1721

1722
    # Just generate the WHERE clause
1723
    my($stmt, @bind) = $sql->where(\%where, $order);
1724

1725
    # Return values in the same order, for hashed queries
1726
    # See PERFORMANCE section for more details
1727
    my @bind = $sql->values(\%fieldvals);
1728

1729
=head1 DESCRIPTION
1730

1731
This module was inspired by the excellent L<DBIx::Abstract>.
1732
However, in using that module I found that what I really wanted
1733
to do was generate SQL, but still retain complete control over my
1734
statement handles and use the DBI interface. So, I set out to
1735
create an abstract SQL generation module.
1736

1737
While based on the concepts used by L<DBIx::Abstract>, there are
1738
several important differences, especially when it comes to WHERE
1739
clauses. I have modified the concepts used to make the SQL easier
1740
to generate from Perl data structures and, IMO, more intuitive.
1741
The underlying idea is for this module to do what you mean, based
1742
on the data structures you provide it. The big advantage is that
1743
you don't have to modify your code every time your data changes,
1744
as this module figures it out.
1745

1746
To begin with, an SQL INSERT is as easy as just specifying a hash
1747
of C<key=value> pairs:
1748

1749
    my %data = (
1750
        name => 'Jimbo Bobson',
1751
        phone => '123-456-7890',
1752
        address => '42 Sister Lane',
1753
        city => 'St. Louis',
1754
        state => 'Louisiana',
1755
    );
1756

1757
The SQL can then be generated with this:
1758

1759
    my($stmt, @bind) = $sql->insert('people', \%data);
1760

1761
Which would give you something like this:
1762

1763
    $stmt = "INSERT INTO people
1764
                    (address, city, name, phone, state)
1765
                    VALUES (?, ?, ?, ?, ?)";
1766
    @bind = ('42 Sister Lane', 'St. Louis', 'Jimbo Bobson',
1767
             '123-456-7890', 'Louisiana');
1768

1769
These are then used directly in your DBI code:
1770

1771
    my $sth = $dbh->prepare($stmt);
1772
    $sth->execute(@bind);
1773

1774
=head2 Inserting and Updating Arrays
1775

1776
If your database has array types (like for example Postgres),
1777
activate the special option C<< array_datatypes => 1 >>
1778
when creating the C<SQL::Abstract> object.
1779
Then you may use an arrayref to insert and update database array types:
1780

1781
    my $sql = SQL::Abstract->new(array_datatypes => 1);
1782
    my %data = (
1783
        planets => [qw/Mercury Venus Earth Mars/]
1784
    );
1785

1786
    my($stmt, @bind) = $sql->insert('solar_system', \%data);
1787

1788
This results in:
1789

1790
    $stmt = "INSERT INTO solar_system (planets) VALUES (?)"
1791

1792
    @bind = (['Mercury', 'Venus', 'Earth', 'Mars']);
1793

1794

1795
=head2 Inserting and Updating SQL
1796

1797
In order to apply SQL functions to elements of your C<%data> you may
1798
specify a reference to an arrayref for the given hash value. For example,
1799
if you need to execute the Oracle C<to_date> function on a value, you can
1800
say something like this:
1801

1802
    my %data = (
1803
        name => 'Bill',
1804
        date_entered => \[ "to_date(?,'MM/DD/YYYY')", "03/02/2003" ],
1805
    );
1806

1807
The first value in the array is the actual SQL. Any other values are
1808
optional and would be included in the bind values array. This gives
1809
you:
1810

1811
    my($stmt, @bind) = $sql->insert('people', \%data);
1812

1813
    $stmt = "INSERT INTO people (name, date_entered)
1814
                VALUES (?, to_date(?,'MM/DD/YYYY'))";
1815
    @bind = ('Bill', '03/02/2003');
1816

1817
An UPDATE is just as easy, all you change is the name of the function:
1818

1819
    my($stmt, @bind) = $sql->update('people', \%data);
1820

1821
Notice that your C<%data> isn't touched; the module will generate
1822
the appropriately quirky SQL for you automatically. Usually you'll
1823
want to specify a WHERE clause for your UPDATE, though, which is
1824
where handling C<%where> hashes comes in handy...
1825

1826
=head2 Complex where statements
1827

1828
This module can generate pretty complicated WHERE statements
1829
easily. For example, simple C<key=value> pairs are taken to mean
1830
equality, and if you want to see if a field is within a set
1831
of values, you can use an arrayref. Let's say we wanted to
1832
SELECT some data based on this criteria:
1833

1834
    my %where = (
1835
       requestor => 'inna',
1836
       worker => ['nwiger', 'rcwe', 'sfz'],
1837
       status => { '!=', 'completed' }
1838
    );
1839

1840
    my($stmt, @bind) = $sql->select('tickets', '*', \%where);
1841

1842
The above would give you something like this:
1843

1844
    $stmt = "SELECT * FROM tickets WHERE
1845
                ( requestor = ? ) AND ( status != ? )
1846
                AND ( worker = ? OR worker = ? OR worker = ? )";
1847
    @bind = ('inna', 'completed', 'nwiger', 'rcwe', 'sfz');
1848

1849
Which you could then use in DBI code like so:
1850

1851
    my $sth = $dbh->prepare($stmt);
1852
    $sth->execute(@bind);
1853

1854
Easy, eh?
1855

1856
=head1 METHODS
1857

1858
The methods are simple. There's one for every major SQL operation,
1859
and a constructor you use first. The arguments are specified in a
1860
similar order for each method (table, then fields, then a where
1861
clause) to try and simplify things.
1862

1863
=head2 new(option => 'value')
1864

1865
The C<new()> function takes a list of options and values, and returns
1866
a new B<SQL::Abstract> object which can then be used to generate SQL
1867
through the methods below. The options accepted are:
1868

1869
=over
1870

1871
=item case
1872

1873
If set to 'lower', then SQL will be generated in all lowercase. By
1874
default SQL is generated in "textbook" case meaning something like:
1875

1876
    SELECT a_field FROM a_table WHERE some_field LIKE '%someval%'
1877

1878
Any setting other than 'lower' is ignored.
1879

1880
=item cmp
1881

1882
This determines what the default comparison operator is. By default
1883
it is C<=>, meaning that a hash like this:
1884

1885
    %where = (name => 'nwiger', email => 'nate@wiger.org');
1886

1887
Will generate SQL like this:
1888

1889
    WHERE name = 'nwiger' AND email = 'nate@wiger.org'
1890

1891
However, you may want loose comparisons by default, so if you set
1892
C<cmp> to C<like> you would get SQL such as:
1893

1894
    WHERE name like 'nwiger' AND email like 'nate@wiger.org'
1895

1896
You can also override the comparison on an individual basis - see
1897
the huge section on L</"WHERE CLAUSES"> at the bottom.
1898

1899
=item sqltrue, sqlfalse
1900

1901
Expressions for inserting boolean values within SQL statements.
1902
By default these are C<1=1> and C<1=0>. They are used
1903
by the special operators C<-in> and C<-not_in> for generating
1904
correct SQL even when the argument is an empty array (see below).
1905

1906
=item logic
1907

1908
This determines the default logical operator for multiple WHERE
1909
statements in arrays or hashes. If absent, the default logic is "or"
1910
for arrays, and "and" for hashes. This means that a WHERE
1911
array of the form:
1912

1913
    @where = (
1914
        event_date => {'>=', '2/13/99'},
1915
        event_date => {'<=', '4/24/03'},
1916
    );
1917

1918
will generate SQL like this:
1919

1920
    WHERE event_date >= '2/13/99' OR event_date <= '4/24/03'
1921

1922
This is probably not what you want given this query, though (look
1923
at the dates). To change the "OR" to an "AND", simply specify:
1924

1925
    my $sql = SQL::Abstract->new(logic => 'and');
1926

1927
Which will change the above C<WHERE> to:
1928

1929
    WHERE event_date >= '2/13/99' AND event_date <= '4/24/03'
1930

1931
The logic can also be changed locally by inserting
1932
a modifier in front of an arrayref:
1933

1934
    @where = (-and => [event_date => {'>=', '2/13/99'},
1935
                       event_date => {'<=', '4/24/03'} ]);
1936

1937
See the L</"WHERE CLAUSES"> section for explanations.
1938

1939
=item convert
1940

1941
This will automatically convert comparisons using the specified SQL
1942
function for both column and value. This is mostly used with an argument
1943
of C<upper> or C<lower>, so that the SQL will have the effect of
1944
case-insensitive "searches". For example, this:
1945

1946
    $sql = SQL::Abstract->new(convert => 'upper');
1947
    %where = (keywords => 'MaKe iT CAse inSeNSItive');
1948

1949
Will turn out the following SQL:
1950

1951
    WHERE upper(keywords) like upper('MaKe iT CAse inSeNSItive')
1952

1953
The conversion can be C<upper()>, C<lower()>, or any other SQL function
1954
that can be applied symmetrically to fields (actually B<SQL::Abstract> does
1955
not validate this option; it will just pass through what you specify verbatim).
1956

1957
=item bindtype
1958

1959
This is a kludge because many databases suck. For example, you can't
1960
just bind values using DBI's C<execute()> for Oracle C<CLOB> or C<BLOB> fields.
1961
Instead, you have to use C<bind_param()>:
1962

1963
    $sth->bind_param(1, 'reg data');
1964
    $sth->bind_param(2, $lots, {ora_type => ORA_CLOB});
1965

1966
The problem is, B<SQL::Abstract> will normally just return a C<@bind> array,
1967
which loses track of which field each slot refers to. Fear not.
1968

1969
If you specify C<bindtype> in new, you can determine how C<@bind> is returned.
1970
Currently, you can specify either C<normal> (default) or C<columns>. If you
1971
specify C<columns>, you will get an array that looks like this:
1972

1973
    my $sql = SQL::Abstract->new(bindtype => 'columns');
1974
    my($stmt, @bind) = $sql->insert(...);
1975

1976
    @bind = (
1977
        [ 'column1', 'value1' ],
1978
        [ 'column2', 'value2' ],
1979
        [ 'column3', 'value3' ],
1980
    );
1981

1982
You can then iterate through this manually, using DBI's C<bind_param()>.
1983

1984
    $sth->prepare($stmt);
1985
    my $i = 1;
1986
    for (@bind) {
1987
        my($col, $data) = @$_;
1988
        if ($col eq 'details' || $col eq 'comments') {
1989
            $sth->bind_param($i, $data, {ora_type => ORA_CLOB});
1990
        } elsif ($col eq 'image') {
1991
            $sth->bind_param($i, $data, {ora_type => ORA_BLOB});
1992
        } else {
1993
            $sth->bind_param($i, $data);
1994
        }
1995
        $i++;
1996
    }
1997
    $sth->execute;      # execute without @bind now
1998

1999
Now, why would you still use B<SQL::Abstract> if you have to do this crap?
2000
Basically, the advantage is still that you don't have to care which fields
2001
are or are not included. You could wrap that above C<for> loop in a simple
2002
sub called C<bind_fields()> or something and reuse it repeatedly. You still
2003
get a layer of abstraction over manual SQL specification.
2004

2005
Note that if you set L</bindtype> to C<columns>, the C<\[ $sql, @bind ]>
2006
construct (see L</Literal SQL with placeholders and bind values (subqueries)>)
2007
will expect the bind values in this format.
2008

2009
=item quote_char
2010

2011
This is the character that a table or column name will be quoted
2012
with.  By default this is an empty string, but you could set it to
2013
the character C<`>, to generate SQL like this:
2014

2015
  SELECT `a_field` FROM `a_table` WHERE `some_field` LIKE '%someval%'
2016

2017
Alternatively, you can supply an array ref of two items, the first being the left
2018
hand quote character, and the second the right hand quote character. For
2019
example, you could supply C<['[',']']> for SQL Server 2000 compliant quotes
2020
that generates SQL like this:
2021

2022
  SELECT [a_field] FROM [a_table] WHERE [some_field] LIKE '%someval%'
2023

2024
Quoting is useful if you have tables or columns names that are reserved
2025
words in your database's SQL dialect.
2026

2027
=item escape_char
2028

2029
This is the character that will be used to escape L</quote_char>s appearing
2030
in an identifier before it has been quoted.
2031

2032
The parameter default in case of a single L</quote_char> character is the quote
2033
character itself.
2034

2035
When opening-closing-style quoting is used (L</quote_char> is an arrayref)
2036
this parameter defaults to the B<closing (right)> L</quote_char>. Occurrences
2037
of the B<opening (left)> L</quote_char> within the identifier are currently left
2038
untouched. The default for opening-closing-style quotes may change in future
2039
versions, thus you are B<strongly encouraged> to specify the escape character
2040
explicitly.
2041

2042
=item name_sep
2043

2044
This is the character that separates a table and column name.  It is
2045
necessary to specify this when the C<quote_char> option is selected,
2046
so that tables and column names can be individually quoted like this:
2047

2048
  SELECT `table`.`one_field` FROM `table` WHERE `table`.`other_field` = 1
2049

2050
=item injection_guard
2051

2052
A regular expression C<qr/.../> that is applied to any C<-function> and unquoted
2053
column name specified in a query structure. This is a safety mechanism to avoid
2054
injection attacks when mishandling user input e.g.:
2055

2056
  my %condition_as_column_value_pairs = get_values_from_user();
2057
  $sqla->select( ... , \%condition_as_column_value_pairs );
2058

2059
If the expression matches an exception is thrown. Note that literal SQL
2060
supplied via C<\'...'> or C<\['...']> is B<not> checked in any way.
2061

2062
Defaults to checking for C<;> and the C<GO> keyword (TransactSQL)
2063

2064
=item array_datatypes
2065

2066
When this option is true, arrayrefs in INSERT or UPDATE are
2067
interpreted as array datatypes and are passed directly
2068
to the DBI layer.
2069
When this option is false, arrayrefs are interpreted
2070
as literal SQL, just like refs to arrayrefs
2071
(but this behavior is for backwards compatibility; when writing
2072
new queries, use the "reference to arrayref" syntax
2073
for literal SQL).
2074

2075

2076
=item special_ops
2077

2078
Takes a reference to a list of "special operators"
2079
to extend the syntax understood by L<SQL::Abstract>.
2080
See section L</"SPECIAL OPERATORS"> for details.
2081

2082
=item unary_ops
2083

2084
Takes a reference to a list of "unary operators"
2085
to extend the syntax understood by L<SQL::Abstract>.
2086
See section L</"UNARY OPERATORS"> for details.
2087

2088

2089

2090
=back
2091

2092
=head2 insert($table, \@values || \%fieldvals, \%options)
2093

2094
This is the simplest function. You simply give it a table name
2095
and either an arrayref of values or hashref of field/value pairs.
2096
It returns an SQL INSERT statement and a list of bind values.
2097
See the sections on L</"Inserting and Updating Arrays"> and
2098
L</"Inserting and Updating SQL"> for information on how to insert
2099
with those data types.
2100

2101
The optional C<\%options> hash reference may contain additional
2102
options to generate the insert SQL. Currently supported options
2103
are:
2104

2105
=over 4
2106

2107
=item returning
2108

2109
Takes either a scalar of raw SQL fields, or an array reference of
2110
field names, and adds on an SQL C<RETURNING> statement at the end.
2111
This allows you to return data generated by the insert statement
2112
(such as row IDs) without performing another C<SELECT> statement.
2113
Note, however, this is not part of the SQL standard and may not
2114
be supported by all database engines.
2115

2116
=back
2117

2118
=head2 update($table, \%fieldvals, \%where, \%options)
2119

2120
This takes a table, hashref of field/value pairs, and an optional
2121
hashref L<WHERE clause|/WHERE CLAUSES>. It returns an SQL UPDATE function and a list
2122
of bind values.
2123
See the sections on L</"Inserting and Updating Arrays"> and
2124
L</"Inserting and Updating SQL"> for information on how to insert
2125
with those data types.
2126

2127
The optional C<\%options> hash reference may contain additional
2128
options to generate the update SQL. Currently supported options
2129
are:
2130

2131
=over 4
2132

2133
=item returning
2134

2135
See the C<returning> option to
2136
L<insert|/insert($table, \@values || \%fieldvals, \%options)>.
2137

2138
=back
2139

2140
=head2 select($source, $fields, $where, $order)
2141

2142
This returns a SQL SELECT statement and associated list of bind values, as
2143
specified by the arguments:
2144

2145
=over
2146

2147
=item $source
2148

2149
Specification of the 'FROM' part of the statement.
2150
The argument can be either a plain scalar (interpreted as a table
2151
name, will be quoted), or an arrayref (interpreted as a list
2152
of table names, joined by commas, quoted), or a scalarref
2153
(literal SQL, not quoted).
2154

2155
=item $fields
2156

2157
Specification of the list of fields to retrieve from
2158
the source.
2159
The argument can be either an arrayref (interpreted as a list
2160
of field names, will be joined by commas and quoted), or a
2161
plain scalar (literal SQL, not quoted).
2162
Please observe that this API is not as flexible as that of
2163
the first argument C<$source>, for backwards compatibility reasons.
2164

2165
=item $where
2166

2167
Optional argument to specify the WHERE part of the query.
2168
The argument is most often a hashref, but can also be
2169
an arrayref or plain scalar --
2170
see section L<WHERE clause|/"WHERE CLAUSES"> for details.
2171

2172
=item $order
2173

2174
Optional argument to specify the ORDER BY part of the query.
2175
The argument can be a scalar, a hashref or an arrayref
2176
-- see section L<ORDER BY clause|/"ORDER BY CLAUSES">
2177
for details.
2178

2179
=back
2180

2181

2182
=head2 delete($table, \%where, \%options)
2183

2184
This takes a table name and optional hashref L<WHERE clause|/WHERE CLAUSES>.
2185
It returns an SQL DELETE statement and list of bind values.
2186

2187
The optional C<\%options> hash reference may contain additional
2188
options to generate the delete SQL. Currently supported options
2189
are:
2190

2191
=over 4
2192

2193
=item returning
2194

2195
See the C<returning> option to
2196
L<insert|/insert($table, \@values || \%fieldvals, \%options)>.
2197

2198
=back
2199

2200
=head2 where(\%where, $order)
2201

2202
This is used to generate just the WHERE clause. For example,
2203
if you have an arbitrary data structure and know what the
2204
rest of your SQL is going to look like, but want an easy way
2205
to produce a WHERE clause, use this. It returns an SQL WHERE
2206
clause and list of bind values.
2207

2208

2209
=head2 values(\%data)
2210

2211
This just returns the values from the hash C<%data>, in the same
2212
order that would be returned from any of the other above queries.
2213
Using this allows you to markedly speed up your queries if you
2214
are affecting lots of rows. See below under the L</"PERFORMANCE"> section.
2215

2216
=head2 generate($any, 'number', $of, \@data, $struct, \%types)
2217

2218
Warning: This is an experimental method and subject to change.
2219

2220
This returns arbitrarily generated SQL. It's a really basic shortcut.
2221
It will return two different things, depending on return context:
2222

2223
    my($stmt, @bind) = $sql->generate('create table', \$table, \@fields);
2224
    my $stmt_and_val = $sql->generate('create table', \$table, \@fields);
2225

2226
These would return the following:
2227

2228
    # First calling form
2229
    $stmt = "CREATE TABLE test (?, ?)";
2230
    @bind = (field1, field2);
2231

2232
    # Second calling form
2233
    $stmt_and_val = "CREATE TABLE test (field1, field2)";
2234

2235
Depending on what you're trying to do, it's up to you to choose the correct
2236
format. In this example, the second form is what you would want.
2237

2238
By the same token:
2239

2240
    $sql->generate('alter session', { nls_date_format => 'MM/YY' });
2241

2242
Might give you:
2243

2244
    ALTER SESSION SET nls_date_format = 'MM/YY'
2245

2246
You get the idea. Strings get their case twiddled, but everything
2247
else remains verbatim.
2248

2249
=head1 EXPORTABLE FUNCTIONS
2250

2251
=head2 is_plain_value
2252

2253
Determines if the supplied argument is a plain value as understood by this
2254
module:
2255

2256
=over
2257

2258
=item * The value is C<undef>
2259

2260
=item * The value is a non-reference
2261

2262
=item * The value is an object with stringification overloading
2263

2264
=item * The value is of the form C<< { -value => $anything } >>
2265

2266
=back
2267

2268
On failure returns C<undef>, on success returns a B<scalar> reference
2269
to the original supplied argument.
2270

2271
=over
2272

2273
=item * Note
2274

2275
The stringification overloading detection is rather advanced: it takes
2276
into consideration not only the presence of a C<""> overload, but if that
2277
fails also checks for enabled
2278
L<autogenerated versions of C<"">|overload/Magic Autogeneration>, based
2279
on either C<0+> or C<bool>.
2280

2281
Unfortunately testing in the field indicates that this
2282
detection B<< may tickle a latent bug in perl versions before 5.018 >>,
2283
but only when very large numbers of stringifying objects are involved.
2284
At the time of writing ( Sep 2014 ) there is no clear explanation of
2285
the direct cause, nor is there a manageably small test case that reliably
2286
reproduces the problem.
2287

2288
If you encounter any of the following exceptions in B<random places within
2289
your application stack> - this module may be to blame:
2290

2291
  Operation "ne": no method found,
2292
    left argument in overloaded package <something>,
2293
    right argument in overloaded package <something>
2294

2295
or perhaps even
2296

2297
  Stub found while resolving method "???" overloading """" in package <something>
2298

2299
If you fall victim to the above - please attempt to reduce the problem
2300
to something that could be sent to the L<SQL::Abstract developers
2301
|DBIx::Class/GETTING HELP/SUPPORT>
2302
(either publicly or privately). As a workaround in the meantime you can
2303
set C<$ENV{SQLA_ISVALUE_IGNORE_AUTOGENERATED_STRINGIFICATION}> to a true
2304
value, which will most likely eliminate your problem (at the expense of
2305
not being able to properly detect exotic forms of stringification).
2306

2307
This notice and environment variable will be removed in a future version,
2308
as soon as the underlying problem is found and a reliable workaround is
2309
devised.
2310

2311
=back
2312

2313
=head2 is_literal_value
2314

2315
Determines if the supplied argument is a literal value as understood by this
2316
module:
2317

2318
=over
2319

2320
=item * C<\$sql_string>
2321

2322
=item * C<\[ $sql_string, @bind_values ]>
2323

2324
=back
2325

2326
On failure returns C<undef>, on success returns an B<array> reference
2327
containing the unpacked version of the supplied literal SQL and bind values.
2328

2329
=head1 WHERE CLAUSES
2330

2331
=head2 Introduction
2332

2333
This module uses a variation on the idea from L<DBIx::Abstract>. It
2334
is B<NOT>, repeat I<not> 100% compatible. B<The main logic of this
2335
module is that things in arrays are OR'ed, and things in hashes
2336
are AND'ed.>
2337

2338
The easiest way to explain is to show lots of examples. After
2339
each C<%where> hash shown, it is assumed you used:
2340

2341
    my($stmt, @bind) = $sql->where(\%where);
2342

2343
However, note that the C<%where> hash can be used directly in any
2344
of the other functions as well, as described above.
2345

2346
=head2 Key-value pairs
2347

2348
So, let's get started. To begin, a simple hash:
2349

2350
    my %where  = (
2351
        user   => 'nwiger',
2352
        status => 'completed'
2353
    );
2354

2355
Is converted to SQL C<key = val> statements:
2356

2357
    $stmt = "WHERE user = ? AND status = ?";
2358
    @bind = ('nwiger', 'completed');
2359

2360
One common thing I end up doing is having a list of values that
2361
a field can be in. To do this, simply specify a list inside of
2362
an arrayref:
2363

2364
    my %where  = (
2365
        user   => 'nwiger',
2366
        status => ['assigned', 'in-progress', 'pending'];
2367
    );
2368

2369
This simple code will create the following:
2370

2371
    $stmt = "WHERE user = ? AND ( status = ? OR status = ? OR status = ? )";
2372
    @bind = ('nwiger', 'assigned', 'in-progress', 'pending');
2373

2374
A field associated to an empty arrayref will be considered a
2375
logical false and will generate 0=1.
2376

2377
=head2 Tests for NULL values
2378

2379
If the value part is C<undef> then this is converted to SQL <IS NULL>
2380

2381
    my %where  = (
2382
        user   => 'nwiger',
2383
        status => undef,
2384
    );
2385

2386
becomes:
2387

2388
    $stmt = "WHERE user = ? AND status IS NULL";
2389
    @bind = ('nwiger');
2390

2391
To test if a column IS NOT NULL:
2392

2393
    my %where  = (
2394
        user   => 'nwiger',
2395
        status => { '!=', undef },
2396
    );
2397

2398
=head2 Specific comparison operators
2399

2400
If you want to specify a different type of operator for your comparison,
2401
you can use a hashref for a given column:
2402

2403
    my %where  = (
2404
        user   => 'nwiger',
2405
        status => { '!=', 'completed' }
2406
    );
2407

2408
Which would generate:
2409

2410
    $stmt = "WHERE user = ? AND status != ?";
2411
    @bind = ('nwiger', 'completed');
2412

2413
To test against multiple values, just enclose the values in an arrayref:
2414

2415
    status => { '=', ['assigned', 'in-progress', 'pending'] };
2416

2417
Which would give you:
2418

2419
    "WHERE status = ? OR status = ? OR status = ?"
2420

2421

2422
The hashref can also contain multiple pairs, in which case it is expanded
2423
into an C<AND> of its elements:
2424

2425
    my %where  = (
2426
        user   => 'nwiger',
2427
        status => { '!=', 'completed', -not_like => 'pending%' }
2428
    );
2429

2430
    # Or more dynamically, like from a form
2431
    $where{user} = 'nwiger';
2432
    $where{status}{'!='} = 'completed';
2433
    $where{status}{'-not_like'} = 'pending%';
2434

2435
    # Both generate this
2436
    $stmt = "WHERE user = ? AND status != ? AND status NOT LIKE ?";
2437
    @bind = ('nwiger', 'completed', 'pending%');
2438

2439

2440
To get an OR instead, you can combine it with the arrayref idea:
2441

2442
    my %where => (
2443
         user => 'nwiger',
2444
         priority => [ { '=', 2 }, { '>', 5 } ]
2445
    );
2446

2447
Which would generate:
2448

2449
    $stmt = "WHERE ( priority = ? OR priority > ? ) AND user = ?";
2450
    @bind = ('2', '5', 'nwiger');
2451

2452
If you want to include literal SQL (with or without bind values), just use a
2453
scalar reference or reference to an arrayref as the value:
2454

2455
    my %where  = (
2456
        date_entered => { '>' => \["to_date(?, 'MM/DD/YYYY')", "11/26/2008"] },
2457
        date_expires => { '<' => \"now()" }
2458
    );
2459

2460
Which would generate:
2461

2462
    $stmt = "WHERE date_entered > to_date(?, 'MM/DD/YYYY') AND date_expires < now()";
2463
    @bind = ('11/26/2008');
2464

2465

2466
=head2 Logic and nesting operators
2467

2468
In the example above,
2469
there is a subtle trap if you want to say something like
2470
this (notice the C<AND>):
2471

2472
    WHERE priority != ? AND priority != ?
2473

2474
Because, in Perl you I<can't> do this:
2475

2476
    priority => { '!=' => 2, '!=' => 1 }
2477

2478
As the second C<!=> key will obliterate the first. The solution
2479
is to use the special C<-modifier> form inside an arrayref:
2480

2481
    priority => [ -and => {'!=', 2},
2482
                          {'!=', 1} ]
2483

2484

2485
Normally, these would be joined by C<OR>, but the modifier tells it
2486
to use C<AND> instead. (Hint: You can use this in conjunction with the
2487
C<logic> option to C<new()> in order to change the way your queries
2488
work by default.) B<Important:> Note that the C<-modifier> goes
2489
B<INSIDE> the arrayref, as an extra first element. This will
2490
B<NOT> do what you think it might:
2491

2492
    priority => -and => [{'!=', 2}, {'!=', 1}]   # WRONG!
2493

2494
Here is a quick list of equivalencies, since there is some overlap:
2495

2496
    # Same
2497
    status => {'!=', 'completed', 'not like', 'pending%' }
2498
    status => [ -and => {'!=', 'completed'}, {'not like', 'pending%'}]
2499

2500
    # Same
2501
    status => {'=', ['assigned', 'in-progress']}
2502
    status => [ -or => {'=', 'assigned'}, {'=', 'in-progress'}]
2503
    status => [ {'=', 'assigned'}, {'=', 'in-progress'} ]
2504

2505

2506

2507
=head2 Special operators: IN, BETWEEN, etc.
2508

2509
You can also use the hashref format to compare a list of fields using the
2510
C<IN> comparison operator, by specifying the list as an arrayref:
2511

2512
    my %where  = (
2513
        status   => 'completed',
2514
        reportid => { -in => [567, 2335, 2] }
2515
    );
2516

2517
Which would generate:
2518

2519
    $stmt = "WHERE status = ? AND reportid IN (?,?,?)";
2520
    @bind = ('completed', '567', '2335', '2');
2521

2522
The reverse operator C<-not_in> generates SQL C<NOT IN> and is used in
2523
the same way.
2524

2525
If the argument to C<-in> is an empty array, 'sqlfalse' is generated
2526
(by default: C<1=0>). Similarly, C<< -not_in => [] >> generates
2527
'sqltrue' (by default: C<1=1>).
2528

2529
In addition to the array you can supply a chunk of literal sql or
2530
literal sql with bind:
2531

2532
    my %where = {
2533
      customer => { -in => \[
2534
        'SELECT cust_id FROM cust WHERE balance > ?',
2535
        2000,
2536
      ],
2537
      status => { -in => \'SELECT status_codes FROM states' },
2538
    };
2539

2540
would generate:
2541

2542
    $stmt = "WHERE (
2543
          customer IN ( SELECT cust_id FROM cust WHERE balance > ? )
2544
      AND status IN ( SELECT status_codes FROM states )
2545
    )";
2546
    @bind = ('2000');
2547

2548
Finally, if the argument to C<-in> is not a reference, it will be
2549
treated as a single-element array.
2550

2551
Another pair of operators is C<-between> and C<-not_between>,
2552
used with an arrayref of two values:
2553

2554
    my %where  = (
2555
        user   => 'nwiger',
2556
        completion_date => {
2557
           -not_between => ['2002-10-01', '2003-02-06']
2558
        }
2559
    );
2560

2561
Would give you:
2562

2563
    WHERE user = ? AND completion_date NOT BETWEEN ( ? AND ? )
2564

2565
Just like with C<-in> all plausible combinations of literal SQL
2566
are possible:
2567

2568
    my %where = {
2569
      start0 => { -between => [ 1, 2 ] },
2570
      start1 => { -between => \["? AND ?", 1, 2] },
2571
      start2 => { -between => \"lower(x) AND upper(y)" },
2572
      start3 => { -between => [
2573
        \"lower(x)",
2574
        \["upper(?)", 'stuff' ],
2575
      ] },
2576
    };
2577

2578
Would give you:
2579

2580
    $stmt = "WHERE (
2581
          ( start0 BETWEEN ? AND ?                )
2582
      AND ( start1 BETWEEN ? AND ?                )
2583
      AND ( start2 BETWEEN lower(x) AND upper(y)  )
2584
      AND ( start3 BETWEEN lower(x) AND upper(?)  )
2585
    )";
2586
    @bind = (1, 2, 1, 2, 'stuff');
2587

2588

2589
These are the two builtin "special operators"; but the
2590
list can be expanded: see section L</"SPECIAL OPERATORS"> below.
2591

2592
=head2 Unary operators: bool
2593

2594
If you wish to test against boolean columns or functions within your
2595
database you can use the C<-bool> and C<-not_bool> operators. For
2596
example to test the column C<is_user> being true and the column
2597
C<is_enabled> being false you would use:-
2598

2599
    my %where  = (
2600
        -bool       => 'is_user',
2601
        -not_bool   => 'is_enabled',
2602
    );
2603

2604
Would give you:
2605

2606
    WHERE is_user AND NOT is_enabled
2607

2608
If a more complex combination is required, testing more conditions,
2609
then you should use the and/or operators:-
2610

2611
    my %where  = (
2612
        -and           => [
2613
            -bool      => 'one',
2614
            -not_bool  => { two=> { -rlike => 'bar' } },
2615
            -not_bool  => { three => [ { '=', 2 }, { '>', 5 } ] },
2616
        ],
2617
    );
2618

2619
Would give you:
2620

2621
    WHERE
2622
      one
2623
        AND
2624
      (NOT two RLIKE ?)
2625
        AND
2626
      (NOT ( three = ? OR three > ? ))
2627

2628

2629
=head2 Nested conditions, -and/-or prefixes
2630

2631
So far, we've seen how multiple conditions are joined with a top-level
2632
C<AND>.  We can change this by putting the different conditions we want in
2633
hashes and then putting those hashes in an array. For example:
2634

2635
    my @where = (
2636
        {
2637
            user   => 'nwiger',
2638
            status => { -like => ['pending%', 'dispatched'] },
2639
        },
2640
        {
2641
            user   => 'robot',
2642
            status => 'unassigned',
2643
        }
2644
    );
2645

2646
This data structure would create the following:
2647

2648
    $stmt = "WHERE ( user = ? AND ( status LIKE ? OR status LIKE ? ) )
2649
                OR ( user = ? AND status = ? ) )";
2650
    @bind = ('nwiger', 'pending', 'dispatched', 'robot', 'unassigned');
2651

2652

2653
Clauses in hashrefs or arrayrefs can be prefixed with an C<-and> or C<-or>
2654
to change the logic inside:
2655

2656
    my @where = (
2657
         -and => [
2658
            user => 'nwiger',
2659
            [
2660
                -and => [ workhrs => {'>', 20}, geo => 'ASIA' ],
2661
                -or => { workhrs => {'<', 50}, geo => 'EURO' },
2662
            ],
2663
        ],
2664
    );
2665

2666
That would yield:
2667

2668
    $stmt = "WHERE ( user = ?
2669
               AND ( ( workhrs > ? AND geo = ? )
2670
                  OR ( workhrs < ? OR geo = ? ) ) )";
2671
    @bind = ('nwiger', '20', 'ASIA', '50', 'EURO');
2672

2673
=head3 Algebraic inconsistency, for historical reasons
2674

2675
C<Important note>: when connecting several conditions, the C<-and->|C<-or>
2676
operator goes C<outside> of the nested structure; whereas when connecting
2677
several constraints on one column, the C<-and> operator goes
2678
C<inside> the arrayref. Here is an example combining both features:
2679

2680
   my @where = (
2681
     -and => [a => 1, b => 2],
2682
     -or  => [c => 3, d => 4],
2683
      e   => [-and => {-like => 'foo%'}, {-like => '%bar'} ]
2684
   )
2685

2686
yielding
2687

2688
  WHERE ( (    ( a = ? AND b = ? )
2689
            OR ( c = ? OR d = ? )
2690
            OR ( e LIKE ? AND e LIKE ? ) ) )
2691

2692
This difference in syntax is unfortunate but must be preserved for
2693
historical reasons. So be careful: the two examples below would
2694
seem algebraically equivalent, but they are not
2695

2696
  { col => [ -and =>
2697
    { -like => 'foo%' },
2698
    { -like => '%bar' },
2699
  ] }
2700
  # yields: WHERE ( ( col LIKE ? AND col LIKE ? ) )
2701

2702
  [ -and =>
2703
    { col => { -like => 'foo%' } },
2704
    { col => { -like => '%bar' } },
2705
  ]
2706
  # yields: WHERE ( ( col LIKE ? OR col LIKE ? ) )
2707

2708

2709
=head2 Literal SQL and value type operators
2710

2711
The basic premise of SQL::Abstract is that in WHERE specifications the "left
2712
side" is a column name and the "right side" is a value (normally rendered as
2713
a placeholder). This holds true for both hashrefs and arrayref pairs as you
2714
see in the L</WHERE CLAUSES> examples above. Sometimes it is necessary to
2715
alter this behavior. There are several ways of doing so.
2716

2717
=head3 -ident
2718

2719
This is a virtual operator that signals the string to its right side is an
2720
identifier (a column name) and not a value. For example to compare two
2721
columns you would write:
2722

2723
    my %where = (
2724
        priority => { '<', 2 },
2725
        requestor => { -ident => 'submitter' },
2726
    );
2727

2728
which creates:
2729

2730
    $stmt = "WHERE priority < ? AND requestor = submitter";
2731
    @bind = ('2');
2732

2733
If you are maintaining legacy code you may see a different construct as
2734
described in L</Deprecated usage of Literal SQL>, please use C<-ident> in new
2735
code.
2736

2737
=head3 -value
2738

2739
This is a virtual operator that signals that the construct to its right side
2740
is a value to be passed to DBI. This is for example necessary when you want
2741
to write a where clause against an array (for RDBMS that support such
2742
datatypes). For example:
2743

2744
    my %where = (
2745
        array => { -value => [1, 2, 3] }
2746
    );
2747

2748
will result in:
2749

2750
    $stmt = 'WHERE array = ?';
2751
    @bind = ([1, 2, 3]);
2752

2753
Note that if you were to simply say:
2754

2755
    my %where = (
2756
        array => [1, 2, 3]
2757
    );
2758

2759
the result would probably not be what you wanted:
2760

2761
    $stmt = 'WHERE array = ? OR array = ? OR array = ?';
2762
    @bind = (1, 2, 3);
2763

2764
=head3 Literal SQL
2765

2766
Finally, sometimes only literal SQL will do. To include a random snippet
2767
of SQL verbatim, you specify it as a scalar reference. Consider this only
2768
as a last resort. Usually there is a better way. For example:
2769

2770
    my %where = (
2771
        priority => { '<', 2 },
2772
        requestor => { -in => \'(SELECT name FROM hitmen)' },
2773
    );
2774

2775
Would create:
2776

2777
    $stmt = "WHERE priority < ? AND requestor IN (SELECT name FROM hitmen)"
2778
    @bind = (2);
2779

2780
Note that in this example, you only get one bind parameter back, since
2781
the verbatim SQL is passed as part of the statement.
2782

2783
=head4 CAVEAT
2784

2785
  Never use untrusted input as a literal SQL argument - this is a massive
2786
  security risk (there is no way to check literal snippets for SQL
2787
  injections and other nastyness). If you need to deal with untrusted input
2788
  use literal SQL with placeholders as described next.
2789

2790
=head3 Literal SQL with placeholders and bind values (subqueries)
2791

2792
If the literal SQL to be inserted has placeholders and bind values,
2793
use a reference to an arrayref (yes this is a double reference --
2794
not so common, but perfectly legal Perl). For example, to find a date
2795
in Postgres you can use something like this:
2796

2797
    my %where = (
2798
       date_column => \[ "= date '2008-09-30' - ?::integer", 10 ]
2799
    )
2800

2801
This would create:
2802

2803
    $stmt = "WHERE ( date_column = date '2008-09-30' - ?::integer )"
2804
    @bind = ('10');
2805

2806
Note that you must pass the bind values in the same format as they are returned
2807
by L<where|/where(\%where, $order)>. This means that if you set L</bindtype>
2808
to C<columns>, you must provide the bind values in the
2809
C<< [ column_meta => value ] >> format, where C<column_meta> is an opaque
2810
scalar value; most commonly the column name, but you can use any scalar value
2811
(including references and blessed references), L<SQL::Abstract> will simply
2812
pass it through intact. So if C<bindtype> is set to C<columns> the above
2813
example will look like:
2814

2815
    my %where = (
2816
       date_column => \[ "= date '2008-09-30' - ?::integer", [ {} => 10 ] ]
2817
    )
2818

2819
Literal SQL is especially useful for nesting parenthesized clauses in the
2820
main SQL query. Here is a first example:
2821

2822
  my ($sub_stmt, @sub_bind) = ("SELECT c1 FROM t1 WHERE c2 < ? AND c3 LIKE ?",
2823
                               100, "foo%");
2824
  my %where = (
2825
    foo => 1234,
2826
    bar => \["IN ($sub_stmt)" => @sub_bind],
2827
  );
2828

2829
This yields:
2830

2831
  $stmt = "WHERE (foo = ? AND bar IN (SELECT c1 FROM t1
2832
                                             WHERE c2 < ? AND c3 LIKE ?))";
2833
  @bind = (1234, 100, "foo%");
2834

2835
Other subquery operators, like for example C<"E<gt> ALL"> or C<"NOT IN">,
2836
are expressed in the same way. Of course the C<$sub_stmt> and
2837
its associated bind values can be generated through a former call
2838
to C<select()> :
2839

2840
  my ($sub_stmt, @sub_bind)
2841
     = $sql->select("t1", "c1", {c2 => {"<" => 100},
2842
                                 c3 => {-like => "foo%"}});
2843
  my %where = (
2844
    foo => 1234,
2845
    bar => \["> ALL ($sub_stmt)" => @sub_bind],
2846
  );
2847

2848
In the examples above, the subquery was used as an operator on a column;
2849
but the same principle also applies for a clause within the main C<%where>
2850
hash, like an EXISTS subquery:
2851

2852
  my ($sub_stmt, @sub_bind)
2853
     = $sql->select("t1", "*", {c1 => 1, c2 => \"> t0.c0"});
2854
  my %where = ( -and => [
2855
    foo   => 1234,
2856
    \["EXISTS ($sub_stmt)" => @sub_bind],
2857
  ]);
2858

2859
which yields
2860

2861
  $stmt = "WHERE (foo = ? AND EXISTS (SELECT * FROM t1
2862
                                        WHERE c1 = ? AND c2 > t0.c0))";
2863
  @bind = (1234, 1);
2864

2865

2866
Observe that the condition on C<c2> in the subquery refers to
2867
column C<t0.c0> of the main query: this is I<not> a bind
2868
value, so we have to express it through a scalar ref.
2869
Writing C<< c2 => {">" => "t0.c0"} >> would have generated
2870
C<< c2 > ? >> with bind value C<"t0.c0"> ... not exactly
2871
what we wanted here.
2872

2873
Finally, here is an example where a subquery is used
2874
for expressing unary negation:
2875

2876
  my ($sub_stmt, @sub_bind)
2877
     = $sql->where({age => [{"<" => 10}, {">" => 20}]});
2878
  $sub_stmt =~ s/^ where //i; # don't want "WHERE" in the subclause
2879
  my %where = (
2880
        lname  => {like => '%son%'},
2881
        \["NOT ($sub_stmt)" => @sub_bind],
2882
    );
2883

2884
This yields
2885

2886
  $stmt = "lname LIKE ? AND NOT ( age < ? OR age > ? )"
2887
  @bind = ('%son%', 10, 20)
2888

2889
=head3 Deprecated usage of Literal SQL
2890

2891
Below are some examples of archaic use of literal SQL. It is shown only as
2892
reference for those who deal with legacy code. Each example has a much
2893
better, cleaner and safer alternative that users should opt for in new code.
2894

2895
=over
2896

2897
=item *
2898

2899
    my %where = ( requestor => \'IS NOT NULL' )
2900

2901
    $stmt = "WHERE requestor IS NOT NULL"
2902

2903
This used to be the way of generating NULL comparisons, before the handling
2904
of C<undef> got formalized. For new code please use the superior syntax as
2905
described in L</Tests for NULL values>.
2906

2907
=item *
2908

2909
    my %where = ( requestor => \'= submitter' )
2910

2911
    $stmt = "WHERE requestor = submitter"
2912

2913
This used to be the only way to compare columns. Use the superior L</-ident>
2914
method for all new code. For example an identifier declared in such a way
2915
will be properly quoted if L</quote_char> is properly set, while the legacy
2916
form will remain as supplied.
2917

2918
=item *
2919

2920
    my %where = ( is_ready  => \"", completed => { '>', '2012-12-21' } )
2921

2922
    $stmt = "WHERE completed > ? AND is_ready"
2923
    @bind = ('2012-12-21')
2924

2925
Using an empty string literal used to be the only way to express a boolean.
2926
For all new code please use the much more readable
2927
L<-bool|/Unary operators: bool> operator.
2928

2929
=back
2930

2931
=head2 Conclusion
2932

2933
These pages could go on for a while, since the nesting of the data
2934
structures this module can handle are pretty much unlimited (the
2935
module implements the C<WHERE> expansion as a recursive function
2936
internally). Your best bet is to "play around" with the module a
2937
little to see how the data structures behave, and choose the best
2938
format for your data based on that.
2939

2940
And of course, all the values above will probably be replaced with
2941
variables gotten from forms or the command line. After all, if you
2942
knew everything ahead of time, you wouldn't have to worry about
2943
dynamically-generating SQL and could just hardwire it into your
2944
script.
2945

2946
=head1 ORDER BY CLAUSES
2947

2948
Some functions take an order by clause. This can either be a scalar (just a
2949
column name), a hashref of C<< { -desc => 'col' } >> or C<< { -asc => 'col' }
2950
>>, a scalarref, an arrayref-ref, or an arrayref of any of the previous
2951
forms. Examples:
2952

2953
               Given              |         Will Generate
2954
    ---------------------------------------------------------------
2955
                                  |
2956
    'colA'                        | ORDER BY colA
2957
                                  |
2958
    [qw/colA colB/]               | ORDER BY colA, colB
2959
                                  |
2960
    {-asc  => 'colA'}             | ORDER BY colA ASC
2961
                                  |
2962
    {-desc => 'colB'}             | ORDER BY colB DESC
2963
                                  |
2964
    ['colA', {-asc => 'colB'}]    | ORDER BY colA, colB ASC
2965
                                  |
2966
    { -asc => [qw/colA colB/] }   | ORDER BY colA ASC, colB ASC
2967
                                  |
2968
    \'colA DESC'                  | ORDER BY colA DESC
2969
                                  |
2970
    \[ 'FUNC(colA, ?)', $x ]      | ORDER BY FUNC(colA, ?)
2971
                                  |   /* ...with $x bound to ? */
2972
                                  |
2973
    [                             | ORDER BY
2974
      { -asc => 'colA' },         |     colA ASC,
2975
      { -desc => [qw/colB/] },    |     colB DESC,
2976
      { -asc => [qw/colC colD/] },|     colC ASC, colD ASC,
2977
      \'colE DESC',               |     colE DESC,
2978
      \[ 'FUNC(colF, ?)', $x ],   |     FUNC(colF, ?)
2979
    ]                             |   /* ...with $x bound to ? */
2980
    ===============================================================
2981

2982

2983

2984
=head1 SPECIAL OPERATORS
2985

2986
  my $sqlmaker = SQL::Abstract->new(special_ops => [
2987
     {
2988
      regex => qr/.../,
2989
      handler => sub {
2990
        my ($self, $field, $op, $arg) = @_;
2991
        ...
2992
      },
2993
     },
2994
     {
2995
      regex => qr/.../,
2996
      handler => 'method_name',
2997
     },
2998
   ]);
2999

3000
A "special operator" is a SQL syntactic clause that can be
3001
applied to a field, instead of a usual binary operator.
3002
For example:
3003

3004
   WHERE field IN (?, ?, ?)
3005
   WHERE field BETWEEN ? AND ?
3006
   WHERE MATCH(field) AGAINST (?, ?)
3007

3008
Special operators IN and BETWEEN are fairly standard and therefore
3009
are builtin within C<SQL::Abstract> (as the overridable methods
3010
C<_where_field_IN> and C<_where_field_BETWEEN>). For other operators,
3011
like the MATCH .. AGAINST example above which is specific to MySQL,
3012
you can write your own operator handlers - supply a C<special_ops>
3013
argument to the C<new> method. That argument takes an arrayref of
3014
operator definitions; each operator definition is a hashref with two
3015
entries:
3016

3017
=over
3018

3019
=item regex
3020

3021
the regular expression to match the operator
3022

3023
=item handler
3024

3025
Either a coderef or a plain scalar method name. In both cases
3026
the expected return is C<< ($sql, @bind) >>.
3027

3028
When supplied with a method name, it is simply called on the
3029
L<SQL::Abstract> object as:
3030

3031
 $self->$method_name($field, $op, $arg)
3032

3033
 Where:
3034

3035
  $field is the LHS of the operator
3036
  $op is the part that matched the handler regex
3037
  $arg is the RHS
3038

3039
When supplied with a coderef, it is called as:
3040

3041
 $coderef->($self, $field, $op, $arg)
3042

3043

3044
=back
3045

3046
For example, here is an implementation
3047
of the MATCH .. AGAINST syntax for MySQL
3048

3049
  my $sqlmaker = SQL::Abstract->new(special_ops => [
3050

3051
    # special op for MySql MATCH (field) AGAINST(word1, word2, ...)
3052
    {regex => qr/^match$/i,
3053
     handler => sub {
3054
       my ($self, $field, $op, $arg) = @_;
3055
       $arg = [$arg] if not ref $arg;
3056
       my $label         = $self->_quote($field);
3057
       my ($placeholder) = $self->_convert('?');
3058
       my $placeholders  = join ", ", (($placeholder) x @$arg);
3059
       my $sql           = $self->_sqlcase('match') . " ($label) "
3060
                         . $self->_sqlcase('against') . " ($placeholders) ";
3061
       my @bind = $self->_bindtype($field, @$arg);
3062
       return ($sql, @bind);
3063
       }
3064
     },
3065

3066
  ]);
3067

3068

3069
=head1 UNARY OPERATORS
3070

3071
  my $sqlmaker = SQL::Abstract->new(unary_ops => [
3072
     {
3073
      regex => qr/.../,
3074
      handler => sub {
3075
        my ($self, $op, $arg) = @_;
3076
        ...
3077
      },
3078
     },
3079
     {
3080
      regex => qr/.../,
3081
      handler => 'method_name',
3082
     },
3083
   ]);
3084

3085
A "unary operator" is a SQL syntactic clause that can be
3086
applied to a field - the operator goes before the field
3087

3088
You can write your own operator handlers - supply a C<unary_ops>
3089
argument to the C<new> method. That argument takes an arrayref of
3090
operator definitions; each operator definition is a hashref with two
3091
entries:
3092

3093
=over
3094

3095
=item regex
3096

3097
the regular expression to match the operator
3098

3099
=item handler
3100

3101
Either a coderef or a plain scalar method name. In both cases
3102
the expected return is C<< $sql >>.
3103

3104
When supplied with a method name, it is simply called on the
3105
L<SQL::Abstract> object as:
3106

3107
 $self->$method_name($op, $arg)
3108

3109
 Where:
3110

3111
  $op is the part that matched the handler regex
3112
  $arg is the RHS or argument of the operator
3113

3114
When supplied with a coderef, it is called as:
3115

3116
 $coderef->($self, $op, $arg)
3117

3118

3119
=back
3120

3121

3122
=head1 PERFORMANCE
3123

3124
Thanks to some benchmarking by Mark Stosberg, it turns out that
3125
this module is many orders of magnitude faster than using C<DBIx::Abstract>.
3126
I must admit this wasn't an intentional design issue, but it's a
3127
byproduct of the fact that you get to control your C<DBI> handles
3128
yourself.
3129

3130
To maximize performance, use a code snippet like the following:
3131

3132
    # prepare a statement handle using the first row
3133
    # and then reuse it for the rest of the rows
3134
    my($sth, $stmt);
3135
    for my $href (@array_of_hashrefs) {
3136
        $stmt ||= $sql->insert('table', $href);
3137
        $sth  ||= $dbh->prepare($stmt);
3138
        $sth->execute($sql->values($href));
3139
    }
3140

3141
The reason this works is because the keys in your C<$href> are sorted
3142
internally by B<SQL::Abstract>. Thus, as long as your data retains
3143
the same structure, you only have to generate the SQL the first time
3144
around. On subsequent queries, simply use the C<values> function provided
3145
by this module to return your values in the correct order.
3146

3147
However this depends on the values having the same type - if, for
3148
example, the values of a where clause may either have values
3149
(resulting in sql of the form C<column = ?> with a single bind
3150
value), or alternatively the values might be C<undef> (resulting in
3151
sql of the form C<column IS NULL> with no bind value) then the
3152
caching technique suggested will not work.
3153

3154
=head1 FORMBUILDER
3155

3156
If you use my C<CGI::FormBuilder> module at all, you'll hopefully
3157
really like this part (I do, at least). Building up a complex query
3158
can be as simple as the following:
3159

3160
    #!/usr/bin/perl
3161

3162
    use warnings;
3163
    use strict;
3164

3165
    use CGI::FormBuilder;
3166
    use SQL::Abstract;
3167

3168
    my $form = CGI::FormBuilder->new(...);
3169
    my $sql  = SQL::Abstract->new;
3170

3171
    if ($form->submitted) {
3172
        my $field = $form->field;
3173
        my $id = delete $field->{id};
3174
        my($stmt, @bind) = $sql->update('table', $field, {id => $id});
3175
    }
3176

3177
Of course, you would still have to connect using C<DBI> to run the
3178
query, but the point is that if you make your form look like your
3179
table, the actual query script can be extremely simplistic.
3180

3181
If you're B<REALLY> lazy (I am), check out C<HTML::QuickTable> for
3182
a fast interface to returning and formatting data. I frequently
3183
use these three modules together to write complex database query
3184
apps in under 50 lines.
3185

3186
=head1 HOW TO CONTRIBUTE
3187

3188
Contributions are always welcome, in all usable forms (we especially
3189
welcome documentation improvements). The delivery methods include git-
3190
or unified-diff formatted patches, GitHub pull requests, or plain bug
3191
reports either via RT or the Mailing list. Contributors are generally
3192
granted full access to the official repository after their first several
3193
patches pass successful review.
3194

3195
This project is maintained in a git repository. The code and related tools are
3196
accessible at the following locations:
3197

3198
=over
3199

3200
=item * Official repo: L<git://git.shadowcat.co.uk/dbsrgits/SQL-Abstract.git>
3201

3202
=item * Official gitweb: L<http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits/SQL-Abstract.git>
3203

3204
=item * GitHub mirror: L<https://github.com/dbsrgits/sql-abstract>
3205

3206
=item * Authorized committers: L<ssh://dbsrgits@git.shadowcat.co.uk/SQL-Abstract.git>
3207

3208
=back
3209

3210
=head1 CHANGES
3211

3212
Version 1.50 was a major internal refactoring of C<SQL::Abstract>.
3213
Great care has been taken to preserve the I<published> behavior
3214
documented in previous versions in the 1.* family; however,
3215
some features that were previously undocumented, or behaved
3216
differently from the documentation, had to be changed in order
3217
to clarify the semantics. Hence, client code that was relying
3218
on some dark areas of C<SQL::Abstract> v1.*
3219
B<might behave differently> in v1.50.
3220

3221
The main changes are:
3222

3223
=over
3224

3225
=item *
3226

3227
support for literal SQL through the C<< \ [ $sql, @bind ] >> syntax.
3228

3229
=item *
3230

3231
support for the { operator => \"..." } construct (to embed literal SQL)
3232

3233
=item *
3234

3235
support for the { operator => \["...", @bind] } construct (to embed literal SQL with bind values)
3236

3237
=item *
3238

3239
optional support for L<array datatypes|/"Inserting and Updating Arrays">
3240

3241
=item *
3242

3243
defensive programming: check arguments
3244

3245
=item *
3246

3247
fixed bug with global logic, which was previously implemented
3248
through global variables yielding side-effects. Prior versions would
3249
interpret C<< [ {cond1, cond2}, [cond3, cond4] ] >>
3250
as C<< "(cond1 AND cond2) OR (cond3 AND cond4)" >>.
3251
Now this is interpreted
3252
as C<< "(cond1 AND cond2) OR (cond3 OR cond4)" >>.
3253

3254

3255
=item *
3256

3257
fixed semantics of  _bindtype on array args
3258

3259
=item *
3260

3261
dropped the C<_anoncopy> of the %where tree. No longer necessary,
3262
we just avoid shifting arrays within that tree.
3263

3264
=item *
3265

3266
dropped the C<_modlogic> function
3267

3268
=back
3269

3270
=head1 ACKNOWLEDGEMENTS
3271

3272
There are a number of individuals that have really helped out with
3273
this module. Unfortunately, most of them submitted bugs via CPAN
3274
so I have no idea who they are! But the people I do know are:
3275

3276
    Ash Berlin (order_by hash term support)
3277
    Matt Trout (DBIx::Class support)
3278
    Mark Stosberg (benchmarking)
3279
    Chas Owens (initial "IN" operator support)
3280
    Philip Collins (per-field SQL functions)
3281
    Eric Kolve (hashref "AND" support)
3282
    Mike Fragassi (enhancements to "BETWEEN" and "LIKE")
3283
    Dan Kubb (support for "quote_char" and "name_sep")
3284
    Guillermo Roditi (patch to cleanup "IN" and "BETWEEN", fix and tests for _order_by)
3285
    Laurent Dami (internal refactoring, extensible list of special operators, literal SQL)
3286
    Norbert Buchmuller (support for literal SQL in hashpair, misc. fixes & tests)
3287
    Peter Rabbitson (rewrite of SQLA::Test, misc. fixes & tests)
3288
    Oliver Charles (support for "RETURNING" after "INSERT")
3289

3290
Thanks!
3291

3292
=head1 SEE ALSO
3293

3294
L<DBIx::Class>, L<DBIx::Abstract>, L<CGI::FormBuilder>, L<HTML::QuickTable>.
3295

3296
=head1 AUTHOR
3297

3298
Copyright (c) 2001-2007 Nathan Wiger <nwiger@cpan.org>. All Rights Reserved.
3299

3300
This module is actively maintained by Matt Trout <mst@shadowcatsystems.co.uk>
3301

3302
For support, your best bet is to try the C<DBIx::Class> users mailing list.
3303
While not an official support venue, C<DBIx::Class> makes heavy use of
3304
C<SQL::Abstract>, and as such list members there are very familiar with
3305
how to create queries.
3306

3307
=head1 LICENSE
3308

3309
This module is free software; you may copy this under the same
3310
terms as perl itself (either the GNU General Public License or
3311
the Artistic License)
3312

3313
=cut
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2024 Coveralls, Inc