Switch the main dev branch back to 'master'
Peter Rabbitson [Fri, 26 Feb 2016 08:57:27 +0000 (09:57 +0100)]
Previously the idea was to have two dev branches - one for "the crowd", and
another one for the rel manager to do periodic squashes, merges, cleanups etc.
This worked rather well for about 1.5 years, but with the primary architect
outgoing it can't be sustained, and only serves to confuse everyone.

Thus a fast forward with a mini-merge of master up to the tip of current/blead
and continuing pushes to master alone from there on. Not yet deleting the old
'current/blead' and 'current/for_cpan_index' branches, as it affects PR states
due to useless "smarts" in the github logic.

1  2 
.travis.yml
lib/DBIx/Class.pm
lib/DBIx/Class/SQLMaker.pm

diff --combined .travis.yml
@@@ -6,18 -6,35 +6,14 @@@
  #
  # * Minimum perl officially supported by DBIC is 5.8.3. This *includes* the
  # basic depchain. On failure either attempt to fix it or bring it to the
 -# attention of ribasushi. *DO NOT* disable 5.8 testing - it is here for a
 -# reason
 -#
 -# * The matrix is built from two main modes - CLEANTEST = [true|false].
 -# - In the first case we test with minimal deps available, and skip everything
 -#   listed in DBIC::OptDesps. The modules are installed with classic CPAN
 -#   invocations and are *fully tested*. In other words we simulate what would
 -#   happen if a user tried to install on a just-compiled virgin perl
 -# - Without CLEANTEST we bring the armada of RDBMS and install the maximum
 -#   possible set of deps *without testing them*. This ensures we stay within
 -#   a reasonable build-time and still run as many of our tests as possible
 -#
 -# * The perl builds and the DBIC tests run under NUMTHREADS number of threads.
 -# The testing of dependencies under CLEANTEST runs single-threaded, at least
 -# until we fix our entire dep-chain to safely pass under -j
 -#
 -# * The way .travis.yml is fed to the command controller is idiotic - it
 -# makes using multiline `bash -c` statements impossible. Therefore to
 -# aid readability (our travis logic is rather complex), the bulk of
 -# functionality is moved to scripts. More about the problem (and the
 -# WONTFIX "explanation") here: https://github.com/travis-ci/travis-ci/issues/497
 +# attention of the maintainer. *DO NOT* disable 5.8 testing - it is here for
 +# a very good reason
  #
 +# the entire run times out after 50 minutes, or after 5 minutes without
 +# console output
  
  #
  # Smoke all branches except for blocked* and wip/*
--#
--# Additionally master does not smoke with bleadperl
--# ( implemented in maint/travis-ci_scripts/10_before_install.bash )
--#
  branches:
    except:
      - /^wip\//
