Merge 'trunk' into 'pri_key_refactor'
Peter Rabbitson [Sun, 14 Feb 2010 10:41:14 +0000 (10:41 +0000)]
r8510@Thesaurus (orig r8497):  caelum | 2010-02-01 12:07:13 +0100
throw exception on attempt to insert a blob with DBD::Oracle == 1.23
r8511@Thesaurus (orig r8498):  caelum | 2010-02-01 12:12:48 +0100
add RT link for Oracle blob bug in DBD::Oracle == 1.23
r8527@Thesaurus (orig r8514):  caelum | 2010-02-02 23:20:17 +0100
 r22968@hlagh (orig r8502):  caelum | 2010-02-02 05:30:47 -0500
 branch to support Sybase SQL Anywhere
 r22971@hlagh (orig r8505):  caelum | 2010-02-02 07:21:13 -0500
 ASA last_insert_id and limit support, still needs BLOB support
 r22972@hlagh (orig r8506):  caelum | 2010-02-02 08:33:57 -0500
 deref table name if needed, check all columns for identity column not just PK
 r22973@hlagh (orig r8507):  caelum | 2010-02-02 08:48:11 -0500
 test blobs, they work, didn't have to do anything
 r22974@hlagh (orig r8508):  caelum | 2010-02-02 09:15:44 -0500
 fix stupid identity bug, test empty insert (works), test DTs (not working yet)
 r22976@hlagh (orig r8510):  caelum | 2010-02-02 14:31:00 -0500
 rename ::Sybase::ASA to ::SQLAnywhere, per mst
 r22978@hlagh (orig r8512):  caelum | 2010-02-02 17:02:29 -0500
 DT inflation now works
 r22979@hlagh (orig r8513):  caelum | 2010-02-02 17:18:06 -0500
 minor POD update

r8528@Thesaurus (orig r8515):  caelum | 2010-02-02 23:23:26 +0100
 r22895@hlagh (orig r8473):  caelum | 2010-01-30 03:57:26 -0500
 branch to fix computed columns in Sybase ASE
 r22911@hlagh (orig r8489):  caelum | 2010-01-31 07:18:33 -0500
 empty insert into a Sybase table with computed columns and either data_type => undef or default_value => SCALARREF works now
 r22912@hlagh (orig r8490):  caelum | 2010-01-31 07:39:32 -0500
 add POD about computed columns and timestamps for Sybase
 r22918@hlagh (orig r8496):  caelum | 2010-02-01 05:09:07 -0500
 update POD about Schema::Loader for Sybase

r8531@Thesaurus (orig r8518):  ribasushi | 2010-02-02 23:57:27 +0100
 r8512@Thesaurus (orig r8499):  boghead | 2010-02-01 23:38:13 +0100
 - Creating a branch for adding _post_inflate_datetime and _pre_deflate_datetime to
   InflateColumn::DateTime

 r8513@Thesaurus (orig r8500):  boghead | 2010-02-01 23:42:14 +0100
 - Add _post_inflate_datetime and _pre_deflate_datetime to InflateColumn::DateTime to allow
   for modifying DateTime objects after inflation or before deflation.

 r8524@Thesaurus (orig r8511):  boghead | 2010-02-02 22:59:28 +0100
 - Simplify by allowing moving column_info depreciated {extra}{timezone} data to
   {timezone} (and the same with locale)

r8533@Thesaurus (orig r8520):  caelum | 2010-02-03 05:19:59 +0100
support for Sybase SQL Anywhere through ODBC
r8536@Thesaurus (orig r8523):  ribasushi | 2010-02-03 08:27:54 +0100
Changes
r8537@Thesaurus (orig r8524):  ribasushi | 2010-02-03 08:31:20 +0100
Quote fail
r8538@Thesaurus (orig r8525):  caelum | 2010-02-03 13:21:37 +0100
test DT inflation for Sybase SQL Anywhere over ODBC too
r8539@Thesaurus (orig r8526):  caelum | 2010-02-03 17:36:39 +0100
minor code cleanup for SQL Anywhere last_insert_id
r8540@Thesaurus (orig r8527):  ribasushi | 2010-02-04 11:28:33 +0100
Fix bug reported by tommyt
r8548@Thesaurus (orig r8535):  ribasushi | 2010-02-04 14:34:45 +0100
Prepare for new SQLA release
r8560@Thesaurus (orig r8547):  ribasushi | 2010-02-05 08:59:04 +0100
Refactor some evil code
r8565@Thesaurus (orig r8552):  ribasushi | 2010-02-05 17:00:12 +0100
Looks like RSC is finally (halfway) fixed
r8566@Thesaurus (orig r8553):  ribasushi | 2010-02-05 17:07:13 +0100
RSC subquery can not include the prefetch
r8567@Thesaurus (orig r8554):  ribasushi | 2010-02-05 17:10:29 +0100
Fix typo and borked test
r8569@Thesaurus (orig r8556):  ribasushi | 2010-02-05 17:33:12 +0100
Release 0.08116
r8571@Thesaurus (orig r8558):  ribasushi | 2010-02-05 18:01:33 +0100
No idea how I missed all these fails...
r8572@Thesaurus (orig r8559):  ribasushi | 2010-02-05 18:13:34 +0100
Release 0.08117
r8574@Thesaurus (orig r8561):  ribasushi | 2010-02-05 18:51:12 +0100
Try to distinguish trunk from official versions
r8580@Thesaurus (orig r8567):  gshank | 2010-02-05 22:29:24 +0100
add doc on 'where' attribute

r8587@Thesaurus (orig r8574):  frew | 2010-02-07 21:07:03 +0100
add as_subselect_rs
r8588@Thesaurus (orig r8575):  frew | 2010-02-07 21:13:04 +0100
fix longstanding unmentioned bug ("me")
r8589@Thesaurus (orig r8576):  frew | 2010-02-08 06:17:43 +0100
another example of as_subselect_rs
r8590@Thesaurus (orig r8577):  frew | 2010-02-08 06:23:58 +0100
fix bug in UTF8Columns
r8591@Thesaurus (orig r8578):  ribasushi | 2010-02-08 09:31:01 +0100
Extend utf8columns test to trap fixed bug
r8592@Thesaurus (orig r8579):  ribasushi | 2010-02-08 12:03:23 +0100
Cleanup rel accessor type handling
r8593@Thesaurus (orig r8580):  ribasushi | 2010-02-08 12:20:47 +0100
Fix some fallout
r8595@Thesaurus (orig r8582):  ribasushi | 2010-02-08 12:38:19 +0100
Merge some obsolete code cleanup from the prefetch branch
r8596@Thesaurus (orig r8583):  ribasushi | 2010-02-08 12:42:09 +0100
Merge fix of RT54039 from prefetch branch
r8598@Thesaurus (orig r8585):  ribasushi | 2010-02-08 12:48:31 +0100
Release 0.08118
r8600@Thesaurus (orig r8587):  ribasushi | 2010-02-08 12:52:33 +0100
Bump trunk version
r8606@Thesaurus (orig r8593):  ribasushi | 2010-02-08 16:16:44 +0100
cheaper lookup
r8609@Thesaurus (orig r8596):  ribasushi | 2010-02-10 12:40:37 +0100
Consolidate last_insert_id handling with a fallback-attempt on DBI::last_insert_id
r8614@Thesaurus (orig r8601):  caelum | 2010-02-10 21:29:51 +0100
workaround for Moose bug affecting Replicated storage
r8615@Thesaurus (orig r8602):  caelum | 2010-02-10 21:40:07 +0100
revert Moose bug workaround, bump Moose dep for Replicated to 0.98
r8616@Thesaurus (orig r8603):  caelum | 2010-02-10 22:48:34 +0100
add a couple proxy methods to Replicated so it can run
r8628@Thesaurus (orig r8615):  caelum | 2010-02-11 11:35:01 +0100
 r21090@hlagh (orig r7836):  caelum | 2009-11-02 06:40:52 -0500
 new branch to fix unhandled methods in Storage::DBI::Replicated
 r21091@hlagh (orig r7837):  caelum | 2009-11-02 06:42:00 -0500
 add test to display unhandled methods
 r21092@hlagh (orig r7838):  caelum | 2009-11-02 06:55:34 -0500
 minor fix to last committed test
 r21093@hlagh (orig r7839):  caelum | 2009-11-02 09:26:00 -0500
 minor test code cleanup
 r23125@hlagh (orig r8607):  caelum | 2010-02-10 19:25:51 -0500
 add unimplemented Storage::DBI methods to ::DBI::Replicated
 r23130@hlagh (orig r8612):  ribasushi | 2010-02-11 05:12:48 -0500
 Podtesting exclusion

