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

dbsrgits / sql-abstract / 27

pending completion
27

Pull #15

travis-ci

web-flow
Do not generate incorrect SQL in presence of -and=>[]
Pull Request #15: Do not generate incorrect SQL in presence of -and=>[]

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

785 of 889 relevant lines covered (88.3%)

37986.88 hits per line

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

87.34
/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.86';
31

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

35
our $AUTOLOAD;
36

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

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

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

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

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

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

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

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

135

136

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

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

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

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

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

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

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

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

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

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

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

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

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

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

196

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

206

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

287

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

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

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

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

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

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

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

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

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

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

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

350
  });
3,012✔
351

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

356

357

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

362

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

453

454

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

459

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

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

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

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

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

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

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

489

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

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

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

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

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

512

513

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

518

519

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

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

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

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

538

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

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

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

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

558

559

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

564

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

793
   });
312✔
794
}
795

796

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

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

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

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

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

818

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1017
  $s;
480✔
1018
}
1019

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

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

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

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

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

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

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

1070

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

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

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

1099

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

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

1111

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

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

1120

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

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

1129

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

1135

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

1140

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

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

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

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

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

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

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

1206

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1319
  $sql;
108✔
1320
}
1321

1322

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

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

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

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

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

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

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

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

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

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

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

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

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

1374
      return () unless $key;
480✔
1375

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

1380
      my $direction = $1;
456✔
1381

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

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

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

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

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

1405

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

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

1420

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

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

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

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

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

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

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

1450

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

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

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

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

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

1501

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

1509

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

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

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

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

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

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

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

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

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

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

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

1554

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

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

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

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

1570

1571

1572

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

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

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

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

1614
    return @all_bind;
72✔
1615
}
1616

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

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

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

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

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

1685

1686
sub DESTROY { 1 }
7,332✔
1687

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

1695
1;
1696

1697

1698

1699
__END__
1700

1701
=head1 NAME
1702

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

1705
=head1 SYNOPSIS
1706

1707
    use SQL::Abstract;
1708

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

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

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

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

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

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

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

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

1730
=head1 DESCRIPTION
1731

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

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

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

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

1758
The SQL can then be generated with this:
1759

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

1762
Which would give you something like this:
1763

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

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

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

1775
=head2 Inserting and Updating Arrays
1776

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

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

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

1789
This results in:
1790

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

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

1795

1796
=head2 Inserting and Updating SQL
1797

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

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

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

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

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

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

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

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

1827
=head2 Complex where statements
1828

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

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

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

1843
The above would give you something like this:
1844

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

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

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

1855
Easy, eh?
1856

1857
=head1 METHODS
1858

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

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

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

1870
=over
1871

1872
=item case
1873

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

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

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

1881
=item cmp
1882

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

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

1888
Will generate SQL like this:
1889

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

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

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

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

1900
=item sqltrue, sqlfalse
1901

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

1907
=item logic
1908

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

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

1919
will generate SQL like this:
1920

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

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

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

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

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

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

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

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

1940
=item convert
1941

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

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

1950
Will turn out the following SQL:
1951

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

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

1958
=item bindtype
1959

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

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

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

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

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

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

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

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

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

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

2010
=item quote_char
2011

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

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

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

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

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

2028
=item escape_char
2029

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

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

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

2043
=item name_sep
2044

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

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

2051
=item injection_guard
2052

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

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

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

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

2065
=item array_datatypes
2066

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

2076

2077
=item special_ops
2078

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

2083
=item unary_ops
2084

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

2089

2090

2091
=back
2092

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

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

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

2106
=over 4
2107

2108
=item returning
2109

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

2117
=back
2118

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

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

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

2132
=over 4
2133

2134
=item returning
2135

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

2139
=back
2140

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

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

2146
=over
2147

2148
=item $source
2149

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

2156
=item $fields
2157

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

2166
=item $where
2167

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

2173
=item $order
2174

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

2180
=back
2181

2182

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

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

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

2192
=over 4
2193

2194
=item returning
2195

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

2199
=back
2200

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

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

2209

2210
=head2 values(\%data)
2211

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

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

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

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

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

2227
These would return the following:
2228

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

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

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

2239
By the same token:
2240

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

2243
Might give you:
2244

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

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

2250
=head1 EXPORTABLE FUNCTIONS
2251

2252
=head2 is_plain_value
2253

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

2257
=over
2258

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

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

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

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

2267
=back
2268

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

2272
=over
2273

2274
=item * Note
2275

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

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

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

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

2296
or perhaps even
2297

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

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

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

2312
=back
2313