@@@ -36,364 -53,211 +32,364 @@@ notifications
    email:
      recipients:
        - ribasushi@cpan.org
      on_success: change
      on_failure: always
  
 -# FIXME - This stuff is not yet available for free OSS accounts, sadpanda
 -# First paragrah on http://about.travis-ci.org/docs/user/caching/
 -#cache:
 -#  apt: true
 -#  directories:
 -#    - /var/cache/apt/archives
 +addons:
 +  apt:
 +    packages:
 +      - libapp-nopaste-perl
 +      - net-tools
  
 +# This is probably a net-loss for setup etc - a bare 'C' will likely fare much better
  language: perl
  
 -perl:
 -  - "5.18"
 +# Currently not trying osx: https://github.com/travis-ci/travis-ci/issues/2314
 +os: linux
  
 -env:
 -  - CLEANTEST=false
 -  - CLEANTEST=true
 +# The defaults run under the more rapid container infra. The hardware is
 +# actually *much* slower, but the jobs start much faster, for more info see
 +# https://docs.travis-ci.com/user/ci-environment/#Virtualization-environments
 +# Combined with 'fast_finish' this will result in an "uh-oh" email as early
 +# as possible
 +dist: precise
 +sudo: false
 +env: CLEANTEST=true
 +
 +perl:
 +  - "5.8"
 +  - "5.10"
 +  - "5.22-extras"
  
  matrix:
 +  fast_finish: true
 +
    include:
 -    # this particular perl is quite widespread
 -    - perl: 5.8.8_thr_mb
 +
 +    # Same as the "master matrix" above, frozen under older dist/infrastructure
 +    # In genereal it is strongly recommended to keep things on the older
 +    # version indefinitely - there is little value in-depth smoking on
 +    # more recent software stacks
 +    - perl: "5.8"
 +      sudo: required
 +      dist: precise
        env:
 -        - CLEANTEST=true
 -        - BREWOPTS="-Duseithreads -Dusemorebits"
 -        - BREWVER=5.8.8
 +        - CLEANTEST=false
  
 -    # so is this one (test a sane CPAN.pm)
 -    - perl: 5.12.4_thr_mb
 +    - perl: "5.10"
 +      sudo: required
 +      dist: precise
        env:
 -        - CLEANTEST=true
 -        - BREWOPTS="-Duseithreads -Dusemorebits"
 -        - BREWVER=5.12.4
 +        - CLEANTEST=false
  
 -    # this is the perl suse ships
 -    - perl: 5.10.0_thr_dbg
 +    - perl: "5.22-extras"
 +      sudo: required
 +      dist: precise
        env:
 -        - CLEANTEST=true
 -        - BREWOPTS="-DDEBUGGING -Duseithreads"
 -        - BREWVER=5.10.0
 +        - CLEANTEST=false
  
 -    # CLEANTEST of minimum supported
 -    - perl: 5.8.3_nt_mb
 +    # CLEANTEST of minimum supported with non-tracing poisoning, single thread (hence the sudo)
 +    - perl: "5.8.3_nt_mb"
 +      sudo: required
 +      dist: precise
        env:
 +        - VCPU_USE=1
          - CLEANTEST=true
 +        - POISON_ENV=true
 +        - DBIC_TRACE_PROFILE=console_monochrome
 +        - BREWVER=5.8.3
          - BREWOPTS="-Dusemorebits"
 +
 +    # Full Test of minimum supported without threads with plain poisoned trace
 +    - perl: "5.8.3_nt"
 +      sudo: required
 +      dist: precise
 +      # run these under legacy - great simulation of low memory env
 +      group: legacy
 +      env:
 +        - CLEANTEST=false
 +        - POISON_ENV=true
 +        - DBIC_TRACE=1
          - BREWVER=5.8.3
  
 -    # Full Test of minimum supported with threads
 -    - perl: 5.8.5_thr
 +    # Full Test of minimum supported with threads with non-tracing poisoning
 +    - perl: "5.8.5_thr"
 +      sudo: required
 +      dist: precise
 +      # run these under legacy - great simulation of low memory env
 +      group: legacy
        env:
          - CLEANTEST=false
 -        - BREWOPTS="-Duseithreads"
 +        - POISON_ENV=true
 +        - DBIC_TRACE_PROFILE=console
          - BREWVER=5.8.5
 +        - BREWOPTS="-Duseithreads"
 +
 +    # CLEANTEST of solaris-like perl with non-tracing poisoning
 +    - perl: "5.8.4_nt"
 +      sudo: false
 +      dist: precise
 +      env:
 +        - CLEANTEST=true
 +        - POISON_ENV=true
          - DBIC_TRACE_PROFILE=console
 +        - BREWVER=5.8.4
  
 -    # Full Test of minimum supported without threads
 -    - perl: 5.8.3_nt
 +    # Full test: this particular perl is quite widespread, single thread
 +    - perl: "5.8.8_thr"
 +      sudo: required
 +      dist: precise
        env:
 +        - VCPU_USE=1
          - CLEANTEST=false
 -        - BREWOPTS=""
 -        - BREWVER=5.8.3
 -        - DBIC_TRACE_PROFILE=console_monochrome
 -
 -    ###
 -    # some permutations of tracing and envvar poisoning
 +        - BREWVER=5.8.8
 +        - BREWOPTS="-Duseithreads"
  
 -    - perl: 5.16.2_thr_mb
 +    # CLEANTEST: this is the perl suse ships, with env poisoning
 +    - perl: "5.10.0_thr_dbg"
 +      sudo: false
 +      dist: precise
        env:
 -        - CLEANTEST=false
 +        - CLEANTEST=true
          - POISON_ENV=true
 -        - DBIC_TRACE=1
 -        - DBIC_MULTICREATE_DEBUG=0
 +        - BREWVER=5.10.0
 +        - BREWOPTS="-DDEBUGGING -Duseithreads"
 +
 +    # CLEANTEST: this one is in a number of debian-based LTS (test a sane CPAN.pm, single thread)
 +    - perl: "5.14.2_thr_mb"
 +      sudo: required
 +      dist: precise
 +      env:
 +        - VCPU_USE=1
 +        - CLEANTEST=true
 +        - BREWVER=5.14.2
          - BREWOPTS="-Duseithreads -Dusemorebits"
 -        - BREWVER=5.16.2
  
 -    - perl: 5.18
 +    ###
 +    # some permutations of tracing and envvar poisoning
 +
 +    - perl: "5.12.3_thr"
 +      sudo: false
 +      dist: precise
        env:
 -        - CLEANTEST=false
 +        - CLEANTEST=true
          - POISON_ENV=true
 +        - DBIC_TRACE=1
 +        - DBIC_MULTICREATE_DEBUG=1
 +        - DBIC_STORAGE_RETRY_DEBUG=1
          - DBIC_TRACE_PROFILE=console
 +        - BREWVER=5.12.3
 +        - BREWOPTS="-Duseithreads"
  
 -    - perl: 5.8
 +    - perl: "5.16.3_thr_mb"
 +      sudo: required
 +      dist: precise
        env:
 -        - CLEANTEST=true
 +        - CLEANTEST=false
          - POISON_ENV=true
          - DBIC_TRACE=1
 -        - DBIC_TRACE_PROFILE=console
 +        - BREWVER=5.16.3
 +        - BREWOPTS="-Duseithreads -Dusemorebits"
  
 -    - perl: 5.18
 +    - perl: "5.18-extras"
 +      sudo: required
 +      # explicit new infra spec preparing for a future forced upgrade
 +      dist: trusty
        env:
          - CLEANTEST=false
          - POISON_ENV=true
          - DBIC_TRACE=1
          - DBIC_TRACE_PROFILE=console_monochrome
 -        - DBIC_MULTICREATE_DEBUG=0
 +        - DBICTEST_VIA_REPLICATED=0
 +        - DBICTEST_VERSION_WARNS_INDISCRIMINATELY=1
  
      ###
      # Start of the allow_failures block
  
 -    # old threaded with blead CPAN
 -    - perl: devcpan_5.8.7_thr
 +    # threaded oldest possible with blead CPAN
 +    - perl: "devcpan_5.8.1_thr_mb"
 +      sudo: false
 +      dist: precise
        env:
          - CLEANTEST=true
 -        - BREWOPTS="-Duseithreads"
 -        - BREWVER=5.8.7
          - DEVREL_DEPS=true
 +        - BREWVER=5.8.1
 +        - BREWOPTS="-Duseithreads -Dusemorebits"
  
 -    # 5.10.0 threaded with blead CPAN
 -    - perl: devcpan_5.10.0_thr_mb
 +    # oldest possible with blead CPAN with poisoning and plain trace
 +    - perl: "devcpan_5.8.1"
 +      sudo: false
 +      dist: precise
        env:
          - CLEANTEST=true
 -        - BREWOPTS="-Duseithreads -Dusemorebits"
 -        - BREWVER=5.10.0
          - DEVREL_DEPS=true
 +        - POISON_ENV=true
 +        - DBIC_TRACE=1
 +        - DBICTEST_VERSION_WARNS_INDISCRIMINATELY=1
 +        - BREWVER=5.8.1
 +
 +    # 5.8.3 with blead CPAN
 +    - perl: "devcpan_5.8.3_mb"
 +      sudo: required
 +      # explicit new infra spec preparing for a future forced upgrade
 +      dist: trusty
 +      env:
 +        - CLEANTEST=false
 +        - DEVREL_DEPS=true
 +        - BREWVER=5.8.3
 +        - BREWOPTS="-Dusemorebits"
  
 -    # 5.12.2 with blead CPAN
 -    - perl: devcpan_5.12.2_thr
 +    # 5.8.7 threaded with blead CPAN with non-tracing poisoning
 +    - perl: "devcpan_5.8.7_thr"
 +      sudo: false
 +      dist: precise
        env:
          - CLEANTEST=true
 +        - DEVREL_DEPS=true
 +        - POISON_ENV=true
 +        - BREWVER=5.8.7
          - BREWOPTS="-Duseithreads"
 -        - BREWVER=5.12.2
 +
 +    # 5.8.8 threaded MB (exercises P5#72210)
 +    - perl: "devcpan_5.8.8_thr_mb"
 +      sudo: false
 +      dist: precise
 +      env:
 +        - CLEANTEST=true
 +        - DBICTEST_VERSION_WARNS_INDISCRIMINATELY=1
          - DEVREL_DEPS=true
 +        - BREWVER=5.8.8
 +        - BREWOPTS="-Duseithreads -Dusemorebits"
  
 -    # recentish threaded stable with blead CPAN
 -    - perl: devcpan_5.18.2_thr_mb
 +    # 5.10.0 threaded with blead CPAN
 +    - perl: "devcpan_5.10.0_thr_mb"
 +      sudo: false
 +      dist: precise
        env:
 -        - CLEANTEST=false
 +        - CLEANTEST=true
 +        - DEVREL_DEPS=true
 +        - BREWVER=5.10.0
          - BREWOPTS="-Duseithreads -Dusemorebits"
 -        - BREWVER=5.18.2
 +
 +    # 5.12.1 with blead CPAN
 +    - perl: "devcpan_5.12.1_thr"
 +      sudo: false
 +      dist: precise
 +      env:
 +        - CLEANTEST=true
          - DEVREL_DEPS=true
 +        - BREWVER=5.12.1
 +        - BREWOPTS="-Duseithreads"
  
 -    # bleadperl with stock CPAN, full depchain test
 -    - perl: bleadperl
 +    # bleadperl with stock CPAN, full depchain test with non-tracing poisoning, single thread
 +    - perl: "bleadperl"
 +      sudo: required
 +      dist: precise
        env:
 +        - VCPU_USE=1
          - CLEANTEST=true
 +        - POISON_ENV=true
          - BREWVER=blead
  
 -    # bleadperl with blead CPAN
 -    - perl: devcpan_bleadperl_thr_mb
 +    # bleadperl with blead CPAN, single thread
 +    - perl: "devcpan_bleadperl_thr_mb"
 +      sudo: required
 +      # explicitly do not specify dist - see what the default does
        env:
 +        - VCPU_USE=1
          - CLEANTEST=false
 -        - BREWOPTS="-Duseithreads -Dusemorebits"
 -        - BREWVER=blead
          - DEVREL_DEPS=true
 +        - BREWVER=blead
 +        - BREWOPTS="-Duseithreads -Dusemorebits"
  
 +    # CLEANTEST of http://schplog.schmorp.de/2015-06-06-a-stable-perl.html with non-tracing poisoning
 +    - perl: "schmorp_stableperl_thr_mb"
 +      sudo: false
 +      dist: precise
 +      env:
 +        - CLEANTEST=true
 +        - POISON_ENV=true
 +        - BREWVER=schmorp_stableperl
 +        - BREWOPTS="-Duseithreads -Dusemorebits"
  
    # which ones of the above can fail
    allow_failures:
  
      # these run with various dev snapshots - allowed to fail
 +    - perl: devcpan_5.8.1_thr_mb
 +    - perl: devcpan_5.8.1
 +    - perl: devcpan_5.8.3_mb
      - perl: devcpan_5.8.7_thr
 +    - perl: devcpan_5.8.8_thr_mb
      - perl: devcpan_5.10.0_thr_mb
 -    - perl: devcpan_5.12.2_thr
 -    - perl: devcpan_5.18.2_thr_mb
 +    - perl: devcpan_5.12.1_thr
      - perl: bleadperl
      - perl: devcpan_bleadperl_thr_mb
 +    - perl: schmorp_stableperl_thr_mb
  
  
 -# sourcing the files is *EXTREMELY* important - otherwise
 -# no envvars will survive
 -
 -# the entire run times out after 50 minutes, or after 5 minutes without
 -# console output
 +###
 +### For the following two phases -e is *set*
 +###
  
  before_install:
 +  # common functions for all run phases below
 +  #
 +  # this is an exporter - sourcing it is crucial
 +  # among other things it also sets -e
 +  #
 +  - source maint/travis-ci_scripts/common.bash
 +
    # Sets global envvars, downloads/configures debs based on CLEANTEST
    # Sets extra DBICTEST_* envvars
    #
 +  # this is an exporter - sourcing it is crucial
 +  #
    - source maint/travis-ci_scripts/10_before_install.bash
  
  install:
    # Build and switch to a custom perl if requested
    # Configure the perl env, preinstall some generic toolchain parts
 +  # Possibly poison the environment
 +  #
 +  # this is an exporter - sourcing it is crucial
    #
    - source maint/travis-ci_scripts/20_install.bash
  
 +###
 +### From this point on -e is *unset*, rely on travis' error handling
 +###
 +  - set +e
 +
  before_script:
    # Preinstall/install deps based on envvars/CLEANTEST
    #
 -  - source maint/travis-ci_scripts/30_before_script.bash
 +  # need to invoke the after_failure script manually
 +  # because 'after_failure' runs only after 'script' fails
 +  #
 +  - maint/getstatus maint/travis-ci_scripts/30_before_script.bash
  
  script:
    # Run actual tests
    #
 -  - source maint/travis-ci_scripts/40_script.bash
 +  - maint/getstatus maint/travis-ci_scripts/40_script.bash
 +
 +###
 +### Set -e back, work around https://github.com/travis-ci/travis-ci/issues/3533
 +###
 +  - set -e
  
  after_success:
    # Check if we can assemble a dist properly if not in CLEANTEST
    #
 -  - source maint/travis-ci_scripts/50_after_success.bash
 +  - maint/getstatus maint/travis-ci_scripts/50_after_success.bash
  
  after_failure:
 -  # No tasks yet
 +  # Final sysinfo printout on fail
    #
 -  #- source maint/travis-ci_scripts/50_after_failure.bash
 +  - maint/getstatus maint/travis-ci_scripts/50_after_failure.bash
  
  after_script:
    # No tasks yet
    #
 -  #- source maint/travis-ci_scripts/60_after_script.bash
 -
 -  # if we do not unset this before we terminate the travis teardown will
 -  # mark the entire job as failed
 -  - set +e
 +  #- maint/getstatus maint/travis-ci_scripts/60_after_script.bash