r8630@Thesaurus (orig r8617):  frew | 2010-02-11 11:45:54 +0100
Changes (from a while ago)
r8631@Thesaurus (orig r8618):  caelum | 2010-02-11 11:46:58 +0100
savepoints for SQLAnywhere
r8640@Thesaurus (orig r8627):  ribasushi | 2010-02-11 12:33:19 +0100
 r8424@Thesaurus (orig r8411):  ribasushi | 2010-01-22 11:19:40 +0100
 Chaining POC test

r8641@Thesaurus (orig r8628):  ribasushi | 2010-02-11 12:34:19 +0100
 r8426@Thesaurus (orig r8413):  ribasushi | 2010-01-22 11:35:15 +0100
 Moev failing regression test away from trunk

r8642@Thesaurus (orig r8629):  ribasushi | 2010-02-11 12:34:56 +0100

r8643@Thesaurus (orig r8630):  ribasushi | 2010-02-11 12:35:03 +0100
 r8507@Thesaurus (orig r8494):  frew | 2010-02-01 04:33:08 +0100
 small refactor to put select/as/+select/+as etc merging in it's own function

r8644@Thesaurus (orig r8631):  ribasushi | 2010-02-11 12:35:11 +0100
 r8514@Thesaurus (orig r8501):  frew | 2010-02-02 05:12:29 +0100
 revert actual changes from yesterday as per ribasushis advice

r8645@Thesaurus (orig r8632):  ribasushi | 2010-02-11 12:35:16 +0100
 r8522@Thesaurus (orig r8509):  frew | 2010-02-02 19:39:33 +0100
 delete +stuff if stuff exists

r8646@Thesaurus (orig r8633):  ribasushi | 2010-02-11 12:35:23 +0100
 r8534@Thesaurus (orig r8521):  frew | 2010-02-03 06:14:44 +0100
 change deletion/overriding to fix t/76

r8647@Thesaurus (orig r8634):  ribasushi | 2010-02-11 12:35:30 +0100
 r8535@Thesaurus (orig r8522):  frew | 2010-02-03 06:57:15 +0100
 some basic readability factorings (aka, fewer nested ternaries and long maps)

r8648@Thesaurus (orig r8635):  ribasushi | 2010-02-11 12:36:01 +0100
 r8558@Thesaurus (orig r8545):  frew | 2010-02-04 20:32:54 +0100
 fix incorrect test in t/76select.t and posit an incorrect solution

r8649@Thesaurus (orig r8636):  ribasushi | 2010-02-11 12:38:47 +0100

r8650@Thesaurus (orig r8637):  ribasushi | 2010-02-11 12:38:57 +0100
 r8578@Thesaurus (orig r8565):  ribasushi | 2010-02-05 19:11:09 +0100
 Should not be needed

r8651@Thesaurus (orig r8638):  ribasushi | 2010-02-11 12:39:03 +0100
 r8579@Thesaurus (orig r8566):  ribasushi | 2010-02-05 19:13:24 +0100
 SQLA now fixed

r8652@Thesaurus (orig r8639):  ribasushi | 2010-02-11 12:39:10 +0100
 r8624@Thesaurus (orig r8611):  ribasushi | 2010-02-11 10:31:08 +0100
 MOAR testing

r8653@Thesaurus (orig r8640):  ribasushi | 2010-02-11 12:39:17 +0100
 r8626@Thesaurus (orig r8613):  frew | 2010-02-11 11:16:30 +0100
 fix bad test

r8654@Thesaurus (orig r8641):  ribasushi | 2010-02-11 12:39:23 +0100
 r8627@Thesaurus (orig r8614):  frew | 2010-02-11 11:21:52 +0100
 fix t/76, break rsc tests

r8655@Thesaurus (orig r8642):  ribasushi | 2010-02-11 12:39:30 +0100
 r8632@Thesaurus (orig r8619):  frew | 2010-02-11 11:53:50 +0100
 fix incorrect test

r8656@Thesaurus (orig r8643):  ribasushi | 2010-02-11 12:39:35 +0100
 r8633@Thesaurus (orig r8620):  frew | 2010-02-11 11:54:49 +0100
 make t/76s and t/88 pass by deleting from the correct attr hash

r8657@Thesaurus (orig r8644):  ribasushi | 2010-02-11 12:39:40 +0100
 r8634@Thesaurus (orig r8621):  frew | 2010-02-11 11:55:41 +0100
 fix a test due to ordering issues

r8658@Thesaurus (orig r8645):  ribasushi | 2010-02-11 12:39:45 +0100
 r8635@Thesaurus (orig r8622):  frew | 2010-02-11 11:58:23 +0100
 this is why you run tests before you commit them.

r8659@Thesaurus (orig r8646):  ribasushi | 2010-02-11 12:39:51 +0100
 r8636@Thesaurus (orig r8623):  frew | 2010-02-11 12:00:59 +0100
 fix another ordering issue

r8660@Thesaurus (orig r8647):  ribasushi | 2010-02-11 12:39:57 +0100
 r8637@Thesaurus (orig r8624):  frew | 2010-02-11 12:11:31 +0100
 fix for search/select_chains

r8661@Thesaurus (orig r8648):  ribasushi | 2010-02-11 12:40:03 +0100

r8662@Thesaurus (orig r8649):  caelum | 2010-02-11 12:40:07 +0100
test nanosecond precision for SQLAnywhere
r8663@Thesaurus (orig r8650):  ribasushi | 2010-02-11 12:40:09 +0100
 r8639@Thesaurus (orig r8626):  ribasushi | 2010-02-11 12:33:03 +0100
 Changes and small ommission

r8666@Thesaurus (orig r8653):  ribasushi | 2010-02-11 18:16:45 +0100
Changes
r8674@Thesaurus (orig r8661):  ribasushi | 2010-02-12 09:12:45 +0100
Fix moose dep
r8680@Thesaurus (orig r8667):  dew | 2010-02-12 18:05:11 +0100
Add is_ordered to DBIC::ResultSet
r8688@Thesaurus (orig r8675):  ribasushi | 2010-02-13 09:36:29 +0100
 r8667@Thesaurus (orig r8654):  ribasushi | 2010-02-11 18:17:35 +0100
 Try a dep-handling idea
 r8675@Thesaurus (orig r8662):  ribasushi | 2010-02-12 12:46:11 +0100
 Move optional deps out of the Makefile
 r8676@Thesaurus (orig r8663):  ribasushi | 2010-02-12 13:40:53 +0100
 Support methods to verify group dependencies
 r8677@Thesaurus (orig r8664):  ribasushi | 2010-02-12 13:45:18 +0100
 Move sqlt dephandling to Optional::Deps
 r8679@Thesaurus (orig r8666):  ribasushi | 2010-02-12 14:03:17 +0100
 Move replicated to Opt::Deps
 r8684@Thesaurus (orig r8671):  ribasushi | 2010-02-13 02:47:52 +0100
 Auto-POD for Optional Deps
 r8685@Thesaurus (orig r8672):  ribasushi | 2010-02-13 02:53:20 +0100
 Privatize the full list method
 r8686@Thesaurus (orig r8673):  ribasushi | 2010-02-13 02:59:51 +0100
 Scary warning
 r8687@Thesaurus (orig r8674):  ribasushi | 2010-02-13 09:35:01 +0100
 Changes