2314
=head2 is_literal_value
2315

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

2319
=over
2320

2321
=item * C<\$sql_string>
2322

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

2325
=back
2326

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

2330
=head1 WHERE CLAUSES
2331

2332
=head2 Introduction
2333

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

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

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

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

2347
=head2 Key-value pairs
2348

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

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

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

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

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

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

2370
This simple code will create the following:
2371

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

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

2378
=head2 Tests for NULL values
2379

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

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

2387
becomes:
2388

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

2392
To test if a column IS NOT NULL:
2393

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

2399
=head2 Specific comparison operators
2400

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

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

2409
Which would generate:
2410

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

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

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

2418
Which would give you:
2419

2420
    "WHERE status = ? OR status = ? OR status = ?"
2421

2422

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

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

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

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

2440

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

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

2448
Which would generate:
2449

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

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

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

2461
Which would generate:
2462

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

2466

2467
=head2 Logic and nesting operators
2468

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

2473
    WHERE priority != ? AND priority != ?
2474

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

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

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

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

2485

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

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

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

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

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

2506

2507

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

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

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

2518
Which would generate:
2519

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

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

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

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

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

2541
would generate:
2542

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

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

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

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

2562
Would give you:
2563

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

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

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

2579
Would give you:
2580

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

2589

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

2593
=head2 Unary operators: bool
2594

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

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

2605
Would give you:
2606

2607
    WHERE is_user AND NOT is_enabled
2608

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

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

2620
Would give you:
2621

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

2629

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

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

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

2647
This data structure would create the following:
2648

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

2653

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

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

2667
That would yield:
2668

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

2674
=head3 Algebraic inconsistency, for historical reasons
2675

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

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

2687
yielding
2688

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

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

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

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

2709

2710
=head2 Literal SQL and value type operators
2711

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

2718
=head3 -ident
2719

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

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

2729
which creates:
2730

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

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

2738
=head3 -value
2739

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

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

2749
will result in:
2750

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

2754
Note that if you were to simply say:
2755

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

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

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

2765
=head3 Literal SQL
2766

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

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

2776
Would create:
2777

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

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

2784
=head4 CAVEAT
2785

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

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

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

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

2802
This would create:
2803

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

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

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

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

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

2830
This yields:
2831

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

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

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

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

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

2860
which yields
2861

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

2866

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

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

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

2885
This yields
2886

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

2890
=head3 Deprecated usage of Literal SQL
2891

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

2896
=over
2897

2898
=item *
2899

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

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

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

2908
=item *
2909

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

2912
    $stmt = "WHERE requestor = submitter"
2913

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

2919
=item *
2920

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

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

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

2930
=back
2931

2932
=head2 Conclusion
2933

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

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

2947
=head1 ORDER BY CLAUSES
2948

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

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

2983

2984

2985
=head1 SPECIAL OPERATORS
2986

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

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

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

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

3018
=over
3019

3020
=item regex
3021

3022
the regular expression to match the operator
3023

3024
=item handler
3025

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

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

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

3034
 Where:
3035

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

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

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

3044

3045
=back
3046

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

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

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

3067
  ]);
3068

3069

3070
=head1 UNARY OPERATORS
3071

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

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

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

3094
=over
3095

3096
=item regex
3097

3098
the regular expression to match the operator
3099

3100
=item handler
3101

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

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

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

3110
 Where:
3111

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

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

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

3119

3120
=back
3121

3122

3123
=head1 PERFORMANCE
3124

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

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

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

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

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

3155
=head1 FORMBUILDER
3156

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

3161
    #!/usr/bin/perl
3162

3163
    use warnings;
3164
    use strict;
3165

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

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

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

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

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

3187
=head1 HOW TO CONTRIBUTE
3188

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

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

3199
=over
3200

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

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

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

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

3209
=back
3210

3211
=head1 CHANGES
3212

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

3222
The main changes are:
3223

3224
=over
3225

3226
=item *
3227

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

3230
=item *
3231

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

3234
=item *
3235

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

3238
=item *
3239

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

3242
=item *
3243

3244
defensive programming: check arguments
3245

3246
=item *
3247

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

3255

3256
=item *
3257

3258
fixed semantics of  _bindtype on array args
3259

3260
=item *
3261

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

3265
=item *
3266

3267
dropped the C<_modlogic> function
3268

3269
=back
3270

3271
=head1 ACKNOWLEDGEMENTS
3272

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

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

3291
Thanks!
3292

3293
=head1 SEE ALSO
3294

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

3297
=head1 AUTHOR
3298

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

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

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

3308
=head1 LICENSE
3309

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

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