diff --combined lib/DBIx/Class.pm
@@@ -11,7 -11,7 +11,7 @@@ our $VERSION
  # $VERSION declaration must stay up here, ahead of any other package
  # declarations, as to not confuse various modules attempting to determine
  # this ones version, whether that be s.c.o. or Module::Metadata, etc
 -$VERSION = '0.08270';
 +$VERSION = '0.082899_15';
  
  $VERSION = eval $VERSION if $VERSION =~ /_/; # numify for warning-free dev releases
  
@@@ -25,19 -25,7 +25,19 @@@ use DBIx::Class::StartupCheck
  use DBIx::Class::Exception;
  
  __PACKAGE__->mk_group_accessors(inherited => '_skip_namespace_frames');
 -__PACKAGE__->_skip_namespace_frames('^DBIx::Class|^SQL::Abstract|^Try::Tiny|^Class::Accessor::Grouped|^Context::Preserve');
 +__PACKAGE__->_skip_namespace_frames('^DBIx::Class|^SQL::Abstract|^Try::Tiny|^Class::Accessor::Grouped|^Context::Preserve|^Moose::Meta::');
 +
 +# FIXME - this is not really necessary, and is in
 +# fact going to slow things down a bit
 +# However it is the right thing to do in order to get
 +# various install bases to highlight their brokenness
 +# Remove at some unknown point in the future
 +#
 +# The oddball BEGIN is there for... reason unknown
 +# It does make non-segfaulty difference on pre-5.8.5 perls, so shrug
 +BEGIN {
 +  sub DESTROY { &DBIx::Class::_Util::detected_reinvoked_destructor };
 +}
  
  sub mk_classdata {
    shift->mk_classaccessor(@_);
@@@ -69,16 -57,12 +69,16 @@@ sub _attr_cache 
    };
  }
  
 +# *DO NOT* change this URL nor the identically named =head1 below
 +# it is linked throughout the ecosystem
 +sub DBIx::Class::_ENV_::HELP_URL () {
 +  'http://p3rl.org/DBIx::Class#GETTING_HELP/SUPPORT'
 +}
 +
  1;
  
  __END__
  
 -=encoding UTF-8
 -
  =head1 NAME
  
  DBIx::Class - Extensible and flexible object <-> relational mapper.