r8691@Thesaurus (orig r8678):  ribasushi | 2010-02-13 10:07:15 +0100
Autogen comment for Dependencies.pod
r8692@Thesaurus (orig r8679):  ribasushi | 2010-02-13 10:11:24 +0100
Ask for newer M::I
r8698@Thesaurus (orig r8685):  ribasushi | 2010-02-13 11:11:10 +0100
Add author/license to pod
r8699@Thesaurus (orig r8686):  arcanez | 2010-02-13 13:43:22 +0100
fix typo per nuba on irc
r8705@Thesaurus (orig r8692):  ribasushi | 2010-02-13 15:15:33 +0100
 r8001@Thesaurus (orig r7989):  goraxe | 2009-11-30 01:14:47 +0100
 Branch for dbicadmin script refactor

 r8003@Thesaurus (orig r7991):  goraxe | 2009-11-30 01:26:39 +0100
 add DBIx::Class::Admin
 r8024@Thesaurus (orig r8012):  goraxe | 2009-12-02 22:49:27 +0100
 get deployment tests to pass
 r8025@Thesaurus (orig r8013):  goraxe | 2009-12-02 22:50:42 +0100
 get deployment tests to pass
 r8026@Thesaurus (orig r8014):  goraxe | 2009-12-02 23:52:40 +0100
 all ddl tests now pass
 r8083@Thesaurus (orig r8071):  goraxe | 2009-12-12 17:01:11 +0100
 add quite attribute to DBIx::Class admin
 r8086@Thesaurus (orig r8074):  goraxe | 2009-12-12 17:36:58 +0100
 add tests for data manipulation ported from 89dbicadmin.t
 r8088@Thesaurus (orig r8076):  goraxe | 2009-12-12 17:38:07 +0100
 add sleep 1 to t/admin/02ddl.t so insert into upgrade table does not happen too quickly
 r8089@Thesaurus (orig r8077):  goraxe | 2009-12-12 17:40:33 +0100
 update DBIx::Class::Admin data manip functions to pass the test
 r8095@Thesaurus (orig r8083):  goraxe | 2009-12-12 19:36:22 +0100
 change passing of preversion to be a parameter
 r8096@Thesaurus (orig r8084):  goraxe | 2009-12-12 19:38:26 +0100
 add some pod to DBIx::Class::Admin
 r8103@Thesaurus (orig r8091):  goraxe | 2009-12-12 22:08:55 +0100
 some changes to make DBIx::Class::Admin more compatible with dbicadmin interface
 r8104@Thesaurus (orig r8092):  goraxe | 2009-12-12 22:09:39 +0100
 commit refactored dbicadmin script and very minor changes to its existing test suite
 r8107@Thesaurus (orig r8095):  goraxe | 2009-12-12 22:34:35 +0100
 add compatability for --op for dbicadmin, revert test suite
 r8127@Thesaurus (orig r8115):  goraxe | 2009-12-15 22:14:20 +0100
 dep check to end of module
 r8128@Thesaurus (orig r8116):  goraxe | 2009-12-15 23:15:25 +0100
 add namespace::autoclean to DBIx::Class::Admin
 r8129@Thesaurus (orig r8117):  goraxe | 2009-12-15 23:16:00 +0100
 update test suite to skip if cannot load DBIx::Class::Admin
 r8130@Thesaurus (orig r8118):  goraxe | 2009-12-15 23:18:35 +0100
 add deps check for 89dbicadmin.t
 r8131@Thesaurus (orig r8119):  goraxe | 2009-12-15 23:19:01 +0100
 include deps for dbicadmin DBIx::Class::Admin to Makefile.PL
 r8149@Thesaurus (orig r8137):  goraxe | 2009-12-17 23:21:50 +0100
 use DBICTest::_database over creating a schema object to steal conn info
 r8338@Thesaurus (orig r8326):  goraxe | 2010-01-15 19:00:17 +0100
 change white space to not be tabs
 r8339@Thesaurus (orig r8327):  goraxe | 2010-01-15 19:10:42 +0100
 remove Module::Load from test suite
 r8358@Thesaurus (orig r8346):  ribasushi | 2010-01-17 17:52:10 +0100
 Real detabify
 r8359@Thesaurus (orig r8347):  ribasushi | 2010-01-17 18:01:53 +0100
 Fix POD (spacing matters)
 r8360@Thesaurus (orig r8348):  ribasushi | 2010-01-17 21:57:53 +0100
 More detabification
 r8361@Thesaurus (orig r8349):  ribasushi | 2010-01-17 22:33:12 +0100
 Test cleanup
 r8362@Thesaurus (orig r8350):  ribasushi | 2010-01-17 22:41:11 +0100
 More tets cleanup
 r8363@Thesaurus (orig r8351):  ribasushi | 2010-01-17 22:43:57 +0100
 And more cleanup
 r8364@Thesaurus (orig r8352):  ribasushi | 2010-01-17 22:51:21 +0100
 Disallow mucking with INC
 r8365@Thesaurus (orig r8353):  ribasushi | 2010-01-17 23:23:15 +0100
 More cleanup
 r8366@Thesaurus (orig r8354):  ribasushi | 2010-01-17 23:27:49 +0100
 Add lib path to ENV so that $^X can see it
 r8367@Thesaurus (orig r8355):  ribasushi | 2010-01-17 23:33:10 +0100
 Move script-test
 r8368@Thesaurus (orig r8356):  goraxe | 2010-01-17 23:35:03 +0100
 change warns/dies -> carp/throw_exception
 r8369@Thesaurus (orig r8357):  goraxe | 2010-01-17 23:53:54 +0100
 add goraxe to contributors
 r8370@Thesaurus (orig r8358):  goraxe | 2010-01-17 23:54:15 +0100
 remove comment headers
 r8404@Thesaurus (orig r8391):  caelum | 2010-01-20 20:54:29 +0100
 minor fixups
 r8405@Thesaurus (orig r8392):  goraxe | 2010-01-20 21:13:24 +0100
 add private types to coerce
 r8406@Thesaurus (orig r8393):  goraxe | 2010-01-20 21:17:19 +0100
 remove un-needed coerce from schema_class of type Str
 r8411@Thesaurus (orig r8398):  caelum | 2010-01-21 23:36:25 +0100
 minor documentation updates
 r8436@Thesaurus (orig r8423):  caelum | 2010-01-25 02:56:30 +0100
 this code never runs anyway
 r8440@Thesaurus (orig r8427):  caelum | 2010-01-26 14:05:53 +0100
 prefer JSON::DWIW for barekey support
 r8693@Thesaurus (orig r8680):  ribasushi | 2010-02-13 10:27:18 +0100
 dbicadmin dependencies
 r8694@Thesaurus (orig r8681):  ribasushi | 2010-02-13 10:28:04 +0100
 Some cleaup, make use of Text::CSV
 r8695@Thesaurus (orig r8682):  ribasushi | 2010-02-13 10:34:19 +0100
 We use Try::Tiny in a single spot, not grounds for inlusion in deps
 r8696@Thesaurus (orig r8683):  ribasushi | 2010-02-13 10:37:30 +0100
 POD section
 r8697@Thesaurus (orig r8684):  ribasushi | 2010-02-13 11:05:17 +0100
 Switch tests to Optional::Deps
 r8700@Thesaurus (orig r8687):  ribasushi | 2010-02-13 14:32:50 +0100
 Switch Admin/dbicadmin to Opt::Deps
 r8702@Thesaurus (orig r8689):  ribasushi | 2010-02-13 14:39:24 +0100
 JSON dep is needed for Admin.pm itself
 r8703@Thesaurus (orig r8690):  ribasushi | 2010-02-13 15:06:28 +0100
 Test fixes
 r8704@Thesaurus (orig r8691):  ribasushi | 2010-02-13 15:13:31 +0100
 Changes

