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

dbsrgits / sql-abstract / 12

pending completion
12

Pull #13

travis-ci

web-flow
Add overloadable _select_field_values method, consistent with _update_set_values and _insert_values
Pull Request #13: Add overloadable _select_field_values method

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

821 of 927 relevant lines covered (88.57%)

36660.93 hits per line

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

87.77
/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,908✔
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,320✔
143
  my $class = ref($self) || $self;
7,320✔
144
  my %opt = (ref $_[0] eq 'HASH') ? %{$_[0]} : @_;
7,320✔
145

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

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

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

155
  # default comparison is "=", but can be overridden
156
  $opt{cmp} ||= '=';
7,320✔
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,320✔
161
  $opt{inequality_op} = qr/^( != | <> )$/ix;
7,320✔
162

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

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

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

175
  # unary operators
176
  $opt{unary_ops} ||= [];
7,320✔
177
  push @{$opt{unary_ops}}, @BUILTIN_UNARY_OPS;
7,320✔
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,320✔
188
    \;
189
      |
190
    ^ \s* go \s
191
  /xmi;
192

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

196

197
sub _assert_pass_injection_guard {
198
  if ($_[1] =~ $_[0]->{injection_guard}) {
21,588✔
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($where_sql, @bind) = $self->where($where, $order);
1,224✔
468

469
  my ($fields_sql, @fields_bind) = $self->_select_field_values($fields);
1,068✔
470
  push @bind, @fields_bind;
1,068✔
471
  my $sql = join(' ', $self->_sqlcase('select'), $fields_sql,
1,068✔
472
                      $self->_sqlcase('from'),   $table)
473
          . $where_sql;
474

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

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

484
#======================================================================
485
# DELETE
486
#======================================================================
487

488

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

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

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

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

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

511

512

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

517

518

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

523
  # where ?
524
  my ($sql, @bind) = $self->_recurse_where($where);
7,416✔
525
  $sql = $sql ? $self->_sqlcase(' where ') . "( $sql )" : '';
6,096✔
526

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

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

537

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

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

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

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

557

558

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

563

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

649
        # top level vs nested
650
        # we assume that handled unary ops will take care of their ()s
651
        $s = "($s)" unless (
3,535✔
652
          List::Util::first {$op =~ $_->{regex}} @{$self->{unary_ops}}
3,932✔
653
            or
654
          ( defined $self->{_nested_func_lhs} and $self->{_nested_func_lhs} eq $k )
1,005✔
655
        );
656
        ($s, @b);
2,412✔
657
      }
658
      else {
659
        if (! length $k) {
14,004✔
660
          if (is_literal_value ($v) ) {
528✔
661
            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✔
662
          }
663
          else {
664
            puke "Supplying an empty left hand side argument is not supported in hash-pairs";
288✔
665
          }
666
        }
667

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

792
   });
312✔
793
}
794

795

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

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

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

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

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

817

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1016
  $s;
480✔
1017
}
1018

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

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

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

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

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

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

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

1069

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

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

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

1098

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

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

1110

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

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

1119

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

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

1128

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

1134

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

1139

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

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

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

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

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

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

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

1205

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1318
  $sql;
108✔
1319
}
1320

1321

1322
#======================================================================
1323
# ORDER BY
1324
#======================================================================
1325

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

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

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

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

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

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

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

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

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

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

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

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

1373
      return () unless $key;
480✔
1374

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

1379
      my $direction = $1;
456✔
1380

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

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

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

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

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

1404

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

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

1419

1420
#======================================================================
1421
# UTILITY FUNCTIONS
1422
#======================================================================
1423

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

1428
  return '' unless defined $_[1];
17,484✔
1429
  return ${$_[1]} if ref($_[1]) eq 'SCALAR';
17,436✔
1430

1431
  $_[0]->{quote_char} or
10,157✔
1432
    ($_[0]->_assert_pass_injection_guard($_[1]), return $_[1]);