@@@ -90,15 -74,13 +90,15 @@@ To get the most out of DBIx::Class wit
  recommended to read (at the very least) the
  L<Manuals|DBIx::Class::Manual::DocMap/Manuals> in the order presented there.
  
 -=head1 HOW TO GET HELP
 +=cut
 +
 +=head1 GETTING HELP/SUPPORT
  
 -Due to the complexity of its problem domain, DBIx::Class is a relatively
 +Due to the sheer size of its problem domain, DBIx::Class is a relatively
  complex framework. After you start using DBIx::Class questions will inevitably
  arise. If you are stuck with a problem or have doubts about a particular
 -approach do not hesitate to contact the community with your questions. The
 -list below is sorted by "fastest response time":
 +approach do not hesitate to contact us via any of the following options (the
 +list is sorted by "fastest response time"):
  
  =over
  
@@@ -214,7 -196,7 +214,7 @@@ Then you can use these classes in your 
    my $cd = $millennium_cds_rs->next; # SELECT ... FROM cds JOIN artists ...
    my $cd_artist_name = $cd->artist->name; # Already has the data so no 2nd query
  
 -  # new() makes a Result object but doesnt insert it into the DB.
 +  # new() makes a Result object but doesn't insert it into the DB.
    # create() is the same as new() then insert().
    my $new_cd = $schema->resultset('CD')->new({ title => 'Spoon' });
    $new_cd->artist($cd->artist);
@@@ -267,10 -249,8 +267,10 @@@ Contributions are always welcome, in al
  welcome documentation improvements). The delivery methods include git-
  or unified-diff formatted patches, GitHub pull requests, or plain bug
  reports either via RT or the Mailing list. Contributors are generally
 -granted full access to the official repository after their first patch
 -passes successful review.
 +granted access to the official repository after their first several
 +patches pass successful review. Don't hesitate to
 +L<contact|/GETTING HELP/SUPPORT> either of the L</CAT HERDERS> with
 +any further questions you may have.
  
  =for comment
  FIXME: Getty, frew and jnap need to get off their asses and finish the contrib section so we can link it here ;)
@@@ -291,48 -271,283 +291,48 @@@ accessible at the following locations
  =item * Travis-CI log: L<https://travis-ci.org/dbsrgits/dbix-class/builds>
  
  =for html