r8707@Thesaurus (orig r8694):  ribasushi | 2010-02-13 16:37:57 +0100
Test for optional deps manager
r8710@Thesaurus (orig r8697):  caelum | 2010-02-14 05:22:03 +0100
add doc on maximum cursors for SQLAnywhere
r8711@Thesaurus (orig r8698):  ribasushi | 2010-02-14 09:23:09 +0100
Cleanup dependencies / Admin inheritance
r8712@Thesaurus (orig r8699):  ribasushi | 2010-02-14 09:28:29 +0100
Some formatting
r8715@Thesaurus (orig r8702):  ribasushi | 2010-02-14 10:46:51 +0100
This is Moose, so use CMOP

1  2 
Makefile.PL
lib/DBIx/Class/ResultSet.pm
lib/DBIx/Class/ResultSource.pm
lib/DBIx/Class/Storage/DBI.pm
lib/DBIx/Class/Storage/DBI/MSSQL.pm
lib/DBIx/Class/Storage/DBI/Sybase/ASE.pm

diff --combined Makefile.PL
- use inc::Module::Install 0.89;
+ use inc::Module::Install 0.93;
  use strict;
  use warnings;
  use POSIX ();
  
  use 5.008001;
  
- # ****** DO NOT ADD OPTIONAL DEPENDENCIES. EVER. --mst ******
+ use FindBin;
+ use lib "$FindBin::Bin/lib";
+ ###
+ ### DO NOT ADD OPTIONAL DEPENDENCIES HERE, EVEN AS recommends()
+ ### All of them should go to DBIx::Class::Optional::Dependencies
+ ###
  
  name     'DBIx-Class';
  perl_version '5.008001';
  all_from 'lib/DBIx/Class.pm';
  
+ my $build_requires = {
+   'DBD::SQLite'              => '1.25',
+ };
+ my $test_requires = {
+   'File::Temp'               => '0.22',
+   'Test::Builder'            => '0.33',
+   'Test::Deep'               => '0',
+   'Test::Exception'          => '0',
+   'Test::More'               => '0.92',
+   'Test::Warn'               => '0.21',
+ };
+ my $runtime_requires = {
+   # Core
+   'List::Util'               => '0',
+   'Scalar::Util'             => '0',
+   'Storable'                 => '0',
+   # Dependencies
+   'Carp::Clan'               => '6.0',
+   'Class::Accessor::Grouped' => '0.09002',
+   'Class::C3::Componentised' => '1.0005',
+   'Class::Inspector'         => '1.24',
+   'Data::Page'               => '2.00',
+   'DBI'                      => '1.609',
+   'MRO::Compat'              => '0.09',
+   'Module::Find'             => '0.06',
+   'Path::Class'              => '0.18',
+   'Scope::Guard'             => '0.03',
+   'SQL::Abstract'            => '1.61',
+   'SQL::Abstract::Limit'     => '0.13',
+   'Sub::Name'                => '0.04',
+   'Data::Dumper::Concise'    => '1.000',
+ };
+ # this is so we can order requires alphabetically
+ # copies are needed for author requires injection
+ my $reqs = {
+   build_requires => { %$build_requires },
+   requires => { %$runtime_requires },
+   test_requires => { %$test_requires },
+ };
+ # re-build README and require extra modules for testing if we're in a checkout
+ if ($Module::Install::AUTHOR) {
+   print "Regenerating README\n";
+   system('pod2text lib/DBIx/Class.pm > README');
+   if (-f 'MANIFEST') {
+     print "Removing MANIFEST\n";
+     unlink 'MANIFEST';
+   }
+   print "Regenerating Optional/Dependencies.pod\n";
+   require DBIx::Class::Optional::Dependencies;
+   DBIx::Class::Optional::Dependencies->_gen_pod;
+ # FIXME Disabled due to unsolved issues, ask theorbtwo
+ #  require Module::Install::Pod::Inherit;
+ #  PodInherit();
+   warn <<'EOW';
+ ******************************************************************************
+ ******************************************************************************
+ ***                                                                        ***
+ *** AUTHOR MODE: all optional test dependencies converted to hard requires ***
+ ***                                                                        ***
+ ******************************************************************************
+ ******************************************************************************
+ EOW
+   $reqs->{test_requires} = {
+     %{$reqs->{test_requires}},
+     %{DBIx::Class::Optional::Dependencies->_all_optional_requirements},
+   };
+ }
+ # compose final req list, for alphabetical ordering
+ my %final_req;
+ for my $rtype (keys %$reqs) {
+   for my $mod (keys %{$reqs->{$rtype}} ) {
+     # sanity check req duplications
+     if ($final_req{$mod}) {
+       die "$mod specified as both a '$rtype' and a '$final_req{$mod}[0]'\n";
+     }
  
- test_requires 'Test::Builder'       => '0.33';
- test_requires 'Test::Deep'          => '0';
- test_requires 'Test::Exception'     => '0';
- test_requires 'Test::More'          => '0.92';
- test_requires 'Test::Warn'          => '0.21';
- test_requires 'File::Temp'          => '0.22';
- # Core
- requires 'List::Util'               => '0';
- requires 'Scalar::Util'             => '0';
- requires 'Storable'                 => '0';
- # Dependencies (keep in alphabetical order)
- requires 'Carp::Clan'               => '6.0';
- requires 'Class::Accessor::Grouped' => '0.09002';
- requires 'Class::C3::Componentised' => '1.0005';
- requires 'Class::Inspector'         => '1.24';
- requires 'Data::Page'               => '2.00';
- requires 'DBD::SQLite'              => '1.25';
- requires 'DBI'                      => '1.609';
- requires 'JSON::Any'                => '1.18';
- requires 'MRO::Compat'              => '0.09';
- requires 'Module::Find'             => '0.06';
- requires 'Path::Class'              => '0.16';
- requires 'Scope::Guard'             => '0.03';
- requires 'SQL::Abstract'            => '1.60';
- requires 'SQL::Abstract::Limit'     => '0.13';
- requires 'Sub::Name'                => '0.04';
- requires 'Data::Dumper::Concise'    => '1.000';
- my %replication_requires = (
-   'Moose',                    => '0.90',
-   'MooseX::Types',            => '0.21',
-   'namespace::clean'          => '0.11',
-   'Hash::Merge',              => '0.11',
- );
- #************************************************************************#
- # Make *ABSOLUTELY SURE* that nothing on this list is a real require,    #
- # since every module listed in %force_requires_if_author is deleted      #
- # from the final META.yml (thus will never make it as a CPAN dependency) #
- #************************************************************************#
- my %force_requires_if_author = (
-   %replication_requires,
-   # when changing also adjust $DBIx::Class::Storage::DBI::minimum_sqlt_version
-   'SQL::Translator'           => '0.11002',
- #  'Module::Install::Pod::Inherit' => '0.01',
-   # when changing also adjust version in t/02pod.t
-   'Test::Pod'                 => '1.26',
-   # when changing also adjust version in t/06notabs.t
- #  'Test::NoTabs'              => '0.9',
-   # when changing also adjust version in t/07eol.t
- #  'Test::EOL'                 => '0.6',
-   # when changing also adjust version in t/03podcoverage.t
-   'Test::Pod::Coverage'       => '1.08',
-   'Pod::Coverage'             => '0.20',
-   # CDBI-compat related
-   'DBIx::ContextualFetch'     => '0',
-   'Class::DBI::Plugin::DeepAbstractSearch' => '0',
-   'Class::Trigger'            => '0',
-   'Time::Piece::MySQL'        => '0',
-   'Clone'                     => '0',
-   'Date::Simple'              => '3.03',
-   # t/52cycle.t
-   'Test::Memory::Cycle'       => '0',
-   'Devel::Cycle'              => '1.10',
-   # t/36datetime.t
-   # t/60core.t
-   'DateTime::Format::SQLite'  => '0',
-   # t/96_is_deteministic_value.t
-   'DateTime::Format::Strptime'=> '0',
-   # database-dependent reqs
-   #
-   $ENV{DBICTEST_PG_DSN}
-     ? (
-       'Sys::SigAction' => '0',
-       'DBD::Pg' => '2.009002',
-       'DateTime::Format::Pg' => '0',
-     ) : ()
-   ,
-   $ENV{DBICTEST_MYSQL_DSN}
-     ? (
-       'DateTime::Format::MySQL' => '0',
-     ) : ()
-   ,
-   $ENV{DBICTEST_ORA_DSN}
-     ? (
-       'DateTime::Format::Oracle' => '0',
-     ) : ()
-   ,
-   $ENV{DBICTEST_SYBASE_DSN}
-     ? (
-       'DateTime::Format::Sybase' => 0,
-     ) : ()
-   ,
- );
- #************************************************************************#
- # Make ABSOLUTELY SURE that nothing on the list above is a real require, #
- # since every module listed in %force_requires_if_author is deleted      #
- # from the final META.yml (thus will never make it as a CPAN dependency) #
- #************************************************************************#
+     $final_req{$mod} = [ $rtype, $reqs->{$rtype}{$mod}||0 ],
+   }
+ }
  