7,255✔
1433

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

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

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

1449

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

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

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

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

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

1499

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

1507

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

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

1515
  return 'UNDEF' unless defined $data;
64,692✔
1516

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

1520
  return 'SCALAR' unless $ref;
61,668✔
1521

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

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

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

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

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

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

1552

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

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

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

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

1568

1569

1570

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

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

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

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

1612
    return @all_bind;
72✔
1613
}
1614

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

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

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

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

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

1683

1684
sub DESTROY { 1 }
7,320✔
1685

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

1693
1;
1694

1695

1696

1697
__END__
1698

1699
=head1 NAME
1700

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

1703
=head1 SYNOPSIS
1704

1705
    use SQL::Abstract;
1706

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

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

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

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

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

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

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

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

1728
=head1 DESCRIPTION
1729

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

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

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

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

1756
The SQL can then be generated with this:
1757

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

1760
Which would give you something like this:
1761

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

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

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

1773
=head2 Inserting and Updating Arrays
1774

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

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

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

1787
This results in:
1788

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

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

1793

1794
=head2 Inserting and Updating SQL
1795

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

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

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

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

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

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

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

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

1825
=head2 Complex where statements
1826

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

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

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

1841
The above would give you something like this:
1842

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

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

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

1853
Easy, eh?
1854

1855
=head1 METHODS
1856

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

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

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

1868
=over
1869

1870
=item case
1871

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

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

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

1879
=item cmp
1880

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

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

1886
Will generate SQL like this:
1887

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

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

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

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

1898
=item sqltrue, sqlfalse
1899

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

1905
=item logic
1906

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

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

1917
will generate SQL like this:
1918

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

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

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

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

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

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

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

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

1938
=item convert
1939

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

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

1948
Will turn out the following SQL:
1949

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

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

1956
=item bindtype
1957

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

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

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

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

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

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

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

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

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

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

2008
=item quote_char
2009

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

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

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

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

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

2026
=item escape_char
2027

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

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

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

2041
=item name_sep
2042

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

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

2049
=item injection_guard
2050

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

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

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

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

2063
=item array_datatypes
2064

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

2074

2075
=item special_ops
2076

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

2081
=item unary_ops
2082

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

2087

2088

2089
=back
2090

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

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

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

2104
=over 4
2105

2106
=item returning
2107

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

2115
=back
2116

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

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

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

2130
=over 4
2131

2132
=item returning
2133

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

2137
=back
2138

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

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

2144
=over
2145

2146
=item $source
2147

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

2154
=item $fields
2155

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

2164
=item $where
2165

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

2171
=item $order
2172

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

2178
=back
2179

2180

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

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

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

2190
=over 4
2191

2192
=item returning
2193

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

2197
=back
2198

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

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

2207

2208
=head2 values(\%data)
2209

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

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

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

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

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

2225
These would return the following:
2226

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

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

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

2237
By the same token:
2238

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

2241
Might give you:
2242

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

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

2248
=head1 EXPORTABLE FUNCTIONS
2249

2250
=head2 is_plain_value
2251

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

2255
=over
2256

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

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

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

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

2265
=back
2266

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

2270
=over
2271

2272
=item * Note
2273

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

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

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

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

2294
or perhaps even
2295

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

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

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

2310
=back
2311

2312
=head2 is_literal_value
2313

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

2317
=over
2318

2319
=item * C<\$sql_string>
2320

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

2323
=back
2324

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

2328
=head1 WHERE CLAUSES
2329

2330
=head2 Introduction
2331

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

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

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

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

2345
=head2 Key-value pairs
2346

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

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

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

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

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

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

2368
This simple code will create the following:
2369

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

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

2376
=head2 Tests for NULL values
2377

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

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

2385
becomes:
2386

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

2390
To test if a column IS NOT NULL:
2391

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

2397
=head2 Specific comparison operators
2398

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

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

2407
Which would generate:
2408

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

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

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

2416
Which would give you:
2417