--&#x21AA; Stable branch CI status: <img src="https://secure.travis-ci.org/dbsrgits/dbix-class.png?branch=master"></img>
++&#x21AA; Bleeding edge dev CI status: <img src="https://secure.travis-ci.org/dbsrgits/dbix-class.png?branch=master"></img>
  
  =back
  
 -=head1 AUTHOR
 -
 -mst: Matt S. Trout <mst@shadowcatsystems.co.uk>
 -
 -(I mostly consider myself "project founder" these days but the AUTHOR heading
 -is traditional :)
 -
 -=head1 CONTRIBUTORS
 -
 -abraxxa: Alexander Hartmaier <abraxxa@cpan.org>
 -
 -acca: Alexander Kuznetsov <acca@cpan.org>
 -
 -aherzog: Adam Herzog <adam@herzogdesigns.com>
 -
 -Alexander Keusch <cpan@keusch.at>
 -
 -alexrj: Alessandro Ranellucci <aar@cpan.org>
 -
 -alnewkirk: Al Newkirk <we@ana.im>
 -
 -amiri: Amiri Barksdale <amiri@metalabel.com>
 -
 -amoore: Andrew Moore <amoore@cpan.org>
 -
 -andrewalker: Andre Walker <andre@andrewalker.net>
 -
 -andyg: Andy Grundman <andy@hybridized.org>
 -
 -ank: Andres Kievsky
 -
 -arc: Aaron Crane <arc@cpan.org>
 -
 -arcanez: Justin Hunter <justin.d.hunter@gmail.com>
 -
 -ash: Ash Berlin <ash@cpan.org>
 -
 -bert: Norbert Csongrádi <bert@cpan.org>
 -
 -blblack: Brandon L. Black <blblack@gmail.com>
 -
 -bluefeet: Aran Deltac <bluefeet@cpan.org>
 -
 -bphillips: Brian Phillips <bphillips@cpan.org>
 -
 -boghead: Bryan Beeley <cpan@beeley.org>
 -
 -brd: Brad Davis <brd@FreeBSD.org>
 -
 -bricas: Brian Cassidy <bricas@cpan.org>
 -
 -brunov: Bruno Vecchi <vecchi.b@gmail.com>
 -
 -caelum: Rafael Kitover <rkitover@cpan.org>
 -
 -caldrin: Maik Hentsche <maik.hentsche@amd.com>
 -
 -castaway: Jess Robinson
 -
 -claco: Christopher H. Laco
 -
 -clkao: CL Kao
 -
 -da5id: David Jack Olrik <djo@cpan.org>
 -
 -dariusj: Darius Jokilehto <dariusjokilehto@yahoo.co.uk>
 -
 -davewood: David Schmidt <davewood@gmx.at>
 -
 -daxim: Lars Dɪᴇᴄᴋᴏᴡ 迪拉斯 <daxim@cpan.org>
 -
 -debolaz: Anders Nor Berle <berle@cpan.org>
 -
 -dew: Dan Thomas <dan@godders.org>
 -
 -dkubb: Dan Kubb <dan.kubb-cpan@onautopilot.com>
 -
 -dnm: Justin Wheeler <jwheeler@datademons.com>
 -
 -dpetrov: Dimitar Petrov <mitakaa@gmail.com>
 -
 -dwc: Daniel Westermann-Clark <danieltwc@cpan.org>
 -
 -dyfrgi: Michael Leuchtenburg <michael@slashhome.org>
 -
 -edenc: Eden Cardim <edencardim@gmail.com>
 -
 -ether: Karen Etheridge <ether@cpan.org>
 -
 -felliott: Fitz Elliott <fitz.elliott@gmail.com>
 -
 -freetime: Bill Moseley <moseley@hank.org>
 -
 -frew: Arthur Axel "fREW" Schmidt <frioux@gmail.com>
 -
 -goraxe: Gordon Irving <goraxe@cpan.org>
 -
 -gphat: Cory G Watson <gphat@cpan.org>
 -
 -Grant Street Group L<http://www.grantstreet.com/>
 -
 -groditi: Guillermo Roditi <groditi@cpan.org>
 -
 -Haarg: Graham Knop <haarg@haarg.org>
 -
 -hobbs: Andrew Rodland <arodland@cpan.org>
 -
 -ilmari: Dagfinn Ilmari MannsE<aring>ker <ilmari@ilmari.org>
 -
 -initself: Mike Baas <mike@initselftech.com>
 -
 -ironcamel: Naveed Massjouni <naveedm9@gmail.com>
 -
 -jawnsy: Jonathan Yu <jawnsy@cpan.org>
 -
 -jasonmay: Jason May <jason.a.may@gmail.com>
 -
 -jesper: Jesper Krogh
 -
 -jgoulah: John Goulah <jgoulah@cpan.org>
 -
 -jguenther: Justin Guenther <jguenther@cpan.org>
 +=head1 AUTHORS
  
 -jhannah: Jay Hannah <jay@jays.net>
 +Even though a large portion of the source I<appears> to be written by just a
 +handful of people, this library continues to remain a collaborative effort -
 +perhaps one of the most successful such projects on L<CPAN|http://cpan.org>.
 +It is important to remember that ideas do not always result in a direct code
 +contribution, but deserve acknowledgement just the same. Time and time again
 +the seemingly most insignificant questions and suggestions have been shown
 +to catalyze monumental improvements in consistency, accuracy and performance.
  
 -jmac: Jason McIntosh <jmac@appleseed-sc.com>
 +=for comment this line is replaced with the author list at dist-building time
  
 -jnapiorkowski: John Napiorkowski <jjn1056@yahoo.com>
 +The canonical source of authors and their details is the F<AUTHORS> file at
 +the root of this distribution (or repository). The canonical source of
 +per-line authorship is the L<git repository|/HOW TO CONTRIBUTE> history
 +itself.
  
 -jon: Jon Schutz <jjschutz@cpan.org>
 +=head1 CAT HERDERS
  
 -jshirley: J. Shirley <jshirley@gmail.com>
 +The fine folks nudging the project in a particular direction:
  
 -kaare: Kaare Rasmussen
 -
 -konobi: Scott McWhirter
 -
 -littlesavage: Alexey Illarionov <littlesavage@orionet.ru>
 -
 -lukes: Luke Saunders <luke.saunders@gmail.com>
 -
 -marcus: Marcus Ramberg <mramberg@cpan.org>
 -
 -mattlaw: Matt Lawrence
 -
 -mattp: Matt Phillips <mattp@cpan.org>
 -
 -michaelr: Michael Reddick <michael.reddick@gmail.com>
 -
 -milki: Jonathan Chu <milki@rescomp.berkeley.edu>
 -
 -mithaldu: Christian Walde <walde.christian@gmail.com>
 -
 -mjemmeson: Michael Jemmeson <michael.jemmeson@gmail.com>
 -
 -mstratman: Mark A. Stratman <stratman@gmail.com>
 -
 -ned: Neil de Carteret
 -
 -nigel: Nigel Metheringham <nigelm@cpan.org>
 -
 -ningu: David Kamholz <dkamholz@cpan.org>
 -
 -Nniuq: Ron "Quinn" Straight" <quinnfazigu@gmail.org>
 -
 -norbi: Norbert Buchmuller <norbi@nix.hu>
 -
 -nuba: Nuba Princigalli <nuba@cpan.org>
 -
 -Numa: Dan Sully <daniel@cpan.org>
 -
 -ovid: Curtis "Ovid" Poe <ovid@cpan.org>
 -
 -oyse: E<Oslash>ystein Torget <oystein.torget@dnv.com>
 -
 -paulm: Paul Makepeace
 -
 -penguin: K J Cheetham
 -
 -perigrin: Chris Prather <chris@prather.org>
 -
 -peter: Peter Collingbourne <peter@pcc.me.uk>
 -
 -Peter Siklósi <einon@einon.hu>
 -
 -Peter Valdemar ME<oslash>rch <peter@morch.com>
 -
 -phaylon: Robert Sedlacek <phaylon@dunkelheit.at>
 -
 -plu: Johannes Plunien <plu@cpan.org>
 -
 -Possum: Daniel LeWarne <possum@cpan.org>
 -
 -quicksilver: Jules Bean
 -
 -rafl: Florian Ragwitz <rafl@debian.org>
 -
 -rainboxx: Matthias Dietrich <perl@rb.ly>
 -
 -rbo: Robert Bohne <rbo@cpan.org>
 -
 -rbuels: Robert Buels <rmb32@cornell.edu>
 -
 -rdj: Ryan D Johnson <ryan@innerfence.com>
 -
 -ribasushi: Peter Rabbitson <ribasushi@cpan.org>
 -
 -rjbs: Ricardo Signes <rjbs@cpan.org>
 -
 -robkinyon: Rob Kinyon <rkinyon@cpan.org>
 -
 -Robert Olson <bob@rdolson.org>
 -
 -moltar: Roman Filippov <romanf@cpan.org>
 -
 -Sadrak: Felix Antonius Wilhelm Ostmann <sadrak@cpan.org>
 -
 -sc_: Just Another Perl Hacker
 -
 -scotty: Scotty Allen <scotty@scottyallen.com>
 -
 -semifor: Marc Mims <marc@questright.com>
 -
 -SineSwiper: Brendan Byrd <bbyrd@cpan.org>
 -
 -solomon: Jared Johnson <jaredj@nmgi.com>
 -
 -spb: Stephen Bennett <stephen@freenode.net>
 -
 -Squeeks <squeek@cpan.org>
 -
 -sszabo: Stephan Szabo <sszabo@bigpanda.com>
 -
 -talexb: Alex Beamish <talexb@gmail.com>
 -
 -tamias: Ronald J Kimball <rjk@tamias.net>
 -
 -teejay : Aaron Trevena <teejay@cpan.org>
 -
 -Todd Lipcon
 -
 -Tom Hukins
 -
 -tonvoon: Ton Voon <tonvoon@cpan.org>
 -
 -triode: Pete Gamache <gamache@cpan.org>
 -
 -typester: Daisuke Murase <typester@cpan.org>
 -
 -victori: Victor Igumnov <victori@cpan.org>
 -
 -wdh: Will Hawes
 -
 -wesm: Wes Malone <wes@mitsi.com>
 -
 -willert: Sebastian Willert <willert@cpan.org>
 -
 -wreis: Wallace Reis <wreis@cpan.org>
 -
 -xenoterracide: Caleb Cushing <xenoterracide@gmail.com>
 +=over
  
 -yrlnry: Mark Jason Dominus <mjd@plover.com>
 +B<ribasushi>: Peter Rabbitson <ribasushi@cpan.org>
 +(present day maintenance and controlled evolution)
  
 -zamolxes: Bogdan Lucaciu <bogdan@wiz.ro>
 +B<castaway>: Jess Robinson <castaway@desert-island.me.uk>
 +(lions share of the reference documentation and manuals)
  
 -Zefram: Andrew Main <zefram@fysh.org>
 +B<mst>: Matt S Trout <mst@shadowcat.co.uk> (project founder -
 +original idea, architecture and implementation)
  
 -=head1 COPYRIGHT
 +=back
  
 -Copyright (c) 2005 - 2011 the DBIx::Class L</AUTHOR> and L</CONTRIBUTORS>
 -as listed above.
 +=head1 COPYRIGHT AND LICENSE
  
 -=head1 LICENSE
 +Copyright (c) 2005 by mst, castaway, ribasushi, and other DBIx::Class
 +L</AUTHORS> as listed above and in F<AUTHORS>.
  
  This library is free software and may be distributed under the same terms
 -as perl itself.
 +as perl5 itself. See F<LICENSE> for the complete licensing terms.