+ # actual require
+ for my $mod (sort keys %final_req) {
+   my ($rtype, $ver) = @{$final_req{$mod}};
+   no strict 'refs';
+   $rtype->($mod, $ver);
+ }
  
  install_script (qw|
      script/dbicadmin
@@@ -150,49 -138,26 +138,25 @@@ no_index directory => $_ for (qw
    lib/DBIx/Class/PK/Auto
  |);
  no_index package => $_ for (qw/
    DBIx::Class::SQLAHacks DBIx::Class::Storage::DBIHacks
  /);
  
- # re-build README and require extra modules for testing if we're in a checkout
- if ($Module::Install::AUTHOR) {
-   warn <<'EOW';
- ******************************************************************************
- ******************************************************************************
- ***                                                                        ***
- *** AUTHOR MODE: all optional test dependencies converted to hard requires ***
- ***                                                                        ***
- ******************************************************************************
- ******************************************************************************
- EOW
-   foreach my $module (sort keys %force_requires_if_author) {
-     build_requires ($module => $force_requires_if_author{$module});
-   }
-   print "Regenerating README\n";
-   system('pod2text lib/DBIx/Class.pm > README');
-   if (-f 'MANIFEST') {
-     print "Removing MANIFEST\n";
-     unlink 'MANIFEST';
-   }
- #  require Module::Install::Pod::Inherit;
- #  PodInherit();
- }
  
  auto_install();
  
  WriteAll();
  
  # Re-write META.yml to _exclude_ all forced requires (we do not want to ship this)
  if ($Module::Install::AUTHOR) {
  
+   # FIXME test_requires is not yet part of META
+   my %original_build_requires = ( %$build_requires, %$test_requires );
+   print "Regenerating META with author requires excluded\n";
    Meta->{values}{build_requires} = [ grep
-     { not exists $force_requires_if_author{$_->[0]} }
-     ( @{Meta->{values}{build_requires}} )
+     { exists $original_build_requires{$_->[0]} }
+    ( @{Meta->{values}{build_requires}} )
    ];
  
    Meta->write;
@@@ -291,10 -291,15 +291,15 @@@ sub search_rs 
      $rows = $self->get_cache;
    }
  
+   # reset the selector list
+   if (List::Util::first { exists $attrs->{$_} } qw{columns select as}) {
+      delete @{$our_attrs}{qw{select as columns +select +as +columns include_columns}};
+   }
    my $new_attrs = { %{$our_attrs}, %{$attrs} };
  
    # merge new attrs into inherited
-   foreach my $key (qw/join prefetch +select +as bind/) {
+   foreach my $key (qw/join prefetch +select +as +columns include_columns bind/) {
      next unless exists $attrs->{$key};
      $new_attrs->{$key} = $self->_merge_attr($our_attrs->{$key}, $attrs->{$key});
    }
@@@ -1256,7 -1261,7 +1261,7 @@@ sub _count_subq_rs 
    # if we multi-prefetch we group_by primary keys only as this is what we would
    # get out of the rs via ->next/->all. We *DO WANT* to clobber old group_by regardless
    if ( keys %{$attrs->{collapse}}  ) {
 -    $sub_attrs->{group_by} = [ map { "$attrs->{alias}.$_" } ($rsrc->primary_columns) ]
 +    $sub_attrs->{group_by} = [ map { "$attrs->{alias}.$_" } ($rsrc->_pri_cols) ]
    }
  
    $sub_attrs->{select} = $rsrc->storage->_subq_count_select ($rsrc, $sub_attrs);
@@@ -1415,7 -1420,7 +1420,7 @@@ sub _rs_update_delete 
      my $attrs = $self->_resolved_attrs_copy;
  
      delete $attrs->{$_} for qw/collapse select as/;
 -    $attrs->{columns} = [ map { "$attrs->{alias}.$_" } ($self->result_source->primary_columns) ];
 +    $attrs->{columns} = [ map { "$attrs->{alias}.$_" } ($self->result_source->_pri_cols) ];
  
      if ($needs_group_by_subq) {
        # make sure no group_by was supplied, or if there is one - make sure it matches
@@@ -2465,6 -2470,23 +2470,23 @@@ sub is_paged 
    return !!$self->{attrs}{page};
  }
  
+ =head2 is_ordered
+ =over 4
+ =item Arguments: none
+ =item Return Value: true, if the resultset has been ordered with C<order_by>.
+ =back
+ =cut
+ sub is_ordered {
+   my ($self) = @_;
+   return scalar $self->result_source->storage->_parse_order_by($self->{attrs}{order_by});
+ }
  =head2 related_resultset
  
  =over 4
@@@ -2502,7 -2524,7 +2524,7 @@@ sub related_resultset 
          ->relname_to_table_alias($rel, $join_count);
  
      # since this is search_related, and we already slid the select window inwards
-     # (the select/as attrs were deleted in the beginning), we need to flip all 
+     # (the select/as attrs were deleted in the beginning), we need to flip all
      # left joins to inner, so we get the expected results
      # read the comment on top of the actual function to see what this does
      $attrs->{from} = $rsrc->schema->storage->_straight_join_to_node ($attrs->{from}, $alias);
@@@ -2588,6 -2610,68 +2610,68 @@@ sub current_source_alias 
    return ($self->{attrs} || {})->{alias} || 'me';
  }
  
+ =head2 as_subselect_rs
+ =over 4
+ =item Arguments: none
+ =item Return Value: $resultset
+ =back
+ Act as a barrier to SQL symbols.  The resultset provided will be made into a
+ "virtual view" by including it as a subquery within the from clause.  From this
+ point on, any joined tables are inaccessible to ->search on the resultset (as if
+ it were simply where-filtered without joins).  For example:
+  my $rs = $schema->resultset('Bar')->search({'x.name' => 'abc'},{ join => 'x' });
+  # 'x' now pollutes the query namespace
+  # So the following works as expected
+  my $ok_rs = $rs->search({'x.other' => 1});
+  # But this doesn't: instead of finding a 'Bar' related to two x rows (abc and
+  # def) we look for one row with contradictory terms and join in another table
+  # (aliased 'x_2') which we never use
+  my $broken_rs = $rs->search({'x.name' => 'def'});
+  my $rs2 = $rs->as_subselect_rs;
+  # doesn't work - 'x' is no longer accessible in $rs2, having been sealed away
+  my $not_joined_rs = $rs2->search({'x.other' => 1});
+  # works as expected: finds a 'table' row related to two x rows (abc and def)
+  my $correctly_joined_rs = $rs2->search({'x.name' => 'def'});
+ Another example of when one might use this would be to select a subset of
+ columns in a group by clause:
+  my $rs = $schema->resultset('Bar')->search(undef, {
+    group_by => [qw{ id foo_id baz_id }],
+  })->as_subselect_rs->search(undef, {
+    columns => [qw{ id foo_id }]
+  });
+ In the above example normally columns would have to be equal to the group by,
+ but because we isolated the group by into a subselect the above works.
+ =cut
+ sub as_subselect_rs {
+    my $self = shift;
+    return $self->result_source->resultset->search( undef, {
+       alias => $self->current_source_alias,
+       from => [{
+             $self->current_source_alias => $self->as_query,
+             -alias         => $self->current_source_alias,
+             -source_handle => $self->result_source->handle,
+          }]
+    });
+ }
  # This code is called by search_related, and makes sure there
  # is clear separation between the joins before, during, and
  # after the relationship. This information is needed later
@@@ -2715,41 -2799,46 +2799,46 @@@ sub _resolved_attrs 
    # build columns (as long as select isn't set) into a set of as/select hashes
    unless ( $attrs->{select} ) {
  
-     my @cols = ( ref($attrs->{columns}) eq 'ARRAY' )
-       ? @{ delete $attrs->{columns}}
-       : (
-           ( delete $attrs->{columns} )
-             ||
-           $source->columns
-         )
-     ;
-     @colbits = map {
-       ( ref($_) eq 'HASH' )
-       ? $_
-       : {
-           (
-             /^\Q${alias}.\E(.+)$/
-               ? "$1"
-               : "$_"
-           )
-             =>
-           (
-             /\./
-               ? "$_"
-               : "${alias}.$_"
-           )
-         }
-     } @cols;
+     my @cols;
+     if ( ref $attrs->{columns} eq 'ARRAY' ) {
+       @cols = @{ delete $attrs->{columns}}
+     } elsif ( defined $attrs->{columns} ) {
+       @cols = delete $attrs->{columns}
+     } else {
+       @cols = $source->columns
+     }
+     for (@cols) {
+       if ( ref $_ eq 'HASH' ) {
+         push @colbits, $_
+       } else {
+         my $key = /^\Q${alias}.\E(.+)$/
+           ? "$1"
+           : "$_";
+         my $value = /\./
+           ? "$_"
+           : "${alias}.$_";
+         push @colbits, { $key => $value };
+       }
+     }
    }
  
    # add the additional columns on
-   foreach ( 'include_columns', '+columns' ) {
-       push @colbits, map {
-           ( ref($_) eq 'HASH' )
-             ? $_
-             : { ( split( /\./, $_ ) )[-1] => ( /\./ ? $_ : "${alias}.$_" ) }
-       } ( ref($attrs->{$_}) eq 'ARRAY' ) ? @{ delete $attrs->{$_} } : delete $attrs->{$_} if ( $attrs->{$_} );
+   foreach (qw{include_columns +columns}) {
+     if ( $attrs->{$_} ) {
+       my @list = ( ref($attrs->{$_}) eq 'ARRAY' )
+         ? @{ delete $attrs->{$_} }
+         : delete $attrs->{$_};
+       for (@list) {
+         if ( ref($_) eq 'HASH' ) {
+           push @colbits, $_
+         } else {
+           my $key = ( split /\./, $_ )[-1];
+           my $value = ( /\./ ? $_ : "$alias.$_" );
+           push @colbits, { $key => $value };
+         }
+       }
+     }
    }
  
    # start with initial select items
          ( ref $attrs->{select} eq 'ARRAY' )
        ? [ @{ $attrs->{select} } ]
        : [ $attrs->{select} ];
-     $attrs->{as} = (
-       $attrs->{as}
-       ? (
-         ref $attrs->{as} eq 'ARRAY'
-         ? [ @{ $attrs->{as} } ]
-         : [ $attrs->{as} ]
+     if ( $attrs->{as} ) {
+       $attrs->{as} =
+         (
+           ref $attrs->{as} eq 'ARRAY'
+             ? [ @{ $attrs->{as} } ]
+             : [ $attrs->{as} ]
          )
-       : [ map { m/^\Q${alias}.\E(.+)$/ ? $1 : $_ } @{ $attrs->{select} } ]
-     );
+     } else {
+       $attrs->{as} = [ map {
+          m/^\Q${alias}.\E(.+)$/
+            ? $1
+            : $_
+          } @{ $attrs->{select} }
+       ]
+     }
    }
    else {
  
    }
  
    # now add colbits to select/as
-   push( @{ $attrs->{select} }, map { values( %{$_} ) } @colbits );
-   push( @{ $attrs->{as} },     map { keys( %{$_} ) } @colbits );
+   push @{ $attrs->{select} }, map values %{$_}, @colbits;
+   push @{ $attrs->{as}     }, map keys   %{$_}, @colbits;
  
-   my $adds;
-   if ( $adds = delete $attrs->{'+select'} ) {
+   if ( my $adds = delete $attrs->{'+select'} ) {
      $adds = [$adds] unless ref $adds eq 'ARRAY';
-     push(
-       @{ $attrs->{select} },
-       map { /\./ || ref $_ ? $_ : "${alias}.$_" } @$adds
-     );
+     push @{ $attrs->{select} },
+       map { /\./ || ref $_ ? $_ : "$alias.$_" } @$adds;
    }
-   if ( $adds = delete $attrs->{'+as'} ) {
+   if ( my $adds = delete $attrs->{'+as'} ) {
      $adds = [$adds] unless ref $adds eq 'ARRAY';
-     push( @{ $attrs->{as} }, @$adds );
+     push @{ $attrs->{as} }, @$adds;
    }
  
-   $attrs->{from} ||= [ {
+   $attrs->{from} ||= [{
      -source_handle => $source->handle,
      -alias => $self->{attrs}{alias},
      $self->{attrs}{alias} => $source->from,
-   } ];
+   }];
  
    if ( $attrs->{join} || $attrs->{prefetch} ) {
  
            $join,
            $alias,
            { %{ $attrs->{seen_join} || {} } },
-           ($attrs->{seen_join} && keys %{$attrs->{seen_join}})
+           ( $attrs->{seen_join} && keys %{$attrs->{seen_join}})
              ? $attrs->{from}[-1][0]{-join_path}
              : []
            ,
        my %already_grouped = map { $_ => 1 } (@{$attrs->{group_by}});
  
        my $storage = $self->result_source->schema->storage;
-       my $sql_maker = $storage->sql_maker;
-       local $sql_maker->{quote_char}; #disable quoting
  
        my $rs_column_list = $storage->_resolve_column_info ($attrs->{from});
-       my @chunks = $sql_maker->_order_by_chunks ($attrs->{order_by});
  
-       for my $chunk (map { ref $_ ? @$_ : $_ } (@chunks) ) {
-         $chunk =~ s/\s+ (?: ASC|DESC ) \s* $//ix;
+       for my $chunk ($storage->_parse_order_by($attrs->{order_by})) {
          if ($rs_column_list->{$chunk} && not $already_grouped{$chunk}++) {
            push @{$attrs->{group_by}}, $chunk;
          }
@@@ -503,16 -503,6 +503,16 @@@ sub primary_columns 
    return @{shift->_primaries||[]};
  }
  
 +sub _pri_cols {
 +  my $self = shift;
 +  my @pcols = $self->primary_columns
 +    or $self->throw_exception (sprintf(
 +      'Operation requires a primary key to be declared on %s via set_primary_key',
 +      ref $self,
 +    ));
 +  return @pcols;
 +}
 +
  =head2 add_unique_constraint
  
  =over 4
@@@ -1198,12 -1188,6 +1198,6 @@@ sub _compare_relationship_keys 
    return $found;
  }
  
- sub resolve_join {
-   carp 'resolve_join is a private method, stop calling it';
-   my $self = shift;
-   $self->_resolve_join (@_);
- }
  # Returns the {from} structure used to express JOIN conditions
  sub _resolve_join {
    my ($self, $join, $alias, $seen, $jpath, $parent_force_left) = @_;
                    : $rel_info->{attrs}{join_type}
                  ,
                 -join_path => [@$jpath, { $join => $as } ],
-                -is_single => (List::Util::first { $rel_info->{attrs}{accessor} eq $_ } (qw/single filter/) ),
+                -is_single => (
+                   $rel_info->{attrs}{accessor}
+                     &&
+                   List::Util::first { $rel_info->{attrs}{accessor} eq $_ } (qw/single filter/)
+                 ),
                 -alias => $as,
                 -relation_chain_depth => $seen->{-relation_chain_depth} || 0,
               },
@@@ -1383,77 -1371,6 +1381,6 @@@ sub _resolve_condition 
    }
  }
  
- # Legacy code, needs to go entirely away (fully replaced by _resolve_prefetch)
- sub resolve_prefetch {
-   carp 'resolve_prefetch is a private method, stop calling it';
-   my ($self, $pre, $alias, $seen, $order, $collapse) = @_;
-   $seen ||= {};
-   if( ref $pre eq 'ARRAY' ) {
-     return
-       map { $self->resolve_prefetch( $_, $alias, $seen, $order, $collapse ) }
-         @$pre;
-   }
-   elsif( ref $pre eq 'HASH' ) {
-     my @ret =
-     map {
-       $self->resolve_prefetch($_, $alias, $seen, $order, $collapse),
-       $self->related_source($_)->resolve_prefetch(
-                $pre->{$_}, "${alias}.$_", $seen, $order, $collapse)
-     } keys %$pre;
-     return @ret;
-   }
-   elsif( ref $pre ) {
-     $self->throw_exception(
-       "don't know how to resolve prefetch reftype ".ref($pre));
-   }
-   else {
-     my $count = ++$seen->{$pre};
-     my $as = ($count > 1 ? "${pre}_${count}" : $pre);
-     my $rel_info = $self->relationship_info( $pre );
-     $self->throw_exception( $self->name . " has no such relationship '$pre'" )
-       unless $rel_info;
-     my $as_prefix = ($alias =~ /^.*?\.(.+)$/ ? $1.'.' : '');
-     my $rel_source = $self->related_source($pre);
-     if (exists $rel_info->{attrs}{accessor}
-          && $rel_info->{attrs}{accessor} eq 'multi') {
-       $self->throw_exception(
-         "Can't prefetch has_many ${pre} (join cond too complex)")
-         unless ref($rel_info->{cond}) eq 'HASH';
-       my $dots = @{[$as_prefix =~ m/\./g]} + 1; # +1 to match the ".${as_prefix}"
-       if (my ($fail) = grep { @{[$_ =~ m/\./g]} == $dots }
-                          keys %{$collapse}) {
-         my ($last) = ($fail =~ /([^\.]+)$/);
-         carp (
-           "Prefetching multiple has_many rels ${last} and ${pre} "
-           .(length($as_prefix)
-             ? "at the same level (${as_prefix}) "
-             : "at top level "
-           )
-           . 'will explode the number of row objects retrievable via ->next or ->all. '
-           . 'Use at your own risk.'
-         );
-       }
-       #my @col = map { (/^self\.(.+)$/ ? ("${as_prefix}.$1") : ()); }
-       #              values %{$rel_info->{cond}};
-       $collapse->{".${as_prefix}${pre}"} = [ $rel_source->primary_columns ];
-         # action at a distance. prepending the '.' allows simpler code
-         # in ResultSet->_collapse_result
-       my @key = map { (/^foreign\.(.+)$/ ? ($1) : ()); }
-                     keys %{$rel_info->{cond}};
-       my @ord = (ref($rel_info->{attrs}{order_by}) eq 'ARRAY'
-                    ? @{$rel_info->{attrs}{order_by}}
-                    : (defined $rel_info->{attrs}{order_by}
-                        ? ($rel_info->{attrs}{order_by})
-                        : ()));
-       push(@$order, map { "${as}.$_" } (@key, @ord));
-     }
-     return map { [ "${as}.$_", "${as_prefix}${pre}.$_", ] }
-       $rel_source->columns;
-   }
- }
  
  # Accepts one or more relationships for the current source and returns an
  # array of column names for each of those relationships. Column names are
@@@ -1502,8 -1419,7 +1429,7 @@@ sub _resolve_prefetch 
      my $as_prefix = ($alias =~ /^.*?\.(.+)$/ ? $1.'.' : '');
      my $rel_source = $self->related_source($pre);
  
-     if (exists $rel_info->{attrs}{accessor}
-          && $rel_info->{attrs}{accessor} eq 'multi') {
+     if ($rel_info->{attrs}{accessor} && $rel_info->{attrs}{accessor} eq 'multi') {
        $self->throw_exception(
          "Can't prefetch has_many ${pre} (join cond too complex)")
          unless ref($rel_info->{cond}) eq 'HASH';
                      keys %{$rel_info->{cond}};
        my @ord = (ref($rel_info->{attrs}{order_by}) eq 'ARRAY'
                     ? @{$rel_info->{attrs}{order_by}}
-                    : (defined $rel_info->{attrs}{order_by}
+    
+                 : (defined $rel_info->{attrs}{order_by}
                         ? ($rel_info->{attrs}{order_by})
                         : ()));
        push(@$order, map { "${as}.$_" } (@key, @ord));
@@@ -16,11 -16,6 +16,6 @@@ use List::Util()
  use Data::Dumper::Concise();
  use Sub::Name ();
  
- # what version of sqlt do we require if deploy() without a ddl_dir is invoked
- # when changing also adjust the corresponding author_require in Makefile.PL
- my $minimum_sqlt_version = '0.11002';
  __PACKAGE__->mk_group_accessors('simple' =>
    qw/_connect_info _dbi_connect_info _dbh _sql_maker _sql_maker_opts _conn_pid
       _conn_tid transaction_depth _dbh_autocommit _driver_determined savepoints/
@@@ -1606,7 -1601,15 +1601,7 @@@ sub _subq_update_delete 
    my $rsrc = $rs->result_source;
  
    # quick check if we got a sane rs on our hands
 -  my @pcols = $rsrc->primary_columns;
 -  unless (@pcols) {
 -    $self->throw_exception (
 -      sprintf (
 -        "You must declare primary key(s) on source '%s' (via set_primary_key) in order to update or delete complex resultsets",
 -        $rsrc->source_name || $rsrc->from
 -      )
 -    );
 -  }
 +  my @pcols = $rsrc->_pri_cols;
  
    my $sel = $rs->_resolved_attrs->{select};
    $sel = [ $sel ] unless ref $sel eq 'ARRAY';
@@@ -1659,7 -1662,7 +1654,7 @@@ sub _per_row_update_delete 
    my ($rs, $op, $values) = @_;
  
    my $rsrc = $rs->result_source;
 -  my @pcols = $rsrc->primary_columns;
 +  my @pcols = $rsrc->_pri_cols;
  
    my $guard = $self->txn_scope_guard;
  
@@@ -1825,7 -1828,7 +1820,7 @@@ sub _select_args 
        &&
      (ref $ident eq 'ARRAY' && @$ident > 1)  # indicates a join
        &&
-     scalar $sql_maker->_order_by_chunks ($attrs->{order_by})
+     scalar $self->_parse_order_by ($attrs->{order_by})
    ) {
      # the RNO limit dialect above mangles the SQL such that the join gets lost
      # wrap a subquery here
@@@ -2045,18 -2048,14 +2040,14 @@@ Return the row id of the last insert
  =cut
  
  sub _dbh_last_insert_id {
-     # All Storage's need to register their own _dbh_last_insert_id
-     # the old SQLite-based method was highly inappropriate
+     my ($self, $dbh, $source, $col) = @_;
  
-     my $self = shift;
-     my $class = ref $self;
-     $self->throw_exception (<<EOE);
+     my $id = eval { $dbh->last_insert_id (undef, undef, $source->name, $col) };
+     return $id if defined $id;
  
- No _dbh_last_insert_id() method found in $class.
- Since the method of obtaining the autoincrement id of the last insert
- operation varies greatly between different databases, this method must be
- individually implemented for every storage class.
- EOE
+     my $class = ref $self;
+     $self->throw_exception ("No storage specific _dbh_last_insert_id() method implemented in $class, and the generic DBI::last_insert_id() failed");
  }
  
  sub last_insert_id {
@@@ -2247,8 -2246,9 +2238,9 @@@ sub create_ddl_dir 
      %{$sqltargs || {}}
    };
  
-   $self->throw_exception("Can't create a ddl file without SQL::Translator: " . $self->_sqlt_version_error)
-     if !$self->_sqlt_version_ok;
+   unless (DBIx::Class::Optional::Dependencies->req_ok_for ('deploy')) {
+     $self->throw_exception("Can't create a ddl file without " . DBIx::Class::Optional::Dependencies->req_missing_for ('deploy') );
+   }
  
    my $sqlt = SQL::Translator->new( $sqltargs );
  
@@@ -2390,8 -2390,9 +2382,9 @@@ sub deployment_statements 
        return join('', @rows);
    }
  
-   $self->throw_exception("Can't deploy without either SQL::Translator or a ddl_dir: " . $self->_sqlt_version_error )
-     if !$self->_sqlt_version_ok;
+   unless (DBIx::Class::Optional::Dependencies->req_ok_for ('deploy') ) {
+     $self->throw_exception("Can't deploy without a ddl_dir or " . DBIx::Class::Optional::Dependencies->req_missing_for ('deploy') );
+   }
  
    # sources needs to be a parser arg, but for simplicty allow at top level
    # coming in
@@@ -2515,33 -2516,6 +2508,6 @@@ sub lag_behind_master 
      return;
  }
  
- # SQLT version handling
- {
-   my $_sqlt_version_ok;     # private
-   my $_sqlt_version_error;  # private
-   sub _sqlt_version_ok {
-     if (!defined $_sqlt_version_ok) {
-       eval "use SQL::Translator $minimum_sqlt_version";
-       if ($@) {
-         $_sqlt_version_ok = 0;
-         $_sqlt_version_error = $@;
-       }
-       else {
-         $_sqlt_version_ok = 1;
-       }
-     }
-     return $_sqlt_version_ok;
-   }
-   sub _sqlt_version_error {
-     shift->_sqlt_version_ok unless defined $_sqlt_version_ok;
-     return $_sqlt_version_error;
-   }
-   sub _sqlt_minimum_version { $minimum_sqlt_version };
- }
  =head2 relname_to_table_alias
  
  =over 4
@@@ -2578,7 -2552,10 +2544,10 @@@ sub DESTROY 
    # some databases need this to stop spewing warnings
    if (my $dbh = $self->_dbh) {
      local $@;
-     eval { $dbh->disconnect };
+     eval {
+       %{ $dbh->{CachedKids} } = ();
+       $dbh->disconnect;
+     };
    }
  
    $self->_dbh(undef);
@@@ -3,7 -3,7 +3,7 @@@ package DBIx::Class::Storage::DBI::MSSQ
  use strict;
  use warnings;
  
 -use base qw/DBIx::Class::Storage::DBI::AmbiguousGlob DBIx::Class::Storage::DBI/;
 +use base qw/DBIx::Class::Storage::DBI/;
  use mro 'c3';
  
  use List::Util();
@@@ -190,7 -190,7 +190,7 @@@ sub _select_args_to_query 
  
    # see if this is an ordered subquery
    my $attrs = $_[3];
-   if ( scalar $self->sql_maker->_order_by_chunks ($attrs->{order_by}) ) {
+   if ( scalar $self->_parse_order_by ($attrs->{order_by}) ) {
      $self->throw_exception(
        'An ordered subselect encountered - this is not safe! Please see "Ordered Subselects" in DBIx::Class::Storage::DBI::MSSQL
      ') unless $attrs->{unsafe_subselect_ok};
@@@ -353,10 -353,19 +353,19 @@@ sub insert 
  
    # check for empty insert
    # INSERT INTO foo DEFAULT VALUES -- does not work with Sybase
-   # try to insert explicit 'DEFAULT's instead (except for identity)
+   # try to insert explicit 'DEFAULT's instead (except for identity, timestamp
+   # and computed columns)
    if (not %$to_insert) {
      for my $col ($source->columns) {
        next if $col eq $identity_col;
+       my $info = $source->column_info($col);
+       next if ref $info->{default_value} eq 'SCALAR'
+         || (exists $info->{data_type} && (not defined $info->{data_type}));
+       next if $info->{data_type} && $info->{data_type} =~ /^timestamp\z/i;
        $to_insert->{$col} = \'DEFAULT';
      }
    }
@@@ -719,9 -728,10 +728,9 @@@ sub _remove_blob_cols_array 
  sub _update_blobs {
    my ($self, $source, $blob_cols, $where) = @_;
  
 -  my (@primary_cols) = $source->primary_columns;
 -
 -  $self->throw_exception('Cannot update TEXT/IMAGE column(s) without a primary key')
 -    unless @primary_cols;
 +  my @primary_cols = eval { $source->_pri_cols };
 +  $self->throw_exception("Cannot update TEXT/IMAGE column(s): $@")
 +    if $@;
  
  # check if we're updating a single row by PK
    my $pk_cols_in_where = 0;
@@@ -753,9 -763,10 +762,9 @@@ sub _insert_blobs 
    my $table = $source->name;
  
    my %row = %$row;
 -  my (@primary_cols) = $source->primary_columns;
 -
 -  $self->throw_exception('Cannot update TEXT/IMAGE column(s) without a primary key')
 -    unless @primary_cols;
 +  my @primary_cols = eval { $source->_pri_cols} ;
 +  $self->throw_exception("Cannot update TEXT/IMAGE column(s): $@")
 +    if $@;
  
    $self->throw_exception('Cannot update TEXT/IMAGE column(s) without primary key values')
      if ((grep { defined $row{$_} } @primary_cols) != @primary_cols);
@@@ -933,12 -944,8 +942,8 @@@ sub _svp_rollback 
  
  =head1 Schema::Loader Support
  
- There is an experimental branch of L<DBIx::Class::Schema::Loader> that will
- allow you to dump a schema from most (if not all) versions of Sybase.
- It is available via subversion from:
-   http://dev.catalyst.perl.org/repos/bast/branches/DBIx-Class-Schema-Loader/current/
+ As of version C<0.05000>, L<DBIx::Class::Schema::Loader> should work well with
+ most (if not all) versions of Sybase ASE.
  
  =head1 FreeTDS
  
@@@ -1091,6 -1098,42 +1096,42 @@@ loading your app, if it doesn't match t
  When inserting IMAGE columns using this method, you'll need to use
  L</connect_call_blob_setup> as well.
  
+ =head1 COMPUTED COLUMNS
+ If you have columns such as:
+   created_dtm AS getdate()
+ represent them in your Result classes as:
+   created_dtm => {
+     data_type => undef,
+     default_value => \'getdate()',
+     is_nullable => 0,
+   }
+ The C<data_type> must exist and must be C<undef>. Then empty inserts will work
+ on tables with such columns.
+ =head1 TIMESTAMP COLUMNS
+ C<timestamp> columns in Sybase ASE are not really timestamps, see:
+ L<http://dba.fyicenter.com/Interview-Questions/SYBASE/The_timestamp_datatype_in_Sybase_.html>.
+ They should be defined in your Result classes as:
+   ts => {
+     data_type => 'timestamp',
+     is_nullable => 0,
+     inflate_datetime => 0,
+   }
+ The C<<inflate_datetime => 0>> is necessary if you use
+ L<DBIx::Class::InflateColumn::DateTime>, and most people do, and still want to
+ be able to read these values.
+ The values will come back as hexadecimal.
  =head1 TODO
  
  =over