2418
    "WHERE status = ? OR status = ? OR status = ?"
2419

2420

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

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

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

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

2438

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

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

2446
Which would generate:
2447

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

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

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

2459
Which would generate:
2460

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

2464

2465
=head2 Logic and nesting operators
2466

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

2471
    WHERE priority != ? AND priority != ?
2472

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

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

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

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

2483

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

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

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

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

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

2504

2505

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

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

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

2516
Which would generate:
2517

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

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

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

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

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

2539
would generate:
2540

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

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

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

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

2560
Would give you:
2561

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

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

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

2577
Would give you:
2578

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

2587

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

2591
=head2 Unary operators: bool
2592

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

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

2603
Would give you:
2604

2605
    WHERE is_user AND NOT is_enabled
2606

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

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

2618
Would give you:
2619

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

2627

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

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

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

2645
This data structure would create the following:
2646

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

2651

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

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

2665
That would yield:
2666

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

2672
=head3 Algebraic inconsistency, for historical reasons
2673

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

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

2685
yielding
2686

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

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

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

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

2707

2708
=head2 Literal SQL and value type operators
2709

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

2716
=head3 -ident
2717

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

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

2727
which creates:
2728

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

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

2736
=head3 -value
2737

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

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

2747
will result in:
2748

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

2752
Note that if you were to simply say:
2753

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

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

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

2763
=head3 Literal SQL
2764

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

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

2774
Would create:
2775

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

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

2782
=head4 CAVEAT
2783

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

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

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

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

2800
This would create:
2801

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

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

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

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

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

2828
This yields:
2829

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

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

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

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

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

2858
which yields
2859

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

2864

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

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

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

2883
This yields
2884

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

2888
=head3 Deprecated usage of Literal SQL
2889

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

2894
=over
2895

2896
=item *
2897

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

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

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

2906
=item *
2907

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

2910
    $stmt = "WHERE requestor = submitter"
2911

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

2917
=item *
2918

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

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

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

2928
=back
2929

2930
=head2 Conclusion
2931

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

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

2945
=head1 ORDER BY CLAUSES
2946

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

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

2981

2982

2983
=head1 SPECIAL OPERATORS
2984

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

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

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

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

3016
=over
3017

3018
=item regex
3019

3020
the regular expression to match the operator
3021

3022
=item handler
3023

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

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

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

3032
 Where:
3033

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

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

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

3042

3043
=back
3044

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

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

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

3065
  ]);
3066

3067

3068
=head1 UNARY OPERATORS
3069

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

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

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

3092
=over
3093

3094
=item regex
3095

3096
the regular expression to match the operator
3097

3098
=item handler
3099

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

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

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

3108
 Where:
3109

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

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

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

3117

3118
=back
3119

3120

3121
=head1 PERFORMANCE
3122

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

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

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

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

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

3153
=head1 FORMBUILDER
3154

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

3159
    #!/usr/bin/perl
3160

3161
    use warnings;
3162
    use strict;
3163

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

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

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

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

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

3185
=head1 HOW TO CONTRIBUTE
3186

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

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

3197
=over
3198

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

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

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

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

3207
=back
3208

3209
=head1 CHANGES
3210

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

3220
The main changes are:
3221

3222
=over
3223

3224
=item *
3225

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

3228
=item *
3229

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

3232
=item *
3233

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

3236
=item *
3237

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

3240
=item *
3241

3242
defensive programming: check arguments
3243

3244
=item *
3245

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

3253

3254
=item *
3255

3256
fixed semantics of  _bindtype on array args
3257

3258
=item *
3259

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

3263
=item *
3264

3265
dropped the C<_modlogic> function
3266

3267
=back
3268

3269
=head1 ACKNOWLEDGEMENTS
3270

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

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

3289
Thanks!
3290

3291
=head1 SEE ALSO
3292

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

3295
=head1 AUTHOR
3296

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

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

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

3306
=head1 LICENSE
3307

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

3312
=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