@@@ -9,13 -9,13 +9,13 @@@ DBIx::Class::SQLMaker - An SQL::Abstrac
  
  =head1 DESCRIPTION
  
 -This module is a subclass of L<SQL::Abstract> and includes a number of
 -DBIC-specific workarounds, not yet suitable for inclusion into the
 +This module is currently a subclass of L<SQL::Abstract> and includes a number of
 +DBIC-specific extensions/workarounds, not suitable for inclusion into the
  L<SQL::Abstract> core. It also provides all (and more than) the functionality
  of L<SQL::Abstract::Limit>, see L<DBIx::Class::SQLMaker::LimitDialects> for
  more info.
  
 -Currently the enhancements to L<SQL::Abstract> are:
 +Currently the enhancements over L<SQL::Abstract> are:
  
  =over
  
  
  =item * C<GROUP BY>/C<HAVING> support (via extensions to the order_by parameter)
  
 +=item * A rudimentary multicolumn IN operator
 +
  =item * Support of C<...FOR UPDATE> type of select statement modifiers
  
  =back
  
 +=head1 ROADMAP
 +
 +Some maintainer musings on the current state of SQL generation within DBIC as
 +of Oct 2015
 +
 +=head2 Folding of most (or all) of L<SQL::Abstract (SQLA)|SQL::Abstract> into DBIC
 +
 +The rise of complex prefetch use, and the general streamlining of result
 +parsing within DBIC ended up pushing the actual SQL generation to the forefront
 +of many casual performance profiles. While the idea behind SQLA's API is sound,
 +the actual implementation is terribly inefficient (once again bumping into the
 +ridiculously high overhead of perl function calls).
 +
 +Given that SQLA has a B<very> distinct life on its own, and is used within an
 +order of magnitude more projects compared to DBIC, it is prudent to B<not>
 +disturb the current call chains within SQLA itself. Instead in the near future
 +an effort will be undertaken to seek a more thorough decoupling of DBIC SQL
 +generation from reliance on SQLA, possibly to a point where B<DBIC will no
 +longer depend on SQLA> at all.
 +
 +B<The L<SQL::Abstract> library itself will continue being maintained> although
 +it is not likely to gain many extra features, notably dialect support, at least
 +not within the base C<SQL::Abstract> namespace.
 +
 +This work (if undertaken) will take into consideration the following
 +constraints:
 +
 +=over
 +
 +=item Main API compatibility
 +
 +The object returned by C<< $schema->storage->sqlmaker >> needs to be able to
 +satisfy most of the basic tests found in the current-at-the-time SQLA dist.
 +While things like L<case|SQL::Abstract/case> or L<logic|SQL::Abstract/logic>
 +or even worse L<convert|SQL::Abstract/convert> will definitely remain
 +unsupported, the rest of the tests should pass (within reason).
 +
 +=item Ability to plug back an SQL::Abstract (or derivative)
 +
 +During the initial work on L<Data::Query> the test suite of DBIC turned out to
 +be an invaluable asset to iron out hard-to-reason-about corner cases. In
 +addition the test suite is much more vast and intricate than the tests of SQLA
 +itself. This state of affairs is way too valuable to sacrifice in order to gain
 +faster SQL generation. Thus a compile-time-ENV-check will be introduced along
 +with an extra CI configuration to ensure that DBIC is used with an off-the-CPAN
 +SQLA and that it continues to flawlessly run its entire test suite. While this
 +will undoubtedly complicate the implementation of the better performing SQL
 +generator, it will preserve both the usability of the test suite for external
 +projects and will keep L<SQL::Abstract> from regressions in the future.
 +
 +=back
 +
 +Aside from these constraints it is becoming more and more practical to simply
 +stop using SQLA in day-to-day production deployments of DBIC. The flexibility
 +of the internals is simply not worth the performance cost.
 +
 +=head2 Relationship to L<Data::Query (DQ)|Data::Query>
 +
 +When initial work on DQ was taking place, the tools in L<::Storage::DBIHacks
- |http://github.com/dbsrgits/dbix-class/blob/current/blead/lib/DBIx/Class/Storage/DBIHacks.pm>
++|http://github.com/dbsrgits/dbix-class/blob/master/lib/DBIx/Class/Storage/DBIHacks.pm>
 +were only beginning to take shape, and it wasn't clear how important they will
 +become further down the road. In fact the I<regexing all over the place> was
 +considered an ugly stop-gap, and even a couple of highly entertaining talks
 +were given to that effect. As the use-cases of DBIC were progressing, and
 +evidence for the importance of supporting arbitrary SQL was mounting, it became
 +clearer that DBIC itself would not really benefit in any way from an
 +integration with DQ, but on the contrary is likely to lose functionality while
 +the corners of the brand new DQ codebase are sanded off.
 +
 +The current status of DBIC/DQ integration is that the only benefit is for DQ by
 +having access to the very extensive "early adopter" test suite, in the same
 +manner as early DBIC benefitted tremendously from usurping the Class::DBI test
 +suite. As far as the DBIC user-base - there are no immediate practical upsides
 +to DQ integration, neither in terms of API nor in performance.
 +
 +So (as described higher up) the DBIC development effort will in the foreseable
 +future ignore the existence of DQ, and will continue optimizing the preexisting
 +SQLA-based solution, potentially "organically growing" its own compatible
 +implementation. Also (again, as described higher up) the ability to plug a
 +separate SQLA-compatible class providing the necessary surface API will remain
 +possible, and will be protected at all costs in order to continue providing DQ
 +access to the test cases of DBIC.
 +
 +In the short term, after one more pass over the ResultSet internals is
 +undertaken I<real soon now (tm)>, and before the SQLA/SQLMaker integration
 +takes place, the preexisting DQ-based branches will be pulled/modified/rebased
 +to get up-to-date with the current state of the codebase, which changed very
 +substantially since the last migration effort, especially in the SQL
 +classification meta-parsing codepath.
 +
  =cut
  
  use base qw/
@@@ -136,16 -44,8 +136,16 @@@ use namespace::clean
  
  __PACKAGE__->mk_group_accessors (simple => qw/quote_char name_sep limit_dialect/);
  
 +sub _quoting_enabled {
 +  ( defined $_[0]->{quote_char} and length $_[0]->{quote_char} ) ? 1 : 0
 +}
 +
  # for when I need a normalized l/r pair
  sub _quote_chars {
 +
 +  # in case we are called in the old !!$sm->_quote_chars fashion
 +  return () if !wantarray and ( ! defined $_[0]->{quote_char} or ! length $_[0]->{quote_char} );
 +
    map
      { defined $_ ? $_ : '' }
      ( ref $_[0]->{quote_char} ? (@{$_[0]->{quote_char}}) : ( ($_[0]->{quote_char}) x 2 ) )
@@@ -210,17 -110,17 +210,17 @@@ sub select 
    my ($self, $table, $fields, $where, $rs_attrs, $limit, $offset) = @_;
  
  
 -  $fields = $self->_recurse_fields($fields);
 +  ($fields, @{$self->{select_bind}}) = $self->_recurse_fields($fields);
  
    if (defined $offset) {
      $self->throw_exception('A supplied offset must be a non-negative integer')
 -      if ( $offset =~ /\D/ or $offset < 0 );
 +      if ( $offset =~ /[^0-9]/ or $offset < 0 );
    }
    $offset ||= 0;
  
    if (defined $limit) {
      $self->throw_exception('A supplied limit must be a positive integer')
 -      if ( $limit =~ /\D/ or $limit <= 0 );
 +      if ( $limit =~ /[^0-9]/ or $limit <= 0 );
    }
    elsif ($offset) {
      $limit = $self->__max_int;
      if( $limiter = $self->can ('emulate_limit') ) {
        carp_unique(
          'Support for the legacy emulate_limit() mechanism inherited from '
 -      . 'SQL::Abstract::Limit has been deprecated, and will be removed when '
 -      . 'DBIC transitions to Data::Query. If your code uses this type of '
 +      . 'SQL::Abstract::Limit has been deprecated, and will be removed at '
 +      . 'some future point, as it gets in the way of architectural and/or '
 +      . 'performance advances within DBIC. If your code uses this type of '
        . 'limit specification please file an RT and provide the source of '
        . 'your emulate_limit() implementation, so an acceptable upgrade-path '
        . 'can be devised'
@@@ -304,9 -203,9 +304,9 @@@ sub insert 
  # optimized due to hotttnesss
  #  my ($self, $table, $data, $options) = @_;
  
 -  # SQLA will emit INSERT INTO $table ( ) VALUES ( )
 +  # FIXME SQLA will emit INSERT INTO $table ( ) VALUES ( )
    # which is sadly understood only by MySQL. Change default behavior here,
 -  # until SQLA2 comes with proper dialect support
 +  # until we fold the extra pieces into SQLMaker properly
    if (! $_[2] or (ref $_[2] eq 'HASH' and !keys %{$_[2]} ) ) {
      my @bind;
      my $sql = sprintf(
@@@ -332,47 -231,42 +332,47 @@@ sub _recurse_fields 
    return $$fields if $ref eq 'SCALAR';
  
    if ($ref eq 'ARRAY') {
 -    return join(', ', map { $self->_recurse_fields($_) } @$fields);
 +    my (@select, @bind);
 +    for my $field (@$fields) {
 +      my ($select, @new_bind) = $self->_recurse_fields($field);
 +      push @select, $select;
 +      push @bind, @new_bind;
 +    }
 +    return (join(', ', @select), @bind);
    }
    elsif ($ref eq 'HASH') {
      my %hash = %$fields;  # shallow copy
  
      my $as = delete $hash{-as};   # if supplied
  
 -    my ($func, $args, @toomany) = %hash;
 +    my ($func, $rhs, @toomany) = %hash;
  
      # there should be only one pair
      if (@toomany) {
        $self->throw_exception( "Malformed select argument - too many keys in hash: " . join (',', keys %$fields ) );
      }
  
 -    if (lc ($func) eq 'distinct' && ref $args eq 'ARRAY' && @$args > 1) {
 +    if (lc ($func) eq 'distinct' && ref $rhs eq 'ARRAY' && @$rhs > 1) {
        $self->throw_exception (
          'The select => { distinct => ... } syntax is not supported for multiple columns.'
 -       .' Instead please use { group_by => [ qw/' . (join ' ', @$args) . '/ ] }'
 -       .' or { select => [ qw/' . (join ' ', @$args) . '/ ], distinct => 1 }'
 +       .' Instead please use { group_by => [ qw/' . (join ' ', @$rhs) . '/ ] }'
 +       .' or { select => [ qw/' . (join ' ', @$rhs) . '/ ], distinct => 1 }'
        );
      }
  
 +    my ($rhs_sql, @rhs_bind) = $self->_recurse_fields($rhs);
      my $select = sprintf ('%s( %s )%s',
        $self->_sqlcase($func),
 -      $self->_recurse_fields($args),
 +      $rhs_sql,
        $as
          ? sprintf (' %s %s', $self->_sqlcase('as'), $self->_quote ($as) )
          : ''
      );
  
 -    return $select;
 +    return ($select, @rhs_bind);
    }
 -  # Is the second check absolutely necessary?
    elsif ( $ref eq 'REF' and ref($$fields) eq 'ARRAY' ) {
 -    push @{$self->{select_bind}}, @{$$fields}[1..$#$$fields];
 -    return $$fields->[0];
 +    return @{$$fields};
    }
    else {
      $self->throw_exception( $ref . qq{ unexpected in _recurse_fields()} );
  # things in the SQLA space need to have more info about the $rs they
  # create SQL for. The alternative would be to keep expanding the
  # signature of _select with more and more positional parameters, which
 -# is just gross. All hail SQLA2!
 +# is just gross.
 +#
 +# FIXME - this will have to transition out to a subclass when the effort
 +# of folding the SQLA machinery into SQLMaker takes place
  sub _parse_rs_attrs {
    my ($self, $arg) = @_;
  
    my $sql = '';
 +  my @sqlbind;
  
 -  if ($arg->{group_by}) {
 -    # horrible horrible, waiting for refactor
 -    local $self->{select_bind};
 -    if (my $g = $self->_recurse_fields($arg->{group_by}) ) {
 -      $sql .= $self->_sqlcase(' group by ') . $g;
 -      push @{$self->{group_bind} ||= []}, @{$self->{select_bind}||[]};
 -    }
 +  if (
 +    $arg->{group_by}
 +      and
 +    @sqlbind = $self->_recurse_fields($arg->{group_by})
 +  ) {
 +    $sql .= $self->_sqlcase(' group by ') . shift @sqlbind;
 +    push @{$self->{group_bind}}, @sqlbind;
    }
  
 -  if (defined $arg->{having}) {
 -    my ($frag, @bind) = $self->_recurse_where($arg->{having});
 -    push(@{$self->{having_bind}}, @bind);
 -    $sql .= $self->_sqlcase(' having ') . $frag;
 +  if (
 +    $arg->{having}
 +      and
 +    @sqlbind = $self->_recurse_where($arg->{having})
 +  ) {
 +    $sql .= $self->_sqlcase(' having ') . shift @sqlbind;
 +    push(@{$self->{having_bind}}, @sqlbind);
    }
  
 -  if (defined $arg->{order_by}) {
 +  if ($arg->{order_by}) {
 +    # unlike the 2 above, _order_by injects into @{...bind...} for us
      $sql .= $self->_order_by ($arg->{order_by});
    }
  
@@@ -427,18 -313,14 +427,18 @@@ sub _order_by 
    my ($self, $arg) = @_;
  
    # check that we are not called in legacy mode (order_by as 4th argument)
 -  if (ref $arg eq 'HASH' and not grep { $_ =~ /^-(?:desc|asc)/i } keys %$arg ) {
 -    return $self->_parse_rs_attrs ($arg);
 -  }
 -  else {
 -    my ($sql, @bind) = $self->next::method($arg);
 -    push @{$self->{order_bind}}, @bind;
 -    return $sql;
 -  }
 +  (
 +    ref $arg eq 'HASH'
 +      and
 +    not grep { $_ =~ /^-(?:desc|asc)/i } keys %$arg
 +  )
 +    ? $self->_parse_rs_attrs ($arg)
 +    : do {
 +      my ($sql, @bind) = $self->next::method($arg);
 +      push @{$self->{order_bind}}, @bind;
 +      $sql; # RV
 +    }
 +  ;
  }
  
  sub _split_order_chunk {
@@@ -559,6 -441,8 +559,6 @@@ sub _join_condition 
  
    # Backcompat for the old days when a plain hashref
    # { 't1.col1' => 't2.col2' } meant ON t1.col1 = t2.col2
 -  # Once things settle we should start warning here so that
 -  # folks unroll their hacks
    if (
      ref $cond eq 'HASH'
        and
        and
      ! ref ( (values %$cond)[0] )
    ) {
 +    carp_unique(
 +      "ResultSet {from} structures with conditions not conforming to the "
 +    . "SQL::Abstract syntax are deprecated: you either need to stop abusing "
 +    . "{from} altogether, or express the condition properly using the "
 +    . "{ -ident => ... } operator"
 +    );
      $cond = { keys %$cond => { -ident => values %$cond } }
    }
    elsif ( ref $cond eq 'ARRAY' ) {
    return $self->_recurse_where($cond);
  }
  
 -# This is hideously ugly, but SQLA does not understand multicol IN expressions
 -# FIXME TEMPORARY - DQ should have native syntax for this
 -# moved here to raise API questions
 +# !!! EXPERIMENTAL API !!! WILL CHANGE !!!
 +#
 +# This is rather odd, but vanilla SQLA does not have support for multicolumn IN
 +# expressions
 +# Currently has only one callsite in ResultSet, body moved into this subclass
 +# of SQLA to raise API questions like:
 +# - how do we convey a list of idents...?
 +# - can binds reside on lhs?
  #
  # !!! EXPERIMENTAL API !!! WILL CHANGE !!!
  sub _where_op_multicolumn_in {
    \[ join( ' IN ', shift @$$lhs, shift @$$rhs ), @$$lhs, @$$rhs ];
  }
  
 -1;
 -
 -=head1 AUTHORS
 +=head1 FURTHER QUESTIONS?
  
 -See L<DBIx::Class/CONTRIBUTORS>.
 +Check the list of L<additional DBIC resources|DBIx::Class/GETTING HELP/SUPPORT>.
  
 -=head1 LICENSE
 +=head1 COPYRIGHT AND LICENSE
  
 -You may distribute this code under the same terms as Perl itself.
 +This module is free software L<copyright|DBIx::Class/COPYRIGHT AND LICENSE>
 +by the L<DBIx::Class (DBIC) authors|DBIx::Class/AUTHORS>. You can
 +redistribute it and/or modify it under the same terms as the
 +L<DBIx::Class library|DBIx::Class/COPYRIGHT AND LICENSE>.
  
  =cut
 +
 +1;